From 37becd478f7fa51e8aebd595d7aebb205dfc1951 Mon Sep 17 00:00:00 2001 From: Antoine Cellerier Date: Sun, 25 Nov 2007 13:32:20 +0000 Subject: [PATCH] Split i422->packed YUV and i422->planar YUV. Add i422->YUVA. This still needs some testing. --- configure.ac | 2 +- modules/video_chroma/Modules.am | 4 + modules/video_chroma/i422_i420.c | 170 +++++++++++++++++++++++++++++++ modules/video_chroma/i422_yuy2.c | 40 +------- 4 files changed, 176 insertions(+), 40 deletions(-) create mode 100644 modules/video_chroma/i422_i420.c diff --git a/configure.ac b/configure.ac index 15156bbf05..fe0cb466e3 100644 --- a/configure.ac +++ b/configure.ac @@ -1262,7 +1262,7 @@ if test "${SYS}" != "mingwce"; then VLC_ADD_PLUGINS([access_fake access_filter_timeshift access_filter_record access_filter_dump]) VLC_ADD_PLUGINS([gestures rc telnet hotkeys showintf marq podcast shout sap fake folder]) VLC_ADD_PLUGINS([rss mosaic wall motiondetect clone crop erase bluescreen alphamask gaussianblur]) - VLC_ADD_PLUGINS([i420_yuy2 i422_yuy2 i420_ymga]) + VLC_ADD_PLUGINS([i420_yuy2 i422_yuy2 i420_ymga i422_i420]) VLC_ADD_PLUGINS([aout_file linear_resampler bandlimited_resampler]) VLC_ADD_PLUGINS([float32_mixer spdif_mixer simple_channel_mixer]) VLC_ADD_PLUGINS([dolby_surround_decoder headphone_channel_mixer normvol equalizer param_eq]) diff --git a/modules/video_chroma/Modules.am b/modules/video_chroma/Modules.am index 8ea7e1aca2..aea44233db 100644 --- a/modules/video_chroma/Modules.am +++ b/modules/video_chroma/Modules.am @@ -55,6 +55,10 @@ SOURCES_i422_yuy2_sse2 = \ i422_yuy2.h \ $(NULL) +SOURCES_i422_i420 = \ + i422_i420.c \ + $(NULL) + SOURCES_i420_ymga = \ i420_ymga.c \ $(NULL) diff --git a/modules/video_chroma/i422_i420.c b/modules/video_chroma/i422_i420.c new file mode 100644 index 0000000000..92fd1bf4e3 --- /dev/null +++ b/modules/video_chroma/i422_i420.c @@ -0,0 +1,170 @@ +/***************************************************************************** + * i422_i420.c : Planar YUV 4:2:2 to Planar YUV 4:2:0 conversion module for vlc + ***************************************************************************** + * Copyright (C) 2000, 2001 - 2007 the VideoLAN team + * $Id$ + * + * Authors: Samuel Hocevar + * Damien Fouilleul + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ + +#include +#include + +#define SRC_FOURCC "I422,J422" +#define DEST_FOURCC "I420,IYUV,J420,YV12,YUVA" + +/***************************************************************************** + * Local and extern prototypes. + *****************************************************************************/ +static int Activate ( vlc_object_t * ); + +static void I422_I420( vout_thread_t *, picture_t *, picture_t * ); +static void I422_YV12( vout_thread_t *, picture_t *, picture_t * ); +static void I422_YUVA( vout_thread_t *, picture_t *, picture_t * ); + +/***************************************************************************** + * Module descriptor + *****************************************************************************/ +vlc_module_begin(); + set_description( _("Conversions from " SRC_FOURCC " to " DEST_FOURCC) ); + set_capability( "chroma", 60 ); + set_callbacks( Activate, NULL ); +vlc_module_end(); + +/***************************************************************************** + * Activate: allocate a chroma function + ***************************************************************************** + * This function allocates and initializes a chroma function + *****************************************************************************/ +static int Activate( vlc_object_t *p_this ) +{ + vout_thread_t *p_vout = (vout_thread_t *)p_this; + + if( p_vout->render.i_width & 1 || p_vout->render.i_height & 1 ) + { + return -1; + } + + switch( p_vout->render.i_chroma ) + { + case VLC_FOURCC('I','4','2','2'): + case VLC_FOURCC('J','4','2','2'): + switch( p_vout->output.i_chroma ) + { + case VLC_FOURCC('I','4','2','0'): + case VLC_FOURCC('I','Y','U','V'): + case VLC_FOURCC('J','4','2','0'): + p_vout->chroma.pf_convert = I422_I420; + break; + + case VLC_FOURCC('Y','V','1','2'): + p_vout->chroma.pf_convert = I422_YV12; + break; + + case VLC_FOURCC('Y','U','V','A'): + p_vout->chroma.pf_convert = I422_YUVA; + break; + + default: + return -1; + } + break; + + default: + return -1; + } + return 0; +} + +/* Following functions are local */ + +/***************************************************************************** + * I422_I420: planar YUV 4:2:2 to planar I420 4:2:0 Y:U:V + *****************************************************************************/ +static void I422_I420( vout_thread_t *p_vout, picture_t *p_source, + picture_t *p_dest ) +{ + uint16_t i_dpy = p_dest->p[Y_PLANE].i_pitch; + uint16_t i_spy = p_source->p[Y_PLANE].i_pitch; + uint16_t i_dpuv = p_dest->p[U_PLANE].i_pitch; + uint16_t i_spuv = p_source->p[U_PLANE].i_pitch; + uint16_t i_width = p_vout->render.i_width; + uint16_t i_y = p_vout->render.i_height; + uint8_t *p_dy = p_dest->Y_PIXELS + (i_y-1)*i_dpy; + uint8_t *p_y = p_source->Y_PIXELS + (i_y-1)*i_spy; + uint8_t *p_du = p_dest->U_PIXELS + (i_y/2-1)*i_dpuv; + uint8_t *p_u = p_source->U_PIXELS + (i_y-1)*i_spuv; + uint8_t *p_dv = p_dest->V_PIXELS + (i_y/2-1)*i_dpuv; + uint8_t *p_v = p_source->V_PIXELS + (i_y-1)*i_spuv; + void *(*pf_memcpy)(void *, const void *, size_t) = p_vout->p_libvlc->pf_memcpy; + i_y /= 2; + + for ( ; i_y--; ) + { + pf_memcpy(p_dy, p_y, i_width); p_dy -= i_dpy; p_y -= i_spy; + pf_memcpy(p_dy, p_y, i_width); p_dy -= i_dpy; p_y -= i_spy; + pf_memcpy(p_du, p_u, i_width/2); p_du -= i_dpuv; p_u -= 2*i_spuv; + pf_memcpy(p_dv, p_v, i_width/2); p_dv -= i_dpuv; p_v -= 2*i_spuv; + } +} + +/***************************************************************************** + * I422_YV12: planar YUV 4:2:2 to planar YV12 4:2:0 Y:V:U + *****************************************************************************/ +static void I422_YV12( vout_thread_t *p_vout, picture_t *p_source, + picture_t *p_dest ) +{ + uint16_t i_dpy = p_dest->p[Y_PLANE].i_pitch; + uint16_t i_spy = p_source->p[Y_PLANE].i_pitch; + uint16_t i_dpuv = p_dest->p[U_PLANE].i_pitch; + uint16_t i_spuv = p_source->p[U_PLANE].i_pitch; + uint16_t i_width = p_vout->render.i_width; + uint16_t i_y = p_vout->render.i_height; + uint8_t *p_dy = p_dest->Y_PIXELS + (i_y-1)*i_dpy; + uint8_t *p_y = p_source->Y_PIXELS + (i_y-1)*i_spy; + uint8_t *p_du = p_dest->V_PIXELS + (i_y/2-1)*i_dpuv; /* U and V are swapped */ + uint8_t *p_u = p_source->U_PIXELS + (i_y-1)*i_spuv; + uint8_t *p_dv = p_dest->U_PIXELS + (i_y/2-1)*i_dpuv; /* U and V are swapped */ + uint8_t *p_v = p_source->V_PIXELS + (i_y-1)*i_spuv; + void *(*pf_memcpy)(void *, const void *, size_t) = p_vout->p_libvlc->pf_memcpy; + i_y /= 2; + + for ( ; i_y--; ) + { + pf_memcpy(p_dy, p_y, i_width); p_dy -= i_dpy; p_y -= i_spy; + pf_memcpy(p_dy, p_y, i_width); p_dy -= i_dpy; p_y -= i_spy; + pf_memcpy(p_du, p_u, i_width/2); p_du -= i_dpuv; p_u -= 2*i_spuv; + pf_memcpy(p_dv, p_v, i_width/2); p_dv -= i_dpuv; p_v -= 2*i_spuv; + } +} + +/***************************************************************************** + * I422_YUVA: planar YUV 4:2:2 to planar YUVA 4:2:0:4 Y:U:V:A + *****************************************************************************/ +static void I422_YUVA( vout_thread_t *p_vout, picture_t *p_source, + picture_t *p_dest ) +{ + I422_I420( p_vout, p_source, p_dest ); + p_vout->p_libvlc->pf_memset( p_dest->p[A_PLANE].p_pixels, 0xff, + p_dest->p[A_PLANE].i_lines + * p_dest->p[A_PLANE].i_pitch ); +} diff --git a/modules/video_chroma/i422_yuy2.c b/modules/video_chroma/i422_yuy2.c index ec1a90305d..932500f5ce 100644 --- a/modules/video_chroma/i422_yuy2.c +++ b/modules/video_chroma/i422_yuy2.c @@ -1,5 +1,5 @@ /***************************************************************************** - * i422_yuy2.c : YUV to YUV conversion module for vlc + * i422_yuy2.c : Planar YUV 4:2:2 to Packed YUV conversion module for vlc ***************************************************************************** * Copyright (C) 2000, 2001 the VideoLAN team * $Id$ @@ -51,7 +51,6 @@ static void I422_cyuv ( vout_thread_t *, picture_t *, picture_t * ); #if defined (MODULE_NAME_IS_i422_yuy2) static void I422_Y211 ( vout_thread_t *, picture_t *, picture_t * ); static void I422_Y211 ( vout_thread_t *, picture_t *, picture_t * ); -static void I422_YV12 ( vout_thread_t *, picture_t *, picture_t * ); #endif /***************************************************************************** @@ -119,10 +118,6 @@ static int Activate( vlc_object_t *p_this ) case VLC_FOURCC('Y','2','1','1'): p_vout->chroma.pf_convert = I422_Y211; break; - - case VLC_FOURCC('Y','V','1','2'): - p_vout->chroma.pf_convert = I422_YV12; - break; #endif default: @@ -548,36 +543,3 @@ static void I422_Y211( vout_thread_t *p_vout, picture_t *p_source, } } #endif - - -/***************************************************************************** - * I422_YV12: planar YUV 4:2:2 to planar YV12 - *****************************************************************************/ -#if defined (MODULE_NAME_IS_i422_yuy2) -static void I422_YV12( vout_thread_t *p_vout, picture_t *p_source, - picture_t *p_dest ) -{ - uint16_t i_dpy = p_dest->p[Y_PLANE].i_pitch; - uint16_t i_spy = p_source->p[Y_PLANE].i_pitch; - uint16_t i_dpuv = p_dest->p[U_PLANE].i_pitch; - uint16_t i_spuv = p_source->p[U_PLANE].i_pitch; - uint16_t i_width = p_vout->render.i_width; - uint16_t i_y = p_vout->render.i_height; - uint8_t *p_dy = p_dest->Y_PIXELS + (i_y-1)*i_dpy; - uint8_t *p_y = p_source->Y_PIXELS + (i_y-1)*i_spy; - uint8_t *p_du = p_dest->U_PIXELS + (i_y/2-1)*i_dpuv; - uint8_t *p_u = p_source->U_PIXELS + (i_y-1)*i_spuv; - uint8_t *p_dv = p_dest->V_PIXELS + (i_y/2-1)*i_dpuv; - uint8_t *p_v = p_source->V_PIXELS + (i_y-1)*i_spuv; - i_y /= 2; - - for ( ; i_y--; ) - { - memcpy(p_dy, p_y, i_width); p_dy -= i_dpy; p_y -= i_spy; - memcpy(p_dy, p_y, i_width); p_dy -= i_dpy; p_y -= i_spy; - memcpy(p_du, p_u, i_width/2); p_du -= i_dpuv; p_u -= 2*i_spuv; - memcpy(p_dv, p_v, i_width/2); p_dv -= i_dpuv; p_v -= 2*i_spuv; - } - -} -#endif -- 2.39.2