经过网络传输接收到的码流,已经存放在公共链表 PacketNode_t 中,码流经过解码成YUV或RGB后才能播放,接下来就介绍FFmpeg解码过程和 SDL 播放视频。
FFmpeg 解码
码流解码很消耗CPU资源,所以要单独开解码线程,在这之前应该进行解码器的初始化。
解码器初始化
AVFrame *m_picture;
AVFrame *m_pFrameYUV;
AVCodec *m_codec;
AVCodecContext *m_pCodecCtx;
struct SwsContext *m_pImgCtx;
AVCodecParserContext *m_pCodecParserCtx;
AVFormatContext *m_pFmtCtx;
int m_PicBytes;
uint8_t* m_PicBuf;
BOOL CVideoDlg::InitDecoder()
{
int Ret = 0;
av_register_all(); //注册所有解码器
m_pFmtCtx = avformat_alloc_context();
if (NULL == m_pFmtCtx)
{
Printf("avformat_alloc_context failed!\n");
}
//寻找解码器
m_codec = avcodec_find_decoder(CODEC_ID_H265);
if (!m_codec)
{
Printf(TRUE,FALSE,"Codec not found !\n");
return 0;
}
//解码器结构
m_pCodecCtx = avcodec_alloc_context3(m_codec);
m_pCodecParserCtx = av_parser_init(AV_CODEC_ID_H264);
if (!m_pCodecParserCtx){
Printf(TRUE,FALSE,"Could not allocate video parser context\n");
return 0;
}
//打开解码器
Ret = avcodec_open2(m_pCodecCtx, m_codec, NULL);
if (Ret < 0)
{
Printf(TRUE,FALSE,"Could not open codec !\n");
return 0;
}