[vlc-devel] [PATCH 2/9] Add transform helper functions.

Rémi Denis-Courmont remi at remlab.net
Wed Mar 5 18:12:29 CET 2014


Le mercredi 5 mars 2014, 17:01:23 Matthias Keiser a écrit :
> ---
>  include/vlc_es.h     |  48 +++++++++++++
>  src/misc/es_format.c | 196
> +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 244
> insertions(+)
> 
> diff --git a/include/vlc_es.h b/include/vlc_es.h
> index 38d63da..d7e43e7 100644
> --- a/include/vlc_es.h
> +++ b/include/vlc_es.h
> @@ -153,6 +153,8 @@ typedef enum video_orientation_t
>      ORIENT_RIGHT_BOTTOM, /**< Anti-transposed */
> 
>      ORIENT_NORMAL      = ORIENT_TOP_LEFT,
> +    ORIENT_TRANSPOSED  = ORIENT_LEFT_TOP,
> +    ORIENT_ANTI_TRANSPOSED = ORIENT_RIGHT_BOTTOM,
>      ORIENT_HFLIPPED    = ORIENT_TOP_RIGHT,
>      ORIENT_VFLIPPED    = ORIENT_BOTTOM_LEFT,
>      ORIENT_ROTATED_180 = ORIENT_BOTTOM_RIGHT,
> @@ -174,6 +176,18 @@ typedef enum video_orientation_t
>  /** Applies horizontal flip to an orientation */
>  #define ORIENT_ROTATE_180(orient) ((orient) ^ 3)
> 
> +typedef enum video_transform_t
> +{
> +    TRANSFORM_IDENTIY = 0,
> +    TRANSFORM_HFLIP,
> +    TRANSFORM_VFLIP,
> +    TRANSFORM_R90,
> +    TRANSFORM_R180,
> +    TRANSFORM_R270,
> +    TRANSFORM_TRANSPOSE,
> +    TRANSFORM_ANTI_TRANSPOSE
> +} video_transform_t;
> +

I don't understand why you need a second identical enumeration.

>  /**
>   * video format description
>   */
> @@ -265,6 +279,28 @@ VLC_API void video_format_CopyCrop( video_format_t *,
> const video_format_t * ); VLC_API void video_format_ScaleCropAr(
> video_format_t *, const video_format_t * );
> 
>  /**
> + * This function "normalizes" the formats orientation, by switching the a/r
> according to the orientation, + * producing a format whose orientation is
> ORIENT_NORMAL. It makes a shallow copy (pallette is not alloc'ed). + */
> +VLC_API void video_format_ApplyRotation(const video_format_t * restrict in,
> video_format_t * restrict out); +
> +/**
> + * This function applies the transform operation to fmt.
> + */
> +VLC_API void video_format_TransformBy(video_format_t *fmt,
> video_transform_t transform); +
> +/**
> + * This function applies the transforms necessary to fmt so that the
> resulting fmt + * has the dst_orientation.
> + */
> +VLC_API void video_format_TransformTo(video_format_t *fmt,
> video_orientation_t dst_orientation); +
> +/**
> + * Returns the operation required to transform src into dst.
> + */
> +VLC_API video_transform_t orientation_GetTransform(video_orientation_t src,
> video_orientation_t dst);

Please do not add to the existing shared object prefix namespace pollution.

> +
> +/**
>   * This function will check if the first video format is similar
>   * to the second one.
>   */
> @@ -275,6 +311,18 @@ VLC_API bool video_format_IsSimilar( const
> video_format_t *, const video_format_ */
>  VLC_API void video_format_Print( vlc_object_t *, const char *, const
> video_format_t * );
> 
> +
> +static inline video_transform_t transform_Inverse( video_transform_t
> transform ) +{
> +    switch ( transform ) {
> +        case TRANSFORM_R90:
> +            return TRANSFORM_R270;
> +        case TRANSFORM_R270:
> +            return TRANSFORM_R90;
> +        default:
> +            return transform;
> +    }
> +}
>  /**
>   * subtitles format description
>   */
> diff --git a/src/misc/es_format.c b/src/misc/es_format.c
> index 8936414..101974b 100644
> --- a/src/misc/es_format.c
> +++ b/src/misc/es_format.c
> @@ -244,6 +244,202 @@ void video_format_ScaleCropAr( video_format_t *p_dst,
> const video_format_t *p_sr p_dst->i_sar_num, p_dst->i_sar_den, 65536);
>  }
> 
> +//Simplify transforms to have something more managable. Order: angle,
> hflip. +void transform_GetBasicOps( video_transform_t transform, int
> *angle, int *hflip ) { +
> +    *angle = 0;
> +    *hflip = 0;
> +
> +    switch ( transform ) {
> +
> +        case TRANSFORM_R90:
> +            *angle = 90;
> +            break;
> +        case TRANSFORM_R180:
> +            *angle = 180;
> +            break;
> +        case TRANSFORM_R270:
> +            *angle = 270;
> +            break;
> +        case TRANSFORM_HFLIP:
> +            *hflip = 1;
> +            break;
> +        case TRANSFORM_VFLIP:
> +            *angle = 180;
> +            *hflip = 1;
> +            break;
> +        case TRANSFORM_TRANSPOSE:
> +            *angle = 90;
> +            *hflip = 1;
> +            break;
> +        case TRANSFORM_ANTI_TRANSPOSE:
> +            *angle = 270;
> +            *hflip = 1;
> +            break;
> +    }
> +}
> +
> +video_transform_t transform_FromBasicOps( int angle, int hflip )
> +{
> +    switch ( angle ) {
> +        case 0:
> +            return hflip ? TRANSFORM_HFLIP : TRANSFORM_IDENTIY;
> +        case 90:
> +            return hflip ? TRANSFORM_TRANSPOSE : TRANSFORM_R90;
> +        case 180:
> +            return hflip ? TRANSFORM_VFLIP : TRANSFORM_R180;
> +        case 270:
> +            return hflip ? TRANSFORM_ANTI_TRANSPOSE : TRANSFORM_R270;
> +        default:
> +            return TRANSFORM_IDENTIY;
> +    }
> +}
> +
> +video_transform_t orientation_GetNormalTransform( video_orientation_t
> orient ) +{
> +    switch( orient ) {
> +
> +        case ORIENT_ROTATED_90:
> +            return TRANSFORM_R90;
> +        case ORIENT_ROTATED_180:
> +            return TRANSFORM_R180;
> +        case ORIENT_ROTATED_270:
> +            return TRANSFORM_R270;
> +        case ORIENT_HFLIPPED:
> +            return TRANSFORM_HFLIP;
> +        case ORIENT_VFLIPPED:
> +            return TRANSFORM_VFLIP;
> +        case ORIENT_TRANSPOSED:
> +            return TRANSFORM_TRANSPOSE;
> +        case ORIENT_ANTI_TRANSPOSED:
> +            return TRANSFORM_ANTI_TRANSPOSE;
> +        default:
> +            return TRANSFORM_IDENTIY;
> +    }
> +}
> +
> +video_transform_t orientation_GetTransform( video_orientation_t src,
> video_orientation_t dst ) +{
> +    int angle1 = 0;
> +    int hflip1 = 0;
> +
> +    transform_GetBasicOps( orientation_GetNormalTransform( src ), &angle1,
> &hflip1 ); +
> +    int angle2 = 0;
> +    int hflip2 = 0;
> +
> +    transform_GetBasicOps( transform_Inverse(
> orientation_GetNormalTransform( dst )), &angle2, &hflip2 ); +
> +    int angle = (angle1 + angle2) % 360;
> +    int hflip = (hflip1 + hflip2) % 2;
> +
> +    return transform_FromBasicOps(angle, hflip);
> +}
> +
> +void video_format_TransformTo( video_format_t *fmt, video_orientation_t
> dst_orientation ) +{
> +    video_transform_t transform =
> orientation_GetTransform(fmt->orientation, dst_orientation); +
> +    video_format_TransformBy(fmt, transform);
> +}
> +
> +void video_format_TransformBy( video_format_t *fmt, video_transform_t
> transform ) +{
> +    /* Get destination orientation */
> +
> +    int angle1 = 0;
> +    int hflip1 = 0;
> +
> +    transform_GetBasicOps( transform, &angle1, &hflip1 );
> +
> +    int angle2 = 0;
> +    int hflip2 = 0;
> +
> +    transform_GetBasicOps( orientation_GetNormalTransform( fmt->orientation
> ), &angle2, &hflip2 ); +
> +    int angle = (angle2 - angle1 + 360) % 360;
> +    int hflip = (hflip2 - hflip1 + 2) % 2;
> +
> +    video_orientation_t dst_orient = ORIENT_NORMAL;
> +
> +    if( hflip ) {
> +
> +        if( angle == 0 )
> +            dst_orient = ORIENT_HFLIPPED;
> +        else if( angle == 90 )
> +            dst_orient = ORIENT_ANTI_TRANSPOSED;
> +        else if( angle == 180 )
> +            dst_orient = ORIENT_VFLIPPED;
> +        else if( angle == 270 )
> +            dst_orient = ORIENT_TRANSPOSED;
> +    }
> +    else {
> +
> +        if( angle == 90 )
> +            dst_orient = ORIENT_ROTATED_90;
> +        else if( angle == 180 )
> +            dst_orient = ORIENT_ROTATED_180;
> +        else if( angle == 270 )
> +            dst_orient = ORIENT_ROTATED_270;
> +    }
> +
> +    /* Apply transform */
> +
> +    video_format_t scratch = *fmt;
> +
> +    if( ORIENT_IS_SWAP( fmt->orientation ) != ORIENT_IS_SWAP( dst_orient ))
> { +
> +        fmt->i_width = scratch.i_height;
> +        fmt->i_visible_width = scratch.i_visible_height;
> +        fmt->i_height = scratch.i_width;
> +        fmt->i_visible_height = scratch.i_visible_width;
> +        fmt->i_sar_num = scratch.i_sar_den;
> +        fmt->i_sar_den = scratch.i_sar_num;
> +    }
> +
> +    unsigned int delta_y = scratch.i_height - scratch.i_visible_height -
> scratch.i_y_offset; +    unsigned int delta_x = scratch.i_width -
> scratch.i_visible_width - scratch.i_x_offset; +
> +    switch ( transform )
> +    {
> +        case TRANSFORM_R90:
> +            fmt->i_x_offset = delta_y;
> +            fmt->i_y_offset = scratch.i_x_offset;
> +            break;
> +        case TRANSFORM_R180:
> +            fmt->i_x_offset = delta_x;
> +            fmt->i_y_offset = delta_y;
> +            break;
> +        case TRANSFORM_R270:
> +            fmt->i_x_offset = scratch.i_y_offset;
> +            fmt->i_y_offset = delta_x;
> +            break;
> +        case TRANSFORM_HFLIP:
> +            fmt->i_x_offset = delta_x;
> +            break;
> +        case TRANSFORM_VFLIP:
> +            fmt->i_y_offset = delta_y;
> +            break;
> +        case TRANSFORM_TRANSPOSE:
> +            fmt->i_x_offset = scratch.i_y_offset;
> +            fmt->i_y_offset = scratch.i_x_offset;
> +            break;
> +        case TRANSFORM_ANTI_TRANSPOSE:
> +            fmt->i_x_offset = delta_y;
> +            fmt->i_y_offset = delta_x;
> +            break;
> +    }
> +
> +    fmt->orientation = dst_orient;
> +}
> +
> +void video_format_ApplyRotation( const video_format_t * restrict in,
> video_format_t * restrict out ) +{
> +    *out = *in;
> +
> +    video_format_TransformTo(out, ORIENT_NORMAL);
> +}
> +
>  bool video_format_IsSimilar( const video_format_t *p_fmt1, const
> video_format_t *p_fmt2 ) {
>      video_format_t v1 = *p_fmt1;

-- 
Rémi Denis-Courmont
http://www.remlab.net/




More information about the vlc-devel mailing list