From aace088c1916c1c8de1be4723801242314b5a40c Mon Sep 17 00:00:00 2001 From: handbrake Date: Wed, 31 Jul 2013 15:11:58 +0000 Subject: [PATCH] QSV: fix for existing yadiff filters usage; fix for clean up of encode; fix for buffer resize and new size git-svn-id: svn://svn.handbrake.fr/HandBrake/branches/qsv@5677 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- libhb/enc_qsv.c | 9 +++-- libhb/fifo.c | 8 +++-- libhb/qsv_filter_pp.c | 76 ++++++++++++++++++++++++++----------------- libhb/qsv_filter_pp.h | 27 +++++++++++++++ libhb/work.c | 20 ++++++++++++ 5 files changed, 105 insertions(+), 35 deletions(-) diff --git a/libhb/enc_qsv.c b/libhb/enc_qsv.c index 779ac8462..830412703 100644 --- a/libhb/enc_qsv.c +++ b/libhb/enc_qsv.c @@ -929,9 +929,12 @@ void encqsvClose( hb_work_object_t * w ) } } - av_freep(&pv->sps_pps->SPSBuffer); - av_freep(&pv->sps_pps->PPSBuffer); - av_freep(&pv->sps_pps); + if (pv->sps_pps) + { + av_freep(&pv->sps_pps->SPSBuffer); + av_freep(&pv->sps_pps->PPSBuffer); + av_freep(&pv->sps_pps); + } } if (pv != NULL) diff --git a/libhb/fifo.c b/libhb/fifo.c index f8ef8555e..e355aa6f1 100644 --- a/libhb/fifo.c +++ b/libhb/fifo.c @@ -383,6 +383,10 @@ hb_buffer_t * hb_buffer_dup( const hb_buffer_t * src ) hb_buffer_init_planes( buf ); } +#ifdef USE_QSV + memcpy(&buf->qsv_details,&src->qsv_details,sizeof(src->qsv_details)); +#endif + return buf; } @@ -406,7 +410,7 @@ int hb_buffer_copy(hb_buffer_t * dst, const hb_buffer_t * src) static void hb_buffer_init_planes_internal( hb_buffer_t * b, uint8_t * has_plane ) { uint8_t * plane = b->data; - int p, tot = 0; + int p; for( p = 0; p < 4; p++ ) { @@ -419,7 +423,6 @@ static void hb_buffer_init_planes_internal( hb_buffer_t * b, uint8_t * has_plane b->plane[p].height = hb_image_height( b->f.fmt, b->f.height, p ); b->plane[p].size = b->plane[p].stride * b->plane[p].height_stride; plane += b->plane[p].size; - tot += b->plane[p].size; } } } @@ -502,6 +505,7 @@ void hb_video_buffer_realloc( hb_buffer_t * buf, int width, int height ) buf->f.width = width; buf->f.height = height; + buf->size = size; hb_buffer_init_planes_internal( buf, has_plane ); } diff --git a/libhb/qsv_filter_pp.c b/libhb/qsv_filter_pp.c index 30aaa8d11..ca39c538c 100644 --- a/libhb/qsv_filter_pp.c +++ b/libhb/qsv_filter_pp.c @@ -33,31 +33,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "qsv_filter.h" #include "qsv_memory.h" -typedef struct hb_qsv_sync_s{ - int frame_go; - hb_cond_t *frame_completed; - hb_lock_t *frame_completed_lock; - - hb_buffer_t *in; - hb_buffer_t *out; -} hb_qsv_sync_t; - -struct hb_filter_private_s -{ - hb_job_t *job; - hb_list_t *list; - - hb_qsv_sync_t pre; - hb_qsv_sync_t post; - - hb_qsv_sync_t pre_busy; - - av_qsv_space *vpp_space; - hb_list_t *qsv_user; - - struct SwsContext* sws_context_to_nv12; - struct SwsContext* sws_context_from_nv12; -}; static int hb_qsv_filter_pre_init( hb_filter_object_t * filter, hb_filter_init_t * init ); @@ -293,6 +268,10 @@ static int hb_qsv_filter_pre_init( hb_filter_object_t * filter, pv->pre_busy.frame_completed = hb_cond_init(); pv->pre_busy.frame_completed_lock = hb_lock_init(); + pv->post_busy.frame_go = 0; + pv->post_busy.frame_completed = hb_cond_init(); + pv->post_busy.frame_completed_lock = hb_lock_init(); + pv->list = hb_list_init(); // just to remind: @@ -460,7 +439,6 @@ static int hb_qsv_filter_pre_work( hb_filter_object_t * filter, if(!in->qsv_details.filter_details) in->qsv_details.filter_details = pv; - if ( in->size <= 0 ) { *buf_out = in; @@ -541,6 +519,11 @@ static void hb_qsv_filter_pre_close( hb_filter_object_t * filter ){ hb_cond_close(&pv->pre_busy.frame_completed); hb_lock_close(&pv->pre_busy.frame_completed_lock); + hb_cond_close(&pv->post_busy.frame_completed); + hb_lock_close(&pv->post_busy.frame_completed_lock); + + hb_list_close( &pv->list ); + free( pv ); filter->private_data = NULL; } @@ -580,6 +563,13 @@ static int hb_qsv_filter_post_work( hb_filter_object_t * filter, av_qsv_context* qsv = pv->job->qsv; pv = in->qsv_details.filter_details; + if (!pv) + { + *buf_out = NULL; + *buf_in = NULL; + return HB_FILTER_OK; + } + while(1){ int ret = filter_pre_init(qsv,pv); if(ret >= 2) @@ -588,19 +578,34 @@ static int hb_qsv_filter_post_work( hb_filter_object_t * filter, break; } - pv->post.in = in; pv->post.out = out; - pv->post.in = in; - + // signal: input is prepared, can start inserting data back into pipeline hb_lock(pv->post.frame_completed_lock); pv->post.frame_go = 1; hb_cond_broadcast(pv->post.frame_completed); hb_unlock(pv->post.frame_completed_lock); - // for now - just bypass to the next + // wait: on signal that data is ready + hb_lock(pv->post_busy.frame_completed_lock); + while(!pv->post_busy.frame_go){ + hb_cond_timedwait(pv->post_busy.frame_completed,pv->post_busy.frame_completed_lock,1000); + if(*pv->job->die) + break; + } + pv->post_busy.frame_go = 0; + hb_unlock(pv->post_busy.frame_completed_lock); + + if (pv->post.status == HB_FILTER_OK || pv->post.status == HB_FILTER_DONE) + { *buf_out = in; + } + else + { + *buf_out = NULL; + pv->post.status = HB_FILTER_OK; + } *buf_in = NULL; return HB_FILTER_OK; @@ -859,11 +864,13 @@ int process_filter(qsv_filter_task_t* task, void* params){ qsv_nv12_to_yuv420(task->pv->sws_context_from_nv12,task->pv->pre.out, task->in, task->processor.core); + // signal: input is prepared, converted from pipeline into internal buffer hb_lock(task->pv->pre.frame_completed_lock); task->pv->pre.frame_go = 1; hb_cond_broadcast(task->pv->pre.frame_completed); hb_unlock(task->pv->pre.frame_completed_lock); + // wait: input is prepared, converted from pipeline into internal buffer hb_lock(task->pv->post.frame_completed_lock); while(!task->pv->post.frame_go){ hb_cond_timedwait(task->pv->post.frame_completed,task->pv->post.frame_completed_lock,1000); @@ -891,7 +898,16 @@ int process_filter(qsv_filter_task_t* task, void* params){ } #endif + if(task->pv->post.in) + { qsv_yuv420_to_nv12(task->pv->sws_context_to_nv12, task->out, task->pv->post.in); + } + + // signal: output is prepared, converted from internal buffer into pipeline + hb_lock(task->pv->post_busy.frame_completed_lock); + task->pv->post_busy.frame_go = 1; + hb_cond_broadcast(task->pv->post_busy.frame_completed); + hb_unlock(task->pv->post_busy.frame_completed_lock); unlock_frame(task->processor.alloc,task->in); unlock_frame(task->processor.alloc,task->out); diff --git a/libhb/qsv_filter_pp.h b/libhb/qsv_filter_pp.h index 9efc59faf..e70370321 100644 --- a/libhb/qsv_filter_pp.h +++ b/libhb/qsv_filter_pp.h @@ -63,6 +63,33 @@ typedef struct qsv_filter_private_s{ hb_list_t *tasks; } qsv_filter_t; +typedef struct hb_qsv_sync_s{ + int frame_go; + int status; + hb_cond_t *frame_completed; + hb_lock_t *frame_completed_lock; + + hb_buffer_t *in; + hb_buffer_t *out; +} hb_qsv_sync_t; + +typedef struct hb_filter_private_s +{ + hb_job_t *job; + hb_list_t *list; + + hb_qsv_sync_t pre; + hb_qsv_sync_t pre_busy; + + hb_qsv_sync_t post; + hb_qsv_sync_t post_busy; + + av_qsv_space *vpp_space; + hb_list_t *qsv_user; + + struct SwsContext* sws_context_to_nv12; + struct SwsContext* sws_context_from_nv12; +} hb_filter_private_t_qsv; // methods to be called by Media SDK mfxStatus MFX_CDECL qsv_PluginInit(mfxHDL pthis, mfxCoreInterface *core); diff --git a/libhb/work.c b/libhb/work.c index d42a87527..418ac185d 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -13,6 +13,7 @@ #ifdef USE_QSV #include "libavcodec/qsv.h" +#include "qsv_filter_pp.h" #endif typedef struct @@ -1640,8 +1641,27 @@ static void filter_loop( void * _f ) } buf_out = NULL; + +#ifdef USE_QSV + hb_buffer_t *last_buf_in = buf_in; +#endif + f->status = f->work( f, &buf_in, &buf_out ); +#ifdef USE_QSV + if (f->status==HB_FILTER_DELAY && last_buf_in->qsv_details.filter_details && + buf_out == NULL) + { + hb_filter_private_t_qsv *qsv_user = buf_in ? buf_in->qsv_details.filter_details : last_buf_in->qsv_details.filter_details ; + qsv_user->post.status = f->status; + + hb_lock(qsv_user->post.frame_completed_lock); + qsv_user->post.frame_go = 1; + hb_cond_broadcast(qsv_user->post.frame_completed); + hb_unlock(qsv_user->post.frame_completed_lock); + + } +#endif if ( buf_out && f->chapter_val && f->chapter_time <= buf_out->s.start ) { buf_out->s.new_chap = f->chapter_val; -- 2.40.0