⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ffplay.c

📁 F:图像处理资料264264书籍ffmpeg-0.4.9-pre1VideoStream.rar 一个视频解压缩源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    ret = 0; fail:    /* disable interrupting */    global_video_state = NULL;    /* close each stream */    if (is->audio_stream >= 0)        stream_component_close(is, is->audio_stream);    if (is->video_stream >= 0)        stream_component_close(is, is->video_stream);    if (is->ic) {        av_close_input_file(is->ic);        is->ic = NULL; /* safety */    }    url_set_interrupt_cb(NULL);    if (ret != 0) {        SDL_Event event;                event.type = FF_QUIT_EVENT;        event.user.data1 = is;        SDL_PushEvent(&event);    }    return 0;}static VideoState *stream_open(const char *filename, AVInputFormat *iformat){    VideoState *is;    is = av_mallocz(sizeof(VideoState));    if (!is)        return NULL;    pstrcpy(is->filename, sizeof(is->filename), filename);    is->iformat = iformat;    if (screen) {        is->width = screen->w;        is->height = screen->h;    }    is->ytop = 0;    is->xleft = 0;    /* start video display */    is->pictq_mutex = SDL_CreateMutex();    is->pictq_cond = SDL_CreateCond();    /* add the refresh timer to draw the picture */    schedule_refresh(is, 40);    is->av_sync_type = av_sync_type;    is->parse_tid = SDL_CreateThread(decode_thread, is);    if (!is->parse_tid) {        av_free(is);        return NULL;    }    return is;}static void stream_close(VideoState *is){    VideoPicture *vp;    int i;    /* XXX: use a special url_shutdown call to abort parse cleanly */    is->abort_request = 1;    SDL_WaitThread(is->parse_tid, NULL);    /* free all pictures */    for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {        vp = &is->pictq[i];        if (vp->bmp) {            SDL_FreeYUVOverlay(vp->bmp);            vp->bmp = NULL;        }    }    SDL_DestroyMutex(is->pictq_mutex);    SDL_DestroyCond(is->pictq_cond);}void stream_cycle_channel(VideoState *is, int codec_type){    AVFormatContext *ic = is->ic;    int start_index, stream_index;    AVStream *st;    if (codec_type == CODEC_TYPE_VIDEO)        start_index = is->video_stream;    else        start_index = is->audio_stream;    if (start_index < 0)        return;    stream_index = start_index;    for(;;) {        if (++stream_index >= is->ic->nb_streams)            stream_index = 0;        if (stream_index == start_index)            return;        st = ic->streams[stream_index];        if (st->codec.codec_type == codec_type) {            /* check that parameters are OK */            switch(codec_type) {            case CODEC_TYPE_AUDIO:                if (st->codec.sample_rate != 0 &&                    st->codec.channels != 0)                    goto the_end;                break;            case CODEC_TYPE_VIDEO:                goto the_end;            default:                break;            }        }    } the_end:    stream_component_close(is, start_index);    stream_component_open(is, stream_index);}void toggle_full_screen(void){    int w, h, flags;    is_full_screen = !is_full_screen;    if (!fs_screen_width) {        /* use default SDL method */        SDL_WM_ToggleFullScreen(screen);    } else {        /* use the recorded resolution */        flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;        if (is_full_screen) {            w = fs_screen_width;            h = fs_screen_height;            flags |= SDL_FULLSCREEN;        } else {            w = screen_width;            h = screen_height;            flags |= SDL_RESIZABLE;        }        screen = SDL_SetVideoMode(w, h, 0, flags);        cur_stream->width = w;        cur_stream->height = h;    }}void toggle_pause(void){    if (cur_stream)        stream_pause(cur_stream);    step = 0;}void step_to_next_frame(void){    if (cur_stream) {        if (cur_stream->paused)            cur_stream->paused=0;        cur_stream->video_current_pts = get_video_clock(cur_stream);    }    step = 1;}void do_exit(void){    if (cur_stream) {        stream_close(cur_stream);        cur_stream = NULL;    }    if (show_status)        printf("\n");    SDL_Quit();    exit(0);}void toggle_audio_display(void){    if (cur_stream) {        cur_stream->show_audio = !cur_stream->show_audio;    }}/* handle an event sent by the GUI */void event_loop(void){    SDL_Event event;    double incr, pos, frac;    for(;;) {        SDL_WaitEvent(&event);        switch(event.type) {        case SDL_KEYDOWN:            switch(event.key.keysym.sym) {            case SDLK_ESCAPE:            case SDLK_q:                do_exit();                break;            case SDLK_f:                toggle_full_screen();                break;            case SDLK_p:            case SDLK_SPACE:                toggle_pause();                break;            case SDLK_s: //S: Step to next frame                step_to_next_frame();                break;            case SDLK_a:                if (cur_stream)                     stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO);                break;            case SDLK_v:                if (cur_stream)                     stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO);                break;            case SDLK_w:                toggle_audio_display();                break;            case SDLK_LEFT:                incr = -10.0;                goto do_seek;            case SDLK_RIGHT:                incr = 10.0;                goto do_seek;            case SDLK_UP:                incr = 60.0;                goto do_seek;            case SDLK_DOWN:                incr = -60.0;            do_seek:                if (cur_stream) {                    pos = get_master_clock(cur_stream);                    pos += incr;                    stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE));                }                break;            default:                break;            }            break;        case SDL_MOUSEBUTTONDOWN:	    if (cur_stream) {		int ns, hh, mm, ss;		int tns, thh, tmm, tss;		tns = cur_stream->ic->duration/1000000LL;		thh = tns/3600;		tmm = (tns%3600)/60;		tss = (tns%60);		frac = (double)event.button.x/(double)cur_stream->width;		ns = frac*tns;		hh = ns/3600;		mm = (ns%3600)/60;		ss = (ns%60);		fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,			hh, mm, ss, thh, tmm, tss);		stream_seek(cur_stream, (int64_t)(cur_stream->ic->start_time+frac*cur_stream->ic->duration));	    }	    break;        case SDL_VIDEORESIZE:            if (cur_stream) {                screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,                                           SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);                cur_stream->width = event.resize.w;                cur_stream->height = event.resize.h;            }            break;        case SDL_QUIT:        case FF_QUIT_EVENT:            do_exit();            break;        case FF_ALLOC_EVENT:            alloc_picture(event.user.data1);            break;        case FF_REFRESH_EVENT:            video_refresh_timer(event.user.data1);            break;        default:            break;        }    }}void opt_width(const char *arg){    screen_width = atoi(arg);}void opt_height(const char *arg){    screen_height = atoi(arg);}static void opt_format(const char *arg){    file_iformat = av_find_input_format(arg);    if (!file_iformat) {        fprintf(stderr, "Unknown input format: %s\n", arg);        exit(1);    }}static void opt_image_format(const char *arg){    AVImageFormat *f;        for(f = first_image_format; f != NULL; f = f->next) {        if (!strcmp(arg, f->name))            break;    }    if (!f) {        fprintf(stderr, "Unknown image format: '%s'\n", arg);        exit(1);    }    image_format = f;}#ifdef CONFIG_NETWORKvoid opt_rtp_tcp(void){    /* only tcp protocol */    rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP);}#endifvoid opt_sync(const char *arg){    if (!strcmp(arg, "audio"))        av_sync_type = AV_SYNC_AUDIO_MASTER;    else if (!strcmp(arg, "video"))        av_sync_type = AV_SYNC_VIDEO_MASTER;    else if (!strcmp(arg, "ext"))        av_sync_type = AV_SYNC_EXTERNAL_CLOCK;    else        show_help();}void opt_seek(const char *arg){    start_time = parse_date(arg, 1);}static void opt_debug(const char *arg){    debug = atoi(arg);}    static void opt_vismv(const char *arg){    debug_mv = atoi(arg);}static void opt_thread_count(const char *arg){    thread_count= atoi(arg);#if !defined(HAVE_PTHREADS) && !defined(HAVE_W32THREADS)    fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");#endif}    const OptionDef options[] = {    { "h", 0, {(void*)show_help}, "show help" },        { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" },    { "y", HAS_ARG, {(void*)opt_height}, "force displayed height", "height" },#if 0    /* disabled as SDL/X11 does not support it correctly on application launch */    { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" },#endif    { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },    { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" },    { "ss", HAS_ARG, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" },    { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" },    { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },    { "img", HAS_ARG, {(void*)opt_image_format}, "force image format", "img_fmt" },    { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" },    { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" },    { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" },    { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" },#ifdef CONFIG_NETWORK    { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" },#endif    { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },    { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },    { NULL, },};void show_help(void){    printf("ffplay version " FFMPEG_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"           "usage: ffplay [options] input_file\n"           "Simple media player\n");    printf("\n");    show_help_options(options, "Main options:\n",                      OPT_EXPERT, 0);    show_help_options(options, "\nAdvanced options:\n",                      OPT_EXPERT, OPT_EXPERT);    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"           "w                   show audio waves\n"           "left/right          seek backward/forward 10 seconds\n"           "down/up             seek backward/forward 1 minute\n"           "mouse click         seek to percentage in file corresponding to fraction of width\n"           );    exit(1);}void parse_arg_file(const char *filename){    if (!strcmp(filename, "-"))                    filename = "pipe:";    input_filename = filename;}/* Called from the main */int main(int argc, char **argv){    int flags, w, h;        /* register all codecs, demux and protocols */    av_register_all();    parse_options(argc, argv, options);    if (!input_filename)        show_help();    if (display_disable) {        video_disable = 1;    }    flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;#ifndef CONFIG_WIN32    flags |= SDL_INIT_EVENTTHREAD; /* Not supported on win32 */#endif    if (SDL_Init (flags)) {        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());        exit(1);    }    if (!display_disable) {#ifdef HAVE_X11        /* save the screen resolution... SDL should allow full screen           by resizing the window */        {            Display *dpy;            dpy = XOpenDisplay(NULL);            if (dpy) {                fs_screen_width = DisplayWidth(dpy, DefaultScreen(dpy));                fs_screen_height = DisplayHeight(dpy, DefaultScreen(dpy));		XCloseDisplay(dpy);            }        }#endif        flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;        if (is_full_screen && fs_screen_width) {            w = fs_screen_width;            h = fs_screen_height;            flags |= SDL_FULLSCREEN;        } else {            w = screen_width;            h = screen_height;            flags |= SDL_RESIZABLE;        }        screen = SDL_SetVideoMode(w, h, 0, flags);        if (!screen) {            fprintf(stderr, "SDL: could not set video mode - exiting\n");            exit(1);        }        SDL_WM_SetCaption("FFplay", "FFplay");    }    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);    SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);    cur_stream = stream_open(input_filename, file_iformat);    event_loop();    /* never returns */    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -