windows-phone-8.1 - هواتف - ويندوز فون 10



ويندوز فون 8.1 مؤسسة الإعلام H264 ماكس القرار (1)

أحاول ترميز فيديو في ويندوز فون 8.1 باستخدام مكتبة ميديا ​​فونداتيون وكاتب بالوعة.

لقد تمكنت من تحقيق ذلك من خلال تعيين MFVideoFormat_H264 باسم MF_MT_SUBTYPE لإخراج الوسائط بلدي واستخدام قرارات مثل 720P و 480 P ..

ولكن عند تغيير القرار إلى 1920x1080 (أو 1920x1088) أحصل على خطأ Incorrect Parameter . لذلك أعتقد أن أقصى قرار ل H.264 الترميز هو 1280x720.

حاولت تغيير الترميز ل هفيك أو MPEG2، الخ ... ولكن لا حظ.

هذا هو رمز كبب حيث أنا إعداد نوع الإخراج وإضافته إلى دفق:

// Setup the output video type   

ComPtr<IMFMediaType> spvideoTypeOut;
CHK(MFCreateMediaType(&spvideoTypeOut));
CHK(spvideoTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));

GUID _vformat =  MFVideoFormat_H264;

CHK(spvideoTypeOut->SetGUID(MF_MT_SUBTYPE, _vformat));
CHK(spvideoTypeOut->SetUINT32(MF_MT_AVG_BITRATE, _bitrate));
CHK(spvideoTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
CHK(MFSetAttributeSize(spvideoTypeOut.Get(), MF_MT_FRAME_SIZE, _width, _height));
CHK(MFSetAttributeRatio(spvideoTypeOut.Get(), MF_MT_FRAME_RATE, framerate, 1));
CHK(MFSetAttributeRatio(spvideoTypeOut.Get(), MF_MT_PIXEL_ASPECT_RATIO, ASPECT_NUM, ASPECT_DENOM));

CHK(_spSinkWriter->AddStream(spvideoTypeOut.Get(), &_streamIndex));

وهذا هو المكان الذي إعداد نوع الإدخال:

// Setup the input video type   

    ComPtr<IMFMediaType> spvideoTypeIn;
    CHK(MFCreateMediaType(&spvideoTypeIn));
    CHK(spvideoTypeIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
    CHK(spvideoTypeIn->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32));
    CHK(spvideoTypeIn->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
    CHK(MFSetAttributeSize(spvideoTypeIn.Get(), MF_MT_FRAME_SIZE, _width, _height));
    CHK(MFSetAttributeRatio(spvideoTypeIn.Get(), MF_MT_FRAME_RATE, framerate, 1));
    CHK(MFSetAttributeRatio(spvideoTypeIn.Get(), MF_MT_PIXEL_ASPECT_RATIO, ASPECT_NUM, ASPECT_DENOM));

    CHK(_spSinkWriter->SetInputMediaType(_streamIndex, spvideoTypeIn.Get(), nullptr));

    CHK(_spSinkWriter->BeginWriting());

لإضافة عينات إلى كاتب بالوعة أنا باستخدام هذه الوظيفة، وهذا هو المكان الذي يحدث الاستثناء:

void PictureWriter::AddFrame(const Platform::Array<uint8>^ videoFrameBuffer, int imageWidth, int imageHeight)
{
    // Create a media sample   
    ComPtr<IMFSample> spSample;
    CHK(MFCreateSample(&spSample));
    CHK(spSample->SetSampleDuration(_duration));
    CHK(spSample->SetSampleTime(_hnsSampleTime));

    _hnsSampleTime += _duration;

    // Add a media buffer
    ComPtr<IMFMediaBuffer> spBuffer;
    CHK(MFCreateMemoryBuffer(_bufferLength, &spBuffer));
    CHK(spBuffer->SetCurrentLength(_bufferLength));
    CHK(spSample->AddBuffer(spBuffer.Get()));

    // Copy the picture into the buffer
    unsigned char *pbBuffer = nullptr;
    CHK(spBuffer->Lock(&pbBuffer, nullptr, nullptr));
    BYTE* buffer = (BYTE*)videoFrameBuffer->begin() + 4 * imageWidth * (imageHeight - 1);
    CHK(MFCopyImage(pbBuffer + 4 * _width * (_height - imageHeight),
        4 * _width, buffer, -4 * imageWidth, 4 * imageWidth, imageHeight));

CHK(spBuffer->Unlock());

    // Write the media sample   
    CHK(_spSinkWriter->WriteSample(_streamIndex, spSample.Get()));
}

لماذا تعتقد أنني أحصل على الاستثناء وكيف يمكنني إصلاح ذلك؟

شكرا لكم.


وجدت الحل من خلال البحث عن معدلات البت الافتراضية لكل قرار،

1080p يعمل مع معدل بت 5.0 ميغابايت في الثانية،

1600x900 يعمل مع معدل بت 2.5 ميغابايت في الثانية،

يعمل 720p مع معدل البت 1.25 ميغابايت في الثانية ...