使用FFMPEG SDK解码流数据

本文以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 – 用来返回视频的长度和宽度

下面列出完整的代码:

  • 释放解码器

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

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

(抱歉的很,文章本来是用Word写的,代码块是一个个文本框,但贴到这里却变成了图片。) 

时间: 2024-10-02 11:48:08

使用FFMPEG SDK解码流数据的相关文章

【FFMpeg视频开发与应用基础】三、调用FFmpeg SDK对H.264格式的视频压缩码流进行解码

<FFMpeg视频开发与应用基础--使用FFMpeg工具与SDK>视频教程已经在"CSDN学院"上线,视频中包含了从0开始逐行代码实现FFMpeg视频开发的过程,欢迎观看!链接地址:FFMpeg视频开发与应用基础--使用FFMpeg工具与SDK 工程代码地址:FFmpeg_Tutorial 经过了上篇调用FFMpeg SDK对视频进行编码的过程之后,我们可以比较容易地理解本篇的内容,即上一篇的逆过程--将H.264格式的裸码流解码为像素格式的图像信息. 1.FFMpeg视频

FFMPEG SDK流媒体开发2---分离.mp4等输入流音视频并且进行解码输出

对于FFMPEG SDK  提供的Demuxing 为我们实现多路复用  提供了很多方便,下面的案案例 实现的是 分离一个媒体文件的音频 视频流 并且解码输出 到  不同的文件中. 对于音频被还原回了 PCM格式  对于视频 被还原成了 YUV420等原生 格式 注意我用的FFMPEG SDK是最新版   API接口稍有改变. 每天更新 博客 记录自己学习的点点滴滴,写完了 上班去 #include "stdafx.h" /*******************************

android-Android 采集摄像头数据 , 通过ffmpeg推送流至服务器

问题描述 Android 采集摄像头数据 , 通过ffmpeg推送流至服务器 Android 采集摄像头数据 , 通过ffmpeg推送流, 通过AdobeMediaServer查看 , 为什么播放视频总是隔一段时间一缓冲 , 而且播放有延迟.求大神帮忙啊 AVFormatContext *ofmt_ctx; AVStream* video_st; //视音频流对应的结构体,用于视音频编解码. AVCodecContext* pCodecCtx; AVCodec* pCodec; AVPacket

编码-FFMPEG实时解码RTP传输的H264流视频花屏

问题描述 FFMPEG实时解码RTP传输的H264流视频花屏 自己用QT写的程序,在PC上采集视频编码RTP打包发送.如果发送给自己,然后用VLC播放的话是可以正常显示的(尽管延迟会不断增大,这个问题再待解决),但是用自己编的软件确无法正常显示,能看到一瞬间有部分画面正常,然后一会画面就糊掉了. 同样的代码, 我在树莓派上,用OPENMAX硬件加速编码,然后同样的打包方式发送,发送给树莓派自己或者给PC,都能正常地显示. 不知道这个是哪部分出了原因?到底是FFMPEG编码部分出问题,还是接收的代

FFMPEG SDK 开发介绍

FFMPEG SDK 开发介绍 1.简介:     ffmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序. 使用ffmpeg能够完成如下功能:parse,demux,decode,filter(preprocessing),encode,mux,stream和player等. 2.下载和编译:     下载地址:  http://ffmpeg.org/download.html     编译:        1)windows平台static library/sh

【FFMpeg视频开发与应用基础】二、调用FFmpeg SDK对YUV视频序列进行编码

<FFMpeg视频开发与应用基础--使用FFMpeg工具与SDK>视频教程已经在"CSDN学院"上线,视频中包含了从0开始逐行代码实现FFMpeg视频开发的过程,欢迎观看!链接地址:FFMpeg视频开发与应用基础--使用FFMpeg工具与SDK 工程代码地址:FFmpeg_Tutorial 视频由像素格式编码为码流格式是FFMpeg的一项基本功能.通常,视频编码器的输入视频通常为原始的图像像素值,输出格式为符合某种格式规定的二进制码流. 1.FFMpeg进行视频编码所需要的

FFMPEG SDK开发介绍

原文地址:FFMPEG SDK 开发介绍(原创)作者:阿东博客 本文是作者在使用ffmpeg sdk开发过程中的实际经验,现在与大家分享,欢迎学习交流. FFMPEG SDK 开发介绍 1.简介:     ffmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序. 使用ffmpeg能够完成如下功能:parse,demux,decode,filter(preprocessing),encode,mux,stream和player等. 2.下载和编译:     下载地址:

用FFMPEG SDK进行视频转码压缩时解决音视频不同步问题的方法

用FFMPEG SDK进行视频转码压缩的时候,转码成功后去看视频的内容,发现音视频是不同步的.这个的确是一个恼火的事情.我在用FFMPEG SDK做h264格式的FLV文件编码Filter的时候就碰到了这个问题.         经过研究发现,FFMPEG SDK写入视频的时候有两个地方用来控制写入的时间戳,一个是AvPacket, 一个是AvFrame. 在调用avcodec_encode_video的时候需要传入AvFrame的对象指针,也就是传入一帧未压缩的视频进行压缩处理,AvFrame

ffmpeg rtsp rtmp-Ubuntu上用FFmpeg将rtsp流转换成rtmp流出错!

问题描述 Ubuntu上用FFmpeg将rtsp流转换成rtmp流出错! 使用"ffmpeg -i rtsp://admin:12345@172.27.35.55 -f flv rtmp://172.27.35.2/live/stream"命令时出错 其中172.27.35.2是我电脑的IP,172.27.35.55是网络摄像机的IP 解决方案 你本地有LiveServer吗?https://github.com/winlinvip/simple-rtmp-server