view ffmpeg_smp/h264dec/h264dec.c @ 1:11d15c47beaf

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