Beispiel #1
0
/***********************************************************************
 *		ICRemove			[MSVFW32.@]
 */
BOOL VFWAPI ICRemove(DWORD fccType, DWORD fccHandler, UINT wFlags) 
{
    reg_driver** pdriver;
    reg_driver*  drv;

    TRACE("(%s,%s,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wFlags);

    /* Check if a driver is already registered */
    for (pdriver = &reg_driver_list; *pdriver; pdriver = &(*pdriver)->next)
    {
        if (!compare_fourcc(fccType, (*pdriver)->fccType) &&
            !compare_fourcc(fccHandler, (*pdriver)->fccHandler))
            break;
    }
    if (!*pdriver)
        return FALSE;

    /* Remove the driver from the list */
    drv = *pdriver;
    *pdriver = (*pdriver)->next;
    HeapFree(GetProcessHeap(), 0, drv->name);
    HeapFree(GetProcessHeap(), 0, drv);
    
    return TRUE;  
}
Beispiel #2
0
/***********************************************************************
 *		ICInfo				[MSVFW32.@]
 * Get information about an installable compressor. Return TRUE if there
 * is one.
 *
 * PARAMS
 *   fccType     [I] type of compressor (e.g. 'vidc')
 *   fccHandler  [I] real fcc for handler or <n>th compressor
 *   lpicinfo    [O] information about compressor
 */
BOOL VFWAPI ICInfo( DWORD fccType, DWORD fccHandler, ICINFO *lpicinfo)
{
    TRACE("(%s,%s/%08x,%p)\n",
          wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), fccHandler, lpicinfo);

    lpicinfo->fccType = fccType;
    lpicinfo->fccHandler = fccHandler;
    return enum_drivers(fccType, ICInfo_enum_handler, lpicinfo);
}
Beispiel #3
0
/***********************************************************************
 *		ICOpenFunction			[MSVFW32.@]
 */
HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, DRIVERPROC lpfnHandler)
{
    ICOPEN      icopen;
    WINE_HIC*   whic;

    TRACE("(%s,%s,%d,%p)\n",
          wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode, lpfnHandler);

    icopen.dwSize		= sizeof(ICOPEN);
    icopen.fccType		= fccType;
    icopen.fccHandler	        = fccHandler;
    icopen.dwVersion            = ICVERSION;
    icopen.dwFlags		= wMode;
    icopen.dwError              = 0;
    icopen.pV1Reserved          = NULL;
    icopen.pV2Reserved          = NULL;
    icopen.dnDevNode            = 0; /* FIXME */

    whic = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC));
    if (!whic) return 0;

    whic->driverproc   = lpfnHandler;
    while (MSVIDEO_GetHicPtr((HIC)(ULONG_PTR)IC_HandleRef) != NULL) IC_HandleRef++;
    whic->hic          = (HIC)(ULONG_PTR)IC_HandleRef++;
    whic->next         = MSVIDEO_FirstHic;
    MSVIDEO_FirstHic = whic;

    /* Now try opening/loading the driver. Taken from DRIVER_AddToList */
    /* What if the function is used more than once? */

    if (MSVIDEO_SendMessage(whic, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) 
    {
        WARN("DRV_LOAD failed for hic %p\n", whic->hic);
        MSVIDEO_FirstHic = whic->next;
        HeapFree(GetProcessHeap(), 0, whic);
        return 0;
    }
    /* return value is not checked */
    MSVIDEO_SendMessage(whic, DRV_ENABLE, 0L, 0L);

    whic->driverId = (DWORD)MSVIDEO_SendMessage(whic, DRV_OPEN, 0, (DWORD_PTR)&icopen);
    /* FIXME: What should we put here? */
    whic->hdrv = NULL;
    
    if (whic->driverId == 0) 
    {
        WARN("DRV_OPEN failed for hic %p\n", whic->hic);
        MSVIDEO_FirstHic = whic->next;
        HeapFree(GetProcessHeap(), 0, whic);
        return 0;
    }

    TRACE("=> %p\n", whic->hic);
    return whic->hic;
}
Beispiel #4
0
/***********************************************************************
 *		ICLocate			[MSVFW32.@]
 */
HIC VFWAPI ICLocate(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
                    LPBITMAPINFOHEADER lpbiOut, WORD wMode)
{
    driver_info_t info;

    TRACE("(%s,%s,%p,%p,0x%04x)\n", 
          wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), lpbiIn, lpbiOut, wMode);

    info.fccType = fccType;
    info.fccHandler = fccHandler;
    info.lpbiIn = lpbiIn;
    info.lpbiOut = lpbiOut;
    info.wMode = wMode;

    switch (wMode) 
    {
    case ICMODE_FASTCOMPRESS:
    case ICMODE_COMPRESS:
        info.querymsg = ICM_COMPRESS_QUERY;
        break;
    case ICMODE_FASTDECOMPRESS:
    case ICMODE_DECOMPRESS:
        info.querymsg = ICM_DECOMPRESS_QUERY;
        break;
    case ICMODE_DRAW:
        info.querymsg = ICM_DRAW_QUERY;
        break;
    default:
        WARN("Unknown mode (%d)\n", wMode);
        return 0;
    }

    /* Easy case: handler/type match, we just fire a query and return */
    info.hic = try_driver(&info);
    /* If it didn't work, try each driver in turn. 32 bit codecs only. */
    /* FIXME: Move this to an init routine? */
    if (!info.hic) enum_drivers(fccType, ICLocate_enum_handler, &info);

    if (info.hic) 
    {
        TRACE("=> %p\n", info.hic);
	return info.hic;
    }

    if (fccType == streamtypeVIDEO) 
        return ICLocate(ICTYPE_VIDEO, fccHandler, lpbiIn, lpbiOut, wMode);
    
    WARN("(%s,%s,%p,%p,0x%04x) not found!\n",
         wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), lpbiIn, lpbiOut, wMode);
    return 0;
}
Beispiel #5
0
/***********************************************************************
 *		ICInstall			[MSVFW32.@]
 */
BOOL VFWAPI ICInstall(DWORD fccType, DWORD fccHandler, LPARAM lParam, LPSTR szDesc, UINT wFlags) 
{
    reg_driver* driver;
    unsigned len;

    TRACE("(%s,%s,%p,%p,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), (void*)lParam, szDesc, wFlags);

    /* Check if a driver is already registered */
    for (driver = reg_driver_list; driver; driver = driver->next)
    {
        if (!compare_fourcc(fccType, driver->fccType) &&
            !compare_fourcc(fccHandler, driver->fccHandler))
            break;
    }
    if (driver) return FALSE;

    /* Register the driver */
    driver = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(reg_driver));
    if (!driver) goto oom;
    driver->fccType = fccType;
    driver->fccHandler = fccHandler;

    switch(wFlags)
    {
    case ICINSTALL_FUNCTION:
        driver->proc = (DRIVERPROC)lParam;
	driver->name = NULL;
        break;
    case ICINSTALL_DRIVER:
	driver->proc = NULL;
        len = MultiByteToWideChar(CP_ACP, 0, (char*)lParam, -1, NULL, 0);
        driver->name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        if (!driver->name) goto oom;
        MultiByteToWideChar(CP_ACP, 0, (char*)lParam, -1, driver->name, len);
	break;
    default:
	ERR("Invalid flags!\n");
	HeapFree(GetProcessHeap(), 0, driver);
	return FALSE;
   }

   /* Insert our driver in the list*/
   driver->next = reg_driver_list;
   reg_driver_list = driver;
    
   return TRUE;
oom:
   HeapFree(GetProcessHeap(), 0, driver);
   return FALSE;
}
Beispiel #6
0
static BOOL enum_compressors(HWND list, COMPVARS *pcv, BOOL enum_all)
{
    UINT id, total = 0;
    ICINFO icinfo;

    id = 0;

    while (ICInfo(pcv->fccType, id, &icinfo))
    {
        struct codec_info *ic;
        DWORD idx;
        HIC hic;

        id++;

        hic = ICOpen(icinfo.fccType, icinfo.fccHandler, ICMODE_COMPRESS);

        if (hic)
        {
            /* for unknown reason fccHandler reported by the driver
             * doesn't always work, use the one returned by ICInfo instead.
             */
            DWORD fccHandler = icinfo.fccHandler;

            if (!enum_all && pcv->lpbiIn)
            {
                if (ICCompressQuery(hic, pcv->lpbiIn, NULL) != ICERR_OK)
                {
                    TRACE("fccHandler %s doesn't support input DIB format %d\n",
                          wine_dbgstr_fcc(icinfo.fccHandler), pcv->lpbiIn->bmiHeader.biCompression);
                    ICClose(hic);
                    continue;
                }
            }

            ICGetInfo(hic, &icinfo, sizeof(icinfo));
            icinfo.fccHandler = fccHandler;

            idx = SendMessageW(list, CB_ADDSTRING, 0, (LPARAM)icinfo.szDescription);

            ic = HeapAlloc(GetProcessHeap(), 0, sizeof(struct codec_info));
            ic->icinfo = icinfo;
            ic->hic = hic;
            SendMessageW(list, CB_SETITEMDATA, idx, (LPARAM)ic);
        }
        total++;
    }

    return total != 0;
}
Beispiel #7
0
/***********************************************************************
 *		ICOpen				[MSVFW32.@]
 * Opens an installable compressor. Return special handle.
 */
HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode) 
{
    WCHAR		codecname[10];
    ICOPEN		icopen;
    HDRVR		hdrv;
    WINE_HIC*           whic;
    static const WCHAR  drv32W[] = {'d','r','i','v','e','r','s','3','2','\0'};
    reg_driver*         driver;

    TRACE("(%s,%s,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode);

    /* Check if there is a registered driver that matches */
    driver = reg_driver_list;
    while(driver)
        if (!compare_fourcc(fccType, driver->fccType) &&
            !compare_fourcc(fccHandler, driver->fccHandler))
	    break;
        else
            driver = driver->next;

    if (driver && driver->proc)
	/* The driver has been registered at runtime with its driverproc */
        return ICOpenFunction(fccType, fccHandler, wMode, driver->proc);
  
    /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
     * same layout as ICOPEN
     */
    icopen.dwSize		= sizeof(ICOPEN);
    icopen.fccType		= fccType;
    icopen.fccHandler	        = fccHandler;
    icopen.dwVersion            = 0x00001000; /* FIXME */
    icopen.dwFlags		= wMode;
    icopen.dwError              = 0;
    icopen.pV1Reserved          = NULL;
    icopen.pV2Reserved          = NULL;
    icopen.dnDevNode            = 0; /* FIXME */
	
    if (!driver) {
        /* The driver is registered in the registry */
	fourcc_to_string(codecname, fccType);
        codecname[4] = '.';
	fourcc_to_string(codecname + 5, fccHandler);
        codecname[9] = '\0';

        hdrv = OpenDriver(codecname, drv32W, (LPARAM)&icopen);
        if (!hdrv) 
            return 0;
    } else {
        /* The driver has been registered at runtime with its name */
        hdrv = OpenDriver(driver->name, NULL, (LPARAM)&icopen);
        if (!hdrv) 
            return 0; 
    }

    whic = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC));
    if (!whic)
    {
        CloseDriver(hdrv, 0, 0);
        return FALSE;
    }
    whic->hdrv          = hdrv;
    whic->driverproc    = NULL;
    whic->type          = fccType;
    whic->handler       = fccHandler;
    while (MSVIDEO_GetHicPtr((HIC)(ULONG_PTR)IC_HandleRef) != NULL) IC_HandleRef++;
    whic->hic           = (HIC)(ULONG_PTR)IC_HandleRef++;
    whic->next          = MSVIDEO_FirstHic;
    MSVIDEO_FirstHic = whic;

    TRACE("=> %p\n", whic->hic);
    return whic->hic;
}
Beispiel #8
0
/***********************************************************************
 *		ICOpen				[MSVFW32.@]
 * Opens an installable compressor. Return special handle.
 */
HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode) 
{
    WCHAR		codecname[10];
    ICOPEN		icopen;
    HDRVR		hdrv;
    WINE_HIC*           whic;
    static const WCHAR  drv32W[] = {'d','r','i','v','e','r','s','3','2','\0'};
    reg_driver*         driver;

    TRACE("(%s,%s,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode);

    if (!fccHandler) /* No specific handler, return the first valid for wMode */
    {
        HIC local;
        ICINFO info;
        DWORD loop = 0;
        info.dwSize = sizeof(info);
        while(ICInfo(fccType, loop++, &info))
        {
            /* Ensure fccHandler is not 0x0 because we will recurse on ICOpen */
            if(!info.fccHandler)
                continue;
            local = ICOpen(fccType, info.fccHandler, wMode);
            if (local != 0)
            {
                TRACE("Returning %s as default handler for %s\n",
                      wine_dbgstr_fcc(info.fccHandler), wine_dbgstr_fcc(fccType));
                return local;
            }
        }
    }

    /* Check if there is a registered driver that matches */
    driver = reg_driver_list;
    while(driver)
        if (!compare_fourcc(fccType, driver->fccType) &&
            !compare_fourcc(fccHandler, driver->fccHandler)) {
	    fccType = driver->fccType;
	    fccHandler = driver->fccHandler;
	    break;
        } else
            driver = driver->next;

    if (driver && driver->proc)
        /* The driver has been registered at runtime with its driverproc */
        return ICOpenFunction(fccType, fccHandler, wMode, driver->proc);
  
    /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
     * same layout as ICOPEN
     */
    icopen.dwSize      = sizeof(ICOPEN);
    icopen.fccType     = fccType;
    icopen.fccHandler  = fccHandler;
    icopen.dwVersion   = 0x00001000; /* FIXME */
    icopen.dwFlags     = wMode;
    icopen.dwError     = 0;
    icopen.pV1Reserved = NULL;
    icopen.pV2Reserved = NULL;
    icopen.dnDevNode   = 0; /* FIXME */

    if (!driver) {
        /* normalize to lower case as in 'vidc' */
        ((char*)&fccType)[0] = tolower(((char*)&fccType)[0]);
        ((char*)&fccType)[1] = tolower(((char*)&fccType)[1]);
        ((char*)&fccType)[2] = tolower(((char*)&fccType)[2]);
        ((char*)&fccType)[3] = tolower(((char*)&fccType)[3]);
        icopen.fccType = fccType;
        /* Seek the driver in the registry */
        fourcc_to_string(codecname, fccType);
        codecname[4] = '.';
        fourcc_to_string(codecname + 5, fccHandler);
        codecname[9] = '\0';

        hdrv = OpenDriver(codecname, drv32W, (LPARAM)&icopen);
        if (!hdrv)
            return 0;
    } else {
        /* The driver has been registered at runtime with its name */
        hdrv = OpenDriver(driver->name, NULL, (LPARAM)&icopen);
        if (!hdrv) 
            return 0; 
    }

    whic = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC));
    if (!whic)
    {
        CloseDriver(hdrv, 0, 0);
        return FALSE;
    }
    whic->hdrv          = hdrv;
    whic->driverproc    = NULL;
    whic->type          = fccType;
    whic->handler       = fccHandler;
    while (MSVIDEO_GetHicPtr((HIC)(ULONG_PTR)IC_HandleRef) != NULL) IC_HandleRef++;
    whic->hic           = (HIC)(ULONG_PTR)IC_HandleRef++;
    whic->next          = MSVIDEO_FirstHic;
    MSVIDEO_FirstHic = whic;

    TRACE("=> %p\n", whic->hic);
    return whic->hic;
}
Beispiel #9
0
/***********************************************************************
 *      ICSeqCompressFrameStart [MSVFW32.@]
 */
BOOL VFWAPI ICSeqCompressFrameStart(PCOMPVARS pc, LPBITMAPINFO lpbiIn)
{
    /* I'm ignoring bmiColors as I don't know what to do with it,
     * it doesn't appear to be used though
     */
    DWORD ret;
    ICCOMPRESS* icComp;
    pc->lpbiIn = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFO));
    if (!pc->lpbiIn)
        return FALSE;

    *pc->lpbiIn = *lpbiIn;

    pc->lpState = HeapAlloc(GetProcessHeap(), 0, sizeof(ICCOMPRESS)
                            + sizeof(*icComp->lpckid) + sizeof(*icComp->lpdwFlags));
    if (!pc->lpState)
        goto error;

    pc->cbState = sizeof(ICCOMPRESS);

    if (!pc->lpbiOut)
    {
        /* Ask compressor for needed header size */
        int size = ICSendMessage(pc->hic, ICM_COMPRESS_GET_FORMAT,
                                 (DWORD_PTR)pc->lpbiIn, 0);
        if (size <= 0)
            goto error;

        pc->lpbiOut = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
        if (!pc->lpbiOut)
            goto error;
        /* Flag to show that we allocated lpbiOut for proper cleanup */
        pc->dwFlags |= 0x80000000;

        ret = ICSendMessage(pc->hic, ICM_COMPRESS_GET_FORMAT,
                            (DWORD_PTR)pc->lpbiIn, (DWORD_PTR)pc->lpbiOut);
        if (ret != ICERR_OK)
        {
            ERR("Could not get output format from compressor\n");
            goto error;
        }
        if (!pc->lpbiOut->bmiHeader.biSizeImage)
        {
            /* If we can't know the output frame size for sure at least allocate
             * the same size of the input frame and also at least 8Kb to be sure
             * that poor compressors will have enough memory to work if the input
             * frame is too small.
             */
            pc->lpbiOut->bmiHeader.biSizeImage = max(8192, pc->lpbiIn->bmiHeader.biSizeImage);
            ERR("Bad codec! Invalid output frame size, guessing from input\n");
        }
    }

    TRACE("Input: %ux%u, fcc %s, bpp %u, size %u\n",
          pc->lpbiIn->bmiHeader.biWidth, pc->lpbiIn->bmiHeader.biHeight,
          wine_dbgstr_fcc(pc->lpbiIn->bmiHeader.biCompression),
          pc->lpbiIn->bmiHeader.biBitCount,
          pc->lpbiIn->bmiHeader.biSizeImage);
    TRACE("Output: %ux%u, fcc %s, bpp %u, size %u\n",
          pc->lpbiOut->bmiHeader.biWidth, pc->lpbiOut->bmiHeader.biHeight,
          wine_dbgstr_fcc(pc->lpbiOut->bmiHeader.biCompression),
          pc->lpbiOut->bmiHeader.biBitCount,
          pc->lpbiOut->bmiHeader.biSizeImage);

    /* Buffer for compressed frame data */
    pc->lpBitsOut = HeapAlloc(GetProcessHeap(), 0, pc->lpbiOut->bmiHeader.biSizeImage);
    if (!pc->lpBitsOut)
        goto error;

    /* Buffer for previous compressed frame data */
    pc->lpBitsPrev = HeapAlloc(GetProcessHeap(), 0, pc->lpbiOut->bmiHeader.biSizeImage);
    if (!pc->lpBitsPrev)
        goto error;

    TRACE("Compvars:\n"
          "\tsize: %i\n"
          "\tflags: 0x%x\n"
          "\thic: %p\n"
          "\ttype: %s\n"
          "\thandler: %s\n"
          "\tin/out: %p/%p\n"
          "\tkey/data/quality: %i/%i/%i\n",
    pc->cbSize, pc->dwFlags, pc->hic, wine_dbgstr_fcc(pc->fccType),
    wine_dbgstr_fcc(pc->fccHandler), pc->lpbiIn, pc->lpbiOut, pc->lKey,
    pc->lDataRate, pc->lQ);

    ret = ICSendMessage(pc->hic, ICM_COMPRESS_BEGIN, (DWORD_PTR)pc->lpbiIn, (DWORD_PTR)pc->lpbiOut);
    if (ret == ICERR_OK)
    {
        icComp = pc->lpState;
        /* Initialise some variables */
        pc->lFrame = 0; pc->lKeyCount = 0;

        icComp->lpbiOutput = &pc->lpbiOut->bmiHeader;
        icComp->lpbiInput = &pc->lpbiIn->bmiHeader;
        icComp->lpckid = (DWORD *)(icComp + 1);
        *icComp->lpckid = 0;
        icComp->lpdwFlags = (DWORD *)((char *)(icComp + 1) + sizeof(*icComp->lpckid));
        *icComp->lpdwFlags = 0;
        icComp->dwFrameSize = 0;
        icComp->dwQuality = pc->lQ;
        icComp->lpbiPrev = &pc->lpbiIn->bmiHeader;
        return TRUE;
    }
error:
    clear_compvars(pc);
    return FALSE;
}