Esempio n. 1
0
int AVInfo::GetCodecListSize(int width, int height)
{
    if (m_plCodecList)
    {
        for (int i=0; i<m_codecListSize; ++i)
            delete m_plCodecList[i];
        delete[] m_plCodecList;
        m_plCodecList = NULL;
        m_codecListSize = 0;
    }

    BITMAPINFO bmi;
    Make24BitRGB(&bmi.bmiHeader, width, height);

    ICINFO icInfo;
    ZeroMemory(&icInfo, sizeof ICINFO);
    icInfo.dwSize = sizeof ICINFO;
    int count = 0;

    std::vector<CODECINFO *> codecList;

    // The first codec is always uncompressed RGB
    // data. We can be sure this is the case here
    CODECINFO *pInfo = new CODECINFO;
    pInfo->fcc = MAKEFOURCC('D', 'I', 'B', ' ');
    pInfo->alternativeFcc = BI_RGB;
    pInfo->bHasAboutDialog = false;
    pInfo->bHasConfigureDialog = false;
    pInfo->bSupportsKeyframes = false;
    pInfo->bSupportsQuality = false;
    pInfo->nDefaultKeyframeRate = 1;
    pInfo->nDefaultQuality = 100;
    _tcscpy(pInfo->tszDescription, _T("DIB : <uncompressed>"));
    codecList.push_back(pInfo);

    while (ICInfo(ICTYPE_VIDEO, count, &icInfo))
    {
        HIC hic = ICOpen(icInfo.fccType, icInfo.fccHandler, ICMODE_QUERY);
        if (hic)
        {
            ICINFO moreInfo;
            ZeroMemory(&moreInfo, sizeof ICINFO);
            moreInfo.dwSize = sizeof ICINFO;

            if (ICGetInfo(hic, &moreInfo, sizeof ICINFO) > 0)
            {
                // Ignore MSVC/CRAM
                if (moreInfo.fccHandler != 'CVSM' &&
                        moreInfo.fccHandler != 'MARC')
                {
                    if (ICERR_OK == ICCompressQuery(hic, &bmi, NULL))
                    {
                        // Ok, this codec seems to be ok; put that
                        // into the list
                        CODECINFO *pInfo = new CODECINFO;
                        ZeroMemory(pInfo, sizeof CODECINFO);

                        char szFcc[5];
                        if (moreInfo.fccHandler != BI_RGB)
                        {
                            szFcc[0] = (moreInfo.fccHandler & 0x000000ff);
                            szFcc[1] = (moreInfo.fccHandler & 0x0000ff00) >> 8;
                            szFcc[2] = (moreInfo.fccHandler & 0x00ff0000) >> 16;
                            szFcc[3] = (moreInfo.fccHandler & 0xff000000) >> 24;
                            szFcc[4] = 0;
                        }
                        else
                            strcpy(szFcc, "DIB ");

                        bool bIsReallyOk = true;

                        // We know that IV50 has restrictions.
                        if (moreInfo.fccHandler == '05vi' ||
                                moreInfo.fccHandler == '05VI')
                        {
                            if (width % 4 != 0 ||
                                    height % 4 != 0)
                                bIsReallyOk = false;
                        }

                        // The following code should normally check if the codec
                        // is really able encode a certain BITMAPINFO type. But,
                        // This will fail for the HuffYUV codec. Thus, we have to
                        // assume that it might fail for other codecs, too.
                        /*
                        if (moreInfo.fccHandler == BI_RGB)
                        {
                           bIsReallyOk = true;
                        }
                        else
                        {
                           // The codec says that the input format is ok.
                           // Let's try to create an output format and try
                           // again. For some resolutions, e.g. Indeo Video 5
                           // now fails to compress the format.
                           AM_MEDIA_TYPE mtTmp;
                           ZeroMemory(&mtTmp, sizeof AM_MEDIA_TYPE);
                           bool cool = CreateStreamFormat(moreInfo.fccHandler, width, height, &mtTmp);

                           if (cool)
                           {
                              BITMAPINFO bmiOut;
                              ZeroMemory(&bmiOut, sizeof BITMAPINFO);
                              bmiOut.bmiHeader = ((VIDEOINFOHEADER *) mtTmp.pbFormat)->bmiHeader;
                              DWORD dwOk = ICCompressBegin(hic, &bmi, &bmiOut);
                              if (ICERR_OK == dwOk)
                              {
                                 // It's really ok to use this codec.
                                 bIsReallyOk = true;
                                 ICCompressEnd(hic);
                              }
                           }

                           FreeMediaType(mtTmp);
                        }
                        */

                        if (bIsReallyOk)
                        {
                            // Copy the name
#ifndef _UNICODE
                            _TCHAR tszDesc[128];
                            if (WideCharToMultiByte(CP_ACP, 0, moreInfo.szDescription, -1, tszDesc, 128, NULL, NULL) == 0)
                                strcpy(tszDesc, "<unknown>");
                            sprintf(pInfo->tszDescription, "(%s): %s", szFcc, tszDesc);
#else
                            _stprintf(pInfo->tszDescription, _T("(%S): %s"), szFcc, moreInfo.szDescription);
#endif

                            pInfo->fcc = moreInfo.fccHandler;
                            pInfo->alternativeFcc = icInfo.fccHandler;
                            pInfo->bSupportsKeyframes = (moreInfo.dwFlags & VIDCF_TEMPORAL) > 0;
                            pInfo->bSupportsQuality = (moreInfo.dwFlags & VIDCF_QUALITY) > 0;
                            if (pInfo->bSupportsKeyframes)
                                pInfo->nDefaultKeyframeRate = ICGetDefaultKeyFrameRate(hic);
                            else
                                pInfo->nDefaultKeyframeRate = 0;
                            if (pInfo->bSupportsQuality)
                                pInfo->nDefaultQuality = ICGetDefaultQuality(hic) / 100;
                            else
                                pInfo->nDefaultQuality = 0;

                            pInfo->bHasConfigureDialog = ICQueryConfigure(hic) == TRUE ? true : false;
                            pInfo->bHasAboutDialog = ICQueryAbout(hic) == TRUE ? true : false;

                            codecList.push_back(pInfo);
                        }
                    }
                }
            }
Esempio n. 2
0
/* lParam1: PAVISTREAM
 * lParam2: LPAVICOMPRESSOPTIONS
 */
static HRESULT WINAPI ICMStream_fnCreate(IAVIStream *iface, LPARAM lParam1,
					  LPARAM lParam2)
{
  IAVIStreamImpl *This = impl_from_IAVIStream(iface);

  ICINFO               icinfo;
  ICCOMPRESSFRAMES     icFrames;
  LPAVICOMPRESSOPTIONS pco = (LPAVICOMPRESSOPTIONS)lParam2;

  TRACE("(%p,0x%08lX,0x%08lX)\n", iface, lParam1, lParam2);

  /* check parameter */
  if ((LPVOID)lParam1 == NULL)
    return AVIERR_BADPARAM;

  /* get infos from stream */
  IAVIStream_Info((PAVISTREAM)lParam1, &This->sInfo, sizeof(This->sInfo));
  if (This->sInfo.fccType != streamtypeVIDEO)
    return AVIERR_ERROR; /* error in registry or AVIMakeCompressedStream */

  /* add reference to the stream */
  This->pStream = (PAVISTREAM)lParam1;
  IAVIStream_AddRef(This->pStream);

  AVIFILE_Reset(This);

  if (pco != NULL && pco->fccHandler != comptypeDIB) {
    /* we should compress */
    This->sInfo.fccHandler = pco->fccHandler;

    This->hic = ICOpen(ICTYPE_VIDEO, pco->fccHandler, ICMODE_COMPRESS);
    if (This->hic == NULL)
      return AVIERR_NOCOMPRESSOR;

    /* restore saved state of codec */
    if (pco->cbParms > 0 && pco->lpParms != NULL) {
      ICSetState(This->hic, pco->lpParms, pco->cbParms);
    }

    /* set quality -- resolve default quality */
    This->sInfo.dwQuality = pco->dwQuality;
    if (pco->dwQuality == ICQUALITY_DEFAULT)
      This->sInfo.dwQuality = ICGetDefaultQuality(This->hic);

    /* get capabilities of codec */
    ICGetInfo(This->hic, &icinfo, sizeof(icinfo));
    This->dwICMFlags = icinfo.dwFlags;

    /* use keyframes? */
    if ((pco->dwFlags & AVICOMPRESSF_KEYFRAMES) &&
	(icinfo.dwFlags & (VIDCF_TEMPORAL|VIDCF_FASTTEMPORALC))) {
      This->lKeyFrameEvery = pco->dwKeyFrameEvery;
    } else
      This->lKeyFrameEvery = 1;

    /* use datarate? */
    if ((pco->dwFlags & AVICOMPRESSF_DATARATE)) {
      /* Do we have a chance to reduce size to desired one? */
      if ((icinfo.dwFlags & (VIDCF_CRUNCH|VIDCF_QUALITY)) == 0)
	return AVIERR_NOCOMPRESSOR;

      assert(This->sInfo.dwRate != 0);

      This->dwBytesPerFrame = MulDiv(pco->dwBytesPerSecond,
				     This->sInfo.dwScale, This->sInfo.dwRate);
    } else {
      pco->dwBytesPerSecond = 0;
      This->dwBytesPerFrame = 0;
    }

    if (icinfo.dwFlags & VIDCF_COMPRESSFRAMES) {
      memset(&icFrames, 0, sizeof(icFrames));
      icFrames.lpbiOutput  = This->lpbiOutput;
      icFrames.lpbiInput   = This->lpbiInput;
      icFrames.lFrameCount = This->sInfo.dwLength;
      icFrames.lQuality    = This->sInfo.dwQuality;
      icFrames.lDataRate   = pco->dwBytesPerSecond;
      icFrames.lKeyRate    = This->lKeyFrameEvery;
      icFrames.dwRate      = This->sInfo.dwRate;
      icFrames.dwScale     = This->sInfo.dwScale;
      ICSendMessage(This->hic, ICM_COMPRESS_FRAMES_INFO,
		    (LPARAM)&icFrames, (LPARAM)sizeof(icFrames));
    }
  } else
    This->sInfo.fccHandler = comptypeDIB;

  return AVIERR_OK;
}