Проблема с GDI
От: andrey.viktorov Россия  
Дата: 09.01.07 05:30
Оценка:
Товарищи, необходимо быстро конвертировать bitmap одного формата (может быть любого разрешения, но 24 бита на пиксель) в bitmap другого формата (разрешение фиксированное -- 320х240, 24 бита на пиксель) для последующего вывода на экран, после чего ещё необходимо послать кадр по сети (естественно он жмётся, но это уже к делу не относится).

Конвертирую так :

    //Здесь VIDEOCHAT_X, VIDEOCHAT_Y -- константы, равные 320 и 240 соответственно
    BITMAPINFOHEADER * srcInfo = videoCB.getBitmapInfo(); //Исходный формат данных
    unsigned char * srcData = videoCB.getBuffer();      //Исходные данные
    unsigned char * bmpData = srcData;//NULL; //Буффер, куда будут записываться преобразованные данные

    BITMAPINFOHEADER inf; // Задаём формат буффера
    inf.biSize = sizeof(BITMAPINFOHEADER);
    inf.biWidth = VIDEOCHAT_X;
    inf.biHeight = VIDEOCHAT_Y;
    inf.biPlanes = 1; 
    inf.biBitCount = 24;
    inf.biCompression = BI_RGB;
    inf.biSizeImage = (((inf.biWidth*inf.biBitCount + 31)& ~31)/8)*(inf.biHeight);
    inf.biXPelsPerMeter = 0;
    inf.biYPelsPerMeter = 0;
    inf.biClrUsed = 0;
    inf.biClrImportant = 0;

    // Convert to compatible format (bitmap, no compression, 24bpp, 320x240)
    HDC dc = ::GetDC(NULL);
    HDC memDc = ::CreateCompatibleDC(dc);
    HBITMAP bmp = ::CreateCompatibleBitmap(dc, VIDEOCHAT_X, VIDEOCHAT_Y);
    ::ReleaseDC(NULL, dc);
    ::SelectObject(memDc, bmp);
    ::SetStretchBltMode(memDc, COLORONCOLOR);
    int x, y;
    int dx, dy;
    if (((double)srcInfo->biWidth / (double) srcInfo->biHeight) > (4.0/3.0)) {
        x = VIDEOCHAT_X;
        y = srcInfo->biHeight * (3.0/4.0);
        dx = 0;
        dy = (VIDEOCHAT_Y - y) / 2.0;
    }
    else {
        y = VIDEOCHAT_Y;
        x = srcInfo->biWidth * (4.0/3.0);
        dy = 0;
        dx = (VIDEOCHAT_X - x) / 2.0;
    }
    int res = ::StretchDIBits(memDc, dx, dy, x, y, 0, 0, srcInfo->biWidth, srcInfo->biHeight, srcData, (BITMAPINFO*)srcInfo, DIB_RGB_COLORS, SRCCOPY);

    HBITMAP curr = (HBITMAP)::SelectObject(memDc, NULL);

    bmpData = new unsigned char[inf.biSizeImage];

    int numLines = GetDIBits(memDc, bmp, 0, VIDEOCHAT_Y, bmpData, (BITMAPINFO*)&inf, DIB_RGB_COLORS); 

    ::DeleteBitmap(bmp);
    ::DeleteDC(memDc);

Всё бы хорошо, только вот скорость меня не устраивает. Если этот код закомментировать, то видео и звук будут синхронизированы, а если оставить, то видео будет заметно отставать. Подскажите пожалуйста, как сделать быстрее это преобразование? Может быть стоит использовать что-то другое, а не GDI?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.