FFMPEG: Cleanup: Remove storage of last FFMPEG frame read as `ImBuf` in anim data.
The `anim` data (e.g. of a VSE sequence) would store the last frame read from FFMPEG as an image buffer, increasing its refcounting and preventing it to be freed until the whole `anim` data itself gets freed. In current code, there is no reason to keep a reference to this image buffer in the `anim` data, so removing it. This may also give a few percent improvement on the memory usage of the VSE in some cases. Found while investigating #114342. Pull Request: https://projects.blender.org/blender/blender/pulls/114395
This commit is contained in:
parent
0f5e7c7469
commit
d1e732a114
|
@ -122,7 +122,6 @@ struct anim {
|
|||
AVFrame *pFrame_backup;
|
||||
bool pFrame_backup_complete;
|
||||
|
||||
struct ImBuf *cur_frame_final;
|
||||
int64_t cur_pts;
|
||||
int64_t cur_key_frame_pts;
|
||||
AVPacket *cur_packet;
|
||||
|
|
|
@ -639,7 +639,6 @@ static int startffmpeg(anim *anim)
|
|||
anim->framesize = anim->x * anim->y * 4;
|
||||
|
||||
anim->cur_position = 0;
|
||||
anim->cur_frame_final = nullptr;
|
||||
anim->cur_pts = -1;
|
||||
anim->cur_key_frame_pts = -1;
|
||||
anim->cur_packet = av_packet_alloc();
|
||||
|
@ -808,11 +807,10 @@ static AVFrame *ffmpeg_double_buffer_frame_fallback_get(anim *anim)
|
|||
/**
|
||||
* Postprocess the image in anim->pFrame and do color conversion and de-interlacing stuff.
|
||||
*
|
||||
* Output is `anim->cur_frame_final`.
|
||||
* \param ibuf: The frame just read by `ffmpeg_fetchibuf`, processed in-place.
|
||||
*/
|
||||
static void ffmpeg_postprocess(anim *anim, AVFrame *input)
|
||||
static void ffmpeg_postprocess(anim *anim, AVFrame *input, ImBuf *ibuf)
|
||||
{
|
||||
ImBuf *ibuf = anim->cur_frame_final;
|
||||
int filter_y = 0;
|
||||
|
||||
/* This means the data wasn't read properly,
|
||||
|
@ -1391,8 +1389,6 @@ static ImBuf *ffmpeg_fetchibuf(anim *anim, int position, IMB_Timecode_Type tc)
|
|||
anim->x = anim->pCodecCtx->width;
|
||||
anim->y = anim->pCodecCtx->height;
|
||||
|
||||
IMB_freeImBuf(anim->cur_frame_final);
|
||||
|
||||
/* Certain versions of FFmpeg have a bug in libswscale which ends up in crash
|
||||
* when destination buffer is not properly aligned. For example, this happens
|
||||
* in FFmpeg 4.3.1. It got fixed later on, but for compatibility reasons is
|
||||
|
@ -1419,14 +1415,14 @@ static ImBuf *ffmpeg_fetchibuf(anim *anim, int position, IMB_Timecode_Type tc)
|
|||
planes = R_IMF_PLANES_RGB;
|
||||
}
|
||||
|
||||
anim->cur_frame_final = IMB_allocImBuf(anim->x, anim->y, planes, 0);
|
||||
ImBuf *cur_frame_final = IMB_allocImBuf(anim->x, anim->y, planes, 0);
|
||||
|
||||
/* Allocate the storage explicitly to ensure the memory is aligned. */
|
||||
uint8_t *buffer_data = static_cast<uint8_t *>(
|
||||
MEM_mallocN_aligned(size_t(4) * anim->x * anim->y, 32, "ffmpeg ibuf"));
|
||||
IMB_assign_byte_buffer(anim->cur_frame_final, buffer_data, IB_TAKE_OWNERSHIP);
|
||||
IMB_assign_byte_buffer(cur_frame_final, buffer_data, IB_TAKE_OWNERSHIP);
|
||||
|
||||
anim->cur_frame_final->byte_buffer.colorspace = colormanage_colorspace_get_named(
|
||||
cur_frame_final->byte_buffer.colorspace = colormanage_colorspace_get_named(
|
||||
anim->colorspace);
|
||||
|
||||
AVFrame *final_frame = ffmpeg_frame_by_pts_get(anim, pts_to_search);
|
||||
|
@ -1439,14 +1435,12 @@ static ImBuf *ffmpeg_fetchibuf(anim *anim, int position, IMB_Timecode_Type tc)
|
|||
/* Even with the fallback from above it is possible that the current decode frame is nullptr. In
|
||||
* this case skip post-processing and return current image buffer. */
|
||||
if (final_frame != nullptr) {
|
||||
ffmpeg_postprocess(anim, final_frame);
|
||||
ffmpeg_postprocess(anim, final_frame, cur_frame_final);
|
||||
}
|
||||
|
||||
anim->cur_position = position;
|
||||
|
||||
IMB_refImBuf(anim->cur_frame_final);
|
||||
|
||||
return anim->cur_frame_final;
|
||||
return cur_frame_final;
|
||||
}
|
||||
|
||||
static void free_anim_ffmpeg(anim *anim)
|
||||
|
@ -1466,7 +1460,6 @@ static void free_anim_ffmpeg(anim *anim)
|
|||
av_frame_free(&anim->pFrameDeinterlaced);
|
||||
|
||||
sws_freeContext(anim->img_convert_ctx);
|
||||
IMB_freeImBuf(anim->cur_frame_final);
|
||||
}
|
||||
anim->duration_in_frames = 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue