h.264 - FFMPEG(libx264)"الارتفاع غير القسمة على 2"




(6)

مجرد استخدام -2

من وثائق فلتر المقياس :

إذا كانت إحدى القيم هي -n مع n > 1 ، فسيستخدم عامل تصفية المقياس أيضًا قيمة تحافظ على نسبة العرض إلى الارتفاع لصورة الإدخال ، محسوبة من البعد المحدد الآخر. بعد ذلك ، ستتحقق بعد ذلك من أن البعد المحسوب قابل للقسمة على n وضبط القيمة إذا لزم الأمر.

أمثلة

تعيين العرض على 1280 ، وسيتم حساب الارتفاع تلقائيًا للحفاظ على نسبة العرض إلى الارتفاع ، وسيتم قسمة الارتفاع على 2:

-vf scale=1280:-2

كما هو مذكور أعلاه ، ولكن مع ارتفاع معلن بدلاً من ذلك ؛ ترك العرض ليتم التعامل معه بواسطة المرشح:

-vf scale=-2:720

"القسمة على 2"

كما هو مطلوب من قبل x264 ، هناك حاجة إلى "القسمة على 2 للعرض والارتفاع" من أجل YUV 4: 2: 0 مخرجات chroma غير المقسمة. 4: 2: 2 تحتاج إلى "divisible by 2 for width" ، و 4: 4: 4 لا تملك هذه القيود. ومع ذلك ، يمكن لمعظم لاعبين غير FFmpeg فقط فك ترميز 4: 2: 0 ، ولهذا السبب غالبا ما ترى أوامر ffmpeg مع الخيار -pix_fmt yuv420p عند إخراج الفيديو H.264.

مذكرة قانونية

لسوء الحظ ، لا يمكنك استخدام -2 لكل من العرض والطول ، ولكن إذا كنت قد حددت بعدًا واحدًا ، فإن استخدام -2 هو حل بسيط.

أحاول ترميز فيديو .mp4 من مجموعة من الإطارات باستخدام FFMPEG باستخدام برنامج الترميز libx264.

هذا هو الأمر الذي أديره:

/usr/local/bin/ffmpeg -r 24 -i frame_%05d.jpg -vcodec libx264 -y -an video.mp4

أتلقى أحيانًا الخطأ التالي:

[libx264 @ 0xa3b85a0] height not divisible by 2 (520x369)

بعد البحث قليلاً يبدو أن المشكلة لها علاقة بخوارزمية القياس ويمكن إصلاحها بإضافة وسيطة -vf.

ومع ذلك ، في حالتي لا أريد أن أفعل أي تحجيم. من الناحية المثالية ، أريد أن أبقي الأبعاد تمامًا مثل الإطارات. اي نصيحه؟ هل هناك نوع من نسبة العرض إلى الارتفاع التي يفرضها h264؟


إذا كنت ترغب في تعيين بعض عرض الإخراج ويكون الإخراج بنفس النسبة مثل الأصلي

scale=720:-1 

وعدم الوقوع مع هذه المشكلة ثم يمكنك استخدامها

scale="720:trunc(ow/a/2)*2"

(فقط للأشخاص الذين يبحثون عن كيفية إجراء ذلك باستخدام القياس)


من المحتمل أن يرجع ذلك إلى حقيقة أن الفيديو H264 عادة ما يتم تحويله من RGB إلى YUV space كـ 4: 2: 0 قبل تطبيق الضغط (على الرغم من أن تحويل التنسيق نفسه عبارة عن خوارزمية انضغاطية ضائعة تؤدي إلى توفير مساحة بنسبة 50٪).

يبدأ YUV-420 مع صورة RGB (أحمر أخضر أزرق) وتحويلها إلى YUV (قناة كثافة واحدة والقنوات اثنين "hue"). ثم يتم قطعيها في قنوات هوى عن طريق إنشاء نموذج هوى واحد لكل مربع 2X2 من هذا اللون.

إذا كان لديك عدد فردي من وحدات بكسل RGB إما أفقيًا أو رأسيًا ، فستتوفر لك بيانات غير كاملة لعمود أو صف البكسل الأخير في مساحة التدفقات الفرعية للإطار YUV.


بعد اللعب بهذا قليلاً ، أعتقد أنني أجبت على سؤالي الخاص. في ما يلي الحل في حالة إصابة أي شخص آخر بمشكلة مشابهة ... كان عليّ إضافة الحجة التالية إلى الأمر:

-vf "scale=trunc(iw/2)*2:trunc(ih/2)*2"

أمر:

ffmpeg -r 24 -i frame_%05d.jpg -vcodec libx264 -y -an video.mp4 -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2"

بشكل أساسي ، يحتاج .h264 إلى أبعاد حتى ؛ لذا سيعمل هذا الفلتر على:

  1. قسِّم الطول والعرض الأصليين بمقدار 2
  2. تقريبه إلى أقرب بكسل
  3. اضربه ب 2 مرة أخرى ، مما يجعله رقم زوجي

LordNeckbeard لديه الإجابة الصحيحة ، سريع جدا

-vf scale=1280:-2

بالنسبة إلى Android ، لا تنس إضافة

"-preset ultrafast" and|or "-threads n"

يمكن العثور على وثائق مفصلة حول طرق مختلفة من تسلسل في ffmpeg هنا .

يمكنك استخدام "فلتر Concat" لسَلسَلة سريعة.

ينفذ إعادة ترميز. هذا الخيار هو الأفضل عندما تكون للإدخالات تنسيقات فيديو / صوتية مختلفة.

من أجل Concatenating 2 الملفات:

ffmpeg -i input1.mp4 -i input2.webm \
-filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mp4

من أجل Concatenating 3 ملفات:

ffmpeg -i input1.mp4 -i input2.webm -i input3.mp4 \
-filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] [2:v:0] [2:a:0] concat=n=3:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mp4

هذا يعمل لنفسه وكذلك العديد من أنواع ملفات الإدخال.





ffmpeg h.264 libx264