nengel@1: /* nengel@1: * H264 decoder main nengel@1: */ nengel@1: nengel@1: #include "config.h" nengel@1: #include "libavcodec/h264.h" nengel@1: nengel@1: #include nengel@1: #include nengel@1: #include nengel@1: #include nengel@1: #include nengel@1: #include nengel@1: #include nengel@1: nengel@1: #include nengel@1: #include nengel@1: #include nengel@1: #include nengel@1: nengel@1: #include nengel@1: nengel@1: nengel@1: static const char program_name[] = "h264dec"; nengel@1: static const int program_birth_year = 2010; nengel@1: nengel@1: static const char *file_name; nengel@1: static int ifile, ofile; nengel@1: static int no_arch =0; nengel@1: static int parallel = 1; nengel@1: static int frame_width = 0; nengel@1: static int frame_height = 0; nengel@1: nengel@1: static void av_exit(int ret) nengel@1: { nengel@1: //do some free calls nengel@1: #undef exit nengel@1: exit(ret); nengel@1: } nengel@1: nengel@1: static void opt_input_file(const char *filename) nengel@1: { nengel@1: /* open the input file */ nengel@1: ifile = open(filename, O_RDONLY, 0666); nengel@1: if (ifile < 0){ nengel@1: fprintf(stderr, "Failed to open %s\n", filename); nengel@1: av_exit(-1); nengel@1: } nengel@1: nengel@1: //parse first frame to get resolution (other information available but not used) nengel@1: H264Slice slice; nengel@1: PictureInfo pi; nengel@1: GetBitContext gb = {0,}; nengel@1: ParserContext *pc; nengel@1: NalContext *nc; nengel@1: nengel@1: pc = get_parse_context(ifile); nengel@1: nc = get_nal_context(0, 0); nengel@1: nengel@1: memset(&slice, 0, sizeof(H264Slice)); nengel@1: slice.current_picture_info=π nengel@1: nengel@1: av_read_frame_internal(pc, &gb); nengel@1: decode_nal_units(nc, &slice, &gb); nengel@1: nengel@1: frame_width = nc->width; nengel@1: frame_height= nc->height; nengel@1: nengel@1: //clean up nengel@1: av_freep(&gb.raw); nengel@1: if (gb.rbsp) nengel@1: av_freep(&gb.rbsp); nengel@1: free_parse_context(pc); nengel@1: free_nal_context(nc); nengel@1: nengel@1: //rewind file nengel@1: int offset; nengel@1: if ( (offset=lseek(ifile, 0, SEEK_SET)) ){ nengel@1: fprintf(stderr, "Rewind input file %s failed at offset %d\n", filename, offset); nengel@1: } nengel@1: nengel@1: } nengel@1: nengel@1: static void opt_output_file(const char *filename) nengel@1: { nengel@1: if (filename){ nengel@1: if (!strcmp(filename, "-")) nengel@1: filename = "pipe:"; nengel@1: nengel@1: ofile = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0666); nengel@1: }else{ nengel@1: ofile =0; nengel@1: } nengel@1: } nengel@1: nengel@1: static void show_usage(void) nengel@1: { nengel@1: printf("usage: ffmpeg [options] -i infile }...\n"); nengel@1: printf("\n"); nengel@1: } nengel@1: nengel@1: static struct option long_options[] = { nengel@1: {"static-sched", 0, 0, 0}, nengel@1: {"static-mbd", 0, 0, 0}, nengel@1: {"numamap", 0, 0, 0}, nengel@1: {"no-mbd", 0, 0, 0}, nengel@1: {"static-3d", 0, 0, 0}, nengel@1: {"slice-bufs", 1, 0, 0}, nengel@1: {"smt", 0, 0, 0}, nengel@1: {"noarch", 0, 0, 'a'}, nengel@1: {"display", 0, 0, 'd'}, nengel@1: {"fullscreen", 0, 0, 'f'}, nengel@1: {"numframes", 1, 0, 'n'}, nengel@1: {"use-ppe-ed", 1, 0, 'p'}, nengel@1: {"sequential", 0, 0, 's'}, nengel@1: {"threads", 1, 0, 't'}, nengel@1: {"verbose", 1, 0, 'v'}, nengel@1: {"wave-order", 1, 0, 'w'}, nengel@1: {"smb-size", 1, 0, 'z'}, nengel@1: {"pipe-bufs", 1, 0, 'e'}, nengel@1: {0, 0, 0, 0} nengel@1: }; nengel@1: nengel@1: static h264_options cli_opts; nengel@1: static void parse_cmd(int argc, char **argv) nengel@1: { nengel@1: int c; nengel@1: int digit_optind = 0; nengel@1: int option_index = 0; nengel@1: char ofile_name[1024]; nengel@1: extern char *optarg; nengel@1: extern int optind, optopt; nengel@1: nengel@1: cli_opts.statsched =0; nengel@1: cli_opts.numamap =0; nengel@1: cli_opts.statmbd =0; nengel@1: cli_opts.no_mbd= 0; nengel@1: cli_opts.numframes = INT_MAX; nengel@1: cli_opts.display=0; nengel@1: cli_opts.fullscreen=0; nengel@1: cli_opts.verbose=0; nengel@1: cli_opts.ppe_ed=0; nengel@1: cli_opts.profile=0; nengel@1: cli_opts.threads = 1; nengel@1: cli_opts.smb_size[0] = cli_opts.smb_size[1] = 1; nengel@1: cli_opts.wave_order=0; nengel@1: cli_opts.static_3d=0; nengel@1: cli_opts.pipe_bufs=8; nengel@1: cli_opts.slice_bufs=1; nengel@1: cli_opts.smt= 0; nengel@1: while ((c = getopt_long(argc, argv, "ade:fi:n:o:p:st:vwz:", long_options, &option_index)) != -1 ){ nengel@1: int this_option_optind = optind ? optind : 1; nengel@1: nengel@1: switch (c){ nengel@1: case 0: nengel@1: if (option_index==0){ nengel@1: cli_opts.statsched=1; nengel@1: }else if (option_index==1){ nengel@1: cli_opts.statmbd= 1; nengel@1: }else if (option_index==2){ nengel@1: cli_opts.numamap= 1; nengel@1: }else if (option_index==3){ nengel@1: cli_opts.no_mbd= 1; nengel@1: }else if (option_index==4){ nengel@1: cli_opts.static_3d= 1; nengel@1: }else if (option_index==5){ nengel@1: cli_opts.slice_bufs= (unsigned) atoi(optarg); nengel@1: }else if (option_index==6){ nengel@1: cli_opts.smt= 1; nengel@1: } nengel@1: break; nengel@1: case '0': nengel@1: case '1': nengel@1: case '2': nengel@1: if (digit_optind != 0 && digit_optind != this_option_optind) nengel@1: printf("digits occur in two different argv-elements.\n"); nengel@1: digit_optind = this_option_optind; nengel@1: printf("option %c\n", c); nengel@1: break; nengel@1: case 'a': nengel@1: no_arch=1; nengel@1: break; nengel@1: case 'd': nengel@1: cli_opts.display=1; nengel@1: break; nengel@1: case 'f': nengel@1: cli_opts.fullscreen=1; nengel@1: break; nengel@1: case 'i': nengel@1: file_name = (const char *)optarg; nengel@1: opt_input_file(file_name); nengel@1: break; nengel@1: case 'n': nengel@1: cli_opts.numframes = (unsigned) atoi(optarg); nengel@1: break; nengel@1: case 'o': nengel@1: strcpy(ofile_name, optarg); nengel@1: opt_output_file(ofile_name); nengel@1: break; nengel@1: case 'p': nengel@1: cli_opts.profile = (unsigned) atoi(optarg); nengel@1: break; nengel@1: case 's': nengel@1: cli_opts.threads = 0; nengel@1: parallel = 0; nengel@1: break; nengel@1: case 't': nengel@1: cli_opts.threads = atoi(optarg); nengel@1: if (cli_opts.threads<=0){ nengel@1: fprintf(stderr, "Option -%c requires thread numbers > 0\n", c); nengel@1: av_exit(-1); nengel@1: } nengel@1: break; nengel@1: case 'v': nengel@1: cli_opts.verbose = 1; nengel@1: break; nengel@1: case 'w': nengel@1: cli_opts.wave_order = 1; nengel@1: break; nengel@1: case 'z': // only useful in ompss nengel@1: if (argc < optind +1){ nengel@1: fprintf(stderr, "Option -%c (--smb-size) requires 2 arguments\n", c); nengel@1: av_exit(-1); nengel@1: } nengel@1: optind--; nengel@1: for (int i=0; i<2; i++){ nengel@1: cli_opts.smb_size[i] = atoi(argv[optind++]); nengel@1: if (!(cli_opts.smb_size > 0)){ nengel@1: fprintf(stderr, "Option -%c (--smb-size) requires dimensions > 0\n", c); nengel@1: av_exit(-1); nengel@1: } nengel@1: } nengel@1: break; nengel@1: case 'e': nengel@1: cli_opts.pipe_bufs = atoi(optarg); nengel@1: break; nengel@1: case ':': nengel@1: fprintf(stderr, "Option -%c requires an operand\n", optopt); nengel@1: av_exit(-1); nengel@1: break; nengel@1: case '?': nengel@1: fprintf(stderr, "Unrecognized option: -%c\n", optopt); nengel@1: av_exit(-1); nengel@1: break; nengel@1: } nengel@1: } nengel@1: nengel@1: } nengel@1: nengel@1: int main(int argc, char **argv) nengel@1: { nengel@1: /* parse options */ nengel@1: parse_cmd(argc, argv); nengel@1: nengel@1: if(!ifile ) { nengel@1: show_usage(); nengel@1: av_exit(1); nengel@1: } nengel@1: nengel@1: H264Context *h = get_h264dec_context(file_name, ifile, ofile, frame_width, frame_height, &cli_opts); nengel@1: #if OMPSS nengel@1: if (h264_decode_ompss( h ) < 0) nengel@1: av_exit(-1); nengel@1: #else nengel@1: if (parallel){ nengel@1: if (ARCH_CELL && !no_arch){ nengel@1: if (h264_decode_cell( h ) < 0) nengel@1: av_exit(-1); nengel@1: }else{ nengel@1: if (h264_decode_pthread( h ) < 0) nengel@1: av_exit(1); nengel@1: } nengel@1: }else{ nengel@1: if (ARCH_CELL && !no_arch){ nengel@1: if (h264_decode_cell_seq( h ) < 0) nengel@1: av_exit(1); nengel@1: }else{ nengel@1: if (h264_decode_seq( h ) < 0) nengel@1: av_exit(1); nengel@1: } nengel@1: } nengel@1: #endif nengel@1: free_h264dec_context(h); nengel@1: close(ifile); nengel@1: close(ofile); nengel@1: nengel@1: return 0; nengel@1: }