gpt4 book ai didi

c++ - 在 GLFW 窗口中显示 FFMPEG 解码帧

转载 作者:行者123 更新时间:2023-12-04 23:12:41 25 4
gpt4 key购买 nike

我正在实现游戏的客户端程序,其中服务器将游戏的编码帧发送到客户端(通过 UDP),而客户端将它们解码(通过 FFMPEG)并将它们显示在 GLFW 中。 window 。
我的程序有两个线程:

  • 线程 1:渲染 uint8_t* 变量的内容 dataToRender
  • 线程2:不断从服务器获取帧,解码并更新dataToRender相应地

  • 线程 1 在 while 循环中执行 GLFW 窗口的典型渲染。我已经尝试显示一些虚拟帧数据(一个完全红色的帧)并且它有效:
    while (!glfwWindowShouldClose(window)) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    ...

    glBindTexture(GL_TEXTURE_2D, tex_handle);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, window_width, window_height, 0, GL_RGB, GL_UNSIGNED_BYTE, dataToRender);
    ...
    glfwSwapBuffers(window);
    }

    线程 2 是我遇到麻烦的地方。我无法将解码后的帧正确存储到我的 dataToRender 中多变的。最重要的是,帧数据原本是 YUV 格式,需要转成 RGB。我使用 FFMPEG 的 sws_scale为此,这也给了我一个 bad dst image pointers控制台中的错误输出。这是负责该部分的代码片段:
            size_t data_size = frameBuffer.size();  // frameBuffer is a std::vector where I accumulate the frame data chunks
    uint8_t* data = frameBuffer.data(); // convert the vector to a pointer
    picture->format = AV_PIX_FMT_RGB24;
    av_frame_get_buffer(picture, 1);
    while (data_size > 0) {
    int ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
    data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
    if (ret < 0) {
    fprintf(stderr, "Error while parsing\n");
    exit(1);
    }
    data += ret;
    data_size -= ret;

    if (pkt->size) {
    swsContext = sws_getContext(
    c->width, c->height,
    AV_PIX_FMT_YUV420P, c->width, c->height,
    AV_PIX_FMT_RGB24, SWS_BILINEAR, NULL, NULL, NULL
    );
    uint8_t* rgb24[1] = { data };
    int rgb24_stride[1] = { 3 * c->width };
    sws_scale(swsContext, rgb24, rgb24_stride, 0, c->height, picture->data, picture->linesize);

    decode(c, picture, pkt, outname);
    // TODO: copy content of picture->data[0] to "dataToRender" maybe?
    }
    }

    我已经尝试做另一个 sws_scale 将内容复制到 dataToRender我无法摆脱 bad dst image pointers错误。任何关于该问题的建议或解决方案都将不胜感激,因为我已经为此困扰了好几天。

    最佳答案

    我认为您应该使用 OpenGL 将 YUV 转换为 RGB。那是非常高效和简单的。片段着色器如下所示:

    precision mediump float;
    varying vec2 v_texPo;
    uniform sampler2D sampler_y;
    uniform sampler2D sampler_u;
    uniform sampler2D sampler_v;

    void main() {
    float y, u, v;
    vec3 rgb;
    y = texture2D(sampler_y, v_texPo).r;
    u = texture2D(sampler_u, v_texPo).r - 0.5;
    v = texture2D(sampler_v, v_texPo).r - 0.5;
    rgb.r = y + 1.403 * v;
    rgb.g = y - 0.344 * u - 0.714 * v;
    rgb.b = y + 1.770 * u;
    gl_FragColor = vec4(rgb, 1);
    }

    您应该将三个纹理上传到 OpenGL。

    关于c++ - 在 GLFW 窗口中显示 FFMPEG 解码帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62342960/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com