xevuel Temat założony przez niniejszego użytkownika |
runtime przy zapisie pliku .avi » 2011-10-31 11:40:05 Używając tej bibiloteki napisałem program, który nagrywa pulpit (docelowo będzie tworzył wycinki z gier). Jednak, kiedy rozmiar pliku .avi dochodzi do ok. 1.83 GB dostaję runtima od programu. Oto mój kod:
int wait = 1000 / 10; HAVI avi = CreateAvi( "test.avi", wait, NULL ); HANDLE ha = CreateEvent( NULL, true, false, "et" ); HDC _dc = GetWindowDC( GetDesktopWindow() ); RECT re; GetWindowRect( GetDesktopWindow(), & re ); int w = re.right, h = re.bottom; tagBITMAPINFO bi; bi.bmiHeader.biSize = sizeof( bi.bmiHeader ); bi.bmiHeader.biWidth = w; bi.bmiHeader.biHeight = h; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 24; bi.bmiHeader.biCompression = 0; bi.bmiHeader.biSizeImage = w * h * 3;
int i = 0; while( i < 5000 ) { HDC dc = CreateCompatibleDC( 0 ); HBITMAP bm = CreateCompatibleBitmap( _dc, w, h ); HBITMAP hbmOld =( HBITMAP ) SelectObject( dc, bm ); StretchBlt( dc, 0, 0, w, h, _dc, 0, 0, w, h, SRCCOPY ); void * buf = new char[ w * h * 3 ]; HBITMAP hbm = CreateDIBSection( _dc, & bi, DIB_RGB_COLORS, & buf, 0, 0 ); GetDIBits( _dc, bm, 0, h, buf, & bi, DIB_RGB_COLORS ); AddAviFrame( avi, hbm ); SelectObject( dc, hbmOld ); DeleteDC( dc ); DeleteObject( hbmOld ); DeleteObject( hbm ); DeleteObject( bm ); delete[] buf; i++; WaitForSingleObject( ha, wait ); }
ReleaseDC( GetDesktopWindow(), _dc ); MessageBox( 0, "Koniec", 0, 0 ); CloseAvi( avi ); SendMessage( hwnd, WM_DESTROY, 0, 0 );
Kod funkcji AddAviFrame jest w linku powyżej, ale podaję:
HRESULT AddAviFrame( HAVI avi, HBITMAP hbm ) { if( avi == NULL ) return AVIERR_BADHANDLE; if( hbm == NULL ) return AVIERR_BADPARAM; DIBSECTION dibs; int sbm = GetObject( hbm, sizeof( dibs ), & dibs ); if( sbm != sizeof( DIBSECTION ) ) return AVIERR_BADPARAM; TAviUtil * au =( TAviUtil * ) avi; if( au->iserr ) return AVIERR_ERROR; if( au->ps == 0 ) { AVISTREAMINFO strhdr; ZeroMemory( & strhdr, sizeof( strhdr ) ); strhdr.fccType = streamtypeVIDEO; strhdr.fccHandler = 0; strhdr.dwScale = au->period; strhdr.dwRate = 1000; strhdr.dwSuggestedBufferSize = dibs.dsBmih.biSizeImage; SetRect( & strhdr.rcFrame, 0, 0, dibs.dsBmih.biWidth, dibs.dsBmih.biHeight ); HRESULT hr = AVIFileCreateStream( au->pfile, & au->ps, & strhdr ); if( hr != AVIERR_OK ) { au->iserr = true; return hr; } } if( au->psCompressed == 0 ) { AVICOMPRESSOPTIONS opts; ZeroMemory( & opts, sizeof( opts ) ); opts.fccHandler = mmioFOURCC( 'D', 'I', 'B', ' ' ); HRESULT hr = AVIMakeCompressedStream( & au->psCompressed, au->ps, & opts, NULL ); if( hr != AVIERR_OK ) { au->iserr = true; return hr; } hr = AVIStreamSetFormat( au->psCompressed, 0, & dibs.dsBmih, dibs.dsBmih.biSize + dibs.dsBmih.biClrUsed * sizeof( RGBQUAD ) ); if( hr != AVIERR_OK ) { au->iserr = true; return hr; } } HRESULT hr = AVIStreamWrite( au->psCompressed, au->nframe, 1, dibs.dsBm.bmBits, dibs.dsBmih.biSizeImage, AVIIF_KEYFRAME, NULL, NULL ); if( hr != AVIERR_OK ) { au->iserr = true; return hr; } au->nframe++; return S_OK; }
Da się coś zrobić, aby tego runtime-a nie dostawać?
PS. Na początku wieszał się po 980 MB, ale część kodu przeniosłem poza pętlę.
PS2. 1.83 GB to około 25 sekund filmu. Wiem że to strasznie dużo, ten rozmiar, ale na razie mam inny problem... |