Примеры кодирования ошибок с помощью "Intel® Quick Sync Video H.264 Encoder MFT" - PullRequest
0 голосов
/ 10 октября 2019

Я использую mfnet (http://mfnet.sourceforge.net/)MediaFoundation, Версия = 3.1.0.0. Я получаю список изображений из файлов, делаю преобразование в NV12, и после этого я пытаюсь поместить их в кодировщик, но ProcessInput возвращает6 раз MF_E_NOTACCEPTING, после этого MFTOutputStreamInfo outStreamInfo; hr = transform.GetOutputStreamInfo (0, out outStreamInfo); returns ProvidesSamples

        int mFActivatesCount;
        IMFActivate[] mFActivates = null;
        Guid inFormat = MFMediaType.NV12;
        Guid outFormat = MFMediaType.H264;
        object comObject;
        string nameTransform;

        MFTRegisterTypeInfo registerTypeInfoOut = new MFTRegisterTypeInfo();
        registerTypeInfoOut.guidMajorType = MFMediaType.Video;
        registerTypeInfoOut.guidSubtype = outFormat;

        MFTRegisterTypeInfo registerTypeInfoIn = new MFTRegisterTypeInfo();
        registerTypeInfoIn.guidMajorType = MFMediaType.Video;
        registerTypeInfoIn.guidSubtype = inFormat;

        hr = MFExtern.MFTEnumEx(TransformCategoryGuids.VideoEncoder, MFT_EnumFlag.Hardware,
            registerTypeInfoIn, registerTypeInfoOut, out mFActivates, out mFActivatesCount);
        if (mFActivatesCount > 0)
        {
            int index_activator = 0;
            Guid clsid;
            hr = mFActivates[index_activator].GetGUID(MFAttributesClsid.MFT_TRANSFORM_CLSID_Attribute, out clsid);
            hr = mFActivates[index_activator].GetAllocatedString(MFAttributesClsid.MFT_FRIENDLY_NAME_Attribute, out nameTransform);
            hr = mFActivates[index_activator].ActivateObject(typeof(IMFTransform).GUID, out comObject);
            retTransform = comObject as IMFTransform;
            IMFAttributes attributes;
            hr = retTransform.GetAttributes(out attributes);
            hr = attributes.SetUINT32(MFAttributesClsid.MF_TRANSFORM_ASYNC_UNLOCK, 1);
            hr = attributes.SetUINT32(MFAttributesClsid.MF_LOW_LATENCY, 1);
            hr = attributes.SetBoolean(MFAttributesClsid.MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true);


            MFInt cIn = new MFInt(), cOut = new MFInt();
            hr = retTransform.GetStreamCount(cIn, cOut);
            IMFMediaType mediaOutType, mediaInType;
            hr = MFExtern.MFCreateMediaType(out mediaOutType);
            hr = mediaOutType.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Video);
            hr = mediaOutType.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, outFormat);
            hr = mediaOutType.SetUINT32(MFAttributesClsid.MF_MT_AVG_BITRATE, 10000000);
            hr = mediaOutType.SetUINT32(MFAttributesClsid.MF_MT_MPEG2_PROFILE, profile.Profile);
            hr = mediaOutType.SetUINT32(MFAttributesClsid.MF_MT_MPEG2_LEVEL, 40);
            hr = mediaOutType.SetUINT32(MFAttributesClsid.MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY, 0);
            hr = MFExtern.MFSetAttributeSize(mediaOutType, MFAttributesClsid.MF_MT_FRAME_SIZE, Width, Height);
            hr = MFExtern.MFSetAttributeRatio(mediaOutType, MFAttributesClsid.MF_MT_FRAME_RATE, h264fps, 1);
            hr = MFExtern.MFSetAttributeRatio(mediaOutType, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
            hr = mediaOutType.SetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, (int)VideoInterlaceMode.Progressive);
            hr = retTransform.SetOutputType(0, mediaOutType, MFTSetTypeFlags.None);
            MFError.ThrowExceptionForHR(hr);

            hr = MFExtern.MFCreateMediaType(out mediaInType);
            hr = mediaInType.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Video);
            hr = mediaInType.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, inFormat);
            hr = MFExtern.MFSetAttributeSize(mediaInType, MFAttributesClsid.MF_MT_FRAME_SIZE, Width, Height);
            hr = MFExtern.MFSetAttributeRatio(mediaInType, MFAttributesClsid.MF_MT_FRAME_RATE, h264fps, 1);
            hr = MFExtern.MFSetAttributeRatio(mediaInType, MFAttributesClsid.MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
            //hr = mediaInType.SetUINT32(MFAttributesClsid.MF_MT_SAMPLE_SIZE, 777600);
            //hr = mediaInType.SetUINT32(MFAttributesClsid.MF_MT_AVG_BITRATE, encoder_bitrate);
            hr = mediaInType.SetUINT32(MFAttributesClsid.MF_MT_DEFAULT_STRIDE, Width);
            hr = mediaInType.SetUINT32(MFAttributesClsid.MF_MT_FIXED_SIZE_SAMPLES, 1);
            hr = mediaInType.SetUINT32(MFAttributesClsid.MF_MT_INTERLACE_MODE, (int)VideoInterlaceMode.Progressive);
            hr = mediaInType.SetUINT32(MFAttributesClsid.MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
            hr = retTransform.GetInputAvailableType(0, 0, out mediaInType);
            hr = retTransform.SetInputType(0, mediaInType, 0);
            MFError.ThrowExceptio`enter code here`nForHR(hr);
            hr = retTransform.ProcessMessage(MFTMessageType.CommandFlush, IntPtr.Zero);
            hr = retTransform.ProcessMessage(MFTMessageType.NotifyBeginStreaming, IntPtr.Zero);
            hr = retTransform.ProcessMessage(MFTMessageType.NotifyStartOfStream, IntPtr.Zero);

            COMBase.SafeRelease(mediaInType);
            COMBase.SafeRelease(mediaOutType);
            COMBase.SafeRelease(attributes);
            cIn = null;
            cOut = null;
            mFActivates = null;
            return HResult.S_OK;
        }
        retTransform = null;
        return HResult.S_FALSE;
    }`

Инициализация проходит без ошибок.

Код кодировки:

        outH264Sample = null;
        if (transform == null)
            return HResult.E_FAIL;

        hr = sampleNV12.SetSampleTime(time_stamp_video_encode);
        hr = sampleNV12.SetSampleDuration(punAverageTimePerFrameVideo);
        time_stamp_video_encode = frame_count_video_encode * punAverageTimePerFrameVideo;

        hr = transform.ProcessInput(0, sampleNV12, 0);
        MFTOutputStatusFlags encoderTransformStatus;
        ProcessOutputStatus outputStatus;

        hr = transform.GetOutputStatus(out encoderTransformStatus);
        if(encoderTransformStatus == MFTOutputStatusFlags.None)
        {
            return HResult.S_OK;
        }
        if (encoderTransformStatus == MFTOutputStatusFlags.SampleReady)
        {
            MFTOutputStreamInfo outStreamInfo;
            hr = transform.GetOutputStreamInfo(0, out outStreamInfo);
            if (outStreamInfo.dwFlags != MFTOutputStreamInfoFlags.ProvidesSamples)
            {
                IMFMediaBuffer pBuffer = null;
                hr = MFExtern.MFCreateMemoryBuffer(outStreamInfo.cbSize, out pBuffer);
                hr = pBuffer.SetCurrentLength(outStreamInfo.cbSize);
                outStreamInfo = default(MFTOutputStreamInfo);
                hr = MFExtern.MFCreateSample(out outH264Sample);
                hr = outH264Sample.AddBuffer(pBuffer);
                MFTOutputDataBuffer odb = new MFTOutputDataBuffer();
                odb.pSample = Marshal.GetIUnknownForObject(outH264Sample);
                odb.dwStreamID = 0;
                odb.dwStatus = 0;
                odb.pEvents = null;

                MFTOutputDataBuffer[] mftOutputData = { odb };
                hr = transform.ProcessOutput(MFTProcessOutputFlags.None, 1, mftOutputData, out outputStatus);

                if (hr == HResult.MF_E_TRANSFORM_NEED_MORE_INPUT)
                {
                    hr = transform.ProcessMessage(MFTMessageType.CommandDrain, IntPtr.Zero);
                    COMBase.SafeRelease(pBuffer);
                    Marshal.Release(odb.pSample);
                    outStreamInfo = default(MFTOutputStreamInfo);
                    return HResult.S_OK;
                }
                if (hr == HResult.S_OK)
                {
                    frame_count_video_encode++;
                    COMBase.SafeRelease(pBuffer);
                    Marshal.Release(odb.pSample);
                    outStreamInfo = default(MFTOutputStreamInfo);
                    return HResult.S_OK;
                }
                outStreamInfo = default(MFTOutputStreamInfo);
                Marshal.Release(odb.pSample);
                COMBase.SafeRelease(pBuffer);
            }
        }
        return HResult.E_FAIL;
    }
`

Помощь, что нужно сделать?

...