TheoraLib - MovieDecoder


目次

概要

theoralib_m_create
theoralib_m_free
theoralib_m_init
theoralib_m_load
theoralib_m_exists
theoralib_m_decodeframe
theoralib_m_setvrevers
theoralib_m_setdecodemode
theoralib_m_nowframe
theoralib_m_totalframe
theoralib_m_totaltime
theoralib_m_info
theoralib_m_comment


概要

動画をデコードし、任意フレームの画像を取得するためのMovieDecoderクラスです。
とはいっても、DLL上でのものですから普通のクラスのようには扱えません。
DLL側の命令を使って、生成、使用、解放を制御します。


theoralib_m_create

function theoralib_m_create:Pointer;

RESULT...MovieDecoderClassアドレス

MovieDecoderクラスを生成し、アドレスを返します。
以後はこのアドレスを用いて操作を行います。


theoralib_m_free

procedure theoralib_m_free(
  ptr:Pointer               //MovieDecoderClassアドレス
);

MovieDecoderクラスを解放します。
忘れずに。


theoralib_m_init

procedure theoralib_m_init(
  ptr:Pointer                //MovieDecoderClassアドレス
);

初期化します。
Load前に戻します。


theoralib_m_load

function theoralib_m_load(
  ptr:Pointer;                         //MovieDecoderClassアドレス
  datasource:Pointer;                  //データソースアドレス
  readfunc:Ttheoralib_cb_read;         //データソースreadコールバック関数
  sizefunc:Ttheoralib_cb_size;         //データソースsizeコールバック関数
  bmpsource:Pointer;                   //ビットマップソースアドレス
  scanlinefunc:Ttheoralib_cb_scanline; //ビットマップscanlineコールバック関数
  resizefunc:Ttheoralib_cb_resize;     //ビットマップresizeコールバック関数
  decodefunc:Ttheoralib_cb_decode      //YUV変換decodeコールバック関数(NULL/nil指定可能)
):Integer;

Theoraファイルを読み込みます。
この命令を行う前に、あらかじめデータソース対象となるストリームにファイルを読み込ませておく必要があります。
各種コールバック関数については「コールバック関数」を参照してください。
成功すると1、失敗すると0を返します。

コールバック関数は、最後の「decodefunc」以外は必ず用意してください。
データソースアドレスとコールバック関数は「WaveDecoder」クラスと同じものを共有することが可能です。

読み込みが行われると、ファイル全体のパケット情報を取得し、シーク情報を生成します。
読み込みにはそれなりの処理負荷と読み込み負荷がかかることに留意してください。

//転送先ARGB32BitBitmap
bmp := TBitmap.Create;
bmp.HandleType := bmDIB;
bmp.PixelFormat:= pf32bit;
bmp.Width:=8;
bmp.Height:=8;

//DataStream
stream := TMemoryStream.Create;
stream.LoadFromFile('sample01.ogv');

//TheoraMovieDecoder
movie := theoralib_m_create;
theoralib_m_setvrevers(movie,1); //上下反転
theoralib_m_load(
  movie,
  stream,cb_read,cb_size,    //データストリームポインタとコールバック関数
  bmp,cb_scanline,cb_resize, //ビットマップポインタとコールバック関数
  nil                        //デコードコールバック関数。使用しないのでNULL
);
//TheoraWaveDecoder
wave := theoralib_w_create;
theoralib_w_load(
  wave,
  stream,cb_read,cb_size       //データをMovieDecoderと共有
);

水色の部分がデータソースの共有です。


theoralib_m_exists

function theoralib_m_exists(
  ptr:Pointer                //MovieDecoderClassアドレス
):Integer;

RESULT...0:なし / 1:あり

映像情報があるかどうかを返します。
動画ですからあると思います。
無い動画は読み込みにエラーが出るかもしれません。読ませないでください。


theoralib_m_decodeframe

function theoralib_m_decodeframe(
  ptr:Pointer;                //MovieDecoderClassアドレス
  frameno:Integer             //フレーム番号
):Integer;

RESULT...0:変化なし / 1:変化有り

指定されたフレーム番号のデコード処理を行います。
Load時に指定したビットマップソースに、展開後の画像がARGB32Bitで転送されます。
内容に変化があれば1を、そうでなければ0を返します。
もし同じフレームを何度も渡した場合は、内部で最適化されて0を返します。
この戻り値を使うことで、簡単に無駄な転送処理を省くことが可能です。

r = theoralib_m_decodeframe(movie,ScrollBar1.Position);
if (r=1)then BitBlt(省略);

指定フレームを後方に移動させたり、前方に大きく移動させると、内部でシーク処理が発生します。
シーク処理の負荷はエンコード時のキーフレーム構造に依存しますが非常に重い処理ですので、基本的にはフレームは前方に+1してシーク処理を極力減らすコードを書くようにしましょう。
逆再生をやりたい場合は、エンコードでキーフレーム間隔を狭くしましょう。


theoralib_m_setvrevers

procedure theoralib_m_setvrevers(
  ptr:Pointer;                //MovieDecoderClassアドレス
  vrev:Integer                //0:そのまま / 1:上下反転
);

上下反転させてビットマップソースに転送させるかどうかを設定します。
WindowsBitmapだと上下反転されて格納するので、そのためのオプションみたいなものです。
初期設定はOFF(0)です。


theoralib_m_setdecodemode

procedure theoralib_m_setdecodemode(
  ptr:Pointer;                //MovieDecoderClassアドレス
  mode:Integer                //変換モード。説明は↓
);

・mode(変換モード)
-1..オートモード(初期設定)
0...YUV ITU-601 Digital-> RGB
1...YUV ITU-601 Analog -> RGB
2...YUV ITU-709 Digital-> RGB
3...YUV ITU-709 Analog -> RGB
4...YUV -> YUV
5...YUV -> YUV(4と同じ)

強制的に変換モードを変更します。
それぞれ微妙に変換公式が違って、色に違いが出てきます。詳しくは調べてください。
AnalogとDigitalの違いは、Analogは要素を235段階を255段階に伸長、Digitalは255段階そのままとして扱います。
4,5はそのままYUVを吐き出します。

普通は-1のオートモードでかまいません。
Loadでデコード処理コールバック関数を設定した場合は、この設定は何の意味もありません。


theoralib_m_nowframe

function theoralib_m_nowframe(
  ptr:Pointer                 //MovieDecoderClassアドレス
):Integer;

RESULT...現在のフレーム

現在の処理フレーム位置を返します。
要するに現在位置ですね。
nowtimeはありませんので、TotalTimeとTitalFrameを使って計算してください。


theoralib_m_totalframe

function theoralib_m_totalframe(
  ptr:Pointer                 //MovieDecoderClassアドレス
):Integer;

RESULT...トータルフレーム数

トータルフレーム数を返します。


theoralib_m_totaltime

function theoralib_m_totaltime(
  ptr:Pointer                 //MovieDecoderClassアドレス
):Integer;

RESULT...トータルタイム(ms)

トータルタイムを返します。
単位はミリ秒(ms)です。

あまり正確ではありません。
動画はフレーム数で扱うことが前提で設計されています。

WaveDecoderのTotalTimeとは異なる数値を返すようなので注意してください。


theoralib_m_info

function theoralib_m_info(
  ptr:Pointer                 //MovieDecoderClassアドレス
):Pointer;

RESULT...Ptheoralib_theorainfo (Ttheoralib_theorainfo構造体のアドレス)

Theoraインフォメーション情報の構造体のアドレスを返します。
以下のようにして情報を取得します。

var
  ti : Ptheoralib_theorainfo;
begin
  ti := theoralib_m_info(movie);
  Memo1.Lines.Add(format('Size %d,%d',[ti.width,ti.height]));
end;

構造体についてはソースファイルを参照してください。


theoralib_m_comment

function theoralib_m_comment(
  ptr:Pointer                 //MovieDecoderClassアドレス
):Pointer;

RESULT...Ptheoralib_theoracomment (Ttheoralib_theoracomment構造体のアドレス)

Theoraコメント情報の構造体のアドレスを返します。
theoralib_m_infoと同じようにアドレスを受け取ってください。
構造体についてはソースファイルを参照してください。