[WIP] VSE: Only free ffmpeg codec context #118112

Draft
Richard Antalik wants to merge 1 commits from iss/blender:ffmpeg-free-1 into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
3 changed files with 57 additions and 7 deletions

View File

@ -350,6 +350,8 @@ ImBuf *IMB_anim_previewframe(ImBufAnim *anim);
void IMB_free_anim(ImBufAnim *anim);
void IMB_anim_flush_buffers(ImBufAnim *anim);
#define FILTER_MASK_NULL 0
#define FILTER_MASK_MARGIN 1
#define FILTER_MASK_USED 2

View File

@ -442,6 +442,39 @@ static ImBuf *avi_fetchibuf(ImBufAnim *anim, int position)
#ifdef WITH_FFMPEG
static void codec_context_ensure(ImBufAnim *anim)
{
if (anim->pCodecCtx != nullptr) {
return;
}
AVStream *video_stream = anim->pFormatCtx->streams[anim->streamindex];
AVCodecContext *pCodecCtx = avcodec_alloc_context3(nullptr);
avcodec_parameters_to_context(pCodecCtx, video_stream->codecpar);
pCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
if (anim->pCodec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
pCodecCtx->thread_count = 0;
}
else {
pCodecCtx->thread_count = BLI_system_thread_count();
}
if (anim->pCodec->capabilities & AV_CODEC_CAP_FRAME_THREADS) {
pCodecCtx->thread_type = FF_THREAD_FRAME;
}
else if (anim->pCodec->capabilities & AV_CODEC_CAP_SLICE_THREADS) {
pCodecCtx->thread_type = FF_THREAD_SLICE;
}
anim->pCodecCtx = pCodecCtx;
if (avcodec_open2(pCodecCtx, anim->pCodec, nullptr) < 0) {
return;
}
}
static int startffmpeg(ImBufAnim *anim)
{
int i, video_stream_index;
@ -1374,6 +1407,8 @@ static ImBuf *ffmpeg_fetchibuf(ImBufAnim *anim, int position, IMB_Timecode_Type
return nullptr;
}
codec_context_ensure(anim);
av_log(anim->pFormatCtx, AV_LOG_DEBUG, "FETCH: seek_pos=%d\n", position);
ImBufAnimIndex *tc_index = IMB_anim_open_index(anim, tc);
@ -1455,6 +1490,17 @@ static ImBuf *ffmpeg_fetchibuf(ImBufAnim *anim, int position, IMB_Timecode_Type
return cur_frame_final;
}
void IMB_anim_flush_buffers(ImBufAnim *anim)
{
if (anim->pCodecCtx == nullptr) {
return;
}
// avcodec_flush_buffers(anim->pCodecCtx);
avcodec_free_context(&anim->pCodecCtx);
anim->pCodecCtx = nullptr;
}
static void free_anim_ffmpeg(ImBufAnim *anim)
{
if (anim == nullptr) {
@ -1577,11 +1623,14 @@ ImBuf *IMB_anim_previewframe(ImBufAnim *anim)
return ibuf;
}
#include "BLI_timeit.hh"
ImBuf *IMB_anim_absolute(ImBufAnim *anim,
int position,
IMB_Timecode_Type tc,
IMB_Proxy_Size preview_size)
{
SCOPED_TIMER(__func__);
ImBuf *ibuf = nullptr;
int filter_y;
if (anim == nullptr) {

View File

@ -308,6 +308,7 @@ static void sequencer_all_free_anim_ibufs(const Scene *scene,
void SEQ_relations_free_all_anim_ibufs(Scene *scene, int timeline_frame)
{
Editing *ed = SEQ_editing_get(scene);
if (ed == nullptr) {
return;
@ -395,17 +396,15 @@ bool SEQ_relations_render_loop_check(Sequence *seq_main, Sequence *seq)
void SEQ_relations_sequence_free_anim(Sequence *seq)
{
while (seq->anims.last) {
StripAnim *sanim = static_cast<StripAnim *>(seq->anims.last);
LISTBASE_FOREACH (StripAnim *, sanim, &seq->anims) {
if (sanim->anim) {
IMB_free_anim(sanim->anim);
sanim->anim = nullptr;
IMB_anim_flush_buffers(sanim->anim);
// sanim->anim = nullptr;
}
BLI_freelinkN(&seq->anims, sanim);
// BLI_freelinkN(&seq->anims, sanim);
}
BLI_listbase_clear(&seq->anims);
// BLI_listbase_clear(&seq->anims);
}
void SEQ_relations_session_uid_generate(Sequence *sequence)