... | ... |
@@ -29,6 +29,7 @@ |
29 | 29 |
#include "internal.h" |
30 | 30 |
#include "riff.h" |
31 | 31 |
#include "isom.h" |
32 |
+#include "mov_chan.h" |
|
32 | 33 |
#include "libavutil/intreadwrite.h" |
33 | 34 |
#include "libavutil/intfloat.h" |
34 | 35 |
#include "libavutil/dict.h" |
... | ... |
@@ -266,6 +267,11 @@ static int read_header(AVFormatContext *s) |
266 | 266 |
found_data = 1; |
267 | 267 |
break; |
268 | 268 |
|
269 |
+ case MKBETAG('c','h','a','n'): |
|
270 |
+ if ((ret = ff_mov_read_chan(s, st, size)) < 0) |
|
271 |
+ return ret; |
|
272 |
+ break; |
|
273 |
+ |
|
269 | 274 |
/* magic cookie chunk */ |
270 | 275 |
case MKBETAG('k','u','k','i'): |
271 | 276 |
if (read_kuki_chunk(s, size)) |
... | ... |
@@ -575,10 +575,6 @@ static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
575 | 575 |
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
576 | 576 |
{ |
577 | 577 |
AVStream *st; |
578 |
- uint8_t av_unused version; |
|
579 |
- uint32_t av_unused flags; |
|
580 |
- uint32_t layout_tag, bitmap, num_descr, label_mask; |
|
581 |
- int i; |
|
582 | 578 |
|
583 | 579 |
if (c->fc->nb_streams < 1) |
584 | 580 |
return 0; |
... | ... |
@@ -587,40 +583,7 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
587 | 587 |
if (atom.size < 16) |
588 | 588 |
return 0; |
589 | 589 |
|
590 |
- version = avio_r8(pb); |
|
591 |
- flags = avio_rb24(pb); |
|
592 |
- |
|
593 |
- layout_tag = avio_rb32(pb); |
|
594 |
- bitmap = avio_rb32(pb); |
|
595 |
- num_descr = avio_rb32(pb); |
|
596 |
- |
|
597 |
- if (atom.size < 16ULL + num_descr * 20ULL) |
|
598 |
- return 0; |
|
599 |
- |
|
600 |
- av_dlog(c->fc, "chan: size=%ld version=%u flags=%u layout=%u bitmap=%u num_descr=%u\n", |
|
601 |
- atom.size, version, flags, layout_tag, bitmap, num_descr); |
|
602 |
- |
|
603 |
- label_mask = 0; |
|
604 |
- for (i = 0; i < num_descr; i++) { |
|
605 |
- uint32_t label; |
|
606 |
- label = avio_rb32(pb); // mChannelLabel |
|
607 |
- avio_rb32(pb); // mChannelFlags |
|
608 |
- avio_rl32(pb); // mCoordinates[0] |
|
609 |
- avio_rl32(pb); // mCoordinates[1] |
|
610 |
- avio_rl32(pb); // mCoordinates[2] |
|
611 |
- if (layout_tag == 0) { |
|
612 |
- uint32_t mask_incr = ff_mov_get_channel_label(label); |
|
613 |
- if (mask_incr == 0) { |
|
614 |
- label_mask = 0; |
|
615 |
- break; |
|
616 |
- } |
|
617 |
- label_mask |= mask_incr; |
|
618 |
- } |
|
619 |
- } |
|
620 |
- if (layout_tag == 0) |
|
621 |
- st->codec->channel_layout = label_mask; |
|
622 |
- else |
|
623 |
- st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap); |
|
590 |
+ ff_mov_read_chan(c->fc, st, atom.size - 4); |
|
624 | 591 |
|
625 | 592 |
return 0; |
626 | 593 |
} |
... | ... |
@@ -477,7 +477,7 @@ uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap) |
477 | 477 |
return layout_map[i].layout; |
478 | 478 |
} |
479 | 479 |
|
480 |
-uint32_t ff_mov_get_channel_label(uint32_t label) |
|
480 |
+static uint32_t mov_get_channel_label(uint32_t label) |
|
481 | 481 |
{ |
482 | 482 |
if (label == 0) |
483 | 483 |
return 0; |
... | ... |
@@ -542,3 +542,47 @@ uint32_t ff_mov_get_channel_layout_tag(enum CodecID codec_id, |
542 | 542 |
|
543 | 543 |
return tag; |
544 | 544 |
} |
545 |
+ |
|
546 |
+int ff_mov_read_chan(AVFormatContext *s, AVStream *st, int64_t size) |
|
547 |
+{ |
|
548 |
+ AVIOContext *pb = s->pb; |
|
549 |
+ uint32_t layout_tag, bitmap, num_descr, label_mask; |
|
550 |
+ int i; |
|
551 |
+ |
|
552 |
+ if (size < 12) |
|
553 |
+ return AVERROR_INVALIDDATA; |
|
554 |
+ |
|
555 |
+ layout_tag = avio_rb32(pb); |
|
556 |
+ bitmap = avio_rb32(pb); |
|
557 |
+ num_descr = avio_rb32(pb); |
|
558 |
+ |
|
559 |
+ av_dlog(s, "chan: layout=%u bitmap=%u num_descr=%u\n", |
|
560 |
+ layout_tag, bitmap, num_descr); |
|
561 |
+ |
|
562 |
+ if (size < 12ULL + num_descr * 20ULL) |
|
563 |
+ return 0; |
|
564 |
+ |
|
565 |
+ label_mask = 0; |
|
566 |
+ for (i = 0; i < num_descr; i++) { |
|
567 |
+ uint32_t label; |
|
568 |
+ label = avio_rb32(pb); // mChannelLabel |
|
569 |
+ avio_rb32(pb); // mChannelFlags |
|
570 |
+ avio_rl32(pb); // mCoordinates[0] |
|
571 |
+ avio_rl32(pb); // mCoordinates[1] |
|
572 |
+ avio_rl32(pb); // mCoordinates[2] |
|
573 |
+ if (layout_tag == 0) { |
|
574 |
+ uint32_t mask_incr = mov_get_channel_label(label); |
|
575 |
+ if (mask_incr == 0) { |
|
576 |
+ label_mask = 0; |
|
577 |
+ break; |
|
578 |
+ } |
|
579 |
+ label_mask |= mask_incr; |
|
580 |
+ } |
|
581 |
+ } |
|
582 |
+ if (layout_tag == 0) |
|
583 |
+ st->codec->channel_layout = label_mask; |
|
584 |
+ else |
|
585 |
+ st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap); |
|
586 |
+ |
|
587 |
+ return 0; |
|
588 |
+} |
... | ... |
@@ -29,6 +29,7 @@ |
29 | 29 |
#include <stdint.h> |
30 | 30 |
|
31 | 31 |
#include "libavcodec/avcodec.h" |
32 |
+#include "avformat.h" |
|
32 | 33 |
|
33 | 34 |
/** |
34 | 35 |
* Get the channel layout for the specified channel layout tag. |
... | ... |
@@ -40,14 +41,6 @@ |
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 label. |
|
44 |
- * |
|
45 |
- * @param[in] label channel label |
|
46 |
- * @return channel layout mask fragment |
|
47 |
- */ |
|
48 |
-uint32_t ff_mov_get_channel_label(uint32_t label); |
|
49 |
- |
|
50 |
-/** |
|
51 | 43 |
* Get the channel layout tag for the specified codec id and channel layout. |
52 | 44 |
* If the layout tag was not found, use a channel bitmap if possible. |
53 | 45 |
* |
... | ... |
@@ -60,4 +53,14 @@ uint32_t ff_mov_get_channel_layout_tag(enum CodecID codec_id, |
60 | 60 |
uint64_t channel_layout, |
61 | 61 |
uint32_t *bitmap); |
62 | 62 |
|
63 |
+/** |
|
64 |
+ * Read 'chan' tag from the input stream. |
|
65 |
+ * |
|
66 |
+ * @param s AVFormatContext |
|
67 |
+ * @param st The stream to set codec values for |
|
68 |
+ * @param size Remaining size in the 'chan' tag |
|
69 |
+ * @return 0 if ok, or negative AVERROR code on failure |
|
70 |
+ */ |
|
71 |
+int ff_mov_read_chan(AVFormatContext *s, AVStream *st, int64_t size); |
|
72 |
+ |
|
63 | 73 |
#endif /* AVFORMAT_MOV_CHAN_H */ |