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 ميغابايت في الثانية ...