2011-05-31

MMDの書き出しとエンコードの話

前置き:どうして突然こんな話を?

ニコニコ動画にMMD動画を投稿し、MikuMikuDanceコミュニティに登録したところ、次のようなコメントを頂きました。
どうしたらこんなにきれいに出力できるの?
別に特別なことをしているわけでは無いんですが、コミュニティに参加したのは他ならぬ自分。出来れば質問には答えたい。
ですが方法がありません。投稿者コメントやマイリストは字数制限が厳しくてとても書けない。コミュニティの掲示板にももちろん書けない(新入りの初心者がいきなりエンコードについて偉そうに解説を始めたらまさしく噴飯ものでしょう)。そこでこういう場を設けてお答えすることにしました。
質問してくれた方がここにたどり着く確率はかなり低いでしょうが、そこは諦めることにします。

詳しい方ならすでにお判りでしょうが、このエントリは初心者向けの内容です。

まとめ

やたら長いエントリになってしまったので結論を先に書きます。
出来るだけキレイにエンコードするには、
  • ビットレートを可能な限り大きくする
  • Avi出力で直接H.264エンコードではなく、複数パスエンコードを行う
  • 中間Aviではロスレスコーデックを使用する
  • 色空間の変換を避ける
  • x264のエンコードオプションを詰める
という事が重要です。
当たり前の事しか書けなくてすみません 。

二つめの「Avi出力で直接H.264エンコードではなく、複数パスエンコードを行う 」についてですが、MMDからのAvi出力で直接H.264エンコードし、ニコニコ動画にUPすることも可能です。ですが当然1passエンコードなので画質では不利になります。画質を上げるためには1度ロスレスのコーデックで出力して、つんでれんこなどで複数パスのエンコードを行うことが必須です。

ということで以降の項目は興味のある方、ヒマで死にそうな方、全くわからないけどふいんきを味わっておくかという方などにしかお勧めできません。

私の手順

投稿した動画で実際に行った手順です。
  1. MMDでAvi書き出し (codec: Ut Video Codec RGB)
  2. モーションブラーをかけて中間Avi出力 (codec: Ut Video Codec YUV420)
  3. H.264で複数パスエンコード
  4. ニコニコ動画に投稿
はい。普通です。
Ut Video Codecはロスレス圧縮するフリーの動画コーデックで、Huffyuvなどと比較しても新しい分いろいろと有利なようです。MMDユーザの間ではわりとメジャーな存在みたいです。詳しくはぐぐって下さい(以降の項目についても同様。すいません)。

ここまでで、書いてあることがまるで意味不明、という方は、すいませんが私の手には負えません。まずはニコニコ動画まとめwikiなどで基礎知識を得ると良いと思います。

注意したこと

作業において注意したことは、何より劣化を避けることでした。
具体的には色空間の変換を出来るだけ避けました。
MMD出力ではRGBのまま保存し、YV12(YUV420と同じだと考えて良いようです)に変換してモーションブラーフィルタをかけYUV420のまま保存、以降変換無しでH.264でエンコードしています。

色空間には普通あまり馴染みがないと思います。なんだそりゃって方はRGB・YUVみたいな単語はとりあえず聞き流してください。いちおう最後の項で説明しています。

1. MMDでAvi書き出し (codec: Ut Video Codec RGB)

MMDでの作業が完了したらAvi書き出しをします。
MMD出力はRGB32ですが今回はアルファ情報を使わないので、Ut Video Codecを使ってRGB24で保存しました。

ファイルがまだ残っていたので確認したところ、全部で27GBほどでした。今回はシーン毎に分けて出力したので関係ありませんが、Avi2.0では最大で約32GBのファイルまでしか扱えません。大きすぎるファイルを無理に出力しても開けないので、ロスレスで保存する際は注意が必要です。

2. モーションブラーをかけて中間Avi出力 (codec: Ut Video Codec YUV420)

そぼろさんがナイスなMMEモーションブラーを配布してくださっているので、この手順は必要なくなりそうです。
 (この項が念仏か何かにしか見えない方はとりあえず無視してください)
AviSynth + MVToolsでモーションブラーをかけました。
MVToolsはYV12を扱えるので、
【Avi読み込み - YV12に変換(Rec601) - MVToolsでモーションブラー】
な処理をAviSynthスクリプトで記述し、VirtualDubで中間Avi出力しました。余分な色空間の変換を避けるためにモードはFast recompressを使用し、Ut Video Codec YUV420でエンコードしました。
今回、色空間の変換はこの1度だけのはずです。

なお上記のAviSynthスクリプトは、ググればわりとそのままズバリなものが見つかります。

3. H.264で複数パスエンコード

2.で作った中間ファイルをエンコードしてmp4ファイルにしました。
忘れてましたが文字入れと各シーンのAviファイルの連結もここでやってます。
手順としては、【全シーンを連結して文字入れ】を記述したAviSynthスクリプト(なんだこの書き方) をエンコーダに渡すだけなのでこのステップで処理しているという自覚はあんまりありません。AviSynthスクリプトはあたかもAviファイルそのものであるかのように扱えてしまうのです。

エンコードは普通はつんでれんこで良いと思います。私もそうしたかったのですが中間ファイルの連結にAviSynthを使う都合上、つんでれんこではエンコードできませんでした。
仕方がないのでx264cliとMP4Boxを使いました。
H.264の色空間は通常YV12なので、ここでも色空間の変換は発生しません。

ビットレートは重要な要素です。通常高ければ高いほどキレイになり、逆に低すぎるとどうやってもキレイにはなりません。動画の長さから逆算し、出来るだけ大きく使いたいところです。HD版ではかなりリミットに近い99.7MBにできました。
一般アカウントではビットレート・最大ファイルサイズの両方に制限が掛かるため、どうしても不利です(詳しくは例によってニコニコ動画まとめwiki参照)

エンコードオプションはニコニコ動画まとめwikiのこのページを大いに参考にしました。とても素晴らしいページでお勧めです。
HD版ではかなり重いオプションを使ったのでHighプロファイルのlevel4.0になりました。
SD版では再生負荷を出来るだけ下げたかったのでHighプロファイルのままCABACをオフにしました。levelは3.1でした。コメントによるとそこそこ軽いようで上手くいったみたいです。

なお、通常エンコードのパス数は2passか、それで目標ビットレートに達しない場合にさらに+1回つまり3passで良いと思います。それ以降は画質は向上しないというのが通説のようです。
なのですが今回、HD版のエンコードではかなり重いエンコード設定を指定したのでとても待ちきれず、バッチファイルで自動化して寝ている間にエンコードさせました。
このバッチファイル、止めるまで延々Nth passエンコードを繰り返すというシロモノで、朝起きたときには19回目をやっていました。つまりHD版では19passのエンコードを行ったわけで、ひょっとするとそれにより綺麗になっていた……のかもしれません。(同じぐらいの確率で3passと変わらないか、逆に悪くなっているおそれもあります)
ちなみにSD版は同じようなバッチファイルを使い、用事を済ませる間エンコードさせてたら、5passほどやってました。

あとはニコニコ動画にUPしただけです。結論についてはすでに述べた「まとめ」の項をご覧下さい。

補足説明:色空間

ニコニコ動画に関する限りでは、色空間=動画のフォーマットだと理解してだいたい問題ありません。詳しい解説はWikipediaなどにお任せするとして、ざっと説明すると
  • RGB32(RGBA) - 1ピクセルにつき32bit使って記憶する。アルファ情報有り
  • RGB24(RGB) - 1ピクセルにつき24bit使って記憶する
  • YUV422(YUY2) - 1ピクセルにつき16bit使って記憶する 
  • YV12(YUV420) - 1ピクセルにつき12bit使って記憶する
という違いがあります。

それぞれ異なった方法で色情報を符号化しており、相互変換では劣化が発生します。 この劣化はあまり問題にならない程度に小さいのですが、それでも劣化であることは確かです。動画CodecやAviUtl・VirtualDubなどでは、必要な場合自動的に色空間を変換するため、知らない間に劣化が発生している場合があります。色空間と各ソフトを良く理解して正しい手順で作業すれば劣化を避けられます。

MMDの出力はRGB32なので、本当にロスレスで保存したい場合にはRGB32を使う必要があります。(アルファが要らない場合はRGB24)
Ut Video Codecはそれぞれ各色空間に対応したものが用意されているので、正しく選択することが重要です。(まちがえると色空間の変換が発生し、劣化します)

H.264は通常YV12を扱うので、MMD動画をニコニコ動画にUPする場合は、YV12への変換が1度は必要になります。

 YV12とYUV420は、普通は同じものと考えて良いようで、YV12とYUV420間の変換では劣化は発生しません。詳しい人にこんなことを言うと「違うわバカヤロー」と怒られそうですが、MMDとニコニコ動画で遊ぶ限りではYV12=YUV420と思って良さそうです。

以上、簡単に述べましたが、私も必要に駆られて調べただけなので不十分な内容になっていると思います。動画の色空間についてはネット上にたくさんの日本語の情報があるのでググれば簡単に調べられます。TVのアナログ放送をPCで録画する際の情報が多いようで、色空間とその変換については多くの人が苦労されているようですね。