在我的 C 程序中使用 h264_cuvid 解码器解码视频时,cuda 无效资源句柄

问题描述

我尝试在我的ffmpeg解码程序中使用GPU加速,通过命令查看ffmpeg的编解码器:ffmpeg -codecs | grep nv显示可以使用h264_cuvid解码器(其实我已经用过ffmpeg命令使用硬件加速对测试视频进行编码和解码,结果一切都很好),但是当我在我的程序中使用解码器时

AVCodec *pCodec = avcodec_find_decoder_by_name("h264_cuvid");

这是我计划的一部分

void FFMPEGCodec::initDecoder()
{
    AVCodec *pCodec = avcodec_find_decoder(AV_CODEC_ID_H264);
    if (!pCodec) {
        LOG("Codec decoder not found\n");
        exit(1);
    }

    pCodecCtx = avcodec_alloc_context3(pCodec);
    if (!pCodecCtx) {
        LOG("Could not allocate video codec context\n");
        exit(1);
    }

    pCodecCtx->width = gConfig->totalWidth;
    pCodecCtx->height = gConfig->totalHeight;
    pCodecCtx->has_b_frames = 0;

    if (avcodec_open2(pCodecCtx,pCodec,NULL) < 0) {
        LOG("Could not open codec\n");
        exit(1);
    }

    if(_x264rgb){
        //used to convert GBRP frame to RGB image.
        convertCtx = sws_getContext(gConfig->totalWidth,gConfig->totalHeight,AV_PIX_FMT_GBRP,gConfig->totalWidth,AV_PIX_FMT_RGB24,SWS_FAST_BILINEAR,NULL,NULL); 
    } else {
        //used to convert YUV frame to RGB image.
        convertCtx = sws_getContext(gConfig->totalWidth,AV_PIX_FMT_YUV420P,NULL); 
    }

    if(convertCtx == NULL){
        LOG("Failed to get SwsContext\n");
        exit(1);
    }

    //when using x264rgb,it's actually GBRP frame,//just don't want to define another variable
    yuvFrame = av_frame_alloc();
    if (!yuvFrame) {
        LOG("Failed to allocate yuv frame\n");
        exit(1);
    }

    rgbFrame = av_frame_alloc();
    if (!rgbFrame) {
        LOG("Failed to allocate rgb frame\n");
        exit(1);
    }

    rgbFrame->format = AV_PIX_FMT_RGB24;
    rgbFrame->width  = pCodecCtx->width;
    rgbFrame->height = pCodecCtx->height;
 
    int ret = av_image_alloc(rgbFrame->data,rgbFrame->linesize,rgbFrame->width,rgbFrame->height,32);
    if (ret < 0) {
        LOG("Failed to allocate raw picture buffer\n");
        exit(1);
    }
}   

int FFMPEGCodec::decode(byte* pktData,int pktSize,byte* imgData)
{
    int ret = 0,got_packet = 0;
    AVPacket pkt;
    av_init_packet(&pkt);
    pkt.data = pktData;
    pkt.size = pktSize;

    // decode video frame
    ret = avcodec_decode_video2(pCodecCtx,yuvFrame,&got_packet,&pkt);
    if (ret < 0) {
        LOG("Error decoding frame\n");
        return -1;
    }

    sws_scale(convertCtx,yuvFrame->data,yuvFrame->linesize,pCodecCtx->height,rgbFrame->data,rgbFrame->linesize);
    
    if (got_packet) {
        int width = pCodecCtx->width,height = pCodecCtx->height;
        int fsize = rgbFrame->linesize[0] * rgbFrame->height;
        int size = 54 + fsize;

        byte bmp_file_header[14] = { 'B','M',54,};
        byte bmp_info_header[40] = { 40,1,24,};
        byte bmp_pad[3] = { 0,0 };

        bmp_file_header[2] = (unsigned char)size;
        bmp_file_header[3] = (unsigned char)(size >> 8);
        bmp_file_header[4] = (unsigned char)(size >> 16);
        bmp_file_header[5] = (unsigned char)(size >> 24);

        bmp_info_header[4] = (unsigned char)(width);
        bmp_info_header[5] = (unsigned char)(width >> 8);
        bmp_info_header[6] = (unsigned char)(width >> 16);
        bmp_info_header[7] = (unsigned char)(width >> 24);
        bmp_info_header[8] = (unsigned char)(height);
        bmp_info_header[9] = (unsigned char)(height >> 8);
        bmp_info_header[10] = (unsigned char)(height >> 16);
        bmp_info_header[11] = (unsigned char)(height >> 24);

        memcpy(imgData,bmp_file_header,14);
        memcpy(imgData + 14,bmp_info_header,40);
        memcpy(imgData + 54,rgbFrame->data[0],fsize);
        ret = size;
    }
    av_free_packet(&pkt);

    return ret;
}

编译后运行程序,解码器报错:

ctx->cvdl->cuvidDecodePicture(ctx->cudecoder,picparams) Failed -> CUDA_ERROR_INVALID_HANDLE: invalid resource handle 调用函数 avcodec_decode_video2

我不知道为什么会出现这个错误,顺便说一下,我使用的是 GTX1060 6G(对不起,我的母语不是英语)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)