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