[vlc-devel] [PATCH 6/9] Make the chain filter handle movie rotations.

Matthias Keiser matthias at tristan-inc.com
Wed Mar 5 17:01:27 CET 2014


---
 modules/video_chroma/chain.c | 151 +++++++++++++++++++++++++++++++++++++------
 1 file changed, 130 insertions(+), 21 deletions(-)

diff --git a/modules/video_chroma/chain.c b/modules/video_chroma/chain.c
index 9088f32..0a7d3ed 100644
--- a/modules/video_chroma/chain.c
+++ b/modules/video_chroma/chain.c
@@ -51,10 +51,12 @@ vlc_module_end ()
 static picture_t *Chain         ( filter_t *, picture_t * );
 static int BufferAllocationInit ( filter_t *, void * );
 
+static int BuildTransformChain( filter_t *p_filter );
 static int BuildChromaResize( filter_t * );
 static int BuildChromaChain( filter_t *p_filter );
 
-static int CreateChain( filter_chain_t *p_chain, es_format_t *p_fmt_mid, config_chain_t * );
+static int CreateChain( filter_t *p_parent, es_format_t *p_fmt_mid, config_chain_t * );
+static filter_t * AppendTransform( filter_chain_t *p_chain, es_format_t *p_fmt_in, es_format_t *p_fmt_out );
 static void EsFormatMergeSize( es_format_t *p_dst,
                                const es_format_t *p_base,
                                const es_format_t *p_size );
@@ -88,7 +90,9 @@ static int Activate( vlc_object_t *p_this )
     const bool b_chroma = p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma;
     const bool b_resize = p_filter->fmt_in.video.i_width  != p_filter->fmt_out.video.i_width ||
                           p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height;
-    if( !b_chroma && !b_resize )
+    const bool b_transform = p_filter->fmt_in.video.orientation != p_filter->fmt_out.video.orientation;
+
+    if( !b_chroma && !b_resize && !b_transform)
         return VLC_EGENERIC;
 
     p_sys = p_filter->p_sys = calloc( 1, sizeof( *p_sys ) );
@@ -102,7 +106,9 @@ static int Activate( vlc_object_t *p_this )
         return VLC_EGENERIC;
     }
 
-    if( b_chroma && b_resize )
+    if( b_transform )
+        i_ret = BuildTransformChain( p_filter );
+    else if( b_chroma && b_resize )
         i_ret = BuildChromaResize( p_filter );
     else if( b_chroma )
         i_ret = BuildChromaChain( p_filter );
@@ -139,28 +145,50 @@ static picture_t *Chain( filter_t *p_filter, picture_t *p_pic )
 /*****************************************************************************
  * Builders
  *****************************************************************************/
+
+static int BuildTransformChain( filter_t *p_filter )
+{
+
+    es_format_t fmt_mid;
+    int i_ret;
+
+    /* Lets try transform first, then (potentially) resize+chroma */
+    msg_Dbg( p_filter, "Trying to build transform, then chroma+resize" );
+    es_format_Copy( &fmt_mid, &p_filter->fmt_in );
+    video_format_TransformTo(&fmt_mid.video, p_filter->fmt_out.video.orientation);
+    i_ret = CreateChain( p_filter, &fmt_mid, NULL );
+    es_format_Clean( &fmt_mid );
+    if( i_ret == VLC_SUCCESS )
+        return VLC_SUCCESS;
+
+    /* Lets try resize+chroma first, then transform */
+    msg_Dbg( p_filter, "Trying to build chroma+resize" );
+    EsFormatMergeSize( &fmt_mid, &p_filter->fmt_out, &p_filter->fmt_in );
+    i_ret = CreateChain( p_filter, &fmt_mid, NULL );
+    es_format_Clean( &fmt_mid );
+    if( i_ret == VLC_SUCCESS )
+        return VLC_SUCCESS;
+
+    return VLC_EGENERIC;
+}
+
 static int BuildChromaResize( filter_t *p_filter )
 {
-    filter_sys_t *p_sys = p_filter->p_sys;
     es_format_t fmt_mid;
     int i_ret;
 
     /* Lets try resizing and then doing the chroma conversion */
-    filter_chain_Reset( p_sys->p_chain, &p_filter->fmt_in, &p_filter->fmt_out );
-
     msg_Dbg( p_filter, "Trying to build resize+chroma" );
     EsFormatMergeSize( &fmt_mid, &p_filter->fmt_in, &p_filter->fmt_out );
-    i_ret = CreateChain( p_sys->p_chain, &fmt_mid, NULL );
+    i_ret = CreateChain( p_filter, &fmt_mid, NULL );
     es_format_Clean( &fmt_mid );
     if( i_ret == VLC_SUCCESS )
         return VLC_SUCCESS;
 
     /* Lets try it the other way arround (chroma and then resize) */
-    filter_chain_Reset( p_sys->p_chain, &p_filter->fmt_in, &p_filter->fmt_out );
-
     msg_Dbg( p_filter, "Trying to build chroma+resize" );
     EsFormatMergeSize( &fmt_mid, &p_filter->fmt_out, &p_filter->fmt_in );
-    i_ret = CreateChain( p_sys->p_chain, &fmt_mid, NULL );
+    i_ret = CreateChain( p_filter, &fmt_mid, NULL );
     es_format_Clean( &fmt_mid );
     if( i_ret == VLC_SUCCESS )
         return VLC_SUCCESS;
@@ -170,7 +198,6 @@ static int BuildChromaResize( filter_t *p_filter )
 
 static int BuildChromaChain( filter_t *p_filter )
 {
-    filter_sys_t *p_sys = p_filter->p_sys;
     es_format_t fmt_mid;
 
     /* We have to protect ourself against a too high recursion */
@@ -221,9 +248,7 @@ static int BuildChromaChain( filter_t *p_filter )
         fmt_mid.video.i_bmask  = 0;
         video_format_FixRgb(&fmt_mid.video);
 
-        filter_chain_Reset( p_sys->p_chain, &p_filter->fmt_in, &p_filter->fmt_out );
-
-        i_ret = CreateChain( p_sys->p_chain, &fmt_mid, &cfg_level );
+        i_ret = CreateChain( p_filter, &fmt_mid, &cfg_level );
         es_format_Clean( &fmt_mid );
 
         if( i_ret == VLC_SUCCESS )
@@ -249,7 +274,7 @@ static void BufferDel( filter_t *p_filter, picture_t *p_pic )
 {
     filter_t *p_parent = (filter_t*)p_filter->p_owner;
 
-    return filter_DeletePicture( p_parent, p_pic );
+    filter_DeletePicture( p_parent, p_pic );
 }
 static int BufferAllocationInit ( filter_t *p_filter, void *p_data )
 {
@@ -262,20 +287,99 @@ static int BufferAllocationInit ( filter_t *p_filter, void *p_data )
 /*****************************************************************************
  *
  *****************************************************************************/
-static int CreateChain( filter_chain_t *p_chain, es_format_t *p_fmt_mid, config_chain_t *p_cfg )
+static int CreateChain( filter_t *p_parent, es_format_t *p_fmt_mid, config_chain_t *p_cfg )
 {
-    filter_t *p_filter1;
-    if( !( p_filter1 =
-           filter_chain_AppendFilter( p_chain, NULL, p_cfg, NULL, p_fmt_mid )) )
+    filter_chain_Reset( p_parent->p_sys->p_chain, &p_parent->fmt_in, &p_parent->fmt_out );
+
+    filter_t *p_filter;
+
+    if( p_parent->fmt_in.video.orientation != p_fmt_mid->video.orientation)
+    {
+        p_filter = AppendTransform( p_parent->p_sys->p_chain, &p_parent->fmt_in, p_fmt_mid );
+    }
+    else
+    {
+        p_filter = filter_chain_AppendFilter( p_parent->p_sys->p_chain, NULL, p_cfg, NULL, p_fmt_mid );
+    }
+
+    if( !p_filter )
         return VLC_EGENERIC;
-    if( !filter_chain_AppendFilter( p_chain, NULL, p_cfg, p_fmt_mid, NULL ) )
+
+    //Check if first filter was enough (transform filter most likely):
+    if( es_format_IsSimilar(&p_filter->fmt_out, &p_parent->fmt_out ))
+       return VLC_SUCCESS;
+
+    if( p_fmt_mid->video.orientation != p_parent->fmt_out.video.orientation)
+    {
+        p_filter = AppendTransform( p_parent->p_sys->p_chain, p_fmt_mid, &p_parent->fmt_out );
+    }
+    else
+    {
+        p_filter = filter_chain_AppendFilter( p_parent->p_sys->p_chain, NULL, p_cfg, p_fmt_mid, NULL );
+    }
+
+    if( !p_filter )
     {
-        filter_chain_DeleteFilter( p_chain, p_filter1 );
+        //Clean up.
+        filter_chain_Reset( p_parent->p_sys->p_chain, NULL, NULL );
         return VLC_EGENERIC;
     }
+
     return VLC_SUCCESS;
 }
 
+static filter_t * AppendTransform( filter_chain_t *p_chain, es_format_t *p_fmt1, es_format_t *p_fmt2 )
+{
+    video_transform_t transform = orientation_GetTransform(p_fmt1->video.orientation, p_fmt2->video.orientation);
+
+    const char *type;
+
+    switch ( transform ) {
+
+        case TRANSFORM_R90:
+            type = "90";
+            break;
+        case TRANSFORM_R180:
+            type = "180";
+            break;
+        case TRANSFORM_R270:
+            type = "270";
+            break;
+        case TRANSFORM_HFLIP:
+            type = "hflip";
+            break;
+        case TRANSFORM_VFLIP:
+            type = "vflip";
+            break;
+        case TRANSFORM_TRANSPOSE:
+            type = "transpose";
+            break;
+        case TRANSFORM_ANTI_TRANSPOSE:
+            type = "antitranspose";
+            break;
+        default:
+            type = NULL;
+            break;
+    }
+
+    if( !type )
+        return NULL;
+
+    config_chain_t *cfg;
+    char *name;
+    char config[100];
+    snprintf( config, 100, "transform{type=%s}", type );
+    char *next = config_ChainCreate( &name, &cfg, config );
+
+    filter_t *p_filter = filter_chain_AppendFilter( p_chain, name, cfg, p_fmt1, p_fmt2 );
+
+    config_ChainDestroy(cfg);
+    free(name);
+    free(next);
+
+    return p_filter;
+}
+
 static void EsFormatMergeSize( es_format_t *p_dst,
                                const es_format_t *p_base,
                                const es_format_t *p_size )
@@ -287,5 +391,10 @@ static void EsFormatMergeSize( es_format_t *p_dst,
 
     p_dst->video.i_visible_width  = p_size->video.i_visible_width;
     p_dst->video.i_visible_height = p_size->video.i_visible_height;
+
+    p_dst->video.i_x_offset = p_size->video.i_x_offset;
+    p_dst->video.i_y_offset = p_size->video.i_y_offset;
+
+    p_dst->video.orientation = p_size->video.orientation;
 }
 
-- 
1.8.3.4 (Apple Git-47)




More information about the vlc-devel mailing list