Skip to content
Snippets Groups Projects
ffplay.c 106 KiB
Newer Older
  • Learn to ignore specific revisions
  • #include "cmdutils_common_opts.h"
    
        { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
        { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
        { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
        { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
        { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
        { "vn", OPT_BOOL, { &video_disable }, "disable video" },
        { "ast", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_AUDIO] }, "select desired audio stream", "stream_number" },
        { "vst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_VIDEO] }, "select desired video stream", "stream_number" },
        { "sst", OPT_INT | HAS_ARG | OPT_EXPERT, { &wanted_stream[AVMEDIA_TYPE_SUBTITLE] }, "select desired subtitle stream", "stream_number" },
        { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
        { "t", HAS_ARG, { .func_arg = opt_duration }, "play  \"duration\" seconds of audio/video", "duration" },
        { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
        { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
        { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
        { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
        { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
        { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, { &workaround_bugs }, "workaround bugs", "" },
        { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
        { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
        { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
        { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
        { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, { &skip_loop_filter }, "", "" },
        { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, { &skip_frame }, "", "" },
        { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, { &skip_idct }, "", "" },
        { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, { &idct }, "set idct algo",  "algo" },
        { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, { &error_concealment }, "set error concealment options",  "bit_mask" },
        { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
        { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
        { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
        { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
        { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
        { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
        { "infbuf", OPT_BOOL | OPT_EXPERT, { &infinite_buffer }, "don't limit the input buffer size (useful with realtime streams)", "" },
        { "window_title", OPT_STRING | HAS_ARG, { &window_title }, "set window title", "window title" },
    
    #if CONFIG_AVFILTER
    
        { "vf", OPT_STRING | HAS_ARG, { &vfilters }, "video filters", "filter list" },
    
        { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
        { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
        { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
        { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
    
        { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder" },
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        { NULL, },
    };
    
    
    static void show_usage(void)
    
        av_log(NULL, AV_LOG_INFO, "Simple media player\n");
        av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
        av_log(NULL, AV_LOG_INFO, "\n");
    
    void show_help_default(const char *opt, const char *arg)
    
        av_log_set_callback(log_callback_help);
    
        show_usage();
    
        show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
        show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
    
        show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
        show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
    
    #if !CONFIG_AVFILTER
    
        show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
    
    #else
        show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        printf("\nWhile playing:\n"
               "q, ESC              quit\n"
               "f                   toggle full screen\n"
               "p, SPC              pause\n"
    
               "a                   cycle audio channel\n"
               "v                   cycle video channel\n"
    
               "s                   activate frame-step mode\n"
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
               "left/right          seek backward/forward 10 seconds\n"
               "down/up             seek backward/forward 1 minute\n"
    
               "page down/page up   seek backward/forward 10 minutes\n"
    
               "mouse click         seek to percentage in file corresponding to fraction of width\n"
    
    static int lockmgr(void **mtx, enum AVLockOp op)
    {
       switch(op) {
          case AV_LOCK_CREATE:
              *mtx = SDL_CreateMutex();
              if(!*mtx)
                  return 1;
              return 0;
          case AV_LOCK_OBTAIN:
              return !!SDL_LockMutex(*mtx);
          case AV_LOCK_RELEASE:
              return !!SDL_UnlockMutex(*mtx);
          case AV_LOCK_DESTROY:
              SDL_DestroyMutex(*mtx);
              return 0;
       }
       return 1;
    }
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    /* Called from the main */
    int main(int argc, char **argv)
    {
    
        char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
    
        av_log_set_flags(AV_LOG_SKIP_REPEATED);
    
        parse_loglevel(argc, argv, options);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        /* register all codecs, demux and protocols */
    
    Luca Abeni's avatar
    Luca Abeni committed
        avcodec_register_all();
    
    Luca Abeni's avatar
    Luca Abeni committed
        avdevice_register_all();
    
    #if CONFIG_AVFILTER
        avfilter_register_all();
    #endif
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        av_register_all();
    
        avformat_network_init();
    
        signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).    */
        signal(SIGTERM, sigterm_handler); /* Termination (ANSI).  */
    
    
        show_banner(argc, argv, options);
    
        parse_options(NULL, argc, argv, options, opt_input_file);
    
            fprintf(stderr, "An input file must be specified\n");
    
    Anton Khirnov's avatar
    Anton Khirnov committed
            fprintf(stderr, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
        if (display_disable) {
            video_disable = 1;
        }
    
        flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
    
        if (audio_disable)
            flags &= ~SDL_INIT_AUDIO;
    
        if (display_disable)
            SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
    
    #if !defined(__MINGW32__) && !defined(__APPLE__)
        flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        if (SDL_Init (flags)) {
    
            fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
    
            fprintf(stderr, "(Did you set the DISPLAY variable?)\n");
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            exit(1);
        }
    
        if (!display_disable) {
    
    #if HAVE_SDL_VIDEO_SIZE
    
            const SDL_VideoInfo *vi = SDL_GetVideoInfo();
            fs_screen_width = vi->current_w;
            fs_screen_height = vi->current_h;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        }
    
        SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
        SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
        SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
    
    
        if (av_lockmgr_register(lockmgr)) {
            fprintf(stderr, "Could not initialize lock manager!\n");
            do_exit(NULL);
        }
    
    
        av_init_packet(&flush_pkt);
    
        flush_pkt.data = (char *)(intptr_t)"FLUSH";
    
        is = stream_open(input_filename, file_iformat);
        if (!is) {
            fprintf(stderr, "Failed to initialize VideoState!\n");
            do_exit(NULL);
        }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
        /* never returns */
    
        return 0;
    }