[vlc-devel] [PATCH] core: add a callback to init/release data for picture pool of opaque formats

Steve Lhomme robux4 at videolabs.io
Mon Apr 20 15:25:32 CEST 2015


a gargabe collector callback is introduced for the global release after all pictures are released from the pool
--
This is needed by DXVA so that D3D9 surfaces can be allocated with the right D3D9 device so that surfaces coming from the decoder can be copied to surfaces of the display pool

The gc in DXVA is used to remove a reference to the D3D9 device and free some memory allocated for the picture_pool_setup_sys_t
---
 include/vlc_aout.h                    |  4 +++-
 include/vlc_codec.h                   |  2 ++
 include/vlc_common.h                  |  1 +
 include/vlc_picture_pool.h            | 26 ++++++++++++++++++++++++++
 include/vlc_vout.h                    |  1 +
 include/vlc_vout_display.h            |  2 ++
 modules/codec/avcodec/dxva2.c         |  2 +-
 modules/codec/avcodec/va.h            |  7 ++++---
 modules/codec/avcodec/video.c         |  4 ++--
 modules/visualization/goom.c          |  6 +++---
 modules/visualization/visual/visual.c |  8 ++++----
 src/audio_output/aout_internal.h      |  2 +-
 src/audio_output/filters.c            |  5 +++--
 src/input/decoder.c                   | 10 ++++++----
 src/input/resource.c                  | 24 ++++++++++++++----------
 src/input/resource.h                  |  5 ++++-
 src/misc/picture_pool.c               |  6 ++++++
 src/video_output/video_output.c       | 18 +++++++++++++++++-
 src/video_output/vout_internal.h      |  1 +
 src/video_output/vout_wrapper.c       | 17 +++++++++++++----
 20 files changed, 114 insertions(+), 37 deletions(-)

diff --git a/include/vlc_aout.h b/include/vlc_aout.h
index 032157f..ef258b7 100644
--- a/include/vlc_aout.h
+++ b/include/vlc_aout.h
@@ -334,6 +334,8 @@ VLC_API void aout_FiltersDelete(vlc_object_t *, aout_filters_t *);
 VLC_API bool aout_FiltersAdjustResampling(aout_filters_t *, int);
 VLC_API block_t *aout_FiltersPlay(aout_filters_t *, block_t *, int rate);
 
-VLC_API vout_thread_t * aout_filter_RequestVout( filter_t *, vout_thread_t *p_vout, video_format_t *p_fmt );
+VLC_API vout_thread_t * aout_filter_RequestVout( filter_t *, vout_thread_t *p_vout,
+                                                 video_format_t *p_fmt,
+                                                 picture_pool_setup_t *p_pool_setup );
 
 #endif /* VLC_AOUT_H */
diff --git a/include/vlc_codec.h b/include/vlc_codec.h
index 8f33165..1d3ee68 100644
--- a/include/vlc_codec.h
+++ b/include/vlc_codec.h
@@ -28,6 +28,7 @@
 #include <vlc_es.h>
 #include <vlc_picture.h>
 #include <vlc_subpicture.h>
+#include <vlc_picture_pool.h>
 
 /**
  * \file
@@ -62,6 +63,7 @@ struct decoder_t
 
     /* Output format of decoder/packetizer */
     es_format_t         fmt_out;
+    picture_pool_setup_t fmt_out_pool_setup;
 
     /* Some decoders only accept packetized data (ie. not truncated) */
     bool                b_need_packetized;
diff --git a/include/vlc_common.h b/include/vlc_common.h
index 98d91fc..b221724 100644
--- a/include/vlc_common.h
+++ b/include/vlc_common.h
@@ -242,6 +242,7 @@ typedef struct video_format_t video_format_t;
 typedef struct subs_format_t subs_format_t;
 typedef struct es_format_t es_format_t;
 typedef struct video_palette_t video_palette_t;
+typedef struct picture_pool_setup_t picture_pool_setup_t;
 
 /* Audio */
 typedef struct audio_output audio_output_t;
diff --git a/include/vlc_picture_pool.h b/include/vlc_picture_pool.h
index a0cf9f3..b33acf9 100644
--- a/include/vlc_picture_pool.h
+++ b/include/vlc_picture_pool.h
@@ -37,17 +37,43 @@
 typedef struct picture_pool_t picture_pool_t;
 
 /**
+ * Picture pool destroy callback
+ */
+typedef struct
+{
+    void *p_sys;
+    void (*pf_destroy)(void *);
+} picture_pool_gc_t;
+
+/**
  * Picture pool configuration
  */
 typedef struct {
     unsigned  picture_count;
     picture_t *const *picture;
 
+    picture_pool_gc_t gc;
+
     int       (*lock)(picture_t *);
     void      (*unlock)(picture_t *);
 } picture_pool_configuration_t;
 
 /**
+ * Private type for picture_pool_setup_t
+ */
+typedef struct picture_pool_setup_sys_t picture_pool_setup_sys_t;
+
+/**
+ * Callback set by the decoder to do special processing when a picture_pool_t
+  * is created.
+ */
+struct picture_pool_setup_t
+{
+    picture_pool_configuration_t *(*pf_create_config) (picture_pool_setup_sys_t *p_sys, const video_format_t *fmt, unsigned count);
+    picture_pool_setup_sys_t     *p_sys;
+};
+
+/**
  * Creates a pool of preallocated pictures. Free pictures can be allocated from
  * the pool, and are returned to the pool when they are no longer referenced.
  *
diff --git a/include/vlc_vout.h b/include/vlc_vout.h
index 50ef135..7b6c821 100644
--- a/include/vlc_vout.h
+++ b/include/vlc_vout.h
@@ -56,6 +56,7 @@ typedef struct {
     bool                 change_fmt;
     const video_format_t *fmt;
     unsigned             dpb_size;
+    picture_pool_setup_t *p_pool_setup;
 } vout_configuration_t;
 
 /**
diff --git a/include/vlc_vout_display.h b/include/vlc_vout_display.h
index a95f98d..285c47b 100644
--- a/include/vlc_vout_display.h
+++ b/include/vlc_vout_display.h
@@ -110,6 +110,8 @@ typedef struct {
         int den;
     } zoom;
 
+    picture_pool_setup_t *p_pool_setup;
+
 } vout_display_cfg_t;
 
 /**
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index dc2e418..23f575a 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -376,7 +376,7 @@ static void DxCreateVideoConversion(vlc_va_sys_t *);
 static void DxDestroyVideoConversion(vlc_va_sys_t *);
 
 /* */
-static int Setup(vlc_va_t *va, AVCodecContext *avctx, vlc_fourcc_t *chroma)
+static int Setup(vlc_va_t *va, AVCodecContext *avctx, vlc_fourcc_t *chroma, picture_pool_setup_t *output_init)
 {
     vlc_va_sys_t *sys = va->sys;
 
diff --git a/modules/codec/avcodec/va.h b/modules/codec/avcodec/va.h
index 64dca01..dc61904 100644
--- a/modules/codec/avcodec/va.h
+++ b/modules/codec/avcodec/va.h
@@ -37,7 +37,7 @@ struct vlc_va_t {
     const char *description;
     int pix_fmt;
 
-    int  (*setup)(vlc_va_t *, AVCodecContext *, vlc_fourcc_t *output);
+    int  (*setup)(vlc_va_t *, AVCodecContext *, vlc_fourcc_t *output, picture_pool_setup_t *output_setup);
     int  (*get)(vlc_va_t *, void **opaque, uint8_t **data);
     void (*release)(void *opaque, uint8_t *surface);
     int  (*extract)(vlc_va_t *, picture_t *dst, void *opaque, uint8_t *data);
@@ -58,9 +58,10 @@ vlc_va_t *vlc_va_New(vlc_object_t *obj, AVCodecContext *, const es_format_t *fmt
  * @return VLC_SUCCESS on success, otherwise an error code.
  */
 static inline int vlc_va_Setup(vlc_va_t *va, AVCodecContext *avctx,
-                               vlc_fourcc_t *output)
+                               vlc_fourcc_t *output,
+                               picture_pool_setup_t *output_setup)
 {
-    return va->setup(va, avctx, output);
+    return va->setup(va, avctx, output, output_setup);
 }
 
 /**
diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index 381fe62..fbbd719 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -966,7 +966,7 @@ static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame,
     decoder_sys_t *sys = dec->p_sys;
     vlc_va_t *va = sys->p_va;
 
-    if (vlc_va_Setup(va, ctx, &dec->fmt_out.video.i_chroma))
+    if (vlc_va_Setup(va, ctx, &dec->fmt_out.video.i_chroma, &dec->fmt_out_pool_setup))
     {
         msg_Err(dec, "hardware acceleration setup failed");
         return -1;
@@ -1352,7 +1352,7 @@ static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
         /* We try to call vlc_va_Setup when possible to detect errors when
          * possible (later is too late) */
         if( p_context->width > 0 && p_context->height > 0
-         && vlc_va_Setup( p_va, p_context, &p_dec->fmt_out.video.i_chroma ) )
+         && vlc_va_Setup( p_va, p_context, &p_dec->fmt_out.video.i_chroma, &p_dec->fmt_out_pool_setup ) )
         {
             msg_Err( p_dec, "acceleration setup failure" );
             break;
diff --git a/modules/visualization/goom.c b/modules/visualization/goom.c
index a57da5b..cc34cad 100644
--- a/modules/visualization/goom.c
+++ b/modules/visualization/goom.c
@@ -135,7 +135,7 @@ static int Open( vlc_object_t *p_this )
     fmt.i_chroma = VLC_CODEC_RGB32;
     fmt.i_sar_num = fmt.i_sar_den = 1;
 
-    p_thread->p_vout = aout_filter_RequestVout( p_filter, NULL, &fmt );
+    p_thread->p_vout = aout_filter_RequestVout( p_filter, NULL, &fmt, NULL );
     if( p_thread->p_vout == NULL )
     {
         msg_Err( p_filter, "no suitable vout module" );
@@ -162,7 +162,7 @@ static int Open( vlc_object_t *p_this )
         msg_Err( p_filter, "cannot lauch goom thread" );
         vlc_mutex_destroy( &p_thread->lock );
         vlc_cond_destroy( &p_thread->wait );
-        aout_filter_RequestVout( p_filter, p_thread->p_vout, NULL );
+        aout_filter_RequestVout( p_filter, p_thread->p_vout, NULL, NULL );
         free( p_thread );
         free( p_sys );
         return VLC_EGENERIC;
@@ -366,7 +366,7 @@ static void Close( vlc_object_t *p_this )
     vlc_join( p_sys->p_thread->thread, NULL );
 
     /* Free data */
-    aout_filter_RequestVout( p_filter, p_sys->p_thread->p_vout, NULL );
+    aout_filter_RequestVout( p_filter, p_sys->p_thread->p_vout, NULL, NULL );
     vlc_mutex_destroy( &p_sys->p_thread->lock );
     vlc_cond_destroy( &p_sys->p_thread->wait );
 
diff --git a/modules/visualization/visual/visual.c b/modules/visualization/visual/visual.c
index 5ce328d..30b5d99 100644
--- a/modules/visualization/visual/visual.c
+++ b/modules/visualization/visual/visual.c
@@ -299,7 +299,7 @@ static int Open( vlc_object_t *p_this )
         .i_sar_num = 1,
         .i_sar_den = 1,
     };
-    p_sys->p_vout = aout_filter_RequestVout( p_filter, NULL, &fmt );
+    p_sys->p_vout = aout_filter_RequestVout( p_filter, NULL, &fmt, NULL );
     if( p_sys->p_vout == NULL )
     {
         msg_Err( p_filter, "no suitable vout module" );
@@ -309,7 +309,7 @@ static int Open( vlc_object_t *p_this )
     p_sys->fifo = block_FifoNew();
     if( unlikely( p_sys->fifo == NULL ) )
     {
-        aout_filter_RequestVout( p_filter, p_sys->p_vout, NULL );
+        aout_filter_RequestVout( p_filter, p_sys->p_vout, NULL, NULL );
         goto error;
     }
 
@@ -317,7 +317,7 @@ static int Open( vlc_object_t *p_this )
                    VLC_THREAD_PRIORITY_VIDEO ) )
     {
         block_FifoRelease( p_sys->fifo );
-        aout_filter_RequestVout( p_filter, p_sys->p_vout, NULL );
+        aout_filter_RequestVout( p_filter, p_sys->p_vout, NULL, NULL );
         goto error;
     }
 
@@ -403,7 +403,7 @@ static void Close( vlc_object_t *p_this )
     vlc_cancel( p_sys->thread );
     vlc_join( p_sys->thread, NULL );
     block_FifoRelease( p_sys->fifo );
-    aout_filter_RequestVout( p_filter, p_filter->p_sys->p_vout, NULL );
+    aout_filter_RequestVout( p_filter, p_filter->p_sys->p_vout, NULL, NULL );
 
     /* Free the list */
     for( int i = 0; i < p_sys->i_effect; i++ )
diff --git a/src/audio_output/aout_internal.h b/src/audio_output/aout_internal.h
index ec729fb..3b31c63 100644
--- a/src/audio_output/aout_internal.h
+++ b/src/audio_output/aout_internal.h
@@ -38,7 +38,7 @@ enum {
 struct aout_request_vout
 {
     struct vout_thread_t  *(*pf_request_vout)( void *, struct vout_thread_t *,
-                                               video_format_t *, bool );
+                                               video_format_t *, picture_pool_setup_t *, bool );
     void *p_private;
 };
 
diff --git a/src/audio_output/filters.c b/src/audio_output/filters.c
index 74c5a6a..04febef 100644
--- a/src/audio_output/filters.c
+++ b/src/audio_output/filters.c
@@ -311,7 +311,8 @@ static int VisualizationCallback (vlc_object_t *obj, const char *var,
 }
 
 vout_thread_t *aout_filter_RequestVout (filter_t *filter, vout_thread_t *vout,
-                                        video_format_t *fmt)
+                                        video_format_t *fmt,
+                                        picture_pool_setup_t *p_pool_setup)
 {
     /* NOTE: This only works from aout_filters_t.
      * If you want to use visualization filters from another place, you will
@@ -324,7 +325,7 @@ vout_thread_t *aout_filter_RequestVout (filter_t *filter, vout_thread_t *vout,
     bool recycle = false;
     free (visual);
 
-    return req->pf_request_vout (req->p_private, vout, fmt, recycle);
+    return req->pf_request_vout (req->p_private, vout, fmt, p_pool_setup, recycle);
 }
 
 static int AppendFilter(vlc_object_t *obj, const char *type, const char *name,
diff --git a/src/input/decoder.c b/src/input/decoder.c
index 79a83c1..2c9f172 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -188,14 +188,15 @@ static block_t *DecoderBlockFlushNew()
  * Buffers allocation callbacks for the decoders
  *****************************************************************************/
 static vout_thread_t *aout_request_vout( void *p_private,
-                                         vout_thread_t *p_vout, video_format_t *p_fmt, bool b_recyle )
+                                         vout_thread_t *p_vout, video_format_t *p_fmt,
+                                         picture_pool_setup_t *p_pool_setup, bool b_recyle )
 {
     decoder_t *p_dec = p_private;
     decoder_owner_sys_t *p_owner = p_dec->p_owner;
     input_thread_t *p_input = p_owner->p_input;
 
-    p_vout = input_resource_RequestVout( p_owner->p_resource, p_vout, p_fmt, 1,
-                                         b_recyle );
+    p_vout = input_resource_RequestVout( p_owner->p_resource, p_vout, p_fmt,
+                                         p_pool_setup, 1, b_recyle );
     if( p_input != NULL )
         input_SendEventVout( p_input );
 
@@ -400,6 +401,7 @@ static int vout_update_format( decoder_t *p_dec )
         }
         p_vout = input_resource_RequestVout( p_owner->p_resource,
                                              p_vout, &fmt,
+                                             &p_dec->fmt_out_pool_setup,
                                              dpb_size +
                                              p_dec->i_extra_picture_buffers + 1,
                                              true );
@@ -1670,7 +1672,7 @@ static void DeleteDecoder( decoder_t * p_dec )
 
         /* */
         input_resource_RequestVout( p_owner->p_resource, p_owner->p_vout, NULL,
-                                    0, true );
+                                    &p_dec->fmt_out_pool_setup, 0, true );
         if( p_owner->p_input != NULL )
             input_SendEventVout( p_owner->p_input );
     }
diff --git a/src/input/resource.c b/src/input/resource.c
index 3440288..0b5b8f2 100644
--- a/src/input/resource.c
+++ b/src/input/resource.c
@@ -193,8 +193,9 @@ static void DisplayVoutTitle( input_resource_t *p_resource,
 }
 static vout_thread_t *RequestVout( input_resource_t *p_resource,
                                    vout_thread_t *p_vout,
-                                   video_format_t *p_fmt, unsigned dpb_size,
-                                   bool b_recycle )
+                                   video_format_t *p_fmt,
+                                   picture_pool_setup_t *p_pool_setup,
+                                   unsigned dpb_size, bool b_recycle )
 {
     vlc_assert_locked( &p_resource->lock );
 
@@ -230,11 +231,12 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource,
 
         /* */
         vout_configuration_t cfg = {
-            .vout       = p_vout,
-            .input      = VLC_OBJECT(p_resource->p_input),
-            .change_fmt = true,
-            .fmt        = p_fmt,
-            .dpb_size   = dpb_size,
+            .vout         = p_vout,
+            .input        = VLC_OBJECT(p_resource->p_input),
+            .change_fmt   = true,
+            .fmt          = p_fmt,
+            .dpb_size     = dpb_size,
+            .p_pool_setup = p_pool_setup,
         };
         p_vout = vout_Request( p_resource->p_parent, &cfg );
         if( !p_vout )
@@ -458,11 +460,13 @@ void input_resource_SetInput( input_resource_t *p_resource, input_thread_t *p_in
 
 vout_thread_t *input_resource_RequestVout( input_resource_t *p_resource,
                                             vout_thread_t *p_vout,
-                                            video_format_t *p_fmt, unsigned dpb_size,
+                                            video_format_t *p_fmt,
+                                            picture_pool_setup_t *p_pool_setup,
+                                            unsigned dpb_size,
                                             bool b_recycle )
 {
     vlc_mutex_lock( &p_resource->lock );
-    vout_thread_t *p_ret = RequestVout( p_resource, p_vout, p_fmt, dpb_size, b_recycle );
+    vout_thread_t *p_ret = RequestVout( p_resource, p_vout, p_fmt, p_pool_setup, dpb_size, b_recycle );
     vlc_mutex_unlock( &p_resource->lock );
 
     return p_ret;
@@ -480,7 +484,7 @@ void input_resource_HoldVouts( input_resource_t *p_resource, vout_thread_t ***pp
 
 void input_resource_TerminateVout( input_resource_t *p_resource )
 {
-    input_resource_RequestVout( p_resource, NULL, NULL, 0, false );
+    input_resource_RequestVout( p_resource, NULL, NULL, NULL, 0, false );
 }
 bool input_resource_HasVout( input_resource_t *p_resource )
 {
diff --git a/src/input/resource.h b/src/input/resource.h
index 4c24c74..1f7f1ec 100644
--- a/src/input/resource.h
+++ b/src/input/resource.h
@@ -39,7 +39,10 @@ sout_instance_t *input_resource_RequestSout( input_resource_t *, sout_instance_t
 /**
  * This function handles vout request.
  */
-vout_thread_t *input_resource_RequestVout( input_resource_t *, vout_thread_t *, video_format_t *, unsigned dpb_size, bool b_recycle );
+vout_thread_t *input_resource_RequestVout( input_resource_t *, vout_thread_t *,
+                                           video_format_t *,
+                                           picture_pool_setup_t *,
+                                           unsigned dpb_size, bool b_recycle );
 
 /**
  * This function returns one of the current vout if any.
diff --git a/src/misc/picture_pool.c b/src/misc/picture_pool.c
index 98e093f..ad04ee8 100644
--- a/src/misc/picture_pool.c
+++ b/src/misc/picture_pool.c
@@ -50,6 +50,8 @@ struct picture_pool_t {
     unsigned       picture_count;
     picture_t      **picture;
 
+    picture_pool_gc_t gc;
+
     int       (*pic_lock)(picture_t *);
     void      (*pic_unlock)(picture_t *);
     unsigned    refs;
@@ -76,6 +78,8 @@ void picture_pool_Release(picture_pool_t *pool)
         free(sys);
         free(picture);
     }
+    if (pool->gc.pf_destroy)
+        pool->gc.pf_destroy( pool->gc.p_sys );
 
     vlc_mutex_destroy(&pool->lock);
     free(pool->picture);
@@ -126,6 +130,7 @@ static picture_t *picture_pool_ClonePicture(picture_pool_t *pool,
         clone->gc.p_sys = sys;
     else
         free(sys);
+    clone->pf_copy_private = picture->pf_copy_private;
 
     return clone;
 }
@@ -157,6 +162,7 @@ picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg
 
     pool->pic_lock   = cfg->lock;
     pool->pic_unlock = cfg->unlock;
+    pool->gc = cfg->gc;
 
     for (unsigned i = 0; i < cfg->picture_count; i++) {
         picture_t *picture = picture_pool_ClonePicture(pool, cfg->picture[i]);
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 81b093f..accc675 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -131,6 +131,7 @@ static vout_thread_t *VoutCreate(vlc_object_t *object,
 
     vout->p->original = original;
     vout->p->dpb_size = cfg->dpb_size;
+    vout->p->p_pool_setup = cfg->p_pool_setup;
 
     vout_control_Init(&vout->p->control);
     vout_control_PushVoid(&vout->p->control, VOUT_CONTROL_INIT);
@@ -569,6 +570,7 @@ static void VoutGetDisplayCfg(vout_thread_t *vout, vout_display_cfg_t *cfg, cons
         cfg->align.vertical = VOUT_DISPLAY_ALIGN_TOP;
     else if (align_mask & 0x8)
         cfg->align.vertical = VOUT_DISPLAY_ALIGN_BOTTOM;
+    cfg->p_pool_setup = vout->p->p_pool_setup;
 }
 
 vout_window_t *vout_NewDisplayWindow(vout_thread_t *vout, unsigned type)
@@ -1389,11 +1391,24 @@ static void ThreadClean(vout_thread_t *vout)
     vout_control_Dead(&vout->p->control);
 }
 
+static bool VoutSafePool(picture_pool_setup_t *p_old, picture_pool_setup_t *p_new)
+{
+    if (p_new == NULL)
+        return p_old == NULL;
+    if (p_old == NULL)
+        return false;
+    if (p_new->pf_create_config != p_old->pf_create_config ||
+        p_new->p_sys != p_old->p_sys)
+        return false;
+    return true;
+}
+
 static int ThreadReinit(vout_thread_t *vout,
                         const vout_configuration_t *cfg)
 {
     video_format_t original;
-    if (VoutValidateFormat(&original, cfg->fmt)) {
+    if (VoutValidateFormat(&original, cfg->fmt) ||
+        !VoutSafePool(vout->p->p_pool_setup, cfg->p_pool_setup)) {
         ThreadStop(vout, NULL);
         ThreadClean(vout);
         return VLC_EGENERIC;
@@ -1430,6 +1445,7 @@ static int ThreadReinit(vout_thread_t *vout,
         state.cfg.zoom.num = 1;
         state.cfg.zoom.den = 1;
     }
+    state.cfg.p_pool_setup = cfg->p_pool_setup;
 
     vout->p->original = original;
     vout->p->dpb_size = cfg->dpb_size;
diff --git a/src/video_output/vout_internal.h b/src/video_output/vout_internal.h
index 3b01567..6087863 100644
--- a/src/video_output/vout_internal.h
+++ b/src/video_output/vout_internal.h
@@ -54,6 +54,7 @@ struct vout_thread_sys_t
 
     /* */
     video_format_t  original;   /* Original format ie coming from the decoder */
+    picture_pool_setup_t  *p_pool_setup;
     unsigned        dpb_size;
 
     /* Snapshot interface */
diff --git a/src/video_output/vout_wrapper.c b/src/video_output/vout_wrapper.c
index 3790c98..0832f2a 100644
--- a/src/video_output/vout_wrapper.c
+++ b/src/video_output/vout_wrapper.c
@@ -143,10 +143,19 @@ int vout_InitWrapper(vout_thread_t *vout)
         sys->decoder_pool = display_pool;
         sys->display_pool = display_pool;
     } else if (!sys->decoder_pool) {
-        sys->decoder_pool =
-            picture_pool_NewFromFormat(&source,
-                                       __MAX(VOUT_MAX_PICTURES,
-                                             reserved_picture + decoder_picture - DISPLAY_PICTURE_COUNT));
+        const unsigned decoder_pool_size = __MAX(VOUT_MAX_PICTURES,
+                                                 reserved_picture + decoder_picture - DISPLAY_PICTURE_COUNT);
+        if (vd->cfg->p_pool_setup)
+        {
+            const picture_pool_configuration_t *conf = NULL;
+            if (vd->cfg->p_pool_setup->pf_create_config)
+                conf = vd->cfg->p_pool_setup->pf_create_config( vd->cfg->p_pool_setup->p_sys, &source, decoder_pool_size);
+            if ( conf != NULL )
+                sys->decoder_pool = picture_pool_NewExtended( conf );
+        }
+
+        if (!sys->decoder_pool)
+            sys->decoder_pool = picture_pool_NewFromFormat(&source, decoder_pool_size);
         if (!sys->decoder_pool)
             return VLC_EGENERIC;
         if (allow_dr) {
-- 
2.3.0




More information about the vlc-devel mailing list