Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (14)
From d4249c712991ab191f05968470b34587cc716a53 Mon Sep 17 00:00:00 2001
From: LIU Hao <lh_mouse@126.com>
Date: Sat, 18 Mar 2023 14:59:38 +0800
Subject: [PATCH 1/2] headers: Update to Wine master and regenerate H from IDL
(edited)
Signed-off-by: LIU Hao <lh_mouse@126.com>
edited:
* only kept the dxvahd.h changes
---
mingw-w64-headers/include/dxvahd.h | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/mingw-w64-headers/include/dxvahd.h b/mingw-w64-headers/include/dxvahd.h
index 71b027863..aaff9400c 100644
--- a/mingw-w64-headers/include/dxvahd.h
+++ b/mingw-w64-headers/include/dxvahd.h
@@ -251,10 +251,16 @@ typedef struct _DXVAHD_BLT_STATE_CONSTRICTION_DATA {
SIZE Size;
} DXVAHD_BLT_STATE_CONSTRICTION_DATA;
typedef struct _DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE_DATA {
- UINT Usage : 1;
- UINT RGB_Range : 1;
- UINT YCbCr_Matrix : 1;
- UINT YCbCr_xvYCC : 1;
+ __C89_NAMELESS union {
+ __C89_NAMELESS struct {
+ UINT Usage : 1;
+ UINT RGB_Range : 1;
+ UINT YCbCr_Matrix : 1;
+ UINT YCbCr_xvYCC : 1;
+ UINT Reserved : 28;
+ } __C89_NAMELESSSTRUCTNAME;
+ UINT Value;
+ } __C89_NAMELESSUNIONNAME;
} DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE_DATA;
typedef struct _DXVAHD_BLT_STATE_PRIVATE_DATA {
GUID Guid;
@@ -332,10 +338,15 @@ typedef struct _DXVAHD_STREAM_STATE_FRAME_FORMAT_DATA {
DXVAHD_FRAME_FORMAT FrameFormat;
} DXVAHD_STREAM_STATE_FRAME_FORMAT_DATA;
typedef struct _DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE_DATA {
- UINT Type : 1;
- UINT RGB_Range : 1;
- UINT YCbCr_Matrix : 1;
- UINT YCbCr_xvYCC : 1;
+ __C89_NAMELESS union {
+ __C89_NAMELESS struct {
+ UINT Type : 1;
+ UINT RGB_Range : 1;
+ UINT YCbCr_Matrix : 1;
+ UINT YCbCr_xvYCC : 1;
+ } __C89_NAMELESSSTRUCTNAME;
+ UINT Value;
+ } __C89_NAMELESSUNIONNAME;
} DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE_DATA;
typedef struct _DXVAHD_STREAM_STATE_LUMA_KEY_DATA {
WINBOOL Enable;
--
2.37.3.windows.1
From d12847294d570acc97790c7a02fb44a73850f347 Mon Sep 17 00:00:00 2001
From: LIU Hao <lh_mouse@126.com>
Date: Sat, 18 Mar 2023 17:19:02 +0800
Subject: [PATCH 2/2] headers/dxvahd: Regenerate H from IDL
Signed-off-by: LIU Hao <lh_mouse@126.com>
---
mingw-w64-headers/include/dxvahd.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/mingw-w64-headers/include/dxvahd.h b/mingw-w64-headers/include/dxvahd.h
index aaff9400c..6bcd753dd 100644
--- a/mingw-w64-headers/include/dxvahd.h
+++ b/mingw-w64-headers/include/dxvahd.h
@@ -344,6 +344,7 @@ typedef struct _DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE_DATA {
UINT RGB_Range : 1;
UINT YCbCr_Matrix : 1;
UINT YCbCr_xvYCC : 1;
+ UINT Reserved : 28;
} __C89_NAMELESSSTRUCTNAME;
UINT Value;
} __C89_NAMELESSUNIONNAME;
--
2.37.3.windows.1
......@@ -11,12 +11,12 @@ PKGS += pthreads
ifndef HAVE_VISUALSTUDIO
PKGS += dxva dxvahd
PKGS_ALL += dxva dxvahd
ifeq ($(call mingw_at_least, 8), true)
PKGS_FOUND += dxvahd
endif # MINGW 8
ifeq ($(call mingw_at_least, 10), true)
PKGS_FOUND += dxva
endif # MINGW 10
ifeq ($(call mingw_at_least, 11), true)
PKGS_FOUND += dxvahd
endif # MINGW 11
ifeq ($(HAVE_WINPTHREAD),)
PKGS_FOUND += pthreads
endif
......@@ -35,6 +35,8 @@ $(TARBALLS)/mingw-w64-v$(MINGW64_VERSION).tar.bz2:
# pthreads: mingw-w64-v$(MINGW64_VERSION).tar.bz2 .sum-pthreads
pthreads: mingw-w64-$(MINGW64_HASH).tar.xz .sum-pthreads
$(UNPACK)
$(APPLY) $(SRC)/pthreads/0001-headers-Update-to-Wine-master-and-regenerate-H-from-.patch
$(APPLY) $(SRC)/pthreads/0002-headers-dxvahd-Regenerate-H-from-IDL.patch
$(MOVE)
.pthreads: pthreads
......
......@@ -431,7 +431,7 @@ libdxva2_plugin_la_SOURCES = \
packetizer/h264_nal.c packetizer/h264_nal.h \
packetizer/hevc_nal.c packetizer/hevc_nal.h \
codec/avcodec/dxva_blacklist.c
libdxva2_plugin_la_LIBADD = libd3d9_common.la $(LIBCOM) -lshlwapi -luuid
libdxva2_plugin_la_LIBADD = libd3d9_common.la libchroma_copy.la $(LIBCOM) -lshlwapi -luuid
if HAVE_AVCODEC_DXVA2
codec_LTLIBRARIES += libdxva2_plugin.la
endif
......@@ -503,7 +503,7 @@ libmediacodec_plugin_la_SOURCES = codec/omxil/mediacodec.c codec/omxil/mediacode
packetizer/hxxx_nal.h packetizer/hxxx_nal.c \
packetizer/h264_nal.c packetizer/h264_nal.h \
packetizer/hevc_nal.c packetizer/hevc_nal.h
libmediacodec_plugin_la_LIBADD = libchroma_copy.la
libmediacodec_plugin_la_LIBADD = libchroma_copy.la
codec_LTLIBRARIES += $(LTLIBomxil) $(LTLIBomxil_vout)
EXTRA_LTLIBRARIES += libomxil_plugin.la libomxil_vout_plugin.la
if HAVE_ANDROID
......
......@@ -3,7 +3,7 @@
*****************************************************************************
* Copyright (C) 2009 Geoffroy Couprie
* Copyright (C) 2009 Laurent Aimar
* $Id$
* $Id: 26cb48dc887acd90eba53d9a30d60a3cbed212d9 $
*
* Authors: Geoffroy Couprie <geal@videolan.org>
* Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
......@@ -82,12 +82,6 @@ DEFINE_GUID(DXVA2_NoEncrypt, 0x1b81bed0, 0xa0c7, 0x11d3,
DEFINE_GUID(DXVA_Intel_H264_NoFGT_ClearVideo, 0x604F8E68, 0x4951, 0x4c54, 0x88, 0xFE, 0xAB, 0xD2, 0x5C, 0x15, 0xB3, 0xD6);
/* */
typedef struct {
const char *name;
D3DFORMAT format;
vlc_fourcc_t codec;
} d3d9_format_t;
/* XXX Preferred format must come first */
static const d3d9_format_t d3d_formats[] = {
{ "YV12", MAKEFOURCC('Y','V','1','2'), VLC_CODEC_YV12 },
......@@ -501,18 +495,14 @@ static int DxSetupOutput(vlc_va_t *va, const GUID *input, const video_format_t *
VLC_UNUSED(fmt);
vlc_va_sys_t *sys = va->sys;
D3DADAPTER_IDENTIFIER9 identifier;
HRESULT hr = IDirect3D9_GetAdapterIdentifier(sys->hd3d.obj, sys->d3d_dev.adapterId, 0, &identifier);
if (FAILED(hr))
return VLC_EGENERIC;
UINT driverBuild = identifier.DriverVersion.LowPart & 0xFFFF;
if (identifier.VendorId == GPU_MANUFACTURER_INTEL && (identifier.DriverVersion.LowPart >> 16) >= 100)
const D3DADAPTER_IDENTIFIER9 *identifier = &sys->d3d_dev.identifier;
UINT driverBuild = identifier->DriverVersion.LowPart & 0xFFFF;
if (identifier->VendorId == GPU_MANUFACTURER_INTEL && (identifier->DriverVersion.LowPart >> 16) >= 100)
{
/* new Intel driver format */
driverBuild += ((identifier.DriverVersion.LowPart >> 16) - 100) * 1000;
driverBuild += ((identifier->DriverVersion.LowPart >> 16) - 100) * 1000;
}
if (!directx_va_canUseDecoder(va, identifier.VendorId, identifier.DeviceId,
if (!directx_va_canUseDecoder(va, identifier->VendorId, identifier->DeviceId,
input, driverBuild))
{
char* psz_decoder_name = directx_va_GetDecoderName(input);
......
......@@ -28,6 +28,9 @@
#include "d3d9_fmt.h"
#include "../codec/avcodec/va_surface.h"
#include "copy.h"
#include <vlc_picture_pool.h>
picture_sys_t *ActivePictureSys(picture_t *p_pic)
{
......@@ -94,12 +97,11 @@ HRESULT D3D9_CreateDevice(vlc_object_t *o, d3d9_handle_t *hd3d, HWND hwnd,
}
/* */
D3DADAPTER_IDENTIFIER9 d3dai;
if (FAILED(IDirect3D9_GetAdapterIdentifier(hd3d->obj, AdapterToUse,0, &d3dai))) {
if (FAILED(IDirect3D9_GetAdapterIdentifier(hd3d->obj, AdapterToUse,0, &out->identifier))) {
msg_Warn(o, "IDirect3D9_GetAdapterIdentifier failed");
} else {
msg_Dbg(o, "Direct3d9 Device: %s %lx %lx %lx", d3dai.Description,
d3dai.VendorId, d3dai.DeviceId, d3dai.Revision );
msg_Dbg(o, "Direct3d9 Device: %s %lx %lx %lx", out->identifier.Description,
out->identifier.VendorId, out->identifier.DeviceId, out->identifier.Revision );
}
DWORD thread_modes[] = { D3DCREATE_MULTITHREADED, 0 };
......@@ -255,3 +257,116 @@ error:
D3D9_Destroy( hd3d );
return VLC_EGENERIC;
}
static void DestroyPicture(picture_t *picture)
{
ReleasePictureSys(picture->p_sys);
free(picture->p_sys);
free(picture);
}
int Direct3D9LockSurface(picture_t *picture)
{
/* Lock the surface to get a valid pointer to the picture buffer */
D3DLOCKED_RECT d3drect;
HRESULT hr = IDirect3DSurface9_LockRect(picture->p_sys->surface, &d3drect, NULL, 0);
if (FAILED(hr)) {
return VLC_EGENERIC;
}
return picture_UpdatePlanes(picture, d3drect.pBits, d3drect.Pitch);
}
void Direct3D9UnlockSurface(picture_t *picture)
{
/* Unlock the Surface */
HRESULT hr = IDirect3DSurface9_UnlockRect(picture->p_sys->surface);
if (FAILED(hr)) {
//msg_Dbg(vd, "Failed IDirect3DSurface9_UnlockRect: 0x%0lx", hr);
}
}
/* */
picture_pool_t *Direct3D9CreatePicturePool(vlc_object_t *o,
d3d9_device_t *p_d3d9_dev, const d3d9_format_t *default_d3dfmt, const video_format_t *fmt, unsigned count)
{
picture_pool_t* pool = NULL;
picture_t** pictures = NULL;
unsigned picture_count = 0;
pictures = calloc(count, sizeof(*pictures));
if (!pictures)
goto error;
D3DFORMAT format;
switch (fmt->i_chroma)
{
case VLC_CODEC_D3D9_OPAQUE_10B:
format = MAKEFOURCC('P','0','1','0');
break;
case VLC_CODEC_D3D9_OPAQUE:
format = MAKEFOURCC('N','V','1','2');
break;
default:
if (!default_d3dfmt)
goto error;
format = default_d3dfmt->format;
break;
}
for (picture_count = 0; picture_count < count; ++picture_count)
{
picture_sys_t *picsys = malloc(sizeof(*picsys));
if (unlikely(picsys == NULL))
goto error;
memset(picsys, 0, sizeof(*picsys));
HRESULT hr = IDirect3DDevice9_CreateOffscreenPlainSurface(p_d3d9_dev->dev,
fmt->i_width,
fmt->i_height,
format,
D3DPOOL_DEFAULT,
&picsys->surface,
NULL);
if (FAILED(hr)) {
msg_Err(o, "Failed to allocate surface %d (hr=0x%0lx)", picture_count, hr);
free(picsys);
goto error;
}
picture_resource_t resource = {
.p_sys = picsys,
.pf_destroy = DestroyPicture,
};
picture_t *picture = picture_NewFromResource(fmt, &resource);
if (unlikely(picture == NULL)) {
free(picsys);
goto error;
}
pictures[picture_count] = picture;
}
picture_pool_configuration_t pool_cfg;
memset(&pool_cfg, 0, sizeof(pool_cfg));
pool_cfg.picture_count = count;
pool_cfg.picture = pictures;
if( !is_d3d9_opaque( fmt->i_chroma ) )
{
pool_cfg.lock = Direct3D9LockSurface;
pool_cfg.unlock = Direct3D9UnlockSurface;
}
pool = picture_pool_NewExtended( &pool_cfg );
error:
if (pool == NULL && pictures) {
for (unsigned i=0;i<picture_count; ++i)
DestroyPicture(pictures[i]);
}
free(pictures);
return pool;
}
......@@ -65,8 +65,19 @@ typedef struct
UINT adapterId;
HWND hwnd;
D3DCAPS9 caps;
D3DADAPTER_IDENTIFIER9 identifier;
} d3d9_device_t;
typedef struct
{
const char *name;
D3DFORMAT format; /* D3D format */
vlc_fourcc_t fourcc; /* VLC fourcc */
uint32_t rmask;
uint32_t gmask;
uint32_t bmask;
} d3d9_format_t;
#include "../codec/avcodec/va_surface.h"
picture_sys_t *ActivePictureSys(picture_t *p_pic);
......@@ -87,6 +98,18 @@ static inline void ReleasePictureSys(picture_sys_t *p_sys)
FreeLibrary(p_sys->dxva2_dll);
}
static inline bool is_d3d9_opaque(vlc_fourcc_t chroma)
{
switch (chroma)
{
case VLC_CODEC_D3D9_OPAQUE:
case VLC_CODEC_D3D9_OPAQUE_10B:
return true;
default:
return false;
}
}
HRESULT D3D9_CreateDevice(vlc_object_t *, d3d9_handle_t *, HWND,
const video_format_t *, d3d9_device_t *out);
#define D3D9_CreateDevice(a,b,c,d,e) D3D9_CreateDevice( VLC_OBJECT(a), b, c, d, e )
......@@ -99,4 +122,21 @@ void D3D9_Destroy(d3d9_handle_t *);
int D3D9_FillPresentationParameters(d3d9_handle_t *, const video_format_t *, d3d9_device_t *);
/**
* It locks the surface associated to the picture and get the surface
* descriptor which amongst other things has the pointer to the picture
* data and its pitch.
*/
int Direct3D9LockSurface(picture_t *picture);
/**
* It unlocks the surface associated to the picture.
*/
void Direct3D9UnlockSurface(picture_t *picture);
struct picture_pool_t *Direct3D9CreatePicturePool(vlc_object_t *, d3d9_device_t *,
const d3d9_format_t *, const video_format_t *, unsigned);
#endif /* VLC_VIDEOCHROMA_D3D9_FMT_H_ */
......@@ -261,9 +261,18 @@ libdirect3d9_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) \
-DMODULE_NAME_IS_direct3d9
libdirect3d9_plugin_la_LIBADD = libchroma_copy.la libd3d9_common.la -lgdi32 $(LIBCOM) -luuid
libdirect3d9_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)'
libglinterop_dxva2_plugin_la_SOURCES = video_output/opengl/interop_dxva2.c \
video_output/opengl/converter.h
libglinterop_dxva2_plugin_la_CFLAGS = $(AM_CFLAGS) $(GL_CFLAGS)
libglinterop_dxva2_plugin_la_LIBADD = libchroma_copy.la libd3d9_common.la
if HAVE_WIN32_DESKTOP
vout_LTLIBRARIES += $(LTLIBdirect3d9)
EXTRA_LTLIBRARIES += libdirect3d9_plugin.la
if HAVE_GL
vout_LTLIBRARIES += libglinterop_dxva2_plugin.la
endif
endif
libdirect3d11_plugin_la_SOURCES = video_output/win32/direct3d11.c \
......
/*****************************************************************************
* direct3d9.c: Windows Direct3D9 video output module
*****************************************************************************
* Copyright (C) 2006-2014 VLC authors and VideoLAN
*
* Authors: Martell Malone <martellmalone@gmail.com>,
* Damien Fouilleul <damienf@videolan.org>,
* Sasha Koruga <skoruga@gmail.com>,
* Felix Abecassis <felix.abecassis@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*****************************************************************************/
/*****************************************************************************
* Preamble:
*
* This plugin will use YUV surface if supported, using YUV will result in
* the best video quality (hardware filtering when rescaling the picture)
* and the fastest display as it requires less processing.
*
* If YUV overlay is not supported this plugin will use RGB offscreen video
* surfaces that will be blitted onto the primary surface (display) to
* effectively display the pictures.
*
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
// For dynamic use of DXVA-HD
#if _WIN32_WINNT < 0x0601 // _WIN32_WINNT_WIN7
# undef _WIN32_WINNT
# define _WIN32_WINNT _WIN32_WINNT_WIN7
#endif
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_vout_display.h>
#include <windows.h>
#include <d3d9.h>
#include "../../video_chroma/d3d9_fmt.h"
#include <dxvahd.h>
#include "../opengl/converter.h"
#include <GL/wglew.h>
/*****************************************************************************
* Module descriptor
*****************************************************************************/
static int GLConvOpen(vlc_object_t *);
static void GLConvClose(vlc_object_t *);
vlc_module_begin ()
set_shortname("dxva2")
set_category(CAT_VIDEO)
set_subcategory(SUBCAT_VIDEO_VOUT)
set_description("DX OpenGL surface converter for D3D9")
set_capability("glconv", 1)
set_callbacks(GLConvOpen, GLConvClose)
vlc_module_end ()
struct wgl_vt {
PFNWGLDXSETRESOURCESHAREHANDLENVPROC DXSetResourceShareHandleNV;
PFNWGLDXOPENDEVICENVPROC DXOpenDeviceNV;
PFNWGLDXCLOSEDEVICENVPROC DXCloseDeviceNV;
PFNWGLDXREGISTEROBJECTNVPROC DXRegisterObjectNV;
PFNWGLDXUNREGISTEROBJECTNVPROC DXUnregisterObjectNV;
PFNWGLDXLOCKOBJECTSNVPROC DXLockObjectsNV;
PFNWGLDXUNLOCKOBJECTSNVPROC DXUnlockObjectsNV;
};
struct glpriv
{
struct wgl_vt vt;
d3d9_handle_t hd3d;
d3d9_device_t d3d_dev;
HANDLE gl_handle_d3d;
HANDLE gl_render;
IDirect3DSurface9 *dx_render;
D3DFORMAT OutputFormat;
/* range converter */
struct {
HMODULE dll;
IDXVAHD_VideoProcessor *proc;
} processor;
};
static int
GLConvUpdate(const opengl_tex_converter_t *tc, GLuint *textures,
const GLsizei *tex_width, const GLsizei *tex_height,
picture_t *pic, const size_t *plane_offset)
{
VLC_UNUSED(textures); VLC_UNUSED(tex_width); VLC_UNUSED(tex_height); VLC_UNUSED(plane_offset);
struct glpriv *priv = tc->priv;
HRESULT hr;
picture_sys_t *picsys = ActivePictureSys(pic);
if (unlikely(!picsys || !priv->gl_render))
return VLC_EGENERIC;
if (!priv->vt.DXUnlockObjectsNV(priv->gl_handle_d3d, 1, &priv->gl_render))
{
msg_Warn(tc->gl, "DXUnlockObjectsNV failed");
return VLC_EGENERIC;
}
if (priv->processor.proc)
{
DXVAHD_STREAM_DATA inputStream = { 0 };
inputStream.Enable = TRUE;
inputStream.pInputSurface = picsys->surface;
hr = IDXVAHD_VideoProcessor_VideoProcessBltHD( priv->processor.proc, priv->dx_render, 0, 1, &inputStream );
if (FAILED(hr)) {
D3DSURFACE_DESC srcDesc, dstDesc;
IDirect3DSurface9_GetDesc(picsys->surface, &srcDesc);
IDirect3DSurface9_GetDesc(priv->dx_render, &dstDesc);
msg_Dbg(tc->gl, "Failed VideoProcessBltHD src:%4.4s (%d) dst:%4.4s (%d) (hr=0x%lX)",
(const char*)&srcDesc.Format, srcDesc.Format,
(const char*)&dstDesc.Format, dstDesc.Format, hr);
return VLC_EGENERIC;
}
}
else
{
const RECT rect = {
.left = 0,
.top = 0,
.right = pic->format.i_visible_width,
.bottom = pic->format.i_visible_height
};
hr = IDirect3DDevice9Ex_StretchRect(priv->d3d_dev.devex, picsys->surface,
&rect, priv->dx_render, NULL, D3DTEXF_NONE);
if (FAILED(hr))
{
msg_Warn(tc->gl, "IDirect3DDevice9Ex_StretchRect failed");
return VLC_EGENERIC;
}
}
if (!priv->vt.DXLockObjectsNV(priv->gl_handle_d3d, 1, &priv->gl_render))
{
msg_Warn(tc->gl, "DXLockObjectsNV failed");
priv->vt.DXUnregisterObjectNV(priv->gl_handle_d3d, priv->gl_render);
priv->gl_render = NULL;
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
static picture_pool_t *
GLConvGetPool(const opengl_tex_converter_t *tc, unsigned requested_count)
{
struct glpriv *priv = tc->priv;
return Direct3D9CreatePicturePool(VLC_OBJECT(tc->gl), &priv->d3d_dev, NULL,
&tc->fmt, requested_count);
}
static int
GLConvAllocateTextures(const opengl_tex_converter_t *tc, GLuint *textures,
const GLsizei *tex_width, const GLsizei *tex_height)
{
VLC_UNUSED(tex_width); VLC_UNUSED(tex_height);
struct glpriv *priv = tc->priv;
priv->gl_render =
priv->vt.DXRegisterObjectNV(priv->gl_handle_d3d, priv->dx_render,
textures[0], GL_TEXTURE_2D, WGL_ACCESS_WRITE_DISCARD_NV);
if (!priv->gl_render)
{
msg_Warn(tc->gl, "DXRegisterObjectNV failed: %lu", GetLastError());
return VLC_EGENERIC;
}
if (!priv->vt.DXLockObjectsNV(priv->gl_handle_d3d, 1, &priv->gl_render))
{
msg_Warn(tc->gl, "DXLockObjectsNV failed");
priv->vt.DXUnregisterObjectNV(priv->gl_handle_d3d, priv->gl_render);
priv->gl_render = NULL;
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
static void
GLConvClose(vlc_object_t *obj)
{
opengl_tex_converter_t *tc = (void *)obj;
struct glpriv *priv = tc->priv;
if (priv->gl_handle_d3d)
{
if (priv->gl_render)
{
priv->vt.DXUnlockObjectsNV(priv->gl_handle_d3d, 1, &priv->gl_render);
priv->vt.DXUnregisterObjectNV(priv->gl_handle_d3d, priv->gl_render);
}
priv->vt.DXCloseDeviceNV(priv->gl_handle_d3d);
}
if (priv->processor.proc)
{
IDXVAHD_VideoProcessor_Release(priv->processor.proc);
FreeLibrary(priv->processor.dll);
}
if (priv->dx_render)
IDirect3DSurface9_Release(priv->dx_render);
D3D9_ReleaseDevice(&priv->d3d_dev);
D3D9_Destroy(&priv->hd3d);
free(tc->priv);
}
static void SetupProcessorInput(opengl_tex_converter_t *interop, const video_format_t *fmt, D3DFORMAT src_format)
{
struct glpriv *sys = interop->priv;
HRESULT hr;
DXVAHD_STREAM_STATE_D3DFORMAT_DATA d3dformat = { src_format };
hr = IDXVAHD_VideoProcessor_SetVideoProcessStreamState( sys->processor.proc, 0, DXVAHD_STREAM_STATE_D3DFORMAT, sizeof(d3dformat), &d3dformat );
DXVAHD_STREAM_STATE_FRAME_FORMAT_DATA frame_format = { DXVAHD_FRAME_FORMAT_PROGRESSIVE };
hr = IDXVAHD_VideoProcessor_SetVideoProcessStreamState( sys->processor.proc, 0, DXVAHD_STREAM_STATE_FRAME_FORMAT, sizeof(frame_format), &frame_format );
DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE_DATA colorspace = {
.Type = 0, // video, not graphics
.RGB_Range = fmt->b_color_range_full ? 0 : 1,
.YCbCr_xvYCC = fmt->b_color_range_full ? 1 : 0,
.YCbCr_Matrix = fmt->space == COLOR_SPACE_BT601 ? 0 : 1,
};
hr = IDXVAHD_VideoProcessor_SetVideoProcessStreamState( sys->processor.proc, 0, DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE, sizeof(colorspace), &colorspace );
DXVAHD_STREAM_STATE_SOURCE_RECT_DATA srcRect;
srcRect.Enable = TRUE;
srcRect.SourceRect = (RECT) {
.left = interop->fmt.i_x_offset,
.right = interop->fmt.i_x_offset + interop->fmt.i_visible_width,
.top = interop->fmt.i_y_offset,
.bottom = interop->fmt.i_y_offset + interop->fmt.i_visible_height,
};;
hr = IDXVAHD_VideoProcessor_SetVideoProcessStreamState( sys->processor.proc, 0, DXVAHD_STREAM_STATE_SOURCE_RECT, sizeof(srcRect), &srcRect );
DXVAHD_BLT_STATE_TARGET_RECT_DATA dstRect;
dstRect.Enable = TRUE;
dstRect.TargetRect = (RECT) {
.left = 0,
.right = interop->fmt.i_visible_width,
.top = 0,
.bottom = interop->fmt.i_visible_height,
};
hr = IDXVAHD_VideoProcessor_SetVideoProcessBltState( sys->processor.proc, DXVAHD_BLT_STATE_TARGET_RECT, sizeof(dstRect), &dstRect);
}
static void GetFrameRate(DXVAHD_RATIONAL *r, const video_format_t *fmt)
{
if (fmt->i_frame_rate && fmt->i_frame_rate_base)
{
r->Numerator = fmt->i_frame_rate;
r->Denominator = fmt->i_frame_rate_base;
}
else
{
r->Numerator = 0;
r->Denominator = 0;
}
}
static int InitRangeProcessor(opengl_tex_converter_t *interop, IDirect3DDevice9Ex *devex, D3DFORMAT src_format)
{
struct glpriv *sys = interop->priv;
HRESULT hr;
sys->processor.dll = LoadLibrary(TEXT("DXVA2.DLL"));
if (unlikely(!sys->processor.dll))
{
msg_Err(interop, "Failed to load DXVA2.DLL");
return VLC_EGENERIC;
}
D3DFORMAT *formatsList = NULL;
DXVAHD_VPCAPS *capsList = NULL;
IDXVAHD_Device *hd_device = NULL;
#ifdef __MINGW64_VERSION_MAJOR
typedef HRESULT (WINAPI* PDXVAHD_CreateDevice)(IDirect3DDevice9Ex *,const DXVAHD_CONTENT_DESC *,DXVAHD_DEVICE_USAGE,PDXVAHDSW_Plugin,IDXVAHD_Device **);
#endif
PDXVAHD_CreateDevice CreateDevice;
CreateDevice = (PDXVAHD_CreateDevice)GetProcAddress(sys->processor.dll, "DXVAHD_CreateDevice");
if (CreateDevice == NULL)
{
msg_Err(interop, "Can't create HD device (not Windows 7+)");
goto error;
}
DXVAHD_CONTENT_DESC desc;
desc.InputFrameFormat = DXVAHD_FRAME_FORMAT_PROGRESSIVE;
GetFrameRate( &desc.InputFrameRate, &interop->fmt );
desc.InputWidth = interop->fmt.i_visible_width;
desc.InputHeight = interop->fmt.i_visible_height;
desc.OutputFrameRate = desc.InputFrameRate;
desc.OutputWidth = interop->fmt.i_visible_width;
desc.OutputHeight = interop->fmt.i_visible_height;
hr = CreateDevice(devex, &desc, DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL, NULL, &hd_device);
if (FAILED(hr))
{
msg_Dbg(interop, "Failed to create the device (error 0x%lX)", hr);
goto error;
}
DXVAHD_VPDEVCAPS devcaps = { 0 };
hr = IDXVAHD_Device_GetVideoProcessorDeviceCaps( hd_device, &devcaps );
if (unlikely(FAILED(hr)))
{
msg_Err(interop, "Failed to get the device capabilities (error 0x%lX)", hr);
goto error;
}
if (devcaps.VideoProcessorCount == 0)
{
msg_Warn(interop, "No good video processor found for range conversion");
goto error;
}
formatsList = malloc(devcaps.InputFormatCount * sizeof(*formatsList));
if (unlikely(formatsList == NULL))
{
msg_Dbg(interop, "Failed to allocate %u input formats", devcaps.InputFormatCount);
goto error;
}
hr = IDXVAHD_Device_GetVideoProcessorInputFormats( hd_device, devcaps.InputFormatCount, formatsList);
UINT i;
for (i=0; i<devcaps.InputFormatCount; i++)
{
if (formatsList[i] == src_format)
break;
}
if (i == devcaps.InputFormatCount)
{
msg_Warn(interop, "Input format %4.4s not supported for range conversion", (const char*)&src_format);
goto error;
}
free(formatsList);
formatsList = malloc(devcaps.OutputFormatCount * sizeof(*formatsList));
if (unlikely(formatsList == NULL))
{
msg_Dbg(interop, "Failed to allocate %u output formats", devcaps.OutputFormatCount);
goto error;
}
hr = IDXVAHD_Device_GetVideoProcessorOutputFormats( hd_device, devcaps.OutputFormatCount, formatsList);
for (i=0; i<devcaps.OutputFormatCount; i++)
{
if (formatsList[i] == sys->OutputFormat)
break;
}
if (i == devcaps.OutputFormatCount)
{
msg_Warn(interop, "Output format %d not supported for range conversion", sys->OutputFormat);
goto error;
}
capsList = malloc(devcaps.VideoProcessorCount * sizeof(*capsList));
if (unlikely(capsList == NULL))
{
msg_Dbg(interop, "Failed to allocate %u video processors", devcaps.VideoProcessorCount);
goto error;
}
hr = IDXVAHD_Device_GetVideoProcessorCaps( hd_device, devcaps.VideoProcessorCount, capsList);
if (FAILED(hr))
{
msg_Dbg(interop, "Failed to get the processor caps (error 0x%lX)", hr);
goto error;
}
hr = IDXVAHD_Device_CreateVideoProcessor( hd_device, &capsList->VPGuid, &sys->processor.proc );
if (FAILED(hr))
{
msg_Dbg(interop, "Failed to create the processor (error 0x%lX)", hr);
goto error;
}
IDXVAHD_Device_Release( hd_device );
SetupProcessorInput(interop, &interop->fmt, src_format);
DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE_DATA colorspace = {
.Usage = 0, // playback
.RGB_Range = /* full range */true ? 0 : 1,
.YCbCr_xvYCC = /* full range */true ? 1 : 0,
.YCbCr_Matrix = /* BT601 colorspace */ false ? 0 : 1,
};
hr = IDXVAHD_VideoProcessor_SetVideoProcessBltState( sys->processor.proc, DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE, sizeof(colorspace), &colorspace);
return VLC_SUCCESS;
error:
free(capsList);
free(formatsList);
if (hd_device)
IDXVAHD_Device_Release(hd_device);
FreeLibrary(sys->processor.dll);
return VLC_EGENERIC;
}
static int
GLConvOpen(vlc_object_t *obj)
{
opengl_tex_converter_t *tc = (void *) obj;
if (tc->fmt.i_chroma != VLC_CODEC_D3D9_OPAQUE
&& tc->fmt.i_chroma != VLC_CODEC_D3D9_OPAQUE_10B)
return VLC_EGENERIC;
if (tc->gl->ext != VLC_GL_EXT_WGL || !tc->gl->wgl.getExtensionsString)
return VLC_EGENERIC;
const char *wglExt = tc->gl->wgl.getExtensionsString(tc->gl);
if (wglExt == NULL || !HasExtension(wglExt, "WGL_NV_DX_interop"))
return VLC_EGENERIC;
struct wgl_vt vt;
#define LOAD_EXT(name, type) do { \
vt.name = (type) vlc_gl_GetProcAddress(tc->gl, "wgl" #name); \
if (!vt.name) { \
msg_Warn(obj, "'wgl " #name "' could not be loaded"); \
return VLC_EGENERIC; \
} \
} while(0)
LOAD_EXT(DXSetResourceShareHandleNV, PFNWGLDXSETRESOURCESHAREHANDLENVPROC);
LOAD_EXT(DXOpenDeviceNV, PFNWGLDXOPENDEVICENVPROC);
LOAD_EXT(DXCloseDeviceNV, PFNWGLDXCLOSEDEVICENVPROC);
LOAD_EXT(DXRegisterObjectNV, PFNWGLDXREGISTEROBJECTNVPROC);
LOAD_EXT(DXUnregisterObjectNV, PFNWGLDXUNREGISTEROBJECTNVPROC);
LOAD_EXT(DXLockObjectsNV, PFNWGLDXLOCKOBJECTSNVPROC);
LOAD_EXT(DXUnlockObjectsNV, PFNWGLDXUNLOCKOBJECTSNVPROC);
struct glpriv *priv = calloc(1, sizeof(struct glpriv));
if (!priv)
return VLC_ENOMEM;
tc->priv = priv;
priv->OutputFormat = D3DFMT_X8R8G8B8;
priv->vt = vt;
if (D3D9_Create(obj, &priv->hd3d) != VLC_SUCCESS)
goto error;
if (!priv->hd3d.use_ex)
{
msg_Warn(obj, "DX/GL interrop only working on d3d9x");
goto error;
}
if (FAILED(D3D9_CreateDevice(obj, &priv->hd3d, tc->gl->surface->handle.hwnd,
&tc->fmt, &priv->d3d_dev)))
goto error;
D3DFORMAT format = tc->fmt.i_chroma == VLC_CODEC_D3D9_OPAQUE_10B ?
MAKEFOURCC('P','0','1','0') : MAKEFOURCC('N','V','1','2');
HRESULT hr;
bool force_dxva_hd = false;
if ( !tc->fmt.b_color_range_full &&
priv->d3d_dev.identifier.VendorId == GPU_MANUFACTURER_NVIDIA )
{
// NVIDIA bug, YUV to RGB internal conversion in StretchRect always converts from limited to limited range
msg_Dbg(tc->gl, "init DXVA-HD processor from %4.4s to RGB", (const char*)&format);
int err = InitRangeProcessor(tc, priv->d3d_dev.devex, format);
if (err == VLC_SUCCESS)
force_dxva_hd = true;
}
if (!force_dxva_hd)
{
// test whether device can perform color-conversion from that format to target format
hr = IDirect3D9_CheckDeviceFormatConversion(priv->hd3d.obj,
priv->d3d_dev.adapterId,
D3DDEVTYPE_HAL,
format, priv->OutputFormat);
if (FAILED(hr))
{
msg_Dbg(tc->gl, "Unsupported conversion from %4.4s to RGB", (const char*)&format );
goto error;
}
msg_Dbg(tc->gl, "using StrecthRect from %4.4s to RGB", (const char*)&format );
}
HANDLE shared_handle = NULL;
hr = IDirect3DDevice9Ex_CreateRenderTarget(priv->d3d_dev.devex,
tc->fmt.i_visible_width,
tc->fmt.i_visible_height,
priv->OutputFormat,
D3DMULTISAMPLE_NONE, 0, FALSE,
&priv->dx_render, &shared_handle);
if (FAILED(hr))
{
msg_Warn(obj, "IDirect3DDevice9_CreateOffscreenPlainSurface failed");
goto error;
}
if (shared_handle)
priv->vt.DXSetResourceShareHandleNV(priv->dx_render, shared_handle);
priv->gl_handle_d3d = priv->vt.DXOpenDeviceNV(priv->d3d_dev.devex);
if (!priv->gl_handle_d3d)
{
msg_Warn(obj, "DXOpenDeviceNV failed: %lu", GetLastError());
goto error;
}
tc->pf_update = GLConvUpdate;
tc->pf_get_pool = GLConvGetPool;
tc->pf_allocate_textures = GLConvAllocateTextures;
tc->fshader = opengl_fragment_shader_init(tc, GL_TEXTURE_2D, VLC_CODEC_RGB32,
COLOR_SPACE_UNDEF);
if (tc->fshader == 0)
goto error;
return VLC_SUCCESS;
error:
GLConvClose(obj);
return VLC_EGENERIC;
}
......@@ -70,9 +70,6 @@
static int Open(vlc_object_t *);
static void Close(vlc_object_t *);
static int GLConvOpen(vlc_object_t *);
static void GLConvClose(vlc_object_t *);
#define DESKTOP_LONGTEXT N_(\
"The desktop mode allows you to display the video on the desktop.")
......@@ -109,13 +106,6 @@ vlc_module_begin ()
set_capability("vout display", 280)
add_shortcut("direct3d9", "direct3d")
set_callbacks(Open, Close)
#ifdef HAVE_GL
add_submodule()
set_description("DX OpenGL surface converter for D3D9")
set_capability("glconv", 1)
set_callbacks(GLConvOpen, GLConvClose)
#endif
vlc_module_end ()
/*****************************************************************************
......@@ -126,16 +116,6 @@ static const vlc_fourcc_t d3d_subpicture_chromas[] = {
0
};
typedef struct
{
const char *name;
D3DFORMAT format; /* D3D format */
vlc_fourcc_t fourcc; /* VLC fourcc */
uint32_t rmask;
uint32_t gmask;
uint32_t bmask;
} d3d9_format_t;
struct vout_display_sys_t
{
vout_display_sys_win32_t sys;
......@@ -188,9 +168,6 @@ static const d3d9_format_t *FindBufferFormat(vout_display_t *, D3DFORMAT);
static int Open(vlc_object_t *);
static picture_pool_t *Direct3D9CreatePicturePool (vlc_object_t *, d3d9_device_t *,
const d3d9_format_t *, const video_format_t *, unsigned);
static void Prepare(vout_display_t *, picture_t *, subpicture_t *subpicture);
static void Display(vout_display_t *, picture_t *, subpicture_t *subpicture);
static picture_pool_t*DisplayPool(vout_display_t *, unsigned);
......@@ -231,18 +208,6 @@ static void Direct3D9RenderScene(vout_display_t *vd, d3d_region_t *, int, d3d_re
/* */
static int DesktopCallback(vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void *);
static bool is_d3d9_opaque(vlc_fourcc_t chroma)
{
switch (chroma)
{
case VLC_CODEC_D3D9_OPAQUE:
case VLC_CODEC_D3D9_OPAQUE_10B:
return true;
default:
return false;
}
}
static HINSTANCE Direct3D9LoadShaderLibrary(void)
{
HINSTANCE instance = NULL;
......@@ -404,126 +369,6 @@ static void Close(vlc_object_t *object)
free(vd->sys);
}
static void DestroyPicture(picture_t *picture)
{
ReleasePictureSys(picture->p_sys);
free(picture->p_sys);
free(picture);
}
/**
* It locks the surface associated to the picture and get the surface
* descriptor which amongst other things has the pointer to the picture
* data and its pitch.
*/
static int Direct3D9LockSurface(picture_t *picture)
{
/* Lock the surface to get a valid pointer to the picture buffer */
D3DLOCKED_RECT d3drect;
HRESULT hr = IDirect3DSurface9_LockRect(picture->p_sys->surface, &d3drect, NULL, 0);
if (FAILED(hr)) {
return VLC_EGENERIC;
}
CommonUpdatePicture(picture, NULL, d3drect.pBits, d3drect.Pitch);
return VLC_SUCCESS;
}
/**
* It unlocks the surface associated to the picture.
*/
static void Direct3D9UnlockSurface(picture_t *picture)
{
/* Unlock the Surface */
HRESULT hr = IDirect3DSurface9_UnlockRect(picture->p_sys->surface);
if (FAILED(hr)) {
//msg_Dbg(vd, "Failed IDirect3DSurface9_UnlockRect: 0x%0lx", hr);
}
}
/* */
static picture_pool_t *Direct3D9CreatePicturePool(vlc_object_t *o,
d3d9_device_t *p_d3d9_dev, const d3d9_format_t *default_d3dfmt, const video_format_t *fmt, unsigned count)
{
picture_pool_t* pool = NULL;
picture_t** pictures = NULL;
unsigned picture_count = 0;
pictures = calloc(count, sizeof(*pictures));
if (!pictures)
goto error;
D3DFORMAT format;
switch (fmt->i_chroma)
{
case VLC_CODEC_D3D9_OPAQUE_10B:
format = MAKEFOURCC('P','0','1','0');
break;
case VLC_CODEC_D3D9_OPAQUE:
format = MAKEFOURCC('N','V','1','2');
break;
default:
if (!default_d3dfmt)
goto error;
format = default_d3dfmt->format;
break;
}
for (picture_count = 0; picture_count < count; ++picture_count)
{
picture_sys_t *picsys = malloc(sizeof(*picsys));
if (unlikely(picsys == NULL))
goto error;
memset(picsys, 0, sizeof(*picsys));
HRESULT hr = IDirect3DDevice9_CreateOffscreenPlainSurface(p_d3d9_dev->dev,
fmt->i_width,
fmt->i_height,
format,
D3DPOOL_DEFAULT,
&picsys->surface,
NULL);
if (FAILED(hr)) {
msg_Err(o, "Failed to allocate surface %d (hr=0x%0lx)", picture_count, hr);
free(picsys);
goto error;
}
picture_resource_t resource = {
.p_sys = picsys,
.pf_destroy = DestroyPicture,
};
picture_t *picture = picture_NewFromResource(fmt, &resource);
if (unlikely(picture == NULL)) {
free(picsys);
goto error;
}
pictures[picture_count] = picture;
}
picture_pool_configuration_t pool_cfg;
memset(&pool_cfg, 0, sizeof(pool_cfg));
pool_cfg.picture_count = count;
pool_cfg.picture = pictures;
if( !is_d3d9_opaque( fmt->i_chroma ) )
{
pool_cfg.lock = Direct3D9LockSurface;
pool_cfg.unlock = Direct3D9UnlockSurface;
}
pool = picture_pool_NewExtended( &pool_cfg );
error:
if (pool == NULL && pictures) {
for (unsigned i=0;i<picture_count; ++i)
DestroyPicture(pictures[i]);
}
free(pictures);
return pool;
}
static picture_pool_t *DisplayPool(vout_display_t *vd, unsigned count)
{
if ( vd->sys->sys.pool != NULL )
......@@ -815,10 +660,12 @@ static void SetupProcessorInput(vout_display_t *vd, const video_format_t *fmt, c
DXVAHD_STREAM_STATE_FRAME_FORMAT_DATA frame_format = { DXVAHD_FRAME_FORMAT_PROGRESSIVE };
hr = IDXVAHD_VideoProcessor_SetVideoProcessStreamState( sys->processor.proc, 0, DXVAHD_STREAM_STATE_FRAME_FORMAT, sizeof(frame_format), &frame_format );
DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE_DATA colorspace = { 0 };
colorspace.RGB_Range = fmt->b_color_range_full ? 0 : 1;
colorspace.YCbCr_xvYCC = fmt->b_color_range_full ? 1 : 0;
colorspace.YCbCr_Matrix = fmt->space == COLOR_SPACE_BT601 ? 0 : 1;
DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE_DATA colorspace = {
.Type = 0, // video, not graphics
.RGB_Range = fmt->b_color_range_full ? 0 : 1,
.YCbCr_xvYCC = fmt->b_color_range_full ? 1 : 0,
.YCbCr_Matrix = fmt->space == COLOR_SPACE_BT601 ? 0 : 1,
};
hr = IDXVAHD_VideoProcessor_SetVideoProcessStreamState( sys->processor.proc, 0, DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE, sizeof(colorspace), &colorspace );
DXVAHD_STREAM_STATE_SOURCE_RECT_DATA srcRect;
......@@ -870,8 +717,11 @@ static int InitRangeProcessor(vout_display_t *vd, const d3d9_format_t *d3dfmt)
DXVAHD_VPCAPS *capsList = NULL;
IDXVAHD_Device *hd_device = NULL;
HRESULT (WINAPI *CreateDevice)(IDirect3DDevice9Ex *,const DXVAHD_CONTENT_DESC *,DXVAHD_DEVICE_USAGE,PDXVAHDSW_Plugin,IDXVAHD_Device **);
CreateDevice = (void *)GetProcAddress(sys->processor.dll, "DXVAHD_CreateDevice");
#ifdef __MINGW64_VERSION_MAJOR
typedef HRESULT (WINAPI* PDXVAHD_CreateDevice)(IDirect3DDevice9Ex *,const DXVAHD_CONTENT_DESC *,DXVAHD_DEVICE_USAGE,PDXVAHDSW_Plugin,IDXVAHD_Device **);
#endif
PDXVAHD_CreateDevice CreateDevice;
CreateDevice = (PDXVAHD_CreateDevice)GetProcAddress(sys->processor.dll, "DXVAHD_CreateDevice");
if (CreateDevice == NULL)
{
msg_Err(vd, "Can't create HD device (not Windows 7+)");
......@@ -961,11 +811,12 @@ static int InitRangeProcessor(vout_display_t *vd, const d3d9_format_t *d3dfmt)
SetupProcessorInput(vd, &vd->source, d3dfmt);
DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE_DATA colorspace;
colorspace.Usage = 0; // playback
colorspace.RGB_Range = 0; // full range display
colorspace.YCbCr_xvYCC = 1;
colorspace.YCbCr_Matrix = 1; // BT.709
DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE_DATA colorspace = {
.Usage = 0, // playback
.RGB_Range = 0, // full range display
.YCbCr_xvYCC = 1,
.YCbCr_Matrix = 1, // BT.709
};
hr = IDXVAHD_VideoProcessor_SetVideoProcessBltState( sys->processor.proc, DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE, sizeof(colorspace), &colorspace);
return VLC_SUCCESS;
......@@ -2057,224 +1908,3 @@ static int FindShadersCallback(vlc_object_t *object, const char *name,
return ctx.count;
}
#ifdef HAVE_GL
#include "../opengl/converter.h"
#include <GL/wglew.h>
struct wgl_vt {
PFNWGLDXSETRESOURCESHAREHANDLENVPROC DXSetResourceShareHandleNV;
PFNWGLDXOPENDEVICENVPROC DXOpenDeviceNV;
PFNWGLDXCLOSEDEVICENVPROC DXCloseDeviceNV;
PFNWGLDXREGISTEROBJECTNVPROC DXRegisterObjectNV;
PFNWGLDXUNREGISTEROBJECTNVPROC DXUnregisterObjectNV;
PFNWGLDXLOCKOBJECTSNVPROC DXLockObjectsNV;
PFNWGLDXUNLOCKOBJECTSNVPROC DXUnlockObjectsNV;
};
struct glpriv
{
struct wgl_vt vt;
d3d9_handle_t hd3d;
d3d9_device_t d3d_dev;
HANDLE gl_handle_d3d;
HANDLE gl_render;
IDirect3DSurface9 *dx_render;
};
static int
GLConvUpdate(const opengl_tex_converter_t *tc, GLuint *textures,
const GLsizei *tex_width, const GLsizei *tex_height,
picture_t *pic, const size_t *plane_offset)
{
VLC_UNUSED(textures); VLC_UNUSED(tex_width); VLC_UNUSED(tex_height); VLC_UNUSED(plane_offset);
struct glpriv *priv = tc->priv;
HRESULT hr;
picture_sys_t *picsys = ActivePictureSys(pic);
if (unlikely(!picsys || !priv->gl_render))
return VLC_EGENERIC;
if (!priv->vt.DXUnlockObjectsNV(priv->gl_handle_d3d, 1, &priv->gl_render))
{
msg_Warn(tc->gl, "DXUnlockObjectsNV failed");
return VLC_EGENERIC;
}
const RECT rect = {
.left = 0,
.top = 0,
.right = pic->format.i_visible_width,
.bottom = pic->format.i_visible_height
};
hr = IDirect3DDevice9Ex_StretchRect(priv->d3d_dev.devex, picsys->surface,
&rect, priv->dx_render, NULL, D3DTEXF_NONE);
if (FAILED(hr))
{
msg_Warn(tc->gl, "IDirect3DDevice9Ex_StretchRect failed");
return VLC_EGENERIC;
}
if (!priv->vt.DXLockObjectsNV(priv->gl_handle_d3d, 1, &priv->gl_render))
{
msg_Warn(tc->gl, "DXLockObjectsNV failed");
priv->vt.DXUnregisterObjectNV(priv->gl_handle_d3d, priv->gl_render);
priv->gl_render = NULL;
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
static picture_pool_t *
GLConvGetPool(const opengl_tex_converter_t *tc, unsigned requested_count)
{
struct glpriv *priv = tc->priv;
return Direct3D9CreatePicturePool(VLC_OBJECT(tc->gl), &priv->d3d_dev, NULL,
&tc->fmt, requested_count);
}
static int
GLConvAllocateTextures(const opengl_tex_converter_t *tc, GLuint *textures,
const GLsizei *tex_width, const GLsizei *tex_height)
{
VLC_UNUSED(tex_width); VLC_UNUSED(tex_height);
struct glpriv *priv = tc->priv;
priv->gl_render =
priv->vt.DXRegisterObjectNV(priv->gl_handle_d3d, priv->dx_render,
textures[0], GL_TEXTURE_2D, WGL_ACCESS_WRITE_DISCARD_NV);
if (!priv->gl_render)
{
msg_Warn(tc->gl, "DXRegisterObjectNV failed: %lu", GetLastError());
return VLC_EGENERIC;
}
if (!priv->vt.DXLockObjectsNV(priv->gl_handle_d3d, 1, &priv->gl_render))
{
msg_Warn(tc->gl, "DXLockObjectsNV failed");
priv->vt.DXUnregisterObjectNV(priv->gl_handle_d3d, priv->gl_render);
priv->gl_render = NULL;
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
static void
GLConvClose(vlc_object_t *obj)
{
opengl_tex_converter_t *tc = (void *)obj;
struct glpriv *priv = tc->priv;
if (priv->gl_handle_d3d)
{
if (priv->gl_render)
{
priv->vt.DXUnlockObjectsNV(priv->gl_handle_d3d, 1, &priv->gl_render);
priv->vt.DXUnregisterObjectNV(priv->gl_handle_d3d, priv->gl_render);
}
priv->vt.DXCloseDeviceNV(priv->gl_handle_d3d);
}
if (priv->dx_render)
IDirect3DSurface9_Release(priv->dx_render);
D3D9_ReleaseDevice(&priv->d3d_dev);
D3D9_Destroy(&priv->hd3d);
free(tc->priv);
}
static int
GLConvOpen(vlc_object_t *obj)
{
opengl_tex_converter_t *tc = (void *) obj;
if (tc->fmt.i_chroma != VLC_CODEC_D3D9_OPAQUE
&& tc->fmt.i_chroma != VLC_CODEC_D3D9_OPAQUE_10B)
return VLC_EGENERIC;
if (tc->gl->ext != VLC_GL_EXT_WGL || !tc->gl->wgl.getExtensionsString)
return VLC_EGENERIC;
const char *wglExt = tc->gl->wgl.getExtensionsString(tc->gl);
if (wglExt == NULL || !HasExtension(wglExt, "WGL_NV_DX_interop"))
return VLC_EGENERIC;
struct wgl_vt vt;
#define LOAD_EXT(name, type) do { \
vt.name = (type) vlc_gl_GetProcAddress(tc->gl, "wgl" #name); \
if (!vt.name) { \
msg_Warn(obj, "'wgl " #name "' could not be loaded"); \
return VLC_EGENERIC; \
} \
} while(0)
LOAD_EXT(DXSetResourceShareHandleNV, PFNWGLDXSETRESOURCESHAREHANDLENVPROC);
LOAD_EXT(DXOpenDeviceNV, PFNWGLDXOPENDEVICENVPROC);
LOAD_EXT(DXCloseDeviceNV, PFNWGLDXCLOSEDEVICENVPROC);
LOAD_EXT(DXRegisterObjectNV, PFNWGLDXREGISTEROBJECTNVPROC);
LOAD_EXT(DXUnregisterObjectNV, PFNWGLDXUNREGISTEROBJECTNVPROC);
LOAD_EXT(DXLockObjectsNV, PFNWGLDXLOCKOBJECTSNVPROC);
LOAD_EXT(DXUnlockObjectsNV, PFNWGLDXUNLOCKOBJECTSNVPROC);
struct glpriv *priv = calloc(1, sizeof(struct glpriv));
if (!priv)
return VLC_ENOMEM;
tc->priv = priv;
priv->vt = vt;
if (D3D9_Create(obj, &priv->hd3d) != VLC_SUCCESS)
goto error;
if (!priv->hd3d.use_ex)
{
msg_Warn(obj, "DX/GL interrop only working on d3d9x");
goto error;
}
if (FAILED(D3D9_CreateDevice(obj, &priv->hd3d, tc->gl->surface->handle.hwnd,
&tc->fmt, &priv->d3d_dev)))
goto error;
HRESULT hr;
HANDLE shared_handle = NULL;
hr = IDirect3DDevice9Ex_CreateRenderTarget(priv->d3d_dev.devex,
tc->fmt.i_visible_width,
tc->fmt.i_visible_height,
D3DFMT_X8R8G8B8,
D3DMULTISAMPLE_NONE, 0, FALSE,
&priv->dx_render, &shared_handle);
if (FAILED(hr))
{
msg_Warn(obj, "IDirect3DDevice9_CreateOffscreenPlainSurface failed");
goto error;
}
if (shared_handle)
priv->vt.DXSetResourceShareHandleNV(priv->dx_render, shared_handle);
priv->gl_handle_d3d = priv->vt.DXOpenDeviceNV(priv->d3d_dev.dev);
if (!priv->gl_handle_d3d)
{
msg_Warn(obj, "DXOpenDeviceNV failed: %lu", GetLastError());
goto error;
}
tc->pf_update = GLConvUpdate;
tc->pf_get_pool = GLConvGetPool;
tc->pf_allocate_textures = GLConvAllocateTextures;
tc->fshader = opengl_fragment_shader_init(tc, GL_TEXTURE_2D, VLC_CODEC_RGB32,
COLOR_SPACE_UNDEF);
if (tc->fshader == 0)
goto error;
return VLC_SUCCESS;
error:
GLConvClose(obj);
return VLC_EGENERIC;
}
#endif