[x264-devel] commit: Add TFF/BFF detection to all demuxers (Steven Walters )

git at videolan.org git at videolan.org
Sun Apr 11 06:50:30 CEST 2010


x264 | branch: master | Steven Walters <kemuri9 at gmail.com> | Tue Apr  6 22:08:21 2010 -0400| [819d121f6cf92b7b5f33e85181b0dcdb0ffbb84a] | committer: Jason Garrett-Glaser 

Add TFF/BFF detection to all demuxers
Fix interlaced Avisynth input, automatically weave field-based input.

> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=819d121f6cf92b7b5f33e85181b0dcdb0ffbb84a
---

 input/avs.c   |   34 ++++++++++++++++++++++++++++++----
 input/ffms.c  |    1 +
 input/input.h |    1 +
 input/lavf.c  |    3 +++
 x264.c        |    7 +++++--
 5 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/input/avs.c b/input/avs.c
index 9e20665..59634f4 100644
--- a/input/avs.c
+++ b/input/avs.c
@@ -117,6 +117,15 @@ static void avs_build_filter_sequence( char *filename_ext, const char *filter[AV
         filter[i++] = all_purpose[j];
 }
 
+static AVS_Value update_clip( avs_hnd_t *h, const AVS_VideoInfo **vi, AVS_Value res, AVS_Value release )
+{
+    h->func.avs_release_clip( h->clip );
+    h->clip = h->func.avs_take_clip( res, h->env );
+    h->func.avs_release_value( release );
+    *vi = h->func.avs_get_video_info( h->clip );
+    return res;
+}
+
 static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt )
 {
     FILE *fh = fopen( psz_filename, "r" );
@@ -213,17 +222,36 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c
         fprintf( stderr, "avs [error]: `%s' has no video data\n", psz_filename );
         return -1;
     }
+    /* if the clip is made of fields instead of frames, call weave to make them frames */
+    if( avs_is_field_based( vi ) )
+    {
+        fprintf( stderr, "avs [warning]: detected fieldbased (separated) input, weaving to frames\n" );
+        AVS_Value tmp = h->func.avs_invoke( h->env, "Weave", res, NULL );
+        if( avs_is_error( tmp ) )
+        {
+            fprintf( stderr, "avs [error]: couldn't weave fields into frames\n" );
+            return -1;
+        }
+        res = update_clip( h, &vi, tmp, res );
+    }
     if( vi->width&1 || vi->height&1 )
     {
         fprintf( stderr, "avs [error]: input clip width or height not divisible by 2 (%dx%d)\n",
                  vi->width, vi->height );
         return -1;
     }
+    /* bff/tff flags in avisynth are not technically mutually exclusive, which can lead to both being set.
+     * avisynth's own functions enact mutual exclusion, but source filters are not guaranteed to do this. */
+    int tff = avs_is_tff( vi );
+    if( avs_is_bff( vi ) ^ tff )
+    {
+        info->interlaced = 1;
+        info->tff = !!tff;
+    }
     /* always call ConvertToYV12 to convert non YV12 planar colorspaces to YV12 when user's AVS supports them,
        as all planar colorspaces are flagged as YV12. If it is already YV12 in this case, the call does nothing */
     if( !avs_is_yv12( vi ) || avs_version >= AVS_INTERFACE_OTHER_PLANAR )
     {
-        h->func.avs_release_clip( h->clip );
         fprintf( stderr, "avs %s\n", !avs_is_yv12( vi ) ? "[warning]: converting input clip to YV12"
                : "[info]: avisynth 2.6+ detected, forcing conversion to YV12" );
         const char *arg_name[2] = { NULL, "interlaced" };
@@ -234,9 +262,7 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c
             fprintf( stderr, "avs [error]: couldn't convert input clip to YV12\n" );
             return -1;
         }
-        h->clip = h->func.avs_take_clip( res2, h->env );
-        h->func.avs_release_value( res2 );
-        vi = h->func.avs_get_video_info( h->clip );
+        res = update_clip( h, &vi, res2, res );
     }
     h->func.avs_release_value( res );
 
diff --git a/input/ffms.c b/input/ffms.c
index 14962c7..01a1257 100644
--- a/input/ffms.c
+++ b/input/ffms.c
@@ -133,6 +133,7 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c
     h->init_height = h->cur_height = info->height = frame->EncodedHeight;
     h->cur_pix_fmt = frame->EncodedPixelFormat;
     info->interlaced = frame->InterlacedFrame;
+    info->tff        = frame->TopFieldFirst;
 
     if( h->cur_pix_fmt != PIX_FMT_YUV420P )
         fprintf( stderr, "ffms [warning]: converting from %s to YV12\n",
diff --git a/input/input.h b/input/input.h
index 7be6fcf..b6cd218 100644
--- a/input/input.h
+++ b/input/input.h
@@ -44,6 +44,7 @@ typedef struct
     int interlaced;
     int sar_width;
     int sar_height;
+    int tff;
     int timebase_num;
     int timebase_den;
     int vfr;
diff --git a/input/lavf.c b/input/lavf.c
index 6ecc6b0..4b0375f 100644
--- a/input/lavf.c
+++ b/input/lavf.c
@@ -124,7 +124,10 @@ static int read_frame_internal( x264_picture_t *p_pic, lavf_hnd_t *h, int i_fram
     sws_scale( h->scaler, frame->data, frame->linesize, 0, c->height, p_pic->img.plane, p_pic->img.i_stride );
 
     if( info )
+    {
         info->interlaced = frame->interlaced_frame;
+        info->tff = frame->top_field_first;
+    }
 
     if( h->vfr_input )
     {
diff --git a/x264.c b/x264.c
index 08fd313..76ff85d 100644
--- a/x264.c
+++ b/x264.c
@@ -1134,6 +1134,7 @@ generic_option:
     info.interlaced = param->b_interlaced;
     info.sar_width  = param->vui.i_sar_width;
     info.sar_height = param->vui.i_sar_height;
+    info.tff        = param->b_tff;
     info.vfr        = param->b_vfr_input;
 
     if( select_input( demuxer, demuxername, input_filename, &opt->hin, &info, &input_opt ) )
@@ -1180,9 +1181,11 @@ generic_option:
     param->i_width     = info.width;
     if( !b_user_interlaced && info.interlaced )
     {
-        fprintf( stderr, "x264 [warning]: input appears to be interlaced, enabling interlaced mode.\n"
-                         "                If you want otherwise, use --no-interlaced\n" );
+        fprintf( stderr, "x264 [warning]: input appears to be interlaced, enabling %cff interlaced mode.\n"
+                         "                If you want otherwise, use --no-interlaced or --%cff\n",
+                 info.tff ? 't' : 'b', info.tff ? 'b' : 't' );
         param->b_interlaced = 1;
+        param->b_tff = !!info.tff;
     }
     if( !b_user_fps )
     {



More information about the x264-devel mailing list