在 GLFW 窗口中显示 FFMPEG 解码帧
Display FFMPEG decoded frame in a GLFW window
我正在实现游戏的客户端程序,其中服务器将游戏的编码帧发送到客户端(通过UDP(,而客户端解码它们(通过FFMPEG(并在GLFW窗口中显示它们。 我的程序有两个线程:
- 线程 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 parsingn");
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。
相关文章:
- FFmpeg——使用硬件加速进行视频解码
- 在 GLFW 窗口中显示 FFMPEG 解码帧
- 如何使用 ffmpeg 将 3840 nb_samples编码为请求 1024 的编解码器
- FFMPEG:为什么当我调用av_codec_next()时,我所有的编解码器都没有显示出来
- FFmpeg:解码从UDP套接字接收的AVPackets
- 快速 TS 片段 ffmpeg 解码 - 内存泄漏
- FFMPEG 解码器似乎会丢帧
- OpenCV:FFMPEG:编解码器 ID 12 和格式 'mp4 / MP4 不支持标记
- 使用C++解码为ffmpeg中的特定像素格式
- 如何将解码缓冲区从ffmpeg映射到QVideoFrame
- FFmpeg解码和转换RGB sws_scale错误
- 如何使用FFMPEG使用DXVA2来解码并获取框架
- 为什么MP3解码的输出听起来如此延迟?(使用FFMPEG mp3lame lib)
- 将FFMPEG命令行转换为C 编解码器设置
- FFMPEG如何有效地解码视频框架
- 寻求使用 FFmpeg 在 mp4 容器中 h264 编解码器的视频帧.数据包 pts 始终为 0
- 使用FFmpeg解码视频帧时获取的撕裂图像
- 在Visual Studio 2010上使用FFMPEG解码
- FFMPEG解码-内存泄漏
- 用ffmpeg解码h264流引入延迟,如何避免