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; }
cv::gpu::detail::VideoParser::VideoParser(VideoDecoder* videoDecoder, FrameQueue* frameQueue) : videoDecoder_(videoDecoder), frameQueue_(frameQueue), unparsedPackets_(0), hasError_(false) { CUVIDPARSERPARAMS params; memset(¶ms, 0, sizeof(CUVIDPARSERPARAMS)); params.CodecType = videoDecoder->codec(); params.ulMaxNumDecodeSurfaces = videoDecoder->maxDecodeSurfaces(); params.ulMaxDisplayDelay = 1; // this flag is needed so the parser will push frames out to the decoder as quickly as it can params.pUserData = this; params.pfnSequenceCallback = HandleVideoSequence; // Called before decoding frames and/or whenever there is a format change params.pfnDecodePicture = HandlePictureDecode; // Called when a picture is ready to be decoded (decode order) params.pfnDisplayPicture = HandlePictureDisplay; // Called whenever a picture is ready to be displayed (display order) cuSafeCall( cuvidCreateVideoParser(&parser_, ¶ms) ); }
VideoParser::VideoParser(VideoDecoder *pVideoDecoder, FrameQueue *pFrameQueue, CUcontext *pCudaContext): hParser_(0) { assert(0 != pFrameQueue); oParserData_.pFrameQueue = pFrameQueue; assert(0 != pVideoDecoder); oParserData_.pVideoDecoder = pVideoDecoder; oParserData_.pContext = pCudaContext; CUVIDPARSERPARAMS oVideoParserParameters; memset(&oVideoParserParameters, 0, sizeof(CUVIDPARSERPARAMS)); oVideoParserParameters.CodecType = pVideoDecoder->codec(); oVideoParserParameters.ulMaxNumDecodeSurfaces = pVideoDecoder->maxDecodeSurfaces(); oVideoParserParameters.ulMaxDisplayDelay = 1; // this flag is needed so the parser will push frames out to the decoder as quickly as it can oVideoParserParameters.pUserData = &oParserData_; oVideoParserParameters.pfnSequenceCallback = HandleVideoSequence; // Called before decoding frames and/or whenever there is a format change oVideoParserParameters.pfnDecodePicture = HandlePictureDecode; // Called when a picture is ready to be decoded (decode order) oVideoParserParameters.pfnDisplayPicture = HandlePictureDisplay; // Called whenever a picture is ready to be displayed (display order) CUresult oResult = cuvidCreateVideoParser(&hParser_, &oVideoParserParameters); assert(CUDA_SUCCESS == oResult); }