diff options
-rw-r--r-- | libhb/avfilter.c | 12 | ||||
-rw-r--r-- | libhb/cropscale.c | 26 | ||||
-rw-r--r-- | libhb/decavcodec.c | 18 | ||||
-rw-r--r-- | libhb/enc_qsv.c | 33 | ||||
-rw-r--r-- | libhb/fifo.c | 12 | ||||
-rw-r--r-- | libhb/handbrake/qsv_common.h | 5 | ||||
-rw-r--r-- | libhb/handbrake/qsv_libav.h | 6 | ||||
-rw-r--r-- | libhb/hbavfilter.c | 15 | ||||
-rw-r--r-- | libhb/qsv_common.c | 111 | ||||
-rw-r--r-- | libhb/work.c | 39 |
10 files changed, 151 insertions, 126 deletions
diff --git a/libhb/avfilter.c b/libhb/avfilter.c index 5b8b30d28..dd2fb7b02 100644 --- a/libhb/avfilter.c +++ b/libhb/avfilter.c @@ -13,8 +13,6 @@ #if HB_PROJECT_FEATURE_QSV #include "handbrake/qsv_common.h" -extern int qsv_filters_are_enabled; -extern HBQSVFramesContext hb_dec_qsv_frames_ctx; #endif static int avfilter_init(hb_filter_object_t * filter, hb_filter_init_t * init); @@ -242,13 +240,15 @@ static hb_buffer_t* filterFrame( hb_filter_private_t * pv, hb_buffer_t * in ) #if HB_PROJECT_FEATURE_QSV mfxFrameSurface1 *surface = NULL; // We need to keep surface pointer because hb_avfilter_add_buf set it to 0 after in ffmpeg call - if (qsv_filters_are_enabled && in && in->qsv_details.frame) + int use_qsv_filters = (pv->input.job && pv->input.job->qsv.ctx && + pv->input.job->qsv.ctx->qsv_filters_are_enabled && in && in->qsv_details.frame) ? 1 : 0; + if (use_qsv_filters) { surface = (mfxFrameSurface1 *)in->qsv_details.frame->data[3]; } else { - av_frame_is_not_null= 0; + av_frame_is_not_null = 0; } #endif if (av_frame_is_not_null) @@ -262,9 +262,9 @@ static hb_buffer_t* filterFrame( hb_filter_private_t * pv, hb_buffer_t * in ) buf = hb_avfilter_get_buf(pv->graph); } #if HB_PROJECT_FEATURE_QSV - if (qsv_filters_are_enabled && surface) + if (use_qsv_filters && surface) { - hb_qsv_release_surface_from_pool_by_surface_pointer(&hb_dec_qsv_frames_ctx, surface); + hb_qsv_release_surface_from_pool_by_surface_pointer(pv->input.job->qsv.ctx->hb_dec_qsv_frames_ctx, surface); } #endif // Delay one frame so we can set the stop time of the output buffer diff --git a/libhb/cropscale.c b/libhb/cropscale.c index 80a35447d..c2beab9b4 100644 --- a/libhb/cropscale.c +++ b/libhb/cropscale.c @@ -13,9 +13,6 @@ #include "handbrake/qsv_common.h" #include "libavutil/hwcontext_qsv.h" #include "libavutil/hwcontext.h" -extern int qsv_filters_are_enabled; -extern int num_cpu_filters; -HBQSVFramesContext hb_vpp_qsv_frames_ctx; #endif static int crop_scale_init(hb_filter_object_t * filter, @@ -95,12 +92,13 @@ static int crop_scale_init(hb_filter_object_t * filter, hb_filter_init_t * init) hb_dict_t * avsettings = hb_dict_init(); #if HB_PROJECT_FEATURE_QSV - if (qsv_filters_are_enabled) + int use_qsv_filters = (init->job && init->job->qsv.ctx && init->job->qsv.ctx->qsv_filters_are_enabled) ? 1 : 0; + if (use_qsv_filters) { 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, &hb_vpp_qsv_frames_ctx.hw_frames_ctx); + 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); if (result < 0) { hb_error("hb_create_ffmpeg_pool vpp allocation failed"); @@ -111,19 +109,19 @@ static int crop_scale_init(hb_filter_object_t * filter, hb_filter_init_t * init) AVQSVFramesContext *frames_hwctx; AVBufferRef *hw_frames_ctx; - hw_frames_ctx = hb_vpp_qsv_frames_ctx.hw_frames_ctx; + hw_frames_ctx = init->job->qsv.ctx->hb_vpp_qsv_frames_ctx->hw_frames_ctx; frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data; frames_hwctx = frames_ctx->hwctx; - hb_vpp_qsv_frames_ctx.input_texture = frames_hwctx->texture; + init->job->qsv.ctx->hb_vpp_qsv_frames_ctx->input_texture = frames_hwctx->texture; /* allocate the memory ids for the external frames */ - av_buffer_unref(&hb_vpp_qsv_frames_ctx.mids_buf); - hb_vpp_qsv_frames_ctx.mids_buf = hb_qsv_create_mids(hb_vpp_qsv_frames_ctx.hw_frames_ctx); - if (!hb_vpp_qsv_frames_ctx.mids_buf) + av_buffer_unref(&init->job->qsv.ctx->hb_vpp_qsv_frames_ctx->mids_buf); + init->job->qsv.ctx->hb_vpp_qsv_frames_ctx->mids_buf = hb_qsv_create_mids(init->job->qsv.ctx->hb_vpp_qsv_frames_ctx->hw_frames_ctx); + if (!init->job->qsv.ctx->hb_vpp_qsv_frames_ctx->mids_buf) return AVERROR(ENOMEM); - hb_vpp_qsv_frames_ctx.mids = (QSVMid*)hb_vpp_qsv_frames_ctx.mids_buf->data; - hb_vpp_qsv_frames_ctx.nb_mids = frames_hwctx->nb_surfaces; - memset(hb_vpp_qsv_frames_ctx.pool, 0, hb_vpp_qsv_frames_ctx.nb_mids * sizeof(hb_vpp_qsv_frames_ctx.pool[0])); + init->job->qsv.ctx->hb_vpp_qsv_frames_ctx->mids = (QSVMid*)init->job->qsv.ctx->hb_vpp_qsv_frames_ctx->mids_buf->data; + init->job->qsv.ctx->hb_vpp_qsv_frames_ctx->nb_mids = frames_hwctx->nb_surfaces; + memset(init->job->qsv.ctx->hb_vpp_qsv_frames_ctx->pool, 0, init->job->qsv.ctx->hb_vpp_qsv_frames_ctx->nb_mids * sizeof(init->job->qsv.ctx->hb_vpp_qsv_frames_ctx->pool[0])); } else #endif @@ -171,7 +169,7 @@ static int crop_scale_init(hb_filter_object_t * filter, hb_filter_init_t * init) avsettings = hb_dict_init(); #if HB_PROJECT_FEATURE_QSV - if (!qsv_filters_are_enabled) + if (!use_qsv_filters) #endif { // TODO: Support other pix formats diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c index 3dbb4a918..60c213584 100644 --- a/libhb/decavcodec.c +++ b/libhb/decavcodec.c @@ -955,7 +955,7 @@ static hb_buffer_t *copy_frame( hb_work_private_t *pv ) if (pv->qsv.decode && pv->qsv.config.io_pattern == MFX_IOPATTERN_OUT_VIDEO_MEMORY) { - out = hb_qsv_copy_frame(&hb_dec_qsv_frames_ctx, pv->frame, pv->job->qsv.ctx, 0); + out = hb_qsv_copy_frame(pv->job, pv->frame, 0); } else #endif @@ -1176,8 +1176,7 @@ int reinit_video_filters(hb_work_private_t * pv) { settings = hb_dict_init(); #if HB_PROJECT_FEATURE_QSV - if (pv->qsv.decode && - pv->qsv.config.io_pattern == MFX_IOPATTERN_OUT_VIDEO_MEMORY) + if (pv->job && pv->job->qsv.ctx && pv->job->qsv.ctx->qsv_filters_are_enabled) { hb_dict_set(settings, "w", hb_value_int(orig_width)); hb_dict_set(settings, "h", hb_value_int(orig_height)); @@ -1222,6 +1221,7 @@ int reinit_video_filters(hb_work_private_t * pv) } } + filter_init.job = pv->job; filter_init.pix_fmt = pv->frame->format; filter_init.geometry.width = pv->frame->width; filter_init.geometry.height = pv->frame->height; @@ -1416,7 +1416,17 @@ static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job ) hb_error( "decavcodecvInit: qsv ctx alloc failed" ); return 1; } - hb_qsv_add_context_usage(pv->job->qsv.ctx, 0); + 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" ); + return 1; + } + } + hb_qsv_add_context_usage(pv->job->qsv.ctx, 0); + + if (!pv->job->qsv.ctx->dec_space) + { pv->job->qsv.ctx->dec_space = av_mallocz(sizeof(hb_qsv_space)); if(!pv->job->qsv.ctx->dec_space) { diff --git a/libhb/enc_qsv.c b/libhb/enc_qsv.c index 7ff3e1489..45e6e8f15 100644 --- a/libhb/enc_qsv.c +++ b/libhb/enc_qsv.c @@ -42,10 +42,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "libavutil/hwcontext.h" #include <mfx/mfxvideo.h> -extern int qsv_filters_are_enabled; extern AVBufferRef *hb_hw_device_ctx; -HBQSVFramesContext hb_dec_qsv_frames_ctx; -extern HBQSVFramesContext hb_vpp_qsv_frames_ctx; /* * The frame info struct remembers information about each frame across calls to @@ -797,7 +794,7 @@ int qsv_enc_init(hb_work_private_t *pv) // reuse parent session qsv->mfx_session = parent_session; mfxFrameAllocator frame_allocator = { - .pthis = &hb_dec_qsv_frames_ctx, + .pthis = pv->job->qsv.ctx->hb_dec_qsv_frames_ctx, .Alloc = hb_qsv_frame_alloc, .Lock = hb_qsv_frame_lock, .Unlock = hb_qsv_frame_unlock, @@ -805,9 +802,9 @@ int qsv_enc_init(hb_work_private_t *pv) .Free = hb_qsv_frame_free, }; - if (qsv_filters_are_enabled) + if (pv->job->qsv.ctx->qsv_filters_are_enabled) { - frame_allocator.pthis = &hb_vpp_qsv_frames_ctx; + frame_allocator.pthis = pv->job->qsv.ctx->hb_vpp_qsv_frames_ctx; } err = MFXVideoCORE_SetFrameAllocator(qsv->mfx_session, &frame_allocator); @@ -1771,6 +1768,8 @@ void encqsvClose(hb_work_object_t *w) hb_qsv_unload_plugins(&pv->loaded_plugins, qsv_ctx->mfx_session, version); } + 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)); @@ -1822,8 +1821,6 @@ void encqsvClose(hb_work_object_t *w) av_freep(&qsv_ctx); } } - - hb_qsv_uninit_enc(); } if (pv != NULL) @@ -2162,13 +2159,13 @@ static int qsv_enc_work(hb_work_private_t *pv, mfxFrameSurface1 *surface = task->stage->in.p_surface; if(!pv->is_sys_mem && surface) { - if (qsv_filters_are_enabled) + if (pv->job->qsv.ctx->qsv_filters_are_enabled) { - hb_qsv_release_surface_from_pool(&hb_vpp_qsv_frames_ctx, surface->Data.MemId); + hb_qsv_release_surface_from_pool(pv->job->qsv.ctx->hb_vpp_qsv_frames_ctx, surface->Data.MemId); } else { - hb_qsv_release_surface_from_pool(&hb_dec_qsv_frames_ctx, surface->Data.MemId); + hb_qsv_release_surface_from_pool(pv->job->qsv.ctx->hb_dec_qsv_frames_ctx, surface->Data.MemId); } } @@ -2252,28 +2249,28 @@ int encqsvWork(hb_work_object_t *w, hb_buffer_t **buf_in, hb_buffer_t **buf_out) if(in->qsv_details.frame) { surface = ((mfxFrameSurface1*)in->qsv_details.frame->data[3]); - if (qsv_filters_are_enabled) + if (pv->job->qsv.ctx->qsv_filters_are_enabled) { - hb_qsv_get_mid_by_surface_from_pool(&hb_vpp_qsv_frames_ctx, surface, &mid); + hb_qsv_get_mid_by_surface_from_pool(pv->job->qsv.ctx->hb_vpp_qsv_frames_ctx, surface, &mid); } else { - hb_qsv_get_mid_by_surface_from_pool(&hb_dec_qsv_frames_ctx, surface, &mid); + hb_qsv_get_mid_by_surface_from_pool(pv->job->qsv.ctx->hb_dec_qsv_frames_ctx, surface, &mid); } } else { // Create black buffer in the begining of the encoding, usually first 2 frames - hb_qsv_get_free_surface_from_pool_with_range(&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_POOL_SURFACE_SIZE - HB_POOL_ENCODER_SIZE, HB_POOL_SURFACE_SIZE, &mid, &surface); } - if (qsv_filters_are_enabled) + if (pv->job->qsv.ctx->qsv_filters_are_enabled) { - hb_qsv_replace_surface_mid(&hb_vpp_qsv_frames_ctx, mid, surface); + hb_qsv_replace_surface_mid(pv->job->qsv.ctx->hb_vpp_qsv_frames_ctx, mid, surface); } else { - hb_qsv_replace_surface_mid(&hb_dec_qsv_frames_ctx, mid, surface); + hb_qsv_replace_surface_mid(pv->job->qsv.ctx->hb_dec_qsv_frames_ctx, mid, surface); } #endif // At this point, enc_qsv takes ownership of the QSV resources diff --git a/libhb/fifo.c b/libhb/fifo.c index 91eacf4b0..4a75d06bb 100644 --- a/libhb/fifo.c +++ b/libhb/fifo.c @@ -715,12 +715,6 @@ void hb_buffer_swap_copy( hb_buffer_t *src, hb_buffer_t *dst ) src->alloc = alloc; } -#if HB_PROJECT_FEATURE_QSV -extern HBQSVFramesContext hb_dec_qsv_frames_ctx; -extern HBQSVFramesContext hb_vpp_qsv_frames_ctx; -extern int qsv_filters_are_enabled; -#endif - // Frees the specified buffer list. void hb_buffer_close( hb_buffer_t ** _b ) { @@ -736,13 +730,13 @@ void hb_buffer_close( hb_buffer_t ** _b ) mfxFrameSurface1 *surface = (mfxFrameSurface1*)b->qsv_details.frame->data[3]; if(surface) { - if(qsv_filters_are_enabled) + if(b->qsv_details.ctx->qsv_filters_are_enabled) { - hb_qsv_release_surface_from_pool_by_surface_pointer(&hb_dec_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(&hb_dec_qsv_frames_ctx, surface->Data.MemId); + hb_qsv_release_surface_from_pool(b->qsv_details.ctx->hb_dec_qsv_frames_ctx, surface->Data.MemId); } b->qsv_details.frame->data[3] = 0; } diff --git a/libhb/handbrake/qsv_common.h b/libhb/handbrake/qsv_common.h index 7bca30aed..1e437831b 100644 --- a/libhb/handbrake/qsv_common.h +++ b/libhb/handbrake/qsv_common.h @@ -267,9 +267,10 @@ typedef struct 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); +void hb_qsv_update_frames_context(hb_job_t *job); int hb_qsv_full_path_is_enabled(hb_job_t *job); AVBufferRef *hb_qsv_create_mids(AVBufferRef *hw_frames_ref); -hb_buffer_t* hb_qsv_copy_frame(HBQSVFramesContext* hb_qsv_frames_ctx, AVFrame *frame, hb_qsv_context *qsv_ctx, int is_vpp); +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); @@ -280,7 +281,7 @@ int hb_qsv_get_buffer(AVCodecContext *s, AVFrame *frame, int flags); enum AVPixelFormat hb_qsv_get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts); int hb_qsv_preset_is_zero_copy_enabled(const hb_dict_t *job_dict); void hb_qsv_uninit_dec(AVCodecContext *s); -void hb_qsv_uninit_enc(); +void hb_qsv_uninit_enc(hb_job_t *job); #endif // __LIBHB__ #endif // HB_PROJECT_FEATURE_QSV diff --git a/libhb/handbrake/qsv_libav.h b/libhb/handbrake/qsv_libav.h index 3fdf7e231..f567944dd 100644 --- a/libhb/handbrake/qsv_libav.h +++ b/libhb/handbrake/qsv_libav.h @@ -260,6 +260,8 @@ typedef struct hb_qsv_space { mfxMemId *mids; } hb_qsv_space; +typedef struct HBQSVFramesContext HBQSVFramesContext; + typedef struct hb_qsv_context { volatile int is_context_active; @@ -288,6 +290,10 @@ typedef struct hb_qsv_context { void *qsv_config; + int num_cpu_filters; + int qsv_filters_are_enabled; + HBQSVFramesContext *hb_dec_qsv_frames_ctx; + HBQSVFramesContext *hb_vpp_qsv_frames_ctx; } hb_qsv_context; typedef enum { diff --git a/libhb/hbavfilter.c b/libhb/hbavfilter.c index 135492945..d3364a6a1 100644 --- a/libhb/hbavfilter.c +++ b/libhb/hbavfilter.c @@ -17,8 +17,6 @@ #if HB_PROJECT_FEATURE_QSV #include "handbrake/qsv_common.h" -extern int qsv_filters_are_enabled; -extern HBQSVFramesContext hb_vpp_qsv_frames_ctx; #endif struct hb_avfilter_graph_s @@ -30,6 +28,7 @@ struct hb_avfilter_graph_s char * settings; AVFrame * frame; AVRational out_time_base; + hb_job_t * job; }; static AVFilterContext * append_filter( hb_avfilter_graph_t * graph, @@ -91,6 +90,7 @@ hb_avfilter_graph_init(hb_value_t * settings, hb_filter_init_t * init) goto fail; } + graph->job = init->job; graph->settings = settings_str; graph->avgraph = avfilter_graph_alloc(); if (graph->avgraph == NULL) @@ -99,7 +99,8 @@ hb_avfilter_graph_init(hb_value_t * settings, hb_filter_init_t * init) goto fail; } #if HB_PROJECT_FEATURE_QSV - if (!qsv_filters_are_enabled) + int use_qsv_filters = (graph->job && graph->job->qsv.ctx && graph->job->qsv.ctx->qsv_filters_are_enabled) ? 1 : 0; + if (!use_qsv_filters) #endif { av_opt_set(graph->avgraph, "scale_sws_opts", "lanczos+accurate_rnd", 0); @@ -115,7 +116,7 @@ hb_avfilter_graph_init(hb_value_t * settings, hb_filter_init_t * init) AVBufferSrcParameters *par = 0; // Build filter input #if HB_PROJECT_FEATURE_QSV - if (qsv_filters_are_enabled) + if (use_qsv_filters) { par = av_buffersrc_parameters_alloc(); init->pix_fmt = AV_PIX_FMT_QSV; @@ -270,7 +271,7 @@ int hb_avfilter_add_buf(hb_avfilter_graph_t * graph, hb_buffer_t * in) if (in != NULL) { #if HB_PROJECT_FEATURE_QSV - if (qsv_filters_are_enabled) + if (graph->job && graph->job->qsv.ctx && graph->job->qsv.ctx->qsv_filters_are_enabled) { hb_video_buffer_to_avframe(in->qsv_details.frame, in); return hb_avfilter_add_frame(graph, in->qsv_details.frame); @@ -297,9 +298,9 @@ hb_buffer_t * hb_avfilter_get_buf(hb_avfilter_graph_t * graph) { hb_buffer_t * buf; #if HB_PROJECT_FEATURE_QSV - if (qsv_filters_are_enabled) + if (graph->job && graph->job->qsv.ctx && graph->job->qsv.ctx->qsv_filters_are_enabled) { - buf = hb_qsv_copy_frame(&hb_vpp_qsv_frames_ctx, graph->frame, 0, 1); + buf = hb_qsv_copy_frame(graph->job, graph->frame, 1); hb_avframe_set_video_buffer_flags(buf, graph->frame, graph->out_time_base); } else diff --git a/libhb/qsv_common.c b/libhb/qsv_common.c index 12bfa0c29..e3971a02e 100644 --- a/libhb/qsv_common.c +++ b/libhb/qsv_common.c @@ -29,7 +29,8 @@ #include "libavutil/hwcontext_qsv.h" #include "libavutil/hwcontext.h" -extern HBQSVFramesContext hb_dec_qsv_frames_ctx; +static HBQSVFramesContext *hb_dec_qsv_frames_ctx = NULL; +static int qsv_filters_are_enabled = 0; // QSV info for each codec static hb_qsv_info_t *hb_qsv_info_avc = NULL; @@ -989,8 +990,12 @@ int hb_qsv_decode_is_enabled(hb_job_t *job) static int hb_dxva2_device_check(); static int hb_d3d11va_device_check(); -extern int qsv_filters_are_enabled; -extern int num_cpu_filters; + +void hb_qsv_update_frames_context(hb_job_t *job) +{ + qsv_filters_are_enabled = job->qsv.ctx->qsv_filters_are_enabled; + hb_dec_qsv_frames_ctx = job->qsv.ctx->hb_dec_qsv_frames_ctx; +} int hb_qsv_full_path_is_enabled(hb_job_t *job) { @@ -1007,7 +1012,7 @@ int hb_qsv_full_path_is_enabled(hb_job_t *job) qsv_full_path_is_enabled = (hb_qsv_decode_is_enabled(job) && hb_qsv_info_get(job->vcodec) && - device_check_succeded && !num_cpu_filters); + device_check_succeded && !job->qsv.ctx->num_cpu_filters); return qsv_full_path_is_enabled; } @@ -2710,29 +2715,6 @@ static int hb_qsv_allocate_dx11_encoder_pool(HBQSVFramesContext* hb_enc_qsv_fram return 0; } -static int hb_qsv_deallocate_dx11_encoder_pool(HBQSVFramesContext* hb_enc_qsv_frames_ctx) -{ - if (device_manager_handle_type == MFX_HANDLE_D3D11_DEVICE) - { - for (size_t i = 0; i < hb_enc_qsv_frames_ctx->nb_mids; i++) - { - QSVMid *mid = &hb_enc_qsv_frames_ctx->mids[i]; - ID3D11Texture2D* texture = mid->texture; - if (texture) - { - HRESULT hr = ID3D11Texture2D_Release(texture); - mid->texture = NULL; - if (hr != S_OK) - { - hb_error("hb_qsv_deallocate_dx11_encoder_pool: ID3D11Device_ReleaseTexture2D error"); - return -1; - } - } - } - } - return 0; -} - static int hb_qsv_get_dx_device(HBQSVFramesContext* hb_enc_qsv_frames_ctx) { AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)hb_hw_device_ctx->data; @@ -2825,7 +2807,7 @@ void hb_qsv_get_free_surface_from_pool_with_range(HBQSVFramesContext* hb_enc_qsv } } -hb_buffer_t* hb_qsv_copy_frame(HBQSVFramesContext* hb_qsv_frames_ctx, AVFrame *frame, hb_qsv_context *qsv_ctx, int is_vpp) +hb_buffer_t* hb_qsv_copy_frame(hb_job_t *job, AVFrame *frame, int is_vpp) { hb_buffer_t *out; out = hb_frame_buffer_init(frame->format, frame->width, frame->height); @@ -2858,8 +2840,18 @@ hb_buffer_t* hb_qsv_copy_frame(HBQSVFramesContext* hb_qsv_frames_ctx, AVFrame *f QSVMid *mid = NULL; mfxFrameSurface1* output_surface = NULL; - - if (!is_vpp && qsv_filters_are_enabled) + HBQSVFramesContext* hb_qsv_frames_ctx = NULL; + + if (is_vpp) + { + hb_qsv_frames_ctx = job->qsv.ctx->hb_vpp_qsv_frames_ctx; + } + else + { + hb_qsv_frames_ctx = job->qsv.ctx->hb_dec_qsv_frames_ctx; + } + + if (!is_vpp && job->qsv.ctx->qsv_filters_are_enabled) { ret = hb_qsv_get_free_surface_from_pool(hb_qsv_frames_ctx, out->qsv_details.frame, &mid); if (ret < 0) @@ -2875,7 +2867,7 @@ hb_buffer_t* hb_qsv_copy_frame(HBQSVFramesContext* hb_qsv_frames_ctx, AVFrame *f { mfxFrameSurface1* input_surface = (mfxFrameSurface1*)frame->data[3]; // copy all surface fields - if (qsv_filters_are_enabled) + if (job->qsv.ctx->qsv_filters_are_enabled) { mfxMemId mem = output_surface->Data.MemId; *output_surface = *input_surface; @@ -2928,7 +2920,7 @@ hb_buffer_t* hb_qsv_copy_frame(HBQSVFramesContext* hb_qsv_frames_ctx, AVFrame *f } out->qsv_details.frame->data[3] = (uint8_t*)output_surface; out->qsv_details.qsv_atom = 0; - out->qsv_details.ctx = qsv_ctx; + out->qsv_details.ctx = job->qsv.ctx; return out; } @@ -2948,27 +2940,30 @@ void hb_qsv_uninit_dec(AVCodecContext *s) av_buffer_unref(&s->hw_frames_ctx); } -extern HBQSVFramesContext hb_vpp_qsv_frames_ctx; - -void hb_qsv_uninit_enc() +void hb_qsv_uninit_enc(hb_job_t *job) { - if(hb_dec_qsv_frames_ctx.hw_frames_ctx) - av_buffer_unref(&hb_dec_qsv_frames_ctx.hw_frames_ctx); - - if(hb_vpp_qsv_frames_ctx.hw_frames_ctx) - av_buffer_unref(&hb_vpp_qsv_frames_ctx.hw_frames_ctx); - - hb_dec_qsv_frames_ctx.hw_frames_ctx = NULL; - hb_vpp_qsv_frames_ctx.hw_frames_ctx = NULL; - hb_hw_device_ctx = NULL; - qsv_device = NULL; - device_manager_handle = NULL; - hb_qsv_deallocate_dx11_encoder_pool(&hb_dec_qsv_frames_ctx); + if(job->qsv.ctx->hb_dec_qsv_frames_ctx) + { + av_buffer_unref(&job->qsv.ctx->hb_dec_qsv_frames_ctx->hw_frames_ctx); + job->qsv.ctx->hb_dec_qsv_frames_ctx->hw_frames_ctx = NULL; + av_free(job->qsv.ctx->hb_dec_qsv_frames_ctx); + job->qsv.ctx->hb_dec_qsv_frames_ctx = NULL; + } + if(job->qsv.ctx->hb_vpp_qsv_frames_ctx) + { + av_buffer_unref(&job->qsv.ctx->hb_vpp_qsv_frames_ctx->hw_frames_ctx); + job->qsv.ctx->hb_vpp_qsv_frames_ctx->hw_frames_ctx = NULL; + av_free(job->qsv.ctx->hb_vpp_qsv_frames_ctx); + job->qsv.ctx->hb_vpp_qsv_frames_ctx = NULL; + } if (device_context) { ID3D11DeviceContext_Release(device_context); device_context = NULL; } + hb_hw_device_ctx = NULL; + qsv_device = NULL; + device_manager_handle = NULL; } static int qsv_device_init() @@ -3054,7 +3049,7 @@ int hb_qsv_init(int coded_width, int coded_height, enum AVPixelFormat sw_pix_fmt AVBufferRef *hw_frames_ctx; 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); if (ret < 0) { hb_error("hb_qsv_init: hb_create_ffmpeg_pool decoder failed %d", ret); @@ -3064,24 +3059,24 @@ int hb_qsv_init(int coded_width, int coded_height, enum AVPixelFormat sw_pix_fmt hw_frames_ctx = *out_hw_frames_ctx; frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data; frames_hwctx = frames_ctx->hwctx; - hb_dec_qsv_frames_ctx.input_texture = frames_hwctx->texture; + 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_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; } /* allocate the memory ids for the external frames */ - av_buffer_unref(&hb_dec_qsv_frames_ctx.mids_buf); - hb_dec_qsv_frames_ctx.mids_buf = hb_qsv_create_mids(hb_dec_qsv_frames_ctx.hw_frames_ctx); - if (!hb_dec_qsv_frames_ctx.mids_buf) + av_buffer_unref(&hb_dec_qsv_frames_ctx->mids_buf); + hb_dec_qsv_frames_ctx->mids_buf = hb_qsv_create_mids(hb_dec_qsv_frames_ctx->hw_frames_ctx); + if (!hb_dec_qsv_frames_ctx->mids_buf) return AVERROR(ENOMEM); - hb_dec_qsv_frames_ctx.mids = (QSVMid*)hb_dec_qsv_frames_ctx.mids_buf->data; - hb_dec_qsv_frames_ctx.nb_mids = frames_hwctx->nb_surfaces; - memset(hb_dec_qsv_frames_ctx.pool, 0, hb_dec_qsv_frames_ctx.nb_mids * sizeof(hb_dec_qsv_frames_ctx.pool[0])); + hb_dec_qsv_frames_ctx->mids = (QSVMid*)hb_dec_qsv_frames_ctx->mids_buf->data; + hb_dec_qsv_frames_ctx->nb_mids = frames_hwctx->nb_surfaces; + memset(hb_dec_qsv_frames_ctx->pool, 0, hb_dec_qsv_frames_ctx->nb_mids * sizeof(hb_dec_qsv_frames_ctx->pool[0])); - ret = hb_qsv_get_dx_device(&hb_dec_qsv_frames_ctx); + ret = hb_qsv_get_dx_device(hb_dec_qsv_frames_ctx); if (ret < 0) { hb_error("qsv_init: hb_qsv_get_dx_device failed %d", ret); return ret; @@ -3209,7 +3204,7 @@ void hb_qsv_uninit_dec(AVCodecContext *s) { } -void hb_qsv_uninit_enc() +void hb_qsv_uninit_enc(hb_job_t *job) { } diff --git a/libhb/work.c b/libhb/work.c index 277e7415e..2efccf47b 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -1226,11 +1226,6 @@ static int sanitize_audio(hb_job_t *job) return 0; } -#if HB_PROJECT_FEATURE_QSV -int num_cpu_filters = 0; -int qsv_filters_are_enabled = 0; -#endif - static int sanitize_qsv( hb_job_t * job ) { #if HB_PROJECT_FEATURE_QSV @@ -1238,9 +1233,26 @@ 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; - qsv_filters_are_enabled = 0; - num_cpu_filters = 0; + int num_cpu_filters = 0; if (job->vcodec & HB_VCODEC_QSV_MASK) { if (job->list_filter != NULL && hb_list_count(job->list_filter) > 0) @@ -1267,8 +1279,19 @@ static int sanitize_qsv( hb_job_t * job ) } } } - qsv_filters_are_enabled = ((hb_list_count(job->list_filter) == 1) && hb_qsv_full_path_is_enabled(job)) ? 1 : 0; } + 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) + { + hb_error( "sanitize_qsv: HBQSVFramesContext vpp alloc failed" ); + return 1; + } + } + hb_qsv_update_frames_context(job); #endif // HB_PROJECT_FEATURE_QSV return 0; |