凡科网站自己如何做,apache php wordpress,互联网公司 网站,wordpress用php版本号1 前言
上一篇文章FFmpeg下载安装及Windows开发环境设置介绍了FFmpeg的下载安装及环境配置#xff0c;本文介绍最简单的FFmpeg视频解码示例。
2 视频解码过程
本文只讨论视频解码。 FFmpeg视频解码的过程比较简单#xff0c;实际就4步#xff1a;
打开媒体流获取…1 前言
上一篇文章FFmpeg下载安装及Windows开发环境设置介绍了FFmpeg的下载安装及环境配置本文介绍最简单的FFmpeg视频解码示例。
2 视频解码过程
本文只讨论视频解码。 FFmpeg视频解码的过程比较简单实际就4步
打开媒体流获取编码格式循环获取解码帧显示图像关闭流
实际上前两步即已实现视频解码。
2.1 打开媒体流获取编码格式
1 打开流文件 这个函数avformat_open_input打开一个媒体流并读取其头信息对于实时流或者不包含头信息的视频流此函数通过几帧数据分析以获取其信息 此函数支持的媒体流非常广泛包括本地视频文件、RTSP、TCP码流、UDP码流等等都支持。
m_pFmtCtx nullptr;
ret avformat_open_input(m_pFmtCtx, sVideoUrl.c_str(), nullptr, nullptr);2 在媒体流中寻找视频流 一个媒体流中可能包含了视频、音频、字幕、文本等多个流到底哪个是我们要的视频流需要首先确定这个实际有两种方法方法1是遍历媒体中所有的流检查流类型判断哪个是视频流找到视频流后获取其解码器 m_nIndexVideo -1;AVCodec* pAVCodec;//method 1for (i 0; i m_pFmtCtx-nb_streams; i){if (m_pFmtCtx-streams[i]-codecpar-codec_type AVMEDIA_TYPE_VIDEO){m_nIndexVideo i;break;}}if (m_nIndexVideo 0)return false;pAVCodec (AVCodec*)avcodec_find_decoder(m_pFmtCtx-streams[m_nIndexVideo]-codecpar-codec_id);方法2就更简单直接av_find_best_stream按视频格式查找最符合的流并直接返回视频流序号及相应的解码器 m_nIndexVideo av_find_best_stream(m_pFmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, (const AVCodec**)pAVCodec, 0);此两种方法结果是同样的选择其中一种方法使用即可。 3 分配解码器 根据视频流解码格式分配及设置解码器此处得到的解码器m_pAVCodecCtx即可用于后续的连续帧的解码了 m_pAVCodecCtx avcodec_alloc_context3(pAVCodec);if (m_pAVCodecCtx nullptr)return false;ret avcodec_parameters_to_context(m_pAVCodecCtx, m_pFmtCtx-streams[m_nIndexVideo]-codecpar);4 准备解码 调用函数avcodec_open2后即可开始解码 ret avcodec_open2(m_pAVCodecCtx, pAVCodec, nullptr);至此一个媒体流的视频流解码工作就准备好了可以进行获取和解码视频帧了。
2.2 获取解码帧
获取解码帧的过程是取一个原始包(AVPacket)用以上的解码器从这个包里解出视频帧(AVFrame具体过程如下 1 用函数av_read_frame从流中取出一个帧包此包为流中的原始数据未解码的。 前面说过一个媒体流中可能包含了多个流所以av_read_frame获取的数据包不一定是我们想要的视频流包需要根据这个包所在流的序号来判断是不是属于前面确定视频流的包。
while (1)
{ret av_read_frame(m_pFmtCtx, m_pPkt);if (ret 0)return nullptr;if (m_pPkt-stream_index m_nIndexVideo)break;
}2 解码这个包获取一帧解码图像 采用如下两个函数的组合用前面获得的解码器m_pAVCodecCtx对这个包进行解码获得AVFrame。 avcodec_send_packet(m_pAVCodecCtx, m_pPkt);avcodec_receive_frame(m_pAVCodecCtx, m_pFrame);此时获得的m_pFrame即为已解码出的一幅视频帧为一个AVFrame结构此结构中包含了图像数据、宽高、格式等等信息可以用于显示、存储等后续工作。
2.3 显示图像帧
有很多软件架构支持直接对AVFrame结构进行显示如SDL、D3DX等等。 我们这里用最基本的RGB图像方式来显示这个AVFrame但AVFrame的图像数据大多数是YUV格式需要做YUV-RGB转换当然可以自己找公式转换实际上FFmpeg对此也提供了方便的转换方法sws_scale int ret;int wid, hei;wid pFrame-width;hei pFrame-height;if (m_pSwsCtx nullptr){m_pSwsCtx sws_getContext(wid, hei, (AVPixelFormat)pFrame-format, wid, hei, AV_PIX_FMT_RGB24, SWS_POINT, nullptr, nullptr, nullptr);}uint8_t* data[1];data[0] pDib;int lines[1] { wid * 3 };ret sws_scale(m_pSwsCtx, pFrame-data, pFrame-linesize, 0, hei, data, lines);这样转出的pDib就是24位RGB的图像了之后的显示此处就不再赘述了。
2.4 关闭流
以上打开的流以及分配的各种资源最后不用时记得要释放如 if (m_pFmtCtx ! nullptr){avformat_close_input(m_pFmtCtx);m_pFmtCtx nullptr;}if (m_pAVCodecCtx ! nullptr){avcodec_close(m_pAVCodecCtx);avcodec_free_context(m_pAVCodecCtx);m_pAVCodecCtx nullptr;}3 示例
下图为程序运行视频解码结果。 以上代码的完整工程供参考https://download.csdn.net/download/hangl_ciom/88152736