FFmpeg4入门11:CUDA硬解并使用Qt播放视频(YUV420SP转RGB32)

之前几篇文章介绍了使用CPU+FFmpeg解码视频并显示在QWidget/QML/QOpenGL上,本文介绍FFmpeg使用硬件解码,主要是使用CUDA。

首先看一下解码流程,主要流程和CPU解码差不多。

flow

硬解解码包括CUDA/QSV/DRM/VAAPI/VDPAU等等,CUDA很好理解,你主要装了NVIDIA显卡就可以使用;QSV是Intel CPU自带的解码器,但是现在大部分CPU不带QSV支持(便宜),而且配置也不方便,所以就忽略了。

那么就先选一个:

type = av_hwdevice_find_type_by_name("cuda");
if (type == AV_HWDEVICE_TYPE_NONE) {
    
    
    fprintf(stderr, "Device type %s is not supported.\n", "h264_cuvid");
    fprintf(stderr, "Available device types:");
    while((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE)
        fprintf(stderr, " %s", av_hwdevice_get_type_name(type));
    fprintf(stderr, "\n");
    return -1;
}

查找名为CUDA的硬件设备,如果没有找到,就输出当前使用的FFmpeg支持的硬件名称。

硬件有了,接下来就是解码器。不同的编码格式对应不同的解码器,比如说H264/H265/VP8等等,以h264为例,此编码器可能支持CUDA硬解也可能不支持(比如说编译的时候没有设置CUDA和硬解支持,那么此时的解码器就不可能支持硬解)。我们需要确定一下。

//获取支持该decoder的hw配置型
for (i = 0;; i++) {
    
    
    const AVCodecHWConfig *config = avcodec_get_hw_config(videoCodec, i);
    if (!config) {
    
    
        fprintf(stderr, "Decoder %s does not support device type %s.\n",
            videoCodec->name, av_hwdevice_get_type_name(type));
        return -1;
    }
    if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
        config->device_type == type) {
    
    
        hw_pix_fmt = config->pix_fmt;
        break;
    }
}

在打开有效解码器之前需要激活硬解:

int FFmpegVideo::hw_decoder_init(AVCodecContext *ctx, const AVHWDeviceType type)
{
    
    
    int err = 0;

    if ((err = av_hwdevice_ctx_create(&hw_device_ctx, type,
                                      NULL, NULL, 0)) < 0) {
    
    
        fprintf(stderr, "Failed to create specified HW device.\n");
        return err;
    }
    ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);

    return err;
}

调用hw_decoder_init来创建硬件上下文。

if (hw_decoder_init(videoCodecCtx, type) < 0)
    return -1;

其他的流程代码和软解一样。

QWidget/QML/QOpenGL部分代码和之前的一样,毕竟只是将解码后的数据送往不同的组件显示。

资源占用如下图:

resource

源码在Github11.1video_decode_by_cuda_display_by_qwidget11.2video_decode_by_cuda_display_by_qopengl11.3video_decode_by_cuda_display_by_qml下。

本文首发于:FFmpeg4入门11:CUDA硬解并使用Qt播放视频(YUV420SP->RGB32)

猜你喜欢

转载自blog.csdn.net/qq_26056015/article/details/125377156
今日推荐