FFmpeg基础知识之视频解码api接口


FFmpeg中的解码模块和编码模块的流程其实差不多,只是比编码模块多了一个从二进制流中解析出Packet包的接口而已,做了封装的非常完善的解码模块,它的API也是非常的简洁完美。

最近尝试使用MarkDown写博客,发现还是蛮好用的,推荐大家写文档的时候可以参考一下,视频解码的API如下所示,其实实际上真正进行转换的API就那么两个:

视频解码

  • 将未解码的Packet数据送给ffmpeg的解码器
  • 从ffmpeg解码器中拿到已经解码完成的H264等数据
static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
                   const char *filename)
{
 	ret = avcodec_send_packet(dec_ctx, pkt);//将存储未解码视频数据的pkt包送到解码器上下文

     ret = avcodec_receive_frame(dec_ctx, frame);//从解码器上下文中读取已经解码好的视频流
     fflush(stdout);
     snprintf(buf, sizeof(buf), "%s-%d", filename, dec_ctx->frame_number);
     pgm_save(frame->data[0], frame->linesize[0],frame->width, frame->height, buf);///将解码好的视频流存储到文件中。
}

解码流程

下面代码的作用就是做好初始化工作,把视频流数据从文件中读取出来,然后送到上面的decode代码中去解码,这也体现了一种封装的思想,通过C语言编写面向对象的设计方式,有助于程序的健壮性。

    pkt = av_packet_alloc(); // 申请packet结构,用于存储解码前的数据
    
    codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO); //根据id 找到解码器

    parser = av_parser_init(codec->id); //创建码流解析器,作用:从一串二进制码流中解析出pak码流包
    
    c = avcodec_alloc_context3(codec);//根据解码器创建解码器上下文

    avcodec_open2(c, codec, NULL)//初始化解码器上下文,并给AVCodecContext上下文数据成员分配存储空间

    f = fopen(filename, "rb");//打开输入文件
    
    frame = av_frame_alloc();//申请frame结构体,用于存储解码后的数据
    
    data_size = fread(inbuf, 1, INBUF_SIZE, f);//从输入文件中读取二进制码流
    
    ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);//从二进制码流中解析出packet相关的数据,并存放到pkt结构体中
    
    decode(c, frame, pkt, outfilename)//解码
    /* flush the decoder */
    decode(c, frame, NULL, outfilename);//刷新解码缓冲区

    fclose(f);//关闭输入文件

    av_parser_close(parser);//关闭码流解析器
    avcodec_free_context(&c);//释放解码器上下文和解码器
    av_frame_free(&frame);//释放frame结构对象
    av_packet_free(&pkt);//释放packet结构对象

总结

上面就是一个ffmpeg中简单的解码模块流程,我在这边再做一个总结:

  • 从输入文件中读取未解码的二进制码流到buf缓冲区
  • 通过码流解析器从二进制码流中解析出符合Packet结构的未解码视频数据
  • 将未解码视频数据送到解码器去解码
  • 从解码器中读取已经解码好的视频数据
  • 将视频数据写入到输出文件中

这是一个非常普适且简单的流程,放到任何一个解码器中,都应该是差不多的。当然,流程是一样的,但是内部的算法称得上是千差万别,就像是吃饭一样,有些人每天粗茶淡饭,有些人每天食不果腹,吃的能一样吗?

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值