示例#1
0
STDMETHODIMP CLAVSubtitleConsumer::ProcessFrame(LAVFrame *pFrame)
{
  CheckPointer(m_pProvider, E_FAIL);
  HRESULT hr = S_OK;
  LPDIRECT3DSURFACE9 pSurface = nullptr;

  // Wait for the requested frame
  m_evFrame.Wait();

  if (m_SubtitleFrame != nullptr) {
    int count = 0;
    if (FAILED(m_SubtitleFrame->GetBitmapCount(&count))) {
      count = 0;
    }

    if (count == 0) {
      SafeRelease(&m_SubtitleFrame);
      return S_FALSE;
    }

    BYTE *data[4] = {0};
    ptrdiff_t stride[4] = {0};
    LAVPixelFormat format = pFrame->format;
    int bpp = pFrame->bpp;

    if (pFrame->format == LAVPixFmt_DXVA2) {
      // Copy the surface, if required
      if (!(pFrame->flags & LAV_FRAME_FLAG_BUFFER_MODIFY)) {
        IMediaSample *pOrigSample = (IMediaSample *)pFrame->data[0];
        LPDIRECT3DSURFACE9 pOrigSurface = (LPDIRECT3DSURFACE9)pFrame->data[3];

        hr = m_pLAVVideo->GetD3DBuffer(pFrame);
        if (FAILED(hr)) {
          DbgLog((LOG_TRACE, 10, L"CLAVSubtitleConsumer::ProcessFrame: getting a new D3D buffer failed"));
        } else {
          IMediaSample *pNewSample = (IMediaSample *)pFrame->data[0];
          pSurface = (LPDIRECT3DSURFACE9)pFrame->data[3];
          IDirect3DDevice9 *pDevice = nullptr;
          if (SUCCEEDED(hr = pSurface->GetDevice(&pDevice))) {
            hr = pDevice->StretchRect(pOrigSurface, nullptr, pSurface, nullptr, D3DTEXF_NONE);
            if (SUCCEEDED(hr)) {
              pFrame->flags |= LAV_FRAME_FLAG_BUFFER_MODIFY|LAV_FRAME_FLAG_DXVA_NOADDREF;
              pOrigSurface = nullptr;

              // Release the surface, we only want to hold a ref on the media buffer
              pSurface->Release();
            }
            SafeRelease(&pDevice);
          }
          if (FAILED(hr)) {
            DbgLog((LOG_TRACE, 10, L"CLAVSubtitleConsumer::ProcessFrame: processing d3d buffer failed, restoring previous buffer"));
            pNewSample->Release();
            pSurface->Release();
            pFrame->data[0] = (BYTE *)pOrigSample;
            pFrame->data[3] = (BYTE *)pOrigSurface;
          }
        }
      }
      pSurface = (LPDIRECT3DSURFACE9)pFrame->data[3];

      D3DSURFACE_DESC surfaceDesc;
      pSurface->GetDesc(&surfaceDesc);

      D3DLOCKED_RECT LockedRect;
      hr = pSurface->LockRect(&LockedRect, nullptr, 0);
      if (FAILED(hr)) {
        DbgLog((LOG_TRACE, 10, L"pSurface->LockRect failed (hr: %X)", hr));
        SafeRelease(&m_SubtitleFrame);
        return E_FAIL;
      }

      data[0] = (BYTE *)LockedRect.pBits;
      data[1] = data[0] + (surfaceDesc.Height * LockedRect.Pitch);
      stride[0] = LockedRect.Pitch;
      stride[1] = LockedRect.Pitch;

      format = LAVPixFmt_NV12;
      bpp = 8;
    } else {
      if (!(pFrame->flags & LAV_FRAME_FLAG_BUFFER_MODIFY)) {
        CopyLAVFrameInPlace(pFrame);
      }
      memcpy(&data, &pFrame->data, sizeof(pFrame->data));
      memcpy(&stride, &pFrame->stride, sizeof(pFrame->stride));
    }

    RECT videoRect;
    ::SetRect(&videoRect, 0, 0, pFrame->width, pFrame->height);

    RECT subRect;
    m_SubtitleFrame->GetOutputRect(&subRect);

    ULONGLONG id;
    POINT position;
    SIZE size;
    const uint8_t *rgbData;
    int pitch;
    for (int i = 0; i < count; i++) {
      if (FAILED(m_SubtitleFrame->GetBitmap(i, &id, &position, &size, (LPCVOID *)&rgbData, &pitch))) {
        DbgLog((LOG_TRACE, 10, L"GetBitmap() failed on index %d", i));
        break;
      }
      ProcessSubtitleBitmap(format, bpp, videoRect, data, stride, subRect, position, size, rgbData, pitch);
    }

    if (pSurface)
      pSurface->UnlockRect();

    SafeRelease(&m_SubtitleFrame);
    return S_OK;
  }

  return S_FALSE;
}
示例#2
0
// draw 3D objects and so on
void RenderScene()
{
	/////////////////////////
	// 1. draw the scene into the render target
	/////////////////////////
	// current hardware backbuffer
	LPDIRECT3DSURFACE9 pHWBackBuffer = NULL;
	gpD3DDevice->GetRenderTarget(0, &pHWBackBuffer);

	// draw onto the render target
	LPDIRECT3DSURFACE9 pSceneSurface = NULL;
	if (SUCCEEDED(gpSceneRenderTarget->GetSurfaceLevel(0, &pSceneSurface)))
	{
		gpD3DDevice->SetRenderTarget(0, pSceneSurface);
		pSceneSurface->Release();
		pSceneSurface = NULL;
	}

	// clear what's drawn in the last frame
	gpD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0xFF000000, 1.0f, 0);

	// make the view matrix
	D3DXMATRIXA16 matView;
	D3DXVECTOR3 vEyePt(gWorldCameraPosition.x, gWorldCameraPosition.y, gWorldCameraPosition.z);
	D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f);
	D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f);
	D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec);

	// projection matrix
	D3DXMATRIXA16			matProjection;
	D3DXMatrixPerspectiveFovLH(&matProjection, FOV, ASPECT_RATIO, NEAR_PLANE, FAR_PLANE);

	// for each frame, we roate 0.4 degree
	gRotationY += 0.4f * PI / 180.0f;
	if (gRotationY > 2 * PI)
	{
		gRotationY -= 2 * PI;
	}

	// world matrix
	D3DXMATRIXA16			matWorld;
	D3DXMatrixRotationY(&matWorld, gRotationY);

	// concatenate world/view/projection matrices
	D3DXMATRIXA16 matWorldView;
	D3DXMATRIXA16 matWorldViewProjection;
	D3DXMatrixMultiply(&matWorldView, &matWorld, &matView);
	D3DXMatrixMultiply(&matWorldViewProjection, &matWorldView, &matProjection);

	// set shader global variables
	gpEnvironmentMappingShader->SetMatrix("gWorldMatrix", &matWorld);
	gpEnvironmentMappingShader->SetMatrix("gWorldViewProjectionMatrix", &matWorldViewProjection);

	gpEnvironmentMappingShader->SetVector("gWorldLightPosition", &gWorldLightPosition);
	gpEnvironmentMappingShader->SetVector("gWorldCameraPosition", &gWorldCameraPosition);

	gpEnvironmentMappingShader->SetVector("gLightColor", &gLightColor);
	gpEnvironmentMappingShader->SetTexture("DiffuseMap_Tex", gpStoneDM);
	gpEnvironmentMappingShader->SetTexture("SpecularMap_Tex", gpStoneSM);
	gpEnvironmentMappingShader->SetTexture("NormalMap_Tex", gpStoneNM);
	gpEnvironmentMappingShader->SetTexture("EnvironmentMap_Tex", gpSnowENV);

	// start a shader
	UINT numPasses = 0;
	gpEnvironmentMappingShader->Begin(&numPasses, NULL);
	{
		for (UINT i = 0; i < numPasses; ++i)
		{
			gpEnvironmentMappingShader->BeginPass(i);
			{
				// draw a sphere
				gpTeapot->DrawSubset(0);
			}
			gpEnvironmentMappingShader->EndPass();
		}
	}
	gpEnvironmentMappingShader->End();


	/////////////////////////
	// 2. apply post-processing
	/////////////////////////
	// use hardware backbuffer
	gpD3DDevice->SetRenderTarget(0, pHWBackBuffer);
	pHWBackBuffer->Release();
	pHWBackBuffer = NULL;

	// post process effect to use
	LPD3DXEFFECT effectToUse = gpNoEffect;
	if (gPostProcessIndex == 1)
	{
		effectToUse = gpGrayScale;
	}
	else if (gPostProcessIndex == 2)
	{
		effectToUse = gpSepia;
	}

	effectToUse->SetTexture("SceneTexture_Tex", gpSceneRenderTarget);
	effectToUse->Begin(&numPasses, NULL);
	{
		for (UINT i = 0; i < numPasses; ++i)
		{
			effectToUse->BeginPass(i);
			{
				// draw a fullscreen quad
				gpD3DDevice->SetStreamSource(0, gpFullscreenQuadVB, 0, sizeof(float)* 5);
				gpD3DDevice->SetIndices(gpFullscreenQuadIB);
				gpD3DDevice->SetVertexDeclaration(gpFullscreenQuadDecl);
				gpD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 6, 0, 2);
			}
			effectToUse->EndPass();
		}
	}
	effectToUse->End();

}
示例#3
0
HRESULT CDxtexDoc::LoadAlphaIntoSurface(CString& strPath, LPDIRECT3DSURFACE9 psurf)
{
    HRESULT hr;
    D3DSURFACE_DESC sd;
    LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
    LPDIRECT3DTEXTURE9 ptexAlpha;
    LPDIRECT3DSURFACE9 psurfAlpha;
    LPDIRECT3DSURFACE9 psurfTarget;

    psurf->GetDesc(&sd);

    // Load the alpha BMP into psurfAlpha, a new A8R8G8B8 surface
    hr = D3DXCreateTextureFromFileEx(pd3ddev, strPath, sd.Width, sd.Height, 1, 0, 
        D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT, 
        D3DX_DEFAULT, 0, NULL, NULL, &ptexAlpha);
    hr = ptexAlpha->GetSurfaceLevel(0, &psurfAlpha);

    // Copy the target surface into an A8R8G8B8 surface
    hr = pd3ddev->CreateOffscreenPlainSurface(sd.Width, sd.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &psurfTarget, NULL);
    hr = D3DXLoadSurfaceFromSurface(psurfTarget, NULL, NULL, psurf, NULL, NULL, 
        D3DX_DEFAULT, 0);

    // Fill in the alpha channels of psurfTarget based on the blue channel of psurfAlpha
    D3DLOCKED_RECT lrSrc;
    D3DLOCKED_RECT lrDest;

    hr = psurfAlpha->LockRect(&lrSrc, NULL, D3DLOCK_READONLY);
    hr = psurfTarget->LockRect(&lrDest, NULL, 0);

    DWORD xp;
    DWORD yp;
    DWORD* pdwRowSrc = (DWORD*)lrSrc.pBits;
    DWORD* pdwRowDest = (DWORD*)lrDest.pBits;
    DWORD* pdwSrc;
    DWORD* pdwDest;
    DWORD dwAlpha;
    LONG dataBytesPerRow = 4 * sd.Width;

    for (yp = 0; yp < sd.Height; yp++)
    {
        pdwSrc = pdwRowSrc;
        pdwDest = pdwRowDest;
        for (xp = 0; xp < sd.Width; xp++)
        {
            dwAlpha = *pdwSrc << 24;
            *pdwDest &= 0x00ffffff;
            *pdwDest |= dwAlpha;

            pdwSrc++;
            pdwDest++;
        }
        pdwRowSrc += lrSrc.Pitch / 4;
        pdwRowDest += lrDest.Pitch / 4;
    }

    psurfAlpha->UnlockRect();
    psurfTarget->UnlockRect();

    // Copy psurfTarget back into real surface
    hr = D3DXLoadSurfaceFromSurface(psurf, NULL, NULL, psurfTarget, NULL, NULL, 
        D3DX_DEFAULT, 0);
    
    // Release allocated interfaces
    ReleasePpo(&psurfTarget);
    ReleasePpo(&psurfAlpha);
    ReleasePpo(&ptexAlpha);

    return S_OK;
}