Writing a buffer of Bitmaps to an AVI file with the Windows API results in a corrupted AVI file

111 Views Asked by At

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.

0

There are 0 best solutions below