Пример #1
0
        // インデックスには、データ チャンクのリストとファイル内でのその位置が含まれている。
        // インデックスは、AVIOLDINDEX 構造体で構成され、各データ チャンクのエントリが含まれている。
        // ファイルにインデックスが含まれる場合、AVIMAINHEADER 構造体の dwFlags メンバにある AVIF_HASINDEX フラグを設定する。
        private static void WriteIdx1Chunk(RiffFile riff, List <Idx1Entry> IndexList)
        {
            const int AVIIF_KEYFRAME = 0x00000010; // 前後のフレームの情報なしにこのフレームの完全な情報を含んでいる
            var       chunk          = riff.CreateChunk("idx1");

            int offset = 4;

            foreach (var item in IndexList)
            {
                int length = item.Length;

                chunk.Write(ToFourCC(item.ChunkId));
                chunk.Write(item.KeyFrame? AVIIF_KEYFRAME: 0x00);
                chunk.Write(offset);
                chunk.Write(length);

                offset += 8 + length; // 8は多分00dcとデータサイズ
                if (item.Padding)
                {
                    offset += 1;
                }
            }

            chunk.Close();
        }
Пример #2
0
        public AviWriter(System.IO.Stream outputAvi, string fourCC, int width, int height, float fps)
        {
            // RIFFファイルは、RIFFヘッダーとその後ろに続く 0個以上のリストとチャンクで構成されている。
            // RIFFヘッダーは、'RIFF'のFOURCC、4バイトのデータサイズ、データを識別するFOURCC、データから構成されている。
            // リストは、'LIST'のFOURCC、4バイトのデータサイズ、データを識別するFOURCC、データから構成されている。
            // チャンクは、データを識別するFOURCC、4バイトのデータサイズ、データから構成されている。
            // チャンクデータを識別するFOURCCは、2桁のストリーム番号とその後に続く2文字コード(dc=ビデオ,wb=音声,tx=字幕など)で構成されている。
            // AVIファイルは、'AVI 'のFOURCCと、2つの必須のLISTチャンク('hdrl''movi')、オプションのインデックスチャンクから構成されるRIFFファイルである。

            var riffFile = new RiffFile(outputAvi, "AVI ");

            // hdrlリストを仮のフレーム数で作成
            var hdrlList = riffFile.CreateList("hdrl");

            WriteHdrlList(hdrlList, fourCC, width, height, fps, 0);
            hdrlList.Close();

            // moviリストを作成し、OnAddImageごとにデータチャンクを追加
            var idx1List = new List <Idx1Entry>();
            var moviList = riffFile.CreateList("movi");

            this.OnAddImage += (data, keyFrame) =>
            {
                var idx1 = WriteMoviList(moviList, "00dc", data);
                idx1.KeyFrame = keyFrame;
                idx1List.Add(idx1);
            };

            // ファイルをクローズ
            this.OnClose += () =>
            {
                // moviリストを閉じる
                moviList.Close();

                // idx1チャンクを作成
                WriteIdx1Chunk(riffFile, idx1List);

                // hdrlListを正しいフレーム数で上書き
                var offset = hdrlList.Offset;
                riffFile.BaseStream.Seek(offset, System.IO.SeekOrigin.Begin);        // hdrlリストの先頭まで戻る
                riffFile.BaseStream.Seek(12, System.IO.SeekOrigin.Current);          // hdrlリストのヘッダ分飛ばす
                WriteHdrlList(riffFile, fourCC, width, height, fps, idx1List.Count); // hdrlリストのデータを正しいフレーム数で上書き
                riffFile.BaseStream.Seek(0, System.IO.SeekOrigin.End);               // 元の場所に戻る

                // ファイルをクローズ
                riffFile.Close();
                outputAvi.Dispose();
            };
        }