これまでの作業でAVIファイルの構造が理解できたので、製作したカメラでAVIファイルを作成、保存できるようにしてみました。ファイルの先頭に配置されるヘッダーの内容は、ファイルサイズ、フレーム・レート、フレーム数等を除けば定数とすることができ、その大きさも定まります。そこで、撮影の際の記録順序を次のようにすることにしました。
インデックス情報は、画像を撮影しながら求めることができますが、JPEG圧縮作業中は集めたインデックス情報を保存するだけのメモリがありません。そこで、いったん画像情報を全て書き込んでから最初の00dcチャンクに戻り、全ての00dcチャンクをスキャンしなおすことでインデックス情報を集めています。
こうしてどうにかAVIファイルを作成できるようになりました。動画の再生速度はAVIMAINHEADER中のdwMicroSecPerFrameで制御することができます。00dcチャンクの各画像の撮影間隔と、dwMicroSecPerFrameの値を等しくしてやれば撮影時と同じ速度で再生されますが、異なる値にしてやれば実際よりも早く再生したり、遅く再生したりすることができます。当然ながら大きな値を指定すれば、1秒あたりのコマ数(fps)が少なくなります。インターバル撮影用途では、画像の撮影間隔とその再生に要する時間を勘案してこの値を決定することになるでしょう。まだインターバル撮影機能までは用意できていないので、dwMicroSecPerFrameは200msで決め打ちにしておくことにします。
実際に撮影した動画については、次回の記事で紹介することにします。
- まず、最初の'00dc'チャンクの位置までseekします。
- さらに00dcチャンクのサイズ分だけseekします。圧縮画像のサイズが未知なので、実際のdc00チャンクの内容は後から書き込みます。
- OV7670から画像を取得し、取得画像をJPEG圧縮しながら、ファイルに書き込みます。
- 圧縮画像のサイズが求まるので、いったんチャンクの先頭に戻って00dcチャンクのデータを書き込みます。その後、画像の終わりの位置に戻ります。
- 2~4の処理を繰り返します。画像記録を終了したならば、各00dcチャンクの位置を求めてインデックスを作成します。
- ファイルの最後の部分に、インデックス情報を書き込みます。
- ファイル全体のサイズが決定されたので、最後にファイルの先頭にRIFFヘッダーを書き込みます。
インデックス情報は、画像を撮影しながら求めることができますが、JPEG圧縮作業中は集めたインデックス情報を保存するだけのメモリがありません。そこで、いったん画像情報を全て書き込んでから最初の00dcチャンクに戻り、全ての00dcチャンクをスキャンしなおすことでインデックス情報を集めています。
こうしてどうにかAVIファイルを作成できるようになりました。動画の再生速度はAVIMAINHEADER中のdwMicroSecPerFrameで制御することができます。00dcチャンクの各画像の撮影間隔と、dwMicroSecPerFrameの値を等しくしてやれば撮影時と同じ速度で再生されますが、異なる値にしてやれば実際よりも早く再生したり、遅く再生したりすることができます。当然ながら大きな値を指定すれば、1秒あたりのコマ数(fps)が少なくなります。インターバル撮影用途では、画像の撮影間隔とその再生に要する時間を勘案してこの値を決定することになるでしょう。まだインターバル撮影機能までは用意できていないので、dwMicroSecPerFrameは200msで決め打ちにしておくことにします。
実際に撮影した動画については、次回の記事で紹介することにします。