[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