H.264/AVC high bit depth decoderがついにきたらしい!
素晴らしい!
そこでx264guiExを10bit(high bit)対応させてみた。
ただ、まだあちこち不具合ある。なので"(仮)"。
例えば10bitだとqpmaxの最大値変わるよね、とか
high10 profileのVBVの制限値ってhigh profileと違うよね、とか
そういうところはまだ。
ちょい忙しいので。 YC48(12bit精度)->YV12(high bit depth)は
Aviutlの内部形式についてを参考に5月に入ってから「これ役に立つ時あんのかなあ」とか思いながら、のんびり書いてた。役に立ってよかった。でも処理速度は遅いんじゃないかな…
変換式は
Aviutlの内部形式についてに8bitの時、
// YC48->YUY2
Y = ((y*219 + 383)>>12) + 16;
U = (((cb + 2048)*7 + 66)>>7) + 16;
V = (((cr + 2048)*7 + 66)>>7) + 16;
とあるので、
10bit(圧縮レンジ)なら
Y = ((y*219 + 383)>>10) + 64;
U = (((cb + 2048)*7 + 66)>>5) + 64;
V = (((cr + 2048)*7 + 66)>>5) + 64;
とすればいい(と思う)。
そいでfullrangeなら
Y = ((y*3517 + 3867)>>14) + 64;
U = (((cb + 2048)*899 + 1991)>>12) + 64;
V = (((cr + 2048)*899 + 1991)>>12) + 64;
間違っていたらご指摘ください。
ともかく、10bitってなんなのかってのがわかってる方だけ遊んでみてください。10bitって聞いてよくわからんって方はguiEx 0.32 + x264 8bit でお願いします。というわけで、
・10bit(high bit) depth
仮対応。
- x264を指定するところの右上にbit depth入力欄をつけた。
・SSE2を自動検出してみる。(調べたら簡単だった)
・その他些細な変更。
ダウンロード>>(計算式修正で"仮2")
なんかよくわからないけど早くなる感じですか?!
正式対応楽しみにしてます。
よく解っていないのでおとなしく8bit版を利用(汗
どんなものか理解した暁には使用してみたいなぁ。
>速くなる感じ
同じ設定だと遅くなるんじゃないかと。
たぶんざっくり言うと画質が上がる感じかな。
>おとなしく8bit
まだほとんどのプレイヤーでは
再生できないor色がおかしいですしね。
その計算式だと、
入力 8bits Y= 255に対して、 出力 10bits Y=1023ではなく、Y=1020が出てくるんですけど。
例えば、こんな感じにすれば入力(0, 255)に対して出力 (0, 1023)になる。
Y = ((y*1757 + 2338)>>13) + 64;
すみません、ご指摘がよくわからないです。
そもそも8bit入力しておりませんので…
Aviutl YC48(PIXEL_YC)の
入力 y(0, 4095)(12bit)から、
Y = ((y*219 + 383)>>10) + 64;
によって
出力 Y(64, 940)(10bit,YC圧縮(非フルレンジ))
が得られると考えていますが、いかがでしょう。
AviUtlはY16を0、Y235を4096にしますので、Y 0 - 255は、内部では-299 - 4470に変換されます。
> そもそも8bit入力しておりませんので…
ぇぇと...
AviUtlってhigh (>8) bits YUV入力に対応してましたっけ?
私の知っている限りでは、AviUtlは常にYUV[0, 255]の範囲で入力されると思いますが?
だとするのならば、AviUtlが入力時点で得うるYC48の最小値、最大値は[-299, 4470]のはずです。
この最小値、最大値を
Y = ((y*219 + 383)>>10) + 64;
に代入しますと、[0, 1020]が得られます。
10bits YUVの取り得る範囲は[0, 1023]のはずです。
x264ではフルレンジ出力する方もいらっしゃるかもしれませんので、これはfatalな事だと思います。
あと、
>入力 y(0, 4095)(12bit)から、
圧縮レンジ8bits YUVからの変換ではYC48では[0, 4096]です。 Y=235を
y = ((Y * 1197)>>6) - 299;
に入力したら4096が返ってきませんか?
あと、圧縮レンジの範囲は、10bitsでは[0,942]だと思ふ。
aがYUVを表す変数(変域は[0, 255])として、それを8bitsから10bitsに写像する関数をfとするなら
a = 0の時, f(a) = 0, a = 255の時, f(a) = 1023となる点を通るから、
f(a) = ((1023.0 - 0) / (255.0 - 0)) * a
= (1023.0 / 255.0) * a
より
f(235) = 942.76470588235294117647058823529
≒ 942
になると思いますがどうでしょうか。
詳しい説明ありがとうございます。
言葉が悪かったですが、私の言ってた「入力」は計算式に対する入力のことでした。もちろんAviutlへの入力は8bitです!
計算式の問題点は理解できました。理解が遅くてすみません。
Y[0,255] が y[-299,4770]
Y[16,235] が y[0,4096]
U,V[0,255] が cb,cr[-2340,2322]
U,V[16,240] が cb,cr[-2048,2048]
ですね。
まず圧縮レンジについて、ただ4倍すりゃいいやという安易な考え方を反省して、考え直してみたのですが、
8bitと10bitの対応関係を256階調が1024階調になったという点から考えると、
8bit 0 が 10bit [0,3]
8bit 1 が 10bit [4,7]
…
8bit 16 が 10bit [64,67]
…
8bit 235 が 10bit [940,943]
8bit 240 が 10bit [960,963]
…
8bit 255 が 10bit [1020,1023]
このように考えると、圧縮レンジは
8bit [16,235] は 10bit [64,943]
8bit [16,240] は 10bit [64,963]
と考えられるのではないかと。
その上で、ご指摘を反映した計算式は
Y = ((y*3517 + 3867)>>14) + 64
U = (((cb + 2048)*899 + 1991)>>12) + 64
V = (((cr + 2048)*899 + 1991)>>12) + 64
といった感じでしょうか。
計算が想定どおりいくならいいんじゃないですかね。
(出力の最小、最大がそれぞれ0, 1023になって、出力値の重複がなければそれでいいと思ふ)
UVの方は面倒なんで計算してない。
計算式がどのように導き出されたのか、よく分からんし(笑)
> 計算式がどのように導き出されたのか、よく分からんし(笑)
たしかに8bit用の計算式とかどうやって出てきたのやら。
ともかく、いろいろありがとうございました。
暇を見つけて修正します。
その前にたまったアニメ見ますがw
このコメントは管理人のみ閲覧できます
はじめまして。
10bitに関しては、まず10bit YUVがどう扱われているか把握しないといけないと思いまして、私もいろいろと調べました。
まずKENくん氏は、「10bit YUVの仕様は今のところ詳しく知らない」と前置きしたうえで、
「入力においてはYC圧縮された8bit(Y,16-235)をYC48の0-4096にマッピングするのと同様、
YC圧縮された10bitレンジも0-4096にマッピングする」という見解であるようです(これは入力に関するお話なのでここで終了)。
次に10bit YUV自体の仕様ですが、EBUのディスプレイ・映像に関する仕様3-3e(
http://tech.ebu.ch/docs/tech/tech3321.pdf )によると、
ITU-R BT.601 および ITU-R BT.709ともに10bitの圧縮Yレンジは64-940と記されており、
YC圧縮レンジ内では8bitの値を単純に2bit拡張(4倍)した値であるようです。
同じく10bits U,Vも512を中点とした64-960レンジです(他の複数の仕様書を見ても同様なので、ほぼ間違いないかと思われ)。
このことは、映像がTV屋さんの概念からIREで語られる事がベースとなっている気がします。
0IRE(Y16)~100IRE(Y235)の範囲が基準という(8bitフルレン基準でなく、YC圧縮レンジが0~100IREという見方)。
AviUtlのYUV入出力もこの考え方が適用されているのと思われ、
Y16(Y64@10bit)はYC48の0、Y235(Y940@10bit)はYC48の4096というYC圧縮レンジを基本としたマッピングですので、
10bit YUVの出力(YC圧縮フォーマット)に関しては Y64-940、U,V64-960になれば良いようです。
ここからは個人的な想像ですが、フルレンジ10bit YUV(Y0-255→Y0-1023)は異なる計算式を持っている可能性も。
こちら(
http://techpubs.sgi.com/library/dynaweb_docs/hdwr/SGI_Developer/books/OctDigVid_PG/sgi_html/ch08.html )の
色空間変換機の仕様を見ると、YC圧縮レンジとフルレンジで別のフォーマット(モード)を持っていたりするので……。
# この仮定がもしも正しければ、YC圧縮映像とフルレンジ映像で出力モードを選ぶ必要がありそうです
あとは更に調べたり、映像方面の識者に訊く必要がありそうですので、今日はこれにて失礼致します。
長文失礼しました。
普段POPさんのx264のL-SMASHビルドを使わせてもらっております。
感謝です。
また、10bitについての情報、ありがとうございます。
なるほど、圧縮レンジは
8-bit 16-235 (Y), 16-240 (Cr, Cb)
10-bit 64-940 (Y), 64-960 (Cr, Cb)
とありますね…
>YC圧縮映像とフルレンジ映像で出力モードを選ぶ必要がありそう
たしかに
YC48[0, 4096] -> 10bit [64, 940] (圧縮レンジ)
YC48[-299, 4470] -> 10bit [0, 1023] (フルレンジ)
の両方を成り立たせる共通の式は難しいですからね。
うーむ。--fullrange on/offで式を切り替えたほうがよさげですね。
まだ10bitをあまり試せてないのですが、いろいろやってみたいと思っています。