mov: Support MOV_CH_LAYOUT_USE_DESCRIPTIONS for labeled descriptions.
authorAlex Converse <alex.converse@gmail.com>
Thu, 5 Jan 2012 01:42:15 +0000 (17:42 -0800)
committerAlex Converse <alex.converse@gmail.com>
Thu, 5 Jan 2012 18:34:06 +0000 (10:34 -0800)
libavformat/mov.c
libavformat/mov_chan.c
libavformat/mov_chan.h

index d3674d9..63089b9 100644 (file)
@@ -559,7 +559,8 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     AVStream *st;
     uint8_t version;
-    uint32_t flags, layout_tag, bitmap, num_descr;
+    uint32_t flags, layout_tag, bitmap, num_descr, label_mask;
+    int i;
 
     if (c->fc->nb_streams < 1)
         return 0;
@@ -581,9 +582,7 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     av_dlog(c->fc, "chan: size=%ld version=%u flags=%u layout=%u bitmap=%u num_descr=%u\n",
             atom.size, version, flags, layout_tag, bitmap, num_descr);
 
-#if 0
-    /* TODO: use the channel descriptions if the layout tag is 0 */
-    int i;
+    label_mask = 0;
     for (i = 0; i < num_descr; i++) {
         uint32_t label, cflags;
         float coords[3];
@@ -592,10 +591,19 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         AV_WN32(&coords[0], avio_rl32(pb)); // mCoordinates[0]
         AV_WN32(&coords[1], avio_rl32(pb)); // mCoordinates[1]
         AV_WN32(&coords[2], avio_rl32(pb)); // mCoordinates[2]
+        if (layout_tag == 0) {
+            uint32_t mask_incr = ff_mov_get_channel_label(label);
+            if (mask_incr == 0) {
+                label_mask = 0;
+                break;
+            }
+            label_mask |= mask_incr;
+        }
     }
-#endif
-
-    st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap);
+    if (layout_tag == 0)
+        st->codec->channel_layout = label_mask;
+    else
+        st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap);
 
     return 0;
 }
index 3c1ced6..5728ebd 100644 (file)
@@ -428,8 +428,7 @@ uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap)
     int i, channels;
     const struct MovChannelLayoutMap *layout_map;
 
-    /* handle the use of the channel descriptions */
-    /* TODO: map MOV channel labels to Libav channels */
+    /* use ff_mov_get_channel_label() to build a layout instead */
     if (tag == MOV_CH_LAYOUT_USE_DESCRIPTIONS)
         return 0;
 
@@ -451,6 +450,19 @@ uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap)
     return layout_map[i].layout;
 }
 
+uint32_t ff_mov_get_channel_label(uint32_t label)
+{
+    if (label == 0)
+        return 0;
+    if (label <= 18)
+        return 1U << (label - 1);
+    if (label == 38)
+        return AV_CH_STEREO_LEFT;
+    if (label == 39)
+        return AV_CH_STEREO_RIGHT;
+    return 0;
+}
+
 uint32_t ff_mov_get_channel_layout_tag(enum CodecID codec_id,
                                        uint64_t channel_layout,
                                        uint32_t *bitmap)
index 9723340..abb6916 100644 (file)
 uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap);
 
 /**
+ * Get the channel layout for the specified channel layout tag.
+ *
+ * @param[in]  tag     channel label
+ * @return             channel layout mask fragment
+ */
+uint32_t ff_mov_get_channel_label(uint32_t label);
+
+/**
  * Get the channel layout tag for the specified codec id and channel layout.
  * If the layout tag was not found, use a channel bitmap if possible.
  *