bool VideoDecoderCUDAPrivate::createCUVIDParser() { cudaVideoCodec cudaCodec = mapCodecFromFFmpeg(codec_ctx->codec_id); if (cudaCodec == -1) { qWarning("CUVID does not support the codec"); available = false; return false; } if (parser) { cuvidDestroyVideoParser(parser); parser = 0; } //lavfilter check level C CUVIDPARSERPARAMS parser_params; memset(&parser_params, 0, sizeof(CUVIDPARSERPARAMS)); parser_params.CodecType = cudaCodec; /*! * CUVIDPICPARAMS.CurrPicIdx <= kMaxDecodeSurfaces. * CUVIDPARSERDISPINFO.picture_index <= kMaxDecodeSurfaces * HandlePictureDecode must check whether CUVIDPICPARAMS.CurrPicIdx is in use * HandlePictureDisplay must mark CUVIDPARSERDISPINFO.picture_index is in use * If a frame is unmapped, mark the index not in use * */ parser_params.ulMaxNumDecodeSurfaces = nb_dec_surface; //parser_params.ulMaxDisplayDelay = 4; //? parser_params.pUserData = this; parser_params.pfnSequenceCallback = VideoDecoderCUDAPrivate::HandleVideoSequence; parser_params.pfnDecodePicture = VideoDecoderCUDAPrivate::HandlePictureDecode; parser_params.pfnDisplayPicture = VideoDecoderCUDAPrivate::HandlePictureDisplay; parser_params.ulErrorThreshold = 0;//!wait for key frame //parser_params.pExtVideoInfo qDebug("~~~~~~~~~~~~~~~~extradata: %p %d", codec_ctx->extradata, codec_ctx->extradata_size); /*! * NOTE: DO NOT call h264_extradata_to_annexb here if use av_bitstream_filter_filter * because av_bitstream_filter_filter will call h264_extradata_to_annexb and marks H264BSFContext has parsed * h264_extradata_to_annexb will not mark it * LAVFilter's */ #if FILTER_ANNEXB_CUVID memset(&extra_parser_info, 0, sizeof(CUVIDEOFORMATEX)); // nalu // TODO: check mpeg, avc1, ccv1? (lavf) if (codec_ctx->extradata && codec_ctx->extradata_size >= 6) { int ret = h264_extradata_to_annexb(codec_ctx, FF_INPUT_BUFFER_PADDING_SIZE); if (ret >= 0) { qDebug("%s @%d ret %d, size %d", __FUNCTION__, __LINE__, ret, codec_ctx->extradata_size); memcpy(extra_parser_info.raw_seqhdr_data, codec_ctx->extradata, codec_ctx->extradata_size); extra_parser_info.format.seqhdr_data_length = codec_ctx->extradata_size; } } parser_params.pExtVideoInfo = &extra_parser_info; #endif checkCudaErrors(cuvidCreateVideoParser(&parser, &parser_params)); //lavfilter: cuStreamCreate force_sequence_update = true; //DecodeSequenceData() return true; }
bool VideoDecoderCUDAPrivate::releaseCuda() { available = false; if (!can_load) return true; if (dec) { cuvidDestroyDecoder(dec); dec = 0; } if (parser) { cuvidDestroyVideoParser(parser); parser = 0; } if (stream) { cuStreamDestroy(stream); stream = 0; } if (host_data) { cuMemFreeHost(host_data); host_data = 0; host_data_size = 0; } if (vid_ctx_lock) { cuvidCtxLockDestroy(vid_ctx_lock); vid_ctx_lock = 0; } if (cuctx) { checkCudaErrors(cuCtxDestroy(cuctx)); } // TODO: dllapi unload return true; }
bool VideoDecoderCUDAPrivate::releaseCuda() { if (!can_load) return true; if (dec) { cuvidDestroyDecoder(dec); dec = 0; } if (parser) { cuvidDestroyVideoParser(parser); parser = 0; } if (stream) { cuStreamDestroy(stream); stream = 0; } cuvidCtxLockDestroy(vid_ctx_lock); if (cuctx) { checkCudaErrors(cuCtxDestroy(cuctx)); } return true; }
~VideoParser() { cuvidDestroyVideoParser(parser_); }