Exemple #1
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);
}
VDTime AVIReadTunnelStream::PositionToTime(VDPosition pos) {
    AVISTREAMINFO asi;
    if (AVIStreamInfo(pas, &asi, sizeof asi))
        return 0;

    return VDRoundToInt64(pos * (double)asi.dwScale / (double)asi.dwRate * 1000000.0);
}
VDPosition AVIReadTunnelStream::TimeToPosition(VDTime timeInUs) {
    AVISTREAMINFO asi;
    if (AVIStreamInfo(pas, &asi, sizeof asi))
        return 0;

    return VDRoundToInt64(timeInUs * (double)asi.dwRate / (double)asi.dwScale * (1.0 / 1000000.0));
}
void VDAVIOutputSegmentedVideoStream::write(uint32 flags, const void *pBuffer, uint32 cbBuffer, uint32 samples) {
	if (mPendingRuns.empty())
		mPendingRuns.push_back(Run());
	else if (flags & AVIIF_KEYFRAME) {
		mPendingRuns.back().mbClosed = true;
		mPendingRuns.push_back(Run());
	}

	Run& run = mPendingRuns.back();
	run.mBlocks.push_back(Block());
	run.mSize += (cbBuffer + 1) & ~1;			// evenify for AVI
	Block& block = run.mBlocks.back();

	block.data = new char[cbBuffer];
	block.size = cbBuffer;
	block.capacity = cbBuffer;
	block.flags = flags;

	memcpy(block.data, pBuffer, cbBuffer);
	++mSamplesWritten;
	++mBufferedSamples;

	run.mEndTime = VDRoundToInt64(mSamplesWritten * (1000000.0 * (double)streamInfo.dwScale / (double)streamInfo.dwRate));

	mpParent->Update();
}
bool VDAVIOutputSegmentedAudioStream::GetNextPendingRun(uint32& samples, uint32& bytes, VDTime& endTime) {
	if (!mBufferedSamples)
		return false;

	samples = mBufferedSamples;
	bytes = samples * ((const WAVEFORMATEX *)getFormat())->nBlockAlign;
	endTime = VDRoundToInt64(mTotalBufferedSamples * (1000000.0 * (double)streamInfo.dwScale / (double)streamInfo.dwRate));
	return true;
}
bool VDAVIOutputSegmentedAudioStream::GetPendingInfo(VDTime endTime, uint32& samples, uint32& bytes) {
	bool ok = true;

	if (endTime < 0)
		samples = mBufferedSamples;
	else {
		samples = (uint32)(VDRoundToInt64(endTime * 1.0 / 1000000.0 * (double)streamInfo.dwRate / (double)streamInfo.dwScale) - mTotalScheduledSamples);

		if (samples > mBufferedSamples) {
			samples = mBufferedSamples;
			if (!mbEnded)
				ok = false;
		}
	}

	bytes = samples * ((const WAVEFORMATEX *)getFormat())->nBlockAlign;

	bytes = (bytes + 1) & ~1;		// evenify for AVI
	return ok;
}
LRESULT CALLBACK VDPositionControlW32::WndProc(UINT msg, WPARAM wParam, LPARAM lParam) {
	switch(msg) {
	case WM_CREATE:
		OnCreate();
		// fall through
	case WM_SIZE:
		OnSize();
		break;

	case WM_PAINT:
		OnPaint();
		return 0;

	case WM_NOTIFY:
		if (TTN_GETDISPINFO == ((LPNMHDR)lParam)->code) {
			NMTTDISPINFO *lphdr = (NMTTDISPINFO *)lParam;
			UINT id = (lphdr->uFlags & TTF_IDISHWND) ? GetWindowLong((HWND)lphdr->hdr.idFrom, GWL_ID) : lphdr->hdr.idFrom;

			*lphdr->lpszText = 0;

			SendMessage(lphdr->hdr.hwndFrom, TTM_SETMAXTIPWIDTH, 0, 5000);

			for(int i=0; i<sizeof g_posctltips/sizeof g_posctltips[0]; ++i) {
				if (id == g_posctltips[i].id)
					lphdr->lpszText = const_cast<char *>(g_posctltips[i].tip);
			}

			return TRUE;
		}
		break;

	case WM_COMMAND:
		{
			UINT cmd;
			VDPositionControlEventData::EventType eventType = VDPositionControlEventData::kEventNone;

			switch(LOWORD(wParam)) {
			case IDC_STOP:			cmd = PCN_STOP;			break;
			case IDC_PLAY:			cmd = PCN_PLAY;			break;
			case IDC_PLAYPREVIEW:	cmd = PCN_PLAYPREVIEW;	break;
			case IDC_MARKIN:		cmd = PCN_MARKIN;		break;
			case IDC_MARKOUT:		cmd = PCN_MARKOUT;		break;

			case IDC_START:
				cmd = PCN_START;
				if (mbAutoStep)
					InternalSetPosition(mRangeStart, VDPositionControlEventData::kEventJumpToStart);
				break;

			case IDC_BACKWARD:
				cmd = PCN_BACKWARD;
				if (mbAutoStep)
					InternalSetPosition(mPosition - 1, VDPositionControlEventData::kEventJumpToPrev);
				break;

			case IDC_FORWARD:
				cmd = PCN_FORWARD;
				if (mbAutoStep)
					InternalSetPosition(mPosition + 1, VDPositionControlEventData::kEventJumpToNext);
				break;

			case IDC_END:
				cmd = PCN_END;
				if (mbAutoStep)
					InternalSetPosition(mRangeEnd, VDPositionControlEventData::kEventJumpToEnd);
				break;

			case IDC_KEYPREV:
				cmd = PCN_KEYPREV;
				eventType = VDPositionControlEventData::kEventJumpToPrevKey;
				break;

			case IDC_KEYNEXT:
				cmd = PCN_KEYNEXT;
				eventType = VDPositionControlEventData::kEventJumpToNextKey;
				break;

			case IDC_SCENEREV:
				cmd = PCN_SCENEREV;
				if (BST_UNCHECKED!=SendMessage((HWND)lParam, BM_GETCHECK, 0, 0)) {
					if (IsDlgButtonChecked(mhwnd, IDC_SCENEFWD))
						CheckDlgButton(mhwnd, IDC_SCENEFWD, BST_UNCHECKED);
				} else
					cmd = PCN_SCENESTOP;
				break;
			case IDC_SCENEFWD:
				cmd = PCN_SCENEFWD;
				if (BST_UNCHECKED!=SendMessage((HWND)lParam, BM_GETCHECK, 0, 0)) {
					if (IsDlgButtonChecked(mhwnd, IDC_SCENEREV))
						CheckDlgButton(mhwnd, IDC_SCENEREV, BST_UNCHECKED);
				} else
					cmd = PCN_SCENESTOP;
				break;
			default:
				return 0;
			}

			SendMessage(GetParent(mhwnd), WM_COMMAND, MAKELONG(GetWindowLong(mhwnd, GWL_ID), cmd), (LPARAM)mhwnd);
		}
		break;

	case WM_LBUTTONDOWN:
		{
			POINT pt = {(SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)};

			if (PtInRect(&mThumbRect, pt)) {
				mDragOffsetX = pt.x - mThumbRect.left;
				mDragMode = kDragThumbFast;
				SetCapture(mhwnd);

				Notify(PCN_BEGINTRACK, VDPositionControlEventData::kEventNone);
				InvalidateRect(mhwnd, &mThumbRect, TRUE);
			} else if (PtInRect(&mPositionArea, pt)) {
				mPosition = (sint64)floor((pt.x - mTrack.left) * mFramesPerPixel + 0.5);
				if (mPosition < mRangeStart)
					mPosition = mRangeStart;
				if (mPosition > mRangeEnd)
					mPosition = mRangeEnd;
				if (mbAutoFrame)
					UpdateString();
				RecalcThumbRect(mPosition);
				Notify(PCN_THUMBPOSITION, VDPositionControlEventData::kEventJump);
				InvalidateRect(mhwnd, &mThumbRect, TRUE);
			}
		}
		break;

	case WM_RBUTTONDOWN:
		{
			POINT pt = {(SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)};

			if (PtInRect(&mThumbRect, pt)) {
				mDragOffsetX = pt.x - mThumbRect.left;
				mDragAnchorPos = mPosition;
				mDragMode = kDragThumbSlow;
				mDragAccum = 0;
				SetCapture(mhwnd);

				Notify(PCN_BEGINTRACK, VDPositionControlEventData::kEventNone);
				InvalidateRect(mhwnd, &mThumbRect, TRUE);
				ShowCursor(FALSE);
			}
		}
		break;

	case WM_MOUSEMOVE:
		if (mDragMode == kDragThumbFast) {
			POINT pt = {(SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)};

			int x = pt.x - mDragOffsetX;

			if (x < mTrack.left - mThumbWidth)
				x = mTrack.left - mThumbWidth;
			if (x > mTrack.right - mThumbWidth)
				x = mTrack.right - mThumbWidth;

			if (x != mThumbRect.left) {
				if (mbAutoFrame) {
					InvalidateRect(mhwnd, &mThumbRect, TRUE);
					mThumbRect.right = x + (mThumbRect.right - mThumbRect.left);
					mThumbRect.left = x;
					InvalidateRect(mhwnd, &mThumbRect, TRUE);
					UpdateWindow(mhwnd);
				}

				sint64 pos = VDRoundToInt64((x - mTrack.left + mThumbWidth) * mFramesPerPixel);
				if (pos > mRangeEnd)
					pos = mRangeEnd;
				if (pos < mRangeStart)
					pos = mRangeStart;
				if (mPosition != pos) {
					mPosition = pos;

					if (mbAutoFrame)
						UpdateString();

					Notify(PCN_THUMBTRACK, VDPositionControlEventData::kEventTracking);
				}
			}
		} else if (mDragMode == kDragThumbSlow) {
			POINT pt = {(SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)};

			mDragAccum += (pt.x - (mThumbRect.left + mDragOffsetX));
			int delta = mDragAccum / 8;
			mDragAccum -= delta * 8;

			if (delta) {
				SetPosition(mDragAnchorPos += delta);
				Notify(PCN_THUMBTRACK, VDPositionControlEventData::kEventTracking);
			}
			
			pt.x = mThumbRect.left + mDragOffsetX;
			ClientToScreen(mhwnd, &pt);
			SetCursorPos(pt.x, pt.y);
		}
		break;

	case WM_CAPTURECHANGED:
		if ((HWND)lParam == mhwnd)
			break;
	case WM_MOUSELEAVE:
	case WM_RBUTTONUP:
	case WM_LBUTTONUP:
		if (mDragMode) {
			if (mDragMode == kDragThumbSlow)
				ShowCursor(TRUE);

			mDragMode = kDragNone;
			ReleaseCapture();

			Notify(PCN_ENDTRACK, VDPositionControlEventData::kEventNone);
			InvalidateRect(mhwnd, &mThumbRect, TRUE);
		}
		break;

	case WM_MOUSEWHEEL:
		{
			mWheelAccum -= (SHORT)HIWORD(wParam);

			int increments = mWheelAccum / WHEEL_DELTA;

			if (increments) {
				mWheelAccum -= WHEEL_DELTA * increments;

				SetPosition(mPosition + increments);

				if (increments < 0)
					Notify(PCN_THUMBPOSITIONPREV, VDPositionControlEventData::kEventJump);
				else
					Notify(PCN_THUMBPOSITIONNEXT, VDPositionControlEventData::kEventJump);
			}
		}
		return 0;
	}

	return DefWindowProc(mhwnd, msg, wParam, lParam);
}
VDTime VDAVIOutputSegmentedAudioStream::GetPendingLevel() {
	return VDRoundToInt64(mTotalBufferedSamples * (1000000.0 * (double)streamInfo.dwScale / (double)streamInfo.dwRate));
}