Beispiel #1
0
VOID CD3DUtils::FillDefaultBltInfo(DXVA2_VideoProcessBltParams &blt)
{
    blt.BackgroundColor.Alpha = 0xFFFF;
    blt.BackgroundColor.Y = 0;
    blt.BackgroundColor.Cr = 128;
    blt.BackgroundColor.Cb = 128;

    FillDefaultDXVAFormat(blt.DestFormat, DXVA2_SampleProgressiveFrame);

    blt.ProcAmpValues.Brightness = m_ProcAmpValues[0];
    blt.ProcAmpValues.Contrast = m_ProcAmpValues[1];
    blt.ProcAmpValues.Hue = m_ProcAmpValues[2];
    blt.ProcAmpValues.Saturation = m_ProcAmpValues[3];

    blt.Alpha = DXVA2_Fixed32OpaqueAlpha();

    // DXVA2_VideoProcess_NoiseFilter
    blt.NoiseFilterLuma.Level       = m_NFilterValues[0];
    blt.NoiseFilterLuma.Threshold   = m_NFilterValues[1];
    blt.NoiseFilterLuma.Radius      = m_NFilterValues[2];
    blt.NoiseFilterChroma.Level     = m_NFilterValues[3];
    blt.NoiseFilterChroma.Threshold = m_NFilterValues[4];
    blt.NoiseFilterChroma.Radius    = m_NFilterValues[5];

    // DXVA2_VideoProcess_DetailFilter
    blt.DetailFilterLuma.Level       = m_DFilterValues[0];
    blt.DetailFilterLuma.Threshold   = m_DFilterValues[1];
    blt.DetailFilterLuma.Radius      = m_DFilterValues[2];
    blt.DetailFilterChroma.Level     = m_DFilterValues[3];
    blt.DetailFilterChroma.Threshold = m_DFilterValues[4];
    blt.DetailFilterChroma.Radius    = m_DFilterValues[5];
}
Beispiel #2
0
static void FillBlitParams( DXVA2_VideoProcessBltParams *params, const RECT *area,
                            const DXVA2_VideoSample *samples, int order )
{
    memset(params, 0, sizeof(*params));
    params->TargetFrame = (samples->End - samples->Start) * order / 2;
    params->TargetRect  = *area;
    params->DestData    = 0;
    params->Alpha       = DXVA2_Fixed32OpaqueAlpha();
    params->DestFormat.SampleFormat = DXVA2_SampleProgressiveFrame;
    params->BackgroundColor.Alpha = 0xFFFF;
    params->ConstrictionSize.cx = params->TargetRect.right;
    params->ConstrictionSize.cy = params->TargetRect.bottom;
}
Beispiel #3
0
HRESULT CD3DUtils::ProgressiveBlt(IDirect3DSurface9 *pSurfIn, IDirect3DSurface9 *pSurfOut)
{
    if (!m_pVPDevice || !pSurfIn || !pSurfOut) return E_FAIL;

    DXVA2_VideoProcessBltParams blt = {0};
    DXVA2_VideoSample samples[2] = {0};
    RECT SrcRect = {0};
    RECT DstRect = {0};
    D3DSURFACE_DESC SrcDesc, DstDesc;
    IDirect3DSurface9 *pSrc = pSurfIn;
    IDirect3DSurface9 *pDst = pSurfOut;
    REFERENCE_TIME rtStart = 0;
    REFERENCE_TIME rtStop = 1;

    pSrc->GetDesc(&SrcDesc);
    pDst->GetDesc(&DstDesc);

    SrcRect.right = SrcDesc.Width;
    SrcRect.bottom = SrcDesc.Height;
    DstRect.right = DstDesc.Width;
    DstRect.bottom = DstDesc.Height;

    FillDefaultBltInfo(blt);

    blt.TargetFrame = rtStart;
    blt.TargetRect  = DstRect;

    // DXVA2_VideoProcess_Constriction
    blt.ConstrictionSize.cx = blt.TargetRect.right - blt.TargetRect.left;
    blt.ConstrictionSize.cy = blt.TargetRect.bottom - blt.TargetRect.top;

    //
    // Initialize main stream video sample.
    //
    samples[0].Start = rtStart;
    samples[0].End   = rtStop;

    FillDefaultDXVAFormat(samples[0].SampleFormat, DXVA2_SampleProgressiveFrame);

    samples[0].SrcSurface = pSrc;
    samples[0].SrcRect = SrcRect;
    samples[0].DstRect = DstRect;

    samples[0].PlanarAlpha = DXVA2_Fixed32OpaqueAlpha();

    HRESULT hr = m_pVPDevice->VideoProcessBlt(pDst, &blt, samples, 1, NULL);

    return hr;
}
Beispiel #4
0
static void FillSample( DXVA2_VideoSample *p_sample,
                        const struct deinterlace_ctx *p_context,
                        picture_t *p_pic,
                        const video_format_t *p_fmt,
                        const RECT *p_area,
                        int i_field )
{
    picture_sys_t *p_sys_src = ActivePictureSys(p_pic);

    p_sample->SrcSurface = p_sys_src->surface;
    p_sample->SampleFormat.SampleFormat = p_pic->b_top_field_first ?
                DXVA2_SampleFieldInterleavedEvenFirst :
                DXVA2_SampleFieldInterleavedOddFirst;
    p_sample->Start = 0;
    p_sample->End = GetFieldDuration(p_context, p_fmt, p_pic) * 10;
    p_sample->SampleData = DXVA2_SampleData_RFF_TFF_Present;
    if (!i_field)
        p_sample->SampleData |= DXVA2_SampleData_TFF;
    else
        p_sample->SampleData |= DXVA2_SampleData_RFF;
    p_sample->DstRect = p_sample->SrcRect = *p_area;
    p_sample->PlanarAlpha    = DXVA2_Fixed32OpaqueAlpha();
}
CDeinterlacer::FrameStatus CDeinterlacer_DXVA::GetFrame(
	CFrameBuffer *pDstBuffer, const CFrameBuffer *pSrcBuffer,
	bool fTopField, int Field)
{
	const int Width = pDstBuffer->m_Width, Height = pDstBuffer->m_Height;

	if (!m_pVideoProcessor || m_Width != Width || m_Height != Height) {
		if (m_fOpenFailed)
			return FRAME_SKIP;
		if (!Open(Width, Height))
			return FRAME_SKIP;
	}

	const size_t TotalSamples = m_BackwardRefSamples + m_ForwardRefSamples + 1;

	if (m_RefSamples.size() == TotalSamples)
		m_RefSamples.pop_front();

	IDirect3DSurface9 *pSurface = GetFreeSurface();
	if (!pSurface) {
		TRACE(TEXT("Unable to find unused surface\n"));
		return FRAME_SKIP;
	}

	HRESULT hr;

	D3DSURFACE_DESC desc;

	hr = pSurface->GetDesc(&desc);
	if (FAILED(hr)) {
		TRACE(TEXT("Failed to get surface desc (%x)\n"), hr);
		return FRAME_SKIP;
	}

	D3DLOCKED_RECT rect;

	hr = pSurface->LockRect(&rect, nullptr, D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK);
	if (FAILED(hr)) {
		TRACE(TEXT("Failed to lock surface (%x)\n"), hr);
		return FRAME_SKIP;
	}

	PixelCopyI420ToNV12(
		Width, Height,
		(uint8_t*)rect.pBits, (uint8_t*)rect.pBits + desc.Height * rect.Pitch, rect.Pitch,
		pSrcBuffer->m_Buffer[0], pSrcBuffer->m_Buffer[1], pSrcBuffer->m_Buffer[2],
		pSrcBuffer->m_PitchY, pSrcBuffer->m_PitchC);

	pSurface->UnlockRect();

	SampleInfo Sample;
	Sample.pSurface = pSurface;
	Sample.StartTime = pDstBuffer->m_rtStart;
	Sample.EndTime = pDstBuffer->m_rtStop;
	Sample.fTopFieldFirst = fTopField;
	m_RefSamples.push_back(Sample);

	if (m_RefSamples.size() <= m_ForwardRefSamples)
		return FRAME_SKIP;

	m_FrameNumber++;

	DXVA2_VideoSample Samples[MAX_DEINTERLACE_SURFACES];
	RECT rc = {0, 0, Width, Height};

	ZeroMemory(Samples, sizeof(Samples));

	size_t BackwardSamples = 0;
	if (m_RefSamples.size() > m_ForwardRefSamples + 1)
		BackwardSamples = m_RefSamples.size() - (m_ForwardRefSamples + 1);

	for (size_t i = 0; i < m_RefSamples.size(); i++) {
		DXVA2_VideoSample &vs = Samples[i];

		vs.Start = m_FrameNumber + i - BackwardSamples;
		vs.End = vs.Start + 1;
		vs.SampleFormat = m_VideoDesc.SampleFormat;
		vs.SampleFormat.SampleFormat =
			m_RefSamples[i].fTopFieldFirst ?
				DXVA2_SampleFieldInterleavedEvenFirst :
				DXVA2_SampleFieldInterleavedOddFirst;
		vs.SrcSurface = m_RefSamples[i].pSurface;
		vs.SrcRect = rc;
		vs.DstRect = rc;
		vs.PlanarAlpha = DXVA2_Fixed32OpaqueAlpha();
	}

	DXVA2_VideoProcessBltParams blt = {};

	blt.TargetFrame = m_FrameNumber;
	blt.TargetRect = rc;
	blt.BackgroundColor.Y     = 0x1000;
	blt.BackgroundColor.Cb    = 0x8000;
	blt.BackgroundColor.Cr    = 0x8000;
	blt.BackgroundColor.Alpha = 0xffff;
	blt.DestFormat.SampleFormat = DXVA2_SampleProgressiveFrame;
	blt.DestFormat.NominalRange = m_VideoDesc.SampleFormat.NominalRange;
	blt.DestFormat.VideoTransferFunction = DXVA2_VideoTransFunc_sRGB;
	blt.ProcAmpValues.Brightness = m_ProcAmpBrightness.DefaultValue;
	blt.ProcAmpValues.Contrast = m_ProcAmpContrast.DefaultValue;
	blt.ProcAmpValues.Hue = m_ProcAmpHue.DefaultValue;
	blt.ProcAmpValues.Saturation = m_ProcAmpSaturation.DefaultValue;
	blt.Alpha = DXVA2_Fixed32OpaqueAlpha();
	blt.NoiseFilterLuma = m_NoiseFilterLuma;
	blt.NoiseFilterChroma = m_NoiseFilterChroma;
	blt.DetailFilterLuma = m_DetailFilterLuma;
	blt.DetailFilterChroma = m_DetailFilterChroma;

	pSurface = m_Surfaces.front();

	hr = m_pVideoProcessor->VideoProcessBlt(pSurface, &blt, Samples, (UINT)m_RefSamples.size(), nullptr);
	if (FAILED(hr)) {
		TRACE(TEXT("VideoProcessBlt() failed (%x)\n"), hr);
		return FRAME_SKIP;
	}

	if (pDstBuffer->m_pSurface) {
		D3DSURFACE_DESC descSrc, descDst;
		D3DLOCKED_RECT rectSrc, rectDst;

		hr = pSurface->GetDesc(&descSrc);
		if (FAILED(hr)) {
			TRACE(TEXT("Failed to get surface desc (%x)\n"), hr);
			return FRAME_SKIP;
		}

		hr = pDstBuffer->m_pSurface->GetDesc(&descDst);
		if (FAILED(hr)) {
			TRACE(TEXT("Failed to get surface desc (%x)\n"), hr);
			return FRAME_SKIP;
		}

		hr = pSurface->LockRect(&rectSrc, nullptr, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK);
		if (FAILED(hr)) {
			TRACE(TEXT("Failed to lock surface (%x)\n"), hr);
			return FRAME_SKIP;
		}

		hr = pDstBuffer->m_pSurface->LockRect(&rectDst, nullptr, D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK);
		if (FAILED(hr)) {
			TRACE(TEXT("Failed to lock surface (%x)\n"), hr);
			pSurface->UnlockRect();
			return FRAME_SKIP;
		}

		PixelCopyNV12ToNV12(
			Width, Height,
			(uint8_t*)rectDst.pBits, (uint8_t*)rectDst.pBits + descDst.Height * rectDst.Pitch, rectDst.Pitch,
			(const uint8_t*)rectSrc.pBits, (const uint8_t*)rectSrc.pBits + descSrc.Height * rectSrc.Pitch, rectSrc.Pitch);

		pDstBuffer->m_pSurface->UnlockRect();
		pSurface->UnlockRect();
	} else {
		hr = pSurface->GetDesc(&desc);
		if (FAILED(hr)) {
			TRACE(TEXT("Failed to get surface desc (%x)\n"), hr);
			return FRAME_SKIP;
		}

		hr = pSurface->LockRect(&rect, nullptr, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK);
		if (FAILED(hr)) {
			TRACE(TEXT("Failed to lock surface (%x)\n"), hr);
			return FRAME_SKIP;
		}

#if 0
		PixelCopyNV12ToI420(
			Width, Height,
			pDstBuffer->m_Buffer[0], pDstBuffer->m_Buffer[1], pDstBuffer->m_Buffer[2],
			pDstBuffer->m_PitchY, pDstBuffer->m_PitchC,
			(const uint8_t*)rect.pBits, (const uint8_t*)rect.pBits + desc.Height * rect.Pitch, rect.Pitch);
#else
		PixelCopyNV12ToNV12(
			Width, Height,
			pDstBuffer->m_Buffer[0], pDstBuffer->m_Buffer[1], pDstBuffer->m_PitchY,
			(const uint8_t*)rect.pBits, (const uint8_t*)rect.pBits + desc.Height * rect.Pitch, rect.Pitch);
		pDstBuffer->m_Subtype = MEDIASUBTYPE_NV12;
#endif

		pSurface->UnlockRect();
	}

	const SampleInfo *pSample = &m_RefSamples[m_RefSamples.size() - 1 - m_ForwardRefSamples];
	pDstBuffer->m_rtStart = pSample->StartTime;
	pDstBuffer->m_rtStop = pSample->EndTime;

	return FRAME_OK;
}