EsakkiRaja Ответов: 1

Setalphabitmap не работает


Всем привет,
Я пытаюсь провести черту над потоковым видео в прямом эфире в приложении direct show. Я успешно рисую линию, но если я постоянно хочу создать линию, вызвав нижеприведенную функцию, я получил ошибку E_OUTOFMEMORY из SetAlphaBitmap(). Я вызываю функцию drawlineOverlay () одну за другой, и 8 вызовов в порядке, но девятый и последующие-нет. SetAlphaBitmap возвращает S_OK для первых 8 вызовов, а затем 9-й возвращает 8007000E.

Почему возникает эта ошибка?


Спасибо!!

Что я уже пробовал:

void drawlineOverlay(HWND m_hwndApp)
{
	int cx, cy;
    HRESULT hr;
	HBITMAP hbm;
	RECT rcClient;

	GetResolution(&cx,&cy);

	GetClientRect(m_hwndApp,&rcClient);

    HDC hdc = GetDC(m_hwndApp);

    if (hdc == NULL)
    {
        return E_FAIL;
    }
    HDC hdcBmp = CreateCompatibleDC(hdc);    
    if (hdcBmp == NULL)
    {
        return E_FAIL;
    }
   hbm = CreateCompatibleBitmap(hdc,cx,cy);
	BITMAP bm;
	if (0 == GetObject(hbm, sizeof(bm), &bm))
	{
		DeleteDC(hdcBmp);
		return E_FAIL;
	}			
	
	HBITMAP hbmOld = (HBITMAP)SelectObject(hdcBmp, hbm);
    if (hbmOld == 0)
    {
        DeleteDC(hdcBmp);
        return E_FAIL;
    }				
	//To draw line
	drawLine1(xx1, yy1, xx2, yy2,hdcBmp,2);

	VMR9AlphaBitmap bmpInfo;
	ZeroMemory(&bmpInfo, sizeof(bmpInfo));

	bmpInfo.dwFlags = VMRBITMAP_HDC | VMRBITMAP_SRCCOLORKEY;

	bmpInfo.hdc = hdcBmp;
	        
	SetRect(&bmpInfo.rSrc, 0, 0, bm.bmWidth, bm.bmHeight);   
	bmpInfo.rDest.left = 0.f;
	bmpInfo.rDest.top = 0.f;
	bmpInfo.rDest.right = 1.0f;
	bmpInfo.rDest.bottom = 1.0f;

	// Set the transparency value (1.0 is opaque, 0.0 is transparent).
	bmpInfo.fAlpha = 0.5f;	
	bmpInfo.clrSrcKey = RGB(0,0,0);

	if(m_pVideoRender != NULL)
	{
		IVMRMixerBitmap9* pBmp;	
		hr = m_pVideoRender->QueryInterface(IID_IVMRMixerBitmap9, (LPVOID *)&pBmp);
		if (SUCCEEDED(hr)) 
		{
			hr = pBmp->SetAlphaBitmap(&bmpInfo);
			if(FAILED(hr))
			{
				PrintMessage(L"pBmp->SetAlphaBitmap hr = 0x%x  GetLastError() = %d\r\n",hr,GetLastError());
			}
			pBmp->Release();
			//SAFE_RELEASE(pBmp);

		}
	}
	// Clean up.
	ReleaseDC(m_hwndApp, hdc);
	DeleteBitmap(hbm);
	DeleteObject(SelectObject(hdcBmp, hbmOld));
	DeleteDC(hdcBmp);
}

1 Ответов

Рейтинг:
1

KarstenK

Создайте и заполните растровое изображение и другие материалы один раз при запуске программы. Эти операции "дорогие", поэтому делайте их как можно меньше.

//Gobal bitmap
BITMAP bm = {0};// init with zeros

void drawlineOverlay(HWND m_hwndApp)
{
  //run code once
  if( bm.bmWidth == 0 ) {
    // set up bitmap
  }
Уничтожьте bitmpa в конце программы или при необходимости.


EsakkiRaja

Спасибо за ваш ответ. Но я пробовал использовать BITMAP bm как глобальный, но все равно у меня та же проблема..можем ли мы постоянно вызывать эту функцию(drawlineOverlay)?

EsakkiRaja

Я новичок в directshow и растровом рендеринге. Как уничтожить растровое изображение ?

EsakkiRaja

Судя по ссылке моего друга, он также сделал это с помощью смешивания текста с видео, но он также столкнулся с этой проблемой..для непрерывного вызова функции наложения текст наложения остается повешенным(не обновляется), но видео непрерывно потоковое. После этого он покинул этот проект по неизвестным причинам.

KarstenK

Если вы загуглите, то обнаружите, что вам нужно использовать DeleteObject. Для перерисовки необходимо вызвать InvalideRect с правильными значениями.