增强axmol引擎视频播放之 - Linux(Ubuntu)视频播放支持

这篇具有很好参考价值的文章主要介绍了增强axmol引擎视频播放之 - Linux(Ubuntu)视频播放支持。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言

接续“增强axmol引擎视频播放之 - android视频播放支持”,本文主要描述如何在 著名的Linux发行版Ubuntu支持视频渲染到纹理播放。如无特殊说明,一下描述中出现Linux均指的是Ubuntu Linux,版本Ubuntu 22.04+

为什么开发

当笔者成功完成了android视频纹理渲染后,axmol引擎所支持的平台(macos,windows,ios/tvos,android,linux),就只剩下Linux了,因此萌生了何不顺带把Linux支持下。

调研

经过研究发现,Linux下比较优秀的播放器里,VLC提供了libvlc LGPL-2.1授权(不修改源码的情况下,以动态库形式免费商用),因此集成libvlc是比较好的方案。

如何实现

依然是实现axmol的MediaEngine接口,不过我们使用libvlc作为backend

  1. 安装libvlc开发包

    sudo apt install libvlc-dev libvlccore-dev vlc
    

    其中libvlc-devlibvlccore-dev是编译连接必须的,而安装vlc实际上是安装播放器和插件.so,其中播放器不需要,插件才是运行必须的,否则运行就会无法解码视频。
    TIPS: 插件加载潜规则:

    • 默认情况下,当调用libvlc_new API时,libvlc会从libvlc.solibvlccore.so库所在目录下的plugins目录搜索播放视频所需解码插件。安装vlc会将插件放到正确的路径
    • 通过环境变量: VLC_PLUGIN_PATH指定libvlc加载插件路径
      • Linux可通过API setenv动态设置:setenv("VLC_PLUGIN_PATH", "/path/to/vlc/plugins", true);
      • Windows可通过API _putenv_s 设置,但特别注意需要根据libvlc.dlllibvlccore.dll以来的c运行库决定,官方预编译好的libvlc库使用的是msvcrt,意味着在win10系统上,直接调用_putenv_s是无效的,直接调用_putenv_s通常会设置ucrt里的环境变量,msvcrtucrtbased/ucrtbase不同C运行库共存时,内存时隔离的,如果想时两种运行库都生效,可通过如下方式设置:
        _putenv_s("VLC_PLUGIN_PATH", R"(D:\dev\axmol\thirdparty\vlc\win\lib\plugins)");
        
        HMODULE hmsvcrt = GetModuleHandleW(L"msvcrt.dll");
        auto msvcrt_getenv = (decltype(getenv)*)GetProcAddress(hmsvcrt, "getenv");
        
        if (msvcrt_getenv)
        {
            auto msvcrt_putenv_s = (decltype(_putenv_s)*)GetProcAddress(hmsvcrt, "_putenv_s");
            if (msvcrt_putenv_s)
                msvcrt_putenv_s("VLC_PLUGIN_PATH", R"(D:\dev\axmol\thirdparty\vlc\win\lib\plugins)");
        }
        
  2. 编写代码实现MediaEngine的核心功能,如播放,暂停等,注册callbacks(媒体事件,视频NV12 Frame事件)等功能。

  3. 关于如何让获取VLC解码的NV12视频数据(网上多数都是RGBA),本文只贴出关键代码

    libvlc lock回调中,为本次视频数据frame锁定内存以便写入:

    static constexpr auto VLC_OUTPUT_FORMAT = ax::MEVideoPixelFormat::NV12;
    
    void* VlcMediaEngine::libvlc_video_lock(void* data, void** p_pixels)
    {
        VlcMediaEngine* mediaEngine = static_cast<VlcMediaEngine*>(data);
    
        auto& bufferDim    = mediaEngine->_videoDim;
        auto& outputBuffer = mediaEngine->_frameBuffer1;
        mediaEngine->_frameBuffer1Mtx.lock();
        if constexpr (VLC_OUTPUT_FORMAT == ax::MEVideoPixelFormat::NV12)
        {
            outputBuffer.resize_fit(bufferDim.x * bufferDim.y + (bufferDim.x * bufferDim.y >> 1));  // NV12
            p_pixels[0] = outputBuffer.data();
            p_pixels[1] = outputBuffer.data() + (bufferDim.x * bufferDim.y);
        }
        else if constexpr (VLC_OUTPUT_FORMAT == ax::MEVideoPixelFormat::YUY2)
        {
            outputBuffer.resize_fit(bufferDim.x * bufferDim.y + ((bufferDim.x >> 1) * bufferDim.y * 4));  // YUY2
            p_pixels[0] = outputBuffer.data();
        }
        else
        {
            outputBuffer.resize_fit(bufferDim.x * bufferDim.y * 4);  // RGBA32
            p_pixels[0] = outputBuffer.data();
        }
        return nullptr;
    }
    void VlcMediaEngine::libvlc_video_unlock(void* data, void* id, void* const* p_pixels)
    {
        VlcMediaEngine* mediaEngine = static_cast<VlcMediaEngine*>(data);
        mediaEngine->_frameBuffer1Mtx.unlock();
        ++mediaEngine->_frameIndex;
        assert(id == nullptr);
    }
    

    libvlc使用回调模式格式设置,值得注意的是NV12需要指定第二个planepitch(bytesPerRow)和lines(视频期望渲染高度/2)

    unsigned int VlcMediaEngine::libvlc_video_format_setup(void** opaque,
                                                           char* chroma,  // forcc, refer to:vlc_fourcc.h
                                                           unsigned* width,
                                                           unsigned* height,
                                                           unsigned* pitches,
                                                           unsigned* lines)
    {
        // refer to: vmem.c:Open https://github.com/videolan/vlc/blob/3.0.18/modules/video_output/vmem.c#L150
        // future: 4.0: will be widths, heights:
        // https://github.com/videolan/vlc/blob/master/modules/video_output/vmem.c#L156
        VlcMediaEngine* mediaEngine = static_cast<VlcMediaEngine*>(*opaque);
    
        // vlc tell us the original codecDim(ALIGNED)
        mediaEngine->_codecDim.set(width[0], height[0]);
    
        // tell vlc we want render as video size
        width[0]  = mediaEngine->_videoDim.x;
        height[0] = mediaEngine->_videoDim.y;
    
        // plane0
        pitches[0] = width[0];   // bytesPerRow
        lines[0]   = height[0];  // rows
    
    #    if LIBVLC_VERSION_MAJOR >= 4
        mediaEngine->_videoDim.set(width[1], height[1]);
    #    endif
    
        int num_of_plane = 1;
    
        if constexpr (VLC_OUTPUT_FORMAT == ax::MEVideoPixelFormat::NV12)
        {
            memcpy(chroma, "NV12", 4);
    
            // plane1
            pitches[1] = mediaEngine->_videoDim.x;       // bytesPerRow
            lines[1]   = mediaEngine->_videoDim.y >> 1;  // rows
    
            num_of_plane = 2;
        }
        else if constexpr (VLC_OUTPUT_FORMAT == ax::MEVideoPixelFormat::YUY2)
        {
            memcpy(chroma, "YUY2", 4);
            pitches[0] = width[0] * 2;  // bytesPerRow
        }
        else
        {
            memcpy(chroma, "RGBA", 4);
            pitches[0] = width[0] * 4;  // bytesPerRow
        }
    
        // return the number of picture buffers allocated, 0 indicates failure
        return num_of_plane;
    }
    

运行和注意事项

请下载axmol引擎最新源码在Ubuntu 22.04+系统下编译运行。如果遇到播放视频出现无法解码问题,请安装ubuntu扩展组件,命令如下:

sudo apt install ubuntu-restricted-extras

结语

自此,axmol引擎的ui::MediaPlayer支持全部平台上的视频纹理渲染播放,这也得益于重新设计的MediaEngine 框架,该框架不仅能在axmol引擎中工作,也可以独立编译,例如笔者编写的bgfx视频播放示例:bgfx-axplay。
另外:libvlc本身是跨平台的,因此本文中的实现VlcMediaEngine经过简单配置也可以运行在其他平台,例如Windows文章来源地址https://www.toymoban.com/news/detail-480679.html

到了这里,关于增强axmol引擎视频播放之 - Linux(Ubuntu)视频播放支持的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 全方位支持图文和音视频、100+增强功能,Facebook开源数据增强库AugLy

    Facebook 近日开源了数据增强库 AugLy,包含四个子库,每个子库对应不同的模态,每个库遵循相同的接口。支持四种模态:文本、图像、音频和视频。 最近,Facebook 开源了一个新的 Python 库——AugLy,该库旨在帮助 AI 研究人员使用数据增强来评估和改进机器学习模型的可用性。

    2024年02月15日
    浏览(45)
  • 用Qt开发的ffmpeg流媒体播放器,支持截图、录像,支持音视频播放,支持本地文件播放、网络流播放

    本工程qt用的版本是5.8-32位,ffmpeg用的版本是较新的5.1版本。它支持TCP或UDP方式拉取实时流,实时流我采用的是监控摄像头的RTSP流。音频播放采用的是QAudioOutput,视频经ffmpeg解码并由YUV转RGB后是在QOpenGLWidget下进行渲染显示。本工程的代码有注释,可以通过本博客查看代码或者

    2024年02月03日
    浏览(100)
  • 视频增强修复软件Topaz Video AI mac中文版支持功能

    Topaz Video AI mac是一款使用人工智能技术对视频进行增强和修复的软件。它可以自动降噪、去除锐化、减少压缩失真、提高清晰度等等。Topaz Video AI可以处理各种类型的视频,包括低分辨率视频、老旧影片、手机录制的视频等等。 使用Topaz Video AI非常简单,只需要将需要处理的

    2024年02月06日
    浏览(39)
  • 安防视频综合管理合平台EasyCVR可支持的视频播放协议有哪些?

    EasyDarwin开源流媒体视频EasyCVR安防监控平台可提供视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、云台控制、语音对讲、智能分析等能力。 视频监控综合管理平台EasyCVR具备视频融合能力,平台基于云边端一体化架构,具有强大的数据接入、处理及

    2024年02月14日
    浏览(34)
  • 浏览器网页内嵌Qt-C++音视频播放器的实现,支持软硬解码,支持音频,支持录像截图,支持多路播放等,提供源码工程下载

        在浏览器中实现播放RTSP实时视频流,⼤体上有如下⼏个⽅案: ⽅案一:浏览器插件⽅案 ActiveX、NPAPI、PPAPI     ActiveX插件适用于IE浏览器,NPAPI与PPAPI插件适用于谷歌浏览器,不过这些插件都已经不被浏览器所支持。 ⽅案二:先转码再转流⽅案     ⼯作原理是架设一

    2024年01月17日
    浏览(94)
  • Qt音视频开发41-文件推流(支持网页和播放器播放并切换进度)

    本功能最初也是有一些人提过类似的需求,就是能不能将本地的音视频文件,通过纯Qt程序推流出去,然后用户可以直接在网页上播放,也可以用各种播放器播放,然后还可以任意切换播放进度,其实说白了就是个文件服务器,用户通过网络地址访问以后,告诉对方当前是媒

    2024年02月01日
    浏览(68)
  • 【OpenCV+Qt】实现简易视频播放器——支持进度条拖动

    OpenCV实现视频播放器,其思路大致就是在线程中使用OpenCV中的VideoCapture循环读取本地视频的每一帧Mat,然后发送到界面转换成QImage进行显示,而进度条拖动则用到了VideoCapture中的set函数,进度条则是使用Qslider;并且通过自定义新的进度条类实现点击跳转功能; 效果: 1.进行

    2023年04月08日
    浏览(52)
  • 展厅中控视频播放器,支持网络、串口、语音、web、键盘控制

    一、控制代码 网盘:https://pan.baidu.com/s/1Jthrn4HXcRarXxCH8P7X9Q 提取码:1234 1、udp、tcp、串口控制协议、强大的指令集,可满足展厅对于播控的需要 2、语音识别控制 播放器也支持语音控制,例如说出暂停、播放、影片名称等等。识别到会进行切换相应响应。 3、web控制 播放器同时

    2024年02月12日
    浏览(47)
  • Qt之基于QMediaPlayer的音视频播放器(支持常见音视频格式)

    Qt自带了一个Media Player的例子,如下图所示: 但是运行这个例子机会发现,连最基本的MP4格式视频都播放不了。因为QMediaPlayer是个壳(也可以叫框架),依赖本地解码器,视频这块默认基本上就播放个MP4,甚至连MP4都不能播放,如果要支持其他格式需要下载k-lite或者LAVFilter

    2024年02月02日
    浏览(67)
  • Ubuntu——安装smplayer视频播放器

    打开终端,输入以下命令(如果是root用户免sudo): 这一行的作用是下载额外的解码器:

    2024年02月13日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包