每天一点点音视频相关_ffmpeg_解包器和解码器连接

我们之前通过 AVFormatContext 创建并打开了一个音视频文件, 获取到特定的流, 然后通过 av_read_frame 从其中获取一个一个的包, 这些包里存储的是编码的数据。

然后,我们又通过 AVFormatContext 获取到流所需要的解码器 AVCodecContext, 这时候我们就可以将包数据喂给解码器,然后就得到了解码后的数据。

下面是解码的一帧的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
frame = av_frame_alloc();

ret = avcodec_send_packet(dec_ctx, pkt);
if (ret < 0) {
fprintf(stderr, "Error sending a packet for decoding\n");
exit(1);
}

while (ret >= 0) {
ret = avcodec_receive_frame(dec_ctx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
return;
else if (ret < 0) {
fprintf(stderr, "Error during decoding\n");
exit(1);
}
// 获取到解码后的帧数据
}

首先,可以看到初始化了一个解码后的帧数据结构, 然后通过 avcodec_send_packet 给解码器喂食为解码的数据包, 然后它就会拉出解码后的数据, 可以看出,为给它一次,它可能会拉出几坨,当然,也可能一坨都没有, 那就再唯。

这种机制根 Android 的 MediaCodec 是相同的, 应该也是音视频文件的数据结构所决定的。也就是一个包的数据和一个帧的数据并不是一一对一个的,而更像是一种多对多的关系。这种方式,最好的操作方式还是流的操作方式,就是喂的只管喂,拉的只管拉。详细的后面将 MediaCodec的时候再说。

明天: 每天一点点音视频相关_第一周总结