static void test_ash1_corruption2(void) { COMMON_AVI_HEADERS cah; char filename[MAX_PATH]; PAVIFILE pFile; int res; PAVISTREAM pStream1; AVISTREAMINFOA asi1; GetTempPathA(MAX_PATH, filename); strcpy(filename+strlen(filename), testfilename); /* Corrupt the block alignment in the audio format header */ init_test_struct(&cah); cah.pcmwf.wf.nBlockAlign = 0xdead; create_avi_file(&cah, filename); res = AVIFileOpenA(&pFile, filename, OF_SHARE_DENY_WRITE, 0L); ok(res == 0, "Unable to open file: error=%u\n", res); res = AVIFileGetStream(pFile, &pStream1, 0, 1); ok(res == 0, "Unable to open audio stream: error=%u\n", res); ok(AVIStreamInfoA(pStream1, &asi1, sizeof(asi1)) == 0, "Unable to read stream info\n"); /* The result will also be the corrupt value, as explained above. */ ok(asi1.dwSampleSize == 0xdead, "got 0x%x (expected 0xdead)\n", asi1.dwSampleSize); AVIStreamRelease(pStream1); AVIFileRelease(pFile); ok(DeleteFileA(filename) !=0, "Deleting file %s failed\n", filename); }
static void test_ash1_corruption(void) { COMMON_AVI_HEADERS cah; char filename[MAX_PATH]; PAVIFILE pFile; int res; PAVISTREAM pStream1; AVISTREAMINFOA asi1; GetTempPathA(MAX_PATH, filename); strcpy(filename+strlen(filename), testfilename); /* Corrupt the sample size in the audio stream header */ init_test_struct(&cah); cah.ash1.dwSampleSize = 0xdeadbeef; create_avi_file(&cah, filename); res = AVIFileOpenA(&pFile, filename, OF_SHARE_DENY_WRITE, 0L); ok(res == 0, "Unable to open file: error=%u\n", res); res = AVIFileGetStream(pFile, &pStream1, 0, 1); ok(res == 0, "Unable to open audio stream: error=%u\n", res); res = AVIStreamInfoA(pStream1, &asi1, sizeof(asi1)); ok(res == 0, "Unable to read stream info: error=%u\n", res); /* The result will still be 2, because the value is dynamically replaced with the nBlockAlign value from the stream format header. The next test will prove this */ ok(asi1.dwSampleSize == 2, "got %u (expected 2)\n", asi1.dwSampleSize); AVIStreamRelease(pStream1); AVIFileRelease(pFile); ok(DeleteFileA(filename) !=0, "Deleting file %s failed\n", filename); }
bool AVIDump::Start(HWND hWnd, int w, int h) { s_emu_wnd = hWnd; s_file_count = 0; s_width = w; s_height = h; s_last_frame = CoreTiming::GetTicks(); if (SConfig::GetInstance().m_SYSCONF->GetData<u8>("IPL.E60")) s_frame_rate = 60; // always 60, for either pal60 or ntsc else s_frame_rate = VideoInterface::TargetRefreshRate; // 50 or 60, depending on region // clear CFR frame cache on start, not on file create (which is also segment switch) SetBitmapFormat(); StoreFrame(nullptr); //Dragonbane: Setup file reading if last side bool lastSide = false; if (Movie::cmp_isRunning) { if (Movie::cmp_leftFinished || Movie::cmp_rightFinished) lastSide = true; if (lastSide) { tempFileCount = 0; s_stopTempFile = false; std::string movie_file_name = GetCurrDumpFile(tempFileCount, true); if (File::Exists(movie_file_name) && Movie::cmp_startTimerFrame > Movie::cmp_curentBranchFrame) //Dragonbane: Open temp file for reading { HRESULT h2 = AVIFileOpenA(&s_file_temp, movie_file_name.c_str(), OF_READ, nullptr); HRESULT h3 = AVIFileGetStream(s_file_temp, &s_stream_temp, streamtypeVIDEO, 0); s_last_key_temp = 1; //Skip first key frame as its always black s_getFrame_temp = AVIStreamGetFrameOpen(s_stream_temp, &s_bitmap); if (!s_getFrame_temp) { PanicAlertT("Your chosen compression codec can not be decompressed again! Can't create video comparison!"); Movie::CancelComparison(); } } } } return CreateFile(); }
avi_str *avi_init(char *out, void *bih, LONG bihl) { avi_str *r = malloc(sizeof(avi_str)); AVIFileInit(); AVIFileOpenA(&r->fp, out, OF_CREATE | OF_WRITE, NULL); AVISTREAMINFO si; ZeroMemory(&si, sizeof(AVISTREAMINFO)); si.fccType = streamtypeVIDEO; si.fccHandler = mmioFOURCC('U', 'L', 'R', 'G'); si.dwScale = 1; si.dwRate = GLC_FPS; si.dwQuality = -1; SetRect(&si.rcFrame, 0, 0, GLC_MAX_WIDTH, GLC_MAX_HEIGHT); AVIFileCreateStream(r->fp, &r->sp, &si); AVIStreamSetFormat(r->sp, 0, bih, bihl); return r; }
static void test_amh_corruption(void) { COMMON_AVI_HEADERS cah; char filename[MAX_PATH]; PAVIFILE pFile; int res; GetTempPathA(MAX_PATH, filename); strcpy(filename+strlen(filename), testfilename); /* Make sure only AVI files with the proper headers will be loaded */ init_test_struct(&cah); cah.fh[3] = mmioFOURCC('A', 'V', 'i', ' '); create_avi_file(&cah, filename); res = AVIFileOpenA(&pFile, filename, OF_SHARE_DENY_WRITE, 0L); ok(res != 0, "Able to open file: error=%u\n", res); ok(DeleteFileA(filename) !=0, "Deleting file %s failed\n", filename); }
bool CvVideoWriter_VFW::open( const char* filename, int _fourcc, double _fps, CvSize frameSize, bool isColor ) { close(); icvInitCapture_VFW(); if( AVIFileOpenA( &avifile, filename, OF_CREATE | OF_WRITE, 0 ) == AVIERR_OK ) { fourcc = _fourcc; fps = _fps; if( frameSize.width > 0 && frameSize.height > 0 && !createStreams( frameSize, isColor ) ) { close(); return false; } return true; } else return false; }
bool CvCaptureAVI_VFW::open( const char* filename ) { close(); icvInitCapture_VFW(); if( !filename ) return false; HRESULT hr = AVIFileOpenA( &avifile, filename, OF_READ, NULL ); if( SUCCEEDED(hr)) { hr = AVIFileGetStream( avifile, &avistream, streamtypeVIDEO, 0 ); if( SUCCEEDED(hr)) { hr = AVIStreamInfo( avistream, &aviinfo, sizeof(aviinfo)); if( SUCCEEDED(hr)) { size.width = aviinfo.rcFrame.right - aviinfo.rcFrame.left; size.height = aviinfo.rcFrame.bottom - aviinfo.rcFrame.top; BITMAPINFOHEADER bmihdr = icvBitmapHeader( size.width, size.height, 24 ); film_range.start_index = (int)aviinfo.dwStart; film_range.end_index = film_range.start_index + (int)aviinfo.dwLength; fps = (double)aviinfo.dwRate/aviinfo.dwScale; pos = film_range.start_index; getframe = AVIStreamGetFrameOpen( avistream, &bmihdr ); if( getframe != 0 ) return true; // Attempt to open as 8-bit AVI. bmihdr = icvBitmapHeader( size.width, size.height, 8); getframe = AVIStreamGetFrameOpen( avistream, &bmihdr ); if( getframe != 0 ) return true; } } } close(); return false; }
static void test_default_data(void) { COMMON_AVI_HEADERS cah; char filename[MAX_PATH]; PAVIFILE pFile; int res; LONG lSize; PAVISTREAM pStream0; PAVISTREAM pStream1; AVISTREAMINFOA asi0, asi1; WAVEFORMATEX wfx; GetTempPathA(MAX_PATH, filename); strcpy(filename+strlen(filename), testfilename); init_test_struct(&cah); create_avi_file(&cah, filename); res = AVIFileOpenA(&pFile, filename, OF_SHARE_DENY_WRITE, 0L); ok(res != AVIERR_BADFORMAT, "Unable to open file: error1=%u\n", AVIERR_BADFORMAT); ok(res != AVIERR_MEMORY, "Unable to open file: error2=%u\n", AVIERR_MEMORY); ok(res != AVIERR_FILEREAD, "Unable to open file: error3=%u\n", AVIERR_FILEREAD); ok(res != AVIERR_FILEOPEN, "Unable to open file: error4=%u\n", AVIERR_FILEOPEN); ok(res != REGDB_E_CLASSNOTREG, "Unable to open file: error5=%u\n", REGDB_E_CLASSNOTREG); ok(res == 0, "Unable to open file: error=%u\n", res); res = AVIFileGetStream(pFile, &pStream0, 0, 0); ok(res == 0, "Unable to open video stream: error=%u\n", res); res = AVIFileGetStream(pFile, &pStream1, 0, 1); ok(res == 0, "Unable to open audio stream: error=%u\n", res); res = AVIStreamInfoA(pStream0, &asi0, sizeof(asi0)); ok(res == 0, "Unable to read stream info: error=%u\n", res); res = AVIStreamInfoA(pStream1, &asi1, sizeof(asi1)); ok(res == 0, "Unable to read stream info: error=%u\n", res); res = AVIStreamReadFormat(pStream0, AVIStreamStart(pStream1), NULL, &lSize); ok(res == 0, "Unable to read format size: error=%u\n", res); res = AVIStreamReadFormat(pStream1, AVIStreamStart(pStream1), &wfx, &lSize); ok(res == 0, "Unable to read format: error=%u\n", res); ok(asi0.fccType == streamtypeVIDEO, "got 0x%x (expected streamtypeVIDEO)\n", asi0.fccType); ok(asi0.fccHandler == 0x30323449, "got 0x%x (expected 0x30323449)\n", asi0.fccHandler); ok(asi0.dwFlags == 0, "got %u (expected 0)\n", asi0.dwFlags); ok(asi0.wPriority == 0, "got %u (expected 0)\n", asi0.wPriority); ok(asi0.wLanguage == 0, "got %u (expected 0)\n", asi0.wLanguage); ok(asi0.dwScale == 1001, "got %u (expected 1001)\n", asi0.dwScale); ok(asi0.dwRate == 30000, "got %u (expected 30000)\n", asi0.dwRate); ok(asi0.dwStart == 0, "got %u (expected 0)\n", asi0.dwStart); ok(asi0.dwLength == 1, "got %u (expected 1)\n", asi0.dwLength); ok(asi0.dwInitialFrames == 0, "got %u (expected 0)\n", asi0.dwInitialFrames); ok(asi0.dwSuggestedBufferSize == 0, "got %u (expected 0)\n", asi0.dwSuggestedBufferSize); ok(asi0.dwQuality == 0xffffffff, "got 0x%x (expected 0xffffffff)\n", asi0.dwQuality); ok(asi0.dwSampleSize == 0, "got %u (expected 0)\n", asi0.dwSampleSize); ok(asi0.rcFrame.left == 0, "got %u (expected 0)\n", asi0.rcFrame.left); ok(asi0.rcFrame.top == 0, "got %u (expected 0)\n", asi0.rcFrame.top); ok(asi0.rcFrame.right == 8, "got %u (expected 8)\n", asi0.rcFrame.right); /* these are based on the values in the mah and not */ ok(asi0.rcFrame.bottom == 6, "got %u (expected 6)\n", asi0.rcFrame.bottom);/* on the ones in the ash which are 0 here */ ok(asi0.dwEditCount == 0, "got %u (expected 0)\n", asi0.dwEditCount); ok(asi0.dwFormatChangeCount == 0, "got %u (expected 0)\n", asi0.dwFormatChangeCount); ok(asi1.fccType == streamtypeAUDIO, "got 0x%x (expected streamtypeVIDEO)\n", asi1.fccType); ok(asi1.fccHandler == 0x1, "got 0x%x (expected 0x1)\n", asi1.fccHandler); ok(asi1.dwFlags == 0, "got %u (expected 0)\n", asi1.dwFlags); ok(asi1.wPriority == 0, "got %u (expected 0)\n", asi1.wPriority); ok(asi1.wLanguage == 0, "got %u (expected 0)\n", asi1.wLanguage); ok(asi1.dwScale == 1, "got %u (expected 1)\n", asi1.dwScale); ok(asi1.dwRate == 11025, "got %u (expected 11025)\n", asi1.dwRate); ok(asi1.dwStart == 0, "got %u (expected 0)\n", asi1.dwStart); ok(asi1.dwLength == 1637, "got %u (expected 1637)\n", asi1.dwLength); ok(asi1.dwInitialFrames == 0, "got %u (expected 0)\n", asi1.dwInitialFrames); ok(asi1.dwSuggestedBufferSize == 0, "got %u (expected 0)\n", asi1.dwSuggestedBufferSize); ok(asi1.dwQuality == 0xffffffff, "got 0x%x (expected 0xffffffff)\n", asi1.dwQuality); ok(asi1.dwSampleSize == 2, "got %u (expected 2)\n", asi1.dwSampleSize); ok(asi1.rcFrame.left == 0, "got %u (expected 0)\n", asi1.rcFrame.left); ok(asi1.rcFrame.top == 0, "got %u (expected 0)\n", asi1.rcFrame.top); ok(asi1.rcFrame.right == 0, "got %u (expected 0)\n", asi1.rcFrame.right); ok(asi1.rcFrame.bottom == 0, "got %u (expected 0)\n", asi1.rcFrame.bottom); ok(asi1.dwEditCount == 0, "got %u (expected 0)\n", asi1.dwEditCount); ok(asi1.dwFormatChangeCount == 0, "got %u (expected 0)\n", asi1.dwFormatChangeCount); ok(wfx.wFormatTag == 1, "got %u (expected 1)\n",wfx.wFormatTag); ok(wfx.nChannels == 2, "got %u (expected 2)\n",wfx.nChannels); ok(wfx.wFormatTag == 1, "got %u (expected 1)\n",wfx.wFormatTag); ok(wfx.nSamplesPerSec == 11025, "got %u (expected 11025)\n",wfx.nSamplesPerSec); ok(wfx.nAvgBytesPerSec == 22050, "got %u (expected 22050)\n",wfx.nAvgBytesPerSec); ok(wfx.nBlockAlign == 2, "got %u (expected 2)\n",wfx.nBlockAlign); AVIStreamRelease(pStream0); AVIStreamRelease(pStream1); AVIFileRelease(pFile); ok(DeleteFileA(filename) !=0, "Deleting file %s failed\n", filename); }
bool AVIDump::CreateFile() { m_totalBytes = 0; m_frameCount = 0; std::string movie_file_name = StringFromFormat("%sframedump%d.avi", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), m_fileCount); // Create path File::CreateFullPath(movie_file_name); // Ask to delete file if (File::Exists(movie_file_name)) { if (AskYesNoT("Delete the existing file '%s'?", movie_file_name.c_str())) File::Delete(movie_file_name); } AVIFileInit(); NOTICE_LOG(VIDEO, "Opening AVI file (%s) for dumping", movie_file_name.c_str()); // TODO: Make this work with AVIFileOpenW without it throwing REGDB_E_CLASSNOTREG HRESULT hr = AVIFileOpenA(&m_file, movie_file_name.c_str(), OF_WRITE | OF_CREATE, nullptr); if (FAILED(hr)) { if (hr == AVIERR_BADFORMAT) NOTICE_LOG(VIDEO, "The file couldn't be read, indicating a corrupt file or an unrecognized format."); if (hr == AVIERR_MEMORY) NOTICE_LOG(VIDEO, "The file could not be opened because of insufficient memory."); if (hr == AVIERR_FILEREAD) NOTICE_LOG(VIDEO, "A disk error occurred while reading the file."); if (hr == AVIERR_FILEOPEN) NOTICE_LOG(VIDEO, "A disk error occurred while opening the file."); if (hr == REGDB_E_CLASSNOTREG) NOTICE_LOG(VIDEO, "AVI class not registered"); Stop(); return false; } SetBitmapFormat(); NOTICE_LOG(VIDEO, "Setting video format..."); if (!SetVideoFormat()) { NOTICE_LOG(VIDEO, "Setting video format failed"); Stop(); return false; } if (!m_fileCount) { if (!SetCompressionOptions()) { NOTICE_LOG(VIDEO, "SetCompressionOptions failed"); Stop(); return false; } } if (FAILED(AVIMakeCompressedStream(&m_streamCompressed, m_stream, &m_options, nullptr))) { NOTICE_LOG(VIDEO, "AVIMakeCompressedStream failed"); Stop(); return false; } if (FAILED(AVIStreamSetFormat(m_streamCompressed, 0, &m_bitmap, m_bitmap.biSize))) { NOTICE_LOG(VIDEO, "AVIStreamSetFormat failed"); Stop(); return false; } return true; }
bool MovieMaker::Snap() { HRESULT hr; if (!bOK) return false; // Get an image and stuff it into a bitmap. HBITMAP bmp; bmp = LoadBMPFromFB( width, height ); LPBITMAPINFOHEADER alpbi = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(bmp, 32)); DeleteObject( bmp ); if (alpbi == NULL) { bOK = false; return false; } if (width>=0 && width != alpbi->biWidth) { GlobalFreePtr(alpbi); bOK = false; return false; } if (height>=0 && height != alpbi->biHeight) { GlobalFreePtr(alpbi); bOK = false; return false; } width = alpbi->biWidth; height = alpbi->biHeight; if (nFrames == 0) { hr = AVIFileOpenA(&pfile, // returned file pointer fname, // file name OF_WRITE | OF_CREATE, // mode to open file with NULL); // use handler determined // from file extension.... if (hr != AVIERR_OK) { GlobalFreePtr(alpbi); bOK = false; return false; } _fmemset(&strhdr, 0, sizeof(strhdr)); strhdr.fccType = streamtypeVIDEO;// stream type strhdr.fccHandler = 0; strhdr.dwScale = 1; strhdr.dwRate = 15; strhdr.dwSuggestedBufferSize = alpbi->biSizeImage; SetRect(&strhdr.rcFrame, 0, 0, // rectangle for stream (int) alpbi->biWidth, (int) alpbi->biHeight); // And create the stream; hr = AVIFileCreateStream(pfile, // file pointer &ps, // returned stream pointer &strhdr); // stream header if (hr != AVIERR_OK) { GlobalFreePtr(alpbi); bOK = false; return false; } _fmemset(&opts, 0, sizeof(opts)); if (!AVISaveOptions(NULL, ICMF_CHOOSE_KEYFRAME, 1, &ps, (LPAVICOMPRESSOPTIONS FAR *) &aopts)) { fprintf( stderr, "AVISaveOptions failed.\n" ); GlobalFreePtr(alpbi); bOK = false; return false; } hr = AVIMakeCompressedStream(&psCompressed, ps, &opts, NULL); if (hr != AVIERR_OK) { fprintf( stderr, "AVIMakeCompressedStream failed.\n" ); GlobalFreePtr(alpbi); bOK = false; return false; } hr = AVIStreamSetFormat(psCompressed, 0, alpbi, // stream format alpbi->biSize + // format size alpbi->biClrUsed * sizeof(RGBQUAD)); if (hr != AVIERR_OK) { fprintf( stderr, "AVIStreamSetFormat failed.\n" ); GlobalFreePtr(alpbi); bOK = false; return false; } // Fill in the stream header for the text stream.... // The text stream is in 60ths of a second.... /* _fmemset(&strhdr, 0, sizeof(strhdr)); strhdr.fccType = streamtypeTEXT; strhdr.fccHandler = mmioFOURCC('D', 'R', 'A', 'W'); strhdr.dwScale = 1; strhdr.dwRate = 60; strhdr.dwSuggestedBufferSize = sizeof(szText); SetRect(&strhdr.rcFrame, 0, (int) alpbi->biHeight, (int) alpbi->biWidth, (int) alpbi->biHeight + TEXT_HEIGHT); // ....and create the stream. hr = AVIFileCreateStream(pfile, &psText, &strhdr); if (hr != AVIERR_OK) { GlobalFreePtr(alpbi); bOK = false; return false; } dwTextFormat = sizeof(dwTextFormat); hr = AVIStreamSetFormat(psText, 0, &dwTextFormat, sizeof(dwTextFormat)); if (hr != AVIERR_OK) { GlobalFreePtr(alpbi); bOK = false; return false; } */ } // Now actual writing hr = AVIStreamWrite(psCompressed, // stream pointer nFrames * 1, // 10, // time of this frame 1, // number to write (LPBYTE) alpbi + // pointer to data alpbi->biSize + alpbi->biClrUsed * sizeof(RGBQUAD), alpbi->biSizeImage, // size of this frame AVIIF_KEYFRAME, // flags.... NULL, NULL); if (hr != AVIERR_OK) { fprintf( stderr, "AVIStreamWrite failed.\n" ); GlobalFreePtr(alpbi); bOK = false; return false; } // Make some text to put in the file ... //LoadString(hInstance, IDS_TEXTFORMAT, szMessage, BUFSIZE ); /* strcpy(szMessage, "This is frame #%d"); int iLen = wsprintf(szText, szMessage, (int)(nFrames + 1)); // ... and write it as well. hr = AVIStreamWrite(psText, nFrames * 40, 1, szText, iLen + 1, AVIIF_KEYFRAME, NULL, NULL); if (hr != AVIERR_OK) { GlobalFreePtr(alpbi); bOK = false; return false; } */ GlobalFreePtr(alpbi); nFrames++; fprintf( stderr, "Wrote frame %d.\r", nFrames ); return true; }
void AVIDump::StoreFrame(const void* data) { if (s_bitmap.biSizeImage > s_stored_frame_size) { void* temp_stored_frame = realloc(s_stored_frame, s_bitmap.biSizeImage); if (temp_stored_frame) { s_stored_frame = temp_stored_frame; } else { free(s_stored_frame); PanicAlertT("Something has gone seriously wrong.\n" "Stopping video recording.\n" "Your video will likely be broken."); Stop(); } s_stored_frame_size = s_bitmap.biSizeImage; memset(s_stored_frame, 0, s_bitmap.biSizeImage); } if (s_stored_frame) { //PanicAlertT("Width: %i, Height: %i, Bit Count: %i", s_bitmap.biWidth, s_bitmap.biHeight, s_bitmap.biBitCount); if (data && (s_file_count || !Movie::cmp_isRunning || s_frame_count > 0)) { bool lastSide = false, readOnly = false; if (Movie::cmp_isRunning && (Movie::cmp_leftFinished || Movie::cmp_rightFinished)) lastSide = true; if (lastSide && Movie::cmp_startTimerFrame > Movie::cmp_curentBranchFrame) //Dragonbane: Combine frames readOnly = true; else readOnly = false; if (readOnly && s_getFrame_temp) { size_t totalBytes = s_bitmap.biSizeImage / 2; size_t rowSize = (s_bitmap.biWidth * (s_bitmap.biBitCount / 8)) / 2; size_t currentByte = 0; if (s_last_key_temp < 2) { BOOL result = AVIStreamIsKeyFrame(s_stream_temp, s_last_key_temp); if (!result) s_last_key_temp = AVIStreamNextKeyFrame(s_stream_temp, s_last_key_temp); } u64 samplePos = AVIStreamFindSample(s_stream_temp, s_last_key_temp, FIND_ANY); u64 s_last_key_old = s_last_key_temp; s_last_key_temp = AVIStreamNextKeyFrame(s_stream_temp, s_last_key_temp); void* s_uncompressed_frame = AVIStreamGetFrame(s_getFrame_temp, samplePos); std::string movie_file_name; if (!s_uncompressed_frame || s_stopTempFile) { //Close current file if (s_getFrame_temp) { AVIStreamGetFrameClose(s_getFrame_temp); s_getFrame_temp = nullptr; } if (s_stream_temp) { AVIStreamClose(s_stream_temp); s_stream_temp = nullptr; } if (s_file_temp) { AVIFileRelease(s_file_temp); s_file_temp = nullptr; movie_file_name = GetCurrDumpFile(tempFileCount, true); if (File::Exists(movie_file_name)) File::Delete(movie_file_name); } //Check if we have another temp file tempFileCount++; s_stopTempFile = false; movie_file_name = GetCurrDumpFile(tempFileCount, true); if (File::Exists(movie_file_name)) //Dragonbane: Open temp file for reading { HRESULT h2 = AVIFileOpenA(&s_file_temp, movie_file_name.c_str(), OF_READ, nullptr); HRESULT h3 = AVIFileGetStream(s_file_temp, &s_stream_temp, streamtypeVIDEO, 0); s_last_key_temp = 0; //Not the first file anymore, so start from keyframe 0 s_getFrame_temp = AVIStreamGetFrameOpen(s_stream_temp, &s_bitmap); if (!s_getFrame_temp) { PanicAlertT("Your chosen compression codec can not be decompressed again! Can't continue video comparison!"); Movie::CancelComparison(); return; } BOOL result = AVIStreamIsKeyFrame(s_stream_temp, s_last_key_temp); if (!result) s_last_key_temp = AVIStreamNextKeyFrame(s_stream_temp, s_last_key_temp); samplePos = AVIStreamFindSample(s_stream_temp, s_last_key_temp, FIND_ANY); s_last_key_old = s_last_key_temp; s_last_key_temp = AVIStreamNextKeyFrame(s_stream_temp, s_last_key_temp); s_uncompressed_frame = AVIStreamGetFrame(s_getFrame_temp, samplePos); if (!s_uncompressed_frame) { //PanicAlertT("Last frame stored. Start timer now!"); Movie::cmp_startTimerFrame = Movie::cmp_curentBranchFrame; memcpy(s_stored_frame, data, s_bitmap.biSizeImage); return; } } else { //PanicAlertT("Last frame stored. Start timer now!"); Movie::cmp_startTimerFrame = Movie::cmp_curentBranchFrame; memcpy(s_stored_frame, data, s_bitmap.biSizeImage); return; } } //Stop temp file on next frame if last frame is processed if (s_last_key_old == s_last_key_temp || AVIStreamFindSample(s_stream_temp, s_last_key_temp, FIND_ANY) == samplePos) s_stopTempFile = true; void* memptr1 = s_uncompressed_frame; memptr1 = static_cast<u8*>(memptr1) + sizeof(BITMAPINFOHEADER); if (Movie::cmp_leftFinished) { memcpy(s_stored_frame, memptr1, s_bitmap.biSizeImage); for (u64 currentRow = 0; currentRow < s_bitmap.biHeight; currentRow++) { currentByte += rowSize; void* memptr = s_stored_frame; const void* memptr2 = data; memptr = static_cast<u8*>(memptr) + currentByte; memptr2 = static_cast<const u8*>(memptr2) + currentByte; memcpy(memptr, memptr2, rowSize); currentByte += rowSize; } } else if (Movie::cmp_rightFinished) { memcpy(s_stored_frame, memptr1, s_bitmap.biSizeImage); //BITMAPINFOHEADER test; //memset(&test, 0, sizeof(BITMAPINFOHEADER)); //memcpy(&test, s_uncompressed_frame, sizeof(BITMAPINFOHEADER)); for (u64 currentRow = 0; currentRow < s_bitmap.biHeight; currentRow++) { void* memptr = s_stored_frame; const void* memptr2 = data; memptr = static_cast<u8*>(memptr) + currentByte; memptr2 = static_cast<const u8*>(memptr2) + currentByte; memcpy(memptr, memptr2, rowSize); currentByte += rowSize * 2; } } else { memcpy(s_stored_frame, data, s_bitmap.biSizeImage); } } else { memcpy(s_stored_frame, data, s_bitmap.biSizeImage); } } else // pitch black frame { memset(s_stored_frame, 0, s_bitmap.biSizeImage); } } }
bool AVIDump::CreateFile() { s_total_bytes = 0; s_frame_count = 0; std::string movie_file_name = ""; //Dragonbane: Movie Logic bool lastSide = false; movie_file_name = GetCurrDumpFile(s_file_count, false); if (Movie::cmp_isRunning) { if (Movie::cmp_leftFinished || Movie::cmp_rightFinished) lastSide = true; } if (!lastSide) //Dragonbane: Stay silent if last side is recorded { // Create path File::CreateFullPath(movie_file_name); // Ask to delete file if (File::Exists(movie_file_name)) { if (SConfig::GetInstance().m_DumpFramesSilent || AskYesNoT("Delete the existing file '%s'?", movie_file_name.c_str())) { File::Delete(movie_file_name); } } } AVIFileInit(); NOTICE_LOG(VIDEO, "Opening AVI file (%s) for dumping", movie_file_name.c_str()); // TODO: Make this work with AVIFileOpenW without it throwing REGDB_E_CLASSNOTREG HRESULT hr = AVIFileOpenA(&s_file, movie_file_name.c_str(), OF_WRITE | OF_CREATE, nullptr); if (FAILED(hr)) { if (hr == AVIERR_BADFORMAT) NOTICE_LOG(VIDEO, "The file couldn't be read, indicating a corrupt file or an unrecognized format."); if (hr == AVIERR_MEMORY) NOTICE_LOG(VIDEO, "The file could not be opened because of insufficient memory."); if (hr == AVIERR_FILEREAD) NOTICE_LOG(VIDEO, "A disk error occurred while reading the file."); if (hr == AVIERR_FILEOPEN) NOTICE_LOG(VIDEO, "A disk error occurred while opening the file."); if (hr == REGDB_E_CLASSNOTREG) NOTICE_LOG(VIDEO, "AVI class not registered"); Stop(); return false; } SetBitmapFormat(); NOTICE_LOG(VIDEO, "Setting video format..."); if (!SetVideoFormat()) { NOTICE_LOG(VIDEO, "Setting video format failed"); Stop(); return false; } if (!s_file_count && !lastSide) //Dragonbane: Stay silent and re-use settings if last side is recorded { if (!SetCompressionOptions()) { NOTICE_LOG(VIDEO, "SetCompressionOptions failed"); Stop(); return false; } } if (FAILED(AVIMakeCompressedStream(&s_stream_compressed, s_stream, &s_options, nullptr))) { NOTICE_LOG(VIDEO, "AVIMakeCompressedStream failed"); Stop(); return false; } if (FAILED(AVIStreamSetFormat(s_stream_compressed, 0, &s_bitmap, s_bitmap.biSize))) { NOTICE_LOG(VIDEO, "AVIStreamSetFormat failed"); Stop(); return false; } return true; }