FFmpegの2.2以上でBMS2のQSVトランスコードができなくなっていたのを直した
BEER Media Server 2でQSVEncCを使ったトランスコードが動かなくなっていました。どうやらFFmpegのVer.2.2から動かなくなったようです。
なんとか動くようになったのでLuaスクリプトを修正しておきました。
BEER Media Server 2でQSVトランスコードができなくなっていました。BMS2のままではエラーを詳しく見れないのでコマンドラインで試して見ます。トランスコードには4つのコマンドで行います。
いままでのトランスコードは次のようなコマンドになっていました。TEST.mkvというメディアファイルからQSVEncCを使ってa.tsというファイルを作っています。4つのコマンドはパイプによりデータを受け渡しています。
1.では元の映像トラックをQSVEncC用のyv12形式に変換します。
2.ではQSVにより映像がH.264/ES形式で出力されます。
3.はおまじないです。映像と音声をmuxするのですが、2.の出力を直接muxしようとすると何故かうまくいきません。
4.では変換された映像と元ファイルの音声をmuxしm2ts形式で出力します。
FFmpeg Ver.2.1.4では問題なく動いていましたがVer.2.2以降では4.でエラーが発生するようになりました。
エラーはこんなやつです。
pts valueの初期値を設定しろ みたいなエラーです。
何を意味してるのでしょうか?
最初は音声と映像の開始時間が不明確なためかなと思ったのですが違う感じです。
そもそもptsって何? mpeg2には2つの時間が記録されているようです。 dtsとptsというやつです。なぜ2種類あるのか? mpeg2など圧縮されたフォーマットでは表示する時間順にデータが並んでいるというわけではないのです。前後フレームの差分だけのデータがあったりしますので1枚のフレームを作るのに過去と未来のデータが必要だったりします。デコード・エンコードに必要なデータの時刻と表示する映像の時刻が別々に管理されています。
ptsというのは表示用の時間です。
つまり、4.の処理でパイプから入ってきたデータのptsに問題があったという事でしょう。
それではなぜ以前のバージョンでは問題なかったのでしょうか? 映像入力の処理が何か変わったのでしょうか? 1.の映像出力時点でおかしいのでしょうか? うーん、判りません。
とりあえず対処療法で改善するか試します。
ptsが無いなら作ればいいのです。そのためのコマンドがFFmpegにはあります。 "-fflags"オプションの"genpts"というやつです。
しかし、ローカルで再生する分には良かったのですがBMS2でビエラへ送ると100フレームほどで映像が停まってしまいます。音声は出ているようです。
音声と映像のタイムコードがズレまくるとありそうな症状ですが、全く原因の推測ができませんでした。もしかしたらコマンドを書き間違えただけかもしれませんが。
こうなったら対処療法です。試行錯誤を繰り返すついでにQSVのエンコード指定の見直しも行いました。いままではvbr指定でした。しかし、これでは動きが激しい場面での映像品質が悪すぎでQSVを使うメリットがありません。mpeg2なみにビットレートを盛ってやらないときれいに映りませんでした。
そこで今回はcqp指定に変更しました。値は25にしています。ここらへんはお好みでどうぞ。
QSVの使い道としてWiFi接続などの帯域幅を減らす手段と想定していました。cqp指定ではビットレートの予測ができないのでイマイチこの用途には合わなくなってしまったかもしれません。
対処療法ですが、今のところ次のコマンドにして動いています。
ついでに、映像にメディア情報を書き込むShowInfoの情報に音声トラック別の情報も追加しました。言語やチャンネル数を表示します。音声フォーマット形式も表示します。音声がトランスコードされる時は括弧で括ってフォーマットを表示します。
さらについでに、メディア情報は300フレームほどで消えるのですが、その時画面左へスライドして消えるようにしてみました。ちょっとdrawtextの使い方を試して見たかっただけです。機会があればフェードアウトも試して見たいです。
それでは新しいLuaスクリプトを BMS2用Luaスクリプト ページに置いておきます。
なんとか動くようになったのでLuaスクリプトを修正しておきました。
BEER Media Server 2でQSVトランスコードができなくなっていました。BMS2のままではエラーを詳しく見れないのでコマンドラインで試して見ます。トランスコードには4つのコマンドで行います。
いままでのトランスコードは次のようなコマンドになっていました。TEST.mkvというメディアファイルからQSVEncCを使ってa.tsというファイルを作っています。4つのコマンドはパイプによりデータを受け渡しています。
- ffmpeg.exe -v 0 -ss 00:10:30 -i TEST.mkv -c:v rawvideo -r 30000/1001 -pix_fmt yuv420p -an -f yuv4mpegpipe -threads 6 -y -
- QSVEncC.exe --y4m --tff -i - --output-res 1920:1080 --sar 1:1 --vbr 4000 --maxbitrate 12000 --quality high --vpp-deinterlace none --vpp-denoise 20 --vpp-detail-enhance 15 --slices 0 --videoformat ntsc --gop-len 30 --scenechange -o -
- ffmpeg.exe -v 0 -f h264 -i - -f avi -vcodec copy -an -y -
- ffmpeg.exe -f avi -i - -ss 00:10:30 -i "TEST.mkv" -c:v copy -c:a ac3 -ar 48000 -async 1000 -f mpegts -mpegts_m2ts_mode -1 -packetsize 188 -threads 2 -y "a.ts"
1.では元の映像トラックをQSVEncC用のyv12形式に変換します。
2.ではQSVにより映像がH.264/ES形式で出力されます。
3.はおまじないです。映像と音声をmuxするのですが、2.の出力を直接muxしようとすると何故かうまくいきません。
4.では変換された映像と元ファイルの音声をmuxしm2ts形式で出力します。
FFmpeg Ver.2.1.4では問題なく動いていましたがVer.2.2以降では4.でエラーが発生するようになりました。
エラーはこんなやつです。
[mpegts @ 057e0ae0] first pts value must be set
av_interleaved_write_frame(): Invalid data found when processing input
[mpegts @ 057e0ae0] first pts value must be set
pts valueの初期値を設定しろ みたいなエラーです。
何を意味してるのでしょうか?
最初は音声と映像の開始時間が不明確なためかなと思ったのですが違う感じです。
そもそもptsって何? mpeg2には2つの時間が記録されているようです。 dtsとptsというやつです。なぜ2種類あるのか? mpeg2など圧縮されたフォーマットでは表示する時間順にデータが並んでいるというわけではないのです。前後フレームの差分だけのデータがあったりしますので1枚のフレームを作るのに過去と未来のデータが必要だったりします。デコード・エンコードに必要なデータの時刻と表示する映像の時刻が別々に管理されています。
ptsというのは表示用の時間です。
つまり、4.の処理でパイプから入ってきたデータのptsに問題があったという事でしょう。
それではなぜ以前のバージョンでは問題なかったのでしょうか? 映像入力の処理が何か変わったのでしょうか? 1.の映像出力時点でおかしいのでしょうか? うーん、判りません。
とりあえず対処療法で改善するか試します。
ptsが無いなら作ればいいのです。そのためのコマンドがFFmpegにはあります。 "-fflags"オプションの"genpts"というやつです。
- ffmpeg.exe -fflags genpts -f avi -i - -ss 00:10:30 -i "TEST.mkv" -c:v copy -c:a ac3 -ar 48000 -async 1000 -f mpegts -mpegts_m2ts_mode -1 -packetsize 188 -threads 2 -y "a.ts"
しかし、ローカルで再生する分には良かったのですがBMS2でビエラへ送ると100フレームほどで映像が停まってしまいます。音声は出ているようです。
音声と映像のタイムコードがズレまくるとありそうな症状ですが、全く原因の推測ができませんでした。もしかしたらコマンドを書き間違えただけかもしれませんが。
こうなったら対処療法です。試行錯誤を繰り返すついでにQSVのエンコード指定の見直しも行いました。いままではvbr指定でした。しかし、これでは動きが激しい場面での映像品質が悪すぎでQSVを使うメリットがありません。mpeg2なみにビットレートを盛ってやらないときれいに映りませんでした。
そこで今回はcqp指定に変更しました。値は25にしています。ここらへんはお好みでどうぞ。
QSVの使い道としてWiFi接続などの帯域幅を減らす手段と想定していました。cqp指定ではビットレートの予測ができないのでイマイチこの用途には合わなくなってしまったかもしれません。
対処療法ですが、今のところ次のコマンドにして動いています。
- ffmpeg.exe -v 0 -ss 00:10:30 -i TEST.mkv -c:v rawvideo -r 30000/1001 -pix_fmt yuv420p -an -f yuv4mpegpipe -threads 0 -y -
- QSVEncC.exe --y4m -i - --output-res 1920:1080 --sar 1:1 --cqp 25 --quality best --vpp-deinterlace none --slices 0 --videoformat ntsc --gop-len 30 --scenechange -o -
- ffmpeg.exe -v 0 -f h264 -i - -f avi -vcodec copy -an -y -
- ffmpeg.exe -fflags +genpts -f avi -i - -ss 00:10:30 -i "TEST.mkv" -c:v copy -c:a ac3 -ar 48000 -async 1000 -f mpegts -mpegts_m2ts_mode -1 -packetsize 188 -threads 0 -y "a.ts"
ついでに、映像にメディア情報を書き込むShowInfoの情報に音声トラック別の情報も追加しました。言語やチャンネル数を表示します。音声フォーマット形式も表示します。音声がトランスコードされる時は括弧で括ってフォーマットを表示します。
さらについでに、メディア情報は300フレームほどで消えるのですが、その時画面左へスライドして消えるようにしてみました。ちょっとdrawtextの使い方を試して見たかっただけです。機会があればフェードアウトも試して見たいです。
それでは新しいLuaスクリプトを BMS2用Luaスクリプト ページに置いておきます。
コメント
コメントを投稿