1、写在前面
此文章主要包含解码H264视频流数据,主要有以下几点:
1、H264视频帧为Annex B格式,若使用AVCC格式可自行研究;
2、H264视频裸流,非解码视频文件(若有需要我后期可添加这部分代码);
3、支持输出RGB24或YUV420格式,其他可自行修改;
4、FFmpeg官网代码迭代及接口变更较大,代码适应于FFmpeg3.4.2"Cantor"、3.3.7"Hilbert"等版本,较旧接口请看旧版本代码;
2、新版本
FFmpegVideoDecoder.h
#include <libavcodec/avcodec.h>
/**
视频流解码器初始化
@param ctx 解码参数结构体AVCodecParameters
@see FFmpeg_H264DecoderInit,此为解码H264视频流
@return 初始化成功返回0,否则<0
*/
int FFmpeg_VideoDecoderInit(AVCodecParameters *ctx);
/**
H264视频流解码器初始化
@return 初始化成功返回0,否则<0
*/
int FFmpeg_H264DecoderInit(void);
/**
释放解码器
@return 初始化成功返回0,否则<0
*/
int FFmpeg_VideoDecoderRelease(void);
//return 0:暂未收到解码数据,-1:解码失败,1:解码成功
/**
解码视频流数据
@param inbuf 视频裸流数据
@param inbufSize 视频裸流数据大小
@param framePara 接收帧参数数组:{width,height,linesize1,linesiz2,linesize3}
@param outRGBBuf 输出RGB数据(若已申请内存)
@param outYUVBuf 输出YUV数据(若已申请内存)
@return 成功返回解码数据帧大小,否则<=0
*/
int FFmpeg_H264Decode(unsigned char * inbuf, int inbufSize, int *framePara, unsigned char *outRGBBuf, unsigned char **outYUVBuf);
FFmpegVideoDecoder.c
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include "FFmpegVideoDecoder.h"
struct AVCodecContext *pAVCodecCtx_decoder = NULL;
struct AVCodec *pAVCodec_decoder;
struct AVPacket mAVPacket_decoder;
struct AVFrame *pAVFrame_decoder = NULL;
struct SwsContext* pImageConvertCtx_decoder = NULL;
struct AVFrame *pFrameYUV_decoder = NULL;
int FFmpeg_VideoDecoderInit(AVCodecParameters *codecParameters)
{
if (!codecParameters) {
CPrintf("Source codec context is NULL."); //CPrintf需替换为printf
return -1;
}
FFmpeg_VideoDecoderRelease();
avcodec_register_all();
pAVCodec_decoder = avcodec_find_decoder(codecParameters->codec_id);
if (!pAVCodec_decoder) {
CPrintf1("Can not find codec:%d\n", codecParameters->codec_id);
return -2;
}
pAVCodecCtx_decoder = avcodec_alloc_context3(pAVCodec_decoder);
if (!pAVCodecCtx_decoder) {
CPrintf("Failed to alloc codec context.");
FFmpeg_VideoDecoderRelease();
return -3;
}