【问题标题】:How to create a Video player using openGL [closed]如何使用 openGL 创建视频播放器 [关闭]
【发布时间】:2023-03-18 19:45:01
【问题描述】:

我有一个自定义视频解码器。对于这个解码器,每当我给一个H.264 文件(只有视频元素不是音频)作为输入时,我都会得到一组YUV 帧作为我的输出。然后我将这个YUV 帧转换为RGB24 帧并在OpenGL 中渲染它。这种转换和渲染同时发生,即逐帧进行,因此看起来就像我正在观看视频一样。

完成上述操作后,我的下一个任务是实现其他功能,例如播放、暂停、后退、前进等。

目前我只是将帧渲染为以及如何解码并转换为 RGB。也就是说,帧速率约为 60-70 fps。现在,如果我必须实现这个播放/暂停功能,那么我应该如何进行。也就是说,如果按下暂停,解码器应该等到我按下播放按钮。

为此提供一些解决方案。

【问题讨论】:

  • 如果您可以发布单独的问题而不是将您的问题合并为一个问题,则最好。这样,它可以帮助回答您的问题的人以及其他寻找您的至少一个问题的人。

标签: opengl video rendering video-player


【解决方案1】:

您设法做了这么多工作却在项目的这一点上卡住了,这有点奇怪。如果您运行 OpenGL 程序,我假设您有一些无限循环,您可以在其中捕获所有事件(鼠标、键)以及从文件中读取图像并将它们渲染到屏幕上(使用 OpenGL)。这类应用程序通常在多线程环境中运行,特别是文件的读取。您可能希望有一些缓冲区,您总是在其中存储类似动画的下一秒(或更多)的内容,并且当您执行事件循环时,您从该缓冲区读取。同时,当您从缓冲区读取内容时,从磁盘读取数据的线程需要用新信息填充缓冲区。

这可能是使用生产者-消费者算法。请注意,尽管您不需要在多线程环境中执行此操作,但如果您的系统无法以 30 fps 运行,您可能会遇到连续性问题。在事件循环中,您可以读取接下来的 20 帧或 10 帧或其他内容,然后从缓冲区读取下一个图像、渲染等。

在这个循环中,如果查看者按下了暂停键(比如空格),那么只需将文件的读取和渲染传递给循环中的屏幕任务。或者,您可以在渲染之前将整个文件读入内存。

// event loop
 while (1) {
    char key = nextEvent(...)
    if (key == 'x') quiteApp();
    else if (key == 'p') { pauseApp = (pauseApp == true) ? false : true; }
    if (!pauseApp) {
        // adjust the number of frames your read in each loop depending
        // on your frame rate. If you frame rate drops below 30 fps
        // read less frames, etc.
        readFrames(&buffer, videoFile, 10);
        getNextFrameFromBuffer(buffer, frameBuffer);
        displayFrameuBuffer(frameCount, frameBuffer);
    }
    frameCount++;
    // do time synchronisation here so that you always play at given frame
    // rate which is likely to be 30 fps.
    ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-20
    • 2011-11-19
    • 2011-03-11
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    相关资源
    最近更新 更多