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; } }
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; } }
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); }
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; }
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; }