FFMPEG (libx264) “yükseklik 2'ye bölünemez”


188

Ben libx264 codec kullanarak FFMPEG kullanarak çerçeve kümesinden bir .mp4 video kodlamak çalışıyorum.

Bu çalıştırdığım komut:

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

Bazen aşağıdaki hatayı alıyorum:

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

Biraz araştırdıktan sonra, sorunun ölçekleme algoritmasıyla ilgili olduğu ve bir -vf argümanı eklenerek düzeltilebileceği anlaşılıyor.

Ancak, benim durumumda herhangi bir ölçeklendirme yapmak istemiyorum. İdeal olarak, boyutları çerçevelerle tamamen aynı tutmak istiyorum. Herhangi bir tavsiye? H264'ün uyguladığı bir tür en boy oranı var mı?


@AleksandrDubinsky Ama LordNeckbeard'ın cevabı orijinal genişlik ve yüksekliği korumuyor. hem yükseklik hem de genişlik eşit değilse çalışın ..
Lütfen

1
@varmashrivastava Yani, SO'nun çalışma şekli başlangıçta bir soru olabilir ve daha sonra Google, farklı bir soruyla bir grup insanı gönderir ve bu da sayfayı ele geçirir. İşte bu, onunla savaşmamaya çalışın. Orijinal soruya doğru cevap -vf pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2", cevaplardan biri bile değil. Herkesin sorusuna doğru cevap LordNeckbeard'ın sorusudur.
Aleksandr Dubinsky

@varmashrivastava Devam ettim ve ilk cevabı düzelttim. Umarım modlar tarafından tahrip olmaz.
Aleksandr Dubinsky

@AleksandrDubinsky teşekkürler .. ve kullanıcı o colured dolgu piksel istemiyorsa "scale="yerine kullanabilirsiniz "pad="?
varmashrivastava

Yanıtlar:


269

Cevabı asıl soruya gelmez değil videoyu ölçeğe istiyorum:

-vf "pad=ceil(iw/2)*2:ceil(ih/2)*2"

Komut:

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

Temel olarak, .h264 eşit boyutlara ihtiyaç duyar, bu nedenle bu filtre:

  1. Orijinal yüksekliği ve genişliği 2'ye bölün
  2. En yakın piksele yuvarlayın
  3. Tekrar 2 ile çarpın, böylece eşit bir sayı haline getirin
  4. Bu sayıya kadar siyah dolgu pikselleri ekleyin

Filtre parametresi ekleyerek dolgu rengini değiştirebilirsiniz :color=white. Pedin belgelerine bakın .


3
Bu bir hata değil. Çıktı girişin çerçeve boyutunu devralacağı için ölçeklendirme yapmamanız önemli değildir.
llogan

5
Kayıt için, sadece bir görüntüden video oluşturduğum bir şey yapıyordum ve piksel formatı olarak yuvj444p kullandı; video boyutunu umursamadı. Sonra yuv420p dönüştürmek gerekiyordu, ve sonra video boyutu hakkında bakım. Vikipedi'de yuv420p'yi aradım, bence çok pikselli bir renk biçimi, görüntünün belirli bir boyutta olması gerekiyor. Gerçi neden sıkıştırılmış olduğundan emin değilim.
lahwran

7
Siyah bir satır / sütun eklemek için ölçek yerine pad kullanmaktan daha iyidir. Görüntüyü bir piksel kadar ölçeklendirmek görüntüyü bulanıklaştıracaktır.
Glenn Maynard

5
@NickeManarin, bu filtre yerleştirilmiş bir video üst sol ile, dikey bir boyuta beyaz dolgu 1 piksel eklemek için çalışması gerekir: -vf pad="width=iw:height=ih+1:x=0:y=0:color=white". Ffmpeg pad belgeleri buradadır: ffmpeg.org/ffmpeg-filters.html#pad-1 .
Mark Berry

4
Burada sadece garip boyutlara dolgu bir pikseli ekleyen bir çözüm: -vf pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2".
danneu

250

Sadece kullan -2

Gönderen kireç filtresi belgelerinde :

Değerlerden biri -nşuysa n > 1, ölçek filtresi ayrıca, belirtilen görüntünün en boy oranını koruyan, belirtilen diğer boyuttan hesaplanan bir değer kullanır. Ancak bundan sonra, hesaplanan boyutun bölünebilir olduğundan emin olun nve gerekirse değeri ayarlayın.

Örnekler

Genişliği 1280 olarak ayarlayın, en boy oranını korumak için yükseklik otomatik olarak hesaplanacaktır, ve yükseklik 2'ye bölünebilir:

-vf scale=1280:-2

Yukarıdaki ile aynı, ancak beyan edilen bir yüksekliğe sahip; filtre tarafından ele alınacak genişlik genişliği:

-vf scale=-2:720

"2'ye bölünebilir"

X264'ün gerektirdiği gibi, YUV 4: 2: 0 renk alt örneklenmiş çıkışlar için "genişlik ve yükseklik için 2'ye bölünebilir" gereklidir. 4: 2: 2 için "genişlik için 2'ye bölünebilir" gerekir ve 4: 4: 4 bu kısıtlamalara sahip değildir. Bununla birlikte, FFmpeg tabanlı olmayan oyuncuların çoğu sadece 4: 2: 0 kodunu düzgün bir şekilde çözebilir, bu yüzden sık sıkffmpeg-pix_fmt yuv420p H.264 videoyu çıkarırken seçenekli komutları .

Uyarı

Ne yazık ki kullanamazsınız -2genişliği her ikisi için ve yükseklik, ama zaten o zaman kullanarak bir boyut belirtilmişse -2basit bir çözümdür.


14
Bence bu hiçbir "hileci" olmadığı için doğru cevap olarak işaretlenmelidir. Birden fazla kez oy vermek için Whish
LucaM

1
Neden çalışmıyor -vf scale=-2:-2? Benim durumumda orijinal dosya boyutunu mümkün olduğunca korumak istiyorum. Benim için işe yarayan buydu -vf scale=-2:ih. Ancak her iki h / w eşit değilse, çalışmaz.
Pascal

2
@tuner Sonuçta ortaya çıkan değer -2, diğer boyutun beyan edilen değerine bağlıdır.
llogan

3
benim durumumda bu bana şu hatayı verdi: Size values less than -1 are not acceptable.ama @Zbyszek gelen cevap mükemmel çalıştı.
Julien

1
@Julien Bu değilffmpeg . Şunları yapabilirsiniz Bir statik yüklenmeyi indirmek .
llogan

64

Biraz çıkış genişliği ayarlamak ve orijinalle aynı oranda çıktıya sahip olmak istiyorsanız

scale=720:-1 

ve bu sorunla düşmemek için kullanabilirsiniz

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

(Sadece bunu ölçeklendirme ile nasıl yapacağını araştıran insanlar için)


16
Ve sabit bir yükseklik içinscale="trunc(oh*a/2)*2:720"
Tom

20

İle ilgili sorun scale çözümlerle , neredeyse hiçbir zaman istediğiniz şey olmayan kaynak görüntüyü / videoyu bozmalarıdır.

Bunun yerine, en iyi çözümü tek boyuta 1 piksel bir ped eklemek olduğunu buldum. (Varsayılan olarak dolgu siyahtır ve fark edilmesi zordur.)

Diğer problem pad çözümlerle keyfi boyutlar üzerinde genelleme yapmamalarıdır, çünkü her zaman pedler.

Bu çözüm, tek sayıları yüksekliğe ve / veya genişliğe yalnızca 1 piksellik bir dolgu ekler:

-vf pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2"

Bu idealdir çünkü dolgu gerekmediğinde bile her zaman doğru olanı yapar.


Ölçek çözümleri, piksel sayısını en fazla 1 değiştirir. Bu görüntüyü pek deforme etmiyor. Hız filtreleme konusunda endişeleriniz varsa kullanın scale=iw+mod(iw,2):ih+mod(ih,2):flags=neighbor. Bu, gerekirse her boyutu yalnızca 1 artırabilir ve son satırı / sütunu çoğaltacaktır.
Gyan

@Gyan O var ben bu çözüldü (cevabım ben uzun zaman önce yapılmış bir yorum çıkartılmıştır) böyle bir sorun vardı, ama tek bir piksel o ölçeklendirme hatırlamak beri çok uzun süredir yoktu ben rahatsız neden olan bazı koşullarda farkedilir görsel eserleri tanıtmak ilk başta. Tam olarak hatırlamıyorum, belki tek bir piksel değişikliğinden orantısız miktarda bulanıklaştırma? Belki sadece bazı video / görüntü formatlarında? Söyleyebileceğim tek şey bu düzeltme ile binlerce videyi işlediğim ve bu olumlu dönüşüm oldu.
danneu

19

H264 videosunun sıkıştırma uygulamadan önce genellikle RGB'den YUV alanına 4: 2: 0 olarak dönüştürülmesinden kaynaklanıyor olabilir (format dönüşümünün kendisi,% 50 alan tasarrufu sağlayan kayıplı bir sıkıştırma algoritması olmasına rağmen).

YUV-420 bir RGB (Kırmızı Yeşil Mavi) resim ile başlar ve onu YUV'ye (temel olarak bir yoğunluk kanalı ve iki "renk tonu" kanalı) dönüştürür. Renk tonu kanalları daha sonra bu renk tonunun her 2X2 karesi için bir renk tonu örneği yaratılarak alt örneklenir.

Yatay veya dikey olarak tek bir RGB pikseliniz varsa, YUV çerçevesinin alt örneklenmiş renk tonu alanındaki son piksel sütunu veya satırı için eksik verileriniz olacaktır.


2
Bir başka ilginç gerçek ... Microsoft Media Foundation ile kod çözdüğünüzde, H264 için 16'nın katlarını kullanmanız gerekir. Yani 1080P video aslında 1088 yüksekliğinde bir arabellekte çözülür (son 8 satırı görmezden gelmenize rağmen).
Adisak

2

LordNeckbeard doğru cevabı veriyor, çok hızlı

-vf scale=1280:-2

Android için eklemeyi unutmayın

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

Konuları bildirmenize gerek yoktur: bu otomatik olarak ele alınır. Ben H.264 kodlama Andriod yavaşlık nedeniyle "/ ffmpeg-android WritingMinds" kullanımlar popüler kullanan kişilere olduğuna inanıyoruz --disable-asmonun içinde x264 yapı komut . Bu, gereksiz ve önemli bir yavaşlık ile sonuçlanır (ffmpeg günlüğünü kontrol edebilirsiniz ve eğer gösteriliyorsa using cpu capabilties: none!bu kötüdür). Bunu neden eklediklerinden emin değilim, ancak Android geliştiricisi değilim.
llogan

1

bitandAşağıdakiler yerine işlevi de kullanabilirsiniz trunc:

bitand (x, 65534)

aynı şeyi yapacak ve trunc(x/2)*2bence daha şeffaf.
( Burada 65534'ü sihirli bir sayı olarak düşünün ;))


Görevim otomatik olarak ölçeklendirmekti birçok video dosyasını olarak yarı çözünürlüğe .

scale=-2,ih/2 biraz yol açmak bulanık görüntülere

nedeni:

  • giriş videoları vardı onların görüntü en boy oranı (DAR) ayarlandı
  • scale gerçek çerçeve boyutlarını ölçeklendirir
  • önizleme sırasında yeni videoların boyutları DAR kullanılarak düzeltilmelidir ; bu, oldukça düşük çözünürlüklü video ( 360x288 , DAR 16: 9) bulanıklaşmaya neden olabilir

çözüm:

-vf "scale='bitand(oh*dar, 65534)':'bitand(ih/2, 65534)', setsar=1"

açıklama:

  • output_height = girdi_yüksekliği / 2
  • output_width = output_height * orijinal_ekran_aspect_ratio
  • hem output_width ve output_height şimdi 2 ile en yakın küçük sayının bölünebilir yuvarlanır
  • setsar=1Çıktı_boyutları artık kesin demektir , en boy oranı düzeltmesi uygulanmamalıdır

Birisi bunu faydalı bulabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.