1

I have a buffer which contains 30 seconds of bitmaps of the user's screen. Since I am making a clipping software which clips the last 30 seconds of the user's screen, I am writing the buffer to an AVI file using the Vfw.h header.

Here is my code:

#include <Windows.h>
#include <Vfw.h>
#include <iostream>
#include <vector>

const int BUFFER_SIZE = 30 * 60; // 30 seconds at 60 fps

int main() {
    RECT desktop;
    const HWND hDesktop = GetDesktopWindow();
    HMONITOR hMonitor = MonitorFromWindow(hDesktop, MONITOR_DEFAULTTOPRIMARY);
    GetWindowRect(hDesktop, &desktop);
    int width = desktop.right;
    int height = desktop.bottom;
    HDC hDC = GetDC(NULL);

    HBITMAP hBitmap = CreateCompatibleBitmap(hDC, width, height);

    HDC hMemDC = CreateCompatibleDC(hDC);
    SelectObject(hMemDC, hBitmap);

    std::vector<HBITMAP> buffer(BUFFER_SIZE);
    int index = 0;

    while (true) {
        BitBlt(hMemDC, 0, 0, width, height, hDC, 0, 0, SRCCOPY);

        buffer[index] = hBitmap;
        index = (index + 1) % BUFFER_SIZE;

        if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) {
            std::cout << "Stopping now" << std::endl;
            break;
        }
    }

    PAVIFILE pFile;
    AVIFileInit();
    AVIFileOpenW(&pFile, L"screen_recording.avi", OF_WRITE | OF_CREATE, NULL);
    PAVISTREAM pStream;
    AVISTREAMINFO streamInfo;
    streamInfo.fccType = streamtypeVIDEO;
    streamInfo.fccHandler = comptypeDIB;
    streamInfo.dwScale = 1;
    streamInfo.dwRate = 60;
    AVIFileCreateStream(pFile, &pStream, &streamInfo);
    AVIStreamSetFormat(pStream, 0, &hBitmap, sizeof(BITMAPINFOHEADER));

    for (int i = 0; i < BUFFER_SIZE; i++) {
        std::cout << "Writing to buffer " << i << std::endl;
        AVIStreamWrite(pStream, i, 1, &buffer[i], sizeof(BITMAPINFOHEADER), AVIIF_KEYFRAME, NULL, NULL);
    }

    AVIStreamClose(pStream);
    AVIFileClose(pFile);

    ReleaseDC(NULL, hDC);
    DeleteDC(hMemDC);
    DeleteObject(hBitmap);

    return 0;
}

I am not sure what I have done wrong.

joeymalvinni
  • 343
  • 9
  • Please see [ask]. – IInspectable Dec 31 '22 at 08:20
  • You check all errors (and also answer/comment/close/etc. your previous questions where people tried to help: https://stackoverflow.com/questions/74959971/windows-api-function-avifileopenw-takes-pavistream-as-input-but-avistreamsetform) – Simon Mourier Dec 31 '22 at 08:21
  • @IInspectable Hi! Thank you for commenting. I have read the `How do I ask a good question` page. I realize that the code block is long, but I also feel like it's not really long enough for me to shorten it. Is there someway else I can improve this post? – joeymalvinni Jan 03 '23 at 01:26
  • @SimonMourier I checked all the errors, rather, the apparent lack of them. As explained in the title, the AVI file is being created, but is corrupted, so I am not getting errors, but am not getting the intended result. – joeymalvinni Jan 03 '23 at 01:28
  • Your program doesn't work and cannot work at all like this, because it's making confusion between HBITMAP and BITMAPINFOHEADER. An HBITMAP is a handle, not a pointer to the bitmap memory. You want to use GetDIBits to get a bitmap data. (it implies you must allocate BUFFER_SIZE bitmaps, not just one). Even though, the net .AVI result will probably not look like what you want (no guarantee of 60fps). – Simon Mourier Jan 03 '23 at 09:06

0 Answers0