使用FFMPEG SDK解码流数据获得YUV数据及其大小

系统 1987 0

本文以H264视频流为例,讲解解码流数据的步骤。

为突出重点,本文只专注于讨论解码视频流数据,不涉及其它(如开发环境的配置等)。如果您需要这方面的信息,请和我联系。

准备变量
定义AVCodecContext。如果您使用类,可以定义成类成员。我这里定义成全局变量。

static AVCodecContext * g_pCodecCtx = NULL;

定义一个AVFrame,AVFrame描述一个多媒体帧。解码后的数据将被放在其中。

static AVFrame * g_pavfFrame = NULL;

初始化解码器
现在开始初始化您的解码器。我把整个初始化过程包在了一个函数里,除非您有更好的主意,我建议您也这么做。函数长得象这样:

BOOL H264_Init()

{

}

初始化libavcodec,MMPEG要求,这个函数一定要第一个被调用:

avcodec_init();

挂上所有的codec。也许只挂一个H264的codec就行,我没试过:

av_register_all();

得到H264的解码器:

AVCodec * pCodec = avcodec_find_decoder(CODEC_ID_H264);

创建一个AVCodecContext,并用默认值初始化:

g_pCodecCtx = avcodec_alloc_context();

更改g_pCodecCtx的一些成员变量的值,您应该从解码方得到这些变量值:

g_pCodecCtx->time_base.num = 1; //这两行:一秒钟25帧

g_pCodecCtx->time_base.den = 25;

g_pCodecCtx->bit_rate = 0; //初始化为0

g_pCodecCtx->frame_number = 1; //每包一个视频帧

g_pCodecCtx->codec_type = CODEC_TYPE_VIDEO;

g_pCodecCtx->width = 704; //这两行:视频的宽度和高度

g_pCodecCtx->height = 576;

打开codec。如果打开成功的话,分配AVFrame:

if(avcodec_open(g_pCodecCtx, pCodec) >= 0)

{

g_pavfFrame = avcodec_alloc_frame();// Allocate video frame

}

列出完整的初始化解码库的代码:

解码
如果您只要求解成YUV 420I数据,只需一次调用就可以了:

avcodec_decode_video(g_pCodecCtx, g_pavfFrame, (int *)&nGot, (unsigned __int8 *)pSrcData, dwDataLen);

这里,nGot用来返回解码成功与否,avcodec_decode_video调用完成后,如果nGot不等于0,则表示解码成功,否则未解出视频帧。

pSrcData是待解的H264编码的一段数据流,dwDataLen表示该段数据流的长度,单位是byte。

解码后的视频帧(YUV数据)被存入g_pavfFrame,g_pavfFrame->data[0]、g_pavfFrame->data[1]、g_pavfFrame->data[2]即是YUV数据。下面的示例代码把YUV数据压在了一块内存里,排列方式为:

YY

YY

U

V

该函数有返回值:如果解码成功,则返回本次解码使用的码流字节数,否则返回0。为简单起见,我这里假设pSrcData只包含一个视频帧。

同样,出于模块化的要求和代码维护的方便,我把解码动作也包在了一个函数里:

BOOL H264_Decode(const PBYTE pSrcData, const DWORD dwDataLen, PBYTE pDeData, int * pnWidth, int * pnHeight)

pSrcData – 待解码数据

dwDataLen – 待解码数据字节数

pDeData – 用来返回解码后的YUV数据

pnWidth, pnHeight – 用来返回视频的长度和宽度

下面列出完整的代码:

释放解码器


以上其实已经完成了本文的任务,但从负责任的角度,要善始善终嘛。

释放的过程没什么好说的,一看就明白。同样,我也把它们包在了一个函数里:

本文来自CSDN博客,转载请标明出处: http://blog.csdn.net/gwinner/archive/2010/04/08/5462855.aspx

使用FFMPEG SDK解码流数据获得YUV数据及其大小


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论