mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-27 21:40:34 +00:00
avcodec: add avpriv_dca_parse_core_frame_header()
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. Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
parent
9e37cc1101
commit
2123ddb425
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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, \
|
||||
|
Loading…
Reference in New Issue
Block a user