[vlc-commits] vout: spu: remove max subpicture limit

Thomas Guillem git at videolan.org
Tue Jun 11 07:59:00 CEST 2019


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Jun  6 11:47:24 2019 +0200| [d44ab570ed32b2e788e509a6b2f7845a129bf725] | committer: Thomas Guillem

vout: spu: remove max subpicture limit

Use a vlc_vector instead of a hard-coded maximum size.

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

 src/video_output/vout_subpictures.c | 137 +++++++++++++++++-------------------
 1 file changed, 66 insertions(+), 71 deletions(-)

diff --git a/src/video_output/vout_subpictures.c b/src/video_output/vout_subpictures.c
index 0bef5fd48b..6659771929 100644
--- a/src/video_output/vout_subpictures.c
+++ b/src/video_output/vout_subpictures.c
@@ -49,9 +49,6 @@
  * Local prototypes
  *****************************************************************************/
 
-/* Number of simultaneous subpictures */
-#define VOUT_MAX_SUBPICTURES (__MAX(VOUT_MAX_PICTURES, SPU_MAX_PREPARE_TIME/5000))
-
 /* Hold of subpicture with converted ts */
 typedef struct {
     subpicture_t *subpic;
@@ -60,8 +57,10 @@ typedef struct {
     bool is_late;
 } spu_render_entry_t;
 
+typedef struct VLC_VECTOR(spu_render_entry_t) spu_render_vector;
+
 struct spu_channel {
-    spu_render_entry_t entries[VOUT_MAX_SUBPICTURES];
+    spu_render_vector entries;
     size_t id;
     vlc_clock_t *clock;
     vlc_tick_t delay;
@@ -113,51 +112,49 @@ static void spu_channel_Init(struct spu_channel *channel, size_t id,
     channel->delay = 0;
     channel->rate = 1.f;
 
-    for (size_t i = 0; i < VOUT_MAX_SUBPICTURES; i++)
-        channel->entries[i].subpic = NULL;
+    vlc_vector_init(&channel->entries);
 }
 
 static int spu_channel_Push(struct spu_channel *channel, subpicture_t *subpic)
 {
-    for (size_t i = 0; i < VOUT_MAX_SUBPICTURES; i++)
-    {
-        if (channel->entries[i].subpic)
-            continue;
-
-        channel->entries[i].subpic = subpic;
-        return VLC_SUCCESS;
-    }
-    return VLC_EGENERIC;
+    const spu_render_entry_t entry = {
+        .subpic = subpic,
+    };
+    return vlc_vector_push(&channel->entries, entry) ? VLC_SUCCESS : VLC_EGENERIC;
 }
 
 static void spu_channel_DeleteAt(struct spu_channel *channel, size_t index)
 {
-    if (channel->entries[index].subpic)
-    {
-        subpicture_Delete(channel->entries[index].subpic);
-        channel->entries[index].subpic = NULL;
-    }
+    assert(index < channel->entries.size);
+    assert(channel->entries.data[index].subpic);
+
+    subpicture_Delete(channel->entries.data[index].subpic);
+    vlc_vector_remove(&channel->entries, index);
 }
 
-static int spu_channel_DeleteSubpicture(struct spu_channel *channel,
-                                        subpicture_t *subpic)
+static void spu_channel_DeleteSubpicture(struct spu_channel *channel,
+                                         subpicture_t *subpic)
 {
-    for (size_t i = 0; i < VOUT_MAX_SUBPICTURES; i++)
+    for (size_t i = 0; i < channel->entries.size; i++)
     {
-        if (channel->entries[i].subpic != subpic)
-            continue;
-
-        spu_channel_DeleteAt(channel, i);
-        return VLC_SUCCESS;
+        if (channel->entries.data[i].subpic == subpic)
+        {
+            subpicture_Delete(subpic);
+            vlc_vector_remove(&channel->entries, i);
+            return;
+        }
     }
-    return VLC_EGENERIC;
+    vlc_assert_unreachable();
 }
 
 static void spu_channel_Clean(struct spu_channel *channel)
 {
-    for (size_t i = 0; i < VOUT_MAX_SUBPICTURES; i++)
-        if (channel->entries[i].subpic)
-            subpicture_Delete(channel->entries[i].subpic);
+    for (size_t i = 0; i < channel->entries.size; i++)
+    {
+        assert(channel->entries.data[i].subpic);
+        subpicture_Delete(channel->entries.data[i].subpic);
+    }
+    vlc_vector_destroy(&channel->entries);
 }
 
 static struct spu_channel *spu_GetChannel(spu_t *spu, size_t channel_id)
@@ -574,45 +571,38 @@ static size_t spu_channel_ConvertDates(struct spu_channel *channel,
 {
     /* Put every spu start and stop ts into the same array to convert them in
      * one shot */
-    vlc_tick_t date_array[VOUT_MAX_SUBPICTURES *2];
-    size_t entry_count = 0;
-    for (size_t index = 0; index < VOUT_MAX_SUBPICTURES; index++)
-    {
-        subpicture_t *current = channel->entries[index].subpic;
+    if (channel->entries.size == 0)
+        return 0;
+    vlc_tick_t *date_array = vlc_alloc(channel->entries.size,
+                                       2 * sizeof(vlc_tick_t));
+    if (!date_array)
+        return 0;
 
-        if (!current)
-            continue;
+    for (size_t index = 0; index < channel->entries.size; index++)
+    {
+        subpicture_t *current = channel->entries.data[index].subpic;
+        assert(current);
 
-        date_array[entry_count * 2] = current->i_start;
-        date_array[entry_count * 2 + 1] = current->i_stop;
-        entry_count++;
+        date_array[index * 2] = current->i_start;
+        date_array[index * 2 + 1] = current->i_stop;
     }
-    if (entry_count == 0)
-        return 0;
 
     /* Convert all spu ts */
     if (channel->clock)
         vlc_clock_ConvertArrayToSystem(channel->clock, system_now, date_array,
-                                       entry_count * 2, channel->rate);
+                                       channel->entries.size * 2, channel->rate);
 
     /* Put back the converted ts into the output spu_render_entry_t struct */
-    entry_count = 0;
-    for (size_t index = 0; index < VOUT_MAX_SUBPICTURES; index++)
+    for (size_t index = 0; index < channel->entries.size; index++)
     {
-        spu_render_entry_t *render_entry = &channel->entries[index];
-        subpicture_t *current = render_entry->subpic;
+        spu_render_entry_t *render_entry = &channel->entries.data[index];
 
-        if (!current)
-            render_entry->subpic = NULL;
-        else
-        {
-            render_entry->subpic = current;
-            render_entry->start = date_array[entry_count * 2];
-            render_entry->stop = date_array[entry_count * 2 + 1];
-            entry_count++;
-        }
+        render_entry->start = date_array[index * 2];
+        render_entry->stop = date_array[index * 2 + 1];
     }
-    return entry_count;
+
+    free(date_array);
+    return channel->entries.size;
 }
 
 static bool
@@ -621,12 +611,12 @@ spu_render_entry_IsSelected(spu_render_entry_t *render_entry, size_t channel_id,
                             vlc_tick_t render_subtitle_date, bool ignore_osd)
 {
     subpicture_t *subpic = render_entry->subpic;
+    assert(subpic);
 
-    if (!subpic)
-        return false;
+    assert(subpic->i_channel >= 0 && (size_t) subpic->i_channel == channel_id);
+    (void) channel_id;
 
-    if ((subpic->i_channel >= 0 && (size_t) subpic->i_channel != channel_id) ||
-       (ignore_osd && !subpic->b_subtitle))
+    if (ignore_osd && !subpic->b_subtitle)
         return false;
 
     const vlc_tick_t render_date =
@@ -658,9 +648,14 @@ spu_SelectSubpictures(spu_t *spu, vlc_tick_t system_now,
 
     /* */
     *subpicture_count = 0;
+    size_t total_size = 0;
+    for (size_t i = 0; i < sys->channels.size; ++i)
+        total_size += sys->channels.data[i].entries.size;
+    if (total_size == 0)
+        return NULL;
+
     spu_render_entry_t *subpicture_array =
-        vlc_alloc(sys->channels.size,
-                  sizeof(spu_render_entry_t) * VOUT_MAX_SUBPICTURES);
+        vlc_alloc(total_size, sizeof(spu_render_entry_t));
     if (!subpicture_array)
         return NULL;
 
@@ -668,7 +663,7 @@ spu_SelectSubpictures(spu_t *spu, vlc_tick_t system_now,
     for (size_t i = 0; i < sys->channels.size; i++)
     {
         struct spu_channel *channel = &sys->channels.data[i];
-        spu_render_entry_t *render_entries = channel->entries;
+        spu_render_entry_t *render_entries = channel->entries.data;
 
         vlc_tick_t   start_date = render_subtitle_date;
         vlc_tick_t   ephemer_subtitle_date = 0;
@@ -680,7 +675,7 @@ spu_SelectSubpictures(spu_t *spu, vlc_tick_t system_now,
             continue;
 
         /* Select available pictures */
-        for (size_t index = 0; index < VOUT_MAX_SUBPICTURES; index++) {
+        for (size_t index = 0; index < channel->entries.size; index++) {
             spu_render_entry_t *render_entry = &render_entries[index];
             subpicture_t *current = render_entry->subpic;
             bool is_stop_valid;
@@ -722,7 +717,7 @@ spu_SelectSubpictures(spu_t *spu, vlc_tick_t system_now,
             start_date = INT64_MAX;
 
         /* Select pictures to be displayed */
-        for (size_t index = 0; index < VOUT_MAX_SUBPICTURES; index++) {
+        for (size_t index = 0; index < channel->entries.size; index++) {
             spu_render_entry_t *render_entry = &render_entries[index];
             subpicture_t *current = render_entry->subpic;
             bool is_late = render_entry->is_late;
@@ -1148,7 +1143,7 @@ static subpicture_t *SpuRenderSubpictures(spu_t *spu,
     subpicture_region_t **output_last_ptr = &output->p_region;
 
     /* Allocate area array for subtitle overlap */
-    spu_area_t subtitle_area_buffer[VOUT_MAX_SUBPICTURES];
+    spu_area_t subtitle_area_buffer[100];
     spu_area_t *subtitle_area;
     size_t subtitle_area_count = 0;
 
@@ -1798,7 +1793,7 @@ ssize_t spu_RegisterChannel(spu_t *spu)
 
 static void spu_channel_Clear(struct spu_channel *channel)
 {
-    for (size_t i = 0; i < VOUT_MAX_SUBPICTURES; i++)
+    for (size_t i = 0; i < channel->entries.size; i++)
         spu_channel_DeleteAt(channel, i);
 }
 
@@ -1822,7 +1817,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_Clear(channel);
+    spu_channel_Clean(channel);
     vlc_vector_remove(&sys->channels, channel_id);
     vlc_mutex_unlock(&sys->lock);
 }



More information about the vlc-commits mailing list