概述
adts写入
adts写入源码如下:
static int adts_write_frame_header(ADTSContext *ctx,
uint8_t *buf, int size, int pce_size)
{
PutBitContext pb;
unsigned full_frame_size = (unsigned)ADTS_HEADER_SIZE + size + pce_size;
if (full_frame_size > ADTS_MAX_FRAME_BYTES) {
av_log(NULL, AV_LOG_ERROR, "ADTS frame size too large: %u (max %d)n",
full_frame_size, ADTS_MAX_FRAME_BYTES);
return AVERROR_INVALIDDATA;
}
init_put_bits(&pb, buf, ADTS_HEADER_SIZE);
/* adts_fixed_header */
put_bits(&pb, 12, 0xfff); /* syncword */
put_bits(&pb, 1, ctx->mpeg_id); /* ID */
put_bits(&pb, 2, 0); /* layer */
put_bits(&pb, 1, 1); /* protection_absent */
put_bits(&pb, 2, ctx->objecttype); /* profile_objecttype */
put_bits(&pb, 4, ctx->sample_rate_index);
put_bits(&pb, 1, 0); /* private_bit */
put_bits(&pb, 3, ctx->channel_conf); /* channel_configuration */
put_bits(&pb, 1, 0); /* original_copy */
put_bits(&pb, 1, 0); /* home */
/* adts_variable_header */
put_bits(&pb, 1, 0); /* copyright_identification_bit */
put_bits(&pb, 1, 0); /* copyright_identification_start */
put_bits(&pb, 13, full_frame_size); /* aac_frame_length */
put_bits(&pb, 11, 0x7ff); /* adts_buffer_fullness */
put_bits(&pb, 2, 0); /* number_of_raw_data_blocks_in_frame */
flush_put_bits(&pb);
return 0;
}
ID :MPEG标识符,0标识MPEG-4,1标识MPEG-2
profile_objecttype :AAC 编码级别, 0: Main Profile, 1:LC(最常用), 2: SSR, 3: reserved
sample_rate_index:采样率标识
channel_configuration: 声道数标识
sample_rate_index对照表:
0: 96000 Hz
1: 88200 Hz
2: 64000 Hz
3: 48000 Hz
4: 44100 Hz
5: 32000 Hz
6: 24000 Hz
7: 22050 Hz
8: 16000 Hz
9: 12000 Hz
10: 11025 Hz
11: 8000 Hz
12: 7350 Hz
13: Reserved
14: Reserved
15: frequency is written explictly
channel_configuration对照表:
0: Defined in AOT Specifc Config
1: 1 channel: front-center
2: 2 channels: front-left, front-right
3: 3 channels: front-center, front-left, front-right
4: 4 channels: front-center, front-left, front-right, back-center
5: 5 channels: front-center, front-left, front-right, back-left, back-right
6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel
8-15: Reserved
PutBitContext
typedef uint64_t BitBuf;
typedef struct PutBitContext {
BitBuf bit_buf;
int bit_left;
uint8_t *buf, *buf_ptr, *buf_end;
} PutBitContext;
init_put_bits
static inline void init_put_bits(PutBitContext *s, uint8_t *buffer,
int buffer_size)
{
if (buffer_size < 0) {
buffer_size = 0;
buffer = NULL;
}
s->buf = buffer;
s->buf_end = s->buf + buffer_size;
s->buf_ptr = s->buf;
s->bit_left = BUF_BITS;
s->bit_buf = 0;
}
init_put_bits
按位逐位写入
static inline void put_bits(PutBitContext *s, int n, BitBuf value)
{
av_assert2(n <= 31 && value < (1UL << n));
put_bits_no_assert(s, n, value);
}
static inline void put_bits_no_assert(PutBitContext *s, int n, BitBuf value)
{
BitBuf bit_buf;
int bit_left;
bit_buf = s->bit_buf;
bit_left = s->bit_left;
if (n < bit_left) {
bit_buf = (bit_buf << n) | value;
bit_left -= n;
} else {
bit_buf <<= bit_left;
bit_buf |= value >> (n - bit_left);
if (s->buf_end - s->buf_ptr >= sizeof(BitBuf)) {
// AV_WBBUF(s->buf_ptr, bit_buf);
*((__unaligned uint64_t*)(s->buf_ptr)) = _byteswap_uint64(bit_buf);
s->buf_ptr += sizeof(BitBuf);
} else {
av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too smalln");
av_assert2(0);
}
bit_left += BUF_BITS - n;
bit_buf = value;
}
s->bit_buf = bit_buf;
s->bit_left = bit_left;
}
adts解析
对着写入顺序逐位解析
int ff_adts_header_parse(GetBitContext *gbc, AACADTSHeaderInfo *hdr)
{
int size, rdb, ch, sr;
int aot, crc_abs;
if (get_bits(gbc, 12) != 0xfff)
return AAC_AC3_PARSE_ERROR_SYNC;
skip_bits1(gbc); /* id */
skip_bits(gbc, 2); /* layer */
crc_abs = get_bits1(gbc); /* protection_absent */
aot = get_bits(gbc, 2); /* profile_objecttype */
sr = get_bits(gbc, 4); /* sample_frequency_index */
if (!avpriv_mpeg4audio_sample_rates[sr])
return AAC_AC3_PARSE_ERROR_SAMPLE_RATE;
skip_bits1(gbc); /* private_bit */
ch = get_bits(gbc, 3); /* channel_configuration */
skip_bits1(gbc); /* original/copy */
skip_bits1(gbc); /* home */
/* adts_variable_header */
skip_bits1(gbc); /* copyright_identification_bit */
skip_bits1(gbc); /* copyright_identification_start */
size = get_bits(gbc, 13); /* aac_frame_length */
if (size < AV_AAC_ADTS_HEADER_SIZE)
return AAC_AC3_PARSE_ERROR_FRAME_SIZE;
skip_bits(gbc, 11); /* adts_buffer_fullness */
rdb = get_bits(gbc, 2); /* number_of_raw_data_blocks_in_frame */
hdr->object_type = aot + 1;
hdr->chan_config = ch;
hdr->crc_absent = crc_abs;
hdr->num_aac_frames = rdb + 1;
hdr->sampling_index = sr;
hdr->sample_rate = avpriv_mpeg4audio_sample_rates[sr];
hdr->samples = (rdb + 1) * 1024;
hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples;
hdr->frame_length = size;
return size;
}
// 将宏定义展开
static inline unsigned int get_bits(GetBitContext *s, int n)
{
register unsigned int tmp;
unsigned int re_index = s->index;
unsigned int re_cache;
unsigned int re_size_plus8 = s->size_in_bits_plus8;
re_cache = av_bswap32(*((const __unaligned uint32_t*)(s->buffer + (re_index >> 3)))) << (re_index & 7);
tmp = ((uint32_t)(re_cache))>>(32-(n));
re_index = re_size_plus8 > re_index + n ? re_index + n : re_size_plus8;
s->index = re_index;
return tmp;
}
最后
以上就是爱笑发带为你收集整理的ffmpeg中aac的adts源码走读的全部内容,希望文章能够帮你解决ffmpeg中aac的adts源码走读所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复