ffmpeg解码H.264视频数据,MFC播放视频

ffmpeg 是一个完整的视频流解决方案,开源且有良好的跨平台性,ffmpeg具有强大的多媒体数据处理能力,能够实现视频的采集,多种视频格式间转换,给视频添加水印等多种功能,已被 VLC、Mplayer 等多种开源项目所采用,本系统客户端在进行 H.264 数据解码时利用 ffmpeg 来进行实现。

                               ffmpeg库 在vs2012中的调用


(1)下载地址:http://ffmpeg.zeranoe.com/builds/ 所需文件Builds(Dev)和Builds(Shared),ffmpeg库是在网上下载的最新版本20160409版

      Builds(Dev):包含了所需要的.h头文件和.lib库文件 

      Builds(Shared):包含了所需要的dll文件

为了解决C99的兼容问题,在vs2012/vc/include中自行添加了auto_stdint.h;auto_inttype.h 如果不添加则会出现编译错误。对应的某些ffmpeg头文件 #include<stdint.h>和#include<inttype.h>都要相应的改为#include<auto_stdint.h>和#include <auto_inttype.h>
(2)包含文件路径,将Build(Dev)和Build(Shared)文件夹放到D:\FFMPEG中,在MFC工程中设置ffmpeg头文件位置

左侧 属性管理器->双击工程名->配置属性 -> C/C++ -> 常规 -> 附加包含目录,添加包含文件路径。

设置ffmpeg的lib文件位置 ,鼠标右键点击工程名,选择属性,然后选择 配置属性 -> 链接器 -> 常规 -> 附加库目录,添加库文件路径。

设置ffmpeg的所引用的lib文件 鼠标右键点击工程名,选择属性,然后选择 配置属性 -> 链接器 -> 输入 -> 附加依赖项,添加的文件为你下载的 Builds (Dev)中的lib 文件。avcodec.lib; avformat.lib; avutil.lib; swscale.lib; swresample.lib; avfilter.lib;swscale.lib。这些lib库在程序编译的时候没影响,但程序运行的时候需要他们。


经过测试发现由于FFMPEG版本的不同,很多函数在的使用方法都做了改变。该版本库有些函数已经声明为已否决,但使用中需要用到需要用到。ffmpeg该版本库使用过程中使用了三个声明已否决(attribute_deprecated)的函数avpicture_get_size; avpicture_fill; av_free_packet暂时未找到替代函数。若要使用这些函数,要将声明这些函数的头文件中的attribute_deprecated注释掉。


                              用ffmpeg实现H.264视频数据的解码


    我们平时看到的视频文件有许多格式,比如 avi, mkv, rmvb, mov, mp4等等,这些被称为容器(Container), 不同的容器格式规定了其中音视频数据的组织方式(也包括其他数据,比如字幕等)。容器中一般会封装有视频和音频轨,也称为视频流(stream)和音频流,播放视频文件的第一步就是根据视频文件的格式,解析(demux)出其中封装的视频流、音频流以及字幕,解析的数据读到包 (packet)中,每个包里保存的是视频帧(frame)或音频帧,然后分别对视频帧和音频帧调用相应的解码器(decoder)进行解码,使用 H.264编码的视频会相应的调用H.264解码器,解码之后得到的就是原始的图像(YUV or RGB)。接下来简略介绍使用FFMPEG解码的步骤
(1)首先定义需要用到的结构体,在本客户端中,主要用到了以下结构体。
        AVFormatContext 保存需要读入的文件的格式信息,比如流的个数以及流数据等
        AVCodecContext  保存了相应流的详细编码信息,比如视频的宽、高,编码类型等。
        AVCodec 真正的编解码器,其中有编解码需要调用的函数
        AVFrame用于保存数据帧的数据结构
        AVFrame 用于保存转换之后的帧
        SwsContext 转换器,用于将YUV420P类型的图片转换为RGB类型
        AVPacket 解析文件时会将音/视频帧读入到packet中
(2)注册解码器,并且初始化自定义的AVIOContext,目的是在主机内存中申请内存空间,并将AVFormatContext的pb指针指向它。在使用avformat_open_input()打开媒体数据的时候,就可以不指定文件的URL了,即其第2个参数为NULL,读取的数据是由read_buffer()提供,read_buffer是回调函数,需要自定义read_buffer使其在视频解码时得到对应的数据。
        av_register_all();  
        pFormatCtx = avformat_alloc_context();  
        unsigned char *aviobuffer=(unsigned char *)av_malloc(1024*15); 

  • 7
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值