2010年05月29日

「Please use vf=pad」と言われたのでlibavfilterを使ってみました

FFmpeg rev.23043からlibavfilterがマージされて、padding関連のオプションはlibavfilterを使うようになりました。
当サイトでは、rev.23359からlibavfilterに対応しています。

-padtop 60 -padbottom 60
などとすると、
Please use vf=pad
とメッセージが返ってきます。

Pleaseとか言いながら強制です。困ったもんです。

困っている方が少なからずいらっしゃるようなので、
pad=width:height:x:y:color
crop=x:y:width:height
scale=width:height
を試してみました。

詳しくは、以下のページを参照してください。
オプションは、-vfilterから-vfに変更されています。
http://ffmpeg.org/libavfilter.html

2010/10/02 追記
FFmpeg rev.25184以降、cropの書式が変わりました。
width:heightとx:yが前後入れ替わり、widthまたはheightのサイズが変わらない場合でも、サイズを明示する必要があります。
crop=width:height:x:y

使い方は、以下のようになります。

・640x360(16:9)の上下に60pixelずつ黒帯を付け、640x480(6:4)で出力
-vf "pad=0:480:0:60"

・640x360(16:9)の上下に60pixelずつ黒帯を付け、320x240(6:4)にリサイズして出力
-vf "pad=0:480:0:60, scale=320:240"

・上下に60pixelずつ黒帯がある640x480(6:4)の黒帯を削除して、640x360(16:9)で出力
-vf "crop=0:60:0:360"
-vf "crop=640:360:0:60"

・上下に60pixelずつ黒帯がある640x480(6:4)を320x240(6:4)にリサイズし、黒帯を削除して320x180(16:9)で出力
-vf "scale=320:240, crop=0:30:0:180"
-vf "scale=320:240, crop=320:180:0:30"

・640x480(6:4)の左右に107pixelずつ黒帯を付け、854x480(16:9)で出力
-vf "pad=854:0:107:0"

などなど。

padの色指定は、
-vf "pad=0:480:0:60:black"
-vf "pad=0:480:0:60:white"

などとなります。
color省略時はblackです。

サイズ等は、お好みに合わせて変更してください。
ご参考まで。


2010/05/30 追記
-vf "scale=..." と -aspect を一緒に指定するとアスペクト比がおかしくなるらしいということで、いろいろ試してみました。

720x480 [PAR 32:27 DAR 16:9] を、
480x272 [PAR 1:1 DAR 16:9] にしたい場合
720:480 = (480x1.5):(272x1.7647)
という関係になっています。

1.7647:1.5≒32:27 となってPARの値とほぼ同じ。

このままリサイズすると横長になるので、横方向の16に、1.5/1.7647 を掛けます。
16x1.5/1.7647 = 13.6000

そうすると、
13.6:9 = 136:90
になります。

720x480 [PAR 32:27 DAR 16:9] のソースを、
-vf "scale=480:272" -aspect 136:90
という設定でエンコードしたところ、
480x272 [PAR 136:135 DAR 16:9] になり、まあまあ近い値になりました。

比率の計算は、
(16x1.5):(9x1.7647) = 24:15.8823 = 240000:158823
でも良いのですが、わりと切りの良い値になったので上記のようにしました。


逆に、
480x272 [PAR 136:135 DAR 16:9] を、
720x480 [PAR 32:27 DAR 16:9] にしたい場合
9x1.5/1.7647 = 7.6500
16:7.65 = 1600:765
-vf "scale=720:480" -aspect 1600:765
となります。

その他、
720x480 [PAR 32:27 DAR 16:9] を、
640x360 [PAR 1:1 DAR 16:9] にしたい場合
720:480 = (640x1.125):(360x1.33333) なので、
16x1.125/1.33333 = 13.5000
13.5:9 = 135:90
-vf "scale=640:360" -aspect 135:90

640x360 [PAR 1:1 DAR 16:9] を、
720x480 [PAR 32:27 DAR 16:9] にしたい場合
9x1.125/1.33333 = 7.5938
16:7.5938 = 160000:75938
-vf "scale=720:480" -aspect 160000:75938
となります。

普通に、-s と -aspect の組み合わせの場合は、
-s 480x272 -aspect 16:9
-s 720x480 -aspect 16:9
などとすると、-aspectの値はDARとして使われ、PARは自動で計算してくれます。

単純にリサイズするだけなら、-s と -aspect の組み合わせで良いと思います。

-vf "scale=..." と -aspect の関係が内部でどうなっているか、もう少し探ってみます。


2011/04/01 追記
当サイトのFFmpeg rev.28742以降、-vfのscaleと-aspectの組み合わせが正常に動作するようになっています。

例えば、
-vf "scale=720:480" -aspect 16:9 -sws_flags lanczos+print_info
とすると、

Stream #0.0: Video: mpeg4, yuv420p, 720x480 [PAR 32:27 DAR 16:9], ...
[swscaler @ 05d3f0d0] Lanczos scaler, from yuv420p to yuv420p using MMX2

PARを自動で計算してくれて、Lanczos scalerが使用されます。
posted by あべちん at 02:21 | Comment(9) | TrackBack(0) | 携帯動画変換君
この記事へのコメント
rev.23100でpad使えない件
質問させて頂いたtekです。

早速、この方法で使用してみたのですが、
-aspect の挙動が変わったようです。

scale=480:272 と -aspect 480:272 を
指定しても、プレーヤーが正方画素として
認識しなくなりました。
(横長になりすぎる&
  元ファイルは720x480で16:9)

法則が分からず困っています。
分かりましたらお教えください。
Posted by tek at 2010年05月29日 10:42
しばらく使ってて気がついたんですが、
「scale=width:height」でリサイズをする時ですが、
「-sws_flags」オプションが無視されてるみたいです。
その代わりに、
「scale=480:272:flags=0x200」
といった風に後ろにフラグ(libswscale/swscale.hの62〜72行目あたりで定義されてる物)を指定することでリサイズアルゴリズムを指定できるみたいです。
(ソースを少し眺めただけなのでこれが正しい方法かは分りませんが)
省略した場合は強制的にバイリニアになるみたいです。
Posted by 通りすがり at 2010年05月29日 11:00
>>tekさん

「-s」オプションが無いと元の動画の解像度を元に計算されるみたいですね。
(ちなみに-vfと-sは地味に競合するので同時に指定できないことが多いみたいです)

役に立つかどうかわかりませんが、自分はgolgol7777さんのところのパッチから一部取り込んで「-sar」オプションが使えるようにした物をビルドすることで解決しています。
http://www.esnips.com/web/ffmpegbinary/
Posted by 通りすがり at 2010年05月29日 11:14
tekさん、こんにちは。管理人です。

元ファイルの720x480というサイズで間違いがなければ3:2ですので、16:9より縦長です。

横480で3:2を維持するには、480x320。

16:9にするには、横に黒帯をつけて854x480にしてからリサイズすれば良いと思います。
Posted by あべちん at 2010年05月29日 11:41
>>あべちんさん

720x480で16:9というのは正方画素ではない、
PARが32:27、DARが16:9ということです。
説明不足ですいません。
Posted by tek at 2010年05月29日 16:03
tekさん、こんにちは。管理人です。

申し訳ありません。
PARとDARの関係をよく理解していませんでした。

DVDをソースにして試してみましたが、確かに-vfと-aspectを組み合わせると、おかしなことになりますね。

padやcropなどをしないのであれば、
「-vf "scale=480:272"」ではなく、
「-s 480x272」だけ指定すれば、

480x272 [PAR 136:135 DAR 16:9]

と表示されて、ちゃんとリサイズできているようですが、それではダメでしょうか。

通りすがりさんの情報も試してみようと思います。
Posted by あべちん at 2010年05月30日 16:31
通りすがりさん、こんにちは。管理人です。

「-sws_flags」について、情報ありがとうございました。

libswscale/swscale.hから一部抜粋すると、

#define SWS_FAST_BILINEAR 1
#define SWS_BILINEAR 2
#define SWS_BICUBIC 4
#define SWS_X 8
#define SWS_POINT 0x10
#define SWS_AREA 0x20
#define SWS_BICUBLIN 0x40
#define SWS_GAUSS 0x80
#define SWS_SINC 0x100
#define SWS_LANCZOS 0x200
#define SWS_SPLINE 0x400

#define SWS_PRINT_INFO 0x1000

となっており、

「-sws_flags lanczos」は、
「scale=480:272:flags=0x200」

「-sws_flags lanczos+print_info」は、
「scale=480:272:flags=0x1200」

などとなります。

いつも通りすがっていただき、ありがとうございす。
Posted by あべちん at 2010年05月30日 16:58
padオプションについて質問します。
このオプションは

widthxheightの大きさの黒い板?の上に動画を貼り付ける。
貼り付ける場所は左上を基点としたx:yの座標になる。
ただし動画がはみ出たりするとエラーになるので
widthxheightは動画より大きい値でないといけないが
もし値が0の場合は動画の大きさと同じ値に変換される。

という解釈でいいでしょうか?
上下に黒帯付のサムネイルを作ろうとしても失敗します。
設定はこんな感じです。なにがいけないのでしょうか?

Command0=""<%AppPath%>\cores\ffmpegffmpeg23359athlon64" -y -i "<%InputFile%>" -f image2 -ss 00:00:03.00 -vframes 1 -vf "scale=160:90, pad=0:120:0:16" -an "<%OutputFile%>.jpg""
Posted by skot at 2010年05月30日 23:04
すいません。
上の設定誤字がありました。おさわがせしました。
Posted by skot at 2010年05月30日 23:32
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/38641938
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック