[vlc-commits] chroma: cvpx: add more filters
Thomas Guillem
git at videolan.org
Fri Jun 2 18:44:16 CEST 2017
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Fri May 12 14:55:31 2017 +0200| [710ecb4ffae06a549f2996fd6a6836cf37057c89] | committer: Thomas Guillem
chroma: cvpx: add more filters
Add CVPX_{NV12|UYVY|I420} to I420 and I420 to CVPX{NV12|UYVY|I420} filters.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=710ecb4ffae06a549f2996fd6a6836cf37057c89
---
modules/video_chroma/Makefile.am | 2 +-
modules/video_chroma/cvpx.c | 185 +++++++++++++++++++++++++++++++--------
2 files changed, 151 insertions(+), 36 deletions(-)
diff --git a/modules/video_chroma/Makefile.am b/modules/video_chroma/Makefile.am
index 5d5003c2ff..cbd8e8a1e7 100644
--- a/modules/video_chroma/Makefile.am
+++ b/modules/video_chroma/Makefile.am
@@ -132,7 +132,7 @@ chroma_LTLIBRARIES += \
libd3d11_surface_plugin.la
endif
-libcvpx_plugin_la_SOURCES = video_chroma/cvpx.c video_chroma/copy.c video_chroma/copy.h \
+libcvpx_plugin_la_SOURCES = video_chroma/cvpx.c \
codec/vt_utils.c codec/vt_utils.h
libcvpx_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(chromadir)' -Wl,-framework,Foundation -Wl,-framework,VideoToolbox -Wl,-framework,CoreMedia -Wl,-framework,CoreVideo
EXTRA_LTLIBRARIES += libcvpx_plugin.la
diff --git a/modules/video_chroma/cvpx.c b/modules/video_chroma/cvpx.c
index 246d60bb6c..4da92ae7de 100644
--- a/modules/video_chroma/cvpx.c
+++ b/modules/video_chroma/cvpx.c
@@ -30,69 +30,184 @@
#include <vlc_plugin.h>
#include <vlc_filter.h>
#include <vlc_picture.h>
+#include <vlc_modules.h>
#include "../codec/vt_utils.h"
-#include "copy.h"
-static int Activate(vlc_object_t *);
+static int Open(vlc_object_t *);
+static void Close(vlc_object_t *);
vlc_module_begin ()
- set_description( N_("Conversions from CoreVideo buffers to I420") )
- set_capability( "video converter", 10 )
- set_callbacks( Activate, NULL )
+ set_description("Conversions from/to CoreVideo buffers")
+ set_capability("video converter", 10)
+ set_callbacks(Open, Close)
vlc_module_end ()
-static void CVPX_I420(filter_t *p_filter, picture_t *src, picture_t *dst)
+struct filter_sys_t
{
- VLC_UNUSED(p_filter);
- assert(src->context != NULL);
+ filter_t *p_sw_filter;
+ CVPixelBufferPoolRef pool;
+};
- CVPixelBufferRef pixelBuffer = cvpxpic_get_ref(src);
+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);
- unsigned width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0);
- unsigned height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0);
+ dst = p_sw_filter->pf_video_filter(p_sw_filter, src_sw);
- if (width == 0 || height == 0)
- return;
+ return dst;
+}
- uint8_t *pp_plane[2];
- size_t pi_pitch[2];
+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;
- CVPixelBufferLockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
+ CVPixelBufferRef cvpx = cvpxpool_get_cvpx(p_sys->pool);
+ if (cvpx == NULL)
+ return NULL;
- for (int i = 0; i < 2; i++) {
- pp_plane[i] = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, i);
- pi_pitch[i] = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, i);
- }
+ picture_t *pic =
+ cvpxpic_create_mapped(&p_sw_filter->fmt_out.video, cvpx, false);
+ CFRelease(cvpx);
+ return pic;
+}
- copy_cache_t cache;
+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;
- if (CopyInitCache(&cache, width))
- return;
+ picture_t *sw_dst = p_sw_filter->pf_video_filter(p_sw_filter, src);
+ if (sw_dst == NULL)
+ return NULL;
- CopyFromNv12ToI420(dst, pp_plane, pi_pitch, height, &cache);
+ 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;
- CopyCleanCache(&cache);
+ 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);
+ }
- CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
+ if (p_sys->pool != NULL)
+ CVPixelBufferPoolRelease(p_sys->pool);
+ free(p_sys);
}
-VIDEO_FILTER_WRAPPER(CVPX_I420)
-
-static int Activate(vlc_object_t *obj)
+static int Open(vlc_object_t *obj)
{
filter_t *p_filter = (filter_t *)obj;
- if (p_filter->fmt_in.video.i_chroma != VLC_CODEC_CVPX_NV12)
- return VLC_EGENERIC;
if (p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height
|| p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width)
return VLC_EGENERIC;
- if (p_filter->fmt_out.video.i_chroma != VLC_CODEC_I420)
- return VLC_EGENERIC;
+#define CASE_CVPX_INPUT(x) \
+ case VLC_CODEC_CVPX_##x: \
+ if (p_filter->fmt_out.video.i_chroma != VLC_CODEC_I420) \
+ return VLC_EGENERIC; \
+ 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 = p_filter->owner; \
+ b_need_pool = false;
+
+#define CASE_CVPX_OUTPUT(x) \
+ case VLC_CODEC_CVPX_##x: \
+ if (p_filter->fmt_in.video.i_chroma != VLC_CODEC_I420) \
+ return VLC_EGENERIC; \
+ 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; \
+ 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 = {};
+ switch (p_filter->fmt_in.video.i_chroma)
+ {
+ CASE_CVPX_INPUT(NV12)
+ break;
+ CASE_CVPX_INPUT(UYVY)
+ break;
+ CASE_CVPX_INPUT(I420)
+ break;
+ default:
+ switch (p_filter->fmt_out.video.i_chroma)
+ {
+ CASE_CVPX_OUTPUT(NV12)
+ break;
+ CASE_CVPX_OUTPUT(UYVY)
+ break;
+ CASE_CVPX_OUTPUT(I420)
+ break;
+ default:
+ return VLC_EGENERIC;
+ }
+ }
+
+ filter_sys_t *p_sys = p_filter->p_sys = malloc(sizeof(filter_sys_t));
+
+ if (unlikely(!p_sys))
+ return VLC_ENOMEM;
+
+ p_sys->p_sw_filter = NULL;
+ p_sys->pool = NULL;
+
+ if (b_need_pool
+ && (p_sys->pool = cvpxpool_create(&p_filter->fmt_out.video, 3)) == NULL)
+ goto error;
+
+ 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);
+ goto error;
+ }
+ p_sys->p_sw_filter = p_sw_filter;
- p_filter->pf_video_filter = CVPX_I420_Filter;
return VLC_SUCCESS;
-}
+error:
+ Close(obj);
+ return VLC_EGENERIC;
+#undef CASE_CVPX_INPUT
+#undef CASE_CVPX_OUTPUT
+}
More information about the vlc-commits
mailing list