Ejemplo n.º 1
0
/**
  \fn brief input is already a surface, in yv12 format
*/
bool dxvaRender::displayImage_surface(ADMImage *pic,admDx2Surface *surface)
{
  // this does not work, both surfaces are coming from different device

  IDirect3DSurface9 *bBuffer;
  POINT point={0,0};
  // 1 upload to myYV12 surface
  if(ADM_FAILED(IDirect3DDevice9_UpdateSurface(d3dDevice,
          surface->surface,   // src
          &panScan,       // src rect
          myYV12Surface, // dst
          &point         // where to
        )))
        {
            ADM_warning("Copying surface failed, switching to non accelerated path \n");
            if(!pic->hwDownloadFromRef())
            {
              ADM_warning("Failed to download yv12 from dxva\n");
              return false;
            }
            // workaround : use default non bridged path
              if(useYV12)
              {
                  return displayImage_yv12(pic);
              }
              return displayImage_argb(pic);
            return false;
        }
 // upload....
  if( ADM_FAILED(IDirect3DDevice9_GetBackBuffer(d3dDevice, 0, 0,
                                            D3DBACKBUFFER_TYPE_MONO,
                                            &bBuffer)))
  {
        ADM_warning("D3D Cannot create backBuffer\n");
        return false;
  }


  // data are in YV12 surface, blit it to mySurface
  // zoom and color conversion happen there

  if (ADM_FAILED(IDirect3DDevice9_StretchRect(d3dDevice,
                  myYV12Surface,
                  NULL,
                  bBuffer,
                  NULL,
                  D3DTEXF_LINEAR)))
                  {
                         ADM_warning("StretchRec yv12 failed\n");
                  }
  IDirect3DDevice9_BeginScene(d3dDevice);
  IDirect3DDevice9_EndScene(d3dDevice);
  if( ADM_FAILED(IDirect3DDevice9_Present(d3dDevice, &targetRect, 0, 0, 0)))
  {
    ADM_warning("D3D Present failed\n");
  }

  return true;
}
static HRESULT WINAPI DirectXVideoProcessor_VideoProcessBlt(IDirectXVideoProcessor *iface, IDirect3DSurface9* pRenderTarget,
                                                            const DXVA2_VideoProcessBltParams* pBltParams,
                                                            const DXVA2_VideoSample* pSamples, UINT NumSamples,
                                                            HANDLE* complete)
{
    DirectXVideoProcessorImpl *This = impl_from_IDirectXVideoProcessor(iface);

    TRACE("(%p)->(%p, %p, %p, %u, %p)\n", This, pRenderTarget, pBltParams, pSamples, NumSamples, complete);

    if (!pRenderTarget || !pBltParams || !pSamples)
        return E_INVALIDARG;

    if (NumSamples > 1)
        FIXME("Deinterlacing not implemented, expect horrible video output!\n");

    return IDirect3DDevice9_StretchRect(This->device, pSamples[0].SrcSurface, &pSamples[0].SrcRect,
                                        pRenderTarget, &pSamples[0].DstRect, D3DTEXF_LINEAR);
}
Ejemplo n.º 3
0
HRESULT STDMETHODCALLTYPE IDirect3DDevice9_EndScene_Hook(IDirect3DDevice9* This) {
	static unsigned count = 0;
	auto ticks = []() {
		LARGE_INTEGER value;
		QueryPerformanceCounter(&value);
		return KSCONVERT_PERFORMANCE_TIME(frequency, value);
	}();
	static auto start = [This, &ticks]() {
		IDirect3DSurface9* renderTarget;
		IDirect3DDevice9_GetRenderTarget(This, 0, &renderTarget);
		IDirect3DSurface9_GetDesc(renderTarget, &desc);
		IDirect3DSurface9_Release(renderTarget);

		// quick hack, first 'ticks - start' is 1.
		return ticks++;
	}();
	fps = static_cast<unsigned>(static_cast<ULONGLONG>(++count) * NANOSECONDS / (ticks - start));

	FramePtr frame = Frame;
	if (frame) {
		IDirect3DSurface9* offsecreen;
		check(TEXT("CreateOffscreenPlainSurface"), IDirect3DDevice9_CreateOffscreenPlainSurface(This, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &offsecreen, nullptr));
		{
			IDirect3DSurface9* target;
			check(TEXT("GetRenderTarget"), IDirect3DDevice9_GetRenderTarget(This, 0, &target));
#if 0
			if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) {
				IDirect3DSurface9* resolved;
				check(TEXT("CreateRenderTarget"), IDirect3DDevice9_CreateRenderTarget(This, desc.Width, desc.Height, desc.Format, D3DMULTISAMPLE_NONE, 0, false, &resolved, nullptr));
				check(TEXT("StretchRect"), IDirect3DDevice9_StretchRect(This, target, nullptr, resolved, nullptr, D3DTEXF_NONE));
				IDirect3DSurface9_Release(target);
				target = resolved;
			}
#endif
			check(TEXT("GetRenderTargetData"), IDirect3DDevice9_GetRenderTargetData(This, target, offsecreen));
			IDirect3DSurface9_Release(target);
		}
		frame(ticks, offsecreen);
		IDirect3DSurface9_Release(offsecreen);
	}
	return IDirect3DDevice9_EndScene_Orig(This);
}
Ejemplo n.º 4
0
static int Extract(vlc_va_t *va, picture_t *picture, uint8_t *data)
{
    directx_sys_t *dx_sys = &va->sys->dx_sys;
    LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)data;
    if ( picture->format.i_chroma == VLC_CODEC_D3D9_OPAQUE ||
         picture->format.i_chroma == VLC_CODEC_D3D9_OPAQUE_10B )
    {
        picture_sys_t *p_sys = picture->p_sys;
        LPDIRECT3DSURFACE9 output = p_sys->surface;

        assert(d3d != output);
#ifndef NDEBUG
        LPDIRECT3DDEVICE9 srcDevice, dstDevice;
        IDirect3DSurface9_GetDevice(d3d, &srcDevice);
        IDirect3DSurface9_GetDevice(output, &dstDevice);
        assert(srcDevice == dstDevice);
#endif

        HRESULT hr;
        RECT visibleSource;
        visibleSource.left = 0;
        visibleSource.top = 0;
        visibleSource.right = picture->format.i_visible_width;
        visibleSource.bottom = picture->format.i_visible_height;
        hr = IDirect3DDevice9_StretchRect( (IDirect3DDevice9*) dx_sys->d3ddev, d3d, &visibleSource, output, &visibleSource, D3DTEXF_NONE);
        if (FAILED(hr)) {
            msg_Err(va, "Failed to copy the hw surface to the decoder surface (hr=0x%0lx)", hr );
            return VLC_EGENERIC;
        }
    }
    else if (va->sys->filter != NULL) {
        va->sys->filter->owner.sys = picture;
        vlc_va_surface_t *surface = picture->context;
        picture_Hold( surface->p_pic );
        va->sys->filter->pf_video_filter( va->sys->filter, surface->p_pic );
    } else {
        msg_Err(va, "Unsupported output picture format %08X", picture->format.i_chroma );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}
Ejemplo n.º 5
0
/**
  \fn displayImage_yv12
  \brief copy image to myV12 surface then convert from yv12 to display format in mySurface

*/
bool dxvaRender::displayImage_yv12(ADMImage *pic)
{
    IDirect3DSurface9 *bBuffer;
    // 1 upload to myYV12 surface
    if(!ADMImage_To_yv12Surface(pic,myYV12Surface))
    {
      return false;
    }
   // upload....
    if( ADM_FAILED(IDirect3DDevice9_GetBackBuffer(d3dDevice, 0, 0,
                                              D3DBACKBUFFER_TYPE_MONO,
                                              &bBuffer)))
    {
          ADM_warning("D3D Cannot create backBuffer\n");
          return false;
    }


    // data are in YV12 surface, blit it to mySurface
    // zoom and color conversion happen there

    if (ADM_FAILED(IDirect3DDevice9_StretchRect(d3dDevice,
                    myYV12Surface,
                    NULL,
                    bBuffer,
                    NULL,
                    D3DTEXF_LINEAR)))
                    {
                           ADM_warning("StretchRec yv12 failed\n");
                    }
    IDirect3DDevice9_BeginScene(d3dDevice);
    IDirect3DDevice9_EndScene(d3dDevice);
    if( ADM_FAILED(IDirect3DDevice9_Present(d3dDevice, &targetRect, 0, 0, 0)))
    {
      ADM_warning("D3D Present failed\n");
    }

    return true;
}
Ejemplo n.º 6
0
Archivo: direct3d.c Proyecto: BtbN/vlc
/**
 * It copies picture surface into a texture and setup the associated d3d_region_t.
 */
static int Direct3DImportPicture(vout_display_t *vd,
                                 d3d_region_t *region,
                                 LPDIRECT3DSURFACE9 source)
{
    vout_display_sys_t *sys = vd->sys;
    HRESULT hr;

    if (!source) {
        msg_Dbg(vd, "no surface to render ?");
        return VLC_EGENERIC;
    }

    /* retrieve texture top-level surface */
    LPDIRECT3DSURFACE9 destination;
    hr = IDirect3DTexture9_GetSurfaceLevel(sys->d3dtex, 0, &destination);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return VLC_EGENERIC;
    }

    /* Copy picture surface into texture surface
     * color space conversion happen here */
    hr = IDirect3DDevice9_StretchRect(sys->d3ddev, source, NULL, destination, NULL, D3DTEXF_LINEAR);
    IDirect3DSurface9_Release(destination);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return VLC_EGENERIC;
    }

    /* */
    region->texture = sys->d3dtex;
    Direct3DSetupVertices(region->vertex,
                          vd->sys->rect_src,
                          vd->sys->rect_src_clipped,
                          vd->sys->rect_dest_clipped, 255);
    return VLC_SUCCESS;
}
Ejemplo n.º 7
0
/** @brief Render a frame on the screen.
 *  @param mpi mpi structure with the decoded frame inside
 *  @return VO_TRUE on success, VO_ERROR on failure
 */
static uint32_t render_d3d_frame(mp_image_t *mpi)
{
    /* Uncomment when direct rendering is implemented.
     * if (mpi->flags & MP_IMGFLAG_DIRECT) ...
     */

    /* If the D3D device is uncooperative (not initialized), return success.
       The device will be probed for reinitialization in the next flip_page() */
    if (!priv->d3d_device)
        return VO_TRUE;

    if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
        goto skip_upload;

    if (mpi->flags & MP_IMGFLAG_PLANAR) { /* Copy a planar frame. */
        draw_slice(mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0);
        goto skip_upload;
    }

    /* If we're here, then we should lock the rect and copy a packed frame */
    if (!priv->locked_rect.pBits) {
        if (FAILED(IDirect3DSurface9_LockRect(priv->d3d_surface,
                                              &priv->locked_rect, NULL, 0))) {
            mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>Surface lock failed.\n");
            return VO_ERROR;
        }
    }

    memcpy_pic(priv->locked_rect.pBits, mpi->planes[0], mpi->stride[0],
               mpi->height, priv->locked_rect.Pitch, mpi->stride[0]);

skip_upload:
    /* This unlock is used for both slice_draw path and render_d3d_frame path. */
    if (FAILED(IDirect3DSurface9_UnlockRect(priv->d3d_surface))) {
        mp_msg(MSGT_VO, MSGL_V, "<vo_direct3d>Surface unlock failed.\n");
        return VO_ERROR;
    }
    priv->locked_rect.pBits = NULL;

    if (FAILED(IDirect3DDevice9_BeginScene(priv->d3d_device))) {
        mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>BeginScene failed.\n");
        return VO_ERROR;
    }

    if (priv->is_clear_needed) {
        IDirect3DDevice9_Clear(priv->d3d_device, 0, NULL,
                               D3DCLEAR_TARGET, 0, 0, 0);
        priv->is_clear_needed = 0;
    }

    if (FAILED(IDirect3DDevice9_StretchRect(priv->d3d_device,
                                            priv->d3d_surface,
                                            &priv->fs_panscan_rect,
                                            priv->d3d_backbuf,
                                            &priv->fs_movie_rect,
                                            D3DTEXF_LINEAR))) {
        mp_msg(MSGT_VO, MSGL_ERR,
               "<vo_direct3d>Copying frame to the backbuffer failed.\n");
        return VO_ERROR;
    }

    if (FAILED(IDirect3DDevice9_EndScene(priv->d3d_device))) {
        mp_msg(MSGT_VO, MSGL_ERR, "<vo_direct3d>EndScene failed.\n");
        return VO_ERROR;
    }

    return VO_TRUE;
}
Ejemplo n.º 8
0
/**
 * It copies picture surface into a texture and renders into a scene.
 *
 * This function is intented for higher end 3D cards, with pixel shader support
 * and at least 64 MiB of video RAM.
 */
static void Direct3DRenderScene(vout_display_t *vd, LPDIRECT3DSURFACE9 surface)
{
    vout_display_sys_t *sys = vd->sys;
    LPDIRECT3DDEVICE9 d3ddev = sys->d3ddev;
    HRESULT hr;

    // check if device is still available
    hr = IDirect3DDevice9_TestCooperativeLevel(d3ddev);
    if (FAILED(hr)) {
        if (hr == D3DERR_DEVICENOTRESET && !sys->reset_device) {
            vout_display_SendEventPicturesInvalid(vd);
            sys->reset_device = true;
        }
        return;
    }
    /* */
    LPDIRECT3DTEXTURE9      d3dtex  = sys->d3dtex;
    LPDIRECT3DVERTEXBUFFER9 d3dvtc  = sys->d3dvtc;

    /* Clear the backbuffer and the zbuffer */
    hr = IDirect3DDevice9_Clear(d3ddev, 0, NULL, D3DCLEAR_TARGET,
                              D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return;
    }
    /*  retrieve picture surface */
    LPDIRECT3DSURFACE9 d3dsrc = surface;
    if (!d3dsrc) {
        msg_Dbg(vd, "no surface to render ?");
        return;
    }

    /* retrieve texture top-level surface */
    LPDIRECT3DSURFACE9 d3ddest;
    hr = IDirect3DTexture9_GetSurfaceLevel(d3dtex, 0, &d3ddest);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return;
    }

    /* Copy picture surface into texture surface
     * color space conversion and scaling happen here */
    RECT src = vd->sys->rect_src_clipped;
    RECT dst = vd->sys->rect_dest_clipped;

    hr = IDirect3DDevice9_StretchRect(d3ddev, d3dsrc, &src, d3ddest, &dst, D3DTEXF_LINEAR);
    IDirect3DSurface9_Release(d3ddest);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return;
    }

    /* Update the vertex buffer */
    CUSTOMVERTEX *vertices;
    hr = IDirect3DVertexBuffer9_Lock(d3dvtc, 0, 0, (void **)&vertices, D3DLOCK_DISCARD);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return;
    }

    /* Setup vertices */
    const float f_width  = vd->sys->d3dpp.BackBufferWidth;
    const float f_height = vd->sys->d3dpp.BackBufferHeight;

    /* -0.5f is a "feature" of DirectX and it seems to apply to Direct3d also */
    /* http://www.sjbrown.co.uk/2003/05/01/fix-directx-rasterisation/ */
    vertices[0].x       = -0.5f;       // left
    vertices[0].y       = -0.5f;       // top
    vertices[0].z       = 0.0f;
    vertices[0].diffuse = D3DCOLOR_ARGB(255, 255, 255, 255);
    vertices[0].rhw     = 1.0f;
    vertices[0].tu      = 0.0f;
    vertices[0].tv      = 0.0f;

    vertices[1].x       = f_width - 0.5f;    // right
    vertices[1].y       = -0.5f;       // top
    vertices[1].z       = 0.0f;
    vertices[1].diffuse = D3DCOLOR_ARGB(255, 255, 255, 255);
    vertices[1].rhw     = 1.0f;
    vertices[1].tu      = 1.0f;
    vertices[1].tv      = 0.0f;

    vertices[2].x       = f_width - 0.5f;    // right
    vertices[2].y       = f_height - 0.5f;   // bottom
    vertices[2].z       = 0.0f;
    vertices[2].diffuse = D3DCOLOR_ARGB(255, 255, 255, 255);
    vertices[2].rhw     = 1.0f;
    vertices[2].tu      = 1.0f;
    vertices[2].tv      = 1.0f;

    vertices[3].x       = -0.5f;       // left
    vertices[3].y       = f_height - 0.5f;   // bottom
    vertices[3].z       = 0.0f;
    vertices[3].diffuse = D3DCOLOR_ARGB(255, 255, 255, 255);
    vertices[3].rhw     = 1.0f;
    vertices[3].tu      = 0.0f;
    vertices[3].tv      = 1.0f;

    hr= IDirect3DVertexBuffer9_Unlock(d3dvtc);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return;
    }

    // Begin the scene
    hr = IDirect3DDevice9_BeginScene(d3ddev);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return;
    }

    // Setup our texture. Using textures introduces the texture stage states,
    // which govern how textures get blended together (in the case of multiple
    // textures) and lighting information. In this case, we are modulating
    // (blending) our texture with the diffuse color of the vertices.
    hr = IDirect3DDevice9_SetTexture(d3ddev, 0, (LPDIRECT3DBASETEXTURE9)d3dtex);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        IDirect3DDevice9_EndScene(d3ddev);
        return;
    }

    // Render the vertex buffer contents
    hr = IDirect3DDevice9_SetStreamSource(d3ddev, 0, d3dvtc, 0, sizeof(CUSTOMVERTEX));
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        IDirect3DDevice9_EndScene(d3ddev);
        return;
    }

    // we use FVF instead of vertex shader
    hr = IDirect3DDevice9_SetFVF(d3ddev, D3DFVF_CUSTOMVERTEX);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        IDirect3DDevice9_EndScene(d3ddev);
        return;
    }

    // draw rectangle
    hr = IDirect3DDevice9_DrawPrimitive(d3ddev, D3DPT_TRIANGLEFAN, 0, 2);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        IDirect3DDevice9_EndScene(d3ddev);
        return;
    }

    // End the scene
    hr = IDirect3DDevice9_EndScene(d3ddev);
    if (FAILED(hr)) {
        msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
        return;
    }
}
Ejemplo n.º 9
0
int video_canvas_refresh_dx9(video_canvas_t *canvas, unsigned int xs, unsigned int ys, unsigned int xi, unsigned int yi, unsigned int w, unsigned int h)
{
    HRESULT stretchresult;
    LPDIRECT3DSURFACE9 d3dbackbuffer = NULL;
    D3DLOCKED_RECT lockedrect;

    if (canvas->videoconfig->doublesizex) {
        xi *= (canvas->videoconfig->doublesizex + 1);
        w *= (canvas->videoconfig->doublesizex + 1);
    }

    if (canvas->videoconfig->doublesizey) {
        yi *= (canvas->videoconfig->doublesizey + 1);
        h *= (canvas->videoconfig->doublesizey + 1);
    }

    if (S_OK != video_canvas_prepare_for_update(canvas)) {
        return -1;
    }

    if (S_OK != IDirect3DDevice9_Clear(canvas->d3ddev, 0, NULL, D3DCLEAR_TARGET, 0, 0, 0) ||
            S_OK != IDirect3DDevice9_BeginScene(canvas->d3ddev) ||
            S_OK != IDirect3DDevice9_GetBackBuffer(canvas->d3ddev, 0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dbackbuffer) ||
            S_OK != IDirect3DSurface9_LockRect(canvas->d3dsurface, &lockedrect, NULL, 0)) {
        log_debug("video_dx9: Failed to prepare for rendering!");
        return -1;
    }

    video_canvas_render(canvas, lockedrect.pBits, w, h, xs, ys, xi, yi, lockedrect.Pitch, 32);
    //video_save_screen ("c:\\temp\\screens\\", w, h, 32, lockedrect.pBits);

    if (S_OK != IDirect3DSurface9_UnlockRect(canvas->d3dsurface)) {
        log_debug("video_dx9: Failed to unlock surface!");
        return -1;
    }

    do {
        stretchresult = IDirect3DDevice9_StretchRect(canvas->d3ddev, canvas->d3dsurface, NULL, d3dbackbuffer, canvas->dest_rect_ptr, d3dpreffilter);

        if (d3dpreffilter == D3DTEXF_NONE) {
            break;
        }

        if (stretchresult != S_OK) {
            /* Some adapters don't support filtering */
            d3dpreffilter = D3DTEXF_NONE;
            log_debug("video_dx9: Disabled StretchRect filtering!");
        }

    } while (stretchresult != S_OK);
    if (stretchresult != S_OK) {
        log_debug("video_dx9: StretchRect failed even without filtering!");
    }

    if (S_OK != IDirect3DSurface9_Release(d3dbackbuffer)
            || S_OK != IDirect3DDevice9_EndScene(canvas->d3ddev))
    {
        log_debug("video_dx9: EndScene failed!");
        return -1;
    }

    if (S_OK != IDirect3DDevice9_Present(canvas->d3ddev, NULL, NULL, NULL, NULL)) {
        log_debug("video_dx9: Refresh failed to present the scene!");
        return -1;
    }
    return 0;
}
Ejemplo n.º 10
0
ILAPI ILboolean ILAPIENTRY ilutD3D9LoadSurface(IDirect3DDevice9 *Device, IDirect3DSurface9 *Surface)
{
	HRESULT				hr;
	D3DSURFACE_DESC		d3dsd;
	LPDIRECT3DSURFACE9	SurfaceCopy;
	D3DLOCKED_RECT		d3dLR;
	ILboolean			bHasAlpha;
	ILubyte				*Image, *ImageAux, *Data;
	ILuint				y, x;
	ILushort			dwColor;

	IDirect3DSurface9_GetDesc(Surface, &d3dsd);

	bHasAlpha = (d3dsd.Format == D3DFMT_A8R8G8B8 || d3dsd.Format == D3DFMT_A1R5G5B5);

	if (bHasAlpha) {
		if (!ilTexImage(d3dsd.Width, d3dsd.Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL)) {
			return IL_FALSE;
		}
	}
	else {
		if (!ilTexImage(d3dsd.Width, d3dsd.Height, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL)) {
			return IL_FALSE;
		}
	}

	hr = IDirect3DDevice9_CreateOffscreenPlainSurface(Device, d3dsd.Width, d3dsd.Height, d3dsd.Format, D3DPOOL_SCRATCH, &SurfaceCopy, NULL);
	if (FAILED(hr)) {
		ilSetError(ILUT_ILLEGAL_OPERATION);
		return IL_FALSE;
	}

	hr = IDirect3DDevice9_StretchRect(Device, Surface, NULL, SurfaceCopy, NULL, D3DTEXF_NONE);
	if (FAILED(hr)) {
		ilSetError(ILUT_ILLEGAL_OPERATION);
		return IL_FALSE;
	}

	hr = IDirect3DSurface9_LockRect(SurfaceCopy, &d3dLR, NULL, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY);
	if (FAILED(hr)) {
		IDirect3DSurface9_Release(SurfaceCopy);
		ilSetError(ILUT_ILLEGAL_OPERATION);
		return IL_FALSE;
	}

	Image = (ILubyte*)d3dLR.pBits;
	Data = ilutCurImage->Data;

	for (y = 0; y < d3dsd.Height; y++) {
		if (d3dsd.Format == D3DFMT_X8R8G8B8) {
			ImageAux = Image;
			for (x = 0; x < d3dsd.Width; x++) {
				Data[0] = ImageAux[0];
				Data[1] = ImageAux[1];
				Data[2] = ImageAux[2];

				Data += 3;
				ImageAux += 4;
			}
		}
		else if (d3dsd.Format == D3DFMT_A8R8G8B8) {
			memcpy(Data, Image, d3dsd.Width * 4);
		}
		else if (d3dsd.Format == D3DFMT_R5G6B5) {
			ImageAux = Image;
			for (x = 0; x < d3dsd.Width; x++) {
				dwColor = *((ILushort*)ImageAux);

				Data[0] = (ILubyte)((dwColor&0x001f)<<3);
				Data[1] = (ILubyte)(((dwColor&0x7e0)>>5)<<2);
				Data[2] = (ILubyte)(((dwColor&0xf800)>>11)<<3);

				Data += 3;
				ImageAux += 2;
			}
		}
		else if (d3dsd.Format == D3DFMT_X1R5G5B5) {
Ejemplo n.º 11
0
static int RenderPic( filter_t *filter, picture_t *p_outpic, picture_t *src,
                      int order, int i_field )
{
    filter_sys_t *sys = filter->p_sys;
    const int i_samples = sys->decoder_caps.NumBackwardRefSamples + 1 +
                          sys->decoder_caps.NumForwardRefSamples;
    HRESULT hr;
    DXVA2_VideoProcessBltParams params;
    DXVA2_VideoSample samples[i_samples];
    picture_t         *pictures[i_samples];
    D3DSURFACE_DESC srcDesc, dstDesc;
    RECT area;

    picture_t *p_prev = sys->context.pp_history[0];
    picture_t *p_cur  = sys->context.pp_history[1];
    picture_t *p_next = sys->context.pp_history[2];

    picture_sys_t *p_sys_src = ActivePictureSys(src);

    hr = IDirect3DSurface9_GetDesc( p_sys_src->surface, &srcDesc );
    if (unlikely(FAILED(hr)))
        return VLC_EGENERIC;
    hr = IDirect3DSurface9_GetDesc( sys->hw_surface, &dstDesc );
    if (unlikely(FAILED(hr)))
        return VLC_EGENERIC;

    area.top = area.left = 0;
    area.bottom = __MIN(srcDesc.Height, dstDesc.Height);
    area.right  = __MIN(srcDesc.Width,  dstDesc.Width);

    int idx = i_samples - 1;
    if (p_next)
    {
        pictures[idx--] = p_next;
        if (p_cur)
            pictures[idx--] = p_cur;
        if (p_prev)
            pictures[idx--] = p_prev;
    }
    else
        pictures[idx--] = src;
    while (idx >= 0)
        pictures[idx--] = NULL;

    for (idx = 0; idx <= i_samples-1; idx++)
    {
        if (pictures[idx])
            FillSample( &samples[idx], &sys->context, pictures[idx], &filter->fmt_out.video, &area, i_field);
        else
        {
            FillSample( &samples[idx], &sys->context, src, &filter->fmt_out.video, &area, i_field);
            samples[idx].SampleFormat.SampleFormat = DXVA2_SampleUnknown;
        }
    }

    FillBlitParams( &params, &area, samples, order );

    hr = IDirectXVideoProcessor_VideoProcessBlt( sys->processor,
                                                 sys->hw_surface,
                                                 &params,
                                                 samples,
                                                 i_samples, NULL );
    if (FAILED(hr))
        return VLC_EGENERIC;

    hr = IDirect3DDevice9_StretchRect( sys->d3ddev,
                                       sys->hw_surface, NULL,
                                       p_outpic->p_sys->surface, NULL,
                                       D3DTEXF_NONE);
    if (FAILED(hr))
        return VLC_EGENERIC;

    return VLC_SUCCESS;
}