<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Thanks for your polite response Thomas - no problem at all.<div class=""><br class=""></div><div class="">Just offering in case it was of interest :)</div><div class=""><br class=""></div><div class="">All the best</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 2 Jul 2017, at 11:26, Thomas Guillem <<a href="mailto:thomas@gllm.fr" class="">thomas@gllm.fr</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">On Sat, Jul 1, 2017, at 14:00, Oliver Collyer wrote:</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">Hello<br class=""><br class="">A little out of left-field this one but I wrote this vout plugin for a<br class="">project I've been working on.<br class=""><br class="">It's kind of similar to vmem in that an application can use this plugin<br class="">to retrieve the decoder/filtered surfaces, but rather than receive a<br class="">system memory copy of the surface (clean but slow) it instead allows<br class="">these surfaces to be passed through directly to the caller. More<br class="">importantly, it supports this for certain hardware formats too -<br class="">currently DXVA2, VideoToolbox and VAAPI. There is no reason why D3D11VA,<br class="">VDPAU etc couldn't be supported in future.<br class=""><br class="">I see this plugin as filling a small niche where an application already<br class="">manages its own devices, contexts, textures etc and wants to embed video<br class="">into this, but without losing the benefits of hardware acceleration.<br class=""><br class="">Im my video streaming application I take these hardware surfaces and use<br class="">them to fill out SDL textures, thus avoiding any GPU-CPU-GPU copies. For<br class="">DXVA2 this is done via StretchRect, for VideoToolbox I used the texture<br class="">cache on both iOS/tvOS and macOS. For VAAPI I use the GLX extension. I<br class="">had to add in a couple of functions to SDL to give deeper access to the<br class="">underling devices/textures/surfaces, but it works very well.<br class=""><br class="">Initially I was hacking these changes into vmem but rather than break<br class="">that interface or get bogged-down trying to support two different methods<br class="">I thought it cleaner to write this as a new plugin.<br class=""><br class="">I understand from jb that there are possible plans in future for a plugin<br class="">that writes to a texture, so maybe my plugin will be redundant, I'm not<br class="">sure, but I'm offering it anyway, in case you want to include it, or in<br class="">case someone wants to use it in their own project.<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Thanks for offering it to the community. I'll keep this patch in a</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">branch. A lot of people already asked us to do something like that. But</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">unfortunately, we won't merge it. As jb already said, we'll add a way to</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">get access to the opengl/direct3D texture for 4.0.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Best regards,</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Thomas.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class=""><br class="">Cheers<br class=""><br class="">Oliver<br class=""><br class="">---<br class="">include/vlc/libvlc_media_player.h | 108 +++++++<br class="">lib/libvlc.sym                    |   1 +<br class="">lib/media_player.c                |  32 ++<br class="">modules/MODULES_LIST              |   1 +<br class="">modules/video_output/Makefile.am  |  33 ++<br class="">modules/video_output/vbridge.c    | 615<br class="">++++++++++++++++++++++++++++++++++++++<br class="">po/POTFILES.in                    |   1 +<br class="">7 files changed, 791 insertions(+)<br class="">create mode 100644 modules/video_output/vbridge.c<br class=""><br class="">diff --git a/include/vlc/libvlc_media_player.h<br class="">b/include/vlc/libvlc_media_player.h<br class="">index 160cdfbaa8..72be05bb9b 100644<br class="">--- a/include/vlc/libvlc_media_player.h<br class="">+++ b/include/vlc/libvlc_media_player.h<br class="">@@ -457,6 +457,114 @@ void libvlc_video_set_format_callbacks(<br class="">libvlc_media_player_t *mp,<br class="">                                        libvlc_video_cleanup_cb cleanup<br class="">                                        );<br class=""><br class="">/**<br class="">+ * Callback prototype to configure format for video bridge output.<br class="">+ *<br class="">+ * This callback gets the format of the video as output by the video<br class="">decoder<br class="">+ * and the chain of video filters (if any). It can opt to change any<br class="">parameter<br class="">+ * as it needs. In that case, LibVLC will attempt to convert the video<br class="">format<br class="">+ * (rescaling and chroma conversion) but these operations can be CPU<br class="">intensive.<br class="">+ *<br class="">+ * The device pointer must be set to a valid D3D9 device in the case of<br class="">DXVA2 or<br class="">+ * a valid VADisplay in the case of VAAPI. This is used by libVLC to<br class="">initialize<br class="">+ * the hardware decoder and create the hardware surfaces that are later<br class="">passed<br class="">+ * to the prepare and display callbacks.<br class="">+ *<br class="">+ * \param opaque pointer to the private pointer passed to<br class="">+ *               libvlc_media_player_set_vbridge_callbacks() [IN/OUT]<br class="">+ * \param chroma pointer to the 4 bytes video format identifier [IN/OUT]<br class="">+ * \param width pointer to the pixel width [IN/OUT]<br class="">+ * \param height pointer to the pixel height [IN/OUT]<br class="">+ * \param x_offset pointer to the pixel x offset [IN/OUT]<br class="">+ * \param y_offset pointer to the pixel y offset [IN/OUT]<br class="">+ * \param visible_width pointer to the pixel visible width [IN/OUT]<br class="">+ * \param visible_height pointer to the pixel visible height [IN/OUT]<br class="">+ * \param device pointer to the platform-specific device pointer [OUT]<br class="">+ *<br class="">+ */<br class="">+typedef void (*libvlc_vbridge_format_cb)(void **opaque, char *chroma,<br class="">+                                         unsigned *width, unsigned<br class="">*height,<br class="">+                                         unsigned *x_offset, unsigned<br class="">*y_offset,<br class="">+                                         unsigned *visible_width,<br class="">+                                         unsigned *visible_height,<br class="">+                                         void **device);<br class="">+<br class="">+/**<br class="">+ * Callback prototype to cleanup resources for video bridge output.<br class="">+ *<br class="">+ * \param opaque private pointer as passed to<br class="">+ *               libvlc_media_player_set_vbridge_callbacks()<br class="">+ *               (and possibly modified by @ref<br class="">libvlc_vbridge_format_cb) [IN]<br class="">+ */<br class="">+typedef void (*libvlc_vbridge_cleanup_cb)(void *opaque);<br class="">+<br class="">+/**<br class="">+ * Callback prototype to prepare a picture for video bridge output.<br class="">+ *<br class="">+ * When the video frame decoding is complete, the prepare callback is<br class="">invoked.<br class="">+ * This callback might not be needed at all. It is only an indication<br class="">that the<br class="">+ * application can now read the pixel values if it needs to.<br class="">+ *<br class="">+ * If the picture is a software surface then planes[] will point to<br class="">system<br class="">+ * memory and pitches[] and lines[] will be valid. The number and layout<br class="">of the<br class="">+ * planes will depend on the chroma.<br class="">+ *<br class="">+ * If the picture is a hardware surface then planes[0] should be cast to<br class="">the<br class="">+ * appropriate type (IDirect3D9Surface, CVPixelBuffer or VASurfaceID)<br class="">and the<br class="">+ * pitches[0] and lines[0] entries will be zero.<br class="">+ *<br class="">+ * \param opaque private pointer as passed to<br class="">+ *               libvlc_media_player_set_vbridge_callbacks()<br class="">+ *               (and possibly modified by @ref<br class="">libvlc_vbridge_format_cb) [IN]<br class="">+ * \param planes start address of the pixel planes[IN]<br class="">+ * \param pitches table of scanline pitches in bytes for each pixel<br class="">plane [IN]<br class="">+ * \param lines table of scanlines count for each plane [IN]<br class="">+ */<br class="">+typedef void (*libvlc_vbridge_prepare_cb)(void *opaque, void *const<br class="">*planes,<br class="">+                                          unsigned *pitches, unsigned<br class="">*lines);<br class="">+<br class="">+/**<br class="">+ * Callback prototype to display a picture for video bridge output.<br class="">+ *<br class="">+ * When the video frame needs to be shown, as determined by the media<br class="">playback<br class="">+ * clock, the display callback is invoked.<br class="">+ *<br class="">+ * If the picture is a software surface then planes[] will point to<br class="">system<br class="">+ * memory and pitches[] and lines[] will be valid. The number and layout<br class="">of the<br class="">+ * planes will depend on the chroma.<br class="">+ *<br class="">+ * If the picture is a hardware surface then planes[0] should be cast to<br class="">the<br class="">+ * appropriate type (IDirect3D9Surface, CVPixelBuffer or VASurfaceID)<br class="">and the<br class="">+ * pitches[0] and lines[0] entries will be zero.<br class="">+ *<br class="">+ * \param opaque private pointer as passed to<br class="">+ *               libvlc_media_player_set_vbridge_callbacks()<br class="">+ *               (and possibly modified by @ref<br class="">libvlc_vbridge_format_cb) [IN]<br class="">+ * \param planes start address of the pixel planes[IN]<br class="">+ * \param pitches table of scanline pitches in bytes for each pixel<br class="">plane [IN]<br class="">+ * \param lines table of scanlines count for each plane [IN]<br class="">+ */<br class="">+typedef void (*libvlc_vbridge_display_cb)(void *opaque, void *const<br class="">*planes,<br class="">+                                          unsigned *pitches, unsigned<br class="">*lines);<br class="">+<br class="">+/**<br class="">+ * Set callbacks and private data for video bridge output.<br class="">+ *<br class="">+ * \param mp the media player<br class="">+ * \param format callback to configure format<br class="">+ * \param cleanup callback to cleanup resources<br class="">+ * \param prepare callback to prepare a picture<br class="">+ * \param display callback to display a picture<br class="">+ * \param opaque private pointer<br class="">+ */<br class="">+LIBVLC_API<br class="">+void libvlc_media_player_set_vbridge_callbacks(libvlc_media_player_t<br class="">*mp,<br class="">+                                               libvlc_vbridge_format_cb<br class="">format,<br class="">+                                               libvlc_vbridge_cleanup_cb<br class="">cleanup,<br class="">+                                               libvlc_vbridge_prepare_cb<br class="">prepare,<br class="">+                                               libvlc_vbridge_display_cb<br class="">display,<br class="">+                                               void *opaque);<br class="">+<br class="">+/**<br class=""> * Set the NSView handler where the media player should render its video<br class=""> output.<br class=""> *<br class=""> * Use the vout called "macosx".<br class="">diff --git a/lib/libvlc.sym b/lib/libvlc.sym<br class="">index caa55981bf..9fb3be8707 100644<br class="">--- a/lib/libvlc.sym<br class="">+++ b/lib/libvlc.sym<br class="">@@ -203,6 +203,7 @@ libvlc_media_player_stop<br class="">libvlc_media_player_will_play<br class="">libvlc_media_player_navigate<br class="">libvlc_media_player_set_video_title_display<br class="">+libvlc_media_player_set_vbridge_callbacks<br class="">libvlc_media_release<br class="">libvlc_media_retain<br class="">libvlc_media_save_meta<br class="">diff --git a/lib/media_player.c b/lib/media_player.c<br class="">index dc17f7765d..9d56402cd7 100644<br class="">--- a/lib/media_player.c<br class="">+++ b/lib/media_player.c<br class="">@@ -693,6 +693,12 @@ libvlc_media_player_new( libvlc_instance_t *instance<br class="">)<br class="">    var_Create (mp, "saturation", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT);<br class="">    var_Create (mp, "gamma", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT);<br class=""><br class="">+    var_Create (mp, "vbridge-format", VLC_VAR_ADDRESS);<br class="">+    var_Create (mp, "vbridge-cleanup", VLC_VAR_ADDRESS);<br class="">+    var_Create (mp, "vbridge-prepare", VLC_VAR_ADDRESS);<br class="">+    var_Create (mp, "vbridge-display", VLC_VAR_ADDRESS);<br class="">+    var_Create (mp, "vbridge-opaque", VLC_VAR_ADDRESS);<br class="">+<br class="">     /* Audio */<br class="">    var_Create (mp, "aout", VLC_VAR_STRING | VLC_VAR_DOINHERIT);<br class="">    var_Create (mp, "audio-device", VLC_VAR_STRING);<br class="">@@ -1115,6 +1121,32 @@ void libvlc_video_set_format(<br class="">libvlc_media_player_t *mp, const char *chroma,<br class="">}<br class=""><br class="">/**************************************************************************<br class="">+ * set_vbridge_callbacks<br class="">+<br class="">**************************************************************************/<br class="">+void libvlc_media_player_set_vbridge_callbacks(libvlc_media_player_t<br class="">*mp,<br class="">+                                               libvlc_vbridge_format_cb<br class="">format,<br class="">+                                               libvlc_vbridge_cleanup_cb<br class="">cleanup,<br class="">+                                               libvlc_vbridge_prepare_cb<br class="">prepare,<br class="">+                                               libvlc_vbridge_display_cb<br class="">display,<br class="">+                                               void *opaque)<br class="">+{<br class="">+    var_SetAddress(mp, "vbridge-format", format);<br class="">+    var_SetAddress(mp, "vbridge-cleanup", cleanup);<br class="">+    var_SetAddress(mp, "vbridge-prepare", prepare);<br class="">+    var_SetAddress(mp, "vbridge-display", display);<br class="">+    var_SetAddress(mp, "vbridge-opaque", opaque);<br class="">+#ifdef _WIN32<br class="">+    var_SetString(mp, "avcodec-hw", "dxva2");<br class="">+#elif defined(__linux__)<br class="">+    var_SetString(mp, "avcodec-hw", "vaapi");<br class="">+#else<br class="">+    var_SetString(mp, "avcodec-hw", "none");<br class="">+#endif<br class="">+    var_SetString(mp, "vout", "vbridge");<br class="">+    var_SetString(mp, "window", "none");<br class="">+}<br class="">+<br class="">+/**************************************************************************<br class=""> * set_nsobject<br class=""> **************************************************************************/<br class="">void libvlc_media_player_set_nsobject( libvlc_media_player_t *p_mi,<br class="">diff --git a/modules/MODULES_LIST b/modules/MODULES_LIST<br class="">index 04468e438d..0db5467123 100644<br class="">--- a/modules/MODULES_LIST<br class="">+++ b/modules/MODULES_LIST<br class="">@@ -421,6 +421,7 @@ $Id$<br class=""> * vaapi_drm: VAAPI hardware-accelerated decoding with drm backend<br class=""> * vaapi_filters: VAAPI hardware-accelerated<br class=""> deinterlacing/adjust/sharpen/chroma filters<br class=""> * vaapi_x11: VAAPI hardware-accelerated decoding with x11 backend<br class="">+ * vbridge: video bridge output<br class=""> * vc1: VC-1 Video demuxer<br class=""> * vcd: input module for accessing Video CDs<br class=""> * vdpau_adjust: VDPAU color adjust video filter<br class="">diff --git a/modules/video_output/Makefile.am<br class="">b/modules/video_output/Makefile.am<br class="">index 2e7c5d8ba7..7407896569 100644<br class="">--- a/modules/video_output/Makefile.am<br class="">+++ b/modules/video_output/Makefile.am<br class="">@@ -440,6 +440,39 @@ vout_LTLIBRARIES += libevas_plugin.la<br class="">endif<br class=""><br class=""><br class="">+### Video Bridge ###<br class="">+libvbridge_plugin_la_SOURCES = video_output/vbridge.c<br class="">+if HAVE_AVCODEC_DXVA2<br class="">+libvbridge_plugin_la_CFLAGS = $(AM_CFLAGS) -DUSE_DXVA2<br class="">+libvbridge_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)'<br class="">+endif<br class="">+if HAVE_OSX<br class="">+libvbridge_plugin_la_SOURCES += codec/vt_utils.c codec/vt_utils.h<br class="">+libvbridge_plugin_la_CFLAGS = $(AM_CFLAGS) -DUSE_VTBOX<br class="">+libvbridge_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)' \<br class="">+       -Wl,-framework,CoreFoundation,-framework,CoreVideo<br class="">+endif<br class="">+if HAVE_IOS<br class="">+libvbridge_plugin_la_SOURCES += codec/vt_utils.c codec/vt_utils.h<br class="">+libvbridge_plugin_la_CFLAGS = $(AM_CFLAGS) -DUSE_VTBOX<br class="">+libvbridge_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)' \<br class="">+       -Wl,-framework,CoreFoundation,-framework,CoreVideo<br class="">+endif<br class="">+if HAVE_TVOS<br class="">+libvbridge_plugin_la_SOURCES += codec/vt_utils.c codec/vt_utils.h<br class="">+libvbridge_plugin_la_CFLAGS = $(AM_CFLAGS) -DUSE_VTBOX<br class="">+libvbridge_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)' \<br class="">+       -Wl,-framework,CoreFoundation,-framework,CoreVideo<br class="">+endif<br class="">+if HAVE_AVCODEC_VAAPI<br class="">+libvbridge_plugin_la_SOURCES += hw/vaapi/vlc_vaapi.c<br class="">hw/vaapi/vlc_vaapi.h<br class="">+libvbridge_plugin_la_CFLAGS = $(AM_CFLAGS) -DUSE_VAAPI<br class="">+libvbridge_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)'<br class="">+libvbridge_plugin_la_LIBADD = $(LIBVA_LIBS) libvlc_vaapi_instance.la<br class="">+endif<br class="">+vout_LTLIBRARIES += libvbridge_plugin.la<br class="">+<br class="">+<br class="">### Common ###<br class=""><br class="">libflaschen_plugin_la_SOURCES = video_output/flaschen.c<br class="">diff --git a/modules/video_output/vbridge.c<br class="">b/modules/video_output/vbridge.c<br class="">new file mode 100644<br class="">index 0000000000..839b51526e<br class="">--- /dev/null<br class="">+++ b/modules/video_output/vbridge.c<br class="">@@ -0,0 +1,615 @@<br class="">+/*****************************************************************************<br class="">+ * vbridge.c: video bridge driver for vlc<br class="">+<br class="">*****************************************************************************<br class="">+ * Copyright (C) 2017 VLC authors and VideoLAN<br class="">+ *<br class="">+ * Authors: Oliver Collyer <<a href="mailto:ovcollyer@mac.com" class="">ovcollyer@mac.com</a>><br class="">+ *<br class="">+ * This program is free software; you can redistribute it and/or modify<br class="">it<br class="">+ * under the terms of the GNU Lesser General Public License as published<br class="">by<br class="">+ * the Free Software Foundation; either version 2.1 of the License, or<br class="">+ * (at your option) any later version.<br class="">+ *<br class="">+ * This program is distributed in the hope that it will be useful,<br class="">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br class="">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br class="">+ * GNU Lesser General Public License for more details.<br class="">+ *<br class="">+ * You should have received a copy of the GNU Lesser General Public<br class="">License<br class="">+ * along with this program; if not, write to the Free Software<br class="">Foundation,<br class="">+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.<br class="">+<br class="">*****************************************************************************/<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Preamble<br class="">+<br class="">*****************************************************************************/<br class="">+#ifdef HAVE_CONFIG_H<br class="">+# include "config.h"<br class="">+#endif<br class="">+<br class="">+#include <assert.h><br class="">+<br class="">+#include <vlc_common.h><br class="">+#include <vlc_plugin.h><br class="">+#include <vlc_vout_display.h><br class="">+#include <vlc_picture_pool.h><br class="">+<br class="">+#ifdef USE_DXVA2<br class="">+#include <d3d9.h><br class="">+#include "../video_chroma/d3d9_fmt.h"<br class="">+#elif defined(USE_VTBOX)<br class="">+#import <CoreVideo/CoreVideo.h><br class="">+#include "../codec/vt_utils.h"<br class="">+#elif defined(USE_VAAPI)<br class="">+#include <va/va.h><br class="">+#include "../hw/vaapi/vlc_vaapi.h"<br class="">+#endif<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Module descriptor<br class="">+<br class="">*****************************************************************************/<br class="">+static int  Open (vlc_object_t *);<br class="">+static void Close(vlc_object_t *);<br class="">+<br class="">+vlc_module_begin()<br class="">+    set_shortname(N_("Video bridge"))<br class="">+    set_description(N_("Video bridge output"))<br class="">+    set_category(CAT_VIDEO)<br class="">+    set_subcategory(SUBCAT_VIDEO_VOUT)<br class="">+    set_capability("vout display", 0)<br class="">+    set_callbacks(Open, Close)<br class="">+vlc_module_end()<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Local prototypes<br class="">+<br class="">*****************************************************************************/<br class="">+struct vout_display_sys_t<br class="">+{<br class="">+    picture_pool_t *pool;<br class="">+    picture_t *prev_pic;<br class="">+    bool hw_surfaces;<br class="">+<br class="">+#ifdef USE_VAAPI<br class="">+    VADisplay dpy;<br class="">+    VABufferID config_id;<br class="">+    VABufferID context_id;<br class="">+#endif<br class="">+<br class="">+    void (*cleanup)(void *);<br class="">+    void (*prepare)(void *, void *const *, unsigned *, unsigned *);<br class="">+    void (*display)(void *, void *const *, unsigned *, unsigned *);<br class="">+    void *opaque;<br class="">+    void *device;<br class="">+};<br class="">+<br class="">+typedef void (*vlc_format_cb)(void **, char *,<br class="">+                              unsigned *, unsigned *,<br class="">+                              unsigned *, unsigned *,<br class="">+                              unsigned *, unsigned *,<br class="">+                              void **);<br class="">+<br class="">+static picture_pool_t *Pool(vout_display_t *, unsigned);<br class="">+static void SoftwareSurfacePrepare(vout_display_t *, picture_t *,<br class="">subpicture_t *);<br class="">+static void SoftwareSurfaceDisplay(vout_display_t *, picture_t *,<br class="">subpicture_t *);<br class="">+static void HardwareSurfacePrepare(vout_display_t *, picture_t *,<br class="">subpicture_t *);<br class="">+static void HardwareSurfaceDisplay(vout_display_t *, picture_t *,<br class="">subpicture_t *);<br class="">+static int Control(vout_display_t *, int, va_list);<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Create the video bridge output<br class="">+<br class="">*****************************************************************************/<br class="">+static int Open(vlc_object_t *object)<br class="">+{<br class="">+    vout_display_t *vd = (vout_display_t *)object;<br class="">+<br class="">+    vlc_format_cb format = var_InheritAddress(vd, "vbridge-format");<br class="">+    if (!format)<br class="">+    {<br class="">+        msg_Err(vd, "Invalid vbridge-format callback");<br class="">+        return VLC_EGENERIC;<br class="">+    }<br class="">+<br class="">+    vout_display_sys_t *sys = calloc(1, sizeof(*sys));<br class="">+    if (unlikely(!sys))<br class="">+        return VLC_ENOMEM;<br class="">+<br class="">+    sys->cleanup = var_InheritAddress(vd, "vbridge-cleanup");<br class="">+    sys->prepare = var_InheritAddress(vd, "vbridge-prepare");<br class="">+    sys->display = var_InheritAddress(vd, "vbridge-display");<br class="">+    sys->opaque  = var_InheritAddress(vd, "vbridge-opaque");<br class="">+<br class="">+#ifdef USE_VAAPI<br class="">+    sys->config_id = VA_INVALID_ID;<br class="">+    sys->context_id = VA_INVALID_ID;<br class="">+#endif<br class="">+<br class="">+    video_format_t fmt;<br class="">+    video_format_ApplyRotation(&fmt, &vd->fmt);<br class="">+<br class="">+    char chroma[5];<br class="">+    memcpy(chroma, &fmt.i_chroma, 4);<br class="">+    chroma[4] = '\0';<br class="">+<br class="">+    format(&sys->opaque,<br class="">+          chroma,<br class="">+          &fmt.i_width, &fmt.i_height,<br class="">+          &fmt.i_x_offset, &fmt.i_y_offset,<br class="">+          &fmt.i_visible_width, &fmt.i_visible_height,<br class="">+          &sys->device);<br class="">+<br class="">+    fmt.i_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, chroma);<br class="">+    if (!fmt.i_chroma)<br class="">+    {<br class="">+        msg_Err(vd, "Invalid chroma requested (%s)", chroma);<br class="">+        free(sys);<br class="">+        return VLC_EGENERIC;<br class="">+    }<br class="">+<br class="">+    switch (fmt.i_chroma)<br class="">+    {<br class="">+    case VLC_CODEC_RGB15:<br class="">+        fmt.i_rmask = 0x001f;<br class="">+        fmt.i_gmask = 0x03e0;<br class="">+        fmt.i_bmask = 0x7c00;<br class="">+        break;<br class="">+    case VLC_CODEC_RGB16:<br class="">+        fmt.i_rmask = 0x001f;<br class="">+        fmt.i_gmask = 0x07e0;<br class="">+        fmt.i_bmask = 0xf800;<br class="">+        break;<br class="">+    case VLC_CODEC_RGB24:<br class="">+    case VLC_CODEC_RGB32:<br class="">+        fmt.i_rmask = 0xff0000;<br class="">+        fmt.i_gmask = 0x00ff00;<br class="">+        fmt.i_bmask = 0x0000ff;<br class="">+        break;<br class="">+    default:<br class="">+        fmt.i_rmask = 0;<br class="">+        fmt.i_gmask = 0;<br class="">+        fmt.i_bmask = 0;<br class="">+        break;<br class="">+    }<br class="">+<br class="">+#ifdef USE_DXVA2<br class="">+    if (vd->fmt.i_chroma == VLC_CODEC_D3D9_OPAQUE ||<br class="">+        vd->fmt.i_chroma == VLC_CODEC_D3D9_OPAQUE_10B)<br class="">+        sys->hw_surfaces = true;<br class="">+#elif defined(USE_VTBOX)<br class="">+    if (vd->fmt.i_chroma == VLC_CODEC_CVPX_UYVY ||<br class="">+        vd->fmt.i_chroma == VLC_CODEC_CVPX_NV12 ||<br class="">+        vd->fmt.i_chroma == VLC_CODEC_CVPX_I420 ||<br class="">+        vd->fmt.i_chroma == VLC_CODEC_CVPX_BGRA)<br class="">+        sys->hw_surfaces = true;<br class="">+#elif defined(USE_VAAPI)<br class="">+    if (vd->fmt.i_chroma == VLC_CODEC_VAAPI_420)<br class="">+        sys->hw_surfaces = true;<br class="">+#endif<br class="">+    if (sys->hw_surfaces)<br class="">+        msg_Dbg(vd, "Using hardware surfaces");<br class="">+<br class="">+    vout_display_info_t info = vd->info;<br class="">+    info.has_hide_mouse = true;<br class="">+<br class="">+    vd->sys     = sys;<br class="">+    vd->fmt     = fmt;<br class="">+    vd->info    = info;<br class="">+    vd->pool    = Pool;<br class="">+    vd->prepare = sys->hw_surfaces ? HardwareSurfacePrepare :<br class="">SoftwareSurfacePrepare;<br class="">+    vd->display = sys->hw_surfaces ? HardwareSurfaceDisplay :<br class="">SoftwareSurfaceDisplay;<br class="">+    vd->control = Control;<br class="">+    vd->manage  = NULL;<br class="">+<br class="">+    vout_display_SendEventDisplaySize(vd, fmt.i_width, fmt.i_height);<br class="">+    vout_display_DeleteWindow(vd, NULL);<br class="">+<br class="">+    return VLC_SUCCESS;<br class="">+}<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Destroy the video bridge output<br class="">+<br class="">*****************************************************************************/<br class="">+static void Close(vlc_object_t *object)<br class="">+{<br class="">+    vout_display_t *vd = (vout_display_t *)object;<br class="">+    vout_display_sys_t *sys = vd->sys;<br class="">+<br class="">+    if (sys->prev_pic)<br class="">+        picture_Release(sys->prev_pic);<br class="">+<br class="">+#ifdef USE_VAAPI<br class="">+    if (sys->context_id != VA_INVALID_ID)<br class="">+        vlc_vaapi_DestroyContext(object, sys->dpy, sys->context_id);<br class="">+#endif<br class="">+    if (sys->pool != NULL)<br class="">+        picture_pool_Release(sys->pool);<br class="">+#ifdef USE_VAAPI<br class="">+    if (sys->config_id != VA_INVALID_ID)<br class="">+        vlc_vaapi_DestroyConfig(object, sys->dpy, sys->config_id);<br class="">+    if (sys->dpy != NULL)<br class="">+        vlc_vaapi_ReleaseInstance(sys->dpy);<br class="">+#endif<br class="">+<br class="">+    if (sys->cleanup)<br class="">+        sys->cleanup(sys->opaque);<br class="">+<br class="">+    free(sys);<br class="">+}<br class="">+<br class="">+#ifdef USE_DXVA2<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Destroy a single DXVA2 picture<br class="">+<br class="">*****************************************************************************/<br class="">+static void DestroyPoolPicture(picture_t *picture)<br class="">+{<br class="">+    picture_sys_t *p_sys = (picture_sys_t *)picture->p_sys;<br class="">+<br class="">+    if (p_sys->surface)<br class="">+        IDirect3DSurface9_Release(p_sys->surface);<br class="">+    free(p_sys);<br class="">+    free(picture);<br class="">+}<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Create the DXVA2 picture pool<br class="">+<br class="">*****************************************************************************/<br class="">+static picture_pool_t *Pool(vout_display_t *vd, unsigned count)<br class="">+{<br class="">+    vout_display_sys_t *sys = vd->sys;<br class="">+<br class="">+    if (sys->pool != NULL)<br class="">+        return sys->pool;<br class="">+<br class="">+    if (!sys->hw_surfaces)<br class="">+    {<br class="">+        sys->pool = picture_pool_NewFromFormat(&vd->fmt, count);<br class="">+        return sys->pool;<br class="">+    }<br class="">+<br class="">+    LPDIRECT3DDEVICE9 d3ddev = (LPDIRECT3DDEVICE9)sys->device;<br class="">+    if (!d3ddev)<br class="">+    {<br class="">+       msg_Err(vd, "Invalid D3D9 display device");<br class="">+       return NULL;<br class="">+    }<br class="">+<br class="">+    D3DFORMAT format;<br class="">+    switch (vd->fmt.i_chroma)<br class="">+    {<br class="">+    case VLC_CODEC_D3D9_OPAQUE_10B:<br class="">+        format = MAKEFOURCC('P','0','1','0');<br class="">+        break;<br class="">+    default:<br class="">+        format = MAKEFOURCC('N','V','1','2');<br class="">+        break;<br class="">+    }<br class="">+<br class="">+    picture_t** pictures = calloc(count, sizeof(*pictures));<br class="">+    if (unlikely(!pictures))<br class="">+        goto error;<br class="">+<br class="">+    for (unsigned int i = 0; i < count; i++)<br class="">+    {<br class="">+        picture_sys_t *picsys = calloc(1, sizeof(*picsys));<br class="">+        if (unlikely(!picsys))<br class="">+            goto error;<br class="">+<br class="">+        HRESULT hr =<br class="">IDirect3DDevice9_CreateOffscreenPlainSurface(d3ddev,<br class="">+                                                             <br class="">vd->fmt.i_width,<br class="">+                                                             <br class="">vd->fmt.i_height,<br class="">+                                                              format,<br class="">+                                                             <br class="">D3DPOOL_DEFAULT,<br class="">+                                                             <br class="">&picsys->surface,<br class="">+                                                              NULL);<br class="">+        if (FAILED(hr))<br class="">+        {<br class="">+            msg_Err(vd, "Failed to create D3D9 surface");<br class="">+            free(picsys);<br class="">+            goto error;<br class="">+        }<br class="">+<br class="">+        picture_resource_t picture_resource;<br class="">+        picture_resource.p_sys = picsys;<br class="">+        picture_resource.pf_destroy = DestroyPoolPicture;<br class="">+<br class="">+        picture_t *picture = picture_NewFromResource(&vd->fmt,<br class="">&picture_resource);<br class="">+        if (unlikely(picture == NULL))<br class="">+        {<br class="">+            free(picsys);<br class="">+            goto error;<br class="">+        }<br class="">+<br class="">+        pictures[i] = picture;<br class="">+    }<br class="">+<br class="">+    picture_pool_configuration_t pool_config;<br class="">+    memset(&pool_config, 0, sizeof(pool_config));<br class="">+    pool_config.picture_count = count;<br class="">+    pool_config.picture = pictures;<br class="">+<br class="">+    sys->pool = picture_pool_NewExtended(&pool_config);<br class="">+    if (!sys->pool)<br class="">+    {<br class="">+        msg_Err(vd, "Failed to create picture pool");<br class="">+        goto error;<br class="">+    }<br class="">+<br class="">+    return sys->pool;<br class="">+<br class="">+error:<br class="">+    if (pictures)<br class="">+    {<br class="">+        for (unsigned int i = 0; i < count; i++)<br class="">+            if (pictures[i])<br class="">+                DestroyPoolPicture(pictures[i]);<br class="">+        free(pictures);<br class="">+    }<br class="">+<br class="">+    return NULL;<br class="">+}<br class="">+<br class="">+#elif defined(USE_VAAPI)<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Create the VAAPI picture pool<br class="">+<br class="">*****************************************************************************/<br class="">+static picture_pool_t *Pool(vout_display_t *vd, unsigned count)<br class="">+{<br class="">+    vout_display_sys_t *sys = vd->sys;<br class="">+    vlc_object_t *o = VLC_OBJECT(vd);<br class="">+<br class="">+    if (sys->pool != NULL)<br class="">+        return sys->pool;<br class="">+<br class="">+    if (!sys->hw_surfaces)<br class="">+    {<br class="">+        sys->pool = picture_pool_NewFromFormat(&vd->fmt, count);<br class="">+        return sys->pool;<br class="">+    }<br class="">+<br class="">+    sys->dpy = (VADisplay)sys->device;<br class="">+    if (!sys->dpy)<br class="">+    {<br class="">+        msg_Err(vd, "Invalid VAAPI display device");<br class="">+        return NULL;<br class="">+    }<br class="">+<br class="">+    if (vlc_vaapi_Initialize(o, sys->dpy))<br class="">+    {<br class="">+        msg_Err(vd, "Failed to initialize VAAPI");<br class="">+        sys->dpy = NULL;<br class="">+        goto error;<br class="">+    }<br class="">+<br class="">+    if (vlc_vaapi_SetInstance(sys->dpy))<br class="">+    {<br class="">+        msg_Err(vd, "Failed to set VAAPI instance");<br class="">+        sys->dpy = NULL;<br class="">+        goto error;<br class="">+    }<br class="">+<br class="">+    sys->config_id = vlc_vaapi_CreateConfigChecked(o, sys->dpy,<br class="">VAProfileNone,<br class="">+                                                  <br class="">VAEntrypointVideoProc, 0);<br class="">+    if (sys->config_id == VA_INVALID_ID)<br class="">+    {<br class="">+        msg_Err(vd, "Failed to create VAAPI config");<br class="">+        goto error;<br class="">+    }<br class="">+<br class="">+    VASurfaceID *surfaces;<br class="">+    sys->pool = vlc_vaapi_PoolNew(o, sys->dpy, count, &surfaces,<br class="">&vd->fmt,<br class="">+                                  VA_RT_FORMAT_YUV420, 0);<br class="">+    if (!sys->pool)<br class="">+    {<br class="">+        msg_Err(vd, "Failed to create VAAPI pool");<br class="">+        goto error;<br class="">+    }<br class="">+<br class="">+    sys->context_id = vlc_vaapi_CreateContext(o, sys->dpy,<br class="">sys->config_id,<br class="">+                                              vd->fmt.i_width,<br class="">vd->fmt.i_height,<br class="">+                                              VA_PROGRESSIVE, surfaces,<br class="">count);<br class="">+    if (sys->context_id == VA_INVALID_ID)<br class="">+    {<br class="">+        msg_Err(vd, "Failed to create VAAPI context");<br class="">+        goto error;<br class="">+    }<br class="">+<br class="">+    return sys->pool;<br class="">+<br class="">+error:<br class="">+    if (sys->context_id != VA_INVALID_ID)<br class="">+        vlc_vaapi_DestroyContext(o, sys->dpy, sys->context_id);<br class="">+    if (sys->pool != NULL)<br class="">+        picture_pool_Release(sys->pool);<br class="">+    if (sys->config_id != VA_INVALID_ID)<br class="">+        vlc_vaapi_DestroyConfig(o, sys->dpy, sys->config_id);<br class="">+    if (sys->dpy != NULL)<br class="">+        vlc_vaapi_ReleaseInstance(sys->dpy);<br class="">+<br class="">+    return NULL;<br class="">+}<br class="">+<br class="">+#else<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Create the generic picture pool<br class="">+<br class="">*****************************************************************************/<br class="">+static picture_pool_t *Pool(vout_display_t *vd, unsigned count)<br class="">+{<br class="">+    vout_display_sys_t *sys = vd->sys;<br class="">+<br class="">+    if (sys->pool != NULL)<br class="">+        return sys->pool;<br class="">+<br class="">+    sys->pool = picture_pool_NewFromFormat(&vd->fmt, count);<br class="">+<br class="">+    return sys->pool;<br class="">+}<br class="">+<br class="">+#endif<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Call the software surface prepare<br class="">+<br class="">*****************************************************************************/<br class="">+static void SoftwareSurfacePrepare(vout_display_t *vd, picture_t *pic,<br class="">subpicture_t *subpic)<br class="">+{<br class="">+    vout_display_sys_t *sys = vd->sys;<br class="">+<br class="">+    if (sys->prepare != NULL)<br class="">+    {<br class="">+        void *planes[PICTURE_PLANE_MAX];<br class="">+        unsigned pitches[PICTURE_PLANE_MAX];<br class="">+        unsigned lines[PICTURE_PLANE_MAX];<br class="">+        for (unsigned int i = 0; i < PICTURE_PLANE_MAX; i++)<br class="">+        {<br class="">+            if (i < (unsigned int)pic->i_planes)<br class="">+            {<br class="">+                plane_t *p_src = pic->p+i;<br class="">+                planes[i] = p_src->p_pixels;<br class="">+                pitches[i] = p_src->i_pitch;<br class="">+                lines[i] = p_src->i_lines;<br class="">+            }<br class="">+            else<br class="">+            {<br class="">+                planes[i] = NULL;<br class="">+                pitches[i] = 0;<br class="">+                lines[i] = 0;<br class="">+            }<br class="">+        }<br class="">+        sys->prepare(sys->opaque, planes, pitches, lines);<br class="">+    }<br class="">+<br class="">+    VLC_UNUSED(subpic);<br class="">+}<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Call the software surface display<br class="">+<br class="">*****************************************************************************/<br class="">+static void SoftwareSurfaceDisplay(vout_display_t *vd, picture_t *pic,<br class="">subpicture_t *subpic)<br class="">+{<br class="">+    vout_display_sys_t *sys = vd->sys;<br class="">+<br class="">+    if (sys->display != NULL)<br class="">+    {<br class="">+        void *planes[PICTURE_PLANE_MAX];<br class="">+        unsigned pitches[PICTURE_PLANE_MAX];<br class="">+        unsigned lines[PICTURE_PLANE_MAX];<br class="">+        for (unsigned int i = 0; i < PICTURE_PLANE_MAX; i++)<br class="">+        {<br class="">+            if (i < (unsigned int)pic->i_planes)<br class="">+            {<br class="">+                plane_t *p_src = pic->p+i;<br class="">+                planes[i] = p_src->p_pixels;<br class="">+                pitches[i] = p_src->i_pitch;<br class="">+                lines[i] = p_src->i_lines;<br class="">+            }<br class="">+            else<br class="">+            {<br class="">+                planes[i] = NULL;<br class="">+                pitches[i] = 0;<br class="">+                lines[i] = 0;<br class="">+            }<br class="">+        }<br class="">+        sys->display(sys->opaque, planes, pitches, lines);<br class="">+    }<br class="">+<br class="">+    if (sys->prev_pic)<br class="">+        picture_Release(sys->prev_pic);<br class="">+    sys->prev_pic = pic;<br class="">+<br class="">+    VLC_UNUSED(subpic);<br class="">+}<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Call the hardware surface prepare<br class="">+<br class="">*****************************************************************************/<br class="">+static void HardwareSurfacePrepare(vout_display_t *vd, picture_t *pic,<br class="">subpicture_t *subpic)<br class="">+{<br class="">+    vout_display_sys_t *sys = vd->sys;<br class="">+<br class="">+    if (sys->prepare)<br class="">+    {<br class="">+        void *planes[PICTURE_PLANE_MAX];<br class="">+        unsigned pitches[PICTURE_PLANE_MAX];<br class="">+        unsigned lines[PICTURE_PLANE_MAX];<br class="">+        for (unsigned int i = 0; i < PICTURE_PLANE_MAX; i++)<br class="">+        {<br class="">+            if (i == 0)<br class="">+            {<br class="">+#ifdef USE_DXVA2<br class="">+                if (pic->context)<br class="">+                    planes[i] = (void*)((struct<br class="">va_pic_context*)pic->context)->picsys.surface;<br class="">+                else<br class="">+                    planes[i] = (void*)pic->p_sys->surface;<br class="">+#elif defined(USE_VTBOX)<br class="">+                planes[i] = (void*)cvpxpic_get_ref(pic);<br class="">+#elif defined(USE_VAAPI)<br class="">+                planes[i] =<br class="">(void*)(uintptr_t)vlc_vaapi_PicGetSurface(pic);<br class="">+#else<br class="">+                planes[i] = NULL;<br class="">+#endif<br class="">+            }<br class="">+            else<br class="">+                planes[i] = NULL;<br class="">+            pitches[i] = 0;<br class="">+            lines[i] = 0;<br class="">+        }<br class="">+        sys->prepare(sys->opaque, planes, pitches, lines);<br class="">+    }<br class="">+<br class="">+    VLC_UNUSED(subpic);<br class="">+}<br class="">+<br class="">+/*****************************************************************************<br class="">+ * Call the hardware surface display<br class="">+<br class="">*****************************************************************************/<br class="">+static void HardwareSurfaceDisplay(vout_display_t *vd, picture_t *pic,<br class="">subpicture_t *subpic)<br class="">+{<br class="">+    vout_display_sys_t *sys = vd->sys;<br class="">+<br class="">+    if (sys->display)<br class="">+    {<br class="">+        void *planes[PICTURE_PLANE_MAX];<br class="">+        unsigned pitches[PICTURE_PLANE_MAX];<br class="">+        unsigned lines[PICTURE_PLANE_MAX];<br class="">+        for (unsigned int i = 0; i < PICTURE_PLANE_MAX; i++)<br class="">+        {<br class="">+            if (i == 0)<br class="">+            {<br class="">+#ifdef USE_DXVA2<br class="">+                if (pic->context)<br class="">+                    planes[i] = (void*)((struct<br class="">va_pic_context*)pic->context)->picsys.surface;<br class="">+                else<br class="">+                    planes[i] = (void*)pic->p_sys->surface;<br class="">+#elif defined(USE_VTBOX)<br class="">+                planes[i] = (void*)cvpxpic_get_ref(pic);<br class="">+#elif defined(USE_VAAPI)<br class="">+                planes[i] =<br class="">(void*)(uintptr_t)vlc_vaapi_PicGetSurface(pic);<br class="">+#else<br class="">+                planes[i] = NULL;<br class="">+#endif<br class="">+            }<br class="">+            else<br class="">+                planes[i] = NULL;<br class="">+            pitches[i] = 0;<br class="">+            lines[i] = 0;<br class="">+        }<br class="">+        sys->display(sys->opaque, planes, pitches, lines);<br class="">+    }<br class="">+<br class="">+    if (sys->prev_pic)<br class="">+        picture_Release(sys->prev_pic);<br class="">+    sys->prev_pic = pic;<br class="">+<br class="">+    VLC_UNUSED(subpic);<br class="">+}<br class="">+<br class="">+/* */<br class="">+static int Control(vout_display_t *vd, int query, va_list args)<br class="">+{<br class="">+    VLC_UNUSED(vd);<br class="">+    VLC_UNUSED(query);<br class="">+    VLC_UNUSED(args);<br class="">+<br class="">+    return VLC_EGENERIC;<br class="">+}<br class="">diff --git a/po/POTFILES.in b/po/POTFILES.in<br class="">index 66ea2ddf6d..3197106a26 100644<br class="">--- a/po/POTFILES.in<br class="">+++ b/po/POTFILES.in<br class="">@@ -1138,6 +1138,7 @@ modules/video_output/win32/events.c<br class="">modules/video_output/win32/glwin32.c<br class="">modules/video_output/win32/wingdi.c<br class="">modules/video_output/sdl.c<br class="">+modules/video_output/vbridge.c<br class="">modules/video_output/vdummy.c<br class="">modules/video_output/vmem.c<br class="">modules/video_output/wayland/shell.c<br class="">--<span class="Apple-converted-space"> </span><br class="">2.11.0<br class=""><br class="">_______________________________________________<br class="">vlc-devel mailing list<br class="">To unsubscribe or modify your subscription options:<br class=""><a href="https://mailman.videolan.org/listinfo/vlc-devel" class="">https://mailman.videolan.org/listinfo/vlc-devel</a></blockquote></div></blockquote></div><br class=""></div></body></html>