[FFmpeg-devel] [PATCH 03/10] avcodec: add avpriv_dca_parse_core_frame_header()

foo86 foobaz86 at gmail.com
Mon Jul 10 17:11:33 EEST 2017


There are 3 different places where DCA core frame header is parsed:
decoder, parser and demuxer. Each one uses ad-hoc code. Add common core
frame header parsing function that will be used in all places.
---
 libavcodec/dca.c     | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/dca.h     | 49 ++++++++++++++++++++++++++++++++++++++++++
 libavcodec/version.h |  4 ++--
 3 files changed, 111 insertions(+), 2 deletions(-)

diff --git a/libavcodec/dca.c b/libavcodec/dca.c
index fb796191d6..39f8f3d81c 100644
--- a/libavcodec/dca.c
+++ b/libavcodec/dca.c
@@ -28,7 +28,9 @@
 #include "libavutil/error.h"
 
 #include "dca.h"
+#include "dca_core.h"
 #include "dca_syncwords.h"
+#include "get_bits.h"
 #include "put_bits.h"
 
 const uint32_t avpriv_dca_sample_rates[16] = {
@@ -85,3 +87,61 @@ int avpriv_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst,
         return AVERROR_INVALIDDATA;
     }
 }
+
+int avpriv_dca_parse_core_frame_header(GetBitContext *gb, DCACoreFrameHeader *h)
+{
+    if (get_bits_long(gb, 32) != DCA_SYNCWORD_CORE_BE)
+        return DCA_PARSE_ERROR_SYNC_WORD;
+
+    h->normal_frame = get_bits1(gb);
+    h->deficit_samples = get_bits(gb, 5) + 1;
+    if (h->deficit_samples != DCA_PCMBLOCK_SAMPLES)
+        return DCA_PARSE_ERROR_DEFICIT_SAMPLES;
+
+    h->crc_present = get_bits1(gb);
+    h->npcmblocks = get_bits(gb, 7) + 1;
+    if (h->npcmblocks & (DCA_SUBBAND_SAMPLES - 1))
+        return DCA_PARSE_ERROR_PCM_BLOCKS;
+
+    h->frame_size = get_bits(gb, 14) + 1;
+    if (h->frame_size < 96)
+        return DCA_PARSE_ERROR_FRAME_SIZE;
+
+    h->audio_mode = get_bits(gb, 6);
+    if (h->audio_mode >= DCA_AMODE_COUNT)
+        return DCA_PARSE_ERROR_AMODE;
+
+    h->sr_code = get_bits(gb, 4);
+    if (!avpriv_dca_sample_rates[h->sr_code])
+        return DCA_PARSE_ERROR_SAMPLE_RATE;
+
+    h->br_code = get_bits(gb, 5);
+    if (get_bits1(gb))
+        return DCA_PARSE_ERROR_RESERVED_BIT;
+
+    h->drc_present = get_bits1(gb);
+    h->ts_present = get_bits1(gb);
+    h->aux_present = get_bits1(gb);
+    h->hdcd_master = get_bits1(gb);
+    h->ext_audio_type = get_bits(gb, 3);
+    h->ext_audio_present = get_bits1(gb);
+    h->sync_ssf = get_bits1(gb);
+    h->lfe_present = get_bits(gb, 2);
+    if (h->lfe_present == DCA_LFE_FLAG_INVALID)
+        return DCA_PARSE_ERROR_LFE_FLAG;
+
+    h->predictor_history = get_bits1(gb);
+    if (h->crc_present)
+        skip_bits(gb, 16);
+    h->filter_perfect = get_bits1(gb);
+    h->encoder_rev = get_bits(gb, 4);
+    h->copy_hist = get_bits(gb, 2);
+    h->pcmr_code = get_bits(gb, 3);
+    if (!ff_dca_bits_per_sample[h->pcmr_code])
+        return DCA_PARSE_ERROR_PCM_RES;
+
+    h->sumdiff_front = get_bits1(gb);
+    h->sumdiff_surround = get_bits1(gb);
+    h->dn_code = get_bits(gb, 4);
+    return 0;
+}
diff --git a/libavcodec/dca.h b/libavcodec/dca.h
index 1d10de4b94..cf6204e554 100644
--- a/libavcodec/dca.h
+++ b/libavcodec/dca.h
@@ -32,6 +32,49 @@
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 
+#include "get_bits.h"
+
+#define DCA_CORE_FRAME_HEADER_SIZE      18
+
+enum DCAParseError {
+    DCA_PARSE_ERROR_SYNC_WORD       = -1,
+    DCA_PARSE_ERROR_DEFICIT_SAMPLES = -2,
+    DCA_PARSE_ERROR_PCM_BLOCKS      = -3,
+    DCA_PARSE_ERROR_FRAME_SIZE      = -4,
+    DCA_PARSE_ERROR_AMODE           = -5,
+    DCA_PARSE_ERROR_SAMPLE_RATE     = -6,
+    DCA_PARSE_ERROR_RESERVED_BIT    = -7,
+    DCA_PARSE_ERROR_LFE_FLAG        = -8,
+    DCA_PARSE_ERROR_PCM_RES         = -9
+};
+
+typedef struct DCACoreFrameHeader {
+    uint8_t     normal_frame;       ///< Frame type
+    uint8_t     deficit_samples;    ///< Deficit sample count
+    uint8_t     crc_present;        ///< CRC present flag
+    uint8_t     npcmblocks;         ///< Number of PCM sample blocks
+    uint16_t    frame_size;         ///< Primary frame byte size
+    uint8_t     audio_mode;         ///< Audio channel arrangement
+    uint8_t     sr_code;            ///< Core audio sampling frequency
+    uint8_t     br_code;            ///< Transmission bit rate
+    uint8_t     drc_present;        ///< Embedded dynamic range flag
+    uint8_t     ts_present;         ///< Embedded time stamp flag
+    uint8_t     aux_present;        ///< Auxiliary data flag
+    uint8_t     hdcd_master;        ///< HDCD mastering flag
+    uint8_t     ext_audio_type;     ///< Extension audio descriptor flag
+    uint8_t     ext_audio_present;  ///< Extended coding flag
+    uint8_t     sync_ssf;           ///< Audio sync word insertion flag
+    uint8_t     lfe_present;        ///< Low frequency effects flag
+    uint8_t     predictor_history;  ///< Predictor history flag switch
+    uint8_t     filter_perfect;     ///< Multirate interpolator switch
+    uint8_t     encoder_rev;        ///< Encoder software revision
+    uint8_t     copy_hist;          ///< Copy history
+    uint8_t     pcmr_code;          ///< Source PCM resolution
+    uint8_t     sumdiff_front;      ///< Front sum/difference flag
+    uint8_t     sumdiff_surround;   ///< Surround sum/difference flag
+    uint8_t     dn_code;            ///< Dialog normalization / unspecified
+} DCACoreFrameHeader;
+
 enum DCASpeaker {
     DCA_SPEAKER_C,    DCA_SPEAKER_L,    DCA_SPEAKER_R,    DCA_SPEAKER_Ls,
     DCA_SPEAKER_Rs,   DCA_SPEAKER_LFE1, DCA_SPEAKER_Cs,   DCA_SPEAKER_Lsr,
@@ -165,4 +208,10 @@ extern const uint8_t ff_dca_bits_per_sample[8];
 int avpriv_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst,
                                  int max_size);
 
+/**
+ * Parse and validate core frame header
+ * @return 0 on success, negative DCA_PARSE_ERROR_ code on failure
+ */
+int avpriv_dca_parse_core_frame_header(GetBitContext *gb, DCACoreFrameHeader *h);
+
 #endif /* AVCODEC_DCA_H */
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 096b062e97..5b99785a72 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -28,8 +28,8 @@
 #include "libavutil/version.h"
 
 #define LIBAVCODEC_VERSION_MAJOR  57
-#define LIBAVCODEC_VERSION_MINOR 100
-#define LIBAVCODEC_VERSION_MICRO 104
+#define LIBAVCODEC_VERSION_MINOR 101
+#define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                LIBAVCODEC_VERSION_MINOR, \
-- 
2.11.0



More information about the ffmpeg-devel mailing list