Basic input and output are now working.
[frameshot.git] / frameshot.c
blob754360b7866c99eecb79aeb2b99082686d594422
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
5 #include <zlib.h>
7 #include <libavcodec/avcodec.h>
8 #include <libavutil/mathematics.h>
10 #define _GNU_SOURCE
11 #include <getopt.h>
13 #include "common.h"
14 #include "output.h"
15 #include "input.h"
17 enum
19 FORMAT_UNKNOWN,
20 FORMAT_H264,
21 FORMAT_DIRAC,
22 FORMAT_OGG,
23 FORMAT_M4V
26 enum
28 COLORSPACE_420,
29 COLORSPACE_422,
30 COLORSPACE_444,
31 COLORSPACE_444A
34 typedef struct {
35 char *psz_filein;
36 hnd_t hout;
37 hnd_t hin;
38 } cli_opt_t;
40 /* input file function pointers */
41 int (*p_open_infile)( char *psz_filename, hnd_t *p_handle, config_t *p_config );
42 int (*p_read_frame)( hnd_t handle, picture_t *p_pic, int i_frame );
43 int (*p_close_infile)( hnd_t handle );
45 /* output file function pointers */
46 static int (*p_open_outfile)( char *psz_filename, hnd_t *p_handle, int i_compression );
47 // static int (*p_set_outfile_param)( hnd_t handle, config_t *p_config );
48 static int (*p_write_image)( hnd_t handle, picture_t *p_pic, config_t *p_config );
49 static int (*p_close_outfile)( hnd_t handle );
51 static int parse_options( int argc, char **argv, config_t *config, cli_opt_t *opt );
52 static int grab_frames( config_t *config, cli_opt_t *opt );
54 int main(int argc, char **argv)
56 config_t config;
57 cli_opt_t opt;
58 int ret = 0;
60 parse_options(argc, argv, &config, &opt);
62 ret = grab_frames( &config, &opt );
64 return ret;
67 static void show_help(void)
69 #define HELP printf
70 HELP( "Syntax: frameshot [options] infile\n"
71 "\n"
72 "Infile is a raw bitstream of one of the following codecs:\n"
73 " YUV4MPEG\n"
74 "\n"
75 "Options:\n"
76 "\n"
77 " -h, --help Displays this message.\n"
79 HELP( " -f, --frames <int,int,...> Frames numbers to grab.\n" );
80 HELP( " -o, --output <string> Prefix to use for each output image.\n" );
81 HELP( " -z, --compression <integer> Ammount of compression to use.\n" );
82 HELP( " -1, --fast Use fastest compression.\n" );
83 HELP( " -9, --best Use best (slowest) compression.\n" );
84 HELP( "\n" );
87 static int parse_options( int argc, char **argv, config_t *config, cli_opt_t *opt )
89 char *psz_filename = NULL;
90 int i_zlevel = Z_DEFAULT_COMPRESSION;
91 char *psz;
92 int b_y4m = 0;
94 memset( opt, 0, sizeof(*opt) );
96 /* Default input driver */
97 p_open_infile = open_file_y4m;
98 p_read_frame = read_frame_y4m;
99 p_close_infile = close_file_y4m;
101 /* Default output driver */
102 p_open_outfile = open_file_png;
103 p_write_image = write_image_png;
104 p_close_outfile = close_file_png;
106 for( ;; )
108 int long_options_index = -1;
109 static struct option long_options[] =
111 { "fast", no_argument, NULL, '1' },
112 { "best", no_argument, NULL, '9' },
113 { "frames", required_argument, NULL, 'f' },
114 { "help", no_argument, NULL, 'h' },
115 { "output", required_argument, NULL, 'o' },
116 { "compression", required_argument, NULL, 'z' },
117 {0, 0, 0, 0}
120 int c = getopt_long( argc, argv, "19f:ho:z:",
121 long_options, &long_options_index);
123 if( c == -1 )
125 break;
128 switch( c )
130 case '1':
131 i_zlevel = Z_BEST_SPEED;
132 break;
133 case '9':
134 i_zlevel = Z_BEST_COMPRESSION;
135 break;
136 case 'f':
138 case 'o':
139 break;
140 case 'z':
141 i_zlevel = atoi(optarg);
142 if( i_zlevel < 0 || i_zlevel > 9)
143 i_zlevel = Z_DEFAULT_COMPRESSION;
144 break;
145 case 'h':
146 default:
147 show_help();
148 exit(0);
152 /* Get the input file name */
153 if( optind > argc - 1 )
155 fprintf( stderr, "[error]: No input file.\n" );
156 show_help();
157 return -1;
159 psz_filename = argv[optind++];
161 psz = strrchr( psz_filename, '.' );
162 if( !strncasecmp( psz, ".y4m", 4 ) )
163 b_y4m = 1;
165 if( !opt->hout )
167 char *psz_outname = strdup(psz_filename);
168 char *psz_ext = strrchr( psz_outname, '.' );
169 psz_ext[1] = 'p'; psz_ext[2] = 'n'; psz_ext[3] = 'g'; psz_ext[4] = 0x00;
170 p_open_outfile( psz_outname, &opt->hout, i_zlevel );
171 free(psz_outname);
174 if( b_y4m )
176 p_open_infile = open_file_y4m;
177 p_read_frame = read_frame_y4m;
178 p_close_infile = close_file_y4m;
181 if( p_open_infile( psz_filename, &opt->hin, config ) )
183 fprintf( stderr, "ERROR: could not open input file '%s'\n", psz_filename );
184 return -1;
187 return 0;
190 static int grab_frames( config_t *config, cli_opt_t *opt )
192 picture_t pic;
194 pic.img.plane[0] = malloc(3 * config->i_width * config->i_height / 2);
195 pic.img.plane[1] = pic.img.plane[0] + config->i_width * config->i_height;
196 pic.img.plane[2] = pic.img.plane[1] + config->i_width * config->i_height / 4;
197 pic.img.plane[3] = NULL;
199 pic.img.i_stride[0] = config->i_width;
200 pic.img.i_stride[1] = pic.img.i_stride[2] = config->i_width / 2;
201 pic.img.i_stride[3] = 0;
203 p_read_frame( opt->hin, &pic, 1 );
205 p_write_image( opt->hout, &pic, config );
207 p_close_infile( opt->hin );
208 p_close_outfile( opt->hout );
210 return 0;