On Sun, May 01, 2016 at 03:30:27PM -0300, James Almer wrote:
> With the samples you shared and with a random lbr-in-wav mono sample i found
> in the wild i get the following when i try to do a codec copy.
> Core and every other DTS extension in contrast seem to set timestamps just
> fine.
> 
> #tb 0: 1/90000
> #media_type 0: audio
> #codec_id 0: dts
> #sample_rate 0: 48000
> #channel_layout 0: 60f
> Output #0, framecrc, to 'pipe:':
>     Stream #0:0: Audio: dts (DTS Express), 48000 Hz, 5.1(side), 505 kb/s
> Stream mapping:
>   Stream #0:0 -> #0:0 (copy)
> Press [q] to stop, [?] for help
> [framecrc @ 0000000000670100] Timestamps are unset in a packet for stream 0. 
> This is deprecated and will stop working in the future. Fix your code to set 
> the timestamps properly
> 0,          0,          0,        0,     5440, 0xdc73e46d
> 0,          0,          0,        0,     5440, 0x7f66bd99
> 0,          0,          0,        0,     5440, 0x116f2d31
> 0,          0,          0,        0,     5440, 0x37a82646
> 0,          0,          0,        0,     5440, 0xcc294e39
> 0,          0,          0,        0,     5440, 0x2293455d
> 0,          0,          0,        0,     5440, 0xbd9b25d3
> 0,          0,          0,        0,     5440, 0xf9331333
> 0,          0,          0,        0,     5440, 0xb96d5581
> 0,          0,          0,        0,     5440, 0x56f55088
> 0,          0,          0,        0,     5440, 0x32f81f50
> 0,          0,          0,        0,     5440, 0x8a0c986d
> 0,          0,          0,        0,     5440, 0x21615dea
> 0,          0,          0,        0,     5440, 0x5adc77e9
> 0,          0,          0,        0,     5440, 0x228e5088
> 0,          0,          0,        0,     5440, 0xd0029e27
> 0,          0,          0,        0,     5440, 0x472d4f33
> 0,          0,          0,        0,     5440, 0xdaff4ac1
> size=       1kB time=00:00:00.00 bitrate=N/A speed=   0x
> video:0kB audio:96kB subtitle:0kB other streams:0kB global headers:0kB muxing 
> overhead: unknown

Attached patch fixes timestamps for core-less DTS for me.
commit 49f02f6422e84cf381eb100b510680ecf46f7a76
Author: foo86 <fooba...@gmail.com>
Date:   Mon May 9 20:08:21 2016 +0300

    avcodec/dca_parser: set duration for core-less streams

diff --git a/libavcodec/dca_exss.c b/libavcodec/dca_exss.c
index 87b2f42..8d0b63f 100644
--- a/libavcodec/dca_exss.c
+++ b/libavcodec/dca_exss.c
@@ -375,7 +375,7 @@ static int set_exss_offsets(DCAExssAsset *asset)
     return 0;
 }
 
-int ff_dca_exss_parse(DCAExssParser *s, uint8_t *data, int size)
+int ff_dca_exss_parse(DCAExssParser *s, const uint8_t *data, int size)
 {
     int i, ret, offset, wide_hdr, header_size;
 
diff --git a/libavcodec/dca_exss.h b/libavcodec/dca_exss.h
index 323063a..208fae1 100644
--- a/libavcodec/dca_exss.h
+++ b/libavcodec/dca_exss.h
@@ -87,6 +87,6 @@ typedef struct DCAExssParser {
     DCAExssAsset   assets[1];    ///< Audio asset descriptors
 } DCAExssParser;
 
-int ff_dca_exss_parse(DCAExssParser *s, uint8_t *data, int size);
+int ff_dca_exss_parse(DCAExssParser *s, const uint8_t *data, int size);
 
 #endif
diff --git a/libavcodec/dca_parser.c b/libavcodec/dca_parser.c
index bde7dfe..83e011c 100644
--- a/libavcodec/dca_parser.c
+++ b/libavcodec/dca_parser.c
@@ -23,6 +23,8 @@
  */
 
 #include "dca.h"
+#include "dcadata.h"
+#include "dca_exss.h"
 #include "dca_syncwords.h"
 #include "get_bits.h"
 #include "parser.h"
@@ -32,6 +34,8 @@ typedef struct DCAParseContext {
     uint32_t lastmarker;
     int size;
     int framesize;
+    DCAExssParser exss;
+    unsigned int sr_code;
 } DCAParseContext;
 
 #define IS_CORE_MARKER(state) \
@@ -106,11 +110,12 @@ static av_cold int dca_parse_init(AVCodecParserContext *s)
     DCAParseContext *pc1 = s->priv_data;
 
     pc1->lastmarker = 0;
+    pc1->sr_code = -1;
     return 0;
 }
 
 static int dca_parse_params(const uint8_t *buf, int buf_size, int *duration,
-                            int *sample_rate, int *framesize)
+                            int *sample_rate, DCAParseContext *pc)
 {
     GetBitContext gb;
     uint8_t hdr[12 + AV_INPUT_BUFFER_PADDING_SIZE] = { 0 };
@@ -119,6 +124,65 @@ static int dca_parse_params(const uint8_t *buf, int buf_size, int *duration,
     if (buf_size < 12)
         return AVERROR_INVALIDDATA;
 
+    if (AV_RB32(buf) == DCA_SYNCWORD_SUBSTREAM) {
+        DCAExssAsset *asset = &pc->exss.assets[0];
+
+        if ((ret = ff_dca_exss_parse(&pc->exss, buf, buf_size)) < 0)
+            return ret;
+
+        pc->framesize = 0;
+
+        if (asset->extension_mask & DCA_EXSS_LBR) {
+            if ((ret = init_get_bits8(&gb, buf + asset->lbr_offset, asset->lbr_size)) < 0)
+                return ret;
+
+            if (get_bits_long(&gb, 32) != DCA_SYNCWORD_LBR)
+                return AVERROR_INVALIDDATA;
+
+            switch (get_bits(&gb, 8)) {
+            case 2:
+                pc->sr_code = get_bits(&gb, 8);
+            case 1:
+                break;
+            default:
+                return AVERROR_INVALIDDATA;
+            }
+
+            if (pc->sr_code >= FF_ARRAY_ELEMS(ff_dca_sampling_freqs))
+                return AVERROR_INVALIDDATA;
+
+            *sample_rate = ff_dca_sampling_freqs[pc->sr_code];
+            if (*sample_rate < 14000)
+                *duration = 1024;
+            else if (*sample_rate < 28000)
+                *duration = 2048;
+            else
+                *duration = 4096;
+
+            return 0;
+        }
+
+        if (asset->extension_mask & DCA_EXSS_XLL) {
+            if ((ret = init_get_bits8(&gb, buf + asset->xll_offset, asset->xll_size)) < 0)
+                return ret;
+
+            if (get_bits_long(&gb, 32) != DCA_SYNCWORD_XLL)
+                return AVERROR_INVALIDDATA;
+
+            if (get_bits(&gb, 4))
+                return AVERROR_INVALIDDATA;
+
+            skip_bits(&gb, 8);
+            skip_bits_long(&gb, get_bits(&gb, 5) + 1);
+            skip_bits(&gb, 4);
+            *duration = 1 << (get_bits(&gb, 4) + get_bits(&gb, 4));
+            *sample_rate = asset->max_sample_rate;
+            return 0;
+        }
+
+        return AVERROR_INVALIDDATA;
+    }
+
     if ((ret = avpriv_dca_convert_bitstream(buf, 12, hdr, 12)) < 0)
         return ret;
 
@@ -130,8 +194,8 @@ static int dca_parse_params(const uint8_t *buf, int buf_size, int *duration,
         return AVERROR_INVALIDDATA;
     *duration = 256 * (sample_blocks / 8);
 
-    *framesize = get_bits(&gb, 14) + 1;
-    if (*framesize < 95)
+    pc->framesize = get_bits(&gb, 14) + 1;
+    if (pc->framesize < 95)
         return AVERROR_INVALIDDATA;
 
     skip_bits(&gb, 6);
@@ -163,8 +227,10 @@ static int dca_parse(AVCodecParserContext *s, AVCodecContext *avctx,
         }
     }
 
+    pc1->exss.avctx = avctx;
+
     /* read the duration and sample rate from the frame header */
-    if (!dca_parse_params(buf, buf_size, &duration, &sample_rate, &pc1->framesize)) {
+    if (!dca_parse_params(buf, buf_size, &duration, &sample_rate, pc1)) {
         if (!avctx->sample_rate)
             avctx->sample_rate = sample_rate;
         s->duration = av_rescale(duration, avctx->sample_rate, sample_rate);
diff --git a/libavcodec/dcadec.h b/libavcodec/dcadec.h
index 5e47077..aa142f6 100644
--- a/libavcodec/dcadec.h
+++ b/libavcodec/dcadec.h
@@ -80,6 +80,8 @@ static inline int ff_dca_check_crc(AVCodecContext *avctx, GetBitContext *s,
 
     if (!(avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_CAREFUL)))
         return 0;
+    if (!dca)
+        return 0;
     if (((p1 | p2) & 7) || p1 < 0 || p2 > s->size_in_bits || p2 - p1 < 16)
         return -1;
     if (av_crc(dca->crctab, 0xffff, s->buffer + p1 / 8, (p2 - p1) / 8))
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to