• ffplay源码解析-main入口函数


    main入口函数

    初始化

    变量、缓存区、SDL窗口初始化等

    int main(int argc, char **argv)
    {
    	int flags;
        VideoState *is;
    //    av_log_set_level(AV_LOG_TRACE);
        init_dynload();
    
        av_log_set_flags(AV_LOG_SKIP_REPEATED);
        parse_loglevel(argc, argv, options);
       /// av_log_set_level(AV_LOG_DEBUG);
        /* register all codecs, demux and protocols */
    #if CONFIG_AVDEVICE
        avdevice_register_all();
    #endif
        avformat_network_init();
    
        init_opts();
    
        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);
    
        if (!input_filename) {
            show_usage();
            av_log(NULL, AV_LOG_FATAL, "An input file must be specified\n");
            av_log(NULL, AV_LOG_FATAL,
                   "Use -h to get full help or, even better, run 'man %s'\n", program_name);
            exit(1);
        }
    
        /* 是否显示视频 */
        if (display_disable) {
            video_disable = 1;
        }
    
        flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
        /* 是否运行音频 */
        if (audio_disable)
            flags &= ~SDL_INIT_AUDIO;
        else {
            /* Try to work around an occasional ALSA buffer underflow issue when the
             * period size is NPOT due to ALSA resampling by forcing the buffer size. */
            if (!SDL_getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"))
                SDL_setenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE","1", 1);
        }
        if (display_disable)
            flags &= ~SDL_INIT_VIDEO;
        if (SDL_Init (flags)) {
            av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
            av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
            exit(1);
        }
    
        SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
        SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
    
        av_init_packet(&flush_pkt);				// 初始化flush_packet
        flush_pkt.data = (uint8_t *)&flush_pkt; // 初始化为数据指向自己本身
    
        if (!display_disable) {
            int flags = SDL_WINDOW_HIDDEN;
            if (alwaysontop)
    #if SDL_VERSION_ATLEAST(2,0,5)
                flags |= SDL_WINDOW_ALWAYS_ON_TOP;
    #else
                av_log(NULL, AV_LOG_WARNING, "Your SDL version doesn't support SDL_WINDOW_ALWAYS_ON_TOP. Feature will be inactive.\n");
    #endif
            if (borderless)
                flags |= SDL_WINDOW_BORDERLESS;
            else
                flags |= SDL_WINDOW_RESIZABLE;
            window = SDL_CreateWindow(program_name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, default_width, default_height, flags);
            SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
            if (window) {
                renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
                if (!renderer) {
                    av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
                    renderer = SDL_CreateRenderer(window, -1, 0);
                }
                if (renderer) {
                    if (!SDL_GetRendererInfo(renderer, &renderer_info))
                        av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", renderer_info.name);
                }
            }
            if (!window || !renderer || !renderer_info.num_texture_formats) {
                av_log(NULL, AV_LOG_FATAL, "Failed to create window or renderer: %s", SDL_GetError());
                do_exit(NULL);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    开始播放

    启动线程:解复用,解码,播放等线程都在stream_open中启动

    	is = stream_open(input_filename, file_iformat);
    	if (!is) {
    	    av_log(NULL, AV_LOG_FATAL, "Failed to initialize VideoState!\n");
    	    do_exit(NULL);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    事件响应机制

    播放、暂停、快进、快退等操作

    	/* 事件响应 */
        event_loop(is);
    
        /* never returns */
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    【性能测试】全链路压测
    elk日志某个时间节点突然搜索不到了
    Codeforces Round #476 (Div. 2)——D. Single-use Stones(二分做法)
    求生之路2专用服务器搭建对抗模式,药抗模式,特殊模式Ubuntu系统另附上游戏代码以及控制台代码
    Unity3d的海盗王地图
    基于flask和fomantic-ui的简易p2p文件分享平台的手动实现
    Arduino之ESP8266编程学习总结体会
    Mysql 45讲学习笔记(三十五)优化join语句
    vite3学习记录
    [LeetCode解题报告] 2376. 统计特殊整数
  • 原文地址:https://blog.csdn.net/qq_43537701/article/details/132946264