Exemplo n.º 1
0
static int vfw_encode_frame(BITMAPINFOHEADER* biOutput,void* OutBuf,
		     BITMAPINFOHEADER* biInput,void* Image,
		     long* keyframe, int quality){
    HRESULT ret;

//long VFWAPIV ICCompress(
//	HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiOutput,void* lpOutputBuf,
//	LPBITMAPINFOHEADER lpbiInput,void* lpImage,long* lpckid,
//	long* lpdwFlags,long lFrameNum,long dwFrameSize,long dwQuality,
//	LPBITMAPINFOHEADER lpbiInputPrev,void* lpImagePrev
//);

//    printf("vfw_encode_frame(%p,%p, %p,%p, %p,%d)\n",biOutput,OutBuf,biInput,Image,keyframe,quality);

    ret=ICCompress(encoder_hic, 0,
	biOutput, OutBuf,
	biInput, Image,
	NULL, keyframe, encoder_frameno, 0, quality,
	biInput, encoder_buf);

//    printf("ok. size=%ld\n",biOutput->biSizeImage);

    memcpy(encoder_buf,Image,encoder_buf_size);
    ++encoder_frameno;

    return (int)ret;
}
std::shared_ptr<WatermarkSearchResult> WatermarkSearchWorker::findWatermark(int width, int height)
{
    std::shared_ptr<WatermarkSearchResult> r = std::make_shared<WatermarkSearchResult>();
    r->size_.width_ = width;
    r->size_.height_ = height;

    int const bytesPerPixel = 4;
    int const scanlineSizeInBytes = width * bytesPerPixel;

    BITMAPINFOHEADER inputFormat;
    ZeroMemory(&inputFormat, sizeof(inputFormat));
    inputFormat.biSize = sizeof(inputFormat);
    inputFormat.biWidth = width;
    inputFormat.biHeight = height;
    inputFormat.biPlanes = 1;
    inputFormat.biBitCount = 8 * bytesPerPixel;
    inputFormat.biCompression = BI_RGB;
    inputFormat.biSizeImage = scanlineSizeInBytes * height;

    DWORD const size = ICCompressGetFormatSize(compressor_, &inputFormat);
    if (size == 0 || (size & 0xFFFF0000) == 0xFFFF0000) {
        return r;
    }
    std::vector<uint8_t> outputFormatStorage(size);
    LPBITMAPINFOHEADER outputFormat = (LPBITMAPINFOHEADER)(BITMAPINFO*)outputFormatStorage.data();
    if (ICCompressGetFormat(compressor_, &inputFormat, outputFormat) != ICERR_OK) {
        return r;
    }

    DWORD const outputSize = ICCompressGetSize(compressor_, &inputFormat, outputFormat);
    if (outputSize < 0) {
        return r;
    }

    if (outputBuffer_.size() < outputSize) {
        outputBuffer_.resize(outputSize);
    }
    if (inputBuffer_.size() < inputFormat.biSizeImage) {
        inputBuffer_.resize(inputFormat.biSizeImage);
    }
    std::fill(inputBuffer_.begin(), inputBuffer_.begin() + inputFormat.biSizeImage, (uint8_t)0xff);

    if (ICCompressBegin(compressor_, &inputFormat, outputFormat) != ICERR_OK) {
        return r;
    }

    DWORD flags = 0;
    DWORD dwckid = 0;

    DWORD result = ICCompress(compressor_,
                              0, // dwFlags
                              outputFormat,
                              outputBuffer_.data(),
                              &inputFormat,
                              inputBuffer_.data(),
                              &dwckid,
                              &flags,
                              0, // lpFrameNum
                              0, // dwFrameSize
                              0, // dwQuality
                              nullptr, // lpbiPrev
                              nullptr); // lpPrev
    if (result != ICERR_OK) {
        return r;
    }

    if (ICCompressEnd(compressor_) != ICERR_OK) {
        return r;
    }

    if (ICDecompressBegin(decompressor_, outputFormat, &inputFormat) != ICERR_OK) {
        return r;
    }

    std::fill(inputBuffer_.begin(), inputBuffer_.begin() + inputFormat.biSizeImage, (uint8_t)0xff);
    if (ICDecompress(decompressor_, 0, outputFormat, outputBuffer_.data(), &inputFormat, inputBuffer_.data()) != ICERR_OK) {
        return r;
    }

    if (ICDecompressEnd(decompressor_) != ICERR_OK) {
        return r;
    }

    // Search left edge of watermark
    int left = -1;
    for (int x = 0; x < width; ++x) {
        bool found = false;
        for (int y = 0; y < height; ++y) {
            for (int j = 0; j < bytesPerPixel; ++j) {
                int index = scanlineSizeInBytes * y + x * bytesPerPixel + j;
                if (inputBuffer_[index] != (uint8_t)0xff) {
                    found = true;
                    left = x;
                    break;
                }
            }
            if (found) {
                break;
            }
        }
        if (found) {
            break;
        }
    }
    if (left < 0) {
        return r;
    }

    // Search right edge of watermark
    int right = -1;
    for (int x = width - 1; x >= 0; --x) {
        bool found = false;
        for (int y = 0; y < height; ++y) {
            for (int j = 0; j < bytesPerPixel; ++j) {
                int index = scanlineSizeInBytes * y + x * bytesPerPixel + j;
                if (inputBuffer_[index] != (uint8_t)0xff) {
                    found = true;
                    right = x;
                    break;
                }
            }
            if (found) {
                break;
            }
        }
        if (found) {
            break;
        }
    }
    if (right < 0) {
        return r;
    }

    // Search top edge of watermark
    int top = -1;
    for (int y = 0; y < height; ++y) {
        bool found = false;
        for (int x = 0; x < width; ++x) {
            for (int j = 0; j < bytesPerPixel; ++j) {
                int index = scanlineSizeInBytes * y + x * bytesPerPixel + j;
                if (inputBuffer_[index] != (uint8_t)0xff) {
                    found = true;
                    top = y;
                    break;
                }
            }
            if (found) {
                break;
            }
        }
        if (found) {
            break;
        }
    }
    if (top < 0) {
        return r;
    }

    // Search bottom edge of watermark
    int bottom = -1;
    for (int y = height - 1; y >= 0; --y) {
        bool found = false;
        for (int x = 0; x < width; ++x) {
            for (int j = 0; j < bytesPerPixel; ++j) {
                int index = scanlineSizeInBytes * y + x * bytesPerPixel + j;
                if (inputBuffer_[index] != (uint8_t)0xff) {
                    found = true;
                    bottom = y;
                    break;
                }
            }
            if (found) {
                break;
            }
        }
        if (found) {
            break;
        }
    }
    if (top < 0) {
        return r;
    }

    r->x_ = left;
    r->y_ = top;

    int const watermarkWidth = right - left + 1;
    int const watermarkHeight = bottom - top + 1;
    r->width_ = watermarkWidth;
    r->height_ = watermarkHeight;

    r->watermark_ = std::make_shared<Bitmap>(watermarkWidth, watermarkHeight);
    for (int y = 0; y < watermarkHeight; ++y) {
        for (int x = 0; x < watermarkWidth; ++x) {
            int index = scanlineSizeInBytes * (y + top) + (x + left) * bytesPerPixel;
            uint8_t red = inputBuffer_[index];
            uint8_t green = inputBuffer_[index + 1];
            uint8_t blue = inputBuffer_[index + 2];
            r->watermark_->setPixel(x, watermarkHeight - y - 1, Color{ red, green, blue });
        }
    }
    return r;
}
Exemplo n.º 3
0
static HRESULT WINAPI AVICompressorIn_Receive(BaseInputPin *base, IMediaSample *pSample)
{
    AVICompressor *This = impl_from_BasePin(&base->pin);
    VIDEOINFOHEADER *src_videoinfo;
    REFERENCE_TIME start, stop;
    IMediaSample *out_sample;
    AM_MEDIA_TYPE *mt;
    IMediaSample2 *sample2;
    DWORD comp_flags = 0;
    BOOL is_preroll;
    BOOL sync_point;
    BYTE *ptr, *buf;
    DWORD res;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", base, pSample);

    if(!This->hic) {
        FIXME("Driver not loaded\n");
        return E_UNEXPECTED;
    }

    hres = IMediaSample_QueryInterface(pSample, &IID_IMediaSample2, (void**)&sample2);
    if(SUCCEEDED(hres)) {
        FIXME("Use IMediaSample2\n");
        IMediaSample2_Release(sample2);
    }

    is_preroll = IMediaSample_IsPreroll(pSample) == S_OK;
    sync_point = IMediaSample_IsSyncPoint(pSample) == S_OK;

    hres = IMediaSample_GetTime(pSample, &start, &stop);
    if(FAILED(hres)) {
        WARN("GetTime failed: %08x\n", hres);
        return hres;
    }

    hres = IMediaSample_GetMediaType(pSample, &mt);
    if(FAILED(hres))
        return hres;

    hres = IMediaSample_GetPointer(pSample, &ptr);
    if(FAILED(hres)) {
        WARN("GetPointer failed: %08x\n", hres);
        return hres;
    }

    hres = BaseOutputPinImpl_GetDeliveryBuffer(This->out, &out_sample, &start, &stop, 0);
    if(FAILED(hres))
        return hres;

    hres = IMediaSample_GetPointer(out_sample, &buf);
    if(FAILED(hres))
        return hres;

    if((This->driver_flags & VIDCF_TEMPORAL) && !(This->driver_flags & VIDCF_FASTTEMPORALC))
        FIXME("Unsupported temporal compression\n");

    src_videoinfo = (VIDEOINFOHEADER*)This->in->pin.mtCurrent.pbFormat;
    This->videoinfo->bmiHeader.biSizeImage = This->max_frame_size;
    res = ICCompress(This->hic, sync_point ? ICCOMPRESS_KEYFRAME : 0, &This->videoinfo->bmiHeader, buf,
            &src_videoinfo->bmiHeader, ptr, 0, &comp_flags, This->frame_cnt, 0, 0, NULL, NULL);
    if(res != ICERR_OK) {
        WARN("ICCompress failed: %d\n", res);
        IMediaSample_Release(out_sample);
        return E_FAIL;
    }

    IMediaSample_SetActualDataLength(out_sample, This->videoinfo->bmiHeader.biSizeImage);
    IMediaSample_SetPreroll(out_sample, is_preroll);
    IMediaSample_SetSyncPoint(out_sample, (comp_flags&AVIIF_KEYFRAME) != 0);
    IMediaSample_SetDiscontinuity(out_sample, (IMediaSample_IsDiscontinuity(pSample) == S_OK));

    if (IMediaSample_GetMediaTime(pSample, &start, &stop) == S_OK)
        IMediaSample_SetMediaTime(out_sample, &start, &stop);
    else
        IMediaSample_SetMediaTime(out_sample, NULL, NULL);

    hres = BaseOutputPinImpl_Deliver(This->out, out_sample);
    if(FAILED(hres))
        WARN("Deliver failed: %08x\n", hres);

    IMediaSample_Release(out_sample);
    This->frame_cnt++;
    return hres;
}
Exemplo n.º 4
0
BOOST_DATA_TEST_CASE(vcm_encdec, make_data_from_tuple_container(vecEncDecClips), src, dst, fmt, config, tolerance)
{
	VideoClip srcClip(src);
	VideoClip dstClip(dst);
	DWORD fccCodec = FCC(fmt);

	BOOST_REQUIRE(srcClip.GetWidth() == dstClip.GetWidth());
	BOOST_REQUIRE(srcClip.GetHeight() == dstClip.GetHeight());

	DWORD fccSrc = srcClip.GetFourCC();
	DWORD fccDst = dstClip.GetFourCC();
	unsigned int nWidth = srcClip.GetWidth();
	unsigned int nHeight = srcClip.GetHeight();

	size_t cbSrcData;
	size_t cbDstData;
	size_t cbCompressedData;

	HIC hicEncode, hicDecode;
	LRESULT lr;
	union
	{
		BITMAPINFOHEADER bihCompressed;
		char bihCompressedBuf[128];
	};
	BITMAPINFOHEADER bihSrc;
	BITMAPINFOHEADER bihDst;

	hicEncode = ICOpen(ICTYPE_VIDEO, fccCodec, ICMODE_COMPRESS);
	BOOST_REQUIRE(hicEncode != NULL);
	ICCloser iccloserEnc(hicEncode);

	lr = ICSetState(hicEncode, &config.front(), config.size());
	BOOST_REQUIRE(lr == config.size());

	hicDecode = ICOpen(ICTYPE_VIDEO, fccCodec, ICMODE_DECOMPRESS);
	BOOST_REQUIRE(hicDecode != NULL);
	ICCloser iccloserDec(hicDecode);

	memset(&bihSrc, 0, sizeof(BITMAPINFOHEADER));
	bihSrc.biSize = sizeof(BITMAPINFOHEADER);
	bihSrc.biWidth = nWidth;
	bihSrc.biHeight = nHeight;
	bihSrc.biPlanes = 1;
	bihSrc.biBitCount = FCC2BitCount(fccSrc);
	bihSrc.biCompression = FCC2Compression(fccSrc);
	bihSrc.biSizeImage = 10000000;

	memset(&bihDst, 0, sizeof(BITMAPINFOHEADER));
	bihDst.biSize = sizeof(BITMAPINFOHEADER);
	bihDst.biWidth = nWidth;
	bihDst.biHeight = nHeight;
	bihDst.biPlanes = 1;
	bihDst.biBitCount = FCC2BitCount(fccDst);
	bihDst.biCompression = FCC2Compression(fccDst);
	bihDst.biSizeImage = 10000000;

	lr = ICCompressGetFormat(hicEncode, &bihSrc, &bihCompressed);
	BOOST_REQUIRE_EQUAL(lr, ICERR_OK);
	cbCompressedData = ICCompressGetSize(hicEncode, &bihSrc, &bihCompressed);

	lr = ICCompressBegin(hicEncode, &bihSrc, &bihCompressed);
	BOOST_REQUIRE_EQUAL(lr, ICERR_OK);

	lr = ICDecompressBegin(hicDecode, &bihCompressed, &bihDst);
	BOOST_REQUIRE_EQUAL(lr, ICERR_OK);

	void *pSrcData;
	void *pDstData;
	void *pEncoderOut = malloc(cbCompressedData);
	void *pDecoderOut = NULL;
	int retSrc, retDst;
	LONG lFrameNum = 0;
	while ((retSrc = srcClip.GetNextFrame(&pSrcData, &cbSrcData, NULL)) == 0 &&
		(retDst = dstClip.GetNextFrame(&pDstData, &cbDstData, NULL) == 0))
	{
		DWORD dwFlags = 0;
		lr = ICCompress(hicEncode, 0, &bihCompressed, pEncoderOut, &bihSrc, pSrcData, NULL, &dwFlags, lFrameNum++, 0, 0, &bihSrc, NULL);
		BOOST_REQUIRE(lr == ICERR_OK);

		if (pDecoderOut == NULL)
			pDecoderOut = malloc(cbDstData);

		lr = ICDecompress(hicDecode, (dwFlags & AVIIF_KEYFRAME) ? 0 : ICDECOMPRESS_NOTKEYFRAME, &bihCompressed, pEncoderOut, &bihDst, pDecoderOut);
		BOOST_REQUIRE(lr == ICERR_OK);

		BOOST_CHECK(bihDst.biSizeImage == cbDstData);
		BOOST_CHECK(CompareFrame(pDstData, pDecoderOut, nWidth, cbDstData, fccDst, tolerance) == 0);
	}

	BOOST_CHECK(retSrc != 0 && retDst != 0);
	if (pDecoderOut != NULL)
		free(pDecoderOut);
	free(pEncoderOut);

	lr = ICDecompressEnd(hicDecode);
	BOOST_CHECK(lr == ICERR_OK);

	lr = ICCompressEnd(hicEncode);
	BOOST_CHECK(lr == ICERR_OK);
}
Exemplo n.º 5
0
static HRESULT AVIFILE_EncodeFrame(IAVIStreamImpl *This,
				   LPBITMAPINFOHEADER lpbi, LPVOID lpBits)
{
  DWORD dwMinQual, dwMaxQual, dwCurQual;
  DWORD dwRequest;
  DWORD icmFlags = 0;
  DWORD idxFlags = 0;
  BOOL  bDecreasedQual = FALSE;
  BOOL  doSizeCheck;
  BOOL  noPrev;

  /* make lKeyFrameEvery and at start a keyframe */
  if ((This->lKeyFrameEvery != 0 &&
       (This->lCurrent - This->lLastKey) >= This->lKeyFrameEvery) ||
      This->lCurrent == This->sInfo.dwStart) {
    idxFlags = AVIIF_KEYFRAME;
    icmFlags = ICCOMPRESS_KEYFRAME;
  }

  if (This->lKeyFrameEvery != 0) {
    if (This->lCurrent == This->sInfo.dwStart) {
      if (idxFlags & AVIIF_KEYFRAME) {
	/* for keyframes allow to consume all unused bytes */
	dwRequest = This->dwBytesPerFrame + This->dwUnusedBytes;
	This->dwUnusedBytes = 0;
      } else {
	/* for non-keyframes only allow something of the unused bytes to be consumed */
	DWORD tmp1 = 0;
	DWORD tmp2;

	if (This->dwBytesPerFrame >= This->dwUnusedBytes)
	  tmp1 = This->dwBytesPerFrame / This->lKeyFrameEvery;
	tmp2 = (This->dwUnusedBytes + tmp1) / This->lKeyFrameEvery;

	dwRequest = This->dwBytesPerFrame - tmp1 + tmp2;
	This->dwUnusedBytes -= tmp2;
      }
    } else
      dwRequest = MAX_FRAMESIZE;
  } else {
    /* only one keyframe at start desired */
    if (This->lCurrent == This->sInfo.dwStart) {
      dwRequest = This->dwBytesPerFrame + This->dwUnusedBytes;
      This->dwUnusedBytes = 0;
    } else
      dwRequest = MAX_FRAMESIZE;
  }

  /* must we check for framesize to gain requested
   * datarate or could we trust codec? */
  doSizeCheck = (dwRequest != 0 && ((This->dwICMFlags & (VIDCF_CRUNCH|VIDCF_QUALITY)) == 0));

  dwMaxQual = dwCurQual = This->sInfo.dwQuality;
  dwMinQual = ICQUALITY_LOW;

  noPrev = TRUE;
  if ((icmFlags & ICCOMPRESS_KEYFRAME) == 0 && 
      (This->dwICMFlags & VIDCF_FASTTEMPORALC) == 0)
    noPrev = FALSE;

  do {
    DWORD   idxCkid = 0;
    DWORD   res;

    res = ICCompress(This->hic,icmFlags,This->lpbiCur,This->lpCur,lpbi,lpBits,
		     &idxCkid, &idxFlags, This->lCurrent, dwRequest, dwCurQual,
		     noPrev ? NULL:This->lpbiPrev, noPrev ? NULL:This->lpPrev);
    if (res == ICERR_NEWPALETTE) {
      FIXME(": codec has changed palette -- unhandled!\n");
    } else if (res != ICERR_OK)
      return AVIERR_COMPRESSOR;

    /* need to check for framesize */
    if (! doSizeCheck)
      break;

    if (dwRequest >= This->lpbiCur->biSizeImage) {
      /* frame is smaller -- try to maximize quality */
      if (dwMaxQual - dwCurQual > 10) {
	DWORD tmp = dwRequest / 8;

	if (tmp < MAX_FRAMESIZE_DIFF)
	  tmp = MAX_FRAMESIZE_DIFF;

	if (tmp < dwRequest - This->lpbiCur->biSizeImage && bDecreasedQual) {
	  tmp = dwCurQual;
	  dwCurQual = (dwMinQual + dwMaxQual) / 2;
	  dwMinQual = tmp;
	  continue;
	}
      } else
	break;
    } else if (dwMaxQual - dwMinQual <= 1) {
      break;
    } else {
      dwMaxQual = dwCurQual;

      if (bDecreasedQual || dwCurQual == This->dwLastQuality)
	dwCurQual = (dwMinQual + dwMaxQual) / 2;
      else
	FIXME(": no new quality computed min=%u cur=%u max=%u last=%u\n",
	      dwMinQual, dwCurQual, dwMaxQual, This->dwLastQuality);

      bDecreasedQual = TRUE;
    }
  } while (TRUE);

  /* remember some values */
  This->dwLastQuality = dwCurQual;
  This->dwUnusedBytes = dwRequest - This->lpbiCur->biSizeImage;
  if (icmFlags & ICCOMPRESS_KEYFRAME)
    This->lLastKey = This->lCurrent;

  /* Does we manage previous frame? */
  if (This->lpPrev != NULL && This->lKeyFrameEvery != 1)
    ICDecompress(This->hic, 0, This->lpbiCur, This->lpCur,
		 This->lpbiPrev, This->lpPrev);

  return AVIERR_OK;
}