[vlc-commits] vout: spu: prerender text

Francois Cartegnie git at videolan.org
Tue Sep 3 13:13:09 CEST 2019


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Thu Jul 25 15:58:33 2019 +0200| [f501c7dc21215b840c106842e8ed54479c047104] | committer: Francois Cartegnie

vout: spu: prerender text

Should avoid frame delay in most cases.
Will still re-render at blending time if dst
has changed in between.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f501c7dc21215b840c106842e8ed54479c047104
---

 src/video_output/vout_subpictures.c | 406 +++++++++++++++++++++++++++++-------
 1 file changed, 332 insertions(+), 74 deletions(-)

diff --git a/src/video_output/vout_subpictures.c b/src/video_output/vout_subpictures.c
index 53daf00827..c2b0d50ace 100644
--- a/src/video_output/vout_subpictures.c
+++ b/src/video_output/vout_subpictures.c
@@ -69,6 +69,8 @@ struct spu_channel {
 };
 
 typedef struct VLC_VECTOR(struct spu_channel) spu_channel_vector;
+typedef struct VLC_VECTOR(subpicture_t *) spu_prerender_vector;
+#define SPU_CHROMALIST_COUNT 8
 
 struct spu_private_t {
     vlc_mutex_t  lock;            /* lock to protect all followings fields */
@@ -78,6 +80,7 @@ struct spu_private_t {
 
     int channel;             /**< number of subpicture channels registered */
     filter_t *text;                              /**< text renderer module */
+    vlc_mutex_t textlock;
     filter_t *scale_yuvp;                     /**< scaling module for YUVP */
     filter_t *scale;                    /**< scaling module (all but YUVP) */
     bool force_crop;                     /**< force cropping of subpicture */
@@ -106,12 +109,28 @@ struct spu_private_t {
     char           *filter_chain_update;
     vlc_mutex_t    filter_chain_lock;
     filter_chain_t *filter_chain;
+    /**/
+    struct
+    {
+        vlc_thread_t    thread;
+        vlc_mutex_t     lock;
+        vlc_cond_t      cond;
+        vlc_cond_t      output_cond;
+        spu_prerender_vector vector;
+        subpicture_t   *p_processed;
+        video_format_t  fmtsrc;
+        video_format_t  fmtdst;
+        vlc_fourcc_t    chroma_list[SPU_CHROMALIST_COUNT+1];
+    } prerender;
 
     /* */
     vlc_tick_t          last_sort_date;
     vout_thread_t       *vout;
 };
 
+static void spu_PrerenderSync(spu_private_t *, const subpicture_t *);
+static void spu_PrerenderCancel(spu_private_t *, const subpicture_t *);
+
 static void spu_channel_Init(struct spu_channel *channel, size_t id,
                              enum vlc_vout_order order, vlc_clock_t *clock)
 {
@@ -144,11 +163,12 @@ static void spu_channel_DeleteAt(struct spu_channel *channel, size_t index)
     vlc_vector_remove(&channel->entries, index);
 }
 
-static void spu_channel_Clean(struct spu_channel *channel)
+static void spu_channel_Clean(spu_private_t *sys, struct spu_channel *channel)
 {
     for (size_t i = 0; i < channel->entries.size; i++)
     {
         assert(channel->entries.data[i].subpic);
+        spu_PrerenderCancel(sys, channel->entries.data[i].subpic);
         subpicture_Delete(channel->entries.data[i].subpic);
     }
     vlc_vector_destroy(&channel->entries);
@@ -295,14 +315,38 @@ static filter_t *SpuRenderCreateAndLoadScale(vlc_object_t *object,
 
 static void SpuRenderText(spu_t *spu,
                           subpicture_region_t *region,
+                          int i_original_width,
+                          int i_original_height,
                           const vlc_fourcc_t *chroma_list)
 {
-    filter_t *text = spu->p->text;
-
+    spu_private_t *sys = spu->p;
+    filter_t *text = sys->text;
     assert(region->fmt.i_chroma == VLC_CODEC_TEXT);
 
-    if ( region->p_text )
-        text->pf_render(text, region, region, chroma_list);
+    vlc_mutex_lock(&sys->textlock);
+    if(text)
+    {
+        // assume rendered text is in sRGB if nothing is set
+        if (region->fmt.transfer == TRANSFER_FUNC_UNDEF)
+            region->fmt.transfer = TRANSFER_FUNC_SRGB;
+        if (region->fmt.primaries == COLOR_PRIMARIES_UNDEF)
+            region->fmt.primaries = COLOR_PRIMARIES_SRGB;
+        if (region->fmt.space == COLOR_SPACE_UNDEF)
+            region->fmt.space = COLOR_SPACE_SRGB;
+        if (region->fmt.color_range == COLOR_RANGE_UNDEF)
+            region->fmt.color_range = COLOR_RANGE_FULL;
+
+        /* FIXME aspect ratio ? */
+        text->fmt_out.video.i_width          =
+        text->fmt_out.video.i_visible_width  = i_original_width;
+
+        text->fmt_out.video.i_height         =
+        text->fmt_out.video.i_visible_height = i_original_height;
+
+        if ( region->p_text )
+            text->pf_render(text, region, region, chroma_list);
+    }
+    vlc_mutex_unlock(&sys->textlock);
 }
 
 /**
@@ -719,6 +763,7 @@ spu_SelectSubpictures(spu_t *spu, vlc_tick_t system_now,
 
             if (is_rejeted)
             {
+                spu_PrerenderCancel(sys, current);
                 subpicture_Delete(current);
                 vlc_vector_remove(&channel->entries, index);
             }
@@ -746,6 +791,7 @@ static void SpuRenderRegion(spu_t *spu,
                             const spu_scale_t scale_size,
                             const vlc_fourcc_t *chroma_list,
                             const video_format_t *fmt,
+                            int i_original_width, int i_original_height,
                             const spu_area_t *subtitle_area, size_t subtitle_area_count,
                             vlc_tick_t render_date)
 {
@@ -763,19 +809,11 @@ static void SpuRenderRegion(spu_t *spu,
     *dst_ptr  = NULL;
 
     /* Render text region */
-    if (region->fmt.i_chroma == VLC_CODEC_TEXT) {
-        // assume rendered text is in sRGB if nothing is set
-        if (region->fmt.transfer == TRANSFER_FUNC_UNDEF)
-            region->fmt.transfer = TRANSFER_FUNC_SRGB;
-        if (region->fmt.primaries == COLOR_PRIMARIES_UNDEF)
-            region->fmt.primaries = COLOR_PRIMARIES_SRGB;
-        if (region->fmt.space == COLOR_SPACE_UNDEF)
-            region->fmt.space = COLOR_SPACE_SRGB;
-        if (region->fmt.color_range == COLOR_RANGE_UNDEF)
-            region->fmt.color_range = COLOR_RANGE_FULL;
-
-        SpuRenderText(spu, region, chroma_list);
-
+    if (region->fmt.i_chroma == VLC_CODEC_TEXT)
+    {
+        SpuRenderText(spu, region,
+                      i_original_width, i_original_height,
+                      chroma_list);
         /* Check if the rendering has failed ... */
         if (region->fmt.i_chroma == VLC_CODEC_TEXT)
             return;
@@ -1101,8 +1139,6 @@ static subpicture_t *SpuRenderSubpictures(spu_t *spu,
                                           vlc_tick_t render_subtitle_date,
                                           bool external_scale)
 {
-    spu_private_t *sys = spu->p;
-
     /* Count the number of regions and subtitle regions */
     unsigned int subtitle_region_count = 0;
     unsigned int region_count          = 0;
@@ -1161,12 +1197,8 @@ static subpicture_t *SpuRenderSubpictures(spu_t *spu,
             subpic->i_original_picture_height = fmt_src->i_visible_height;
         }
 
-        /* FIXME aspect ratio ? */
-        sys->text->fmt_out.video.i_width          =
-        sys->text->fmt_out.video.i_visible_width  = subpic->i_original_picture_width;
-
-        sys->text->fmt_out.video.i_height         =
-        sys->text->fmt_out.video.i_visible_height = subpic->i_original_picture_height;
+        const int i_original_width = subpic->i_original_picture_width;
+        const int i_original_height = subpic->i_original_picture_height;
 
         /* Render all regions
          * We always transform non absolute subtitle into absolute one on the
@@ -1208,6 +1240,7 @@ static subpicture_t *SpuRenderSubpictures(spu_t *spu,
             SpuRenderRegion(spu, output_last_ptr, &area,
                             entry, region, virtual_scale,
                             chroma_list, fmt_dst,
+                            i_original_width, i_original_height,
                             subtitle_area, subtitle_area_count,
                             subpic->b_subtitle ? render_subtitle_date : system_now);
             if (*output_last_ptr)
@@ -1373,10 +1406,247 @@ static int SubSourceDelProxyCallbacks(filter_t *filter, void *opaque)
     return VLC_SUCCESS;
 }
 
+static void spu_PrerenderWake(spu_private_t *sys,
+                              const video_format_t *fmt_dst,
+                              const video_format_t *fmt_src,
+                              const vlc_fourcc_t *chroma_list)
+{
+    vlc_mutex_lock(&sys->prerender.lock);
+    if(!video_format_IsSimilar(fmt_dst, &sys->prerender.fmtdst))
+    {
+        video_format_Clean(&sys->prerender.fmtdst);
+        video_format_Copy(&sys->prerender.fmtdst, fmt_dst);
+    }
+    if(!video_format_IsSimilar(fmt_src, &sys->prerender.fmtsrc))
+    {
+        video_format_Clean(&sys->prerender.fmtsrc);
+        video_format_Copy(&sys->prerender.fmtsrc, fmt_src);
+    }
+
+    for(size_t i=0; i<SPU_CHROMALIST_COUNT; i++)
+    {
+        sys->prerender.chroma_list[i] = chroma_list[i];
+        if(!chroma_list[i])
+            break;
+    }
+
+    vlc_cond_signal(&sys->prerender.cond);
+    vlc_mutex_unlock(&sys->prerender.lock);
+}
+
+static void spu_PrerenderEnqueue(spu_private_t *sys, subpicture_t *p_subpic)
+{
+    vlc_mutex_lock(&sys->prerender.lock);
+    vlc_vector_push(&sys->prerender.vector, p_subpic);
+    vlc_cond_signal(&sys->prerender.cond);
+    vlc_mutex_unlock(&sys->prerender.lock);
+}
+
+static void spu_PrerenderCancel(spu_private_t *sys, const subpicture_t *p_subpic)
+{
+    vlc_mutex_lock(&sys->prerender.lock);
+    ssize_t i_idx;
+    vlc_vector_index_of(&sys->prerender.vector, p_subpic, &i_idx);
+    if(i_idx >= 0)
+        vlc_vector_remove(&sys->prerender.vector, i_idx);
+    else while(sys->prerender.p_processed == p_subpic)
+        vlc_cond_wait(&sys->prerender.output_cond, &sys->prerender.lock);
+    vlc_mutex_unlock(&sys->prerender.lock);
+}
+
+static void spu_PrerenderPause(spu_private_t *sys)
+{
+    vlc_mutex_lock(&sys->prerender.lock);
+    while(sys->prerender.p_processed)
+        vlc_cond_wait(&sys->prerender.output_cond, &sys->prerender.lock);
+    sys->prerender.chroma_list[0] = 0;
+    vlc_mutex_unlock(&sys->prerender.lock);
+}
+
+static void spu_PrerenderSync(spu_private_t *sys, const subpicture_t *p_subpic)
+{
+    vlc_mutex_lock(&sys->prerender.lock);
+    ssize_t i_idx;
+    vlc_vector_index_of(&sys->prerender.vector, p_subpic, &i_idx);
+    while(i_idx >= 0 || sys->prerender.p_processed == p_subpic)
+    {
+        vlc_cond_wait(&sys->prerender.output_cond, &sys->prerender.lock);
+        vlc_vector_index_of(&sys->prerender.vector, p_subpic, &i_idx);
+    }
+    vlc_mutex_unlock(&sys->prerender.lock);
+}
+
+static void spu_PrerenderText(spu_t *spu, subpicture_t *p_subpic,
+                              video_format_t *fmtsrc, video_format_t *fmtdst,
+                              vlc_fourcc_t *chroma_list)
+{
+    if (p_subpic->i_original_picture_width  <= 0 ||
+        p_subpic->i_original_picture_height <= 0) {
+        if (p_subpic->i_original_picture_width  > 0 ||
+            p_subpic->i_original_picture_height > 0)
+            msg_Err(spu, "original picture size %dx%d is unsupported",
+                     p_subpic->i_original_picture_width,
+                     p_subpic->i_original_picture_height);
+        else
+            msg_Warn(spu, "original picture size is undefined");
+
+        p_subpic->i_original_picture_width  = fmtsrc->i_visible_width;
+        p_subpic->i_original_picture_height = fmtsrc->i_visible_height;
+    }
+
+
+    subpicture_Update(p_subpic, fmtsrc, fmtdst,
+                      p_subpic->b_subtitle ? p_subpic->i_start : vlc_tick_now());
+
+    const int i_original_picture_width = p_subpic->i_original_picture_width;
+    const int i_original_picture_height = p_subpic->i_original_picture_height;
+
+    subpicture_region_t *region;
+    for (region = p_subpic->p_region; region != NULL; region = region->p_next)
+    {
+        if(region->fmt.i_chroma != VLC_CODEC_TEXT)
+            continue;
+        SpuRenderText(spu, region,
+                      i_original_picture_width, i_original_picture_height,
+                      chroma_list);
+    }
+}
+
+struct spu_prerender_ctx_s
+{
+    video_format_t fmtsrc;
+    video_format_t fmtdst;
+    vlc_fourcc_t chroma_list[SPU_CHROMALIST_COUNT+1];
+    vlc_mutex_t *cleanuplock;
+    subpicture_t **pp_processed;
+};
+
+static void spu_prerender_cleanup_routine(void *priv)
+{
+    struct spu_prerender_ctx_s *ctx = priv;
+    video_format_Clean(&ctx->fmtdst);
+    video_format_Clean(&ctx->fmtsrc);
+    *ctx->pp_processed = NULL;
+    vlc_mutex_unlock(ctx->cleanuplock);
+}
+
+static void * spu_PrerenderThread(void *priv)
+{
+    spu_t *spu = priv;
+    spu_private_t *sys = spu->p;
+
+    struct spu_prerender_ctx_s ctx;
+    ctx.cleanuplock = &sys->prerender.lock;
+    ctx.chroma_list[SPU_CHROMALIST_COUNT] = 0;
+    video_format_Init(&ctx.fmtsrc, 0);
+    video_format_Init(&ctx.fmtdst, 0);
+    ctx.pp_processed = &sys->prerender.p_processed;
+
+    vlc_mutex_lock(&sys->prerender.lock);
+    for( ;; )
+    {
+        vlc_cleanup_push(spu_prerender_cleanup_routine, &ctx);
+        while(!sys->prerender.vector.size || !sys->prerender.chroma_list[0])
+            vlc_cond_wait(&sys->prerender.cond, &sys->prerender.lock);
+
+        size_t i_idx = 0;
+        sys->prerender.p_processed = sys->prerender.vector.data[0];
+        for(size_t i=1; i<sys->prerender.vector.size; i++)
+        {
+             if(sys->prerender.p_processed->i_start > sys->prerender.vector.data[i]->i_start)
+             {
+                 sys->prerender.p_processed = sys->prerender.vector.data[i];
+                 i_idx = i;
+             }
+        }
+        vlc_vector_remove(&sys->prerender.vector, i_idx);
+        memcpy(&ctx.chroma_list, sys->prerender.chroma_list, SPU_CHROMALIST_COUNT);
+        video_format_Clean(&ctx.fmtdst);
+        video_format_Clean(&ctx.fmtsrc);
+        video_format_Copy(&ctx.fmtdst, &sys->prerender.fmtdst);
+        video_format_Copy(&ctx.fmtsrc, &sys->prerender.fmtsrc);
+
+        vlc_mutex_unlock(&sys->prerender.lock);
+        vlc_cleanup_pop();
+
+        int canc = vlc_savecancel();
+        spu_PrerenderText(spu, sys->prerender.p_processed,
+                          &ctx.fmtsrc, &ctx.fmtdst, ctx.chroma_list);
+        vlc_restorecancel(canc);
+
+        vlc_mutex_lock(&sys->prerender.lock);
+        sys->prerender.p_processed = NULL;
+        vlc_cond_signal(&sys->prerender.output_cond);
+    }
+
+    return NULL;
+}
+
 /*****************************************************************************
  * Public API
  *****************************************************************************/
 
+static void spu_Cleanup(spu_t *spu)
+{
+    spu_private_t *sys = spu->p;
+
+    if (sys->text)
+        FilterRelease(sys->text);
+    vlc_mutex_destroy(&sys->textlock);
+
+    if (sys->scale_yuvp)
+        FilterRelease(sys->scale_yuvp);
+
+    if (sys->scale)
+        FilterRelease(sys->scale);
+
+    filter_chain_ForEach(sys->source_chain, SubSourceClean, spu);
+    if (sys->vout)
+        filter_chain_ForEach(sys->source_chain,
+                             SubSourceDelProxyCallbacks, sys->vout);
+    filter_chain_Delete(sys->source_chain);
+    free(sys->source_chain_current);
+    if (sys->vout)
+        filter_chain_ForEach(sys->filter_chain,
+                             SubFilterDelProxyCallbacks, sys->vout);
+    filter_chain_Delete(sys->filter_chain);
+    free(sys->filter_chain_current);
+    vlc_mutex_destroy(&sys->filter_chain_lock);
+    free(sys->source_chain_update);
+    free(sys->filter_chain_update);
+
+    /* Destroy all remaining subpictures */
+    for (size_t i = 0; i < sys->channels.size; ++i)
+        spu_channel_Clean(sys, &sys->channels.data[i]);
+
+    vlc_vector_destroy(&sys->channels);
+
+    vlc_mutex_destroy(&sys->lock);
+
+    vlc_mutex_destroy(&sys->prerender.lock);
+    vlc_cond_destroy(&sys->prerender.cond);
+    vlc_cond_destroy(&sys->prerender.output_cond);
+    vlc_vector_clear(&sys->prerender.vector);
+    video_format_Clean(&sys->prerender.fmtdst);
+    video_format_Clean(&sys->prerender.fmtsrc);
+}
+
+/**
+ * Destroy the subpicture unit
+ *
+ * \param p_this the parent object which destroys the subpicture unit
+ */
+void spu_Destroy(spu_t *spu)
+{
+    spu_private_t *sys = spu->p;
+    /* stop prerendering */
+    vlc_cancel(sys->prerender.thread);
+    vlc_join(sys->prerender.thread, NULL);
+    /* delete filters and free resources */
+    spu_Cleanup(spu);
+    vlc_object_delete(spu);
+}
+
 #undef spu_Create
 /**
  * Creates the subpicture unit
@@ -1424,6 +1694,7 @@ spu_t *spu_Create(vlc_object_t *object, vout_thread_t *vout)
 
     /* Load text and scale module */
     sys->text = SpuRenderCreateAndLoadText(spu);
+    vlc_mutex_init(&sys->textlock);
 
     /* XXX spu->p_scale is used for all conversion/scaling except yuvp to
      * yuva/rgba */
@@ -1440,58 +1711,31 @@ spu_t *spu_Create(vlc_object_t *object, vout_thread_t *vout)
      || !sys->scale_yuvp)
     {
         sys->vout = NULL;
-        spu_Destroy(spu);
+        spu_Cleanup(spu);
+        vlc_object_delete(spu);
         return NULL;
     }
     /* */
     sys->last_sort_date = -1;
     sys->vout = vout;
 
-    return spu;
-}
-
-/**
- * Destroy the subpicture unit
- *
- * \param p_this the parent object which destroys the subpicture unit
- */
-void spu_Destroy(spu_t *spu)
-{
-    spu_private_t *sys = spu->p;
-
-    if (sys->text)
-        FilterRelease(sys->text);
-
-    if (sys->scale_yuvp)
-        FilterRelease(sys->scale_yuvp);
-
-    if (sys->scale)
-        FilterRelease(sys->scale);
-
-    filter_chain_ForEach(sys->source_chain, SubSourceClean, spu);
-    if (sys->vout)
-        filter_chain_ForEach(sys->source_chain,
-                             SubSourceDelProxyCallbacks, sys->vout);
-    filter_chain_Delete(sys->source_chain);
-    free(sys->source_chain_current);
-    if (sys->vout)
-        filter_chain_ForEach(sys->filter_chain,
-                             SubFilterDelProxyCallbacks, sys->vout);
-    filter_chain_Delete(sys->filter_chain);
-    free(sys->filter_chain_current);
-    vlc_mutex_destroy(&sys->filter_chain_lock);
-    free(sys->source_chain_update);
-    free(sys->filter_chain_update);
-
-    /* Destroy all remaining subpictures */
-    for (size_t i = 0; i < sys->channels.size; ++i)
-        spu_channel_Clean(&sys->channels.data[i]);
-
-    vlc_vector_destroy(&sys->channels);
-
-    vlc_mutex_destroy(&sys->lock);
+    vlc_mutex_init(&sys->prerender.lock);
+    vlc_cond_init(&sys->prerender.cond);
+    vlc_cond_init(&sys->prerender.output_cond);
+    vlc_vector_init(&sys->prerender.vector);
+    video_format_Init(&sys->prerender.fmtdst, 0);
+    video_format_Init(&sys->prerender.fmtsrc, 0);
+    sys->prerender.p_processed = NULL;
+    sys->prerender.chroma_list[0] = 0;
+    sys->prerender.chroma_list[SPU_CHROMALIST_COUNT] = 0;
+    if(vlc_clone(&sys->prerender.thread, spu_PrerenderThread, spu, VLC_THREAD_PRIORITY_VIDEO))
+    {
+        spu_Cleanup(spu);
+        vlc_object_delete(spu);
+        spu = NULL;
+    }
 
-    vlc_object_delete(spu);
+    return spu;
 }
 
 /**
@@ -1505,9 +1749,11 @@ void spu_Attach(spu_t *spu, input_thread_t *input)
 
         spu->p->input = input;
 
+        vlc_mutex_lock(&spu->p->textlock);
         if (spu->p->text)
             FilterRelease(spu->p->text);
         spu->p->text = SpuRenderCreateAndLoadText(spu);
+        vlc_mutex_unlock(&spu->p->textlock);
     }
     vlc_mutex_unlock(&spu->p->lock);
 }
@@ -1518,6 +1764,7 @@ void spu_Attach(spu_t *spu, input_thread_t *input)
 void spu_Detach(spu_t *spu)
 {
     vlc_mutex_lock(&spu->p->lock);
+    spu_PrerenderPause(spu->p);
     spu->p->input = NULL;
     vlc_mutex_unlock(&spu->p->lock);
 }
@@ -1652,6 +1899,7 @@ void spu_PutSubpicture(spu_t *spu, subpicture_t *subpic)
         subpicture_Delete(subpic);
         return;
     }
+    spu_PrerenderEnqueue(sys, subpic);
     vlc_mutex_unlock(&sys->lock);
 }
 
@@ -1712,6 +1960,9 @@ subpicture_t *spu_Render(spu_t *spu,
         chroma_list = vlc_fourcc_IsYUV(fmt_dst->i_chroma) ? chroma_list_default_yuv
                                                           : chroma_list_default_rgb;
 
+    /* wake up prerenderer, we have some video size and chroma */
+    spu_PrerenderWake(sys, fmt_dst, fmt_src, chroma_list);
+
     vlc_mutex_lock(&sys->lock);
 
     size_t subpicture_count;
@@ -1730,6 +1981,9 @@ subpicture_t *spu_Render(spu_t *spu,
     for (size_t i = 0; i < subpicture_count; i++) {
         spu_render_entry_t *entry = &subpicture_array[i];
         subpicture_t *subpic = entry->subpic;
+
+        spu_PrerenderSync(sys, entry->subpic);
+
         if (!subpic->updater.pf_validate)
             continue;
 
@@ -1789,10 +2043,14 @@ ssize_t spu_RegisterChannel(spu_t *spu)
     return spu_RegisterChannelInternal(spu, NULL, NULL);
 }
 
-static void spu_channel_Clear(struct spu_channel *channel)
+static void spu_channel_Clear(spu_private_t *sys,
+                              struct spu_channel *channel)
 {
     for (size_t i = 0; i < channel->entries.size; i++)
+    {
+        spu_PrerenderCancel(sys, channel->entries.data[i].subpic);
         spu_channel_DeleteAt(channel, i);
+    }
 }
 
 void spu_ClearChannel(spu_t *spu, size_t channel_id)
@@ -1800,7 +2058,7 @@ void spu_ClearChannel(spu_t *spu, size_t channel_id)
     spu_private_t *sys = spu->p;
     vlc_mutex_lock(&sys->lock);
     struct spu_channel *channel = spu_GetChannel(spu, channel_id);
-    spu_channel_Clear(channel);
+    spu_channel_Clear(sys, channel);
     if (channel->clock)
     {
         vlc_clock_Reset(channel->clock);
@@ -1815,7 +2073,7 @@ void spu_UnregisterChannel(spu_t *spu, size_t channel_id)
 
     vlc_mutex_lock(&sys->lock);
     struct spu_channel *channel = spu_GetChannel(spu, channel_id);
-    spu_channel_Clean(channel);
+    spu_channel_Clean(sys, channel);
     vlc_vector_remove(&sys->channels, channel_id);
     vlc_mutex_unlock(&sys->lock);
 }



More information about the vlc-commits mailing list