示例#1
0
文件: api.c 项目: AlexSteel/wine
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);
}
示例#2
0
文件: api.c 项目: AlexSteel/wine
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);
}
示例#3
0
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();
}
示例#4
0
文件: avi.c 项目: yogpstop/MyGCCProj
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;
}
示例#5
0
文件: api.c 项目: AlexSteel/wine
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);
}
示例#6
0
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;
}
示例#7
0
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;
}
示例#8
0
文件: api.c 项目: AlexSteel/wine
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);
}
示例#9
0
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;
}
示例#10
0
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;
}
示例#11
0
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);
		}
	}
}
示例#12
0
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;
}