第六章 音视频-FFmpeg实现播放器解码和对应数据处理
第一章 音视频-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
- 要将视频
AVFrame
的时间戳(PTS)转换为毫秒,你需要考虑视频的时间基(time base)以及帧率(frame rate)。通常情况下,视频的时间戳是以基本时间单位(如秒)表示的,而帧率则指示每秒播放的帧数。 - 要将视频的
AVFrame
转换为YUV420p格式,你可以使用FFmpeg的相关功能、libYUV等。 - 然后上面转换后放在在视频帧队列进行渲染备用
音频AVFrame
- 把音频解码出来
AVFrame
对应时间戳有两种,对于音频AVFrame的时间戳,一种常见的方式是跟视频一样根据时间戳(PTS),另一种方式是使用时间基(time base)和采样率(sample rate)来计算。 - 音频AVFrame进行重采样匹配相关采样率、格式位数、通道等处理,原因扩张播放器匹配其他混音用途
- 把音频帧保存在音频队列进行播放音频备用