Example #1
0
 public static unsafe extern IntPtr ICSeqCompressFrame(
     COMPVARS *pc,
     UInt32 uiFlags,
     IntPtr lpBits,
     Int32 *pfKey,
     Int32 *plSize
     );
Example #2
0
 public static unsafe extern int ICCompressorChoose(
     IntPtr hwnd,
     UInt32 uiFlags,
     IntPtr pvIn,
     IntPtr lpData,
     COMPVARS *pc,
     string lpszTitle
     );
Example #3
0
        /// <summary>
        /// 指定したAVI_CONTAINER構造体にAVIファイルの情報を格納すると共に,
        /// ファイルにヘッダー情報を書き込みます.
        /// </summary>
        /// <param name="file">書き込み対象のファイル</param>
        /// <param name="scale"></param>
        /// <param name="rate"></param>
        /// <param name="compressed"></param>
        public unsafe bool Open(string file, uint scale, uint rate, int width, int height, bool compressed, bool transparent, IntPtr hWnd)
        {
#if DEBUG
            Console.WriteLine("AviWriterEx.Open(string,uint,uint,bool,IntPtr)");
#endif
            m_stream = new BinaryWriter(new FileStream(file, FileMode.Create, FileAccess.Write));
            float fps = (float)rate / (float)scale;
            m_main_header.dwMicroSecPerFrame = (uint)(1.0e6 / fps);//  ! 1秒は10^6μ秒
            m_main_header.dwReserved1        = 0;
            m_main_header.dwFlags            = 2064;
            m_main_header.dwInitialFrames    = 0;
            m_main_header.dwStreams          = 0;
            m_main_header.dwScale            = scale;
            m_main_header.dwRate             = rate;
            m_main_header.dwStart            = 0;
            m_main_header.dwLength           = 0;
            m_rate  = rate;
            m_scale = scale;
            Util.fwrite("RIFF", m_stream);
            Util.WriteDWORD(0, m_stream);
            Util.fwrite("AVI ", m_stream);
            Util.fwrite("LIST", m_stream);
            Util.WriteDWORD(0x9cc, m_stream);
            Util.fwrite("hdrl", m_stream);
            m_current_chunk      = 0;
            m_position_in_chunk  = 0L;
            m_std_index          = new AVISTDINDEX(0L);
            m_super_index        = new AVISUPERINDEX(0);
            m_riff_position      = 0x4;
            m_compressed         = compressed;
            m_is_transparent     = transparent;
            m_stream_fcc_handler = 0;
            m_hwnd   = hWnd;
            m_file   = file;
            m_opened = true;
            if (m_is_first)
            {
                int stride = 0;
                using (Bitmap b = new Bitmap(width, height, m_is_transparent ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb)) {
                    BitmapData bd = b.LockBits(new Rectangle(0, 0, width, height),
                                               ImageLockMode.ReadOnly,
                                               b.PixelFormat);
                    stride = bd.Stride;
                    b.UnlockBits(bd);
                }
                m_is_first                          = false;
                m_main_header.dwWidth               = (uint)width;
                m_main_header.dwHeight              = (uint)height;
                m_main_header.dwMaxBytesPerSec      = (uint)(stride * height * frameRate);
                m_main_header.dwStreams             = 1;
                m_main_header.dwSuggestedBufferSize = (uint)(stride * height);
                m_linesize                          = stride;

                m_stream_header.fccType               = Util.mmioFOURCC("vids");
                m_stream_header.fccHandler            = 0;
                m_stream_header.dwFlags               = 0;
                m_stream_header.dwReserved1           = 0;
                m_stream_header.dwInitialFrames       = 0;
                m_stream_header.dwScale               = m_scale;
                m_stream_header.dwRate                = m_rate;
                m_stream_header.dwStart               = 0;
                m_stream_header.dwSuggestedBufferSize = m_main_header.dwSuggestedBufferSize;
                m_stream_header.dwQuality             = 0;
                m_stream_header.dwSampleSize          = 0;

                Util.aviWriteMainHeader(m_main_header, m_stream);

                Util.fwrite("LIST", m_stream);
                Util.WriteDWORD(0x874, m_stream);
                Util.fwrite("strl", m_stream);

                Util.aviWriteStreamHeader(m_stream_header, m_main_header, m_stream);

                Util.fwrite("strf", m_stream);
                BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); //(BITMAPINFOHEADER)Marshal.PtrToStructure( Marshal.AllocHGlobal( sizeof( BITMAPINFOHEADER ) ), typeof( BITMAPINFOHEADER ) );
                bih.biSize          = (uint)(Marshal.SizeOf(bih));
                bih.biWidth         = width;
                bih.biHeight        = height;
                bih.biPlanes        = 1;
                bih.biBitCount      = m_is_transparent ? (short)32 : (short)24;
                bih.biCompression   = 0;//BI_RGB
                bih.biSizeImage     = (uint)(stride * height);
                bih.biXPelsPerMeter = 0;
                bih.biYPelsPerMeter = 0;
                bih.biClrUsed       = 0;
                bih.biClrImportant  = 0;

                if (m_compressed)
                {
                    m_p_compvar = Marshal.AllocHGlobal(sizeof(COMPVARS));
                    m_compvar   = (COMPVARS *)m_p_compvar.ToPointer();
                    byte[] buf = new byte[sizeof(COMPVARS)];
                    for (int i = 0; i < buf.Length; i++)
                    {
                        buf[i] = 0x0;
                    }
                    Marshal.Copy(buf, 0, m_p_compvar, buf.Length);
                    m_compvar->cbSize = sizeof(COMPVARS);
                    int ret = VCM.ICCompressorChoose(m_hwnd, 0, IntPtr.Zero, IntPtr.Zero, m_compvar, "Select Video Compressor");
                    if (ret == 0)
                    {
                        m_opened = false;
                        Marshal.FreeHGlobal(m_p_compvar);
                        m_stream.Close();
                        return(false);
                    }
                    if (m_compvar->hic != 0)
                    {
                        m_p_bitmapinfo_in = Marshal.AllocHGlobal(sizeof(BITMAPINFO));
                        m_bitmapinfo_in   = (BITMAPINFO *)m_p_bitmapinfo_in.ToPointer();
                        buf = new byte[sizeof(BITMAPINFO)];
                        for (int i = 0; i < buf.Length; i++)
                        {
                            buf[i] = 0x0;
                        }
                        Marshal.Copy(buf, 0, m_p_bitmapinfo_in, buf.Length);
                        m_bitmapinfo_in->bmiHeader = bih;
                        uint dwSize = VCM.ICCompressGetFormatSize(m_compvar->hic, m_bitmapinfo_in);
#if DEBUG
                        Console.WriteLine("m_compvar->hic=" + m_compvar->hic);
                        Console.WriteLine("ICCompressGetFormatSize=" + dwSize);
#endif
                        m_p_bitmapinfo_out = Marshal.AllocHGlobal((int)dwSize);
                        m_bitmapinfo_out   = (BITMAPINFO *)m_p_bitmapinfo_out.ToPointer();
                        buf = new byte[dwSize];
                        for (int i = 0; i < buf.Length; i++)
                        {
                            buf[i] = 0x0;
                        }
                        Marshal.Copy(buf, 0, m_p_bitmapinfo_out, buf.Length);
                        VCM.ICCompressGetFormat(m_compvar->hic, m_bitmapinfo_in, m_bitmapinfo_out);
                        m_bih_compression = m_bitmapinfo_out->bmiHeader.biCompression;
#if DEBUG
                        Console.WriteLine("AddFrame(Bitmap)");
                        Console.WriteLine("    biout.biSize=" + m_bitmapinfo_out->bmiHeader.biSize);
#endif
                        VCM.ICSeqCompressFrameStart(m_compvar, m_bitmapinfo_in);
                        bih = m_bitmapinfo_out->bmiHeader;
                        Util.WriteDWORD(bih.biSize, m_stream);// infoHeaderのサイズ
                        m_bitmapinfo_out->Write(m_stream);
                    }
                    else
                    {
                        m_compressed = false;
                        Util.WriteDWORD(bih.biSize, m_stream);// infoHeaderのサイズ
                        bih.Write(m_stream);
                    }
                }
                else
                {
                    Util.WriteDWORD(bih.biSize, m_stream);// infoHeaderのサイズ
                    bih.Write(m_stream);
                }

                m_super_index_position = m_stream.BaseStream.Position;
                Util.fwrite("indx", m_stream);                       //fcc
                Util.WriteDWORD(0x7f8, m_stream);                    // cb
                Util.WriteWORD((byte)0x4, m_stream);                 // wLongsPerEntry
                Util.WriteBYTE(0x0, m_stream);                       // bIndexSubType
                Util.WriteBYTE(Util.AVI_INDEX_OF_INDEXES, m_stream); // bIndexType
                Util.WriteDWORD(0x0, m_stream);                      // nEntriesInUse
                Util.fwrite("00db", m_stream);                       // dwChunkId
                Util.WriteDWORD(0x0, m_stream);
                Util.WriteDWORD(0x0, m_stream);
                Util.WriteDWORD(0x0, m_stream);
                for (int ii = 1; ii <= 126; ii++)
                {
                    Util.WriteQWORD(0x0, m_stream);
                    Util.WriteDWORD(0x0, m_stream);
                    Util.WriteDWORD(0x0, m_stream);
                }

                Util.fwrite("LIST", m_stream);
                Util.WriteDWORD(0x104, m_stream);
                Util.fwrite("odml", m_stream);
                Util.fwrite("dmlh", m_stream);
                Util.WriteDWORD(0xf8, m_stream);
                Util.WriteDWORD(0x0, m_stream);//ここ後で更新するべき
                for (int ii = 1; ii <= 61; ii++)
                {
                    Util.WriteDWORD(0x0, m_stream);
                }

                Util.fwrite("JUNK", m_stream);
                Util.WriteDWORD(0x60c, m_stream);
                Util.WriteDWORD(0, m_stream);//"This"が将来登録されたらやばいので
                string    msg    = "This file was generated by [email protected];VfwBugCompatible=" + VfwBugCompatible;
                const int tlen   = 1544;
                int       remain = tlen - msg.Length;
                Util.fwrite(msg, m_stream);
                for (int i = 1; i <= remain; i++)
                {
                    m_stream.Write((byte)0);
                }
                m_junk_length = 0xff4;

                Util.fwrite("LIST", m_stream);
                m_movi_position = m_stream.BaseStream.Position;
                Util.WriteDWORD(0, m_stream);// call bmpQWordWrite( 0, avi%fp )     !// ******************ココの数字は一番最後に書き換える必要あり2040~2043あとdwTotalFrames(48~51)も
                Util.fwrite("movi", m_stream);
                m_next_framedata_position = m_stream.BaseStream.Position;

                m_std_index.SetBaseOffset((ulong)m_next_framedata_position);
                m_super_index.nEntriesInUse++;
            }
            return(true);
        }
Example #4
0
        /// <summary>
        /// 指定したAVI_CONTAINER構造体にAVIファイルの情報を格納すると共に,
        /// ファイルにヘッダー情報を書き込みます.
        /// </summary>
        /// <param name="file">書き込み対象のファイル</param>
        /// <param name="scale"></param>
        /// <param name="rate"></param>
        /// <param name="compressed"></param>
        public unsafe bool Open( string file, uint scale, uint rate, int width, int height, bool compressed, bool transparent, IntPtr hWnd ) {
#if DEBUG
            Console.WriteLine( "AviWriterEx.Open(string,uint,uint,bool,IntPtr)" );
#endif
            m_stream = new BinaryWriter( new FileStream( file, FileMode.Create, FileAccess.Write ) );
            float fps = (float)rate / (float)scale;
            m_main_header.dwMicroSecPerFrame = (uint)(1.0e6 / fps);//  ! 1秒は10^6μ秒
            m_main_header.dwReserved1 = 0;
            m_main_header.dwFlags = 2064;
            m_main_header.dwInitialFrames = 0;
            m_main_header.dwStreams = 0;
            m_main_header.dwScale = scale;
            m_main_header.dwRate = rate;
            m_main_header.dwStart = 0;
            m_main_header.dwLength = 0;
            m_rate = rate;
            m_scale = scale;
            Util.fwrite( "RIFF", m_stream );
            Util.WriteDWORD( 0, m_stream );
            Util.fwrite( "AVI ", m_stream );
            Util.fwrite( "LIST", m_stream );
            Util.WriteDWORD( 0x9cc, m_stream );
            Util.fwrite( "hdrl", m_stream );
            m_current_chunk = 0;
            m_position_in_chunk = 0L;
            m_std_index = new AVISTDINDEX( 0L );
            m_super_index = new AVISUPERINDEX( 0 );
            m_riff_position = 0x4;
            m_compressed = compressed;
            m_is_transparent = transparent;
            m_stream_fcc_handler = 0;
            m_hwnd = hWnd;
            m_file = file;
            m_opened = true;
            if ( m_is_first ) {
                int stride = 0;
                using ( Bitmap b = new Bitmap( width, height, m_is_transparent ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb ) ) {
                    BitmapData bd = b.LockBits( new Rectangle( 0, 0, width, height ),
                                                ImageLockMode.ReadOnly,
                                                b.PixelFormat );
                    stride = bd.Stride;
                    b.UnlockBits( bd );
                }
                m_is_first = false;
                m_main_header.dwWidth = (uint)width;
                m_main_header.dwHeight = (uint)height;
                m_main_header.dwMaxBytesPerSec = (uint)(stride * height * frameRate);
                m_main_header.dwStreams = 1;
                m_main_header.dwSuggestedBufferSize = (uint)(stride * height);
                m_linesize = stride;

                m_stream_header.fccType = Util.mmioFOURCC( "vids" );
                m_stream_header.fccHandler = 0;
                m_stream_header.dwFlags = 0;
                m_stream_header.dwReserved1 = 0;
                m_stream_header.dwInitialFrames = 0;
                m_stream_header.dwScale = m_scale;
                m_stream_header.dwRate = m_rate;
                m_stream_header.dwStart = 0;
                m_stream_header.dwSuggestedBufferSize = m_main_header.dwSuggestedBufferSize;
                m_stream_header.dwQuality = 0;
                m_stream_header.dwSampleSize = 0;

                Util.aviWriteMainHeader( m_main_header, m_stream );

                Util.fwrite( "LIST", m_stream );
                Util.WriteDWORD( 0x874, m_stream );
                Util.fwrite( "strl", m_stream );

                Util.aviWriteStreamHeader( m_stream_header, m_main_header, m_stream );

                Util.fwrite( "strf", m_stream );
                BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); //(BITMAPINFOHEADER)Marshal.PtrToStructure( Marshal.AllocHGlobal( sizeof( BITMAPINFOHEADER ) ), typeof( BITMAPINFOHEADER ) );
                bih.biSize = (uint)(Marshal.SizeOf( bih ));
                bih.biWidth = width;
                bih.biHeight = height;
                bih.biPlanes = 1;
                bih.biBitCount = m_is_transparent ? (short)32 : (short)24;
                bih.biCompression = 0;//BI_RGB
                bih.biSizeImage = (uint)(stride * height);
                bih.biXPelsPerMeter = 0;
                bih.biYPelsPerMeter = 0;
                bih.biClrUsed = 0;
                bih.biClrImportant = 0;

                if ( m_compressed ) {
                    m_p_compvar = Marshal.AllocHGlobal( sizeof( COMPVARS ) );
                    m_compvar = (COMPVARS*)m_p_compvar.ToPointer();
                    byte[] buf = new byte[sizeof( COMPVARS )];
                    for ( int i = 0; i < buf.Length; i++ ) {
                        buf[i] = 0x0;
                    }
                    Marshal.Copy( buf, 0, m_p_compvar, buf.Length );
                    m_compvar->cbSize = sizeof( COMPVARS );
                    int ret = VCM.ICCompressorChoose( m_hwnd, 0, IntPtr.Zero, IntPtr.Zero, m_compvar, "Select Video Compressor" );
                    if ( ret == 0 ) {
                        m_opened = false;
                        Marshal.FreeHGlobal( m_p_compvar );
                        m_stream.Close();
                        return false;
                    }
                    if ( m_compvar->hic != 0 ) {
                        m_p_bitmapinfo_in = Marshal.AllocHGlobal( sizeof( BITMAPINFO ) );
                        m_bitmapinfo_in = (BITMAPINFO*)m_p_bitmapinfo_in.ToPointer();
                        buf = new byte[sizeof( BITMAPINFO )];
                        for ( int i = 0; i < buf.Length; i++ ) {
                            buf[i] = 0x0;
                        }
                        Marshal.Copy( buf, 0, m_p_bitmapinfo_in, buf.Length );
                        m_bitmapinfo_in->bmiHeader = bih;
                        uint dwSize = VCM.ICCompressGetFormatSize( m_compvar->hic, m_bitmapinfo_in );
#if DEBUG
                        Console.WriteLine( "m_compvar->hic=" + m_compvar->hic );
                        Console.WriteLine( "ICCompressGetFormatSize=" + dwSize );
#endif
                        m_p_bitmapinfo_out = Marshal.AllocHGlobal( (int)dwSize );
                        m_bitmapinfo_out = (BITMAPINFO*)m_p_bitmapinfo_out.ToPointer();
                        buf = new byte[dwSize];
                        for ( int i = 0; i < buf.Length; i++ ) {
                            buf[i] = 0x0;
                        }
                        Marshal.Copy( buf, 0, m_p_bitmapinfo_out, buf.Length );
                        VCM.ICCompressGetFormat( m_compvar->hic, m_bitmapinfo_in, m_bitmapinfo_out );
                        m_bih_compression = m_bitmapinfo_out->bmiHeader.biCompression;
#if DEBUG
                        Console.WriteLine( "AddFrame(Bitmap)" );
                        Console.WriteLine( "    biout.biSize=" + m_bitmapinfo_out->bmiHeader.biSize );
#endif
                        VCM.ICSeqCompressFrameStart( m_compvar, m_bitmapinfo_in );
                        bih = m_bitmapinfo_out->bmiHeader;
                        Util.WriteDWORD( bih.biSize, m_stream );// infoHeaderのサイズ
                        m_bitmapinfo_out->Write( m_stream );
                    } else {
                        m_compressed = false;
                        Util.WriteDWORD( bih.biSize, m_stream );// infoHeaderのサイズ
                        bih.Write( m_stream );
                    }
                } else {
                    Util.WriteDWORD( bih.biSize, m_stream );// infoHeaderのサイズ
                    bih.Write( m_stream );
                }

                m_super_index_position = m_stream.BaseStream.Position;
                Util.fwrite( "indx", m_stream );          //fcc
                Util.WriteDWORD( 0x7f8, m_stream );       // cb
                Util.WriteWORD( (byte)0x4, m_stream );    // wLongsPerEntry
                Util.WriteBYTE( 0x0, m_stream );          // bIndexSubType
                Util.WriteBYTE( Util.AVI_INDEX_OF_INDEXES, m_stream );// bIndexType
                Util.WriteDWORD( 0x0, m_stream );         // nEntriesInUse
                Util.fwrite( "00db", m_stream );          // dwChunkId
                Util.WriteDWORD( 0x0, m_stream );
                Util.WriteDWORD( 0x0, m_stream );
                Util.WriteDWORD( 0x0, m_stream );
                for ( int ii = 1; ii <= 126; ii++ ) {
                    Util.WriteQWORD( 0x0, m_stream );
                    Util.WriteDWORD( 0x0, m_stream );
                    Util.WriteDWORD( 0x0, m_stream );
                }

                Util.fwrite( "LIST", m_stream );
                Util.WriteDWORD( 0x104, m_stream );
                Util.fwrite( "odml", m_stream );
                Util.fwrite( "dmlh", m_stream );
                Util.WriteDWORD( 0xf8, m_stream );
                Util.WriteDWORD( 0x0, m_stream );//ここ後で更新するべき
                for ( int ii = 1; ii <= 61; ii++ ) {
                    Util.WriteDWORD( 0x0, m_stream );
                }

                Util.fwrite( "JUNK", m_stream );
                Util.WriteDWORD( 0x60c, m_stream );
                Util.WriteDWORD( 0, m_stream );//"This"が将来登録されたらやばいので
                string msg = "This file was generated by [email protected];VfwBugCompatible=" + VfwBugCompatible;
                const int tlen = 1544;
                int remain = tlen - msg.Length;
                Util.fwrite( msg, m_stream );
                for ( int i = 1; i <= remain; i++ ) {
                    m_stream.Write( (byte)0 );
                }
                m_junk_length = 0xff4;

                Util.fwrite( "LIST", m_stream );
                m_movi_position = m_stream.BaseStream.Position;
                Util.WriteDWORD( 0, m_stream );// call bmpQWordWrite( 0, avi%fp )     !// ******************ココの数字は一番最後に書き換える必要あり2040~2043あとdwTotalFrames(48~51)も
                Util.fwrite( "movi", m_stream );
                m_next_framedata_position = m_stream.BaseStream.Position;

                m_std_index.SetBaseOffset( (ulong)m_next_framedata_position );
                m_super_index.nEntriesInUse++;
            }
            return true;
        }
Example #5
0
 public static unsafe extern void ICCompressorFree(COMPVARS *pc);
Example #6
0
 public static unsafe extern void ICSeqCompressFrameEnd(COMPVARS *pc);
Example #7
0
 public static unsafe extern int ICSeqCompressFrameStart(
     COMPVARS *pc,
     BITMAPINFO *lpbiIn
     );