]> git.sesse.net Git - x264/blob - input/yuv.c
Preprocessing cosmetics
[x264] / input / yuv.c
1 /*****************************************************************************
2  * yuv.c: x264 yuv input module
3  *****************************************************************************
4  * Copyright (C) 2003-2009 x264 project
5  *
6  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7  *          Loren Merritt <lorenm@u.washington.edu>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #include "muxers.h"
25
26 typedef struct
27 {
28     FILE *fh;
29     int width, height;
30     int next_frame;
31 } yuv_hnd_t;
32
33 static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt )
34 {
35     yuv_hnd_t *h = malloc( sizeof(yuv_hnd_t) );
36     if( !h )
37         return -1;
38
39     if( !opt->resolution )
40     {
41         /* try to parse the file name */
42         for( char *p = psz_filename; *p; p++ )
43             if( *p >= '0' && *p <= '9' && sscanf( p, "%ux%u", &info->width, &info->height ) == 2 )
44                 break;
45     }
46     else
47         sscanf( opt->resolution, "%ux%u", &info->width, &info->height );
48     if( !info->width || !info->height )
49     {
50         fprintf( stderr, "yuv [error]: rawyuv input requires a resolution.\n" );
51         return -1;
52     }
53
54     h->next_frame = 0;
55     info->vfr     = 0;
56     h->width      = info->width;
57     h->height     = info->height;
58
59     if( !strcmp( psz_filename, "-" ) )
60         h->fh = stdin;
61     else
62         h->fh = fopen( psz_filename, "rb" );
63     if( h->fh == NULL )
64         return -1;
65
66     *p_handle = h;
67     return 0;
68 }
69
70 static int get_frame_total( hnd_t handle )
71 {
72     yuv_hnd_t *h = handle;
73     int i_frame_total = 0;
74
75     if( x264_is_regular_file( h->fh ) )
76     {
77         fseek( h->fh, 0, SEEK_END );
78         uint64_t i_size = ftell( h->fh );
79         fseek( h->fh, 0, SEEK_SET );
80         i_frame_total = (int)(i_size / ( h->width * h->height * 3 / 2 ));
81     }
82
83     return i_frame_total;
84 }
85
86 static int read_frame_internal( x264_picture_t *p_pic, yuv_hnd_t *h )
87 {
88     return fread( p_pic->img.plane[0], h->width * h->height, 1, h->fh ) <= 0
89         || fread( p_pic->img.plane[1], h->width * h->height / 4, 1, h->fh ) <= 0
90         || fread( p_pic->img.plane[2], h->width * h->height / 4, 1, h->fh ) <= 0;
91 }
92
93 static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame )
94 {
95     yuv_hnd_t *h = handle;
96
97     if( i_frame > h->next_frame )
98     {
99         if( x264_is_regular_file( h->fh ) )
100             fseek( h->fh, (uint64_t)i_frame * h->width * h->height * 3 / 2, SEEK_SET );
101         else
102             while( i_frame > h->next_frame )
103             {
104                 if( read_frame_internal( p_pic, h ) )
105                     return -1;
106                 h->next_frame++;
107             }
108     }
109
110     if( read_frame_internal( p_pic, h ) )
111         return -1;
112
113     h->next_frame = i_frame+1;
114     return 0;
115 }
116
117 static int close_file( hnd_t handle )
118 {
119     yuv_hnd_t *h = handle;
120     if( !h || !h->fh )
121         return 0;
122     fclose( h->fh );
123     free( h );
124     return 0;
125 }
126
127 const cli_input_t yuv_input = { open_file, get_frame_total, x264_picture_alloc, read_frame, NULL, x264_picture_clean, close_file };