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 VideoDecoderCUDA::prepare() { //TODO: destroy decoder DPTR_D(VideoDecoderCUDA); if (!d.codec_ctx) { qWarning("AVCodecContext not ready"); return false; } // d.available is true if cuda decoder is ready if (!d.can_load) { qWarning("VideoDecoderCUDA::prepare(): CUVID library not available"); return false; } if (!d.isLoaded()) //cuda_api return false; // max decoder surfaces is computed in createCUVIDDecoder. createCUVIDParser use the value return d.createCUVIDDecoder(mapCodecFromFFmpeg(d.codec_ctx->codec_id), d.codec_ctx->coded_width, d.codec_ctx->coded_height) && d.createCUVIDParser(); }
bool VideoDecoderCUDA::prepare() { //TODO: destroy decoder DPTR_D(VideoDecoderCUDA); if (!d.codec_ctx) { qWarning("AVCodecContext not ready"); return false; } // d.available is true if cuda decoder is ready if (!d.can_load) { qWarning("VideoDecoderCUDA::prepare(): CUVID library not available"); return false; } if (!d.isLoaded()) //cuda_api return false; if (!d.cuctx) d.initCuda(); d.bitstream_filter_ctx = av_bitstream_filter_init("h264_mp4toannexb"); Q_ASSERT_X(d.bitstream_filter_ctx, "av_bitstream_filter_init", "Unknown bitstream filter"); // max decoder surfaces is computed in createCUVIDDecoder. createCUVIDParser use the value return d.createCUVIDDecoder(mapCodecFromFFmpeg(d.codec_ctx->codec_id), d.codec_ctx->coded_width, d.codec_ctx->coded_height) && d.createCUVIDParser(); }