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