[vlc-devel] [PATCH 9/9] direct3D: implement support of NVIDIA 3D Vision
Jean-Baptiste Kempf
jb at videolan.org
Fri Aug 8 20:47:59 CEST 2014
Hmmm:
- same remark as above for licenses.
- some removal/adding of empty lines are useless.
- I'm not too much fan of the common.h/direct3d.c modifications, since they
are a bit too nVidia specific, when they could be abstracted
(pf_stereo_unload, pf_stereo_create, etc...)
The rest is good, as usual...
On 08 Aug, Felix Abecassis wrote :
> ---
> modules/video_output/Modules.am | 3 +-
> modules/video_output/msw/common.h | 27 +++
> modules/video_output/msw/direct3d.c | 70 +++++--
> modules/video_output/msw/nvapi.h | 65 +++++++
> modules/video_output/msw/nvidia_3dvision.c | 295 +++++++++++++++++++++++++++++
> modules/video_output/msw/nvidia_3dvision.h | 46 +++++
> 6 files changed, 486 insertions(+), 20 deletions(-)
> create mode 100644 modules/video_output/msw/nvapi.h
> create mode 100644 modules/video_output/msw/nvidia_3dvision.c
> create mode 100644 modules/video_output/msw/nvidia_3dvision.h
>
> diff --git a/modules/video_output/Modules.am b/modules/video_output/Modules.am
> index df8fbf6..d0dc784 100644
> --- a/modules/video_output/Modules.am
> +++ b/modules/video_output/Modules.am
> @@ -141,7 +141,8 @@ EXTRA_LTLIBRARIES += libdirect2d_plugin.la
>
> libdirect3d_plugin_la_SOURCES = msw/direct3d.c \
> msw/common.c msw/common.h msw/events.c msw/events.h msw/builtin_shaders.h \
> - msw/win32touch.c msw/win32touch.h
> + msw/win32touch.c msw/win32touch.h \
> + msw/nvidia_3dvision.c msw/nvidia_3dvision.h msw/nvapi.h
> libdirect3d_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) \
> -DMODULE_NAME_IS_direct3d
> libdirect3d_plugin_la_LIBADD = -lgdi32 -lole32 -luuid
> diff --git a/modules/video_output/msw/common.h b/modules/video_output/msw/common.h
> index 5ddf85e..e727860 100644
> --- a/modules/video_output/msw/common.h
> +++ b/modules/video_output/msw/common.h
> @@ -28,6 +28,7 @@
> #ifdef MODULE_NAME_IS_direct3d
> # include <d3d9.h>
> # include <d3dx9effect.h>
> +# include "nvapi.h"
> #endif
> #ifdef MODULE_NAME_IS_glwin32
> # include "../opengl.h"
> @@ -41,6 +42,26 @@
> *****************************************************************************/
> #include "events.h"
>
> +#ifdef MODULE_NAME_IS_direct3d
> +typedef struct
> +{
> + FLOAT x,y,z; // vertex untransformed position
> + FLOAT rhw; // eye distance
> + D3DCOLOR diffuse; // diffuse color
> + FLOAT tu, tv; // texture relative coordinates
> +} CUSTOMVERTEX;
> +#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
> +
> +typedef struct d3d_region_t {
> + D3DFORMAT format;
> + unsigned width;
> + unsigned height;
> + CUSTOMVERTEX vertex[4];
> + LPDIRECT3DTEXTURE9 texture;
> +} d3d_region_t;
> +#endif
> +
> +
> /*****************************************************************************
> * vout_sys_t: video output method descriptor
> *****************************************************************************
> @@ -155,6 +176,12 @@ struct vout_display_sys_t
> LPDIRECT3DDEVICE9 d3ddev;
> D3DPRESENT_PARAMETERS d3dpp;
>
> + // NVIDIA 3D Vision objects
> + bool nvidia_3dvision_enabled;
> + NvAPIHandle *nvapi_handle;
> + StereoHandle nvidia_3dvision_handle;
> + LPDIRECT3DSURFACE9 nvidia_3dvision_surface;
> +
> // scene objects
> LPDIRECT3DTEXTURE9 d3dtex;
> LPDIRECT3DVERTEXBUFFER9 d3dvtc;
> diff --git a/modules/video_output/msw/direct3d.c b/modules/video_output/msw/direct3d.c
> index fc959fc..26b8bbd 100644
> --- a/modules/video_output/msw/direct3d.c
> +++ b/modules/video_output/msw/direct3d.c
> @@ -49,6 +49,7 @@
>
> #include "common.h"
> #include "builtin_shaders.h"
> +#include "nvidia_3dvision.h"
>
> /*****************************************************************************
> * Module descriptor
> @@ -125,22 +126,6 @@ static int Direct3DOpen (vout_display_t *, video_format_t *);
> static void Direct3DClose(vout_display_t *);
>
> /* */
> -typedef struct
> -{
> - FLOAT x,y,z; // vertex untransformed position
> - FLOAT rhw; // eye distance
> - D3DCOLOR diffuse; // diffuse color
> - FLOAT tu, tv; // texture relative coordinates
> -} CUSTOMVERTEX;
> -#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
> -
> -typedef struct d3d_region_t {
> - D3DFORMAT format;
> - unsigned width;
> - unsigned height;
> - CUSTOMVERTEX vertex[4];
> - LPDIRECT3DTEXTURE9 texture;
> -} d3d_region_t;
>
> static void Direct3DDeleteRegions(int, d3d_region_t *);
>
> @@ -241,6 +226,15 @@ static int Open(vlc_object_t *object)
> if (sys->use_desktop && vd->cfg->is_fullscreen)
> vout_display_SendEventFullscreen(vd, false);
>
> + if (sys->nvidia_3dvision_enabled) {
> + if (vd->fmt.stereo_format.mode
> + && vd->fmt.stereo_format.mode != VLC_STEREO3D_SBS
> + && vd->fmt.stereo_format.mode != VLC_STEREO3D_TB) {
> + /* Unsupported stereo mode: request a conversion to SBS */
> + vd->fmt.stereo_format.mode = VLC_STEREO3D_SBS;
> + }
> + }
> +
> return VLC_SUCCESS;
> error:
> Direct3DClose(vd);
> @@ -589,6 +583,8 @@ static void Direct3DDestroy(vout_display_t *vd)
> FreeLibrary(sys->hd3d9_dll);
> if (sys->hd3d9x_dll)
> FreeLibrary(sys->hd3d9x_dll);
> + if (sys->nvidia_3dvision_enabled)
> + Nvidia3DVisionUnload(vd);
>
> sys->d3dobj = NULL;
> sys->hd3d9_dll = NULL;
> @@ -700,6 +696,10 @@ static int Direct3DOpen(vout_display_t *vd, video_format_t *fmt)
>
> UpdateRects(vd, NULL, NULL, true);
>
> + Nvidia3DVisionLoad(vd);
> + if (sys->nvidia_3dvision_enabled)
> + Nvidia3DVisionCreateHandle(vd);
> +
> if (Direct3DCreateResources(vd, fmt)) {
> msg_Err(vd, "Failed to allocate resources");
> return VLC_EGENERIC;
> @@ -721,6 +721,9 @@ static void Direct3DClose(vout_display_t *vd)
>
> Direct3DDestroyResources(vd);
>
> + if (sys->nvidia_3dvision_enabled)
> + Nvidia3DVisionDestroyHandle(vd);
> +
> if (sys->d3ddev)
> IDirect3DDevice9_Release(sys->d3ddev);
>
> @@ -741,6 +744,9 @@ static int Direct3DReset(vout_display_t *vd)
> /* release all D3D objects */
> Direct3DDestroyResources(vd);
>
> + if (sys->nvidia_3dvision_enabled)
> + Nvidia3DVisionDestroyHandle(vd);
> +
> /* */
> HRESULT hr = IDirect3DDevice9_Reset(d3ddev, &sys->d3dpp);
> if (FAILED(hr)) {
> @@ -748,6 +754,9 @@ static int Direct3DReset(vout_display_t *vd)
> return VLC_EGENERIC;
> }
>
> + if (sys->nvidia_3dvision_enabled)
> + Nvidia3DVisionCreateHandle(vd);
> +
> UpdateRects(vd, NULL, NULL, true);
>
> /* re-create them */
> @@ -775,6 +784,7 @@ static int Direct3DCreateResources(vout_display_t *vd, video_format_t *fmt)
> {
> vout_display_sys_t *sys = vd->sys;
>
> +
> if (Direct3DCreatePool(vd, fmt)) {
> msg_Err(vd, "Direct3D picture pool initialization failed");
> return VLC_EGENERIC;
> @@ -1048,6 +1058,13 @@ static int Direct3DCreateScene(vout_display_t *vd, const video_format_t *fmt)
> LPDIRECT3DDEVICE9 d3ddev = sys->d3ddev;
> HRESULT hr;
>
> + if (sys->nvidia_3dvision_enabled) {
> + if (Nvidia3DVisionCreateScene(vd, fmt)) {
> + msg_Err(vd, "Failed to create NVIDIA 3D Vision scene.");
> + return VLC_EGENERIC;
> + }
> + }
> +
> /*
> * Create a texture for use when rendering a scene
> * for performance reason, texture format is identical to backbuffer
> @@ -1088,7 +1105,6 @@ static int Direct3DCreateScene(vout_display_t *vd, const video_format_t *fmt)
> /* */
> sys->d3dtex = d3dtex;
> sys->d3dvtc = d3dvtc;
> -
> sys->d3dregion_count = 0;
> sys->d3dregion = NULL;
>
> @@ -1166,6 +1182,9 @@ static void Direct3DDestroyScene(vout_display_t *vd)
>
> Direct3DDeleteRegions(sys->d3dregion_count, sys->d3dregion);
>
> + if (sys->nvidia_3dvision_enabled)
> + Nvidia3DVisionDestroyScene(vd);
> +
> LPDIRECT3DVERTEXBUFFER9 d3dvtc = sys->d3dvtc;
> if (d3dvtc)
> IDirect3DVertexBuffer9_Release(d3dvtc);
> @@ -1463,13 +1482,20 @@ static int Direct3DImportPicture(vout_display_t *vd,
> /* Copy picture surface into texture surface
> * color space conversion happen here */
> hr = IDirect3DDevice9_StretchRect(sys->d3ddev, source, NULL, destination, NULL, D3DTEXF_LINEAR);
> + // 3D: check!
> IDirect3DSurface9_Release(destination);
> +
> if (FAILED(hr)) {
> msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
> return VLC_EGENERIC;
> }
>
> /* */
> +/* if(sys->left_tex_filled && sys->right_tex_filled &&
> + sys->nvidia_3dvision_enabled)
> + return VLC_SUCCESS;*/
> +
> + /* only needed for 3d, but if we rapidly turn off 2d we require this to exist */
> region->texture = sys->d3dtex;
> Direct3DSetupVertices(region->vertex,
> vd->sys->rect_src,
> @@ -1608,7 +1634,6 @@ static int Direct3DRenderRegion(vout_display_t *vd,
> vout_display_sys_t *sys = vd->sys;
>
> LPDIRECT3DDEVICE9 d3ddev = vd->sys->d3ddev;
> -
> LPDIRECT3DVERTEXBUFFER9 d3dvtc = sys->d3dvtc;
> LPDIRECT3DTEXTURE9 d3dtex = region->texture;
>
> @@ -1713,15 +1738,22 @@ static void Direct3DRenderScene(vout_display_t *vd,
> return;
> }
>
> - Direct3DRenderRegion(vd, picture, true);
> + if (sys->nvidia_3dvision_enabled && Nvidia3DVisionCanRender(vd))
> + Nvidia3DVisionRenderRegion(vd, picture);
> + else
> + Direct3DRenderRegion(vd, picture, true);
>
> if (subpicture_count > 0)
> IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_ALPHABLENDENABLE, TRUE);
> +
> + sys->nvidia_3dvision_enabled = false;
> for (int i = 0; i < subpicture_count; i++) {
> d3d_region_t *r = &subpicture[i];
> if (r->texture)
> Direct3DRenderRegion(vd, r, false);
> }
> + sys->nvidia_3dvision_enabled = true;
> +
> if (subpicture_count > 0)
> IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_ALPHABLENDENABLE, FALSE);
>
> diff --git a/modules/video_output/msw/nvapi.h b/modules/video_output/msw/nvapi.h
> new file mode 100644
> index 0000000..c32d7a8
> --- /dev/null
> +++ b/modules/video_output/msw/nvapi.h
> @@ -0,0 +1,65 @@
> +/*****************************************************************************
> + * nvapi.h: NVIDIA stereoscopic API
> + *****************************************************************************
> + * Copyright (C) 2014 the VideoLAN team
> + *
> + * Authors: Felix Abecassis <felix.abecassis at gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#ifndef NVAPI_H_
> +# define NVAPI_H_
> +
> +# define NVSTEREO_IMAGE_SIGNATURE 0x4433564e
> +# define DXNV_SWAP_EYES 0x01
> +# define DXNV_SCALE_TO_FIT 0x02
> +
> +typedef struct
> +{
> + uint32_t dwSignature;
> + uint32_t dwWidth;
> + uint32_t dwHeight;
> + uint32_t dwBPP;
> + uint32_t dwFlags;
> +} NVSTEREOIMAGEHEADER;
> +
> +typedef enum
> +{
> + NVAPI_OK = 0,
> +} NvAPI_Status;
> +
> +typedef void* StereoHandle;
> +
> +typedef struct
> +{
> + HINSTANCE instance;
> + bool initialized;
> +
> + void* (__cdecl *QueryInterface)(unsigned offset);
> + NvAPI_Status (__cdecl *Initialize)(void);
> + NvAPI_Status (__cdecl *Unload)(void);
> + NvAPI_Status (__cdecl *Stereo_IsEnabled)(uint8_t *pIsStereoEnabled);
> +
> + NvAPI_Status (__cdecl *Stereo_CreateHandleFromIUnknown)(IUnknown *pDevice,
> + StereoHandle *pStereoHandle);
> + NvAPI_Status (__cdecl *Stereo_DestroyHandle)(StereoHandle stereoHandle);
> +
> + NvAPI_Status (__cdecl *Stereo_IsActivated)(StereoHandle stereoHandle, uint8_t *pIsStereoOn);
> + NvAPI_Status (__cdecl *Stereo_Activate)(StereoHandle stereoHandle);
> + NvAPI_Status (__cdecl *Stereo_Deactivate)(StereoHandle stereoHandle);
> +} NvAPIHandle;
> +
> +#endif
> diff --git a/modules/video_output/msw/nvidia_3dvision.c b/modules/video_output/msw/nvidia_3dvision.c
> new file mode 100644
> index 0000000..b0ceffe
> --- /dev/null
> +++ b/modules/video_output/msw/nvidia_3dvision.c
> @@ -0,0 +1,295 @@
> +/*****************************************************************************
> + * nvidia_3dvision.h
> + *****************************************************************************
> + * Copyright (C) 2014 the VideoLAN team
> + *
> + * Authors: Felix Abecassis <felix.abecassis at gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#include "nvidia_3dvision.h"
> +
> +#include <vlc_charset.h> /* ToT function */
> +
> +#include "common.h"
> +#include "nvapi.h"
> +
> +int Nvidia3DVisionLoad(vout_display_t *vd)
> +{
> + vout_display_sys_t *sys = vd->sys;
> +
> + sys->nvidia_3dvision_enabled = false;
> +
> + HINSTANCE nvapi_dll = LoadLibrary(ToT("nvapi.dll"));
> + if (!nvapi_dll)
> + {
> + msg_Dbg(vd, "Could not load NvAPI library (nvapi.dll)");
> + return VLC_EGENERIC;
> + }
> +
> + sys->nvapi_handle = calloc(1, sizeof(*sys->nvapi_handle));
> + if (!sys->nvapi_handle)
> + {
> + msg_Warn(vd, "Initialization of NVIDIA stereoscopy failed: could not find NvAPI dll.");
> + return VLC_EGENERIC;
> +
> + }
> + NvAPIHandle *nvapi_handle = sys->nvapi_handle;
> + nvapi_handle->instance = nvapi_dll;
> + nvapi_handle->initialized = false;
> +
> + nvapi_handle->QueryInterface = (void *)GetProcAddress(nvapi_handle->instance, "nvapi_QueryInterface");
> +
> + /* FIXME: check if everything was fine. */
> + if (!nvapi_handle->QueryInterface)
> + {
> + msg_Err(vd, "Could not find NvAPI_QueryInterface in the NvAPI dll.");
> + goto error;
> + }
> +
> + nvapi_handle->Initialize = nvapi_handle->QueryInterface(0x0150E828);
> + nvapi_handle->Unload = nvapi_handle->QueryInterface(0xD22BDD7E);
> + nvapi_handle->Stereo_IsEnabled = nvapi_handle->QueryInterface(0x348FF8E1);
> + nvapi_handle->Stereo_CreateHandleFromIUnknown = nvapi_handle->QueryInterface(0xAC7E37F4);
> + nvapi_handle->Stereo_DestroyHandle = nvapi_handle->QueryInterface(0x3A153134);
> + nvapi_handle->Stereo_IsActivated = nvapi_handle->QueryInterface(0x1FB0BC30);
> + nvapi_handle->Stereo_Activate = nvapi_handle->QueryInterface(0xF6A1AD68);
> + nvapi_handle->Stereo_Deactivate = nvapi_handle->QueryInterface(0x2D68DE96);
> +
> + if (!nvapi_handle->Initialize || !nvapi_handle->Unload || !nvapi_handle->Stereo_IsEnabled
> + || !nvapi_handle->Stereo_CreateHandleFromIUnknown || !nvapi_handle->Stereo_DestroyHandle
> + || !nvapi_handle->Stereo_IsActivated || !nvapi_handle->Stereo_Activate
> + || !nvapi_handle->Stereo_Deactivate)
> + {
> + msg_Err(vd, "Could not load all NvAPI functions.");
> + goto error;
> + }
> +
> + NvAPI_Status status = nvapi_handle->Initialize();
> + if (status != NVAPI_OK)
> + {
> + msg_Warn(vd, "Could not initialize NvAPI (err=%d).", status);
> + goto error;
> + }
> + nvapi_handle->initialized = true;
> +
> + uint8_t stereoEnabled;
> + status = nvapi_handle->Stereo_IsEnabled(&stereoEnabled);
> + if (status != NVAPI_OK)
> + {
> + msg_Warn(vd, "Could not get NVIDIA 3D Vision status (err=%d).", status);
> + goto error;
> + }
> +
> + if (!stereoEnabled)
> + {
> + msg_Warn(vd, "NVIDIA 3D Vision should be enabled from the NVIDIA Control Panel");
> + goto error;
> + }
> +
> + sys->nvidia_3dvision_enabled = true;
> +
> + return VLC_SUCCESS;
> +
> +error:
> + Nvidia3DVisionUnload(vd);
> + return VLC_EGENERIC;
> +}
> +
> +void Nvidia3DVisionUnload(vout_display_t *vd)
> +{
> + vout_display_sys_t *sys = vd->sys;
> + NvAPIHandle *nvapi_handle = sys->nvapi_handle;
> +
> + sys->nvidia_3dvision_enabled = false;
> +
> + if (!nvapi_handle)
> + return;
> +
> + if (nvapi_handle->instance)
> + {
> + if (nvapi_handle->initialized)
> + nvapi_handle->Unload();
> + FreeLibrary(nvapi_handle->instance);
> + }
> +
> + free(nvapi_handle);
> + sys->nvapi_handle = NULL;
> + sys->nvidia_3dvision_handle = NULL;
> +}
> +
> +int Nvidia3DVisionCreateHandle(vout_display_t *vd)
> +{
> + vout_display_sys_t *sys = vd->sys;
> + NvAPIHandle *nvapi_handle = sys->nvapi_handle;
> + NvAPI_Status status;
> +
> + status = nvapi_handle->Stereo_CreateHandleFromIUnknown((IUnknown*)sys->d3ddev,
> + &sys->nvidia_3dvision_handle);
> + if (status != NVAPI_OK)
> + {
> + msg_Err(vd, "could not create NVIDIA 3D Vision handle (err=%d)", status);
> + goto error;
> + }
> +
> + status = nvapi_handle->Stereo_Activate(sys->nvidia_3dvision_handle);
> + if (status != NVAPI_OK)
> + goto error;
> +
> + return VLC_SUCCESS;
> +
> +
> +error:
> + Nvidia3DVisionUnload(vd);
> + return VLC_EGENERIC;
> +}
> +
> +void Nvidia3DVisionDestroyHandle(vout_display_t *vd)
> +{
> + vout_display_sys_t *sys = vd->sys;
> + NvAPIHandle *nvapi_handle = sys->nvapi_handle;
> +
> + nvapi_handle->Stereo_DestroyHandle(sys->nvidia_3dvision_handle);
> + sys->nvidia_3dvision_handle = NULL;
> +}
> +
> +int Nvidia3DVisionCreateScene(vout_display_t *vd,
> + const video_format_t *fmt)
> +{
> + VLC_UNUSED(fmt);
> +
> + vout_display_sys_t *sys = vd->sys;
> + LPDIRECT3DDEVICE9 d3ddev = sys->d3ddev;
> + HRESULT hr;
> +
> + LPDIRECT3DSURFACE9 nvidia_3dvision_surface;
> + hr = IDirect3DDevice9_CreateRenderTarget(d3ddev, sys->rect_display.right * 2,
> + sys->rect_display.bottom + 1,
> + D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE,
> + 0, TRUE, &nvidia_3dvision_surface, NULL);
> + if (FAILED(hr)) {
> + msg_Err(vd, "Failed to create stereo surface. (hr=0x%lx)", hr);
> + return VLC_EGENERIC;
> + }
> +
> + sys->nvidia_3dvision_surface = nvidia_3dvision_surface;
> +
> + return VLC_SUCCESS;
> +}
> +
> +void Nvidia3DVisionDestroyScene(vout_display_t *vd)
> +{
> + vout_display_sys_t *sys = vd->sys;
> +
> + if (sys->nvidia_3dvision_surface)
> + IDirect3DSurface9_Release(sys->nvidia_3dvision_surface);
> + sys->nvidia_3dvision_surface = NULL;
> +}
> +
> +bool Nvidia3DVisionCanRender(vout_display_t *vd)
> +{
> + vout_display_sys_t *sys = vd->sys;
> +
> + if (vd->fmt.stereo_format.mode != VLC_STEREO3D_2D) {
> + uint8_t stereo_enabled = 0;
> + NvAPI_Status status;
> + status = sys->nvapi_handle->Stereo_IsActivated(sys->nvidia_3dvision_handle, &stereo_enabled);
> + return status == NVAPI_OK && stereo_enabled;
> + }
> +
> + return false;
> +}
> +
> +int Nvidia3DVisionRenderRegion(vout_display_t *vd,
> + d3d_region_t *region)
> +{
> + vout_display_sys_t *sys = vd->sys;
> + LPDIRECT3DDEVICE9 d3ddev = sys->d3ddev;
> + HRESULT hr;
> +
> + LPDIRECT3DSURFACE9 stereo_picture;
> + hr = IDirect3DTexture9_GetSurfaceLevel(sys->d3dtex, 0, &stereo_picture);
> + if (FAILED(hr)) {
> + msg_Dbg(vd, "%s:%d (hr=0x%0lX)", __FUNCTION__, __LINE__, hr);
> + return VLC_EGENERIC;
> + }
> +
> + int width = region->width;
> + int height = region->height;
> + RECT src_left;
> + RECT src_right;
> + if (vd->fmt.stereo_format.mode == VLC_STEREO3D_SBS) {
> + src_left = (RECT){ 0, 0, width / 2, height };
> + src_right = (RECT){ width / 2, 0, width, height };
> + }
> + else {
> + src_left = (RECT){ 0, 0, width, height / 2 };
> + src_right = (RECT){ 0, height / 2, width, height };
> + }
> +
> + RECT dst_left = sys->rect_dest_clipped;
> + IDirect3DDevice9_StretchRect(sys->d3ddev, stereo_picture, &src_left,
> + sys->nvidia_3dvision_surface, &dst_left,
> + D3DTEXF_POINT);
> +
> + RECT dst_right = { sys->rect_display.right, dst_left.top,
> + dst_left.right + sys->rect_display.right, dst_left.bottom };
> + IDirect3DDevice9_StretchRect(sys->d3ddev, stereo_picture, &src_right,
> + sys->nvidia_3dvision_surface, &dst_right,
> + D3DTEXF_POINT);
> +
> + IDirect3DSurface9_Release(stereo_picture);
> +
> + /*
> + * Write the 3D Vision signature at the beginning of the extra
> + * line at the bottom of the stereoscopy surface.
> + */
> + D3DLOCKED_RECT lock;
> + IDirect3DSurface9_LockRect(sys->nvidia_3dvision_surface, &lock, NULL, 0);
> + uint8_t *surface_data = lock.pBits;
> + NVSTEREOIMAGEHEADER *stereo_header = (NVSTEREOIMAGEHEADER *)(surface_data + lock.Pitch * sys->rect_display.bottom);
> +
> +
> + stereo_header->dwSignature = NVSTEREO_IMAGE_SIGNATURE;
> + /* 3D Vision is Right-Left by default. */
> + if (vd->fmt.stereo_format.flags & VLC_STEREO3D_SWAP_EYES)
> + stereo_header->dwFlags = 0;
> + else
> + stereo_header->dwFlags = DXNV_SWAP_EYES;
> +
> + /* These fields seems to be currently ignored and could be omitted. */
> + stereo_header->dwBPP = 32;
> + stereo_header->dwWidth = sys->rect_display.right * 2;
> + stereo_header->dwHeight = sys->rect_display.bottom;
> +
> + IDirect3DSurface9_UnlockRect(sys->nvidia_3dvision_surface);
> +
> + LPDIRECT3DSURFACE9 d3dback_buffer;
> + hr = IDirect3DDevice9_GetBackBuffer(d3ddev, 0, 0, D3DBACKBUFFER_TYPE_MONO,
> + &d3dback_buffer);
> + if (FAILED(hr)) {
> + msg_Err(vd, "Failed to get device back buffer. (hr=0x%lx)", hr);
> + return VLC_EGENERIC;
> + }
> +
> + /* copy stereo surface into back buffer */
> + IDirect3DDevice9_StretchRect(sys->d3ddev, sys->nvidia_3dvision_surface, NULL,
> + d3dback_buffer, NULL, D3DTEXF_POINT);
> +
> + IDirect3DSurface9_Release(d3dback_buffer);
> +
> + return VLC_SUCCESS;
> +}
> diff --git a/modules/video_output/msw/nvidia_3dvision.h b/modules/video_output/msw/nvidia_3dvision.h
> new file mode 100644
> index 0000000..1cf0fe7
> --- /dev/null
> +++ b/modules/video_output/msw/nvidia_3dvision.h
> @@ -0,0 +1,46 @@
> +/*****************************************************************************
> + * nvidia_3dvision.h
> + *****************************************************************************
> + * Copyright (C) 2014 the VideoLAN team
> + *
> + * Authors: Felix Abecassis <felix.abecassis at gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#ifndef NVIDIA_3DVISION_H_
> +# define NVIDIA_3DVISION_H_
> +
> +# ifdef HAVE_CONFIG_H
> +# include "config.h"
> +# endif
> +
> +# include <vlc_common.h>
> +# include <vlc_vout_display.h>
> +
> +int Nvidia3DVisionLoad(vout_display_t *);
> +void Nvidia3DVisionUnload(vout_display_t *);
> +
> +int Nvidia3DVisionCreateHandle(vout_display_t *);
> +void Nvidia3DVisionDestroyHandle(vout_display_t *);
> +
> +int Nvidia3DVisionCreateScene(vout_display_t *, const video_format_t *);
> +void Nvidia3DVisionDestroyScene(vout_display_t *);
> +
> +typedef struct d3d_region_t d3d_region_t;
> +bool Nvidia3DVisionCanRender(vout_display_t *);
> +int Nvidia3DVisionRenderRegion(vout_display_t *, d3d_region_t *);
> +
> +#endif
> --
> 1.9.1
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
--
With my kindest regards,
--
Jean-Baptiste Kempf
http://www.jbkempf.com/ - +33 672 704 734
Sent from my Electronic Device
More information about the vlc-devel
mailing list