【发布时间】:2021-09-03 23:11:37
【问题描述】:
我需要在我的 QT 应用程序中将视频帧提取为图像。我事先不知道源视频/帧(yuv、rgb ...)的像素格式,但我需要获得可靠的图像像素格式,以便以后可以始终如一地处理图像。 我正在使用 ffmpeg 库来获取已经解码的帧。我试图避免使用已弃用的函数,并且我需要优化速度。
我尝试实现这个例子:https://stackoverflow.com/a/42615610/7360943 which
-
将原始帧转换为 rgb 帧
-
从第二帧的数据创建一个 QImage。
但是,这有两个主要问题:它使用了已弃用的 avpicture_alloc 函数,并且还不释放分配的内存,这导致我的应用程序快速崩溃,使用越来越多的 RAM,直到它在需要拍摄数千张图像时崩溃。我还没有找到独立解决这两个问题的方法,因为我不知道用什么来代替 avpicture_alloc,如果我使用 avpicture_free,它实际上会释放 QImage 底层的数据,这会破坏 QImage。
我尝试了以下方法,直接将 QImage 预分配的数据传递给 sws_scale,大部分时间都很好用:
// we will convert the original color format to rgb24
SwsContext* img_convert_ctx = sws_getContext(
pFrame->width,
pFrame->height,
(AVPixelFormat)pFrame->format,
pFrame->width,
pFrame->height,
AV_PIX_FMT_RGB24,
SWS_BICUBIC, NULL, NULL, NULL);
QImage image(pFrame->width,
pFrame->height,
QImage::Format_RGB888);
int rgb_linesizes[8] = {0};
rgb_linesizes[0] = 3*pFrame->width;
sws_scale(img_convert_ctx,
pFrame->data,
pFrame->linesize, 0,
pFrame->height,
(uint8_t *[]){image.bits()},
rgb_linesizes);
ffmpeg::sws_freeContext(img_convert_ctx);
问题在于对于某些特定视频,它会输出一些看起来有点黑白的奇怪图像(并且可能显示输入宽度和输出宽度之间的偏移量为 1... ?我无法完全解释可能导致这种情况的原因): 查看参考图片,它的外观:
以及有问题的灰色图像:
那么,我的代码中的问题是什么导致它在大多数情况下表现良好,但在某些特定情况下无法按预期工作?不然怎么办?
【问题讨论】:
-
对于您的内存问题 - 请参阅 QImage documentation - 您可以将 cleanuFunction 传递给 QImage ctor。
-
哦,谢谢,好主意,所以我会传递一个函数,一旦 QImage 被删除,就会释放数据......!