summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Galin <[email protected]>2020-07-17 16:55:20 +0100
committerScott <[email protected]>2020-07-20 16:56:43 +0100
commitd25f593a7fd9f639b0e5d89e710d48fd3f39e39f (patch)
tree4125f235bbb332117e4c5e15d08eb5dccfac1ca1
parent990654edba2cd1fd1c81b28fe60e126ee3ee8ef9 (diff)
qsv: reimplemented context memory management and small fixes
-rw-r--r--libhb/cropscale.c2
-rw-r--r--libhb/decavcodec.c19
-rw-r--r--libhb/enc_qsv.c15
-rw-r--r--libhb/handbrake/internal.h9
-rw-r--r--libhb/handbrake/qsv_common.h46
-rw-r--r--libhb/handbrake/qsv_libav.h45
-rw-r--r--libhb/hbavfilter.c16
-rw-r--r--libhb/qsv_common.c6
-rw-r--r--libhb/work.c59
9 files changed, 99 insertions, 118 deletions
diff --git a/libhb/cropscale.c b/libhb/cropscale.c
index 15ed199a4..c7522c2e0 100644
--- a/libhb/cropscale.c
+++ b/libhb/cropscale.c
@@ -97,7 +97,7 @@ static int crop_scale_init(hb_filter_object_t * filter, hb_filter_init_t * init)
hb_dict_set_int(avsettings, "w", width);
hb_dict_set_int(avsettings, "h", height);
hb_dict_set(avfilter, "scale_qsv", avsettings);
- int result = hb_create_ffmpeg_pool(width, height, AV_PIX_FMT_NV12, HB_POOL_SURFACE_SIZE, 0, &init->job->qsv.ctx->hb_vpp_qsv_frames_ctx->hw_frames_ctx);
+ int result = hb_create_ffmpeg_pool(width, height, AV_PIX_FMT_NV12, HB_QSV_POOL_SURFACE_SIZE, 0, &init->job->qsv.ctx->hb_vpp_qsv_frames_ctx->hw_frames_ctx);
if (result < 0)
{
hb_error("hb_create_ffmpeg_pool vpp allocation failed");
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c
index 0e120f763..0b6375d42 100644
--- a/libhb/decavcodec.c
+++ b/libhb/decavcodec.c
@@ -52,7 +52,6 @@
#include "libavutil/hwcontext_qsv.h"
#include "handbrake/qsv_common.h"
#include "handbrake/qsv_libav.h"
-extern HBQSVFramesContext hb_dec_qsv_frames_ctx;
#endif
static void compute_frame_duration( hb_work_private_t *pv );
@@ -1408,23 +1407,21 @@ static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job )
// more surfaces may be needed for the lookahead
pv->qsv.config.additional_buffers = 160;
}
- if(!pv->job->qsv.ctx)
+ if (!pv->job->qsv.ctx)
+ {
+ hb_error( "decavcodecvInit: no context" );
+ return 1;
+ }
+ if (!pv->job->qsv.ctx->hb_dec_qsv_frames_ctx)
{
- pv->job->qsv.ctx = av_mallocz(sizeof(hb_qsv_context));
- if(!pv->job->qsv.ctx)
- {
- hb_error( "decavcodecvInit: qsv ctx alloc failed" );
- return 1;
- }
pv->job->qsv.ctx->hb_dec_qsv_frames_ctx = av_mallocz(sizeof(HBQSVFramesContext));
if(!pv->job->qsv.ctx->hb_dec_qsv_frames_ctx)
{
- hb_error( "sanitize_qsv: HBQSVFramesContext dec alloc failed" );
+ hb_error( "decavcodecvInit: HBQSVFramesContext dec alloc failed" );
return 1;
}
}
- hb_qsv_add_context_usage(pv->job->qsv.ctx, 0);
-
+ hb_qsv_update_frames_context(pv->job);
if (!pv->job->qsv.ctx->dec_space)
{
pv->job->qsv.ctx->dec_space = av_mallocz(sizeof(hb_qsv_space));
diff --git a/libhb/enc_qsv.c b/libhb/enc_qsv.c
index 2b5346d54..751591e4d 100644
--- a/libhb/enc_qsv.c
+++ b/libhb/enc_qsv.c
@@ -746,12 +746,8 @@ int qsv_enc_init(hb_work_private_t *pv)
if (qsv == NULL)
{
- if (!pv->is_sys_mem)
- {
- hb_error("qsv_enc_init: decode enabled but no context!");
- return 3;
- }
- job->qsv.ctx = qsv = av_mallocz(sizeof(hb_qsv_context));
+ hb_error("qsv_enc_init: no context!");
+ return 3;
}
hb_qsv_space *qsv_encode = qsv->enc_space;
@@ -1815,11 +1811,6 @@ void encqsvClose(hb_work_object_t *w)
}
qsv_enc_space->is_init_done = 0;
}
-
- if (pv->is_sys_mem)
- {
- av_freep(&qsv_ctx);
- }
}
}
@@ -2261,7 +2252,7 @@ int encqsvWork(hb_work_object_t *w, hb_buffer_t **buf_in, hb_buffer_t **buf_out)
else
{
// Create black buffer in the begining of the encoding, usually first 2 frames
- hb_qsv_get_free_surface_from_pool_with_range(pv->job->qsv.ctx->hb_dec_qsv_frames_ctx, HB_POOL_SURFACE_SIZE - HB_POOL_ENCODER_SIZE, HB_POOL_SURFACE_SIZE, &mid, &surface);
+ hb_qsv_get_free_surface_from_pool_with_range(pv->job->qsv.ctx->hb_dec_qsv_frames_ctx, HB_QSV_POOL_SURFACE_SIZE - HB_QSV_POOL_ENCODER_SIZE, HB_QSV_POOL_SURFACE_SIZE, &mid, &surface);
}
if (hb_qsv_hw_filters_are_enabled(pv->job))
diff --git a/libhb/handbrake/internal.h b/libhb/handbrake/internal.h
index b0f1dd9fe..c8f3ecdd3 100644
--- a/libhb/handbrake/internal.h
+++ b/libhb/handbrake/internal.h
@@ -12,12 +12,7 @@
#include "libavutil/imgutils.h"
#include "libavutil/pixdesc.h"
-
#include "handbrake/project.h"
-#if HB_PROJECT_FEATURE_QSV
-#include "handbrake/qsv_libav.h"
-#include "libavcodec/avcodec.h"
-#endif
/***********************************************************************
* common.c
@@ -64,6 +59,10 @@ void hb_job_setup_passes(hb_handle_t *h, hb_job_t *job, hb_list_t *list_pass);
*/
typedef struct hb_buffer_s hb_buffer_t;
+#if HB_PROJECT_FEATURE_QSV
+#include "handbrake/qsv_libav.h"
+#endif
+
struct hb_buffer_settings_s
{
enum { OTHER_BUF, AUDIO_BUF, VIDEO_BUF, SUBTITLE_BUF, FRAME_BUF } type;
diff --git a/libhb/handbrake/qsv_common.h b/libhb/handbrake/qsv_common.h
index c70c0c53f..b92a59271 100644
--- a/libhb/handbrake/qsv_common.h
+++ b/libhb/handbrake/qsv_common.h
@@ -25,8 +25,8 @@ void hb_qsv_force_workarounds(); // for developers only
#include "mfx/mfxvideo.h"
#include "mfx/mfxplugin.h"
-#include "libavcodec/avcodec.h"
#include "handbrake/hb_dict.h"
+#include "handbrake/qsv_libav.h"
/* Minimum Intel Media SDK version (currently 1.3, for Sandy Bridge support) */
#define HB_QSV_MINVERSION_MAJOR HB_QSV_MSDK_VERSION_MAJOR
@@ -220,50 +220,6 @@ uint8_t hb_qsv_frametype_xlat(uint16_t qsv_frametype, uint16_t *out_flags);
const char* hb_qsv_impl_get_name(int impl);
const char* hb_qsv_impl_get_via_name(int impl);
-
-typedef struct QSVMid {
- AVBufferRef *hw_frames_ref;
- mfxHDL handle;
-
- void *texture;
-
- AVFrame *locked_frame;
- AVFrame *hw_frame;
- mfxFrameSurface1 surf;
-} QSVMid;
-
-typedef struct QSVFrame {
- AVFrame *frame;
- mfxFrameSurface1 surface;
- mfxEncodeCtrl enc_ctrl;
- mfxExtDecodedFrameInfo dec_info;
- mfxExtBuffer *ext_param;
-
- int queued;
- int used;
-
- struct QSVFrame *next;
-} QSVFrame;
-
-#define HB_POOL_FFMPEG_SURFACE_SIZE (64)
-#define HB_POOL_SURFACE_SIZE (64)
-#define HB_POOL_ENCODER_SIZE (8)
-
-typedef struct HBQSVFramesContext {
- AVBufferRef *hw_frames_ctx;
- //void *logctx;
-
- /* The memory ids for the external frames.
- * Refcounted, since we need one reference owned by the HBQSVFramesContext
- * (i.e. by the encoder/decoder) and another one given to the MFX session
- * from the frame allocator. */
- AVBufferRef *mids_buf;
- QSVMid *mids;
- int nb_mids;
- int pool[HB_POOL_SURFACE_SIZE];
- void *input_texture;
-} HBQSVFramesContext;
-
/* Full QSV pipeline helpers */
int hb_qsv_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);
diff --git a/libhb/handbrake/qsv_libav.h b/libhb/handbrake/qsv_libav.h
index f567944dd..2a41fe9ec 100644
--- a/libhb/handbrake/qsv_libav.h
+++ b/libhb/handbrake/qsv_libav.h
@@ -119,6 +119,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "mfx/mfxvideo.h"
#include "libavutil/mem.h"
#include "libavutil/time.h"
+#include "libavcodec/avcodec.h"
#if defined (__GNUC__)
#include <pthread.h>
@@ -187,6 +188,48 @@ typedef enum HB_QSV_STAGE_TYPE {
#define HB_QSV_ANY_MASK 0xFFF
} HB_QSV_STAGE_TYPE;
+typedef struct QSVMid {
+ AVBufferRef *hw_frames_ref;
+ mfxHDL handle;
+
+ void *texture;
+
+ AVFrame *locked_frame;
+ AVFrame *hw_frame;
+ mfxFrameSurface1 surf;
+} QSVMid;
+
+typedef struct QSVFrame {
+ AVFrame *frame;
+ mfxFrameSurface1 surface;
+ mfxEncodeCtrl enc_ctrl;
+ mfxExtDecodedFrameInfo dec_info;
+ mfxExtBuffer *ext_param;
+
+ int queued;
+ int used;
+
+ struct QSVFrame *next;
+} QSVFrame;
+
+#define HB_QSV_POOL_FFMPEG_SURFACE_SIZE (64)
+#define HB_QSV_POOL_SURFACE_SIZE (64)
+#define HB_QSV_POOL_ENCODER_SIZE (8)
+
+typedef struct HBQSVFramesContext {
+ AVBufferRef *hw_frames_ctx;
+ //void *logctx;
+
+ /* The memory ids for the external frames.
+ * Refcounted, since we need one reference owned by the HBQSVFramesContext
+ * (i.e. by the encoder/decoder) and another one given to the MFX session
+ * from the frame allocator. */
+ AVBufferRef *mids_buf;
+ QSVMid *mids;
+ int nb_mids;
+ int pool[HB_QSV_POOL_SURFACE_SIZE];
+ void *input_texture;
+} HBQSVFramesContext;
typedef struct hb_qsv_list {
// practically pthread_mutex_t
@@ -260,8 +303,6 @@ typedef struct hb_qsv_space {
mfxMemId *mids;
} hb_qsv_space;
-typedef struct HBQSVFramesContext HBQSVFramesContext;
-
typedef struct hb_qsv_context {
volatile int is_context_active;
diff --git a/libhb/hbavfilter.c b/libhb/hbavfilter.c
index 80ec654e0..cbb668169 100644
--- a/libhb/hbavfilter.c
+++ b/libhb/hbavfilter.c
@@ -70,12 +70,13 @@ static AVFilterContext * append_filter( hb_avfilter_graph_t * graph,
hb_avfilter_graph_t *
hb_avfilter_graph_init(hb_value_t * settings, hb_filter_init_t * init)
{
- hb_avfilter_graph_t * graph;
- AVFilterInOut * in = NULL, * out = NULL;
- AVFilterContext * avfilter;
- char * settings_str;
- int result;
- char * filter_args;
+ hb_avfilter_graph_t * graph;
+ AVFilterInOut * in = NULL, * out = NULL;
+ AVBufferSrcParameters * par = NULL;
+ AVFilterContext * avfilter;
+ char * settings_str;
+ int result;
+ char * filter_args;
graph = calloc(1, sizeof(hb_avfilter_graph_t));
if (graph == NULL)
@@ -112,7 +113,6 @@ hb_avfilter_graph_init(hb_value_t * settings, hb_filter_init_t * init)
goto fail;
}
- AVBufferSrcParameters *par = 0;
// Build filter input
#if HB_PROJECT_FEATURE_QSV
if (hb_qsv_hw_filters_are_enabled(graph->job))
@@ -148,6 +148,7 @@ hb_avfilter_graph_init(hb_value_t * settings, hb_filter_init_t * init)
init->vrate.num, init->vrate.den);
}
avfilter = append_filter(graph, "buffer", filter_args, par);
+ av_free(par);
free(filter_args);
if (avfilter == NULL)
{
@@ -206,6 +207,7 @@ hb_avfilter_graph_init(hb_value_t * settings, hb_filter_init_t * init)
return graph;
fail:
+ av_free(par);
avfilter_inout_free(&in);
avfilter_inout_free(&out);
hb_avfilter_graph_close(&graph);
diff --git a/libhb/qsv_common.c b/libhb/qsv_common.c
index 215a2e2cd..e3bc2f2c3 100644
--- a/libhb/qsv_common.c
+++ b/libhb/qsv_common.c
@@ -2865,7 +2865,7 @@ hb_buffer_t* hb_qsv_copy_frame(hb_job_t *job, AVFrame *frame, int is_vpp)
}
else
{
- hb_qsv_get_free_surface_from_pool_with_range(hb_qsv_frames_ctx, 0, HB_POOL_SURFACE_SIZE - HB_POOL_ENCODER_SIZE, &mid, &output_surface);
+ hb_qsv_get_free_surface_from_pool_with_range(hb_qsv_frames_ctx, 0, HB_QSV_POOL_SURFACE_SIZE - HB_QSV_POOL_ENCODER_SIZE, &mid, &output_surface);
}
if (device_manager_handle_type == MFX_HANDLE_D3D9_DEVICE_MANAGER)
@@ -3055,7 +3055,7 @@ int hb_qsv_init(int coded_width, int coded_height, enum AVPixelFormat sw_pix_fmt
int ret;
- ret = hb_create_ffmpeg_pool(coded_width, coded_height, sw_pix_fmt, HB_POOL_FFMPEG_SURFACE_SIZE, extra_hw_frames, out_hw_frames_ctx);
+ ret = hb_create_ffmpeg_pool(coded_width, coded_height, sw_pix_fmt, HB_QSV_POOL_FFMPEG_SURFACE_SIZE, extra_hw_frames, out_hw_frames_ctx);
if (ret < 0) {
hb_error("hb_qsv_init: hb_create_ffmpeg_pool decoder failed %d", ret);
return ret;
@@ -3066,7 +3066,7 @@ int hb_qsv_init(int coded_width, int coded_height, enum AVPixelFormat sw_pix_fmt
frames_hwctx = frames_ctx->hwctx;
hb_dec_qsv_frames_ctx->input_texture = frames_hwctx->texture;
- ret = hb_create_ffmpeg_pool(coded_width, coded_height, sw_pix_fmt, HB_POOL_SURFACE_SIZE, extra_hw_frames, &hb_dec_qsv_frames_ctx->hw_frames_ctx);
+ ret = hb_create_ffmpeg_pool(coded_width, coded_height, sw_pix_fmt, HB_QSV_POOL_SURFACE_SIZE, extra_hw_frames, &hb_dec_qsv_frames_ctx->hw_frames_ctx);
if (ret < 0) {
hb_error("hb_qsv_init: hb_create_ffmpeg_pool qsv surface allocation failed %d", ret);
return ret;
diff --git a/libhb/work.c b/libhb/work.c
index 2efccf47b..944c920a6 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -1233,28 +1233,10 @@ static int sanitize_qsv( hb_job_t * job )
* When QSV's VPP is used for filtering, not all CPU filters
* are supported, so we need to do a little extra setup here.
*/
-
- if(!job->qsv.ctx)
- {
- job->qsv.ctx = av_mallocz(sizeof(hb_qsv_context));
- if(!job->qsv.ctx)
- {
- hb_error( "sanitize_qsv: qsv ctx alloc failed" );
- return 1;
- }
- job->qsv.ctx->hb_dec_qsv_frames_ctx = av_mallocz(sizeof(HBQSVFramesContext));
- if(!job->qsv.ctx->hb_dec_qsv_frames_ctx)
- {
- hb_error( "sanitize_qsv: HBQSVFramesContext dec alloc failed" );
- return 1;
- }
- hb_qsv_add_context_usage(job->qsv.ctx, 0);
- }
-
- int i = 0;
- int num_cpu_filters = 0;
if (job->vcodec & HB_VCODEC_QSV_MASK)
{
+ int i = 0;
+ int num_cpu_filters = 0;
if (job->list_filter != NULL && hb_list_count(job->list_filter) > 0)
{
for (i = 0; i < hb_list_count(job->list_filter); i++)
@@ -1279,19 +1261,19 @@ static int sanitize_qsv( hb_job_t * job )
}
}
}
- }
- job->qsv.ctx->num_cpu_filters = num_cpu_filters;
- job->qsv.ctx->qsv_filters_are_enabled = ((hb_list_count(job->list_filter) == 1) && hb_qsv_full_path_is_enabled(job)) ? 1 : 0;
- if (job->qsv.ctx->qsv_filters_are_enabled)
- {
- job->qsv.ctx->hb_vpp_qsv_frames_ctx = av_mallocz(sizeof(HBQSVFramesContext));
- if(!job->qsv.ctx->hb_vpp_qsv_frames_ctx)
+ job->qsv.ctx->num_cpu_filters = num_cpu_filters;
+ job->qsv.ctx->qsv_filters_are_enabled = ((hb_list_count(job->list_filter) == 1) && hb_qsv_full_path_is_enabled(job)) ? 1 : 0;
+ if (job->qsv.ctx->qsv_filters_are_enabled)
{
- hb_error( "sanitize_qsv: HBQSVFramesContext vpp alloc failed" );
- return 1;
+ job->qsv.ctx->hb_vpp_qsv_frames_ctx = av_mallocz(sizeof(HBQSVFramesContext));
+ if (!job->qsv.ctx->hb_vpp_qsv_frames_ctx)
+ {
+ hb_error( "sanitize_qsv: HBQSVFramesContext vpp alloc failed" );
+ return 1;
+ }
+ hb_qsv_update_frames_context(job);
}
}
- hb_qsv_update_frames_context(job);
#endif // HB_PROJECT_FEATURE_QSV
return 0;
@@ -1421,7 +1403,18 @@ static void do_job(hb_job_t *job)
goto cleanup;
}
-
+#if HB_PROJECT_FEATURE_QSV
+ if (!job->qsv.ctx)
+ {
+ job->qsv.ctx = av_mallocz(sizeof(hb_qsv_context));
+ if (!job->qsv.ctx)
+ {
+ hb_error( "qsv ctx alloc failed" );
+ return;
+ }
+ hb_qsv_add_context_usage(job->qsv.ctx, 0);
+ }
+#endif
// Filters have an effect on settings.
// So initialize the filters and update the job.
if (job->list_filter && hb_list_count(job->list_filter))
@@ -1884,8 +1877,10 @@ cleanup:
{
analyze_subtitle_scan(job);
}
-
hb_buffer_pool_free();
+#if HB_PROJECT_FEATURE_QSV
+ av_free(job->qsv.ctx);
+#endif
}
static inline void copy_chapter( hb_buffer_t * dst, hb_buffer_t * src )