[FFmpeg-cvslog] avcodec/dca_parser: set duration for core-less streams

foo86 git at videolan.org
Wed May 25 16:33:12 CEST 2016


ffmpeg | branch: master | foo86 <foobaz86 at gmail.com> | Mon May 23 17:58:42 2016 +0300| [cb55c5b49e6d21709d0ea1bf93cc30a577b1de35] | committer: James Almer

avcodec/dca_parser: set duration for core-less streams

Signed-off-by: James Almer <jamrial at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=cb55c5b49e6d21709d0ea1bf93cc30a577b1de35
---

 libavcodec/dca_parser.c |   68 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 65 insertions(+), 3 deletions(-)

diff --git a/libavcodec/dca_parser.c b/libavcodec/dca_parser.c
index 0b09ba5..308df53 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) \
@@ -177,11 +181,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)
+static int dca_parse_params(DCAParseContext *pc1, const uint8_t *buf,
+                            int buf_size, int *duration, int *sample_rate)
 {
     GetBitContext gb;
     uint8_t hdr[12 + AV_INPUT_BUFFER_PADDING_SIZE] = { 0 };
@@ -190,6 +195,63 @@ 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 = &pc1->exss.assets[0];
+
+        if ((ret = ff_dca_exss_parse(&pc1->exss, buf, buf_size)) < 0)
+            return ret;
+
+        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:
+                pc1->sr_code = get_bits(&gb, 8);
+            case 1:
+                break;
+            default:
+                return AVERROR_INVALIDDATA;
+            }
+
+            if (pc1->sr_code >= FF_ARRAY_ELEMS(ff_dca_sampling_freqs))
+                return AVERROR_INVALIDDATA;
+
+            *sample_rate = ff_dca_sampling_freqs[pc1->sr_code];
+            *duration = 1024 << ff_dca_freq_ranges[pc1->sr_code];
+            return 0;
+        }
+
+        if (asset->extension_mask & DCA_EXSS_XLL) {
+            int nsamples_log2;
+
+            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);
+            nsamples_log2 = get_bits(&gb, 4) + get_bits(&gb, 4);
+            if (nsamples_log2 > 24)
+                return AVERROR_INVALIDDATA;
+
+            *sample_rate = asset->max_sample_rate;
+            *duration = (1 + (*sample_rate > 96000)) << nsamples_log2;
+            return 0;
+        }
+
+        return AVERROR_INVALIDDATA;
+    }
+
     if ((ret = avpriv_dca_convert_bitstream(buf, 12, hdr, 12)) < 0)
         return ret;
 
@@ -230,7 +292,7 @@ static int dca_parse(AVCodecParserContext *s, AVCodecContext *avctx,
     }
 
     /* read the duration and sample rate from the frame header */
-    if (!dca_parse_params(buf, buf_size, &duration, &sample_rate)) {
+    if (!dca_parse_params(pc1, buf, buf_size, &duration, &sample_rate)) {
         if (!avctx->sample_rate)
             avctx->sample_rate = sample_rate;
         s->duration = av_rescale(duration, avctx->sample_rate, sample_rate);



More information about the ffmpeg-cvslog mailing list