ffplay深入解析——main函数解析篇(五)

介绍:

我是李铁山,ffplay是基于ffmpeg的播放器,B站大名鼎鼎的ijkplayer也是基于此二次开发,因此很有学习价值。

这篇文章是我深入解析ffplay的首篇,将会从main函数,自顶向下地剖析源码。

如果您对于源码感兴趣,可以查看ffplay的github地址https://github.com/FFmpeg/FFmpeg/blob/master/fftools/ffplay.c

解读源码

今天要读的代码有点长,大家耐着点性子看哈~

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;

#ifdef SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR
        SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
#endif
        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);
        }
    }

 这段代码主要是处理 display_disable 为 false 的情况,就是在可以播放的情况下,开始处理以下逻辑。

首先,定义了一个变量 flags,将 SDL_WINDOW_HIDDEN 赋值给它,用于将窗口设置为不可见状态。这意味着在创建窗口后,该窗口将不会显示在屏幕上。接着我们看下一段代码,这是一个用了宏定义的条件判断,我改写一下,这样可能好阅读点

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");
}

SDL_VERSION_ATLEAST 是 SDL 中的一个宏,用于检查 SDL 库的版本是否至少符合指定的版本号。如果符合 2.0.5 的版本,那么 flags 再增添  SDL_WINDOW_ALWAYS_ON_TOP 的值,意思为该窗口始终位于其他窗口的顶部,但之前该窗口因为 SDL_WINDOW_HIDDEN 屏蔽掉了,不知道还设置在顶部有什么意义,有没有高手在评论区指点我一下。

如果不符合 2.0.5 的版本,就程序就打印 “你的SDL不支持设置窗口在顶部” 的信息。然后我们接着看下一段,同样是一个条件判断

if (borderless)
    flags |= SDL_WINDOW_BORDERLESS;
else
    flags |= SDL_WINDOW_RESIZABLE;

这段比较好理解,大家也不用往下深究。符合 borderless 的条件的时候,将 SDL_WINDOW_BORDERLESS 赋值给 flags,表示窗口没有边框,否则窗口可以设置大小。我疑惑的是窗口有没有边框和能不能设置大小冲突吗,算了,这也不是很重要,知道意思后跳过就行。

下面也是一个宏条件判断

#ifdef SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR
        SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
#endif

 这应该是希望如果符合这个宏,就直接控制窗口的渲染,而不通过窗口管理器的复合操作,应该是提高性能的一种手段。

好了,这段代码比较长,今天就讲了前一半,前半段代码比较基础,基本就是设置 SDL 窗口的一些效果。后半段比较重要,会涉及到 SDL 窗口的初始化,下一篇文章再讲吧。

欲知后事如何,请听下回分解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值