#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 );
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:
if(!in->qsv_details.filter_details)
in->qsv_details.filter_details = pv;
-
if ( in->size <= 0 )
{
*buf_out = in;
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;
}
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)
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;
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);
}
#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);
#ifdef USE_QSV
#include "libavcodec/qsv.h"
+#include "qsv_filter_pp.h"
#endif
typedef struct
}
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;