* Preamble
*****************************************************************************/
-#include <vlc/vlc.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
#include <vlc_vout.h>
#include "filter_common.h"
static void Render ( vout_thread_t *, picture_t * );
static void FilterPlanar( vout_thread_t *, const picture_t *, picture_t * );
+static void FilterI422( vout_thread_t *, const picture_t *, picture_t * );
static void FilterYUYV( vout_thread_t *, const picture_t *, picture_t * );
static int SendEvents( vlc_object_t *, char const *,
#define TYPE_TEXT N_("Transform type")
#define TYPE_LONGTEXT N_("One of '90', '180', '270', 'hflip' and 'vflip'")
-static const char *type_list[] = { "90", "180", "270", "hflip", "vflip" };
-static const char *type_list_text[] = { N_("Rotate by 90 degrees"),
+static const char *const type_list[] = { "90", "180", "270", "hflip", "vflip" };
+static const char *const type_list_text[] = { N_("Rotate by 90 degrees"),
N_("Rotate by 180 degrees"), N_("Rotate by 270 degrees"),
N_("Flip horizontally"), N_("Flip vertically") };
#define CFG_PREFIX "transform-"
vlc_module_begin();
- set_description( _("Video transformation filter") );
- set_shortname( _("Transformation"));
+ set_description( N_("Video transformation filter") );
+ set_shortname( N_("Transformation"));
set_capability( "video filter", 0 );
set_category( CAT_VIDEO );
set_subcategory( SUBCAT_VIDEO_VFILTER );
add_string( CFG_PREFIX "type", "90", NULL,
- TYPE_TEXT, TYPE_LONGTEXT, VLC_FALSE);
- change_safe();
+ TYPE_TEXT, TYPE_LONGTEXT, false);
change_string_list( type_list, type_list_text, 0);
add_shortcut( "transform" );
set_callbacks( Create, Destroy );
vlc_module_end();
-static const char *ppsz_filter_options[] = {
+static const char *const ppsz_filter_options[] = {
"type", NULL
};
struct vout_sys_t
{
int i_mode;
- vlc_bool_t b_rotation;
+ bool b_rotation;
vout_thread_t *p_vout;
void (*pf_filter)( vout_thread_t *, const picture_t *, picture_t * );
switch( p_vout->fmt_in.i_chroma )
{
- CASE_PLANAR_YUV
+ CASE_PLANAR_YUV_SQUARE
case VLC_FOURCC('G','R','E','Y'):
p_vout->p_sys->pf_filter = FilterPlanar;
break;
+ case VLC_FOURCC('I','4','2','2'):
+ case VLC_FOURCC('J','4','2','2'):
+ p_vout->p_sys->pf_filter = FilterI422;
+ break;
+
CASE_PACKED_YUV_422
p_vout->p_sys->pf_filter = FilterYUYV;
break;
static int SendEvents( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *_p_vout )
{
+ VLC_UNUSED(p_this); VLC_UNUSED(oldval);
vout_thread_t *p_vout = (vout_thread_t *)_p_vout;
vlc_value_t sentval = newval;
static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
+ VLC_UNUSED(p_data); VLC_UNUSED(oldval);
vout_thread_t *p_vout = (vout_thread_t *)p_this;
var_Set( p_vout->p_sys->p_vout, psz_var, newval );
return VLC_SUCCESS;
for( ; p_in < p_in_end ; )
{
p_in_end -= p_pic->p[i_index].i_pitch;
- p_vout->p_libvlc->pf_memcpy( p_out, p_in_end,
- p_pic->p[i_index].i_visible_pitch );
+ vlc_memcpy( p_out, p_in_end,
+ p_pic->p[i_index].i_visible_pitch );
p_out += p_pic->p[i_index].i_pitch;
}
}
}
}
+static void FilterI422( vout_thread_t *p_vout,
+ const picture_t *p_pic, picture_t *p_outpic )
+{
+ int i_index;
+ switch( p_vout->p_sys->i_mode )
+ {
+ case TRANSFORM_MODE_180:
+ case TRANSFORM_MODE_HFLIP:
+ case TRANSFORM_MODE_VFLIP:
+ /* Fall back on the default implementation */
+ FilterPlanar( p_vout, p_pic, p_outpic );
+ return;
+
+ case TRANSFORM_MODE_90:
+ for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ )
+ {
+ int i_pitch = p_pic->p[i_index].i_pitch;
+
+ uint8_t *p_in = p_pic->p[i_index].p_pixels;
+
+ uint8_t *p_out = p_outpic->p[i_index].p_pixels;
+ uint8_t *p_out_end = p_out +
+ p_outpic->p[i_index].i_visible_lines *
+ p_outpic->p[i_index].i_pitch;
+
+ if( i_index == 0 )
+ {
+ for( ; p_out < p_out_end ; )
+ {
+ uint8_t *p_line_end;
+
+ p_out_end -= p_outpic->p[i_index].i_pitch
+ - p_outpic->p[i_index].i_visible_pitch;
+ p_line_end = p_in + p_pic->p[i_index].i_visible_lines *
+ i_pitch;
+
+ for( ; p_in < p_line_end ; )
+ {
+ p_line_end -= i_pitch;
+ *(--p_out_end) = *p_line_end;
+ }
+
+ p_in++;
+ }
+ }
+ else /* i_index == 1 or 2 */
+ {
+ for( ; p_out < p_out_end ; )
+ {
+ uint8_t *p_line_end, *p_out_end2;
+
+ p_out_end -= p_outpic->p[i_index].i_pitch
+ - p_outpic->p[i_index].i_visible_pitch;
+ p_out_end2 = p_out_end - p_outpic->p[i_index].i_pitch;
+ p_line_end = p_in + p_pic->p[i_index].i_visible_lines *
+ i_pitch;
+
+ for( ; p_in < p_line_end ; )
+ {
+ uint8_t p1, p2;
+
+ p_line_end -= i_pitch;
+ p1 = *p_line_end;
+ p_line_end -= i_pitch;
+ p2 = *p_line_end;
+
+ /* Trick for (x+y)/2 without overflow, based on
+ * x + y == (x ^ y) + 2 * (x & y) */
+ *(--p_out_end) = (p1 & p2) + ((p1 ^ p2) / 2);
+ *(--p_out_end2) = (p1 & p2) + ((p1 ^ p2) / 2);
+ }
+
+ p_out_end = p_out_end2;
+ p_in++;
+ }
+ }
+ }
+ break;
+
+ case TRANSFORM_MODE_270:
+ for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ )
+ {
+ int i_pitch = p_pic->p[i_index].i_pitch;
+
+ uint8_t *p_in = p_pic->p[i_index].p_pixels;
+
+ uint8_t *p_out = p_outpic->p[i_index].p_pixels;
+ uint8_t *p_out_end = p_out +
+ p_outpic->p[i_index].i_visible_lines *
+ p_outpic->p[i_index].i_pitch;
+
+ if( i_index == 0 )
+ {
+ for( ; p_out < p_out_end ; )
+ {
+ uint8_t *p_in_end;
+
+ p_in_end = p_in + p_pic->p[i_index].i_visible_lines *
+ i_pitch;
+
+ for( ; p_in < p_in_end ; )
+ {
+ p_in_end -= i_pitch;
+ *p_out++ = *p_in_end;
+ }
+
+ p_out += p_outpic->p[i_index].i_pitch
+ - p_outpic->p[i_index].i_visible_pitch;
+ p_in++;
+ }
+ }
+ else /* i_index == 1 or 2 */
+ {
+ for( ; p_out < p_out_end ; )
+ {
+ uint8_t *p_in_end, *p_out2;
+
+ p_in_end = p_in + p_pic->p[i_index].i_visible_lines *
+ i_pitch;
+ p_out2 = p_out + p_outpic->p[i_index].i_pitch;
+
+ for( ; p_in < p_in_end ; )
+ {
+ uint8_t p1, p2;
+
+ p_in_end -= i_pitch;
+ p1 = *p_in_end;
+ p_in_end -= i_pitch;
+ p2 = *p_in_end;
+
+ /* Trick for (x+y)/2 without overflow, based on
+ * x + y == (x ^ y) + 2 * (x & y) */
+ *p_out++ = (p1 & p2) + ((p1 ^ p2) / 2);
+ *p_out2++ = (p1 & p2) + ((p1 ^ p2) / 2);
+ }
+
+ p_out2 += p_outpic->p[i_index].i_pitch
+ - p_outpic->p[i_index].i_visible_pitch;
+ p_out = p_out2;
+ p_in++;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
static void FilterYUYV( vout_thread_t *p_vout,
const picture_t *p_pic, picture_t *p_outpic )
{
switch( p_vout->p_sys->i_mode )
{
+ case TRANSFORM_MODE_HFLIP:
+ /* Fall back on the default implementation */
+ FilterPlanar( p_vout, p_pic, p_outpic );
+ return;
+
case TRANSFORM_MODE_90:
for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ )
{
}
break;
- case TRANSFORM_MODE_HFLIP:
- for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ )
- {
- uint8_t *p_in = p_pic->p[i_index].p_pixels;
- uint8_t *p_in_end = p_in + p_pic->p[i_index].i_visible_lines
- * p_pic->p[i_index].i_pitch;
-
- uint8_t *p_out = p_outpic->p[i_index].p_pixels;
-
- for( ; p_in < p_in_end ; )
- {
- p_in_end -= p_pic->p[i_index].i_pitch;
- p_vout->p_libvlc->pf_memcpy( p_out, p_in_end,
- p_pic->p[i_index].i_visible_pitch );
- p_out += p_pic->p[i_index].i_pitch;
- }
- }
- break;
-
case TRANSFORM_MODE_VFLIP:
for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ )
{