عند استخدام MediaCodec
لترميز الفيديو باستخدام تنسيق الألوان COLOR_FormatYUV420Flexible
، يجب أن تتأكد من أن الأجهزة التي تستخدمها تدعم هذا التنسيق. على الرغم من أن هذا التنسيق مدعوم منذ API 21، إلا أن بعض الأجهزة قد تواجه مشكلة في استرجاع الصورة الخام (Image
) باستخدام getInputImage
، كما تظهر في حالتك مع هواوي P7 وموتورولا Moto X Pro.
حتى تتمكن من التعامل مع هذه المشكلة، يمكنك استخدام الطريقة الأولى التي وصفتها بتعبئة البيانات مباشرة في الـ ByteBuffer
الذي تحصل عليه من dequeueInputBuffer
، وذلك بدلاً من الاعتماد على getInputImage
. يمكنك محاولة تعيين القيم المباشرة في الـ ByteBuffer
واختبارها على الأجهزة التي تواجه مشكلة.
على الرغم من أن هذا الحل قد يعمل، إلا أنه ليس الأمثل، لذا يجب عليك البحث عن حلول أخرى قد تكون أفضل. يمكنك مراجعة منتديات المطورين أو الوثائق الرسمية لـ Android لمعرفة ما إذا كان هناك حلاً أفضل لمشكلتك.
المزيد من المعلومات
عند استخدام COLOR_FormatYUV420Flexible
في MediaCodec
، يجب أن تتأكد من مطابقة تنسيق الألوان مع بيانات الفيديو الخام التي تقدمها. يعتمد تنسيق YUV420 على ترتيب محدد للمكونات (Y، U، V) وحجم معين لكل مكون.
إذا كنت تعالج بيانات YUV420p، يجب أن تتأكد من ترتيب البيانات وحجم الإطارات (frames) الخاصة بك. الشكل القياسي للإطار YUV420p هو كالتالي:
- المكون Y (السطوع) يأخذ مكانًا في البداية مع حجم نفس حجم الإطار.
- المكون U (اللون الأزرق) يأتي بعد Y بنسبة 1:4 من حجم الإطار.
- المكون V (اللون الأحمر) يأتي بعد U بنسبة 1:4 من حجم الإطار.
عند تعيين البيانات في الـ ByteBuffer
، يجب أن تكون متأكدًا من مطابقة ترتيب البيانات وحجم الإطارات لتنسيق YUV420p. إذا كان هذا الترتيب غير صحيح، فقد يؤدي ذلك إلى ظهور ألوان غير صحيحة عند تشفير الفيديو.
يمكنك استخدام الشفرة التالية كمرجع لتعيين البيانات في الـ ByteBuffer
بترتيب YUV420p الصحيح:
javaint width = ...; // عرض الإطار
int height = ...; // ارتفاع الإطار
int strideY = width;
int strideUV = (width + 1) / 2;
ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
inputBuffer.clear();
// Fill Y plane
for (int y = 0; y < height; y++) {
inputBuffer.put(yuv420pData, y * width, width);
}
// Fill U and V planes
for (int y = 0; y < height / 2; y++) {
inputBuffer.put(yuv420pData, width * height + y * strideUV, strideUV);
}
for (int y = 0; y < height / 2; y++) {
inputBuffer.put(yuv420pData, width * height + strideUV * (height / 2 + y), strideUV);
}
حيث yuv420pData
هو مصفوفة تحتوي على البيانات الخام YUV420p.