用DirectX显示video时加边框

4 篇文章 0 订阅
1 篇文章 0 订阅

1、是给每帧图像加一个边框, 显示出来的视频的每一帧上下左右的几个像素都被填充的颜色覆盖掉了。

HRESULT Demo::ShowVideo(D3DFORMAT Format, BYTE * image, int width, int height, int borderWidth)
{
	HRESULT hr;
	int resizeYuvW = width;
	int resizeYuvH = height;
	
	// 锁定 swap-chain 表面.
	D3DLOCKED_RECT lr;
	hr = pPlainSurf_->LockRect(&lr, NULL, D3DLOCK_NOSYSLOCK);
	if (FAILED(hr))
	{
		return hr;
	}

    BYTE* newImage = new BYTE[resizeYuvW*resizeYuvH * 3 / 2];
    memcpy(newImage, image, resizeYuvW*resizeYuvH * 3 / 2);
	// 将数据拷贝到 Direct3D surface.
	BYTE *dest = (BYTE*)lr.pBits;
	DrawBorder(newImage, resizeYuvW, resizeYuvH, 1, borderWidth);

	BYTE *src = newImage;
	int stride = lr.Pitch;
	CopyFrameToD3DRectYV12(src, dest, resizeYuvW, resizeYuvH, stride);

    delete[] newImage;

	hr = pPlainSurf_->UnlockRect();
	if (FAILED(hr))
	{
		return hr;
	}

	// 获取下一个表面.
	IDirect3DSurface9 *pSurface = NULL;
	hr = pSwapChain_->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurface);
	if (FAILED(hr))
	{
		return hr;
	}

	RECT srcRect, destRect;
	::SetRect(&srcRect, 0, 0, resizeYuvW, resizeYuvH);
	if (borderWidth != 0)
	{
		// 填充颜色.
		hr = pDevice_->ColorFill(pSurface, NULL, D3DCOLOR_ARGB(0, 60, 210, 60));
		::SetRect(&destRect, borderWidth, borderWidth, width_ - borderWidth, height_ - borderWidth);
	}
	else
	{
		::SetRect(&destRect, 0, 0, width_, height_);
	}

	hr = pDevice_->StretchRect(pPlainSurf_, &srcRect, pSurface, &destRect, D3DTEXF_LINEAR);

	if (FAILED(hr))
	{
		SafeRelease(&pSurface);
		return hr;
	}

	// 显示.
	hr = pSwapChain_->Present(NULL, NULL, NULL, NULL, 0);
	SafeRelease(&pSurface);
	return hr;
}


void Demo::DrawBorder(BYTE * src, int w, int h, int num, int border)
{
	for (int i = 0; i < num; i++)
	{
		for (int m = 0; m < h; m++)
		{
			for (int n = 0; n < w; n++)
			{
				if ((m < border) | (m > (h - border)) | (n < border) | (n > (w - border)))
				{
					src[m*w + n] = 105;
				}
			}
		}

		BYTE *U = src + w * h;
		BYTE *V = src + w * h * 5 / 4;
		for (int m = 0; m < h/2; m++)
		{
			for (int n = 0; n < w/2; n++)
			{
				if ((m < border/2) | (m > (h - border)/2) | (n < border/2) | (n >= (w - border)/2))
				{
					U[m*w / 2 + n] = 184;
					V[m*w / 2 + n] = 63;
				}
			}
		}
	}
}


2、是给画布填充颜色,然后把显示video的部分上下左右各缩进几个像素

HRESULT Demo::ShowVideo(D3DFORMAT Format, BYTE * image, int width, int height, int borderWidth)
{
	HRESULT hr;
	int resizeYuvW = width;
	int resizeYuvH = height;
	
	// 锁定 swap-chain 表面.
	D3DLOCKED_RECT lr;
	hr = pPlainSurf_->LockRect(&lr, NULL, D3DLOCK_NOSYSLOCK);
	if (FAILED(hr))
	{
		return hr;
	}

	// 将数据拷贝到 Direct3D surface.
	BYTE *dest = (BYTE*)lr.pBits;
	BYTE *src = image;
	int stride = lr.Pitch;
	CopyFrameToD3DRectYV12(src, dest, resizeYuvW, resizeYuvH, stride);

	hr = pPlainSurf_->UnlockRect();
	if (FAILED(hr))
	{
		return hr;
	}

	// 获取下一个表面.
	IDirect3DSurface9 *pSurface = NULL;
	hr = pSwapChain_->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurface);
	if (FAILED(hr))
	{
		return hr;
	}

	RECT srcRect, destRect;
	::SetRect(&srcRect, 0, 0, resizeYuvW, resizeYuvH);
	if (borderWidth != 0)
	{
		// 填充颜色.
		hr = pDevice_->ColorFill(pSurface, NULL, D3DCOLOR_ARGB(0, 60, 210, 60));
		::SetRect(&destRect, borderWidth, borderWidth, width_ - borderWidth, height_ - borderWidth);
	}
	else
	{
		::SetRect(&destRect, 0, 0, width_, height_);
	}

	hr = pDevice_->StretchRect(pPlainSurf_, &srcRect, pSurface, &destRect, D3DTEXF_LINEAR);

	if (FAILED(hr))
	{
		SafeRelease(&pSurface);
		return hr;
	}

	// 显示.
	hr = pSwapChain_->Present(NULL, NULL, NULL, NULL, 0);
	SafeRelease(&pSurface);
	return hr;
}


void Demo::CopyFrameToD3DRectYV12(BYTE* src, BYTE* dest, int width, int height, int stride)
{
    int bufferH = 1080;
    int i = 0;
    for (i = 0; i < height; i++)
    {
        memcpy(dest + i * stride, src + i * width, width);
    }
    for (i = 0; i < height / 2; i++)
    {
        memcpy(dest + stride * bufferH + i * stride / 2, src + width * height + width * height / 4 + i * width / 2, width / 2);
    }
    for (i = 0; i < height / 2; i++)
    {
        memcpy(dest + stride * bufferH + stride * bufferH / 4 + i * stride / 2, src + width * height + i * width / 2, width / 2);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值