void VDUIHotKeyExControlW32::OnPaint() { PAINTSTRUCT ps; HDC hdc = BeginPaint(mhwnd, &ps); if (!hdc) return; RECT r; if (GetClientRect(mhwnd, &r)) { VDVERIFY(DrawEdge(hdc, &r, EDGE_SUNKEN, BF_ADJUST | BF_RECT)); VDVERIFY(FillRect(hdc, &r, (HBRUSH)(COLOR_WINDOW + 1))); int cx = GetSystemMetrics(SM_CXEDGE); int cy = GetSystemMetrics(SM_CYEDGE); r.left += cx; r.top += cy; r.right -= cx; r.bottom -= cy; if (r.right > r.left && r.bottom > r.top) { SetBkColor(hdc, GetSysColor(COLOR_WINDOW)); SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT)); SetTextAlign(hdc, TA_TOP | TA_LEFT); HGDIOBJ holdFont = SelectObject(hdc, mhfont); if (holdFont) { ExtTextOutW(hdc, r.left, r.top, ETO_CLIPPED, &r, mBuffer.c_str(), mBuffer.size(), NULL); SelectObject(hdc, holdFont); } } } EndPaint(mhwnd, &ps); }
void VDPositionControlW32::RecomputeMetrics() { if (!mhwnd) return; RECT r; VDVERIFY(GetClientRect(mhwnd, &r)); mPositionArea = r; mPositionArea.bottom -= 24; // Compute space we need for the ticks. int labelDigits = mRangeEnd > 0 ? ((int)floor(log10((double)mRangeEnd)) + 1) : 1; int labelSpace = ((labelDigits * mFrameNumberWidth) >> 1) + 8; if (labelSpace < 16) labelSpace = 16; mTrackArea.left = mPositionArea.left; mTrackArea.top = mPositionArea.top; mTrackArea.right = mPositionArea.right; mTrackArea.bottom = mPositionArea.bottom - 2 - mFrameNumberHeight; int trackRailHeight = (mTrackArea.bottom - mTrackArea.top + 1) / 3; mTrack.left = mTrackArea.left + labelSpace; mTrack.top = mTrackArea.top + trackRailHeight; mTrack.right = mTrackArea.right - labelSpace; mTrack.bottom = mTrackArea.bottom - trackRailHeight; mTickArea.top = mTrack.bottom + 1*GetSystemMetrics(SM_CYEDGE); mTickArea.bottom = mTrackArea.bottom; const int tickHeight = mTickArea.bottom - mTickArea.top; mTickArea.left = mTrack.left - tickHeight; mTickArea.right = mTrack.right + tickHeight; // (left+0.5) -> mRangeStart // (right-0.5) -> mRangeEnd if (mRangeEnd > mRangeStart) mPixelsPerFrame = (double)(mTrack.right - mTrack.left - 1) / (double)(mRangeEnd - mRangeStart); else mPixelsPerFrame = 0.0; mPixelToFrameBias = mTrack.left + 0.5 - mPixelsPerFrame*mRangeStart; if (mTrack.right > mTrack.left + 1) mFramesPerPixel = (double)(mRangeEnd - mRangeStart) / (double)(mTrack.right - mTrack.left - 1); else mFramesPerPixel = 0.0; RecalcThumbRect(mPosition, false); RECT rInv = {0,0,r.right,r.bottom-24}; InvalidateRect(mhwnd, &rInv, TRUE); }
void VDFilterFrameManualSource::CompleteRequest(VDFilterFrameRequest *req, bool cache) { if (cache) { VDFilterFrameBuffer *buf = req->GetResultBuffer(); if (buf) mFrameCache.Add(buf, req->GetTiming().mOutputFrame); } VDVERIFY(mFrameQueueInProgress.Remove(req)); }
void VDShutdownThunkAllocator() { while(g_VDJITAllocatorLock.xchg(1)) ::Sleep(1); VDASSERT(g_pVDJITAllocator); if (!g_pVDJITAllocator->Release()) g_pVDJITAllocator = NULL; VDVERIFY(1 == g_VDJITAllocatorLock.xchg(0)); }
bool VDInitThunkAllocator() { bool success = true; while(g_VDJITAllocatorLock.xchg(1)) ::Sleep(1); if (!g_pVDJITAllocator) { g_pVDJITAllocator = new_nothrow VDJITAllocator; if (!g_pVDJITAllocator) success = false; } if (success) g_pVDJITAllocator->AddRef(); VDVERIFY(1 == g_VDJITAllocatorLock.xchg(0)); return success; }
void VDPositionControlW32::OnPaint() { PAINTSTRUCT ps; HDC hdc = BeginPaint(mhwnd, &ps); if (!hdc) // hrm... this is bad return; HGDIOBJ hOldFont = SelectObject(hdc, mFrameNumberFont); SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT)); SetTextAlign(hdc, TA_TOP | TA_CENTER); char buf[64]; RECT rClient; VDVERIFY(GetClientRect(mhwnd, &rClient)); int trackRight = mTrack.right; HGDIOBJ hOldPen = SelectObject(hdc, GetStockObject(BLACK_PEN)); // Determine digit spacing. int labelDigits = mRangeEnd > 0 ? (int)floor(log10((double)mRangeEnd)) + 1 : 1; int labelWidth = (labelDigits + 1) * mFrameNumberWidth; // Add 1 digit for nice padding. sint64 framesPerLabel = 1; if (mRangeEnd > mRangeStart) { while(framesPerLabel * mPixelsPerFrame < labelWidth) { sint64 fpl2 = framesPerLabel + framesPerLabel; if (fpl2 * mPixelsPerFrame >= labelWidth) { framesPerLabel = fpl2; break; } sint64 fpl5 = framesPerLabel * 5; if (fpl5 * mPixelsPerFrame >= labelWidth) { framesPerLabel = fpl5; break; } framesPerLabel *= 10; } } sint64 frame = mRangeStart; bool bDrawLabels = ps.rcPaint.bottom >= mTrackArea.bottom; while(frame < mRangeEnd) { int x = FrameToPixel(frame); const RECT rTick = { x, mTickArea.top, x+1, mTickArea.bottom }; FillRect(hdc, &rTick, mBrushes[kBrushTick]); if (x > trackRight - labelWidth) break; // don't allow labels to encroach last label if (bDrawLabels) { sprintf(buf, "%I64d", frame); TextOut(hdc, x, mTrackArea.bottom, buf, strlen(buf)); } frame += framesPerLabel; } const RECT rLastTick = { mTrack.right, mTrack.bottom, mTrack.right+1, mTrackArea.bottom }; FillRect(hdc, &rLastTick, mBrushes[kBrushTick]); if (bDrawLabels) { sprintf(buf, "%I64d", mRangeEnd); TextOut(hdc, trackRight, mTrackArea.bottom, buf, strlen(buf)); } // Fill the track. We draw the track borders later so they're always on top. FillRect(hdc, &mTrack, mBrushes[kBrushTrack]); // Draw selection and ticks. if (mSelectionEnd >= mSelectionStart) { int selx1 = FrameToPixel(mSelectionStart); int selx2 = FrameToPixel(mSelectionEnd); RECT rSel={selx1, mTrack.top, selx2, mTrack.bottom}; if (rSel.right == rSel.left) ++rSel.right; FillRect(hdc, &rSel, mBrushes[kBrushSelection]); if (HPEN hNullPen = CreatePen(PS_NULL, 0, 0)) { if (HGDIOBJ hLastPen = SelectObject(hdc, hNullPen)) { if (HGDIOBJ hOldBrush = SelectObject(hdc, GetStockObject(BLACK_BRUSH))) { const int tickHeight = mTickArea.bottom - mTickArea.top; const POINT pts1[3]={ { selx1+1, mTickArea.top }, { selx1+1, mTickArea.bottom }, { selx1+1-tickHeight, mTickArea.top }, }; const POINT pts2[3]={ { selx2, mTickArea.top }, { selx2, mTickArea.bottom }, { selx2+tickHeight, mTickArea.top }, }; Polygon(hdc, pts1, 3); Polygon(hdc, pts2, 3); SelectObject(hdc, hOldBrush); } SelectObject(hdc, hLastPen); } DeleteObject(hNullPen); } } // Draw track border. const int xedge = GetSystemMetrics(SM_CXEDGE); const int yedge = GetSystemMetrics(SM_CYEDGE); RECT rEdge = mTrack; InflateRect(&rEdge, xedge, yedge); DrawEdge(hdc, &rEdge, EDGE_SUNKEN, BF_RECT); // Draw cursor. RECT rThumb = mThumbRect; DrawEdge(hdc, &rThumb, EDGE_RAISED, BF_SOFT|BF_RECT|BF_ADJUST); DrawEdge(hdc, &rThumb, EDGE_SUNKEN, BF_SOFT|BF_RECT|BF_ADJUST); // All done. SelectObject(hdc, hOldPen); SelectObject(hdc, hOldFont); EndPaint(mhwnd, &ps); }
bool VDAudioCodecW32::Init(const WAVEFORMATEX *pSrcFormat, const WAVEFORMATEX *pDstFormat, bool isCompression, const char *pDriverShortNameHint, bool throwOnError) { Shutdown(); SafeCopyWaveFormat(mSrcFormat, (const VDWaveFormat *)pSrcFormat); if (pDstFormat) SafeCopyWaveFormat(mDstFormat, (const VDWaveFormat *)pDstFormat); // enumerate IDs for all installed codecs ACMDriverList driverList(pDriverShortNameHint); // try one driver at a time MMRESULT res = 0; for(ACMDriverList::const_iterator it(driverList.begin()), itEnd(driverList.end()); it != itEnd; ++it) { const HACMDRIVERID driverId = *it; // open driver HACMDRIVER hDriver = NULL; if (acmDriverOpen(&hDriver, *it, 0)) continue; if (!pDstFormat) { VDASSERT(!isCompression); DWORD dwDstFormatSize = 0; VDVERIFY(!acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, (LPVOID)&dwDstFormatSize)); if (dwDstFormatSize < sizeof(WAVEFORMATEX)) dwDstFormatSize = sizeof(WAVEFORMATEX); mDstFormat.resize(dwDstFormatSize); memset(mDstFormat.data(), 0, dwDstFormatSize); mDstFormat->mTag = WAVE_FORMAT_PCM; if (acmFormatSuggest(hDriver, (WAVEFORMATEX *)pSrcFormat, (WAVEFORMATEX *)mDstFormat.data(), dwDstFormatSize, ACM_FORMATSUGGESTF_WFORMATTAG)) { acmDriverClose(hDriver, NULL); continue; } // sanitize the destination format a bit if (mDstFormat->mSampleBits != 8 && mDstFormat->mSampleBits != 16) mDstFormat->mSampleBits = 16; if (mDstFormat->mChannels != 1 && mDstFormat->mChannels !=2) mDstFormat->mChannels = 2; mDstFormat->mBlockSize = (uint16)((mDstFormat->mSampleBits >> 3) * mDstFormat->mChannels); mDstFormat->mDataRate = mDstFormat->mBlockSize * mDstFormat->mSamplingRate; mDstFormat->mExtraSize = 0; mDstFormat.resize(sizeof(WAVEFORMATEX)); } // open conversion stream res = acmStreamOpen(&mhStream, hDriver, (WAVEFORMATEX *)pSrcFormat, (WAVEFORMATEX *)mDstFormat.data(), NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME); if (!res) { mhDriver = hDriver; break; } // Aud-X accepts PCM/6ch but not WAVE_FORMAT_EXTENSIBLE/PCM/6ch. Argh. We attempt to work // around this by trying a PCM version if WFE doesn't work. if (isCompression) { // Need to put this somewhere. struct WaveFormatExtensibleW32 { WAVEFORMATEX mFormat; union { uint16 mBitDepth; uint16 mSamplesPerBlock; // may be zero, according to MSDN }; uint32 mChannelMask; GUID mGuid; }; static const GUID local_KSDATAFORMAT_SUBTYPE_PCM={ // so we don't have to bring in ksmedia.h WAVE_FORMAT_PCM, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }; if (pSrcFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE && pSrcFormat->cbSize >= sizeof(WaveFormatExtensibleW32) - sizeof(WAVEFORMATEX)) { const WaveFormatExtensibleW32& wfexex = *(const WaveFormatExtensibleW32 *)pSrcFormat; if (wfexex.mGuid == local_KSDATAFORMAT_SUBTYPE_PCM) { // Rewrite the format to be straight PCM and try again. vdstructex<VDWaveFormat> srcFormat2(mSrcFormat.data(), sizeof(VDWaveFormat)); srcFormat2->mExtraSize = 0; srcFormat2->mTag = WAVE_FORMAT_PCM; MMRESULT res2 = acmStreamOpen(&mhStream, hDriver, (WAVEFORMATEX *)srcFormat2.data(), (WAVEFORMATEX *)mDstFormat.data(), NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME); if (!res2) { res = res2; mSrcFormat = srcFormat2; pSrcFormat = (WAVEFORMATEX *)mSrcFormat.data(); mhDriver = hDriver; break; } } } } acmDriverClose(hDriver, 0); }