[vlc-commits] chroma: cvpx: use copy helper instead of sub filters

Thomas Guillem git at videolan.org
Fri Mar 16 16:08:37 CET 2018


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Fri Mar 16 15:22:59 2018 +0100| [e15546b2e1edc4ee18743dff938168018648e8df] | committer: Thomas Guillem

chroma: cvpx: use copy helper instead of sub filters

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

 modules/video_chroma/Makefile.am |   1 +
 modules/video_chroma/cvpx.c      | 261 +++++++++++++++++++++------------------
 2 files changed, 141 insertions(+), 121 deletions(-)

diff --git a/modules/video_chroma/Makefile.am b/modules/video_chroma/Makefile.am
index 720bee1a85..96a2299eeb 100644
--- a/modules/video_chroma/Makefile.am
+++ b/modules/video_chroma/Makefile.am
@@ -119,6 +119,7 @@ if HAVE_TVOS
 libcvpx_plugin_la_CFLAGS = $(AM_CFLAGS) -mtvos-version-min=10.2
 endif
 libcvpx_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(chromadir)' -Wl,-framework,Foundation -Wl,-framework,VideoToolbox -Wl,-framework,CoreMedia -Wl,-framework,CoreVideo
+libcvpx_plugin_la_LIBADD = libchroma_copy.la
 EXTRA_LTLIBRARIES += libcvpx_plugin.la
 chroma_LTLIBRARIES += $(LTLIBcvpx)
 
diff --git a/modules/video_chroma/cvpx.c b/modules/video_chroma/cvpx.c
index 62ae1f77b0..7eebd60972 100644
--- a/modules/video_chroma/cvpx.c
+++ b/modules/video_chroma/cvpx.c
@@ -36,6 +36,7 @@
 #include <vlc_picture.h>
 #include <vlc_modules.h>
 #include "../codec/vt_utils.h"
+#include "../video_chroma/copy.h"
 
 static int Open(vlc_object_t *);
 static void Close(vlc_object_t *);
@@ -50,7 +51,12 @@ struct filter_sys_t
     CVPixelBufferPoolRef pool;
     union
     {
-        filter_t *p_sw_filter;
+        struct
+        {
+            video_format_t fmt;
+            copy_cache_t cache;
+            bool has_cache;
+        } sw;
 #if !TARGET_OS_IPHONE
         VTPixelTransferSessionRef vttransfer;
 #endif
@@ -75,19 +81,63 @@ vlc_module_end ()
 
 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 =
-        cvpxpic_create_mapped(&p_filter->fmt_out.video, cvpxpic_get_ref(src),
-                              true);
+        cvpxpic_create_mapped(&p_sys->sw.fmt, cvpxpic_get_ref(src), true);
     if (!src_sw)
     {
         picture_Release(src);
         return NULL;
     }
+
     picture_CopyProperties(src_sw, src);
     picture_Release(src);
     return src_sw;
 }
 
+static picture_t *CVPX_TO_SW_I420_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);
+    if (!src_sw)
+        return NULL;
+
+    picture_t *dst = filter_NewPicture(p_filter);
+    if (!dst)
+    {
+        picture_Release(src_sw);
+        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);
+    picture_Release(src_sw);
+
+    return dst;
+}
+
 static picture_t *SW_TO_CVPX_Filter(filter_t *p_filter, picture_t *src)
 {
     filter_sys_t *p_sys = p_filter->p_sys;
@@ -101,7 +151,7 @@ static picture_t *SW_TO_CVPX_Filter(filter_t *p_filter, picture_t *src)
 
     /* Allocate a CPVX backed picture mapped for read/write */
     picture_t *mapped_dst =
-        cvpxpic_create_mapped(&p_filter->fmt_in.video, cvpx, false);
+        cvpxpic_create_mapped(&p_sys->sw.fmt, cvpx, false);
     CFRelease(cvpx);
     if (!mapped_dst)
     {
@@ -109,6 +159,54 @@ 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)
@@ -118,11 +216,6 @@ static picture_t *SW_TO_CVPX_Filter(filter_t *p_filter, picture_t *src)
         return NULL;
     }
 
-    /* Copy pixels to the CVPX backed picture. Don't use picture_CopyPixels()
-     * since we want to handle the context ourself. */
-    for( int i = 0; i < src->i_planes ; i++ )
-        plane_CopyPixels( mapped_dst->p+i, src->p+i );
-
     /* Attach the CVPX to a new opaque picture */
     cvpxpic_attach(dst, cvpxpic_get_ref(mapped_dst));
 
@@ -134,76 +227,15 @@ static picture_t *SW_TO_CVPX_Filter(filter_t *p_filter, picture_t *src)
     return dst;
 }
 
-
-static picture_t *CVPX_TO_I420_Filter(filter_t *p_filter, picture_t *src)
-{
-    filter_sys_t *p_sys = p_filter->p_sys;
-    filter_t *p_sw_filter = p_sys->p_sw_filter;
-    assert(p_sw_filter != NULL);
-    picture_t *dst = NULL;
-
-    picture_t *src_sw =
-        cvpxpic_create_mapped(&p_sw_filter->fmt_in.video, cvpxpic_get_ref(src),
-                              true);
-
-    if (!src_sw)
-    {
-        picture_Release(src);
-        return NULL;
-    }
-    picture_CopyProperties(src_sw, src);
-    picture_Release(src);
-
-    dst = p_sw_filter->pf_video_filter(p_sw_filter, src_sw);
-
-    return dst;
-}
-
-static picture_t *SW_buffer_new(filter_t *p_filter)
-{
-    return picture_NewFromFormat( &p_filter->fmt_out.video );
-}
-
-static picture_t *CVPX_buffer_new(filter_t *p_sw_filter)
-{
-    filter_t *p_filter = p_sw_filter->owner.sys;
-    filter_sys_t *p_sys = p_filter->p_sys;
-
-    CVPixelBufferRef cvpx = cvpxpool_new_cvpx(p_sys->pool);
-    if (cvpx == NULL)
-        return NULL;
-
-    picture_t *pic =
-        cvpxpic_create_mapped(&p_sw_filter->fmt_out.video, cvpx, false);
-    CFRelease(cvpx);
-    return pic;
-}
-
-static picture_t *I420_TO_CVPX_Filter(filter_t *p_filter, picture_t *src)
-{
-    filter_sys_t *p_sys = p_filter->p_sys;
-    filter_t *p_sw_filter = p_sys->p_sw_filter;
-
-    picture_t *sw_dst = p_sw_filter->pf_video_filter(p_sw_filter, src);
-    if (sw_dst == NULL)
-        return NULL;
-
-    return cvpxpic_unmap(sw_dst);
-}
-
 static void Close(vlc_object_t *obj)
 {
     filter_t *p_filter = (filter_t *)obj;
     filter_sys_t *p_sys = p_filter->p_sys;
 
-    if (p_sys->p_sw_filter != NULL)
-    {
-        module_unneed(p_sys->p_sw_filter, p_sys->p_sw_filter->p_module);
-        vlc_object_release(p_sys->p_sw_filter);
-    }
-
     if (p_sys->pool != NULL)
         CVPixelBufferPoolRelease(p_sys->pool);
+    if (p_sys->sw.has_cache)
+        CopyCleanCache(&p_sys->sw.cache);
     free(p_sys);
 }
 
@@ -215,58 +247,60 @@ static int Open(vlc_object_t *obj)
         || p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width)
         return VLC_EGENERIC;
 
-#define CASE_CVPX_INPUT(x) \
+    video_format_t sw_fmt;
+#define CASE_CVPX_INPUT(x, i420_fcc) \
     case VLC_CODEC_CVPX_##x: \
-        if (p_filter->fmt_out.video.i_chroma == VLC_CODEC_##x) { \
+        sw_fmt = p_filter->fmt_out.video; \
+        if (p_filter->fmt_out.video.i_chroma == VLC_CODEC_##x) \
             p_filter->pf_video_filter = CVPX_TO_SW_Filter; \
-        } else if (p_filter->fmt_out.video.i_chroma == VLC_CODEC_I420) {\
-            p_filter->pf_video_filter = CVPX_TO_I420_Filter; \
-            i_sw_filter_in_chroma = VLC_CODEC_##x; \
-            i_sw_filter_out_chroma = VLC_CODEC_I420; \
-            sw_filter_owner.video.buffer_new = SW_buffer_new; \
+        else if (i420_fcc != 0 && p_filter->fmt_out.video.i_chroma == i420_fcc) { \
+            p_filter->pf_video_filter = CVPX_TO_SW_I420_Filter; \
+            sw_fmt.i_chroma = VLC_CODEC_##x; \
+            b_need_cache = true; \
         } else return VLC_EGENERIC; \
-        b_need_pool = false;
 
-#define CASE_CVPX_OUTPUT(x) \
+#define CASE_CVPX_OUTPUT(x, i420_fcc) \
     case VLC_CODEC_CVPX_##x: \
+        sw_fmt = p_filter->fmt_in.video; \
         if (p_filter->fmt_in.video.i_chroma == VLC_CODEC_##x) { \
             p_filter->pf_video_filter = SW_TO_CVPX_Filter; \
-        } else if (p_filter->fmt_in.video.i_chroma == VLC_CODEC_I420) {\
-            p_filter->pf_video_filter = I420_TO_CVPX_Filter; \
-            i_sw_filter_in_chroma = VLC_CODEC_I420; \
-            i_sw_filter_out_chroma = VLC_CODEC_##x; \
-            sw_filter_owner.sys = p_filter; \
-            sw_filter_owner.video.buffer_new = CVPX_buffer_new; \
+        } \
+        else if (i420_fcc != 0 && p_filter->fmt_in.video.i_chroma == i420_fcc) { \
+            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;
-    vlc_fourcc_t i_sw_filter_in_chroma = 0, i_sw_filter_out_chroma = 0;
-    filter_owner_t sw_filter_owner = {};
+    bool b_need_pool = false;
+    bool b_need_cache = false;
+    unsigned i_cache_pixel_bytes = 1;
     switch (p_filter->fmt_in.video.i_chroma)
     {
-        CASE_CVPX_INPUT(NV12)
+        CASE_CVPX_INPUT(NV12, VLC_CODEC_I420)
             break;
-        CASE_CVPX_INPUT(P010)
+        CASE_CVPX_INPUT(P010, VLC_CODEC_I420_10L)
+            i_cache_pixel_bytes = 2;
             break;
-        CASE_CVPX_INPUT(UYVY)
+        CASE_CVPX_INPUT(UYVY, 0)
             break;
-        CASE_CVPX_INPUT(I420)
+        CASE_CVPX_INPUT(I420, 0)
             break;
-        CASE_CVPX_INPUT(BGRA)
+        CASE_CVPX_INPUT(BGRA, 0)
             break;
         default:
             switch (p_filter->fmt_out.video.i_chroma)
             {
-                CASE_CVPX_OUTPUT(NV12)
+                CASE_CVPX_OUTPUT(NV12, VLC_CODEC_I420)
                     break;
-                CASE_CVPX_OUTPUT(P010)
+                CASE_CVPX_OUTPUT(P010, VLC_CODEC_I420_10L)
+                    i_cache_pixel_bytes = 2;
                     break;
-                CASE_CVPX_OUTPUT(UYVY)
+                CASE_CVPX_OUTPUT(UYVY, 0)
                     break;
-                CASE_CVPX_OUTPUT(I420)
+                CASE_CVPX_OUTPUT(I420, 0)
                     break;
-                CASE_CVPX_OUTPUT(BGRA)
+                CASE_CVPX_OUTPUT(BGRA, 0)
                     break;
                 default:
                     return VLC_EGENERIC;
@@ -278,35 +312,20 @@ static int Open(vlc_object_t *obj)
     if (unlikely(!p_sys))
         return VLC_ENOMEM;
 
-    p_sys->p_sw_filter = NULL;
     p_sys->pool = NULL;
+    p_sys->sw.fmt = sw_fmt;
+    p_sys->sw.has_cache = false;
 
     if (b_need_pool
      && (p_sys->pool = cvpxpool_create(&p_filter->fmt_out.video, 3)) == NULL)
         goto error;
 
-    if (i_sw_filter_in_chroma != 0)
+    if (b_need_cache)
     {
-        filter_t *p_sw_filter = vlc_object_create(p_filter, sizeof(filter_t));
-        if (unlikely(p_sw_filter == NULL))
-            goto error;
-
-        p_sw_filter->fmt_in = p_filter->fmt_in;
-        p_sw_filter->fmt_out = p_filter->fmt_out;
-        p_sw_filter->fmt_in.i_codec = p_sw_filter->fmt_in.video.i_chroma
-                                    = i_sw_filter_in_chroma;
-        p_sw_filter->fmt_out.i_codec = p_sw_filter->fmt_out.video.i_chroma
-                                     = i_sw_filter_out_chroma;
-
-        p_sw_filter->owner = sw_filter_owner;
-        p_sw_filter->p_module = module_need(p_sw_filter, "video converter",
-                                            NULL, false);
-        if (p_sw_filter->p_module == NULL)
-        {
-            vlc_object_release(p_sw_filter);
+        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->p_sw_filter = p_sw_filter;
+        p_sys->sw.has_cache = true;
     }
 
     return VLC_SUCCESS;



More information about the vlc-commits mailing list