1、背景
上篇文章我们详细阐述了windows环境下使用ffmpeg进行软解码的步骤,并给出了完整代码。 FFmpeg 4.x 从入门到精通(一)—— QT 中如何用 FFmpeg 实现软件解码
接下来这篇文章继续进行深入,带大家学习使用FFmpeg实现windows下的硬解码。
FFmpeg下载地址(粉丝免费下载): download.csdn.net/download/u0…
本文的语言环境基于C++,界面部分是 QT。
2、流程分析
老规矩,在开始看代码之前,我们必须先了解下ffmpeg硬解的常规流程:
红色的部分是和软解的区别。
虽然有些函数在第一篇文章已经解释了,但是为了使文章显得完整,因为本文也会再讲一遍。
1.1 avformat_open_input
为 AVFormatContext 分配空间,打开输入的视频数据并且探测视频的格式,这个函数里面包含了复杂的格式解析与探测算法,可解析的内容包括:视频流、音频流、视频流参数、音频流参数、视频帧索引等。用雷神的话说就是 可以算作FFmpeg的“灵魂”
。
1.2 avformat_find_stream_info
获取多媒体流的信息,包括码流、帧率、时长等信息。但是有些早期格式或者裸流数据它的索引并没有放到头当中,因此需要在后面进行探测。注意一个视频文件中可能会同时包括视频文件、音频文件、字幕文件等多个媒体流。
1.3 av_find_best_stream
当视频被解封装出来后,需要分开处理音频和视频,需要找到对应的音频流和视频流,获取音视频对应的stream_index。
1.4 enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name)
对于硬解码来说就不能使用avcodec_find_decoder
方法来查找解码器了。而是使用av_hwdevice_find_type_by_name
方法。要知道avcodec_find_decoder
根据 AVCodecID 查找,比如我们要解码H264,那入参就是AV_CODEC_ID_H264
,找到先注册的decoder就退出了,可能得到的这个解码器不能去解码AV_CODEC_ID_VP6
文件。最主要的是:同一个 AVCodecID 可能对应多个不同的解码器 (AVCodec),他们有不同的 AVCodec.name。
但是比如说你想在windows下使用dxva
解码,不管视频源是h264、H265,使用av_hwdevice_find_type_by_name
函数,入参是dxva
就行,得到的解码器就可以解H264和H265(当然前提是你的解码器支持解码这两种编码)。
所以说这是两个完全不同的方法,可能看起来类似,但千万不要被它迷惑。
【学习地址】: FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【文章福利】:免费领取更多音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击 1079654574 加群领取哦~
1.5 const AVCodecHWConfig *avcodec_get_hw_config(const AVCodec *codec, int index);
获取到该解码器codec的硬件属性,比如可以支持的目标像素格式等。
1.6 avcodec_alloc_context3
创建AVCodecContext并分配空间。
1.7 avcodec_parameters_to_context
该函数用于将流里面的参数,也就是AVStream里面的参数直接复制到AVCodecContext的上下文当中,执行真正的内容拷贝。avcodec_parameters_to_context()是新的API,替换了旧版本的avcodec_copy_context()。
1.8 av_hwdevice_ctx_create
初始化硬件,打开硬件,创建硬件设备相关的上下文信息AVHWDeviceCont