]> git.sesse.net Git - x264/blobdiff - input/yuv.c
Add TFF/BFF detection to all demuxers
[x264] / input / yuv.c
index 98dc46c2c195629efd3430b26070d551f0b434c6..cbed7fc09ab1f2450ebeb77083eec8a170d14ea8 100644 (file)
@@ -30,14 +30,31 @@ typedef struct
     int next_frame;
 } yuv_hnd_t;
 
-static int open_file( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param )
+static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt )
 {
     yuv_hnd_t *h = malloc( sizeof(yuv_hnd_t) );
     if( !h )
         return -1;
-    h->width = p_param->i_width;
-    h->height = p_param->i_height;
+
+    if( !opt->resolution )
+    {
+        /* try to parse the file name */
+        for( char *p = psz_filename; *p; p++ )
+            if( *p >= '0' && *p <= '9' && sscanf( p, "%ux%u", &info->width, &info->height ) == 2 )
+                break;
+    }
+    else
+        sscanf( opt->resolution, "%ux%u", &info->width, &info->height );
+    if( !info->width || !info->height )
+    {
+        fprintf( stderr, "yuv [error]: rawyuv input requires a resolution.\n" );
+        return -1;
+    }
+
     h->next_frame = 0;
+    info->vfr     = 0;
+    h->width      = info->width;
+    h->height     = info->height;
 
     if( !strcmp( psz_filename, "-" ) )
         h->fh = stdin;
@@ -55,8 +72,9 @@ static int get_frame_total( hnd_t handle )
     yuv_hnd_t *h = handle;
     int i_frame_total = 0;
 
-    if( !fseek( h->fh, 0, SEEK_END ) )
+    if( x264_is_regular_file( h->fh ) )
     {
+        fseek( h->fh, 0, SEEK_END );
         uint64_t i_size = ftell( h->fh );
         fseek( h->fh, 0, SEEK_SET );
         i_frame_total = (int)(i_size / ( h->width * h->height * 3 / 2 ));
@@ -65,21 +83,34 @@ static int get_frame_total( hnd_t handle )
     return i_frame_total;
 }
 
+static int read_frame_internal( x264_picture_t *p_pic, yuv_hnd_t *h )
+{
+    return fread( p_pic->img.plane[0], h->width * h->height, 1, h->fh ) <= 0
+        || fread( p_pic->img.plane[1], h->width * h->height / 4, 1, h->fh ) <= 0
+        || fread( p_pic->img.plane[2], h->width * h->height / 4, 1, h->fh ) <= 0;
+}
+
 static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame )
 {
     yuv_hnd_t *h = handle;
 
-    if( i_frame != h->next_frame )
-        if( fseek( h->fh, (uint64_t)i_frame * h->width * h->height * 3 / 2, SEEK_SET ) )
-            return -1;
+    if( i_frame > h->next_frame )
+    {
+        if( x264_is_regular_file( h->fh ) )
+            fseek( h->fh, (uint64_t)i_frame * h->width * h->height * 3 / 2, SEEK_SET );
+        else
+            while( i_frame > h->next_frame )
+            {
+                if( read_frame_internal( p_pic, h ) )
+                    return -1;
+                h->next_frame++;
+            }
+    }
 
-    if( fread( p_pic->img.plane[0], 1, h->width * h->height, h->fh ) <= 0
-     || fread( p_pic->img.plane[1], 1, h->width * h->height / 4, h->fh ) <= 0
-     || fread( p_pic->img.plane[2], 1, h->width * h->height / 4, h->fh ) <= 0 )
+    if( read_frame_internal( p_pic, h ) )
         return -1;
 
     h->next_frame = i_frame+1;
-
     return 0;
 }
 
@@ -93,4 +124,4 @@ static int close_file( hnd_t handle )
     return 0;
 }
 
-cli_input_t yuv_input = { open_file, get_frame_total, read_frame, close_file };
+const cli_input_t yuv_input = { open_file, get_frame_total, x264_picture_alloc, read_frame, NULL, x264_picture_clean, close_file };