shithub: opus-tools

Download patch

ref: 05a089c892a6d298b26f353adcdb3a0581767f48
parent: e8baf59939f8d33d0bcd1232753a651d3dde052e
author: Jean-Marc Valin <[email protected]>
date: Tue Aug 9 09:50:22 EDT 2011

New version of the Opus header -- reversing the stream/channel map

--- a/src/opus_header.c
+++ b/src/opus_header.c
@@ -110,45 +110,45 @@
    read_chars(&p, (unsigned char*)str, 8);
    if (strcmp(str, "OpusHead")!=0)
       return 0;
+   
    if (!read_chars(&p, &ch, 1))
       return 0;
    h->version = ch;
-   if (!read_uint32(&p, &h->input_sample_rate))
-      return 0;
+   
    if (!read_chars(&p, &ch, 1))
       return 0;
-   h->multi_stream = ch;
-   if (!read_chars(&p, &ch, 1))
-      return 0;
    h->channels = ch;
+   if (h->channels == 0)
+      return 0;
+
    if (!read_uint16(&p, &shortval))
       return 0;
    h->preskip = shortval;
+
+   if (!read_uint32(&p, &h->input_sample_rate))
+      return 0;
    
-   /* Multi-stream support */
-   if (h->multi_stream!=0)
+   if (!read_chars(&p, &ch, 1))
+      return 0;
+   h->channel_mapping = ch;
+   
+   if (h->channel_mapping != 0)
    {
       if (!read_chars(&p, &ch, 1))
          return 0;
       h->nb_streams = ch;
+      
+      if (!read_chars(&p, &ch, 1))
+         return 0;
+      h->nb_coupled = ch;
+      
+      /* Multi-stream support */
       for (i=0;i<h->nb_streams;i++)
       {
-         if (!read_chars(&p, &h->mapping[i][0], 1))
+         if (!read_chars(&p, &h->stream_map[i], 1))
             return 0;
-         /* 0 = mono, 1 = stereo, rest is undefined for version 0 */
-         if (h->version == 0 && h->mapping[i][0]>1)
-            return 0;
-
-         if (!read_chars(&p, &h->mapping[i][1], 1))
-            return 0;
-         if (h->mapping[i][0]==1)
-         {
-            if (!read_chars(&p, &h->mapping[i][2], 1))
-               return 0;
-         }
       }
    }
-
    if (h->version==0 && p.pos != len)
       return 0;
    return 1;
@@ -169,34 +169,36 @@
    ch = 0;
    if (!write_chars(&p, &ch, 1))
       return 0;
-   if (!write_uint32(&p, h->input_sample_rate))
-      return 0;
-   ch = h->multi_stream;
-   if (!write_chars(&p, &ch, 1))
-      return 0;
+   
    ch = h->channels;
    if (!write_chars(&p, &ch, 1))
       return 0;
+   
    if (!write_uint16(&p, h->preskip))
       return 0;
-   
-   /* Multi-stream support */
-   if (h->multi_stream!=0)
+
+   if (!write_uint32(&p, h->input_sample_rate))
+      return 0;
+
+   ch = h->channel_mapping;
+   if (!write_chars(&p, &ch, 1))
+      return 0;
+
+   if (h->channel_mapping != 0)
    {
       ch = h->nb_streams;
       if (!write_chars(&p, &ch, 1))
          return 0;
+      
+      ch = h->nb_coupled;
+      if (!write_chars(&p, &ch, 1))
+         return 0;
+
+      /* Multi-stream support */
       for (i=0;i<h->nb_streams;i++)
       {
-         if (!write_chars(&p, &h->mapping[i][0], 1))
+         if (!write_chars(&p, &h->stream_map[i], 1))
             return 0;
-         if (!write_chars(&p, &h->mapping[i][1], 1))
-            return 0;
-         if (h->mapping[i][0]==1)
-         {
-            if (!write_chars(&p, &h->mapping[i][2], 1))
-               return 0;
-         }
       }
    }
 
--- a/src/opus_header.h
+++ b/src/opus_header.h
@@ -5,12 +5,14 @@
 
 typedef struct {
    int version;
-   opus_uint32 input_sample_rate;
-   int multi_stream;
-   int channels;
+   int channels; /* Number of channels: 1..255 */
    int preskip;
+   opus_uint32 input_sample_rate;
+   int channel_mapping;
+   /* The rest is only used if channel_mapping != 0 */
    int nb_streams;
-   unsigned char mapping[256][3];
+   int nb_coupled;
+   unsigned char stream_map[255];
 } OpusHeader;
 
 int opus_header_parse(const unsigned char *header, int len, OpusHeader *h);
--- a/src/opusenc.c
+++ b/src/opusenc.c
@@ -506,7 +506,9 @@
    header.preskip = lookahead;
    if (resampler)
       header.preskip += speex_resampler_get_output_latency(resampler);
-   header.multi_stream = 0;
+   header.channel_mapping = 0;
+   header.nb_streams = 1;
+   header.nb_coupled = 1;
    header.input_sample_rate = rate;
    
    /* Extra samples that need to be read to compensate for the pre-skip */