第一章 音视频-FFmpeg解码流程和对应结构参数意
第二章 音视频-FFmpeg对应解析格式说明
第三章 音视频-FFmpeg对应AVFrame解码处理思路和用途
第四章 音视频-FFmpeg实现播放器思维
第五章 音视频-FFmpeg实现播放器解封装、读AVPacket包
第六章 音视频-FFmpeg实现播放器解码和对应数据处理
根据播放器框架步骤,上一章说完读AVPacket包后解码,读AVPacket可以把包放进队列,分为音频队列audio_queue和视频队列video_queue进去入队。然后创建音频和视频解码线程thread,上面逻辑步骤自己实现。ffmpeg解码是把AVPacket的压缩包解码成AVFrame的数据结构体,下面通用音视频解码方法:
// This does not quite work like avcodec_decode_audio4/avcodec_decode_video2.
// There is the following difference: if you got a frame, you must call
// it again with pkt=NULL. pkt==NULL is treated differently from pkt->size==0
// (pkt==NULL means get more output, pkt->size==0 is a flush/drain packet)
static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
{
int ret;
*got_frame = 0;
if (pkt) {
ret = avcodec_send_packet(avctx, pkt);
// In particular, we don't expect AVERROR(EAGAIN), because we read all
// decoded frames with avcodec_receive_frame() until done.
if (ret < 0 && ret != AVERROR_EOF)
return ret;
}
ret = avcodec_receive_frame(avctx, frame);
if (ret < 0 && ret != AVERROR(EAGAIN))
return ret;
if (ret >= 0)
*got_frame = 1;
return 0;
}
AVFrame的时间戳(PTS)转换为毫秒,你需要考虑视频的时间基(time base)以及帧率(frame rate)。通常情况下,视频的时间戳是以基本时间单位(如秒)表示的,而帧率则指示每秒播放的帧数。AVFrame转换为YUV420p格式,你可以使用FFmpeg的相关功能、libYUV等。AVFrame对应时间戳有两种,对于音频AVFrame的时间戳,一种常见的方式是跟视频一样根据时间戳(PTS),另一种方式是使用时间基(time base)和采样率(sample rate)来计算。