Esempio n. 1
0
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(&params, 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_, &params) );
}
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);
}