summaryrefslogtreecommitdiffstats
path: root/libhb
diff options
context:
space:
mode:
authoragalin89 <[email protected]>2020-07-24 02:12:22 +0100
committerScott <[email protected]>2020-07-28 20:26:06 +0100
commit9944f69c0dba9abeb47bf1842bc61c0ee19e5475 (patch)
tree419debe8fed21956d6bdbfa1fa172fd0ca743bcb /libhb
parent20778280638af215d9e341f78b1896917ea3a4ff (diff)
qsv: improved memory management
Diffstat (limited to 'libhb')
-rw-r--r--libhb/enc_qsv.c10
-rw-r--r--libhb/fifo.c7
-rw-r--r--libhb/handbrake/qsv_common.h5
-rw-r--r--libhb/qsv_common.c79
-rw-r--r--libhb/work.c7
5 files changed, 37 insertions, 71 deletions
diff --git a/libhb/enc_qsv.c b/libhb/enc_qsv.c
index 751591e4d..91055243a 100644
--- a/libhb/enc_qsv.c
+++ b/libhb/enc_qsv.c
@@ -756,9 +756,6 @@ int qsv_enc_init(hb_work_private_t *pv)
// if only for encode
if (pv->is_sys_mem)
{
- // no need to use additional sync as encode only -> single thread
- hb_qsv_add_context_usage(qsv, 0);
-
// re-use the session from encqsvInit
qsv->mfx_session = pv->mfx_session;
}
@@ -1766,9 +1763,6 @@ void encqsvClose(hb_work_object_t *w)
hb_qsv_uninit_enc(pv->job);
- /* QSV context cleanup and MFXClose */
- hb_qsv_context_clean(qsv_ctx,hb_qsv_full_path_is_enabled(pv->job));
-
hb_display_close(&pv->display);
if (qsv_enc_space != NULL)
@@ -2152,11 +2146,11 @@ static int qsv_enc_work(hb_work_private_t *pv,
{
if (hb_qsv_hw_filters_are_enabled(pv->job))
{
- hb_qsv_release_surface_from_pool(pv->job->qsv.ctx->hb_vpp_qsv_frames_ctx, surface->Data.MemId);
+ hb_qsv_release_surface_from_pool_by_surface_pointer(pv->job->qsv.ctx->hb_vpp_qsv_frames_ctx, surface);
}
else
{
- hb_qsv_release_surface_from_pool(pv->job->qsv.ctx->hb_dec_qsv_frames_ctx, surface->Data.MemId);
+ hb_qsv_release_surface_from_pool_by_surface_pointer(pv->job->qsv.ctx->hb_dec_qsv_frames_ctx, surface);
}
}
diff --git a/libhb/fifo.c b/libhb/fifo.c
index 14da3a9f2..1c4870691 100644
--- a/libhb/fifo.c
+++ b/libhb/fifo.c
@@ -725,18 +725,19 @@ void hb_buffer_close( hb_buffer_t ** _b )
#if HB_PROJECT_FEATURE_QSV
// Reclaim QSV resources before dropping the buffer.
// when decoding without QSV, the QSV atom will be NULL.
- if(b->qsv_details.frame)
+ if(b->qsv_details.frame && b->qsv_details.ctx != NULL)
{
mfxFrameSurface1 *surface = (mfxFrameSurface1*)b->qsv_details.frame->data[3];
- if(surface && b->qsv_details.ctx)
+ if(surface)
{
if(b->qsv_details.ctx->qsv_filters_are_enabled)
{
+ hb_qsv_release_surface_from_pool_by_surface_pointer(b->qsv_details.ctx->hb_vpp_qsv_frames_ctx, surface);
hb_qsv_release_surface_from_pool_by_surface_pointer(b->qsv_details.ctx->hb_dec_qsv_frames_ctx, surface);
}
else
{
- hb_qsv_release_surface_from_pool(b->qsv_details.ctx->hb_dec_qsv_frames_ctx, surface->Data.MemId);
+ hb_qsv_release_surface_from_pool_by_surface_pointer(b->qsv_details.ctx->hb_dec_qsv_frames_ctx, surface);
}
b->qsv_details.frame->data[3] = 0;
}
diff --git a/libhb/handbrake/qsv_common.h b/libhb/handbrake/qsv_common.h
index 83d74bf37..9c1fa62d1 100644
--- a/libhb/handbrake/qsv_common.h
+++ b/libhb/handbrake/qsv_common.h
@@ -223,7 +223,7 @@ const char* hb_qsv_impl_get_via_name(int impl);
/* Full QSV pipeline helpers */
int hb_qsv_is_enabled(hb_job_t *job);
hb_qsv_context* hb_qsv_context_init();
-void hb_qsv_context_uninit();
+void hb_qsv_context_uninit(hb_job_t *job);
int hb_qsv_sanitize_filter_list(hb_job_t *job);
int hb_qsv_hw_frames_init(int coded_width, int coded_height, enum AVPixelFormat sw_pix_fmt, int extra_hw_frames, AVBufferRef **out_hw_frames_ctx);
int hb_create_ffmpeg_pool(int coded_width, int coded_height, enum AVPixelFormat sw_pix_fmt, int pool_size, int extra_hw_frames, AVBufferRef **out_hw_frames_ctx);
@@ -235,9 +235,8 @@ AVBufferRef *hb_qsv_create_mids(AVBufferRef *hw_frames_ref);
hb_buffer_t* hb_qsv_copy_frame(hb_job_t *job, AVFrame *frame, int is_vpp);
int hb_qsv_get_free_surface_from_pool(HBQSVFramesContext* hb_enc_qsv_frames_ctx, AVFrame* frame, QSVMid** out_mid);
void hb_qsv_get_free_surface_from_pool_with_range(HBQSVFramesContext* hb_enc_qsv_frames_ctx, const int start_index, const int end_index, QSVMid** out_mid, mfxFrameSurface1** out_surface);
-void hb_qsv_get_mid_by_surface_from_pool(HBQSVFramesContext* hb_enc_qsv_frames_ctx, mfxFrameSurface1 *surface, QSVMid **out_mid);
+int hb_qsv_get_mid_by_surface_from_pool(HBQSVFramesContext* hb_enc_qsv_frames_ctx, mfxFrameSurface1 *surface, QSVMid **out_mid);
int hb_qsv_replace_surface_mid(HBQSVFramesContext* hb_qsv_frames_ctx, const QSVMid *mid, mfxFrameSurface1 *surface);
-int hb_qsv_release_surface_from_pool(HBQSVFramesContext* hb_qsv_frames_ctx, const QSVMid *mid);
int hb_qsv_release_surface_from_pool_by_surface_pointer(HBQSVFramesContext* hb_enc_qsv_frames_ctx, const mfxFrameSurface1 *surface);
int hb_qsv_get_buffer(AVCodecContext *s, AVFrame *frame, int flags);
enum AVPixelFormat hb_qsv_get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts);
diff --git a/libhb/qsv_common.c b/libhb/qsv_common.c
index 4548ce73c..8f10fdf4e 100644
--- a/libhb/qsv_common.c
+++ b/libhb/qsv_common.c
@@ -2564,70 +2564,47 @@ static int hb_qsv_find_surface_idx(const QSVMid *mids, const int nb_mids, const
int hb_qsv_replace_surface_mid(HBQSVFramesContext* hb_enc_qsv_frames_ctx, const QSVMid *mid, mfxFrameSurface1 *surface)
{
- int ret = hb_qsv_find_surface_idx(hb_enc_qsv_frames_ctx->mids, hb_enc_qsv_frames_ctx->nb_mids, mid);
- if (ret < 0)
- {
- hb_error("hb_qsv_replace_surface_mid: Surface with MemId=%p has not been found in the pool", mid);
+ if (!hb_enc_qsv_frames_ctx || !surface)
return -1;
- }
- else
- {
- surface->Data.MemId = &hb_enc_qsv_frames_ctx->mids[ret];
- }
- return 0;
-}
-int hb_qsv_release_surface_from_pool(HBQSVFramesContext* hb_enc_qsv_frames_ctx, const QSVMid *mid)
-{
int ret = hb_qsv_find_surface_idx(hb_enc_qsv_frames_ctx->mids, hb_enc_qsv_frames_ctx->nb_mids, mid);
if (ret < 0)
{
- hb_error("hb_qsv_release_surface_from_pool: Surface with MemId=%p has not been found in the pool", mid);
+ hb_error("hb_qsv_replace_surface_mid: Surface with MemId=%p has not been found in the pool", mid);
return -1;
}
- else if(hb_enc_qsv_frames_ctx->pool[ret] == 1)
- {
- ff_qsv_atomic_dec(&hb_enc_qsv_frames_ctx->pool[ret]);
- }
else
{
- hb_error("hb_qsv_release_surface_from_pool: Surface with index=%d and MemId=%p is used more than once", ret, mid);
- return -1;
+ surface->Data.MemId = &hb_enc_qsv_frames_ctx->mids[ret];
}
return 0;
}
int hb_qsv_release_surface_from_pool_by_surface_pointer(HBQSVFramesContext* hb_enc_qsv_frames_ctx, const mfxFrameSurface1 *surface)
{
- int count = 0;
+ if (!hb_enc_qsv_frames_ctx || !surface)
+ return -1;
AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hb_enc_qsv_frames_ctx->hw_frames_ctx->data;
AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
- while(1)
+ for(int i = 0; i < hb_enc_qsv_frames_ctx->nb_mids; i++)
{
- if(count > 30)
+ mfxFrameSurface1 *pool_surface = &frames_hwctx->surfaces[i];
+ if(surface == pool_surface)
{
- hb_error("hb_qsv_release_surface_from_pool_by_surface: surface=%p has not been found or busy", surface);
- hb_qsv_sleep(10); // prevent hang when all surfaces all used
- count = 0;
- }
-
- for(int i = 0; i < hb_enc_qsv_frames_ctx->nb_mids; i++)
- {
- mfxFrameSurface1 *pool_surface = &frames_hwctx->surfaces[i];
- if( (pool_surface->Data.Locked == 0) && (surface == pool_surface))
- {
- ff_qsv_atomic_dec(&hb_enc_qsv_frames_ctx->pool[i]);
- return 0;
- }
+ ff_qsv_atomic_dec(&hb_enc_qsv_frames_ctx->pool[i]);
+ return 0;
}
- count++;
}
+ return -1;
}
-void hb_qsv_get_mid_by_surface_from_pool(HBQSVFramesContext* hb_enc_qsv_frames_ctx, mfxFrameSurface1 *surface, QSVMid **out_mid)
+int hb_qsv_get_mid_by_surface_from_pool(HBQSVFramesContext* hb_enc_qsv_frames_ctx, mfxFrameSurface1 *surface, QSVMid **out_mid)
{
+ if (!hb_enc_qsv_frames_ctx || !surface)
+ return -1;
+
QSVMid *mid = NULL;
AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hb_enc_qsv_frames_ctx->hw_frames_ctx->data;
@@ -2650,7 +2627,7 @@ void hb_qsv_get_mid_by_surface_from_pool(HBQSVFramesContext* hb_enc_qsv_frames_c
if( (pool_surface->Data.Locked == 0) && (surface == pool_surface))
{
*out_mid = mid;
- return;
+ return 0;
}
}
count++;
@@ -2659,6 +2636,9 @@ void hb_qsv_get_mid_by_surface_from_pool(HBQSVFramesContext* hb_enc_qsv_frames_c
int hb_qsv_get_free_surface_from_pool(HBQSVFramesContext* hb_enc_qsv_frames_ctx, AVFrame* frame, QSVMid** out_mid)
{
+ if (!hb_enc_qsv_frames_ctx || !frame)
+ return -1;
+
AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hb_enc_qsv_frames_ctx->hw_frames_ctx->data;
AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
@@ -2846,12 +2826,6 @@ hb_buffer_t* hb_qsv_copy_frame(hb_job_t *job, AVFrame *frame, int is_vpp)
hb_error("hb_qsv_copy_frame: av_frame_copy_props error %d", ret);
}
- // copy content of input frame
- ret = av_frame_copy(out->qsv_details.frame, frame);
- if (ret < 0) {
- hb_error("hb_qsv_copy_frame: av_frame_copy error %d", ret);
- }
-
QSVMid *mid = NULL;
mfxFrameSurface1* output_surface = NULL;
HBQSVFramesContext* hb_qsv_frames_ctx = NULL;
@@ -3249,11 +3223,6 @@ int hb_qsv_replace_surface_mid(HBQSVFramesContext* hb_qsv_frames_ctx, const QSVM
return -1;
}
-int hb_qsv_release_surface_from_pool(HBQSVFramesContext* hb_qsv_frames_ctx, const QSVMid *mid)
-{
- return -1;
-}
-
enum AVPixelFormat hb_qsv_get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts)
{
return AV_PIX_FMT_NONE;
@@ -3287,7 +3256,7 @@ static int hb_d3d11va_device_check()
return -1;
}
-void hb_qsv_get_mid_by_surface_from_pool(HBQSVFramesContext* hb_enc_qsv_frames_ctx, mfxFrameSurface1 *surface, QSVMid **out_mid)
+int hb_qsv_get_mid_by_surface_from_pool(HBQSVFramesContext* hb_enc_qsv_frames_ctx, mfxFrameSurface1 *surface, QSVMid **out_mid)
{
}
@@ -3311,16 +3280,18 @@ hb_qsv_context* hb_qsv_context_init()
return ctx;
}
-void hb_qsv_context_uninit(hb_qsv_context ** _ctx)
+void hb_qsv_context_uninit(hb_job_t *job)
{
- hb_qsv_context *ctx = *_ctx;
+ hb_qsv_context *ctx = job->qsv.ctx;
if ( ctx == NULL )
{
hb_error( "hb_qsv_context_uninit: ctx is NULL" );
return;
}
+ /* QSV context cleanup and MFXClose */
+ hb_qsv_context_clean(ctx, hb_qsv_full_path_is_enabled(job));
av_free(ctx);
- *_ctx = NULL;
+ job->qsv.ctx = NULL;
}
#else
diff --git a/libhb/work.c b/libhb/work.c
index 0b404cda6..ffce4577e 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -1351,7 +1351,7 @@ static void do_job(hb_job_t *job)
}
#if HB_PROJECT_FEATURE_QSV
- if(hb_qsv_is_enabled(job))
+ if (hb_qsv_is_enabled(job))
job->qsv.ctx = hb_qsv_context_init();
#endif
@@ -1366,7 +1366,7 @@ static void do_job(hb_job_t *job)
#if HB_PROJECT_FEATURE_QSV && (defined( _WIN32 ) || defined( __MINGW32__ ))
// sanitize_qsv looks for subtitle render filter, so must happen after
// sanitize_subtitle
- if(hb_qsv_is_enabled(job))
+ if (hb_qsv_is_enabled(job))
{
result = hb_qsv_sanitize_filter_list(job);
if (result)
@@ -1823,7 +1823,8 @@ cleanup:
}
hb_buffer_pool_free();
#if HB_PROJECT_FEATURE_QSV
- hb_qsv_context_uninit(&job->qsv.ctx);
+ if (hb_qsv_is_enabled(job))
+ hb_qsv_context_uninit(job);
#endif
}