对于我的项目,我需要将glReadPixels
生成的RGB(GL_RGB
)图像转换为AVFrame
。我在谷歌上搜索了一下,发现了一些相反的例子。但在本例中,我需要从GL_RGB
转换为AVFrame
。
下面是我的代码:
以下是我设置编解码器的方法:
/* Allocate resources and write header data to the output file. */
void ffmpeg_encoder_start(AVCodecID codec_id, int fps, int width, int height) {
const AVCodec *codec;
int ret;
codec = avcodec_find_encoder(codec_id);
if (!codec ) {
std::cerr << "Codec not found" << std::endl;
exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c) {
std::cerr << "Could not allocate video codec context" << std::endl;
exit(1);
}
c->bit_rate = 400000;
c->width = width;
c->height = height;
c->time_base.num = 1;
c->time_base.den = fps;
c->keyint_min = 600;
c->pix_fmt = AV_PIX_FMT_YUV420P;
if (avcodec_open2(c, codec, NULL) < 0) {
std::cerr << "Could not open codec" << std::endl;
exit(1);
}
frame = av_frame_alloc();
if (!frame) {
std::cerr << "Could not allocate video frame" << std::endl;
exit(1);
}
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;
ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height, c->pix_fmt, 32);
if (ret < 0) {
std::cerr << "Could not allocate raw picture buffer" << std::endl;
exit(1);
}
}
获取像素并设置新帧:
BYTE* pixels = new BYTE[3 * DEFAULT_MONITOR.maxResolution.width * DEFAULT_MONITOR.maxResolution.height];
glReadPixels(0, 0, DEFAULT_MONITOR.maxResolution.width, DEFAULT_MONITOR.maxResolution.height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
screenSrc->setNextFrame(pixels, DEFAULT_MONITOR.maxResolution.width, DEFAULT_MONITOR.maxResolution.height);
我的转换函数是:
static void ffmpeg_encoder_set_frame_yuv_from_rgb(uint8_t *rgb) {
const int in_linesize[1] = { 3 * c->width };
sws_context = sws_getCachedContext(sws_context,
c->width, c->height, AV_PIX_FMT_RGB24,
c->width, c->height, AV_PIX_FMT_YUV420P,
0, 0, 0, 0);
sws_scale(sws_context, (const uint8_t * const *)&rgb, in_linesize, 0,
c->height, frame->data, frame->linesize);
}
所有的代码都可以在here中找到这里是导致分段错误的代码行。
不幸的是,函数给了我一个分段错误,你有办法解决这个问题吗?
2条答案
按热度按时间csbfibhn1#
sws_scale
的第二个参数是一个指针数组:const uint8_t *const srcSlice[]
个代替指针转换:
(const uint8_t * const *)&rgb
,将rgb
指针放入指针数组中:将RGB转换为YUV420P的示例:
xmjla07d2#
在发布的代码片段中似乎没有明显的错误,可以这样验证:
并这样检查:
因此,很难说问题源自何处。可能出现的问题是:
DEFAULT_MONITOR.maxResolution.width
和DEFAULT_MONITOR.maxResolution.height
值是否有效?是否需要使用堆?AVFrame
、AVCodecContext
、sws_context
指针变量在使用前是否已初始化?sws_scale()
中使用的库的确切故障点在哪里?(我猜可以通过使用调试版本和调试器来检查,通过深入研究该函数来查看程序在哪里崩溃...)这个问题似乎与OpenGL没有直接关系。FFmpeg的libswscale library文档可以在here中找到。
为了找到一个更好的答案,如果这个问题可以被其他具有类似minimal reproducible example的人复制,这将是有帮助的。