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
/**
* @file
* audio decoding with libavcodec API example
*
* @example decode_audio.c
*/
av_packet_alloc();//分配并初始化pkt
avcodec_find_decoder();//根据id找一个解码器codec
av_parser_init();//根据编码器id返回一个解析器上下文parserctx
avcodec_alloc_context3();//根据codec分配ctx
avcodec_open2();//用编码器打开上下文

data = inbuf;//一个数组
data_size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
while (data_size > 0) {
if (!frame) {
if (!(frame = av_frame_alloc())) {//分配和初始化完整包
exit(1);
}
}
ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,data, data_size,
AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);//从上下文中解析一个压缩包
if (ret < 0) {
exit(1);
}
data += ret;//指针移动
data_size -= ret;//缓存数量减少
if (pkt->size)
decode(c, frame, pkt, outfile);//解码 并写到文件中去
if (data_size < AUDIO_REFILL_THRESH) {//若数据少于AUDIO_REFILL_THRESH,就去文件中读取缺少的部分 直到达到AUDIO_INBUF_SIZE
memmove(inbuf, data, data_size);//将inbuf内容变为由data开始 连续data_size
data = inbuf;
len = fread(data + data_size, 1,AUDIO_INBUF_SIZE - data_size, f);
if (len > 0)
data_size += len;
}
}
pkt->data = NULL;
pkt->size = 0;
decode(c, frame, pkt, outfile);//有可能文件没解析完
avcodec_free_context();//关闭编码器上下文
av_parser_close();//关闭解析器
av_frame_free();//释放帧
av_packet_free();//释放压缩包
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
/**
* @file
* video decoding with libavcodec API example
*
* @example decode_video.c
*/
av_packet_alloc();//初始化pkt
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);//初始化缓存数组 防止越界
avcodec_find_decoder();//查找一个解码器 codec
av_parser_init();//初始化parser
avcodec_alloc_contex3();//初始化ctx
av_frame_alloc();//初始化frame

while (!feof(f)) {
data_size = fread(inbuf, 1, INBUF_SIZE, f);
if (!data_size)
break;
data = inbuf;
while (data_size > 0) {
ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);//根据parser拆分一个压缩包
if (ret < 0) {
exit(1);
}
data += ret;
data_size -= ret;
if (pkt->size)
decode(c, frame, pkt, outfilename);
}
}
decode(c, frame, NULL, outfilename);//缓存
av_parser_close();
avcodec_free_context();
av_frame_free();
av_packet_free();
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
static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
const char *filename)
{
char buf[1024];
int ret;
ret = avcodec_send_packet(dec_ctx, pkt);//将ctx中的一些字段保存到解码器中 去解码pkt
if (ret < 0) {
exit(1);
}
while (ret >= 0) {
ret = avcodec_receive_frame(dec_ctx, frame);//返回解码后的数据到frame
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
return;
else if (ret < 0) {
exit(1);
}
/*video
printf("saving frame %3d\n", dec_ctx->frame_number);
fflush(stdout);
for (i = 0; i < frame->height; i++)
fwrite(frame->data[0] + i * frame->linesize[0], 1, frame->width, f);
*/

/*audio:
data_size = av_get_bytes_per_sample(dec_ctx->sample_fmt);//每个样本的字节数
if (data_size < 0) {
exit(1);
}
for (i = 0; i < frame->nb_samples; i++)
for (ch = 0; ch < dec_ctx->channels; ch++)
fwrite(frame->data[ch] + data_size*i, 1, data_size, f);
*/
}
}