diff 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 diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/ffmpeg_smp/h264dec/h264dec.c	Mon Aug 27 12:09:56 2012 +0200
     1.3 @@ -0,0 +1,288 @@
     1.4 +/*
     1.5 +* H264 decoder main
     1.6 +*/
     1.7 +
     1.8 +#include "config.h"
     1.9 +#include "libavcodec/h264.h"
    1.10 +
    1.11 +#include <string.h>
    1.12 +#include <stdlib.h>
    1.13 +#include <errno.h>
    1.14 +#include <signal.h>
    1.15 +#include <unistd.h>
    1.16 +#include <getopt.h>
    1.17 +#include <fcntl.h>
    1.18 +
    1.19 +#include <sys/types.h>
    1.20 +#include <sys/time.h>
    1.21 +#include <sys/resource.h>
    1.22 +#include <time.h>
    1.23 +
    1.24 +#include <assert.h>
    1.25 +
    1.26 +
    1.27 +static const char program_name[] = "h264dec";
    1.28 +static const int program_birth_year = 2010;
    1.29 +
    1.30 +static const char *file_name;
    1.31 +static int ifile, ofile;
    1.32 +static int no_arch =0;
    1.33 +static int parallel = 1;
    1.34 +static int frame_width  = 0;
    1.35 +static int frame_height = 0;
    1.36 +
    1.37 +static void av_exit(int ret)
    1.38 +{
    1.39 +    //do some free calls
    1.40 +#undef exit
    1.41 +    exit(ret);
    1.42 +}
    1.43 +
    1.44 +static void opt_input_file(const char *filename)
    1.45 +{
    1.46 +    /* open the input file */
    1.47 +    ifile = open(filename, O_RDONLY, 0666);
    1.48 +    if (ifile < 0){
    1.49 +        fprintf(stderr, "Failed to open %s\n", filename);
    1.50 +        av_exit(-1);
    1.51 +    }
    1.52 +
    1.53 +    //parse first frame to get resolution (other information available but not used)
    1.54 +    H264Slice slice;
    1.55 +    PictureInfo pi;
    1.56 +    GetBitContext gb = {0,};
    1.57 +    ParserContext *pc;
    1.58 +    NalContext *nc;
    1.59 +
    1.60 +    pc = get_parse_context(ifile);
    1.61 +    nc = get_nal_context(0, 0);
    1.62 +
    1.63 +    memset(&slice, 0, sizeof(H264Slice));
    1.64 +    slice.current_picture_info=&pi;
    1.65 +
    1.66 +    av_read_frame_internal(pc, &gb);
    1.67 +    decode_nal_units(nc, &slice, &gb);
    1.68 +
    1.69 +    frame_width = nc->width;
    1.70 +    frame_height= nc->height;
    1.71 +
    1.72 +    //clean up
    1.73 +    av_freep(&gb.raw);
    1.74 +    if (gb.rbsp)
    1.75 +        av_freep(&gb.rbsp);
    1.76 +    free_parse_context(pc);
    1.77 +    free_nal_context(nc);
    1.78 +
    1.79 +    //rewind file
    1.80 +    int offset;
    1.81 +    if ( (offset=lseek(ifile, 0, SEEK_SET)) ){
    1.82 +        fprintf(stderr, "Rewind input file %s failed at offset %d\n", filename, offset);
    1.83 +    }
    1.84 +
    1.85 +}
    1.86 +
    1.87 +static void opt_output_file(const char *filename)
    1.88 +{
    1.89 +    if (filename){
    1.90 +        if (!strcmp(filename, "-"))
    1.91 +            filename = "pipe:";
    1.92 +
    1.93 +        ofile = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0666);
    1.94 +    }else{
    1.95 +        ofile =0;
    1.96 +    }
    1.97 +}
    1.98 +
    1.99 +static void show_usage(void)
   1.100 +{
   1.101 +    printf("usage: ffmpeg [options] -i infile }...\n");
   1.102 +    printf("\n");
   1.103 +}
   1.104 +
   1.105 +static struct option long_options[] = {
   1.106 +    {"static-sched", 0, 0, 0},
   1.107 +    {"static-mbd", 0, 0, 0},
   1.108 +    {"numamap", 0, 0, 0},
   1.109 +    {"no-mbd", 0, 0, 0},
   1.110 +    {"static-3d", 0, 0, 0},
   1.111 +    {"slice-bufs", 1, 0, 0},
   1.112 +    {"smt", 0, 0, 0},
   1.113 +    {"noarch", 0, 0, 'a'},
   1.114 +    {"display", 0, 0, 'd'},
   1.115 +    {"fullscreen", 0, 0, 'f'},
   1.116 +    {"numframes", 1, 0, 'n'},
   1.117 +    {"use-ppe-ed", 1, 0, 'p'},
   1.118 +    {"sequential", 0, 0, 's'},
   1.119 +    {"threads", 1, 0, 't'},
   1.120 +    {"verbose", 1, 0, 'v'},
   1.121 +    {"wave-order", 1, 0, 'w'},
   1.122 +    {"smb-size", 1, 0, 'z'},
   1.123 +    {"pipe-bufs", 1, 0, 'e'},
   1.124 +    {0, 0, 0, 0}
   1.125 +};
   1.126 +
   1.127 +static h264_options cli_opts;
   1.128 +static void parse_cmd(int argc, char **argv)
   1.129 +{
   1.130 +    int c;
   1.131 +    int digit_optind = 0;
   1.132 +    int option_index = 0;
   1.133 +    char ofile_name[1024];
   1.134 +    extern char *optarg;
   1.135 +    extern int optind, optopt;
   1.136 +
   1.137 +    cli_opts.statsched =0;
   1.138 +    cli_opts.numamap =0;
   1.139 +    cli_opts.statmbd =0;
   1.140 +    cli_opts.no_mbd= 0;
   1.141 +    cli_opts.numframes = INT_MAX;
   1.142 +    cli_opts.display=0;
   1.143 +    cli_opts.fullscreen=0;
   1.144 +    cli_opts.verbose=0;
   1.145 +    cli_opts.ppe_ed=0;
   1.146 +    cli_opts.profile=0;
   1.147 +    cli_opts.threads = 1;
   1.148 +    cli_opts.smb_size[0] = cli_opts.smb_size[1] = 1;
   1.149 +    cli_opts.wave_order=0;
   1.150 +    cli_opts.static_3d=0;
   1.151 +    cli_opts.pipe_bufs=8;
   1.152 +    cli_opts.slice_bufs=1;
   1.153 +    cli_opts.smt= 0;
   1.154 +    while ((c = getopt_long(argc, argv, "ade:fi:n:o:p:st:vwz:", long_options, &option_index)) != -1 ){
   1.155 +        int this_option_optind = optind ? optind : 1;
   1.156 +
   1.157 +        switch (c){
   1.158 +            case 0:
   1.159 +                if (option_index==0){
   1.160 +                    cli_opts.statsched=1;
   1.161 +                }else if (option_index==1){
   1.162 +                    cli_opts.statmbd= 1;
   1.163 +                }else if (option_index==2){
   1.164 +                    cli_opts.numamap= 1;
   1.165 +                }else if (option_index==3){
   1.166 +                    cli_opts.no_mbd= 1;
   1.167 +                }else if (option_index==4){
   1.168 +                    cli_opts.static_3d= 1;
   1.169 +                }else if (option_index==5){
   1.170 +                    cli_opts.slice_bufs= (unsigned) atoi(optarg);
   1.171 +                }else if (option_index==6){
   1.172 +                    cli_opts.smt= 1;
   1.173 +                }
   1.174 +                break;
   1.175 +            case '0':
   1.176 +            case '1':
   1.177 +            case '2':
   1.178 +                if (digit_optind != 0 && digit_optind != this_option_optind)
   1.179 +                    printf("digits occur in two different argv-elements.\n");
   1.180 +                digit_optind = this_option_optind;
   1.181 +                printf("option %c\n", c);
   1.182 +                break;
   1.183 +            case 'a':
   1.184 +                no_arch=1;
   1.185 +                break;
   1.186 +            case 'd':
   1.187 +                cli_opts.display=1;
   1.188 +                break;
   1.189 +            case 'f':
   1.190 +                cli_opts.fullscreen=1;
   1.191 +                break;
   1.192 +            case 'i':
   1.193 +                file_name = (const char *)optarg;
   1.194 +                opt_input_file(file_name);
   1.195 +                break;
   1.196 +            case 'n':
   1.197 +                cli_opts.numframes = (unsigned) atoi(optarg);
   1.198 +                break;
   1.199 +            case 'o':
   1.200 +                strcpy(ofile_name, optarg);
   1.201 +                opt_output_file(ofile_name);
   1.202 +                break;
   1.203 +            case 'p':
   1.204 +                cli_opts.profile = (unsigned) atoi(optarg);
   1.205 +                break;
   1.206 +            case 's':
   1.207 +                cli_opts.threads = 0;
   1.208 +                parallel = 0;
   1.209 +                break;
   1.210 +            case 't':
   1.211 +                cli_opts.threads = atoi(optarg);
   1.212 +                if (cli_opts.threads<=0){
   1.213 +                    fprintf(stderr, "Option -%c requires thread numbers > 0\n", c);
   1.214 +                    av_exit(-1);
   1.215 +                }
   1.216 +                break;
   1.217 +            case 'v':
   1.218 +                cli_opts.verbose = 1;
   1.219 +                break;
   1.220 +            case 'w':
   1.221 +                cli_opts.wave_order = 1;
   1.222 +                break;
   1.223 +            case 'z': // only useful in ompss
   1.224 +                if (argc < optind +1){
   1.225 +                    fprintf(stderr, "Option -%c (--smb-size) requires 2 arguments\n", c);
   1.226 +                    av_exit(-1);
   1.227 +                }
   1.228 +                optind--;
   1.229 +                for (int i=0; i<2; i++){
   1.230 +                    cli_opts.smb_size[i] = atoi(argv[optind++]);
   1.231 +                    if (!(cli_opts.smb_size > 0)){
   1.232 +                        fprintf(stderr, "Option -%c (--smb-size) requires dimensions > 0\n", c);
   1.233 +                        av_exit(-1);
   1.234 +                    }
   1.235 +                }
   1.236 +                break;
   1.237 +            case 'e':
   1.238 +                cli_opts.pipe_bufs = atoi(optarg);
   1.239 +                break;
   1.240 +            case ':':
   1.241 +                fprintf(stderr, "Option -%c requires an operand\n", optopt);
   1.242 +                av_exit(-1);
   1.243 +                break;
   1.244 +            case '?':
   1.245 +                fprintf(stderr, "Unrecognized option: -%c\n", optopt);
   1.246 +                av_exit(-1);
   1.247 +                break;
   1.248 +        }
   1.249 +    }
   1.250 +
   1.251 +}
   1.252 +
   1.253 +int main(int argc, char **argv)
   1.254 +{
   1.255 +    /* parse options */
   1.256 +    parse_cmd(argc, argv);
   1.257 +
   1.258 +    if(!ifile ) {
   1.259 +        show_usage();
   1.260 +        av_exit(1);
   1.261 +    }
   1.262 +
   1.263 +    H264Context *h = get_h264dec_context(file_name, ifile, ofile, frame_width, frame_height, &cli_opts);
   1.264 +#if OMPSS
   1.265 +    if (h264_decode_ompss( h ) < 0)
   1.266 +        av_exit(-1);
   1.267 +#else
   1.268 +    if (parallel){
   1.269 +        if (ARCH_CELL && !no_arch){
   1.270 +            if (h264_decode_cell( h ) < 0)
   1.271 +                av_exit(-1);
   1.272 +        }else{
   1.273 +            if (h264_decode_pthread( h ) < 0)
   1.274 +                av_exit(1);
   1.275 +        }
   1.276 +    }else{
   1.277 +        if (ARCH_CELL && !no_arch){
   1.278 +            if (h264_decode_cell_seq( h ) < 0)
   1.279 +                av_exit(1);
   1.280 +        }else{
   1.281 +            if (h264_decode_seq( h ) < 0)
   1.282 +                av_exit(1);
   1.283 +        }
   1.284 +    }
   1.285 +#endif
   1.286 +    free_h264dec_context(h);
   1.287 +    close(ifile);
   1.288 +    close(ofile);
   1.289 +
   1.290 +    return 0;
   1.291 +}