diff options
author | Artem Galin <[email protected]> | 2020-07-17 16:55:20 +0100 |
---|---|---|
committer | Scott <[email protected]> | 2020-07-20 16:56:43 +0100 |
commit | d25f593a7fd9f639b0e5d89e710d48fd3f39e39f (patch) | |
tree | 4125f235bbb332117e4c5e15d08eb5dccfac1ca1 | |
parent | 990654edba2cd1fd1c81b28fe60e126ee3ee8ef9 (diff) |
qsv: reimplemented context memory management and small fixes
-rw-r--r-- | libhb/cropscale.c | 2 | ||||
-rw-r--r-- | libhb/decavcodec.c | 19 | ||||
-rw-r--r-- | libhb/enc_qsv.c | 15 | ||||
-rw-r--r-- | libhb/handbrake/internal.h | 9 | ||||
-rw-r--r-- | libhb/handbrake/qsv_common.h | 46 | ||||
-rw-r--r-- | libhb/handbrake/qsv_libav.h | 45 | ||||
-rw-r--r-- | libhb/hbavfilter.c | 16 | ||||
-rw-r--r-- | libhb/qsv_common.c | 6 | ||||
-rw-r--r-- | libhb/work.c | 59 |
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 ) |