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