Я пишу файл кода для рендеринга видеофайла yuv на основе qt и opengl, когда его высота <ширина работает; иначе это не ра ⇐ C++
-
Anonymous
Я пишу файл кода для рендеринга видеофайла yuv на основе qt и opengl, когда его высота <ширина работает; иначе это не ра
Пожалуйста, простите мой плохой английский. Когда я запускаю код, он выглядит как картинка: один кадр размером 886x1920.yuv
Я могу использовать командную строку «ffplay» для нормального воспроизведения этого файла yuv. Я заменяю файл yuv другим файлом yuv с шириной и высотой 1920x886, это сработало.
это мой код:
[*]
заголовочный файл:
#ifndef GL_SHOW_WIDGET_H #define GL_SHOW_WIDGET_H #include #include #include #include #include #include #include #include класс GLShowWidget: общедоступный QOpenGLWidget, защищенный QOpenGLFunctions { Q_OBJECT публика: GLShowWidget (родитель QWidget * = nullptr); ~GLShowWidget(); защищено: недействительными инициализироватьGL () Q_DECL_OVERRIDE; void resizeGL (int w, int h) Q_DECL_OVERRIDE; недействительный PaintGL () Q_DECL_OVERRIDE; частный: QOpenGLVertexArrayObject vao_; QOpenGLBuffer vbo_; QOpenGLShaderProgram* m_sharder_program_; std::vector m_textureYUV_; // для теста QФайл m_file_; }; #endif // GL_SHOW_WIDGET_H [*]файл cpp
#include "gl_show_widget.h" #include #include #include #include статическая константа uint32_t VideoWidth = 886; статическая константа uint32_t VideoHeight = 1920; #define GL_VERSION_this "ядро #версия 330\n" #define GET_GLSTR(x) GL_VERSION_this#x const char *vsrc = GET_GLSTR( макет (location = 0) в позиции vec2; из vec2 texCoord; пустая функция() { gl_Position = vec4 (позиция, 0,0, 1,0); texCoord = позиция * 0,5 + 0,5; } ); const char *fsrc =GET_GLSTR( в vec2 texCoord; униформа sampler2D yTexture; единый сэмплер2D uTexture; униформа sampler2D vTexture; из vec4 fragColor; пустая функция() { float y = текстура (yTexture, texCoord).r; float u = текстура(uTexture, texCoord).r - 0,5; float v = текстура(vTexture, texCoord).r - 0,5; плавающий г = у + 1,13983 * v; float g = y - 0,39465 * u - 0,5806 * v; поплавок б = у + 2,03211 * и; fragColor = vec4(r, g, b, 1.0); } ); GLShowWidget::GLShowWidget(QWidget *parent) : QOpenGLWidget(parent) { qDebug() уничтожить(); удалить текстуру; } m_textureYUV_.clear(); } если (m_sharder_program_) { m_sharder_program_->release(); удалить m_sharder_program_; m_sharder_program_ = nullptr; } vbo_.destroy(); вао_.разрушить(); } void GLShowWidget::initializeGL() { qDebug() setSize(VideoWidth/2, VideoHeight/2); } m_textureYUV_->setMinMagFilters(QOpenGLTexture::LinearMipMapNearest, QOpenGLTexture::Linear); m_textureYUV_->setFormat(QOpenGLTexture::R8_UNorm); m_textureYUV_->setWrapMode(QOpenGLTexture::ClampToEdge); m_textureYUV_->allocateStorage(); qDebug() addShaderFromSourceCode(QOpenGLShader::Vertex, vsrc); m_sharder_program_->addShaderFromSourceCode(QOpenGLShader::Fragment, fsrc); m_sharder_program_->ссылка(); m_sharder_program_->bind(); вершины с плавающей запятой[] = { -1.0f, -1.0f, 1.0ф, -1.0ф, -1.0f, 1.0f, 1.0ф, 1.0ф, }; vbo_.allocate(вершины, sizeof(вершины)); vbo_.setUsagePattern(QOpenGLBuffer::StaticDraw); m_sharder_program_->setAttributeBuffer(0, GL_FLOAT, 0, 2, 2 * sizeof(float)); m_sharder_program_->enableAttributeArray(0); m_sharder_program_->setUniformValue("yTexture", 0); m_sharder_program_->setUniformValue("uTexture", 1); m_sharder_program_->setUniformValue("vTexture", 2); vbo_.release(); vao_.release(); QTimer *ti = новый QTimer(this); Connect(ti, СИГНАЛ(таймаут()), это, СЛОТ(обновление())); ти-> старт (30); } void GLShowWidget::paintGL() { qDebug() setData(QOpenGLTexture::Red,QOpenGLTexture::UInt8,buf1.data()); m_textureYUV_[0]->bind(0); QByteArray buf2 = m_file_.read(VideoWidth * VideoHeight/4); m_textureYUV_[1]->setData(QOpenGLTexture::Red,QOpenGLTexture::UInt8,buf2.data()); m_textureYUV_[1]->bind(1); QByteArray buf3 = m_file_.read(VideoWidth * VideoHeight/4); m_textureYUV_[2]->setData(QOpenGLTexture::Red,QOpenGLTexture::UInt8,buf3.data()); m_textureYUV_[2]->bind(2); glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); m_textureYUV_[0]->release(); m_textureYUV_[1]->release(); m_textureYUV_[2]->release(); vbo_.release(); vao_.release(); } void GLShowWidget::resizeGL(int w, int h) { qDebug()
Пожалуйста, простите мой плохой английский. Когда я запускаю код, он выглядит как картинка: один кадр размером 886x1920.yuv
Я могу использовать командную строку «ffplay» для нормального воспроизведения этого файла yuv. Я заменяю файл yuv другим файлом yuv с шириной и высотой 1920x886, это сработало.
это мой код:
[*]
заголовочный файл:
#ifndef GL_SHOW_WIDGET_H #define GL_SHOW_WIDGET_H #include #include #include #include #include #include #include #include класс GLShowWidget: общедоступный QOpenGLWidget, защищенный QOpenGLFunctions { Q_OBJECT публика: GLShowWidget (родитель QWidget * = nullptr); ~GLShowWidget(); защищено: недействительными инициализироватьGL () Q_DECL_OVERRIDE; void resizeGL (int w, int h) Q_DECL_OVERRIDE; недействительный PaintGL () Q_DECL_OVERRIDE; частный: QOpenGLVertexArrayObject vao_; QOpenGLBuffer vbo_; QOpenGLShaderProgram* m_sharder_program_; std::vector m_textureYUV_; // для теста QФайл m_file_; }; #endif // GL_SHOW_WIDGET_H [*]файл cpp
#include "gl_show_widget.h" #include #include #include #include статическая константа uint32_t VideoWidth = 886; статическая константа uint32_t VideoHeight = 1920; #define GL_VERSION_this "ядро #версия 330\n" #define GET_GLSTR(x) GL_VERSION_this#x const char *vsrc = GET_GLSTR( макет (location = 0) в позиции vec2; из vec2 texCoord; пустая функция() { gl_Position = vec4 (позиция, 0,0, 1,0); texCoord = позиция * 0,5 + 0,5; } ); const char *fsrc =GET_GLSTR( в vec2 texCoord; униформа sampler2D yTexture; единый сэмплер2D uTexture; униформа sampler2D vTexture; из vec4 fragColor; пустая функция() { float y = текстура (yTexture, texCoord).r; float u = текстура(uTexture, texCoord).r - 0,5; float v = текстура(vTexture, texCoord).r - 0,5; плавающий г = у + 1,13983 * v; float g = y - 0,39465 * u - 0,5806 * v; поплавок б = у + 2,03211 * и; fragColor = vec4(r, g, b, 1.0); } ); GLShowWidget::GLShowWidget(QWidget *parent) : QOpenGLWidget(parent) { qDebug() уничтожить(); удалить текстуру; } m_textureYUV_.clear(); } если (m_sharder_program_) { m_sharder_program_->release(); удалить m_sharder_program_; m_sharder_program_ = nullptr; } vbo_.destroy(); вао_.разрушить(); } void GLShowWidget::initializeGL() { qDebug() setSize(VideoWidth/2, VideoHeight/2); } m_textureYUV_->setMinMagFilters(QOpenGLTexture::LinearMipMapNearest, QOpenGLTexture::Linear); m_textureYUV_->setFormat(QOpenGLTexture::R8_UNorm); m_textureYUV_->setWrapMode(QOpenGLTexture::ClampToEdge); m_textureYUV_->allocateStorage(); qDebug() addShaderFromSourceCode(QOpenGLShader::Vertex, vsrc); m_sharder_program_->addShaderFromSourceCode(QOpenGLShader::Fragment, fsrc); m_sharder_program_->ссылка(); m_sharder_program_->bind(); вершины с плавающей запятой[] = { -1.0f, -1.0f, 1.0ф, -1.0ф, -1.0f, 1.0f, 1.0ф, 1.0ф, }; vbo_.allocate(вершины, sizeof(вершины)); vbo_.setUsagePattern(QOpenGLBuffer::StaticDraw); m_sharder_program_->setAttributeBuffer(0, GL_FLOAT, 0, 2, 2 * sizeof(float)); m_sharder_program_->enableAttributeArray(0); m_sharder_program_->setUniformValue("yTexture", 0); m_sharder_program_->setUniformValue("uTexture", 1); m_sharder_program_->setUniformValue("vTexture", 2); vbo_.release(); vao_.release(); QTimer *ti = новый QTimer(this); Connect(ti, СИГНАЛ(таймаут()), это, СЛОТ(обновление())); ти-> старт (30); } void GLShowWidget::paintGL() { qDebug() setData(QOpenGLTexture::Red,QOpenGLTexture::UInt8,buf1.data()); m_textureYUV_[0]->bind(0); QByteArray buf2 = m_file_.read(VideoWidth * VideoHeight/4); m_textureYUV_[1]->setData(QOpenGLTexture::Red,QOpenGLTexture::UInt8,buf2.data()); m_textureYUV_[1]->bind(1); QByteArray buf3 = m_file_.read(VideoWidth * VideoHeight/4); m_textureYUV_[2]->setData(QOpenGLTexture::Red,QOpenGLTexture::UInt8,buf3.data()); m_textureYUV_[2]->bind(2); glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); m_textureYUV_[0]->release(); m_textureYUV_[1]->release(); m_textureYUV_[2]->release(); vbo_.release(); vao_.release(); } void GLShowWidget::resizeGL(int w, int h) { qDebug()
Мобильная версия