| rev |
line source |
|
nengel@2
|
1 /*
|
|
nengel@2
|
2 * H264 decoder main
|
|
nengel@2
|
3 */
|
|
nengel@2
|
4
|
|
nengel@2
|
5 #include "config.h"
|
|
nengel@2
|
6 #include "libavcodec/h264.h"
|
|
nengel@2
|
7
|
|
nengel@2
|
8 #include <string.h>
|
|
nengel@2
|
9 #include <stdlib.h>
|
|
nengel@2
|
10 #include <errno.h>
|
|
nengel@2
|
11 #include <signal.h>
|
|
nengel@2
|
12 #include <unistd.h>
|
|
nengel@2
|
13 #include <getopt.h>
|
|
nengel@2
|
14 #include <fcntl.h>
|
|
nengel@2
|
15
|
|
nengel@2
|
16 #include <sys/types.h>
|
|
nengel@2
|
17 #include <sys/time.h>
|
|
nengel@2
|
18 #include <sys/resource.h>
|
|
nengel@2
|
19 #include <time.h>
|
|
nengel@2
|
20
|
|
nengel@2
|
21 #include <assert.h>
|
|
nengel@2
|
22
|
|
nengel@3
|
23 #include "VSs_impl/VSs.h"
|
|
nengel@2
|
24
|
|
nengel@2
|
25 static const char program_name[] = "h264dec";
|
|
nengel@2
|
26 static const int program_birth_year = 2010;
|
|
nengel@2
|
27
|
|
nengel@2
|
28 static const char *file_name;
|
|
nengel@2
|
29 static int ifile, ofile;
|
|
nengel@2
|
30 static int no_arch =0;
|
|
nengel@2
|
31 static int parallel = 1;
|
|
nengel@2
|
32 static int frame_width = 0;
|
|
nengel@2
|
33 static int frame_height = 0;
|
|
nengel@2
|
34
|
|
nengel@2
|
35 static void av_exit(int ret)
|
|
nengel@2
|
36 {
|
|
nengel@2
|
37 //do some free calls
|
|
nengel@2
|
38 #undef exit
|
|
nengel@2
|
39 exit(ret);
|
|
nengel@2
|
40 }
|
|
nengel@2
|
41
|
|
nengel@2
|
42 static void opt_input_file(const char *filename)
|
|
nengel@2
|
43 {
|
|
nengel@2
|
44 /* open the input file */
|
|
nengel@2
|
45 ifile = open(filename, O_RDONLY, 0666);
|
|
nengel@2
|
46 if (ifile < 0){
|
|
nengel@2
|
47 fprintf(stderr, "Failed to open %s\n", filename);
|
|
nengel@2
|
48 av_exit(-1);
|
|
nengel@2
|
49 }
|
|
nengel@2
|
50
|
|
nengel@2
|
51 //parse first frame to get resolution (other information available but not used)
|
|
nengel@2
|
52 H264Slice slice;
|
|
nengel@2
|
53 PictureInfo pi;
|
|
nengel@2
|
54 GetBitContext gb = {0,};
|
|
nengel@2
|
55 ParserContext *pc;
|
|
nengel@2
|
56 NalContext *nc;
|
|
nengel@2
|
57
|
|
nengel@2
|
58 pc = get_parse_context(ifile);
|
|
nengel@2
|
59 nc = get_nal_context(0, 0);
|
|
nengel@2
|
60
|
|
nengel@2
|
61 memset(&slice, 0, sizeof(H264Slice));
|
|
nengel@2
|
62 slice.current_picture_info=π
|
|
nengel@2
|
63
|
|
nengel@2
|
64 av_read_frame_internal(pc, &gb);
|
|
nengel@2
|
65 decode_nal_units(nc, &slice, &gb);
|
|
nengel@2
|
66
|
|
nengel@2
|
67 frame_width = nc->width;
|
|
nengel@2
|
68 frame_height= nc->height;
|
|
nengel@2
|
69
|
|
nengel@2
|
70 //clean up
|
|
nengel@2
|
71 av_freep(&gb.raw);
|
|
nengel@2
|
72 if (gb.rbsp)
|
|
nengel@2
|
73 av_freep(&gb.rbsp);
|
|
nengel@2
|
74 free_parse_context(pc);
|
|
nengel@2
|
75 free_nal_context(nc);
|
|
nengel@2
|
76
|
|
nengel@2
|
77 //rewind file
|
|
nengel@2
|
78 int offset;
|
|
nengel@2
|
79 if ( (offset=lseek(ifile, 0, SEEK_SET)) ){
|
|
nengel@2
|
80 fprintf(stderr, "Rewind input file %s failed at offset %d\n", filename, offset);
|
|
nengel@2
|
81 }
|
|
nengel@2
|
82
|
|
nengel@2
|
83 }
|
|
nengel@2
|
84
|
|
nengel@2
|
85 static void opt_output_file(const char *filename)
|
|
nengel@2
|
86 {
|
|
nengel@2
|
87 if (filename){
|
|
nengel@2
|
88 if (!strcmp(filename, "-"))
|
|
nengel@2
|
89 filename = "pipe:";
|
|
nengel@2
|
90
|
|
nengel@2
|
91 ofile = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0666);
|
|
nengel@2
|
92 }else{
|
|
nengel@2
|
93 ofile =0;
|
|
nengel@2
|
94 }
|
|
nengel@2
|
95 }
|
|
nengel@2
|
96
|
|
nengel@2
|
97 static void show_usage(void)
|
|
nengel@2
|
98 {
|
|
nengel@2
|
99 printf("usage: ffmpeg [options] -i infile }...\n");
|
|
nengel@2
|
100 printf("\n");
|
|
nengel@2
|
101 }
|
|
nengel@2
|
102
|
|
nengel@2
|
103 static struct option long_options[] = {
|
|
nengel@2
|
104 {"static-sched", 0, 0, 0},
|
|
nengel@2
|
105 {"static-mbd", 0, 0, 0},
|
|
nengel@2
|
106 {"numamap", 0, 0, 0},
|
|
nengel@2
|
107 {"no-mbd", 0, 0, 0},
|
|
nengel@2
|
108 {"static-3d", 0, 0, 0},
|
|
nengel@2
|
109 {"slice-bufs", 1, 0, 0},
|
|
nengel@2
|
110 {"smt", 0, 0, 0},
|
|
nengel@2
|
111 {"noarch", 0, 0, 'a'},
|
|
nengel@2
|
112 {"display", 0, 0, 'd'},
|
|
nengel@2
|
113 {"fullscreen", 0, 0, 'f'},
|
|
nengel@2
|
114 {"numframes", 1, 0, 'n'},
|
|
nengel@2
|
115 {"use-ppe-ed", 1, 0, 'p'},
|
|
nengel@2
|
116 {"sequential", 0, 0, 's'},
|
|
nengel@2
|
117 {"threads", 1, 0, 't'},
|
|
nengel@2
|
118 {"verbose", 1, 0, 'v'},
|
|
nengel@2
|
119 {"wave-order", 1, 0, 'w'},
|
|
nengel@2
|
120 {"smb-size", 1, 0, 'z'},
|
|
nengel@2
|
121 {"pipe-bufs", 1, 0, 'e'},
|
|
nengel@2
|
122 {0, 0, 0, 0}
|
|
nengel@2
|
123 };
|
|
nengel@2
|
124
|
|
nengel@2
|
125 static h264_options cli_opts;
|
|
nengel@2
|
126 static void parse_cmd(int argc, char **argv)
|
|
nengel@2
|
127 {
|
|
nengel@2
|
128 int c;
|
|
nengel@2
|
129 int digit_optind = 0;
|
|
nengel@2
|
130 int option_index = 0;
|
|
nengel@2
|
131 char ofile_name[1024];
|
|
nengel@2
|
132 extern char *optarg;
|
|
nengel@2
|
133 extern int optind, optopt;
|
|
nengel@2
|
134
|
|
nengel@2
|
135 cli_opts.statsched =0;
|
|
nengel@2
|
136 cli_opts.numamap =0;
|
|
nengel@2
|
137 cli_opts.statmbd =0;
|
|
nengel@2
|
138 cli_opts.no_mbd= 0;
|
|
nengel@2
|
139 cli_opts.numframes = INT_MAX;
|
|
nengel@2
|
140 cli_opts.display=0;
|
|
nengel@2
|
141 cli_opts.fullscreen=0;
|
|
nengel@2
|
142 cli_opts.verbose=0;
|
|
nengel@2
|
143 cli_opts.ppe_ed=0;
|
|
nengel@2
|
144 cli_opts.profile=0;
|
|
nengel@2
|
145 cli_opts.threads = 1;
|
|
nengel@2
|
146 cli_opts.smb_size[0] = cli_opts.smb_size[1] = 1;
|
|
nengel@2
|
147 cli_opts.wave_order=0;
|
|
nengel@2
|
148 cli_opts.static_3d=0;
|
|
nengel@2
|
149 cli_opts.pipe_bufs=8;
|
|
nengel@2
|
150 cli_opts.slice_bufs=1;
|
|
nengel@2
|
151 cli_opts.smt= 0;
|
|
nengel@2
|
152 while ((c = getopt_long(argc, argv, "ade:fi:n:o:p:st:vwz:", long_options, &option_index)) != -1 ){
|
|
nengel@2
|
153 int this_option_optind = optind ? optind : 1;
|
|
nengel@2
|
154
|
|
nengel@2
|
155 switch (c){
|
|
nengel@2
|
156 case 0:
|
|
nengel@2
|
157 if (option_index==0){
|
|
nengel@2
|
158 cli_opts.statsched=1;
|
|
nengel@2
|
159 }else if (option_index==1){
|
|
nengel@2
|
160 cli_opts.statmbd= 1;
|
|
nengel@2
|
161 }else if (option_index==2){
|
|
nengel@2
|
162 cli_opts.numamap= 1;
|
|
nengel@2
|
163 }else if (option_index==3){
|
|
nengel@2
|
164 cli_opts.no_mbd= 1;
|
|
nengel@2
|
165 }else if (option_index==4){
|
|
nengel@2
|
166 cli_opts.static_3d= 1;
|
|
nengel@2
|
167 }else if (option_index==5){
|
|
nengel@2
|
168 cli_opts.slice_bufs= (unsigned) atoi(optarg);
|
|
nengel@2
|
169 }else if (option_index==6){
|
|
nengel@2
|
170 cli_opts.smt= 1;
|
|
nengel@2
|
171 }
|
|
nengel@2
|
172 break;
|
|
nengel@2
|
173 case '0':
|
|
nengel@2
|
174 case '1':
|
|
nengel@2
|
175 case '2':
|
|
nengel@2
|
176 if (digit_optind != 0 && digit_optind != this_option_optind)
|
|
nengel@2
|
177 printf("digits occur in two different argv-elements.\n");
|
|
nengel@2
|
178 digit_optind = this_option_optind;
|
|
nengel@2
|
179 printf("option %c\n", c);
|
|
nengel@2
|
180 break;
|
|
nengel@2
|
181 case 'a':
|
|
nengel@2
|
182 no_arch=1;
|
|
nengel@2
|
183 break;
|
|
nengel@2
|
184 case 'd':
|
|
nengel@2
|
185 cli_opts.display=1;
|
|
nengel@2
|
186 break;
|
|
nengel@2
|
187 case 'f':
|
|
nengel@2
|
188 cli_opts.fullscreen=1;
|
|
nengel@2
|
189 break;
|
|
nengel@2
|
190 case 'i':
|
|
nengel@2
|
191 file_name = (const char *)optarg;
|
|
nengel@2
|
192 opt_input_file(file_name);
|
|
nengel@2
|
193 break;
|
|
nengel@2
|
194 case 'n':
|
|
nengel@2
|
195 cli_opts.numframes = (unsigned) atoi(optarg);
|
|
nengel@2
|
196 break;
|
|
nengel@2
|
197 case 'o':
|
|
nengel@2
|
198 strcpy(ofile_name, optarg);
|
|
nengel@2
|
199 opt_output_file(ofile_name);
|
|
nengel@2
|
200 break;
|
|
nengel@2
|
201 case 'p':
|
|
nengel@2
|
202 cli_opts.profile = (unsigned) atoi(optarg);
|
|
nengel@2
|
203 break;
|
|
nengel@2
|
204 case 's':
|
|
nengel@2
|
205 cli_opts.threads = 0;
|
|
nengel@2
|
206 parallel = 0;
|
|
nengel@2
|
207 break;
|
|
nengel@2
|
208 case 't':
|
|
nengel@2
|
209 cli_opts.threads = atoi(optarg);
|
|
nengel@2
|
210 if (cli_opts.threads<=0){
|
|
nengel@2
|
211 fprintf(stderr, "Option -%c requires thread numbers > 0\n", c);
|
|
nengel@2
|
212 av_exit(-1);
|
|
nengel@2
|
213 }
|
|
nengel@2
|
214 break;
|
|
nengel@2
|
215 case 'v':
|
|
nengel@2
|
216 cli_opts.verbose = 1;
|
|
nengel@2
|
217 break;
|
|
nengel@2
|
218 case 'w':
|
|
nengel@2
|
219 cli_opts.wave_order = 1;
|
|
nengel@2
|
220 break;
|
|
nengel@2
|
221 case 'z': // only useful in ompss
|
|
nengel@2
|
222 if (argc < optind +1){
|
|
nengel@2
|
223 fprintf(stderr, "Option -%c (--smb-size) requires 2 arguments\n", c);
|
|
nengel@2
|
224 av_exit(-1);
|
|
nengel@2
|
225 }
|
|
nengel@2
|
226 optind--;
|
|
nengel@2
|
227 for (int i=0; i<2; i++){
|
|
nengel@2
|
228 cli_opts.smb_size[i] = atoi(argv[optind++]);
|
|
nengel@2
|
229 if (!(cli_opts.smb_size > 0)){
|
|
nengel@2
|
230 fprintf(stderr, "Option -%c (--smb-size) requires dimensions > 0\n", c);
|
|
nengel@2
|
231 av_exit(-1);
|
|
nengel@2
|
232 }
|
|
nengel@2
|
233 }
|
|
nengel@2
|
234 break;
|
|
nengel@2
|
235 case 'e':
|
|
nengel@2
|
236 cli_opts.pipe_bufs = atoi(optarg);
|
|
nengel@2
|
237 break;
|
|
nengel@2
|
238 case ':':
|
|
nengel@2
|
239 fprintf(stderr, "Option -%c requires an operand\n", optopt);
|
|
nengel@2
|
240 av_exit(-1);
|
|
nengel@2
|
241 break;
|
|
nengel@2
|
242 case '?':
|
|
nengel@2
|
243 fprintf(stderr, "Unrecognized option: -%c\n", optopt);
|
|
nengel@2
|
244 av_exit(-1);
|
|
nengel@2
|
245 break;
|
|
nengel@2
|
246 }
|
|
nengel@2
|
247 }
|
|
nengel@2
|
248
|
|
nengel@2
|
249 }
|
|
nengel@2
|
250
|
|
nengel@2
|
251 int main(int argc, char **argv)
|
|
nengel@2
|
252 {
|
|
nengel@2
|
253 /* parse options */
|
|
nengel@2
|
254 parse_cmd(argc, argv);
|
|
nengel@2
|
255
|
|
nengel@2
|
256 if(!ifile ) {
|
|
nengel@2
|
257 show_usage();
|
|
nengel@2
|
258 av_exit(1);
|
|
nengel@2
|
259 }
|
|
nengel@2
|
260
|
|
nengel@2
|
261 H264Context *h = get_h264dec_context(file_name, ifile, ofile, frame_width, frame_height, &cli_opts);
|
|
nengel@2
|
262 #if OMPSS
|
|
nengel@3
|
263 VSs__create_seed_slave_and_do_work( &h264_decode_ompss , (void*)h );
|
|
nengel@2
|
264 #else
|
|
nengel@2
|
265 if (parallel){
|
|
nengel@2
|
266 if (ARCH_CELL && !no_arch){
|
|
nengel@2
|
267 if (h264_decode_cell( h ) < 0)
|
|
nengel@2
|
268 av_exit(-1);
|
|
nengel@2
|
269 }else{
|
|
nengel@2
|
270 if (h264_decode_pthread( h ) < 0)
|
|
nengel@2
|
271 av_exit(1);
|
|
nengel@2
|
272 }
|
|
nengel@2
|
273 }else{
|
|
nengel@2
|
274 if (ARCH_CELL && !no_arch){
|
|
nengel@2
|
275 if (h264_decode_cell_seq( h ) < 0)
|
|
nengel@2
|
276 av_exit(1);
|
|
nengel@2
|
277 }else{
|
|
nengel@2
|
278 if (h264_decode_seq( h ) < 0)
|
|
nengel@2
|
279 av_exit(1);
|
|
nengel@2
|
280 }
|
|
nengel@2
|
281 }
|
|
nengel@2
|
282 #endif
|
|
nengel@2
|
283 free_h264dec_context(h);
|
|
nengel@2
|
284 close(ifile);
|
|
nengel@2
|
285 close(ofile);
|
|
nengel@2
|
286
|
|
nengel@2
|
287 return 0;
|
|
nengel@2
|
288 }
|