Search code examples
c++directshow

Setalphabitmap not working due to out of memory error


I am trying to draw a line over the live video streaming in direct show application. Am successfully drawing a line but if I continuously want to create a line by calling the below function, i got an error E_OUTOFMEMORY from the SetAlphaBitmap(). Am calling drawlineOverlay() function one after the other and 8 of the calling is ok, but the ninth and subsequent ones do not. SetAlphaBitmap returns S_OK for the first 8 callings and then the 9th returns 8007000E. But the video streaming is going peacefully only the overlay diagram was hanged. If I continuously call that function after sometimes video streaming is stopped and hanging.

Why is this error occuring?

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



void drawLine1(int xx1, int yy1, int xx2, int yy2,HDC hdcBmp) 
{
    RECT clntRc;
    int temp,s1,s2,swap;
    double dx,dy,p,x,y;
    x = xx1;
    y = yy1;
    dx = abs(xx2 - xx1);
    dy = abs(yy2 - yy1);
    s1 = sign(xx2 - xx1); 
    s2 = sign(yy2 - yy1);
    swap = 0;
    if (dy > dx)
    { 
        temp = dx; 
        dx = dy;
        dy = temp;
        swap = 1;
    }
    p = 2*dy - dx;
    for (int i = 0; i < dx; i++)
    {
        clntRc.left =x;
        clntRc.top = y;
        clntRc.right = x+g_Thickness;
        clntRc.bottom =y+g_Thickness;   
        FillRect(hdcBmp,&clntRc,CreateSolidBrush(RGB(0,255,0)));

        while (p >= 0)
        { 
            p = p - 2*dx; 
            if (swap)
                x += s1; 
            else
                y += s2;
        }
            p = p + 2*dy; 
            if (swap) 
                y += s2; 
            else 
                x += s1;
    }
}

Solution

  • CreateSolidBrush(RGB(0,255,0)) is leaking resources. You need to DeleteObject the handle that is returned by CreateSolidBrush(RGB(0,255,0)): https://msdn.microsoft.com/en-us/library/windows/desktop/dd183523(v=vs.85).aspx