土井研top/自習室/ 動画


VideoForWindowsAPI関数を用いたAVIファイル操作

目次

1.動画の取り込み
  1.1 動画と動画ファイル
  1.2 DVキャプチャシステム
  1.3 AVIファイル
2.VideoForWindowsAPIを使ったAVIファイルを扱うプログラミング
  2.1 AVIファイルを見る
	リスト1: RIFFファイルをダンプするプログラム
  2.2 非圧縮ビデオデータを表示する
	リスト2: AVIのストリームヘッダと非圧縮のDIBデータを読み出し、
		DIBデータをヘッダの情報に従ってウィンドウに表示するプログラム
		mmioOpen(), mmioClose(), mmioRead(), 
		mmioSeek(), mmioDescend(), mmioAscend()を用いる
  2.3 圧縮されたフレームを取り出す
	リスト3: 解凍の関数も含めVideoForWindowsのAVIファイル操作の関数を用いる
  2.4 連続処理〜スレッドを使ってウィンドウプログラミングから解放されよう
	リスト4: 連続処理例として各フレームの平均明度と隣り合うフレーム間の
		明度変化を計算します。コンソールアプリケーション
  2.5  音声の切り出し
	リスト5: ストリームの切り出し、AVIStreamRead()を使って音声を切り出し

 テレビのデジタル放送が目前となり、動画をハードディスクに録画できるパソコンや、 単体でVTRのように使えるハードディスク録画機まで現れてきました。 Webページも動画の表示が珍しくなくなり、カメラからの動画を 直接Webページとして送信できるWebカメラも現れ、まさに動画の時代です。

 筆者は計測系の研究者でもあるわけなのですが、 いわゆる研究室や実験室の世界でもパソコンレベルのハードウェアで実現できる 簡易かつ安価で、しかも、強力なツールとして動画が扱えるようになってきました。

 今回紹介する内容は、高圧縮なWebのストリーム配信をどう実現するかといった 最先端の動画技術ではなく、DV(デジタルビデオ)やVideoForWindowsというどちら かというと枯れた技術を計測に使うというものです。ですが、枯れているからこそ、 どのような環境でも安定したパフォーマンスが得られ、ツールとして実用に耐えうる ということにもなります。

 今回は図1に示すようにデジタルビデオカメラからの動画をAVIファイルに取り込む までは既存のシステムを使いその動画ファイルから1枚毎のフレームを切り出す方法や ストリームを切り出す方法について紹介します。

図1 DVとVideoForWindowsを利用した動画計測(zu01_blk.bmp)

1.動画の取り込み

1.1 動画と動画ファイル

 パソコンで扱える動画の種類はその細かな形式の違いも含めると大変多種に渡ります。
その原因は動画の持つ情報量の多さとそれに伴う多岐にわたる圧縮方式の存在です。
動画はアニメーションや映画と同じで複数のフレームの集合となり、データという
視点でみると、縦、横、時間という軸を持つ立方体を構成するピクセルの集合になります。
この立方体のそれぞれの軸に対して様々な圧縮が施されるので話は複雑になります。
 まず1フレームだけについて圧縮を考えるとJPEGでお馴染みのDCTやハフマン符号化が
あります。これを空間圧縮と呼びます。
このフレームを時間軸に沿って並べると、隣り合うフレーム間で相関が大きいことから
フレーム間の差分を計算することで時間軸の圧縮が行えます。
この差分も動きという視点でみる、さらに圧縮できることから
動き補償予測という技術を使ってもう1段の圧縮が行えます。これらの圧縮を時間圧縮
と呼びます。
 空間圧縮、時間圧縮を共に行っているものの代表的なものがMPEGで、
今回取り上げる、DVやIR32(IntelIndeo)のAVIファイルは空間圧縮のみを行っています。
また一般にノンリニア編集と呼ばれるパソコン上でのビデオ編集では
時間圧縮を行った状態では直接編集が行えないものもあります。
 空間圧縮を行っているAVIファイルについてもその圧縮方法により多くの種類が存在します。
またその圧縮が解凍できるかどうかはWindowsを使用する場合、OSに組み込まれている
CODECの状況に依存します。
 現状のWindowsで動画を扱う場合、VideoForWindowsとDirectShowの2つの系列が
用意されています。VideoForWindowsは従来のWin32APIと同様にAVIファイルを扱う
API関数群で構成され、DirectShowはマルチメディア機能を充実させるための
DirectXMediaの機能の1つとして実装されています。
 DirecShowでは多くのコーディックがDirectShow自体に実装されていますが
VideoForWindowsではWindowsに組み込む形で新しいコーディックを追加します。
 ですから同じパソコン上であっても、DirectShowベースのアプリケーションの
WindowsMediaPlayerで再生できても
VideoForWindowsベースのアプリケーション、たとえばプレミア/アドビで再生できない、
あるいはその逆といったファイルが存在することになります。
 デジタルビデオカメラの圧縮方法をそのままAVIファイルに適応させたのが
DV形式のAVIファイルです。このDV-AVIファイルには
Type1DV-AVI(AVI2と呼ぶ場合もある)とType2DV-AVIの2つの形式があり、
Type1DVはDirectShowからしかアクセスできません。これらの関係を図3に示します。

図2 デジタルビデオ、デジタルムービーの歴史(zu02_his.bmp)

図3 VideoForWindowsとDirectShow(zu03_vfw_ds.bmp)

1.2 DVキャプチャシステム

 いくつかの機種、ソフトを例にDVキャプチャがどのように行われているかを
説明します。ここでは、一般的なwindowsパソコンとしてWindows98SE搭載の
ThinkPad570にPCカード型のIEEE1394インターフェース
IOデータ社GV-DVC/CBとメルコ社のIFC-ILCB/DVを付属ドライブソフトと共に組み込んだ場合と
マルチメディアパソコンのVAIO-R51をとりあげます。
 GV-DVC/CBとIFC-ILCB/DVはハードウェアはよく似た構成ですが、付属ソフトは
かなり異なります。GV-DVC/CBではDV用のCODECとしてType2DVと
松下、IOデータの共同開発と説明されている、参照型DVの2種類の
VideoForWindows用CODECが追加されます。一方のIFC-ILCB/DVに付属するキャプチャソフト
UreadVideoStudio単体ではVideoForWindows用のCODECは追加されません。
ですか、DirectShow経由でType1DV-AVI、Type2DV-AVIともに
扱うことができます。またIFC-ILCB/DVではVideoStudioと合わせてNetShowも組み込まれるため
NetShowの1部としてVideoForWindows用のMPEG4のCODECが追加されます。
VAIO-R51にはDV以外にMPEG2などさまざまなマルチメディア機能が
実装されていますが、VideoForWindowsのCODECとしてはSONY製のDV-CODECが
追加されています。
 これらの各種DVキャプチャソフト、DVキャプチャソフトでの
DV-AVIファイルの種類の選択の様子、組み込まれたVideoForWindows用CODECの一覧を
図4、図5、図6に示します。windowsへのCODECの組み込み状態は windowsディレクトリの
windows.ini の [drivers32] のセクションを見れば分かります。
 これらのことから同じWindows、同じデジタルビデオカメラを使う場合でも、DVキャプチャ
システムの違いによって相互にファイル交換ができない場合が生じることになります。
各DVキャプチャシステムの機能、互換性について表1にまとめます。
併せて、各CODECの違いによるAVIファイルのサイズの一覧を表2に示します。

a.IOデータ社 DVworks  (zu04a_io.bmp)		
b.Uread VideoStudio3.0SE (zu04b_uread2.bmp)	
c.DVgate motion      (zu04c_v.bmp)
図4 各種DVキャプチャソフト

  
(a)DVworks	      (zu05a_io.bmp) 
(b)Uread VideoStudio3.0SE (zu05b_u.bmp)
図5 DV-AVIファイルの選択画面


(a)ThinckPad570単体                   (zu06a_th.bmp)	
(b)ThinkPad570 + GV-DVC/CB(I/Oデータ) (zu06b_io.bmp) 
(c)ThinkPad570 + IFC-ILCB/DV(メルコ)  (zu06c_un.bmp)   
(d)VAIO R51                           (zu06d_v.bmp)	
図6 VideoForWindowsのCODECの状態

表1 DVキャプチャシステムの機能、ファイル互換一覧(hyo1.txt)                     

表2 各CODECによるAVIファイルのサイズ:
┌─────────┬───────────┐                                           
│圧縮形式         │	サイズ(バイト)     │                                          
├─────────┼───────────┤                                           
│非圧縮AVI         │	315,525,632         │                                   
│Type1DV-AVI       │	 36,521,984         │                                           
│Type2DV-AVI       │	 37,735,232         │                                           
│IR32  65%         │	  8,870,032         │                                             
│IR32 100%         │	 15,148,668         │                                              
│MPEG4 V1          │	  6,177,328         │                                              
│MPEG4 V2          │	  6,165,890         │                                       
├─────────┴───────────┤                                            
│ファイルは720*480画素、24ビットカラー     │                                           
│303フレーム10.11秒の動画と                │                                       
│32kHz、16ビット、ステレオ、非圧縮音声。   │                                         
│ただしIR32のみ640*480画素に縮小           │                                     
└─────────────────────┘                                            

1.3 AVIファイル

 AVIとはAudio Video Interleave の略です。本来の意味は「ビデオ」と「オーディオ」を
「交互に(Interleave)」配置したファイルという意味になります。
マックのmovと同様にWinodwsでの代表的なメディアファイルです。
AVIファイルはRIFF( Resource Interchange File Format )形式を
とっています。RIFFは様々なリソースをひとつのファイルにするためのファイル形式で、
新しいフォーマットのリソースが出来ても基本構造の互換が保たれる構造をしています。

●RIFFファイルの構造
 RIFFファイルは図7のように階層的に構成されている複数のブロックからなっています。
このひとつのブロックのことをチャンク(塊)と呼びます。各チャンクには以下の4つの情
報をもちます。
 ・ チャンクのタイプを識別するIDフィールド(4バイト)
 ・ チャンクのデータ部のサイズ(4バイト)
 ・ データ部
 ・ データ部が奇数バイトの場合のみ1文字のNULLコード
   (チャンクのデータ部のサイズが奇数のときは、実際のデータ部サイズは+1になっています)
チャンクの種類はデータ部にサブチャンクを持つものと持たないものに分けられ、
サブチャンクを持つチャンクをRIFFチャンクとLISTチャンクと呼びます。
RIFFチャンクとLISTチャンクのデータ部の先頭4バイトはフォームタイプまたはリストタイプという
各チャンクの内容を表す識別コードです。
 RIFFファイルの最上位のチャンクは常にRIFFチャンクです。RIFFチャンクのフォームタイプには
'AVI'や'WAVE'というようにファイルに保存されるデータの形式を表す4文字が入っています。
LISTチャンクのリストタイプも同様に'hdrl'や'movi'などのようにリストの内容を示す4文字が入
っています。RIFFファイルでサブチャンクを持つチャンクは、ファイル先頭のみRIFFチャンクであり
それ以外はすべてLISTチャンクです。

図7 RIFFファイルの構造(zu07_rif.bmp)

●AVIファイルの構造

 図8のようにAVIファイルは多重の階層構造になっています。この図7の例は、ビデオストリームがひとつと
オーディオストリームがひとつのAVIファイルです。この例に沿ってAVIのファイル構造を説明します。
 先頭のRIFFチャンクのフォームタイプは'AVI'です。この下にはLIST(hdrl)チャンク、JUNKサブチャンク、
LIST(movi)チャンク、idx1サブチャンクという4つの子があります。
 ・LIST(hdrl)チャンク
   ヘッダ情報を保存しています。「avihサブチャンク」と、ストリームの数だけ「LIST(strl)チャンク」が
   続きます。「avihサブチャンク」はAVIファイル全体の情報を保存しています。
   「LIST(strl)チャンク」は各ストリームの「ヘッダチャンク(strhサブチャンク)」、
   「フォーマットチャンク(strfサブチャンク)」、「オプションデータチャンク(strnサブチャンク)」
   の3つのサブチャンクをもちます。「フォーマットチャンク」はオーディオストリームの場合は
   WAVEFORMAT(or PCMWAVEFORMAT)構造体、ビデオストリームの場合はBITMAPINFO構造体です。
 ・JUNKサブチャンク	データ境界を2048byte単位にするためのダミーデータです。
 ・LIST(movi)チャンク
   実際のオーディオやビデオのデータが入っています。各サブチャンクの識別子の先頭2文字はストリーム番号、
   後ろ2文字はデータのタイプを示します。主なデータのタイプは、'db'(非圧縮のデバイスに
   依存しないビットマップ(DIB))、'dc'(圧縮したDIB)、'wb'(WAVEデータ)等です。
      例えば'00db'は「ストリーム番号0の非圧縮DIB」を意味します。
   これらのデータチャンクはLIST(rec)チャンクにグループ化されることもあります。
 ・idx1サブチャンク
   各チャンクの再生順にAVIINDEXENTRY構造体が並んでいます。この順にしたがってチャンクを再生していきます。
      idx1サブチャンクがない場合はファイル内のチャンクの物理的な順番(記録されている順)
      にしたがって再生します。

表3 AVIINDEXENTRY構造体
          typedef struct {
            DWORD    ckid;              //チャンク識別子('00db', '00wb'等)
            DWORD    dwFlags;
            DWORD    dwChunkOffset;     //チャンクの位置
            DWORD    dwChunkLength;     //チャンクのサイズ
          } AVIINDEXENTRY;


図8 AVIファイルの構造(zu08_avi.bmp)

●ビデオストリームの圧縮
  AVIファイル内のビデオストリームは連続するビットマップで表されますが
一般に非常にサイズが大きくなるため、ほとんどの場合圧縮されています。
圧縮の形式はIntelIndeoやCinepak、DV、MPEGなど多くの形式がありますが、各形式に
対応したcodec(圧縮/展開を行なうドライバ)をシステムにインストール
することによってVideoForWindowsで展開が可能になります。


2.VideoForWindowsAPIを使ったAVIファイルを扱うプログラミング

2.1 AVIファイルを見る

 動画を取り巻く環境をざっと勉強しました。次は実際にAVIファイルを見てみることにしましょう。
 リスト1はRIFFファイルをダンプするプログラムです。
「開く」ボタンでダンプを行うファイルを指定します。
画面左上のリストコントロールにはファイル全体のRIFFチャンクの
インデックスが表示されます。インデックスでチャンクを選択し、
「Dump」ボタンを押すと選択したチャンクのデータ部を16進で表示します。
各チャンク内のデータは非常に大きくなることもありますのでDumpの上限を
指定できるようにします。
 このプログラムではRIFFファイルのインタフェースとしてCの基本ファイル関数
fopen()、 fclose()、 fread()、 fseek()、 ftell() を用います。

●ウィンドウを開く : WinMain(),dlgproc()
 メインのウィンドウはDialogBoxParam()によってダイアログボックスで構成されます。
ダイアログボックスプロシージャdlgproc()では「Dump」ボタンを押されたときの処理と
「開く」ボタンを押されたときの処理を行います。

●チャンクインデックスの表示 : chunk_display(), chunk_1(), set_data()
 ファイルの最初12バイトを読み込み、階層構造になっているRIFFファイルを
chunk_1()で再帰的に検索していきます。検索の際、各チャンクのデータ開始位置・サイズは、
共にグローバル変数chunk[MAX_CHUNK_N]とchunk_size[MAX_CHUNK_N]に保存して行きます。
chunk_1()は引数にウィンドウハンドルhwnd、RIFFファイルポインタhm, チャンクサイズc_size、
階層の深さdpを持ちます。ftell()で現在のファイルの位置をpos0に取得し、
チャンクの先頭8バイトを読み込みます。チャンクがLISTチャンクであれば階層の
深さを1増やしてchunk_1()を再帰呼び出しします。一方サブチャンクであれば
データ部を読み飛ばし(データ部が奇数の場合は「データサイズ+1」バイト分読み飛ばす)、
チャンク先頭からの距離とチャンクサイズを比較し当該階層の終端チェックを行います。

●選択されたチャンクデータのダンプ表示 : dump_display()
 リストボックスで選択されたチャンク位置までchunk[MAX_CHUNK_N]によって
fseek()でシークします。その上でデータ部を順に読み込み、16進で表示します。


リスト1(list1.h、list1.cpp、list1.rc)
図9 リスト1の実行画面:Type2DV-AVIファイルをダンプする

2.2 非圧縮ビデオデータを表示する

 リスト1の実行結果から分かるように、動画のAVIファイルであっても1フレーム毎のデータは
独立していて、これを選択して読み出せば1フレーム毎のデータが取り出せます。
 リスト2はAVIのストリームヘッダ( LISTチャンク'strl'内のサブチャンク'strh'と'strf' )と
非圧縮のDIBデータ( LISTチャンク'movi'内のサブチャンク'00db' )を読み出し、
DIBデータをヘッダの情報に従ってウィンドウに表示するプログラムです。
「開く」ボタンで表示を行うAVIファイルを指定します。
リストコントロールにはストリームヘッダの情報が表示されます。
「表示」ボタンを押すとテキストボックスに指定された表示フレームのDIBデータを
サブウィンドウに表示します。「←戻る」「進む→」ボタンで前後フレームを表示します。
 このプログラムではRIFFファイルのインタフェースとしてWin32APIの
マルチメディアファイル入出力関数 mmioOpen(), mmioClose(), mmioRead(), 
mmioSeek(), mmioDescend(), mmioAscend()を用います。

●ウィンドウを開く : WinMain(),dlgproc()
 メインのウィンドウはlist1と同じくDialogBoxParam()によってダイアログボックスで
構成されます。ダイアログボックスプロシージャdlgproc()では「開く」ボタンを
押されたときの処理と「表示」「←戻る」「進む→」ボタンを押されたときの処理を行います。
 「開く」ボタンを押されたときには、ファイルダイアログからファイルを指定し、
mmioOpen()でMMIO_READ|MMIO_ALLOCBUF(読取り専用、バッファ付き入出力)属性でオープンします。

●ヘッダ情報の表示 : header_display()
 ファイルヘッダから順にmmioDescend()を用いてAVIチャンクを探し、さらにhdrlチャンクを探し、
その中でavihチャンクを探します。avihチャンクデータ(AVIMainHeader構造体)を読み込み、
mmioAscend()でavihチャンクの外部へ移動します。この時点で階層位置は AVI->hdrl 
になっています。さらに下の階層のstrlチャンク、さらに下のstrhチャンクと探していき
データ部(AVIStreamHeader構造体)を読み込みます。同様にstrhチャンクの外部へ移動
(AVI->hdrl->strl)し、strfチャンクを探し、データ部(BITMAPINFO構造体)を読み込みます。
mmioAscend()で順にチャンクの外部へ移動し、階層AVIまで戻ります。
 moviチャンクを探し、フレームの再生順を記述しているidx1チャンクを探します。
idx1チャンク内の00dbチャンクを順に読み込み、INX0構造体(list2プログラム内で定義)に
各フレームの位置、大きさを記録します。AVIINDEXENTRY構造体のdwChunkOffsetメンバは
チャンク位置を示しますが、AVIファイルによっては、その意味がファイル内の絶対位置
の場合とmoviチャンク内の相対位置の場合の2種類があるようです。
リスト2ではその判定は先頭フレームのoffset値が4以下ならmoviチャンク内の
相対位置と判断しています。

●選択されたフレームの表示 : frame_make(), frame_display(), DataWndProc()
 frame_make()は指定されたAVIファイルのDIBデータのサイズにしたがって表示ウィンドウを
設定します。現在表示対象のフレームはINX0構造体のc_frameメンバで与えられます。
frame_display()で表示対象フレームのDIBデータをmmioRead()で読み込み、DataWndProc()で
SetDIBitstoDevice()を用いて描画します。

●非圧縮AVIファイルの用途
 リスト2は、チャンク内のデータをそのままDIBのデータとして表示していますので、
非圧縮のAVIファイルしか扱えません。表2を見ると非圧縮のファイルのサイズが
非常に大きくなることが分かります。はたしてこのような形式は実用に耐えるのでしょうか。
 答えはイエスです。たとえば圧縮を嫌う用途や、静止画を適当なインターバル(以上秒のオーダ)
をとりながら記録する場合などは非圧縮AVIファイルが利用できます。またアナログの
ビデオキャプチャボードのキャプチャソフトは非圧縮AVIファイルだけを出力するものもあります。
図10にリスト2の実行画面を示します。

リスト2 非圧縮AVIファイルの表示(list2.h、list2.cpp、list2.rc)

図10 リスト2の実行画面(zu10_l2.bmp)

表4 マルチメディアファイルの基本操作関数(hyo4.txt)
     
表5  チャンクを操作する関数(hyo5.txt)      

2.3 圧縮されたフレームを取り出す

  次に今回のテーマのデジタルビデオのキャプチャによって作られる、
DV-AVIファイルからのフレームの切り出し方法を紹介します。
先にも解説したようにDV-AVIファイルはVideoForWindowsで読み出すことのできるType2DV-AVI形式
と一般的なAVIファイルの構造と異なるType1DV-AVI形式(AVI2と呼ばれる場合もある)があります。
現状ではこれらは混在して使われている状況で、VideoForWindowsによる処理を行うのであれば、
Type2DV-AVI形式のファイルが出力できるキャプチャシステムを選択する必要があります。
 DV-AVIファイルの各フレームは圧縮されているので画像処理のために
フレームの各ビットを取り出すには解凍の作業が必要です。VideoForWindowsには
この解凍作業を行うAVIが用意されています。リスト3ではこの解凍の
関数も含めVideoForWindowsのAVIファイル操作の関数を利用して組み立てます。
 VideoForWindowsのAVIファイル操作の関数では、ファイル全体と各フレームデータとの間に
ストリームという概念を導入します。mmio系の関数も含め通常のファイルアクセスでは、
ファイルをオープンして、そのファイルハンドルを用いてみ書きするという手順をとりますが、
VideoForWindowsによるAVIファイルのアクセスでは、ファイルをオープンしてストリームを取り出し、
そのストリームのハンドルでデータをアクセスするという手順をとります。
 リスト3はユーザインターフェースはリスト2を流用し、
ファイルアクセス部分をmmio系のAPIからAVI系のAPIに変更しています。
AVI系のAPIではファイル全体の情報をAVIFILEINFO構造体、
ストリームの情報をAVISTREAMINFO構造体に持ちますが、この内容はAVIファイルの
avihチャンクのMainAVIHeader構造体とビデオストリーム用のLIST(strl)チャンクの
AVIStreamHeader構造体が持つ内容に対応しています。  

リスト3 圧縮AVIファイルの表示(list3.cpp、ヘッダ、リソースはリスト2と同じ)

図11	リスト3の実行画面(zu11_l3.bmp)

表6 AVIファイルのオープンに関連する関数(hyo6.txt)

表7  AVIストリームを操作する関数(hyo7.txt)

表8 圧縮フレームを操作する関数(hyo8.txt)

2.4 連続処理〜スレッドを使ってウィンドウプログラミングから解放されよう

 前節のように、VideoForWindowsのAVI系API関数を使えば動画から1枚ごとのフレームが解凍された
ピクセルデータとして取り出せることがわかりました。動画を使った計測を行うのであれば、
この解凍作業をループをつかって各フレームについて連続的に行い、
計測として必要な画像に対する特徴抽出などの計算を行えばよいことになります。
ところが、各フレームのモニタを行うなどウィンドウを扱う部分も処理に併設しようとすると
ウィンドウのメッセージループと処理ループとを両立させないといけないという問題が生じます。
この問題を解決する1つの方法がメッセージループ処理のスレッドを設ける方法です。
 リスト4は連続処理例として各フレームの平均明度と隣り合うフレーム間の明度変化を計算します。
計算だけならmain()でフレームのループを作ってフレーム毎に計算するだけですみますが、
リスト4では処理対象フレームのモニタも可能にしています。
 リスト4は最初にモニタウィンドウ用のスレッドを起動して、そのスレッドでモニタウィンドウのための
メッセージを処理します。また、リスト4では画像の計算処理にAVIファイルハンドルは
直接必要ありませんから、「AVIファイルのオープン」→「ストリームのオープン」を
1度に行うAVIStreamOpenFromFile()を使ってストリームハンドルを得ます。 
 図12に連続計算処理中の様子、図13に計算結果をExcelでグラフにしたものを示します。計算対象は
ミュージックビデオクリップの一部ですが、カットが変わるところで明度変化が大きくなるなどの
特徴が見られます。

リスト4 スレッドを使った動画の連続処理(list4.cpp)

図12 リスト4の実行画面(zu12_l4.bmp)

図13 リスト4の計算結果のグラフ:
   計算対象は「スピード」のビデオクリップ「プレシャスタイム」の前半
   (zu13_gr.bmp)

 
2.5  音声の切り出し

 最後にビデオだけでなく、オーディオについての切り出しを紹介します。デジタルビデオでは
オーディオは通常、32kHzサンプリング、16ビット、ステレオ、非圧縮で記録されます。
DV-AVIファイルもこの仕様のままファイルに書き込まれます。このデータは適当なサイズに区切って
複数のwbチャンクに分割されて記録されます。このオーディオをAVIファイルから取り出す場合は、
wbチャンクを1つづつ読み出してもかまいませんが、wbチャンクの数やサイズ等を気にせず、
1つのストリームとしてファイル中のオーディオ全体を連続的に取り出すことができます。
 ストリームを連続したデータの流れ、まさにストリームとして読み出すには
AVIStreamRead()を使います。切り出しプログラムの例をリスト5に示します。
これまでのプログラムで利用したAVIファイル操作のAPIの関連を図14に示します。
 切り出した後のデータはWAVファイルとしてファイルに書き出します。
こちらの作業はmmio系のAPI関数を使います。WAVファイルもチャンクを使った構成
ですから、各チャンクをmmioCreateChunk()で作成します。
WAVファイルの構造を図15に示します。

リスト5 音声データをオーディオストリームから切り出す(list5.cpp)

図14 AVIファイルを扱うAPIの関連図(zu14_api.bmp)

図15 WAVEのデータ形式(zu15_wav.bmp)

参考文献
1)藤原洋、「画像&音声圧縮技術のすべて」、インターフェース増刊、CQ出版、2000年
2)貴家仁志、「マルチメディア技術の基礎DCT入門」、CQ出版
3)Richard J.Simon、「Windows95APIバイブル3」、翔泳社、1997年
4)高田信司、「高速デジタルインターフェ−スIEEE1394AV機器への応用」、
 日刊工業、2000年
5)エ・ビスコム・テック・ラボ、「知りたい人のためのデジタルビデオガイド」、
 毎日コミュニケーションズ、1999年
6)エ・ビスコム・テック・ラボ、「わかりやすい[目的別]デジタルビデオ出力ガイド」、 
 毎日コミュニケーションズ、2000年
7)特集「フォーマット事典」、雑誌Cマガジン1999年10月号