[vlc-commits] chroma: cvpx: always use cached copy

Thomas Guillem git at videolan.org
Fri Mar 16 18:58:57 CET 2018


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Fri Mar 16 16:58:13 2018 +0100| [1dca00fef8552921576c0f52fff1f37e9a75ae2e] | committer: Thomas Guillem

chroma: cvpx: always use cached copy

Don't send IOSurface mapped pictures directly but copy them in a intermediate
picture with uswc.

This improve performances of filters since they could read on a GPU mapped
pictures.

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

 modules/video_chroma/cvpx.c | 181 ++++++++++++++++++++------------------------
 1 file changed, 84 insertions(+), 97 deletions(-)

diff --git a/modules/video_chroma/cvpx.c b/modules/video_chroma/cvpx.c
index 7eebd60972..1f001a04fe 100644
--- a/modules/video_chroma/cvpx.c
+++ b/modules/video_chroma/cvpx.c
@@ -55,7 +55,6 @@ struct filter_sys_t
         {
             video_format_t fmt;
             copy_cache_t cache;
-            bool has_cache;
         } sw;
 #if !TARGET_OS_IPHONE
         VTPixelTransferSessionRef vttransfer;
@@ -79,62 +78,103 @@ vlc_module_end ()
  * CVPX to/from I420 conversion *
  ********************************/
 
-static picture_t *CVPX_TO_SW_Filter(filter_t *p_filter, picture_t *src)
+static void Copy(filter_t *p_filter, picture_t *dst, picture_t *src)
 {
     filter_sys_t *p_sys = p_filter->p_sys;
 
-    picture_t *src_sw =
-        cvpxpic_create_mapped(&p_sys->sw.fmt, cvpxpic_get_ref(src), true);
-    if (!src_sw)
+    const uint8_t *src_planes[3] = { src->p[0].p_pixels,
+                                     src->p[1].p_pixels,
+                                     src->p[2].p_pixels };
+    const size_t src_pitches[3] = { src->p[0].i_pitch,
+                                    src->p[1].i_pitch,
+                                    src->p[2].i_pitch };
+
+#define DO(x) \
+    x(dst, src_planes, src_pitches, src->format.i_visible_height, &p_sys->sw.cache)
+#define DO_S(x, shift) \
+    x(dst, src_planes, src_pitches, src->format.i_visible_height, shift, &p_sys->sw.cache)
+#define DO_P(x) \
+    x(dst, src_planes[0], src_pitches[0], src->format.i_visible_height, &p_sys->sw.cache)
+
+    const vlc_fourcc_t infcc = src->format.i_chroma;
+    const vlc_fourcc_t outfcc = dst->format.i_chroma;
+
+    switch (infcc)
     {
-        picture_Release(src);
-        return NULL;
+        case VLC_CODEC_NV12:
+            if (outfcc == VLC_CODEC_NV12)
+                DO(Copy420_SP_to_SP);
+            else
+            {
+                assert(outfcc == VLC_CODEC_I420);
+                DO(Copy420_SP_to_P);
+            }
+            break;
+        case VLC_CODEC_P010:
+            if (outfcc == VLC_CODEC_P010)
+                DO(Copy420_SP_to_SP);
+            else
+            {
+                assert(dst->format.i_chroma == VLC_CODEC_I420_10L);
+                DO_S(Copy420_16_SP_to_P, 6);
+            }
+            break;
+        case VLC_CODEC_I420:
+            if (outfcc == VLC_CODEC_I420)
+                DO(Copy420_P_to_P);
+            else
+            {
+                assert(outfcc == VLC_CODEC_NV12);
+                DO(Copy420_P_to_SP);
+            }
+            break;
+        case VLC_CODEC_I420_10L:
+            assert(outfcc == VLC_CODEC_P010);
+            DO_S(Copy420_16_P_to_SP, -6);
+            break;
+        case VLC_CODEC_UYVY:
+            assert(outfcc == VLC_CODEC_UYVY);
+            DO_P(CopyPacked);
+            break;
+        case VLC_CODEC_BGRA:
+            assert(outfcc == VLC_CODEC_BGRA);
+            DO_P(CopyPacked);
+            break;
+        default:
+            vlc_assert_unreachable();
     }
 
-    picture_CopyProperties(src_sw, src);
-    picture_Release(src);
-    return src_sw;
+#undef DO
+#undef DO_S
+#undef DO_P
 }
 
-static picture_t *CVPX_TO_SW_I420_Filter(filter_t *p_filter, picture_t *src)
+static picture_t *CVPX_TO_SW_Filter(filter_t *p_filter, picture_t *src)
 {
     filter_sys_t *p_sys = p_filter->p_sys;
 
-    picture_t *src_sw = CVPX_TO_SW_Filter(p_filter, src);
+    picture_t *src_sw =
+        cvpxpic_create_mapped(&p_sys->sw.fmt, cvpxpic_get_ref(src), true);
     if (!src_sw)
+    {
+        picture_Release(src);
         return NULL;
+    }
 
     picture_t *dst = filter_NewPicture(p_filter);
     if (!dst)
     {
         picture_Release(src_sw);
+        picture_Release(src);
         return NULL;
     }
 
-    const uint8_t *src_planes[2] = { src_sw->p[0].p_pixels,
-                                     src_sw->p[1].p_pixels };
-    const size_t src_pitches[2] = { src_sw->p[0].i_pitch,
-                                    src_sw->p[1].i_pitch };
-
-    switch (p_filter->fmt_in.video.i_chroma)
-    {
-        case VLC_CODEC_CVPX_NV12:
-            assert(dst->format.i_chroma == VLC_CODEC_I420);
-            Copy420_SP_to_P(dst, src_planes, src_pitches, src_sw->format.i_visible_height,
-                            &p_sys->sw.cache);
-            break;
-        case VLC_CODEC_CVPX_P010:
-            assert(dst->format.i_chroma == VLC_CODEC_I420_10L);
-            Copy420_16_SP_to_P(dst, src_planes, src_pitches, src_sw->format.i_visible_height,
-                               6, &p_sys->sw.cache);
-            break;
-        default:
-            vlc_assert_unreachable();
-    }
-
-    picture_CopyProperties(dst, src_sw);
+    Copy(p_filter, dst, src_sw);
     picture_Release(src_sw);
 
+    picture_CopyProperties(dst, src);
+    picture_Release(src);
+
     return dst;
 }
 
@@ -159,54 +199,6 @@ static picture_t *SW_TO_CVPX_Filter(filter_t *p_filter, picture_t *src)
         return NULL;
     }
 
-    const uint8_t *src_planes[3] = { src->p[0].p_pixels,
-                                     src->p[1].p_pixels,
-                                     src->p[2].p_pixels };
-    const size_t src_pitches[3] = { src->p[0].i_pitch,
-                                    src->p[1].i_pitch,
-                                    src->p[2].i_pitch };
-
-#define DO(x, planes, pitches) \
-    x(mapped_dst, planes, pitches, src->format.i_visible_height, &p_sys->sw.cache)
-#define DO_S(x, planes, pitches, shift) \
-    x(mapped_dst, planes, pitches, src->format.i_visible_height, shift, &p_sys->sw.cache)
-
-    switch (p_filter->fmt_out.video.i_chroma)
-    {
-        case VLC_CODEC_CVPX_NV12:
-            if (p_filter->fmt_in.video.i_chroma == VLC_CODEC_I420)
-                DO(Copy420_P_to_SP, src_planes, src_pitches);
-            else
-            {
-                assert(p_filter->fmt_in.video.i_chroma == VLC_CODEC_NV12);
-                DO(Copy420_SP_to_SP, src_planes, src_pitches);
-            }
-            break;
-        case VLC_CODEC_CVPX_P010:
-            if (p_filter->fmt_in.video.i_chroma == VLC_CODEC_I420_10L)
-                DO_S(Copy420_16_P_to_SP, src_planes, src_pitches, -6);
-            else
-            {
-                assert(p_filter->fmt_in.video.i_chroma == VLC_CODEC_P010);
-                DO(Copy420_SP_to_SP, src_planes, src_pitches);
-            }
-            break;
-        case VLC_CODEC_CVPX_I420:
-            assert(p_filter->fmt_in.video.i_chroma == VLC_CODEC_I420);
-            DO(Copy420_P_to_P, src_planes, src_pitches);
-            break;
-        case VLC_CODEC_CVPX_UYVY:
-            assert(p_filter->fmt_in.video.i_chroma == VLC_CODEC_UYVY);
-            DO(CopyPacked, src_planes[0], src_pitches[0]);
-            break;
-        case VLC_CODEC_CVPX_BGRA:
-            assert(p_filter->fmt_in.video.i_chroma == VLC_CODEC_BGRA);
-            DO(CopyPacked, src_planes[0], src_pitches[0]);
-            break;
-        default:
-            vlc_assert_unreachable();
-    }
-
     /* Allocate a CVPX picture without any context */
     picture_t *dst = picture_NewFromFormat(&p_filter->fmt_out.video);
     if (!dst)
@@ -216,6 +208,8 @@ static picture_t *SW_TO_CVPX_Filter(filter_t *p_filter, picture_t *src)
         return NULL;
     }
 
+    Copy(p_filter, mapped_dst, src);
+
     /* Attach the CVPX to a new opaque picture */
     cvpxpic_attach(dst, cvpxpic_get_ref(mapped_dst));
 
@@ -234,8 +228,6 @@ static void Close(vlc_object_t *obj)
 
     if (p_sys->pool != NULL)
         CVPixelBufferPoolRelease(p_sys->pool);
-    if (p_sys->sw.has_cache)
-        CopyCleanCache(&p_sys->sw.cache);
     free(p_sys);
 }
 
@@ -254,9 +246,8 @@ static int Open(vlc_object_t *obj)
         if (p_filter->fmt_out.video.i_chroma == VLC_CODEC_##x) \
             p_filter->pf_video_filter = CVPX_TO_SW_Filter; \
         else if (i420_fcc != 0 && p_filter->fmt_out.video.i_chroma == i420_fcc) { \
-            p_filter->pf_video_filter = CVPX_TO_SW_I420_Filter; \
+            p_filter->pf_video_filter = CVPX_TO_SW_Filter; \
             sw_fmt.i_chroma = VLC_CODEC_##x; \
-            b_need_cache = true; \
         } else return VLC_EGENERIC; \
 
 #define CASE_CVPX_OUTPUT(x, i420_fcc) \
@@ -269,11 +260,9 @@ static int Open(vlc_object_t *obj)
             p_filter->pf_video_filter = SW_TO_CVPX_Filter; \
             sw_fmt.i_chroma = VLC_CODEC_##x; \
         } else return VLC_EGENERIC; \
-        b_need_cache = true; \
         b_need_pool = true;
 
     bool b_need_pool = false;
-    bool b_need_cache = false;
     unsigned i_cache_pixel_bytes = 1;
     switch (p_filter->fmt_in.video.i_chroma)
     {
@@ -314,20 +303,18 @@ static int Open(vlc_object_t *obj)
 
     p_sys->pool = NULL;
     p_sys->sw.fmt = sw_fmt;
-    p_sys->sw.has_cache = false;
+
+    unsigned i_cache_width = p_filter->fmt_in.video.i_width * i_cache_pixel_bytes;
+    if (CopyInitCache(&p_sys->sw.cache, i_cache_width) != VLC_SUCCESS)
+    {
+        free(p_sys);
+        return VLC_ENOMEM;
+    }
 
     if (b_need_pool
      && (p_sys->pool = cvpxpool_create(&p_filter->fmt_out.video, 3)) == NULL)
         goto error;
 
-    if (b_need_cache)
-    {
-        unsigned i_cache_width = p_filter->fmt_in.video.i_width * i_cache_pixel_bytes;
-        if (CopyInitCache(&p_sys->sw.cache, i_cache_width) != VLC_SUCCESS)
-            goto error;
-        p_sys->sw.has_cache = true;
-    }
-
     return VLC_SUCCESS;
 
 error:



More information about the vlc-commits mailing list