Unsolved New QImage is invalid (am I out of memory)?
-
I have a loop in my program where I'm loading several images into memory. They're all 1920x1080 RGBA images. Things go well until the 23rd image where I allocate a new QImage and try to write to it by doing a memcpy to
image.scanline(0)
, which causes a crash. The debugger variable watch displays my image as(invalid)
. I'm wondering if maybe I'm running out of memory, and if so how I could monitor this? Also, I'd like to cache around 50 of these images. Is there a way to do that? -
1920 * 1080 * 4 * 50 ~ 400MB
. That doesn't seem like enough for you to run out. You'd have to be seriously low on memory and disk space for that to be the case. Could you show us some code? -
I'm deserializing from a stream. My method first looks to see if I've cached the frame I'm looking for. Then if it doesn't find it, it jumps to the keyframe image prior to it and scans in all the images to the next keyframe, placing them in the cache:
QImage FfmpegMediaSource::getVideoFrame(int timeMs) { int frameFinished; AVPacket packet; //Seek to our goal time avcodec_flush_buffers(pCodecCtx); int64_t targetPts = timeMs * 1000; targetPts = av_rescale_q(targetPts, AV_TIME_BASE_Q, pFormatCtx->streams[videoStream]->time_base); VideoFrame* vf = lookupVideoFrame(targetPts); if (!vf->image.isNull()) return vf->image; int64_t keyframePts = vf->keyPts; int err = av_seek_frame(pFormatCtx, videoStream, keyframePts, AVSEEK_FLAG_BACKWARD); //Clear loaded image buffer for (VideoFrame* loaded: _loadedImageList) { loaded->image = QImage(); } _loadedImageList.clear(); //Read frame int seq = 0; while (av_read_frame(pFormatCtx, &packet) == 0) { if (packet.stream_index != videoStream) continue; int64_t pts = packet.pts == AV_NOPTS_VALUE ? packet.dts : packet.pts; if ((packet.flags & AV_PKT_FLAG_KEY) != 0 && pts != keyframePts) { //If we hit next keyframe, break break; } int err = avcodec_send_packet(pCodecCtx, &packet); if (err != 0) { qDebug() << "Error sendsing packet: " << err; } QImage img = readVideoFrame(packet); _videoPtsMap[pts]->image = img; _loadedImageList.append(_videoPtsMap[pts]); AVRational time_base = pFormatCtx->streams[videoStream]->time_base; int presentationTime = pts * av_q2d(time_base) * 1000; } return vf->image; } QImage FfmpegMediaSource::readVideoFrame(AVPacket& packet) { int err = 0; while (err >= 0) { err = avcodec_receive_frame(pCodecCtx, pFrame); if (err == AVERROR(EAGAIN) || err == AVERROR_EOF) { qDebug() << "Error decoding packet: " << err; break; } if (err < 0) { qDebug() << "Error decoding packet: " << err; break; } // Convert the image from its native format to RGB sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize); QImage videoFrame = QImage(pCodecCtx->width, pCodecCtx->height, QImage::Format_RGB32); for (int j = 0; j < pCodecCtx->height; ++j) { memcpy(videoFrame.scanLine(j), pFrameRGB->data[0] + j * pFrameRGB->linesize[0], pCodecCtx->width * 4); } return videoFrame; } return QImage(); }
-
@kitfox said in New QImage is invalid (am I out of memory)?:
for (VideoFrame* loaded: _loadedImageList)
{
loaded->image = QImage();
}Why do you need this? image is not a pointer.
Did you observe memory consumption of your app?
-
@jsulm This was my attempt to clear memory by replacing the previously allocated image with a null one. Not sure if this is actually achieving what I want it to.
I don't know how to observe memory consumption in my app. I'm doing this on windows with Qt Creator, and I'm not sure how to set up memory profiling.
-
@kitfox You can simply open the Windows Task Manager and see what happens when your app is running.