Ejemplo n.º 1
0
        private void H264Decode(string path, int fps)
        {
            var decoder = new OpenH264Lib.Decoder("openh264-1.7.0-win32.dll");

            var aviFile = System.IO.File.OpenRead(path);
            var riff    = new RiffFile(aviFile);

            var frames     = riff.Chunks.OfType <RiffChunk>().Where(x => x.FourCC == "00dc");
            var enumerator = frames.GetEnumerator();
            var timer      = new System.Timers.Timer(1000 / fps)
            {
                SynchronizingObject = this, AutoReset = true
            };

            timer.Elapsed += (s, e) =>
            {
                if (enumerator.MoveNext() == false)
                {
                    timer.Stop();
                    return;
                }

                var chunk = enumerator.Current;
                var frame = chunk.ReadToEnd();
                var image = decoder.Decode(frame, frame.Length);
                if (image == null)
                {
                    return;
                }
                pbxScreen.Image = image;
            };
            timer.Start();
        }
        // インデックスには、データ チャンクのリストとファイル内でのその位置が含まれている。
        // インデックスは、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();
        }
Ejemplo n.º 3
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();
                if (outputAvi.GetType() == typeof(MemoryStream))
                {
                    finishedData = ((MemoryStream)outputAvi).ToArray();
                }
                outputAvi.Dispose();
            };
        }
Ejemplo n.º 4
0
        public RiffBase(System.IO.Stream output, string fourCC)
        {
            this.FourCC = fourCC;
            this.Offset = output.Position;

            Writer = new System.IO.BinaryWriter(output);
            Writer.Write(RiffFile.ToFourCC(fourCC));

            this.SizeOffset = output.Position;

            uint dummy_size = 0;

            Writer.Write(dummy_size);

            this.DataOffset = output.Position;
        }