【DivXを】__Ogg/Theora開発スッドレ__【超えろ】
■ このスレッドは過去ログ倉庫に格納されています
00011
NGNG目的
1.Theora開発プロジェクトの参加者募集
2.Theoraの性能向上・機能強化をするための提案
3.バグ報告
4.特許を抑止し、今後の技術的な選択肢の幅を広げるために様々な技術に関する提案を行う
00021
NGNGXiph
http://www.xiph.org/
Theora
http://www.theora.org/
Xiph CVS(TheoraおよびVP3のソース)
http://xiph.org/cgi-bin/viewcvs.cgi/#dirlist
【Audio/Video】ogg規格統合スレッド【OpenSource】
http://pc3.2ch.net/test/read.cgi/software/1036246672/
Ogg Vorbisプログラム
http://pc3.2ch.net/test/read.cgi/tech/1032623615/
________On2________
http://pc.2ch.net/test/read.cgi/avi/1027955774/
0003デフォルトの名無しさん
NGNG00041
NGNG0005デフォルトの名無しさん
NGNG4nd
00061
NGNG目標として、VP3の2倍の圧縮率を実現するってどうよ。
なんにせよ、VP3の構造が分からんことには話にならんので
まずはここを和訳して参考にしよう
ttp://www.pcisys.net/~melanson/codecs/
ttp://www.pcisys.net/~melanson/codecs/vp3-notes.txt
00071
NGNG前書き
0n2という名の会社がVP3というビデオコーデックを作った。
やがて、On2はこのコーデックをオープンソース化し、On2のwebサイトにソースを公開した。
数多のソースコードと同様に、このソースを追っていくことは、初めは非常に難しかった。しかし、
やがて徐々に理解できるようになる。このドキュメントに、私が、VP3のデコーダーがどの様なデータストリームを実装し、どの様にフレームを再構築するのか解析した結果を記す。
ただし、ここに記されているものは、あくまでメモ書き程度のもので、VP3の完全な仕様ではない。
このノートもいまだ不完全であが、VP3を理解しようとするにあたり、役立ててほしい。
また、VP3の仕様を完全に解明するために、皆様からの意見もE-mailにて募集している。
また、VP3のソースコードを調査することは、可変長ラン・レングス圧縮という概念に基づいた
圧縮技術を扱う私の初めての試みであることも心に留めておいてほしい。なぜならば、このノ
ートにも時々この概念が出現するからである。
00081
NGNGRead onってどう訳すんだろう?
00091
NGNGソースコードを理解するに当たり、重要な概念を以下に記す。
cx:エンコーダー
dx:デコーダー
pp:ポストプロセッシング
mv:動きベクトル
df:ディスプレイフラグメント
sb:スーパーブロック(32x32ピクセルで構成されるらしい)
mb:マクロブロック(16x16ピクセルで構成される)
ブロックは8x8ピクセルで構成される。
フラグメントは、ブロックと同じように見える。
ゆえに、スーパーブロックの中に4個のマクロブロックがあり、
マクロブロックの中に4個のブロックがある。
CoreLibs\CDXV\Vp31\dx\generic\DFrameR.cの中の
BOOL ValidateImageSize( UINT32 Width, UINT32 Height )関数によると
利用できるフレームサイズは以下のようになる。
128x96
160x112
176x144
192x144
240x176
256x256
320x240
352x288
384x288
しかしながら、この関数はVP3のソースコードの中では呼ばれていない。
加えて、デコーダは奇怪なフレームの形状をサポートするためのコードを持っている。
00101
NGNG縦、および横のピクセル数が16の倍数であるという制約のみで、
640x480や、さらに上のフレームサイズを実現できる。
00111
NGNGVP3のライブラリは、pbi構造体に数多の再生用パラメータを定義している。
FrameIni.cのInitFrameDetails()関数において、
再生用パラメータの初期設定を行う。
再生パラメータを以下に記す。
- YPlaneSize = width * height
- UVPlaneSize = YPlaneSize / 4
- HFragments = width / HFragPixels
- VFragments = height / VFragPixels
- UnitFragments = (VFragments * HFragments) * 3 / 2
- YPlaneFragments = HFragments * VFragments
- UVPlaneFragments = YPlaneFragments / 4
- YStride = width + STRIDE_EXTRA -> (32) (STRIDE_EXTRA = UMV_BORDER * 2) (UMV_BORDER = 16)
- UVStride = YStride / 2
- ReconYPlaneSize = YStride * (height + STRIDE_EXTRA)
- ReconUVPlaneSize = YPlaneSize / 4
- YSBRows = (height / 32) + (height % 32) ? 1 : 0 (height / 32, rounded up)
- YSBCols = (width / 32) + (width % 32) ? 1 : 0 (width / 32, rounded up)
- similar calcs for UVSBRows, UVSBCols
- YSuperBlocks = YSBRows * YSBCols
- UVSuperBlocks = UVSBRows * UVSBCols
そして、FrameInfoとFragCoordinatesの領域に配置し、各フラグメント(ブロック)
の座標を初期化する。それは、全てのブロック、マクロブロック、スーパーブロック
間の配置を作るのに適しているとがわかる。最後に、ピクセルインデックステーブルの
初期化を行う。
0012山崎渉
NGNG00131 ◆KREjpauFo.
NGNGデコードフローの全体は、おおよそ次に示すようになると思われる。(末尾の付録に掲載している)
-> int LoadAndDecode(PB_INSTANCE *pbi) (vfwPback.c)
-> BOOL LoadFrame(PB_INSTANCE *pbi) (DFrameR.c)
-> BOOL LoadFrameHeader(PB_INSTANCE *pbi) (DFrameR.c)
-> void InitQTables( PB_INSTANCE *pbi ) (Quantize.c)
-> void SelectHuffmanSet( PB_INSTANCE *pbi ) (Huffman.c)
-> void ReadAndUnPackDFArray( PB_INSTANCE *pbi ) (Frarray.c)
-> void QuadDecodeDisplayFragments ( PB_INSTANCE *pbi ) (Frarray.c)
-> void GetNextSbInit(PB_INSTANCE *pbi) (Frarray.c)
-> void DecodeData(PB_INSTANCE *pbi) (DDecode.c)
-> void DecodeModes( PB_INSTANCE *pbi, UINT32 SBRows, UINT32 SBCols, UINT32 HExtra, UINT32 VExtra ) (DDecode.c)
-> void DecodeMVectors ( PB_INSTANCE *pbi, UINT32 SBRows, UINT32 SBCols, UINT32 HExtra, UINT32 VExtra ) (DDecode.c)
-> void UnPackVideo (PB_INSTANCE *pbi) (unpack.c, or system dependent)
-> void ClearDownQFrag(PB_INSTANCE *pbi) (DCT_Decode.c)
(mapped to ClearDownQFragData())
-> void UnpackAndExpandDcToken( PB_INSTANCE *pbi, Q_LIST_ENTRY * ExpandedBlock, UINT8 * CoeffIndex ) (unpack.c)
-> void UnpackAndExpandAcToken( PB_INSTANCE *pbi, Q_LIST_ENTRY * ExpandedBlock, UINT8 * CoeffIndex ) (unpack.c)
-> void ReconRefFrames (PB_INSTANCE *pbi) (DCT_decode.c)
00141 ◆KREjpauFo.
NGNGLoadFrameHeader()関数によると、フレームの第1バイトは次のように使われる。
bit 7: 0 = intra frame、 1 = inter frame
bit 6: 未使用
bit 5-0: クォリティ(Q)インデックス(DctQMask変数に格納)
キー(ベース)フレームを読み出した場合、LoadFrameHeader()は、バージョン情報
とキーフレームタイプを取得し、定数配列をコピーしてQインデックステーブルを初期化する。(ソースコードによると、Qインデックステーブルはバージョン固有らしい)
一つ疑問点として、Qインデックステーブルはプログラム実行中は不変であるのに、
キーフレームを読み出すたびに初期化する必要があるのだろうか?
キーフレームの最初の2バイトを次のように使用する。
byte 0: version byte 0(何も使用しない)
byte 1:
bit 7-3: VP3 version番号(0はVP31もしくはそれ以下であること示す)
bit 2: キーフレームの圧縮方法(0 = DCT、DCT以外存在しない)
bit 1-0:未使用
キーフレームであった場合、SelectHuffmanSet()関数も呼び出すが、
この関数はストリームからは何も読み出さない。LoadFrameHeader()関数の
最後で、Qインデックスを使用してQインデックステーブルから量子化係数を設定する。
00151 ◆KREjpauFo.
NGNG設定してるのは量子化行列ではなく、量子化"定数"をQ値から
求めるための変換テーブルを初期化している。
プログラム中で使用しているQ値は、エンコーディング設定の"画質ALQ"で
設定する値の対極値(63-ALQ)が使用される。
■ このスレッドは過去ログ倉庫に格納されています