summaryrefslogtreecommitdiff
path: root/libavformat/mov.c
diff options
context:
space:
mode:
authorShawn Singh <shawnsingh@google.com>2015-09-29 14:44:38 -0700
committerMichael Niedermayer <michael@niedermayer.cc>2015-09-30 05:05:17 +0200
commit733475160a0a8a2a9d8888f6dbc0188454c3c4d6 (patch)
treea4f9dfb13023a8d7d2118d15211be1bf6cdf6e6d /libavformat/mov.c
parente3242c021980e0a2688c27cb50674e7cd14c282a (diff)
libavformat/mov.c: Add parsing for DDTS atom for DTS audio
The DDTS atom is defined in ETSI TS 102 114, v1.4.1, Annex E. This is useful for DTS-HD formats, some of which cannot be decoded by dcadec.c or libdcadec. Signed-off-by: Shawn Singh <shawnsingh@google.com> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavformat/mov.c')
-rw-r--r--libavformat/mov.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c
index c57aaeb178..da170a68fa 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -744,6 +744,61 @@ static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
}
+static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ const uint32_t ddts_size = 20;
+ AVStream *st = NULL;
+ uint8_t *buf = NULL;
+ uint32_t frame_duration_code = 0;
+ uint32_t channel_layout_code = 0;
+ GetBitContext gb;
+
+ buf = av_malloc(ddts_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!buf) {
+ return AVERROR(ENOMEM);
+ }
+ if (avio_read(pb, buf, ddts_size) < ddts_size) {
+ av_free(buf);
+ return AVERROR_INVALIDDATA;
+ }
+
+ init_get_bits(&gb, buf, 8*ddts_size);
+
+ if (c->fc->nb_streams < 1) {
+ return 0;
+ }
+ st = c->fc->streams[c->fc->nb_streams-1];
+
+ st->codec->sample_rate = get_bits_long(&gb, 32);
+ skip_bits_long(&gb, 32); /* max bitrate */
+ st->codec->bit_rate = get_bits_long(&gb, 32);
+ st->codec->bits_per_coded_sample = get_bits(&gb, 8);
+ frame_duration_code = get_bits(&gb, 2);
+ skip_bits(&gb, 30); /* various fields */
+ channel_layout_code = get_bits(&gb, 16);
+
+ st->codec->frame_size =
+ (frame_duration_code == 0) ? 512 :
+ (frame_duration_code == 1) ? 1024 :
+ (frame_duration_code == 2) ? 2048 :
+ (frame_duration_code == 3) ? 4096 : 0;
+
+ if (channel_layout_code > 0xff) {
+ av_log(c->fc, AV_LOG_WARNING, "Unsupported DTS audio channel layout");
+ }
+ st->codec->channel_layout =
+ ((channel_layout_code & 0x1) ? AV_CH_FRONT_CENTER : 0) |
+ ((channel_layout_code & 0x2) ? AV_CH_FRONT_LEFT : 0) |
+ ((channel_layout_code & 0x2) ? AV_CH_FRONT_RIGHT : 0) |
+ ((channel_layout_code & 0x4) ? AV_CH_SIDE_LEFT : 0) |
+ ((channel_layout_code & 0x4) ? AV_CH_SIDE_RIGHT : 0) |
+ ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
+
+ st->codec->channels = av_get_channel_layout_nb_channels(st->codec->channel_layout);
+
+ return 0;
+}
+
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
@@ -3824,6 +3879,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
{ MKTAG('e','s','d','s'), mov_read_esds },
{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
{ MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
+{ MKTAG('d','d','t','s'), mov_read_ddts }, /* DTS audio descriptor */
{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
{ MKTAG('w','f','e','x'), mov_read_wfex },
{ MKTAG('c','m','o','v'), mov_read_cmov },