Beispiel #1
0
        // たとえば、ストリーム 0 にオーディオが含まれる場合、そのストリームのデータ チャンクは FOURCC '00wb' を持つ。
        // ストリーム 1 にビデオが含まれる場合、そのストリームのデータ チャンクは FOURCC '01db' または '01dc' を持つ。
        private static Idx1Entry WriteMoviList(RiffList moviList, string chunkId, byte[] data)
        {
            int  length  = data.Length;
            bool padding = false;

            try
            {
                var chunk = moviList.CreateChunk(chunkId);
                chunk.Write(data);

                // データはワード境界に配置しなければならない
                // バイト数が奇数の場合は、1バイトのダミーデータを書き込んでワード境界にあわせる

                padding = false;
                if (length % 2 != 0)
                {
                    chunk.WriteByte(0x00); // 1バイトのダミーを書いてワード境界にあわせる
                    padding = true;
                }

                chunk.Close();
            }
            catch (ObjectDisposedException odx)
            {
            }


            return(new Idx1Entry(chunkId, length, padding));
        }
Beispiel #2
0
        private void WriteHdrlList(RiffList hdrlList, string fourCC, int width, int height, float fps, int frames)
        {
            int streams = 1; // ストリーム数。音声なしの場合1。ありの場合2。

            // LISTチャンク'hdrl'を追加

            // 'hdrl' リストは AVI メイン ヘッダーで始まり、このメイン ヘッダーは 'avih' チャンクに含まれている。
            // メイン ヘッダーには、ファイル内のストリーム数、AVI シーケンスの幅と高さなど、AVI ファイル全体に関するグローバル情報が含まれる。
            // メイン ヘッダー チャンクは、AVIMAINHEADER 構造体で構成されている。
            {
                var chunk = hdrlList.CreateChunk("avih");
                var avih  = new AVIMAINHEADER();
                avih.dwMicroSecPerFrame    = (uint)(1 / fps * 1000 * 1000);
                avih.dwMaxBytesPerSec      = 25000;  // ffmpegと同じ値に
                avih.dwFlags               = 0x0910; // ffmpegと同じ値に
                avih.dwTotalFrames         = (uint)frames;
                avih.dwStreams             = (uint)streams;
                avih.dwSuggestedBufferSize = 0x100000;
                avih.dwWidth               = (uint)width;
                avih.dwHeight              = (uint)height;

                var data = StructureToBytes(avih);
                chunk.Write(data);
                chunk.Close();
            }

            // メイン ヘッダーの次には、1 つ以上の 'strl' リストが続く。'strl' リストは各データ ストリームごとに必要である。
            // 各 'strl' リストには、ファイル内の単一のストリームに関する情報が含まれ、ストリーム ヘッダー チャンク ('strh') とストリーム フォーマット チャンク ('strf') が必ず含まれる。
            // ストリーム ヘッダー チャンク ('strh') は、AVISTREAMHEADER 構造体で構成されている。
            // ストリーム フォーマット チャンク ('strf') は、ストリーム ヘッダー チャンクの後に続けて記述する必要がある。
            // ストリーム フォーマット チャンクは、ストリーム内のデータのフォーマットを記述する。このチャンクに含まれるデータは、ストリーム タイプによって異なる。
            // ビデオ ストリームの場合、この情報は必要に応じてパレット情報を含む BITMAPINFO 構造体である。オーディオ ストリームの場合、この情報は WAVEFORMATEX 構造体である。

            // Videoストリーム用の'strl'チャンク
            var strl_list = hdrlList.CreateList("strl");

            {
                var chunk = strl_list.CreateChunk("strh");
                var strh  = new AVISTREAMHEADER();
                strh.fccType               = ToFourCC("vids");
                strh.fccHandler            = ToFourCC(fourCC);
                strh.dwScale               = 1000 * 1000; // fps = dwRate / dwScale。秒間30フレームであることをあらわすのにdwScale=33333、dwRate=1000000という場合もあればdwScale=1、dwRate=30という場合もあります
                strh.dwRate                = (int)(fps * strh.dwScale);
                strh.dwLength              = frames;
                strh.dwSuggestedBufferSize = 0x100000;
                strh.dwQuality             = -1;

                var data = StructureToBytes(strh);
                chunk.Write(data);
                chunk.Close();
            }
            {
                var chunk = strl_list.CreateChunk("strf");
                var strf  = new BITMAPINFOHEADER();
                strf.biWidth       = width;
                strf.biHeight      = height;
                strf.biBitCount    = 24;
                strf.biSizeImage   = strf.biHeight * ((3 * strf.biWidth + 3) / 4) * 4; // らしい
                strf.biCompression = ToFourCC(fourCC);
                strf.biSize        = System.Runtime.InteropServices.Marshal.SizeOf(strf);
                strf.biPlanes      = 1;

                var data = StructureToBytes(strf);
                chunk.Write(data);
                chunk.Close();
            }
            strl_list.Close();
        }