您的位置:首页 > 其它

FFmpeg解码H264流程分析

2017-12-27 13:46 375 查看
    简单介绍下FFmpeg解码的流程,具体可以参考雷神的博客:点击打开链接
    
    声明变量:AVCodec *pCodec;
AVCodecContext *pCodecCtx = NULL;
AVPacket packet;
AVFrame *pFrame;
AVCodecID codec_id = AV_CODEC_ID_H264;    AVCodec是包含了编解码器信息的结构体;
    AVCodecContext里包含的信息很多,像编解码器的类型,附加信息,视频宽高,参考帧等等;
    AVPacket存储压缩编码数据相关信息;
    AVFrame存储着码流数据,解码后的原始数据都保存在这里;
    AVCodecID指定码流对应标准;

    打开文件:FILE *fp_in = fopen("test.h264", "rb");
if (!fp_in)
{
printf("Could not open input stream\n");
return -1;
}


    首先要注册解码器及各种组件,这样才能进行解码:av_register_all();    通过上面的函数注册好后,查找解码器:pCodec = avcodec_find_decoder(codec_id);    为AVCodecContext分配存储空间:
pCodecCtx = avcodec_alloc_context3(pCodec);
    打开解码器:
avcodec_open2(pCodecCtx, pCodec, NULL);
    为解码后的数据分配内存空间,且初始化packet:   
pFrame = av_frame_alloc();
av_init_packet(&packet);
       准备工作完成后,我们读取本地的H264文件,读取的数据交给函数av_parser_parse2()解析,解析完成得到一帧数据即可交给解码器进行解码。
    av_parser_parse2()的原型和各参数:int av_parser_parse2(AVCodecParserContext *s,AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int64_t pts, int64_t dts, int64_t pos);     第一个参数:结构体AVCodecParserContext;第二个参数:结构体AVCodecContext;第三个参数:初始化后的packet.data;第四个参数:初始化后的packet.size;第五个参数:一次接收的数据包;第六个参数:接收数据包的长度;第七个参数:pts;第八个参数:dts;第九个参数:pos;
    解码函数是avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &packet),可以解码一帧数据,输入压缩编码数据的结构体AVPacket,输出解码后的结构体AVFrame。解码成功时,got_picture为非零值。
    代码如下:while (1)
{
cur_size = fread(in_buffer, 1, in_buffer_size, fp_in);
cur_ptr = in_buffer;
while (cur_size > 0)
{
int len = av_parser_parse2(pCodecParserCtx, pCodecCtx, &packet.data, &packet.size, cur_ptr, cur_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
cur_ptr += len;
cur_size -= len;

ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &packet);
if (ret < 0)
{
printf("Decode Error\n");
return ret;
}
if (got_picture)
{
printf("Succeed to decode 1 frame!\n");
}
}
}        收尾工作,释放我们分配的空间,关掉打开的解码器:fclose(fp_in);
fclose(fp_out);
av_parser_close(pCodecParserCtx);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
av_free(pCodecCtx);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: