[vlc-devel] [RFC v2 8/8] libvlc: use a callback to select the plane to render to

Steve Lhomme robux4 at ycbcr.xyz
Thu May 2 15:28:51 CEST 2019


We can now render to NV12/P010 externally. Only supported by D3D11 rendering.
---
 include/vlc/libvlc_media_player.h | 19 +++++++++++++++++++
 include/vlc_vout_display.h        | 13 +++++++++++++
 lib/media_player.c                |  5 +++++
 3 files changed, 37 insertions(+)

diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h
index 233db673d6..b9c09226a7 100644
--- a/include/vlc/libvlc_media_player.h
+++ b/include/vlc/libvlc_media_player.h
@@ -636,6 +636,10 @@ typedef struct
     libvlc_video_transfer_func_t transfer;        /** video transfer function */
 } libvlc_video_output_cfg_t;
 
+typedef struct
+{
+    size_t plane;
+} libvlc_video_surface_plane_t;
 
 typedef struct
 {
@@ -737,6 +741,21 @@ typedef enum libvlc_video_callback_control_t {
      */
     LIBVLC_VIDEO_START_RENDERING,
 
+    /** Tell the host the rendering for the given plane is about to start
+     *
+     * \ref input const libvlc_video_surface_plane_t*
+     * \ref output ignored
+     *
+     * The host should call OMSetRenderTargets for Direct3D11.
+     *
+     * The number of planes depend on the DXGI_FORMAT returned during the
+     * \ref LIBVLC_VIDEO_UPDATE_OUTPUT call. It's usually one plane except for
+     * semi-planar formats like DXGI_FORMAT_NV12 or DXGI_FORMAT_P010.
+     *
+     * This is only used with \ref libvlc_video_rendering_direct3d11.
+     */
+    LIBVLC_VIDEO_SURFACE_SELECT_PLANE,
+
     /** Tell the host the rendering has ended.
      *
      * \ref input ignored
diff --git a/include/vlc_vout_display.h b/include/vlc_vout_display.h
index b08a35d9e7..b9b1f60c03 100644
--- a/include/vlc_vout_display.h
+++ b/include/vlc_vout_display.h
@@ -497,6 +497,11 @@ typedef struct
     video_transfer_func_t   transfer;
 } video_surface_output_cfg_t; /* must match libvlc_video_surface_cfg_t */
 
+typedef struct
+{
+    size_t plane;
+} vlc_video_surface_plane_t; /* must match libvlc_video_surface_plane_t */
+
 typedef enum
 {
     VLC_VIDEO_SURFACE_DEVICE_SETUP,
@@ -504,6 +509,7 @@ typedef enum
     VLC_VIDEO_SURFACE_UPDATE_OUTPUT,
     VLC_VIDEO_SURFACE_SWAP,
     VLC_VIDEO_SURFACE_START_RENDERING,
+    VLC_VIDEO_SURFACE_SELECT_PLANE,
     VLC_VIDEO_SURFACE_FINISHED_RENDERING,
 } vlc_video_surface_control_t; /* must match libvlc_video_callback_control_t */
 
@@ -544,6 +550,13 @@ static inline bool vlc_video_surface_start_rendering(void *opaque, vlc_video_sur
     return ctrl(opaque, VLC_VIDEO_SURFACE_START_RENDERING, hdr10, NULL) == 0;
 }
 
+static inline bool vlc_video_surface_select_plane(void *opaque, vlc_video_surface_control ctrl,
+                                                  size_t plane)
+{
+    vlc_video_surface_plane_t select = { .plane = plane };
+    return ctrl(opaque, VLC_VIDEO_SURFACE_SELECT_PLANE, &select, NULL) == 0;
+}
+
 static inline void vlc_video_surface_finished_rendering(void *opaque, vlc_video_surface_control ctrl)
 {
     ctrl(opaque, VLC_VIDEO_SURFACE_FINISHED_RENDERING, 0, NULL);
diff --git a/lib/media_player.c b/lib/media_player.c
index 54782e8084..073e58014f 100644
--- a/lib/media_player.c
+++ b/lib/media_player.c
@@ -2095,6 +2095,7 @@ static_assert(VLC_VIDEO_SURFACE_DEVICE_SETUP       == LIBVLC_VIDEO_DEVICE_SETUP
               VLC_VIDEO_SURFACE_UPDATE_OUTPUT      == LIBVLC_VIDEO_UPDATE_OUTPUT &&
               VLC_VIDEO_SURFACE_SWAP               == LIBVLC_VIDEO_SWAP &&
               VLC_VIDEO_SURFACE_START_RENDERING    == LIBVLC_VIDEO_START_RENDERING &&
+              VLC_VIDEO_SURFACE_SELECT_PLANE       == LIBVLC_VIDEO_SURFACE_SELECT_PLANE &&
               VLC_VIDEO_SURFACE_FINISHED_RENDERING == LIBVLC_VIDEO_FINISHED_RENDERING
               , "video surface callback IDs mismatch");
 
@@ -2157,3 +2158,7 @@ static_assert(sizeof(vlc_video_surface_hdr10_metadata_t) == sizeof(libvlc_video_
               offsetof(vlc_video_surface_hdr10_metadata_t, MaxContentLightLevel) == offsetof(libvlc_video_surface_hdr10_metadata_t, MaxContentLightLevel) &&
               offsetof(vlc_video_surface_hdr10_metadata_t, MaxFrameAverageLightLevel)== offsetof(libvlc_video_surface_hdr10_metadata_t, MaxFrameAverageLightLevel)
               , "video surface hdr10 metadata mismatch");
+
+static_assert( sizeof(vlc_video_surface_plane_t) == sizeof(libvlc_video_surface_plane_t) &&
+               offsetof(vlc_video_surface_plane_t, plane) == offsetof(libvlc_video_surface_plane_t, plane)
+               , "video surface plane selection mismatch" );
-- 
2.17.1



More information about the vlc-devel mailing list