我是靠谱客的博主 爱笑发带,这篇文章主要介绍ffmpeg中aac的adts源码走读,现在分享给大家,希望可以做个参考。

adts写入

adts写入源码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
复制代码
1
2
3
4
5
6
7
typedef uint64_t BitBuf; typedef struct PutBitContext { BitBuf bit_buf; int bit_left; uint8_t *buf, *buf_ptr, *buf_end; } PutBitContext;
init_put_bits
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

按位逐位写入

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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解析

对着写入顺序逐位解析

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部