Commit a9a59e05 authored by Thomas Guillem's avatar Thomas Guillem

vout: process static filter chain in separate thread

parent 4c822763
......@@ -676,6 +676,106 @@ int vout_HideWindowMouse(vout_thread_t *vout, bool hide)
return window != NULL ? vout_window_HideMouse(window, hide) : VLC_EGENERIC;
}
static void *static_filter_thread_Run(void *ctx)
{
vout_thread_t *vout = ctx;
vout_thread_sys_t *sys = vout->p;
int canc = vlc_savecancel();
for (;;)
{
picture_t *pic = picture_fifo_Wait(sys->decoder_fifo);
const mtime_t now_dbg = mdate();
if (pic == NULL)
{
filter_chain_VideoFlush(sys->filter.chain_static);
vlc_restorecancel(canc);
vlc_testcancel();
canc = vlc_savecancel();
continue;
}
if (sys->is_late_dropped && !pic->b_force)
{
if (vout_IsPictureLate(vout, pic, mdate(), pic->date))
{
picture_Release(pic);
vout_statistic_AddLost(&vout->p->statistic, 1);
continue;
}
}
pic = filter_chain_VideoFilter(sys->filter.chain_static, pic);
if (pic)
picture_fifo_Push(sys->filter.static_fifo, pic);
else
{
pic = filter_chain_VideoFilter(sys->filter.chain_static, NULL);
if (pic)
picture_fifo_Push(sys->filter.static_fifo, pic);
}
fprintf(stderr, "filter took %"PRId64 "\n", mdate() - now_dbg);
}
vlc_assert_unreachable();
}
static int static_filter_thread_Start(vout_thread_t *vout)
{
vout_thread_sys_t *sys = vout->p;
assert(!sys->filter.static_fifo);
sys->filter.static_fifo = picture_fifo_New();
if (!sys->filter.static_fifo)
return VLC_ENOMEM;
int ret = vlc_clone(&sys->filter.static_thread, static_filter_thread_Run,
vout, VLC_THREAD_PRIORITY_OUTPUT);
if (ret != VLC_SUCCESS)
{
picture_fifo_Delete(sys->filter.static_fifo);
sys->filter.static_fifo = NULL;
return ret;
}
msg_Info(vout, "static_filter_thread_Start");
return VLC_SUCCESS;
}
static void static_filter_thread_Stop(vout_thread_t *vout)
{
vout_thread_sys_t *sys = vout->p;
if (!sys->filter.static_fifo)
return;
vlc_cancel(sys->filter.static_thread);
picture_fifo_Signal(sys->decoder_fifo);
vlc_join(sys->filter.static_thread, NULL);
picture_fifo_Delete(sys->filter.static_fifo);
sys->filter.static_fifo = NULL;
msg_Info(vout, "static_filter_thread_Stop");
}
static void static_filter_thread_Flush(vout_thread_t *vout)
{
vout_thread_sys_t *sys = vout->p;
if (!sys->filter.static_fifo)
return;
picture_fifo_Signal(sys->decoder_fifo);
}
/* */
static int FilterRestartCallback(vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval,
......@@ -704,7 +804,7 @@ static picture_t *VoutVideoFilterInteractiveNewPicture(filter_t *filter)
{
vout_thread_t *vout = filter->owner.sys;
picture_t *picture = picture_pool_Get(vout->p->private_pool);
picture_t *picture = picture_pool_Wait(vout->p->private_pool);
if (picture) {
picture_Reset(picture);
VideoFormatCopyCropAr(&picture->format, &filter->fmt_out.video);
......@@ -716,7 +816,6 @@ static picture_t *VoutVideoFilterStaticNewPicture(filter_t *filter)
{
vout_thread_t *vout = filter->owner.sys;
vlc_assert_locked(&vout->p->filter.lock);
if (filter_chain_IsEmpty(vout->p->filter.chain_interactive))
return VoutVideoFilterInteractiveNewPicture(filter);
......@@ -735,10 +834,13 @@ static void ThreadFilterFlush(vout_thread_t *vout, bool is_locked)
if (!is_locked)
vlc_mutex_lock(&vout->p->filter.lock);
filter_chain_VideoFlush(vout->p->filter.chain_static);
filter_chain_VideoFlush(vout->p->filter.chain_interactive);
if (!is_locked)
vlc_mutex_unlock(&vout->p->filter.lock);
static_filter_thread_Flush(vout);
}
typedef struct {
......@@ -752,6 +854,8 @@ static void ThreadChangeFilters(vout_thread_t *vout,
int deinterlace,
bool is_locked)
{
static_filter_thread_Stop(vout);
ThreadFilterFlush(vout, is_locked);
ThreadDelAllFilterCallbacks(vout);
......@@ -859,6 +963,12 @@ static void ThreadChangeFilters(vout_thread_t *vout,
video_format_Copy(&vout->p->filter.format, source);
}
if (!filter_chain_IsEmpty(vout->p->filter.chain_static))
{
if (static_filter_thread_Start(vout) != VLC_SUCCESS)
goto error;
}
if (!is_locked)
vlc_mutex_unlock(&vout->p->filter.lock);
......@@ -880,7 +990,7 @@ static int ThreadDisplayPreparePicture(vout_thread_t *vout, bool reuse, bool fra
vlc_mutex_lock(&vout->p->filter.lock);
picture_t *picture = filter_chain_VideoFilter(vout->p->filter.chain_static, NULL);
picture_t *picture = NULL;
assert(!reuse || !picture);
while (!picture) {
......@@ -888,7 +998,9 @@ static int ThreadDisplayPreparePicture(vout_thread_t *vout, bool reuse, bool fra
if (reuse && vout->p->displayed.decoded) {
decoded = picture_Hold(vout->p->displayed.decoded);
} else {
decoded = picture_fifo_Pop(vout->p->decoder_fifo);
decoded = vout->p->filter.static_fifo ? picture_fifo_Pop(vout->p->filter.static_fifo)
: picture_fifo_Pop(vout->p->decoder_fifo);
if (decoded) {
if (is_late_dropped && !decoded->b_force) {
const mtime_t predicted = mdate() + 0; /* TODO improve */
......@@ -914,8 +1026,7 @@ static int ThreadDisplayPreparePicture(vout_thread_t *vout, bool reuse, bool fra
vout->p->displayed.decoded = picture_Hold(decoded);
vout->p->displayed.timestamp = decoded->date;
vout->p->displayed.is_interlaced = !decoded->b_progressive;
picture = filter_chain_VideoFilter(vout->p->filter.chain_static, decoded);
picture = decoded;
}
vlc_mutex_unlock(&vout->p->filter.lock);
......@@ -1357,6 +1468,8 @@ static void ThreadFlush(vout_thread_t *vout, bool below, mtime_t date)
}
picture_fifo_Flush(vout->p->decoder_fifo, date, below);
if (vout->p->filter.static_fifo)
picture_fifo_Flush(vout->p->filter.static_fifo, date, below);
vout_FilterFlush(vout->p->display.vd);
}
......@@ -1516,6 +1629,7 @@ static int ThreadStart(vout_thread_t *vout, vout_display_state_t *state)
vout->p->private_pool = NULL;
vout->p->filter.configuration = NULL;
vout->p->filter.static_fifo = NULL;
video_format_Copy(&vout->p->filter.format, &vout->p->original);
filter_owner_t owner = {
......@@ -1601,6 +1715,8 @@ static void ThreadStop(vout_thread_t *vout, vout_display_state_t *state)
vout_CloseWrapper(vout, state);
}
static_filter_thread_Stop(vout);
/* Destroy the video filters */
ThreadDelAllFilterCallbacks(vout);
filter_chain_Delete(vout->p->filter.chain_interactive);
......
......@@ -125,6 +125,9 @@ struct vout_thread_sys_t
struct filter_chain_t *chain_static;
struct filter_chain_t *chain_interactive;
bool has_deint;
vlc_thread_t static_thread;
picture_fifo_t *static_fifo;
} filter;
/* */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment