Esempio n. 1
0
void VDAudioOutputWaveOutW32::Shutdown() {
	if (mCurState == kStateSilent)
		return;

	Stop();

	if (!mHeaders.empty()) {
		for(int i=mHeaders.size()-1; i>=0; --i) {
			WAVEHDR& hdr = mHeaders[i];

			if (hdr.dwFlags & WHDR_PREPARED)
				waveOutUnprepareHeader(mhWaveOut, &hdr, sizeof hdr);
		}
	}

	mHeaders.clear();
	mBuffer.clear();
	mBlocksPending = 0;
	mBlockCount = 0;
	mBlockSize = 0;
	mBytesQueued = 0;

	if (mhWaveOut) {
		waveOutClose(mhWaveOut);
		mhWaveOut = NULL;
	}

	if (mhWaveEvent) {
		CloseHandle(mhWaveEvent);
		mhWaveEvent = NULL;
	}

	mCurState = kStateNone;
}
Esempio n. 2
0
void VDFileAsyncNT::Open(VDFileHandle h, uint32 count, uint32 bufferSize) {
	try {
		mFilename = "<anonymous pipe>";

		HANDLE hProcess = GetCurrentProcess();
		if (!DuplicateHandle(hProcess, h, hProcess, &mhFileSlow, 0, FALSE, DUPLICATE_SAME_ACCESS))
			throw MyWin32Error("Unable to open file \"%s\" for write: %%s", GetLastError(), mFilename.c_str());

		mSectorSize = 4096;		// guess for now... proper way would be GetVolumeMountPoint() followed by GetDiskFreeSpace().

		mBlockSize = bufferSize;
		mBlockCount = count;
		mBufferSize = mBlockSize * mBlockCount;

		mWriteOffset = 0;
		mBufferLevel = 0;

		mState = kStateNormal;

		if (mhFileFast != INVALID_HANDLE_VALUE) {
			mpBlocks = new VDFileAsyncNTBuffer[count];
			mBuffer.resize(count * bufferSize);
			ThreadStart();
		}
	} catch(const MyError&) {
		Close();
		throw;
	}
}
Esempio n. 3
0
void VDFileAsyncNT::Open(const wchar_t *pszFilename, uint32 count, uint32 bufferSize) {
	try {
		mFilename = VDTextWToA(pszFilename);

		mhFileSlow = CreateFileW(pszFilename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
		if (mhFileSlow == INVALID_HANDLE_VALUE)
			throw MyWin32Error("Unable to open file \"%s\" for write: %%s", GetLastError(), mFilename.c_str());

		mhFileFast = CreateFileW(pszFilename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL);
		if (mhFileFast == INVALID_HANDLE_VALUE)
			mhFileFast = CreateFileW(pszFilename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_OVERLAPPED, NULL);

		mSectorSize = 4096;		// guess for now... proper way would be GetVolumeMountPoint() followed by GetDiskFreeSpace().

		mBlockSize = bufferSize;
		mBlockCount = count;
		mBufferSize = mBlockSize * mBlockCount;

		mWriteOffset = 0;
		mBufferLevel = 0;

		mState = kStateNormal;

		if (mhFileFast != INVALID_HANDLE_VALUE) {
			mpBlocks = new VDFileAsyncNTBuffer[count];
			mBuffer.resize(count * bufferSize);
			ThreadStart();
		}
	} catch(const MyError&) {
		Close();
		throw;
	}
}
Esempio n. 4
0
void VDCaptureReplayDriver::Init(const wchar_t *filename) {
	VDTextInputFile ifile(filename);

	// skip first line
	ifile.GetNextLine();

	uint32 largestDataBlock = 0;

	while(const char *txt = ifile.GetNextLine()) {
		const char *ranges[9][2];

		for(int i=0; i<9; ++i) {
			ranges[i][0] = txt;
			ranges[i][1] = strchr(txt, ',');
			if (!ranges[i][1])
				ranges[i][1] = txt + strlen(txt);

			txt = ranges[i][1];
			if (*txt)
				++txt;
		}

		if (ranges[1][0] != ranges[1][1]) {
			Event vev;

			vev.audio = false;
			vev.key = atoi(ranges[4][0]) > 0;
			vev.captime = VDRoundToInt64(strtod(ranges[1][0], NULL) * 1000.0);
			vev.globaltime = VDRoundToInt64(strtod(ranges[2][0], NULL) * 1000.0);
			vev.bytes = atoi(ranges[3][0]);

			if (largestDataBlock < vev.bytes)
				largestDataBlock = vev.bytes;

			mEvents.push_back(vev);
		}

		if (ranges[5][0] != ranges[5][1]) {
			Event aev;

			aev.audio = true;
			aev.key = false;
			aev.globaltime = VDRoundToInt64(strtod(ranges[7][0], NULL) * 1000.0);
			aev.captime = aev.globaltime;
			aev.bytes = atoi(ranges[8][0]);

			if (largestDataBlock < aev.bytes)
				largestDataBlock = aev.bytes;

			mEvents.push_back(aev);
		}
	}

	mDummyData.resize(largestDataBlock);

	std::sort(mEvents.begin(), mEvents.end(), ReverseEventSorter());

	mpCB->CapBegin(0);
}
Esempio n. 5
0
bool VDCaptureReplayDriver::ReplayNext() {
	if (mEvents.empty())
		return false;

	Event& ev = mEvents.back();

	try {
		mpCB->CapProcessData(ev.audio ? 1 : 0, mDummyData.data(), ev.bytes, ev.captime, ev.key, ev.globaltime);
	} catch(const MyError& e) {
		mpCB->CapEnd(&e);
		return false;
	}

	mEvents.pop_back();

	return true;
}
Esempio n. 6
0
bool VDAudioOutputWaveOutW32::Init(uint32 bufsize, uint32 bufcount, const WAVEFORMATEX *wf, const wchar_t *preferredDevice) {
	UINT deviceID = WAVE_MAPPER;

	if (preferredDevice && *preferredDevice) {
		UINT numDevices = waveOutGetNumDevs();

		for(UINT i=0; i<numDevices; ++i) {
			WAVEOUTCAPSA caps = {0};

			if (MMSYSERR_NOERROR == waveOutGetDevCapsA(i, &caps, sizeof(caps))) {
				const VDStringW key(VDTextAToW(caps.szPname).c_str());

				if (key == preferredDevice) {
					deviceID = i;
					break;
				}
			}
		}
	}

	mBuffer.resize(bufsize * bufcount);
	mBlockHead = 0;
	mBlockTail = 0;
	mBlockWriteOffset = 0;
	mBlocksPending = 0;
	mBlockSize = bufsize;
	mBlockCount = bufcount;
	mBytesQueued = 0;

	if (!mhWaveEvent) {
		mhWaveEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

		if (!mhWaveEvent)
			return false;
	}

	MMRESULT res = waveOutOpen(&mhWaveOut, deviceID, wf, (DWORD_PTR)mhWaveEvent, 0, CALLBACK_EVENT);
	if (MMSYSERR_NOERROR != res) {
		Shutdown();
		return false;
	}

	mCurState = kStateOpened;
	mSamplesPerSec = wf->nSamplesPerSec;
	mAvgBytesPerSec = wf->nAvgBytesPerSec;

	// Hmmm... we can't allocate buffers while the wave device
	// is active...
	mHeaders.resize(bufcount);
	memset(mHeaders.data(), 0, bufcount * sizeof mHeaders[0]);

	for(uint32 i=0; i<bufcount; ++i) {
		WAVEHDR& hdr = mHeaders[i];

		hdr.dwBufferLength	= bufsize;
		hdr.dwBytesRecorded	= 0;
		hdr.dwFlags			= 0;
		hdr.dwLoops			= 0;
		hdr.dwUser			= 0;
		hdr.lpData			= mBuffer.data() + bufsize * i;

		res = waveOutPrepareHeader(mhWaveOut, &hdr, sizeof hdr);
		if (MMSYSERR_NOERROR != res) {
			Shutdown();
			return false;
		}
	}

	waveOutPause(mhWaveOut);
	return true;
}
Esempio n. 7
0
LRESULT Frameserver::SessionFrame(LPARAM lParam, WPARAM original_frame) {
	FrameserverSession *fs = SessionLookup(lParam);

	if (!fs)
		return VDSRVERR_BADSESSION;

	try {
		const void *ptr = vSrc->getFrameBuffer();
		const BITMAPINFOHEADER *bmih = vSrc->getDecompressedFormat();
		VDPosition sample;
		bool is_preroll;

		if (fs->arena_size < ((filters.LastBitmap()->w*3+3)&-4)*filters.LastBitmap()->h)
			return VDSRVERR_TOOBIG;

		sample = mVideoFrameMap[original_frame].mDisplayFrame;

		if (sample < 0)
			return VDSRVERR_FAILED;

		vSrc->streamSetDesiredFrame(sample);

		VDPosition targetSample = vSrc->displayToStreamOrder(sample);
		VDPosition frame = vSrc->streamGetNextRequiredFrame(is_preroll);

		if (frame >= 0) {
			do {
				uint32 lSize;
				int hr;

	//			_RPT1(0,"feeding frame %ld\n", frame);

				hr = vSrc->read(frame, 1, NULL, 0x7FFFFFFF, &lSize, NULL);
				if (hr)
					return VDSRVERR_FAILED;

				uint32 bufSize = (lSize + 65535 + vSrc->streamGetDecodePadding()) & ~65535;
				if (mInputBuffer.size() < bufSize)
					mInputBuffer.resize(bufSize);

				hr = vSrc->read(frame, 1, mInputBuffer.data(), lSize, &lSize, NULL); 
				if (hr)
					return VDSRVERR_FAILED;

				vSrc->streamFillDecodePadding(mInputBuffer.data(), lSize);
				ptr = vSrc->streamGetFrame(mInputBuffer.data(), lSize, is_preroll, frame, targetSample);
			} while(-1 != (frame = vSrc->streamGetNextRequiredFrame(is_preroll)));

		} else
			ptr = vSrc->streamGetFrame(NULL, 0, FALSE, targetSample, targetSample);

		VDPixmap pxdst(VDPixmapFromLayout(mFrameLayout, fs->arena));

		if (!g_listFA.IsEmpty()) {
			VDPixmapBlt(VDAsPixmap(*filters.InputBitmap()), vSrc->getTargetFormat());

			fsi.lCurrentFrame				= original_frame;
			fsi.lCurrentSourceFrame			= sample;
			fsi.lSourceFrameMS				= MulDiv(fsi.lCurrentSourceFrame, fsi.lMicrosecsPerSrcFrame, 1000);
			fsi.lDestFrameMS				= MulDiv(fsi.lCurrentFrame, fsi.lMicrosecsPerFrame, 1000);

			filters.RunFilters(fsi);

			VDPixmapBlt(pxdst, VDAsPixmap(*filters.LastBitmap()));
		} else
			VDPixmapBlt(pxdst, vSrc->getTargetFormat());

	} catch(const MyError&) {
		return VDSRVERR_FAILED;
	}

	return VDSRVERR_OK;
}