... | ... |
@@ -559,7 +559,8 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
559 | 559 |
{ |
560 | 560 |
AVStream *st; |
561 | 561 |
uint8_t version; |
562 |
- uint32_t flags, layout_tag, bitmap, num_descr; |
|
562 |
+ uint32_t flags, layout_tag, bitmap, num_descr, label_mask; |
|
563 |
+ int i; |
|
563 | 564 |
|
564 | 565 |
if (c->fc->nb_streams < 1) |
565 | 566 |
return 0; |
... | ... |
@@ -581,9 +582,7 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
581 | 581 |
av_dlog(c->fc, "chan: size=%ld version=%u flags=%u layout=%u bitmap=%u num_descr=%u\n", |
582 | 582 |
atom.size, version, flags, layout_tag, bitmap, num_descr); |
583 | 583 |
|
584 |
-#if 0 |
|
585 |
- /* TODO: use the channel descriptions if the layout tag is 0 */ |
|
586 |
- int i; |
|
584 |
+ label_mask = 0; |
|
587 | 585 |
for (i = 0; i < num_descr; i++) { |
588 | 586 |
uint32_t label, cflags; |
589 | 587 |
float coords[3]; |
... | ... |
@@ -592,10 +591,19 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
592 | 592 |
AV_WN32(&coords[0], avio_rl32(pb)); // mCoordinates[0] |
593 | 593 |
AV_WN32(&coords[1], avio_rl32(pb)); // mCoordinates[1] |
594 | 594 |
AV_WN32(&coords[2], avio_rl32(pb)); // mCoordinates[2] |
595 |
+ if (layout_tag == 0) { |
|
596 |
+ uint32_t mask_incr = ff_mov_get_channel_label(label); |
|
597 |
+ if (mask_incr == 0) { |
|
598 |
+ label_mask = 0; |
|
599 |
+ break; |
|
600 |
+ } |
|
601 |
+ label_mask |= mask_incr; |
|
602 |
+ } |
|
595 | 603 |
} |
596 |
-#endif |
|
597 |
- |
|
598 |
- st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap); |
|
604 |
+ if (layout_tag == 0) |
|
605 |
+ st->codec->channel_layout = label_mask; |
|
606 |
+ else |
|
607 |
+ st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap); |
|
599 | 608 |
|
600 | 609 |
return 0; |
601 | 610 |
} |
... | ... |
@@ -428,8 +428,7 @@ uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap) |
428 | 428 |
int i, channels; |
429 | 429 |
const struct MovChannelLayoutMap *layout_map; |
430 | 430 |
|
431 |
- /* handle the use of the channel descriptions */ |
|
432 |
- /* TODO: map MOV channel labels to Libav channels */ |
|
431 |
+ /* use ff_mov_get_channel_label() to build a layout instead */ |
|
433 | 432 |
if (tag == MOV_CH_LAYOUT_USE_DESCRIPTIONS) |
434 | 433 |
return 0; |
435 | 434 |
|
... | ... |
@@ -451,6 +450,19 @@ uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap) |
451 | 451 |
return layout_map[i].layout; |
452 | 452 |
} |
453 | 453 |
|
454 |
+uint32_t ff_mov_get_channel_label(uint32_t label) |
|
455 |
+{ |
|
456 |
+ if (label == 0) |
|
457 |
+ return 0; |
|
458 |
+ if (label <= 18) |
|
459 |
+ return 1U << (label - 1); |
|
460 |
+ if (label == 38) |
|
461 |
+ return AV_CH_STEREO_LEFT; |
|
462 |
+ if (label == 39) |
|
463 |
+ return AV_CH_STEREO_RIGHT; |
|
464 |
+ return 0; |
|
465 |
+} |
|
466 |
+ |
|
454 | 467 |
uint32_t ff_mov_get_channel_layout_tag(enum CodecID codec_id, |
455 | 468 |
uint64_t channel_layout, |
456 | 469 |
uint32_t *bitmap) |
... | ... |
@@ -40,6 +40,14 @@ |
40 | 40 |
uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap); |
41 | 41 |
|
42 | 42 |
/** |
43 |
+ * Get the channel layout for the specified channel layout tag. |
|
44 |
+ * |
|
45 |
+ * @param[in] tag channel label |
|
46 |
+ * @return channel layout mask fragment |
|
47 |
+ */ |
|
48 |
+uint32_t ff_mov_get_channel_label(uint32_t label); |
|
49 |
+ |
|
50 |
+/** |
|
43 | 51 |
* Get the channel layout tag for the specified codec id and channel layout. |
44 | 52 |
* If the layout tag was not found, use a channel bitmap if possible. |
45 | 53 |
* |