FFmpeg视频解码硬件加速

《音视频应用开发系列文章目录》

ffmpeg支持的硬件解码器

enum AVHWDeviceType {
    AV_HWDEVICE_TYPE_NONE,
    AV_HWDEVICE_TYPE_VDPAU,
    AV_HWDEVICE_TYPE_CUDA,
    AV_HWDEVICE_TYPE_VAAPI,
    AV_HWDEVICE_TYPE_DXVA2,
    AV_HWDEVICE_TYPE_QSV,
    AV_HWDEVICE_TYPE_VIDEOTOOLBOX,
    AV_HWDEVICE_TYPE_D3D11VA,
    AV_HWDEVICE_TYPE_DRM,
    AV_HWDEVICE_TYPE_OPENCL,
    AV_HWDEVICE_TYPE_MEDIACODEC,
};

获取当前环境支持的硬件解码器

std::vector get_vdec_support_hwdevices() {

	std::vector hwdevs;
	hwdevs.clear();
	enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE;
	while ((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE) {

		hwdevs.push_back(av_hwdevice_get_type_name(type));
	}
	return hwdevs;
}

CPU解码流程

avformat_open_input -> 
avformat_find_stream_info -> 
avcodec_open2 -> 
LOOP:
	av_read_frame -> 
	avcodec_send_packet -> 
	avcodec_receive_frame

GPU解码流程

相比于CPU解码同样都是使用AVCodec为解码器结构体。GPU解码需要多填充AVCodec两个成员get_format和hw_device_ctx。

get_format 用于获取硬件像素格式的回调函数

hw_device_ctx 硬件解码器设备上下文

avformat_open_input -> 
avformat_find_stream_info -> 
avcodec_get_hw_config -> (从AVCodec获取对应硬件编码器的配置以取得hw_pix_fmt)
av_hwdevice_ctx_create -> (创建解码器设备上下文,用于填充AVCodec的hw_device_ctx)
register AVCodecContext's callback function:get_format -> (注册回调函数,在解码的时候会调用)
avcodec_open2 -> 
LOOP:
	av_read_frame -> 
	avcodec_send_packet -> 
	avcodec_receive_frame -> 
	av_hwframe_transfer_data (从GPU拷贝数据到CPU或则从CPU拷贝数据到GPU)

回调函数get_format

static enum AVPixelFormat get_hw_format(AVCodecContext *ctx, const enum AVPixelFormat *pix_fmts) {

	const enum AVPixelFormat *p;
	for (p = pix_fmts; *p != -1; p++) {
		if (*p == g_hw_pix_fmt)
			return *p;
	}
	return AV_PIX_FMT_NONE;
}

代码示例

参考《FFmpeg拉流器》

 

你可能感兴趣的:(音视频应用开发)