Пример #1
0
bool BitBltFromI420ToI420(int w, int h, BYTE* dsty, BYTE* dstu, BYTE* dstv, int dstpitch, BYTE* srcy, BYTE* srcu, BYTE* srcv, int srcpitch)
{
    VDPixmap srcbm = {0};

    srcbm.data      = srcy;
    srcbm.pitch     = srcpitch;
    srcbm.w         = w;
    srcbm.h         = h;
    srcbm.format    = nsVDPixmap::kPixFormat_YUV420_Planar;
    srcbm.data2     = srcu;
    srcbm.pitch2    = srcpitch / 2;
    srcbm.data3     = srcv;
    srcbm.pitch3    = srcpitch / 2;

    VDPixmap dstpxm = {0};

    dstpxm.data     = dsty;
    dstpxm.pitch    = dstpitch;
    dstpxm.w        = w;
    dstpxm.h        = h;
    dstpxm.format   = nsVDPixmap::kPixFormat_YUV420_Planar;
    dstpxm.data2    = dstu;
    dstpxm.pitch2   = dstpitch / 2;
    dstpxm.data3    = dstv;
    dstpxm.pitch3   = dstpitch / 2;

    return VDPixmapBlt(dstpxm, srcbm);
}
Пример #2
0
sint32 VDVideoFilterInput::Run() {
	mpSource->getFrame(mpContext->mpOutput->mFrameNum);

	mpContext->AllocFrame();

	VDPixmapBlt(*mpContext->mpDstFrame->mpPixmap, mpSource->getTargetFormat());

	return kVFVRun_OK;
}
Пример #3
0
bool BitBltFromRGBToRGB(int w, int h, BYTE* dst, int dstpitch, int dbpp, BYTE* src, int srcpitch, int sbpp)
{
    VDPixmap srcbm = {
        (char *)src + srcpitch * (h - 1),
        NULL,
        w,
        h,
        -srcpitch
    };

    switch(sbpp) {
    case 8:
        srcbm.format = nsVDPixmap::kPixFormat_Pal8;
        break;
    case 16:
        srcbm.format = nsVDPixmap::kPixFormat_RGB565;
        break;
    case 24:
        srcbm.format = nsVDPixmap::kPixFormat_RGB888;
        break;
    case 32:
        srcbm.format = nsVDPixmap::kPixFormat_XRGB8888;
        break;
    default:
        VDASSERT(false);
    }

    VDPixmap dstpxm = {
        (char *)dst + dstpitch * (h - 1),
        NULL,
        w,
        h,
        -dstpitch
    };

    switch(dbpp) {
    case 8:
        dstpxm.format = nsVDPixmap::kPixFormat_Pal8;
        break;
    case 16:
        dstpxm.format = nsVDPixmap::kPixFormat_RGB565;
        break;
    case 24:
        dstpxm.format = nsVDPixmap::kPixFormat_RGB888;
        break;
    case 32:
        dstpxm.format = nsVDPixmap::kPixFormat_XRGB8888;
        break;
    default:
        VDASSERT(false);
    }

    return VDPixmapBlt(dstpxm, srcbm);
}
Пример #4
0
const void *VDVideoSourceFLM::streamGetFrame(const void *inputBuffer, uint32 data_len, bool is_preroll, VDPosition frame_num, VDPosition target_sample) {
	VDPixmap srcbm = {0};

	srcbm.data		= (void *)inputBuffer;
	srcbm.pitch		= mWidth * 4;
	srcbm.w			= mWidth;
	srcbm.h			= mHeight;
	srcbm.format	= nsVDPixmap::kPixFormat_XRGB8888;

	VDPixmapBlt(mTargetFormat, srcbm);

	mCachedFrame = frame_num;

	return getFrameBuffer();
}
Пример #5
0
void VDVideoDecompressorHuffyuv::DecompressFrame(void *dst, const void *src, uint32 srcSize, bool keyframe, bool preroll) {
	if (!mFormat)
		throw MyError("Cannot find compatible target format for video decompression.");

	mpDecoder->DecompressFrame(src, srcSize);

	// blit time!

	VDPixmap pxsrc(mpDecoder->GetFrameBuffer());

	VDPixmapLayout dstlayout;
	VDMakeBitmapCompatiblePixmapLayout(dstlayout, mWidth, mHeight, mFormat, 0);
	VDPixmap pxdst(VDPixmapFromLayout(dstlayout, dst));

	VDPixmapBlt(pxdst, pxsrc);
}
Пример #6
0
LRESULT Frameserver::SessionFrame(LPARAM lParam, WPARAM original_frame) {
	FrameserverSession *fs = SessionLookup(lParam);

	if (!fs)
		return VDSRVERR_BADSESSION;

	try {
		const VDPixmapLayout& output = filters.GetOutputLayout();
		if (fs->arena_size < ((output.w*3+3)&-4)*output.h)
			return VDSRVERR_TOOBIG;

		VDPosition pos = mVideoFrameMap[original_frame].mSourceFrame;

		if (pos < 0)
			return VDSRVERR_FAILED;

		vdrefptr<IVDFilterFrameClientRequest> creq;
		filters.RequestFrame(pos, 0, ~creq);

		while(!creq->IsCompleted()) {
			if (filters.Run(NULL, false) == FilterSystem::kRunResult_Running)
				continue;

			switch(mpVideoFrameSource->RunRequests(NULL)) {
				case IVDFilterFrameSource::kRunResult_Running:
				case IVDFilterFrameSource::kRunResult_IdleWasActive:
				case IVDFilterFrameSource::kRunResult_BlockedWasActive:
					continue;
			}

			filters.Block();
		}

		VDPixmap pxdst(VDPixmapFromLayout(mFrameLayout, fs->arena));

		VDFilterFrameBuffer *buf = creq->GetResultBuffer();
		VDPixmapBlt(pxdst, VDPixmapFromLayout(filters.GetOutputLayout(), (void *)buf->LockRead()));
		buf->Unlock();
	} catch(const MyError&) {
		return VDSRVERR_FAILED;
	}

	return VDSRVERR_OK;
}
Пример #7
0
bool BitBltFromI420ToYUY2(int w, int h, BYTE* dst, int dstpitch, BYTE* srcy, BYTE* srcu, BYTE* srcv, int srcpitch)
{
    if (srcpitch == 0) srcpitch = w;

#ifndef _WIN64
    if ((g_cpuid.m_flags & CCpuID::sse2)
        && !((DWORD_PTR)srcy&15) && !((DWORD_PTR)srcu&15) && !((DWORD_PTR)srcv&15) && !(srcpitch&31)
        && !((DWORD_PTR)dst&15) && !(dstpitch&15))
    {
        if (w<=0 || h<=0 || (w&1) || (h&1))
            return false;

        yv12_yuy2_sse2(srcy, srcu, srcv, srcpitch/2, w/2, h, dst, dstpitch);
        return true;
    }
#endif

    VDPixmap srcbm = {0};

    srcbm.data      = srcy;
    srcbm.pitch     = srcpitch;
    srcbm.w         = w;
    srcbm.h         = h;
    srcbm.format    = nsVDPixmap::kPixFormat_YUV420_Planar;
    srcbm.data2     = srcu;
    srcbm.pitch2    = srcpitch/2;
    srcbm.data3     = srcv;
    srcbm.pitch3    = srcpitch/2;

    VDPixmap dstpxm = {
        dst,
        NULL,
        w,
        h,
        dstpitch
    };

    dstpxm.format = nsVDPixmap::kPixFormat_YUV422_YUYV;

    return VDPixmapBlt(dstpxm, srcbm);
}
Пример #8
0
bool BitBltFromYUY2ToYUY2(int w, int h, BYTE* dst, int dstpitch, BYTE* src, int srcpitch)
{
    VDPixmap srcbm = {0};

    srcbm.data      = src;
    srcbm.pitch     = srcpitch;
    srcbm.w         = w;
    srcbm.h         = h;
    srcbm.format    = nsVDPixmap::kPixFormat_YUV422_YUYV;

    VDPixmap dstpxm = {
        dst,
        NULL,
        w,
        h,
        dstpitch
    };

    dstpxm.format = nsVDPixmap::kPixFormat_YUV422_YUYV;

    return VDPixmapBlt(dstpxm, srcbm);
}
Пример #9
0
bool BitBltFromI420ToRGB(int w, int h, BYTE* dst, int dstpitch, int dbpp, BYTE* srcy, BYTE* srcu, BYTE* srcv, int srcpitch)
{
    VDPixmap srcbm = {0};

    srcbm.data      = srcy;
    srcbm.pitch     = srcpitch;
    srcbm.w         = w;
    srcbm.h         = h;
    srcbm.format    = nsVDPixmap::kPixFormat_YUV420_Planar;
    srcbm.data2     = srcu;
    srcbm.pitch2    = srcpitch/2;
    srcbm.data3     = srcv;
    srcbm.pitch3    = srcpitch/2;

    VDPixmap dstpxm = {
        (char *)dst + dstpitch * (h - 1),
        NULL,
        w,
        h,
        -dstpitch
    };

    switch(dbpp) {
    case 16:
        dstpxm.format = nsVDPixmap::kPixFormat_RGB565;
        break;
    case 24:
        dstpxm.format = nsVDPixmap::kPixFormat_RGB888;
        break;
    case 32:
        dstpxm.format = nsVDPixmap::kPixFormat_XRGB8888;
        break;
    default:
        VDASSERT(false);
    }

    return VDPixmapBlt(dstpxm, srcbm);
}
Пример #10
0
bool BitBltFromYUY2ToRGB(int w, int h, BYTE* dst, int dstpitch, int dbpp, BYTE* src, int srcpitch)
{
    if (srcpitch == 0) srcpitch = w;

    VDPixmap srcbm = {0};

    srcbm.data      = src;
    srcbm.pitch     = srcpitch;
    srcbm.w         = w;
    srcbm.h         = h;
    srcbm.format    = nsVDPixmap::kPixFormat_YUV422_YUYV;

    VDPixmap dstpxm = {
        (char *)dst + dstpitch * (h - 1),
        NULL,
        w,
        h,
        -dstpitch
    };

    switch(dbpp) {
    case 16:
        dstpxm.format = nsVDPixmap::kPixFormat_RGB565;
        break;
    case 24:
        dstpxm.format = nsVDPixmap::kPixFormat_RGB888;
        break;
    case 32:
        dstpxm.format = nsVDPixmap::kPixFormat_XRGB8888;
        break;
    default:
        VDASSERT(false);
    }

    return VDPixmapBlt(dstpxm, srcbm);
}
Пример #11
0
LRESULT Frameserver::SessionFrame(LPARAM lParam, WPARAM original_frame) {
	FrameserverSession *fs = SessionLookup(lParam);

	if (!fs)
		return VDSRVERR_BADSESSION;

	try {
		const void *ptr = vSrc->getFrameBuffer();
		const BITMAPINFOHEADER *bmih = vSrc->getDecompressedFormat();
		VDPosition sample;
		bool is_preroll;

		if (fs->arena_size < ((filters.LastBitmap()->w*3+3)&-4)*filters.LastBitmap()->h)
			return VDSRVERR_TOOBIG;

		sample = mVideoFrameMap[original_frame].mDisplayFrame;

		if (sample < 0)
			return VDSRVERR_FAILED;

		vSrc->streamSetDesiredFrame(sample);

		VDPosition targetSample = vSrc->displayToStreamOrder(sample);
		VDPosition frame = vSrc->streamGetNextRequiredFrame(is_preroll);

		if (frame >= 0) {
			do {
				uint32 lSize;
				int hr;

	//			_RPT1(0,"feeding frame %ld\n", frame);

				hr = vSrc->read(frame, 1, NULL, 0x7FFFFFFF, &lSize, NULL);
				if (hr)
					return VDSRVERR_FAILED;

				uint32 bufSize = (lSize + 65535 + vSrc->streamGetDecodePadding()) & ~65535;
				if (mInputBuffer.size() < bufSize)
					mInputBuffer.resize(bufSize);

				hr = vSrc->read(frame, 1, mInputBuffer.data(), lSize, &lSize, NULL); 
				if (hr)
					return VDSRVERR_FAILED;

				vSrc->streamFillDecodePadding(mInputBuffer.data(), lSize);
				ptr = vSrc->streamGetFrame(mInputBuffer.data(), lSize, is_preroll, frame, targetSample);
			} while(-1 != (frame = vSrc->streamGetNextRequiredFrame(is_preroll)));

		} else
			ptr = vSrc->streamGetFrame(NULL, 0, FALSE, targetSample, targetSample);

		VDPixmap pxdst(VDPixmapFromLayout(mFrameLayout, fs->arena));

		if (!g_listFA.IsEmpty()) {
			VDPixmapBlt(VDAsPixmap(*filters.InputBitmap()), vSrc->getTargetFormat());

			fsi.lCurrentFrame				= original_frame;
			fsi.lCurrentSourceFrame			= sample;
			fsi.lSourceFrameMS				= MulDiv(fsi.lCurrentSourceFrame, fsi.lMicrosecsPerSrcFrame, 1000);
			fsi.lDestFrameMS				= MulDiv(fsi.lCurrentFrame, fsi.lMicrosecsPerFrame, 1000);

			filters.RunFilters(fsi);

			VDPixmapBlt(pxdst, VDAsPixmap(*filters.LastBitmap()));
		} else
			VDPixmapBlt(pxdst, vSrc->getTargetFormat());

	} catch(const MyError&) {
		return VDSRVERR_FAILED;
	}

	return VDSRVERR_OK;
}
Пример #12
0
const void *VideoSourceImages::streamGetFrame(const void *inputBuffer, uint32 data_len, bool is_preroll, VDPosition frame_num, VDPosition target_sample) {
	// We may get a zero-byte frame if we already have the image.

	if (!data_len)
		return getFrameBuffer();

	int w, h;
	bool bHasAlpha;

	bool bIsPNG = false;
	bool bIsJPG = false;
	bool bIsBMP = false;
	bool bIsIFF = false;
	bool bIsTGA = false;

	bIsPNG = VDDecodePNGHeader(inputBuffer, data_len, w, h, bHasAlpha);
	if (!bIsPNG) {
		bIsJPG = VDIsJPEGHeader(inputBuffer, data_len);
		if (!bIsJPG) {
			bIsBMP = DecodeBMPHeader(inputBuffer, data_len, w, h, bHasAlpha);
			if (!bIsBMP) {
				bIsIFF = VDIsMayaIFFHeader(inputBuffer, data_len);
				if (!bIsIFF)
					bIsTGA = DecodeTGAHeader(inputBuffer, data_len, w, h, bHasAlpha);
			}
		}
	}

	if (!bIsBMP && !bIsTGA && !bIsJPG && !bIsPNG && !bIsIFF)
		throw MyError("Image file must be in PNG, Windows BMP, truecolor TARGA format, MayaIFF, or sequential JPEG format.");

	if (bIsJPG) {
		if (!mpJPEGDecoder)
			mpJPEGDecoder = VDCreateJPEGDecoder();
		mpJPEGDecoder->Begin(inputBuffer, data_len);
		mpJPEGDecoder->DecodeHeader(w, h);
	}

	VDPixmap pxIFF;
	if (bIsIFF) {
		if (!mpIFFDecoder)
			mpIFFDecoder = VDCreateImageDecoderIFF();
		pxIFF = mpIFFDecoder->Decode(inputBuffer, data_len);
		w = pxIFF.w;
		h = pxIFF.h;
	}

	// Check image header.

	VDAVIBitmapInfoHeader *pFormat = getImageFormat();

	if (getFrameBuffer()) {
		if (w != pFormat->biWidth || h != pFormat->biHeight) {
			vdfastvector<wchar_t> errBuf;

			throw MyError("Image \"%ls\" (%dx%d) doesn't match the image dimensions of the first image (%dx%d)."
					, mpParent->ComputeFilename(errBuf, frame_num), w, h, pFormat->biWidth, pFormat->biHeight);
		}

	} else {
		if (!AllocFrameBuffer(w * h * 4))
			throw MyMemoryError();

		pFormat->biSize				= sizeof(BITMAPINFOHEADER);
		pFormat->biWidth			= w;
		pFormat->biHeight			= h;
		pFormat->biPlanes			= 1;
		pFormat->biCompression		= 0xFFFFFFFFUL;
		pFormat->biBitCount			= 0;
		pFormat->biSizeImage		= 0;
		pFormat->biXPelsPerMeter	= 0;
		pFormat->biYPelsPerMeter	= 0;
		pFormat->biClrUsed			= 0;
		pFormat->biClrImportant		= 0;

		// special case for initial read in constructor

		return NULL;
	}

	if (bIsJPG) {
		int format;

		switch(mvbFrameBuffer.depth) {
		case 16:	format = IVDJPEGDecoder::kFormatXRGB1555;	break;
		case 24:	format = IVDJPEGDecoder::kFormatRGB888;		break;
		case 32:	format = IVDJPEGDecoder::kFormatXRGB8888;	break;
		}

		mpJPEGDecoder->DecodeImage((char *)mvbFrameBuffer.data + mvbFrameBuffer.pitch * (mvbFrameBuffer.h - 1), -mvbFrameBuffer.pitch, format);
		mpJPEGDecoder->End();
	}

	if (bIsIFF)
		VDPixmapBlt(getTargetFormat(), pxIFF);

	if (bIsBMP)
		DecodeBMP(inputBuffer, data_len, mvbFrameBuffer);
	if (bIsTGA)
		DecodeTGA(inputBuffer, data_len, mvbFrameBuffer);
	if (bIsPNG) {
		if (!mpPNGDecoder)
			mpPNGDecoder = VDCreateImageDecoderPNG();

		PNGDecodeError err = mpPNGDecoder->Decode(inputBuffer, data_len);

		if (err) {
			if (err == kPNGDecodeOutOfMemory)
				throw MyMemoryError();

			vdfastvector<wchar_t> errBuf;

			throw MyError("Error decoding \"%ls\": %ls\n", mpParent->ComputeFilename(errBuf, frame_num), VDLoadString(0, kVDST_PNGDecodeErrors, err));
		}

		VDPixmapBlt(VDAsPixmap(mvbFrameBuffer), mpPNGDecoder->GetFrameBuffer());
	}

	mCachedFrame = frame_num;

	return mpFrameBuffer;
}
Пример #13
0
void VDTestPixmaps() {
	CPUEnableExtensions(CPUCheckForExtensions());
	VDFastMemcpyAutodetect();

	VDRegisterVideoDisplayControl();

	HWND hwndDisp = CreateWindow(VIDEODISPLAYCONTROLCLASS, "Kasumi onee-sama", WS_VISIBLE|WS_POPUP, 0, 0, 1024, 768, NULL, NULL, GetModuleHandle(NULL), NULL);

	IVDVideoDisplay *pDisp = VDGetIVideoDisplay(hwndDisp);

	const int srcw = 80;
	const int srch = 60;

	VDPixmapBuffer image(srcw, srch, nsVDPixmap::kPixFormat_XRGB8888);

	for(int y=0; y<srch; ++y) {
		for(int x=0; x<srcw; ++x) {
			int x2 = x - (srcw>>1);
			int y2 = y - (srch>>1);

			uint32 v = (int)((1.0 + sin((x2*x2 + y2*y2) / 50.0)) * 255.0 / 2.0 + 0.5);

			uint32 r = (255-v)<<16;

			if ((x^y)&1)
				v = r = 0;

			((uint32 *)((char *)image.data + image.pitch * y))[x] = (v*x/srcw) + (((v*y)/srch)<<8) + r;
		}
	}

	VDPixmapBuffer sprite(srcw, srch, nsVDPixmap::kPixFormat_XRGB8888);
	VDPixmapBuffer buffer(1024, 768, nsVDPixmap::kPixFormat_XRGB8888);

	VDPixmapBlt(sprite, image);

	pDisp->SetSourcePersistent(true, buffer);

	bouncer p1(-64, -48, 1024+64, 768+48, 1.0);
	bouncer p2(-64, -48, 1024+64, 768+48, 0.5);

	sint64 freq;
	QueryPerformanceFrequency((LARGE_INTEGER *)&freq);

	sint64 start;
	QueryPerformanceCounter((LARGE_INTEGER *)&start);
	int blits = 0;
	double th = 0;

	VDPixmapTextureMipmapChain mipchain(sprite);

	vdautoptr<IVDPixmapResampler> pResampler(VDCreatePixmapResampler());

	while(pump()) {
		int x1 = p1.xposf();
		int y1 = p1.yposf();
		int x2 = p2.xposf();
		int y2 = p2.yposf();

//		VDPixmapBlt(buffer, xp, yp, image, 0, 0, 320, 240);
//		VDPixmapStretchBltNearest(buffer, x1, y1, x2, y2, sprite, -32<<16, -32<<16, (srcw+32)<<16, (srch+32)<<16);
//		VDPixmapStretchBltBilinear(buffer, x1, y1, x2, y2, sprite, 0, 0, srcw<<16, srch<<16);

		double fx1 = x1 / 65536.0;
		double fy1 = y1 / 65536.0;
		double fx2 = x2 / 65536.0;
		double fy2 = y2 / 65536.0;

		if (fx2 < fx1)
			std::swap(fx1, fx2);
		if (fy2 < fy1)
			std::swap(fy1, fy2);

		pResampler->Init(fx2-fx1, fy2-fy1, buffer.format, sprite.w, sprite.h, sprite.format, IVDPixmapResampler::kFilterLanczos3, IVDPixmapResampler::kFilterLanczos3, false);
		pResampler->Process(&buffer, fx1, fy1, fx2, fy2, &sprite, 0, 0);

#if 0
		float mx[16]={1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1};

		mx[0] = cos(th) / 512.0f;
		mx[1] = sin(th) / 512.0f;
		mx[5] = cos(th) / 384.0f;
		mx[4] = -sin(th) / 384.0f;

		mx[13] = -6.0f / 384.0f;
		mx[15] = 1.0f;

		VDTriBltVertex vx[4]={
			{ -100, -100, 0, 0, 0 },
			{ +100, -100, 0, 0, 60 },
			{ +100, +100, 0, 80, 60 },
			{ -100, +100, 0, 80, 0 },
		};

		const int idx[6]={0,1,2,0,2,3};

		VDPixmap buffer_cropped(VDPixmapOffset(buffer, 160, 120));

		buffer_cropped.w -= 320;
		buffer_cropped.h -= 240;

		VDPixmapTriBlt(buffer_cropped, mipchain.Mips(), mipchain.Levels(), vx, 4, idx, 6, kTriBltFilterTrilinear, 0.0f, mx);

		th += 0.01;
#endif

		pDisp->Update();
		++blits;

		p1.advance();
		p2.advance();

		sint64 last;
		QueryPerformanceCounter((LARGE_INTEGER *)&last);

		if (last-start >= freq) {
			start += freq;
			VDDEBUG2("%d blits/sec\n", blits);
			blits = 0;
		}
	}
}