Commit 77e04037 authored by Laurent Aimar's avatar Laurent Aimar

No functionnal changes (vout).

parent ea3a73d0
...@@ -30,10 +30,10 @@ ...@@ -30,10 +30,10 @@
/* */ /* */
enum { enum {
#if 0
VOUT_CONTROL_INIT, VOUT_CONTROL_INIT,
VOUT_CONTROL_EXIT, VOUT_CONTROL_CLEAN,
#if 0
/* */ /* */
VOUT_CONTROL_START, VOUT_CONTROL_START,
VOUT_CONTROL_STOP, VOUT_CONTROL_STOP,
......
...@@ -134,12 +134,8 @@ vout_thread_t *vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout, ...@@ -134,12 +134,8 @@ vout_thread_t *vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout,
/* If we now have a video output, check it has the right properties */ /* If we now have a video output, check it has the right properties */
if( p_vout ) if( p_vout )
{ {
vlc_mutex_lock( &p_vout->p->change_lock );
if( !video_format_IsSimilar( &p_vout->p->original, p_fmt ) ) if( !video_format_IsSimilar( &p_vout->p->original, p_fmt ) )
{ {
vlc_mutex_unlock( &p_vout->p->change_lock );
/* We are not interested in this format, close this vout */ /* We are not interested in this format, close this vout */
vout_CloseAndRelease( p_vout ); vout_CloseAndRelease( p_vout );
vlc_object_release( p_vout ); vlc_object_release( p_vout );
...@@ -148,8 +144,6 @@ vout_thread_t *vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout, ...@@ -148,8 +144,6 @@ vout_thread_t *vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout,
else else
{ {
/* This video output is cool! Hijack it. */ /* This video output is cool! Hijack it. */
vlc_mutex_unlock( &p_vout->p->change_lock );
vlc_object_release( p_vout ); vlc_object_release( p_vout );
} }
...@@ -222,6 +216,7 @@ vout_thread_t * (vout_Create)( vlc_object_t *p_parent, video_format_t *p_fmt ) ...@@ -222,6 +216,7 @@ vout_thread_t * (vout_Create)( vlc_object_t *p_parent, video_format_t *p_fmt )
/* Initialize misc stuff */ /* Initialize misc stuff */
vout_control_Init( &p_vout->p->control ); vout_control_Init( &p_vout->p->control );
vout_control_PushVoid( &p_vout->p->control, VOUT_CONTROL_INIT );
vout_chrono_Init( &p_vout->p->render, 5, 10000 ); /* Arbitrary initial time */ vout_chrono_Init( &p_vout->p->render, 5, 10000 ); /* Arbitrary initial time */
vout_statistic_Init( &p_vout->p->statistic ); vout_statistic_Init( &p_vout->p->statistic );
p_vout->p->i_par_num = p_vout->p->i_par_num =
...@@ -251,7 +246,6 @@ vout_thread_t * (vout_Create)( vlc_object_t *p_parent, video_format_t *p_fmt ) ...@@ -251,7 +246,6 @@ vout_thread_t * (vout_Create)( vlc_object_t *p_parent, video_format_t *p_fmt )
/* Initialize locks */ /* Initialize locks */
vlc_mutex_init( &p_vout->p->picture_lock ); vlc_mutex_init( &p_vout->p->picture_lock );
vlc_mutex_init( &p_vout->p->change_lock );
vlc_mutex_init( &p_vout->p->vfilter_lock ); vlc_mutex_init( &p_vout->p->vfilter_lock );
/* Mouse coordinates */ /* Mouse coordinates */
...@@ -327,7 +321,6 @@ vout_thread_t * (vout_Create)( vlc_object_t *p_parent, video_format_t *p_fmt ) ...@@ -327,7 +321,6 @@ vout_thread_t * (vout_Create)( vlc_object_t *p_parent, video_format_t *p_fmt )
vlc_object_set_destructor( p_vout, vout_Destructor ); vlc_object_set_destructor( p_vout, vout_Destructor );
/* */ /* */
vlc_cond_init( &p_vout->p->change_wait );
if( vlc_clone( &p_vout->p->thread, Thread, p_vout, if( vlc_clone( &p_vout->p->thread, Thread, p_vout,
VLC_THREAD_PRIORITY_OUTPUT ) ) VLC_THREAD_PRIORITY_OUTPUT ) )
{ {
...@@ -338,16 +331,9 @@ vout_thread_t * (vout_Create)( vlc_object_t *p_parent, video_format_t *p_fmt ) ...@@ -338,16 +331,9 @@ vout_thread_t * (vout_Create)( vlc_object_t *p_parent, video_format_t *p_fmt )
return NULL; return NULL;
} }
vlc_mutex_lock( &p_vout->p->change_lock ); vout_control_WaitEmpty( &p_vout->p->control );
while( !p_vout->p->b_ready )
{ /* We are (ab)using the same condition in opposite directions for
* b_ready and b_done. This works because of the strict ordering. */
assert( !p_vout->p->b_done );
vlc_cond_wait( &p_vout->p->change_wait, &p_vout->p->change_lock );
}
vlc_mutex_unlock( &p_vout->p->change_lock );
if( p_vout->p->b_error ) if (p_vout->p->dead )
{ {
msg_Err( p_vout, "video output creation failed" ); msg_Err( p_vout, "video output creation failed" );
vout_CloseAndRelease( p_vout ); vout_CloseAndRelease( p_vout );
...@@ -369,13 +355,9 @@ void vout_Close( vout_thread_t *p_vout ) ...@@ -369,13 +355,9 @@ void vout_Close( vout_thread_t *p_vout )
{ {
assert( p_vout ); assert( p_vout );
vlc_mutex_lock( &p_vout->p->change_lock );
p_vout->p->b_done = true;
vlc_cond_signal( &p_vout->p->change_wait );
vlc_mutex_unlock( &p_vout->p->change_lock );
vout_snapshot_End( &p_vout->p->snapshot ); vout_snapshot_End( &p_vout->p->snapshot );
vout_control_PushVoid( &p_vout->p->control, VOUT_CONTROL_CLEAN );
vlc_join( p_vout->p->thread, NULL ); vlc_join( p_vout->p->thread, NULL );
} }
...@@ -400,9 +382,7 @@ static void vout_Destructor( vlc_object_t * p_this ) ...@@ -400,9 +382,7 @@ static void vout_Destructor( vlc_object_t * p_this )
assert( !p_vout->p->decoder_pool ); assert( !p_vout->p->decoder_pool );
/* Destroy the locks */ /* Destroy the locks */
vlc_cond_destroy( &p_vout->p->change_wait );
vlc_mutex_destroy( &p_vout->p->picture_lock ); vlc_mutex_destroy( &p_vout->p->picture_lock );
vlc_mutex_destroy( &p_vout->p->change_lock );
vlc_mutex_destroy( &p_vout->p->vfilter_lock ); vlc_mutex_destroy( &p_vout->p->vfilter_lock );
vout_control_Clean( &p_vout->p->control ); vout_control_Clean( &p_vout->p->control );
...@@ -582,29 +562,7 @@ void vout_ControlChangeCropBorder(vout_thread_t *vout, ...@@ -582,29 +562,7 @@ void vout_ControlChangeCropBorder(vout_thread_t *vout,
vout_control_Push(&vout->p->control, &cmd); vout_control_Push(&vout->p->control, &cmd);
} }
/***************************************************************************** /* */
* InitThread: initialize video output thread
*****************************************************************************
* This function is called from Thread and performs the second step of the
* initialization. It returns 0 on success. Note that the thread's flag are not
* modified inside this function.
* XXX You have to enter it with change_lock taken.
*****************************************************************************/
static int ThreadInit(vout_thread_t *vout)
{
/* Initialize output method, it allocates direct buffers for us */
if (vout_InitWrapper(vout))
return VLC_EGENERIC;
assert(vout->p->decoder_pool);
vout->p->displayed.decoded = NULL;
/* print some usefull debug info about different vout formats
*/
PrintVideoFormat(vout, "pic render", &vout->p->original);
return VLC_SUCCESS;
}
static int ThreadDisplayPicture(vout_thread_t *vout, static int ThreadDisplayPicture(vout_thread_t *vout,
bool now, mtime_t *deadline) bool now, mtime_t *deadline)
{ {
...@@ -794,7 +752,7 @@ static int ThreadDisplayPicture(vout_thread_t *vout, ...@@ -794,7 +752,7 @@ static int ThreadDisplayPicture(vout_thread_t *vout,
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static int ThreadManage(vout_thread_t *vout, static void ThreadManage(vout_thread_t *vout,
mtime_t *deadline, mtime_t *deadline,
vout_interlacing_support_t *interlacing, vout_interlacing_support_t *interlacing,
vout_postprocessing_support_t *postprocessing) vout_postprocessing_support_t *postprocessing)
...@@ -815,14 +773,7 @@ static int ThreadManage(vout_thread_t *vout, ...@@ -815,14 +773,7 @@ static int ThreadManage(vout_thread_t *vout,
/* Deinterlacing */ /* Deinterlacing */
vout_SetInterlacingState(vout, interlacing, picture_interlaced); vout_SetInterlacingState(vout, interlacing, picture_interlaced);
if (vout_ManageWrapper(vout)) { vout_ManageWrapper(vout);
/* A fatal error occurred, and the thread must terminate
* immediately, without displaying anything - setting b_error to 1
* causes the immediate end of the main while() loop. */
// FIXME pf_end
return VLC_EGENERIC;
}
return VLC_SUCCESS;
} }
static void ThreadDisplayOsdTitle(vout_thread_t *vout, const char *string) static void ThreadDisplayOsdTitle(vout_thread_t *vout, const char *string)
...@@ -830,8 +781,6 @@ static void ThreadDisplayOsdTitle(vout_thread_t *vout, const char *string) ...@@ -830,8 +781,6 @@ static void ThreadDisplayOsdTitle(vout_thread_t *vout, const char *string)
if (!vout->p->title.show) if (!vout->p->title.show)
return; return;
vlc_assert_locked(&vout->p->change_lock);
vout_OSDText(vout, SPU_DEFAULT_CHANNEL, vout_OSDText(vout, SPU_DEFAULT_CHANNEL,
vout->p->title.position, INT64_C(1000) * vout->p->title.timeout, vout->p->title.position, INT64_C(1000) * vout->p->title.timeout,
string); string);
...@@ -855,7 +804,6 @@ static void ThreadChangeFilters(vout_thread_t *vout, const char *filters) ...@@ -855,7 +804,6 @@ static void ThreadChangeFilters(vout_thread_t *vout, const char *filters)
static void ThreadChangePause(vout_thread_t *vout, bool is_paused, mtime_t date) static void ThreadChangePause(vout_thread_t *vout, bool is_paused, mtime_t date)
{ {
vlc_assert_locked(&vout->p->change_lock);
assert(!vout->p->pause.is_on || !is_paused); assert(!vout->p->pause.is_on || !is_paused);
if (vout->p->pause.is_on) { if (vout->p->pause.is_on) {
...@@ -1031,13 +979,42 @@ static void ThreadExecuteCropRatio(vout_thread_t *vout, ...@@ -1031,13 +979,42 @@ static void ThreadExecuteCropRatio(vout_thread_t *vout,
ThreadExecuteCropWindow(vout, num, den, x, y, width, height); ThreadExecuteCropWindow(vout, num, den, x, y, width, height);
} }
static int ThreadInit(vout_thread_t *vout)
{
vout->p->dead = false;
if (vout_OpenWrapper(vout, vout->p->psz_module_name))
return VLC_EGENERIC;
if (vout_InitWrapper(vout))
return VLC_EGENERIC;
assert(vout->p->decoder_pool);
vout->p->displayed.decoded = NULL;
PrintVideoFormat(vout, "original format", &vout->p->original);
return VLC_SUCCESS;
}
static void ThreadClean(vout_thread_t *vout) static void ThreadClean(vout_thread_t *vout)
{ {
/* Destroy the video filters2 */
filter_chain_Delete(vout->p->vfilter_chain);
/* Destroy translation tables */ /* Destroy translation tables */
if (!vout->p->b_error) { if (vout->p->display.vd) {
if (vout->p->decoder_pool) {
ThreadFlush(vout, true, INT64_MAX); ThreadFlush(vout, true, INT64_MAX);
vout_EndWrapper(vout); vout_EndWrapper(vout);
} }
vout_CloseWrapper(vout);
}
/* Detach subpicture unit from both input and vout */
spu_Attach(vout->p->p_spu, VLC_OBJECT(vout), false);
vlc_object_detach(vout->p->p_spu);
vout->p->dead = true;
vout_control_Dead(&vout->p->control);
} }
/***************************************************************************** /*****************************************************************************
...@@ -1050,28 +1027,7 @@ static void ThreadClean(vout_thread_t *vout) ...@@ -1050,28 +1027,7 @@ static void ThreadClean(vout_thread_t *vout)
static void *Thread(void *object) static void *Thread(void *object)
{ {
vout_thread_t *vout = object; vout_thread_t *vout = object;
bool has_wrapper;
/*
* Initialize thread
*/
has_wrapper = !vout_OpenWrapper(vout, vout->p->psz_module_name);
vlc_mutex_lock(&vout->p->change_lock);
if (has_wrapper)
vout->p->b_error = ThreadInit(vout);
else
vout->p->b_error = true;
/* signal the creation of the vout */
vout->p->b_ready = true;
vlc_cond_signal(&vout->p->change_wait);
if (vout->p->b_error)
goto exit_thread;
/* */
vout_interlacing_support_t interlacing = { vout_interlacing_support_t interlacing = {
.is_interlaced = false, .is_interlaced = false,
.date = mdate(), .date = mdate(),
...@@ -1080,22 +1036,23 @@ static void *Thread(void *object) ...@@ -1080,22 +1036,23 @@ static void *Thread(void *object)
.qtype = QTYPE_NONE, .qtype = QTYPE_NONE,
}; };
/*
* Main loop - it is not executed if an error occurred during
* initialization
*/
mtime_t deadline = VLC_TS_INVALID; mtime_t deadline = VLC_TS_INVALID;
while (!vout->p->b_done && !vout->p->b_error) { for (;;) {
vout_control_cmd_t cmd; vout_control_cmd_t cmd;
vlc_mutex_unlock(&vout->p->change_lock);
/* FIXME remove thoses ugly timeouts /* FIXME remove thoses ugly timeouts
*/ */
while (!vout_control_Pop(&vout->p->control, &cmd, deadline, 100000)) { while (!vout_control_Pop(&vout->p->control, &cmd, deadline, 100000)) {
/* TODO remove the lock when possible (ie when
* vout->p->fmt_* are not protected by it anymore) */
vlc_mutex_lock(&vout->p->change_lock);
switch(cmd.type) { switch(cmd.type) {
case VOUT_CONTROL_INIT:
if (ThreadInit(vout)) {
ThreadClean(vout);
return NULL;
}
break;
case VOUT_CONTROL_CLEAN:
ThreadClean(vout);
return NULL;
case VOUT_CONTROL_OSD_TITLE: case VOUT_CONTROL_OSD_TITLE:
ThreadDisplayOsdTitle(vout, cmd.u.string); ThreadDisplayOsdTitle(vout, cmd.u.string);
break; break;
...@@ -1145,46 +1102,11 @@ static void *Thread(void *object) ...@@ -1145,46 +1102,11 @@ static void *Thread(void *object)
default: default:
break; break;
} }
vlc_mutex_unlock(&vout->p->change_lock);
vout_control_cmd_Clean(&cmd); vout_control_cmd_Clean(&cmd);
} }
vlc_mutex_lock(&vout->p->change_lock);
/* */ ThreadManage(vout, &deadline, &interlacing, &postprocessing);
if (ThreadManage(vout, &deadline,
&interlacing, &postprocessing)) {
vout->p->b_error = true;
break;
}
} }
/*
* Error loop - wait until the thread destruction is requested
*
* XXX I wonder if we should periodically clean the decoder_fifo
* or have a way to prevent it filling up.
*/
while (vout->p->b_error && !vout->p->b_done)
vlc_cond_wait(&vout->p->change_wait, &vout->p->change_lock);
/* Clean thread */
ThreadClean(vout);
exit_thread:
/* Detach subpicture unit from both input and vout */
spu_Attach(vout->p->p_spu, VLC_OBJECT(vout), false);
vlc_object_detach(vout->p->p_spu);
vlc_mutex_unlock(&vout->p->change_lock);
if (has_wrapper)
vout_CloseWrapper(vout);
vout_control_Dead(&vout->p->control);
/* Destroy the video filters2 */
filter_chain_Delete(vout->p->vfilter_chain);
return NULL;
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -53,10 +53,7 @@ struct vout_thread_sys_t ...@@ -53,10 +53,7 @@ struct vout_thread_sys_t
/* Thread & synchronization */ /* Thread & synchronization */
vlc_thread_t thread; vlc_thread_t thread;
vlc_cond_t change_wait; bool dead;
bool b_ready;
bool b_done;
bool b_error;
vout_control_t control; vout_control_t control;
/* */ /* */
...@@ -124,8 +121,6 @@ struct vout_thread_sys_t ...@@ -124,8 +121,6 @@ struct vout_thread_sys_t
picture_fifo_t *decoder_fifo; picture_fifo_t *decoder_fifo;
bool is_decoder_pool_slow; bool is_decoder_pool_slow;
vout_chrono_t render; /**< picture render time estimator */ vout_chrono_t render; /**< picture render time estimator */
vlc_mutex_t change_lock; /**< thread change lock */
}; };
/* TODO to move them to vlc_vout.h */ /* TODO to move them to vlc_vout.h */
...@@ -146,7 +141,7 @@ int vout_OpenWrapper (vout_thread_t *, const char *); ...@@ -146,7 +141,7 @@ int vout_OpenWrapper (vout_thread_t *, const char *);
void vout_CloseWrapper(vout_thread_t *); void vout_CloseWrapper(vout_thread_t *);
int vout_InitWrapper(vout_thread_t *); int vout_InitWrapper(vout_thread_t *);
void vout_EndWrapper(vout_thread_t *); void vout_EndWrapper(vout_thread_t *);
int vout_ManageWrapper(vout_thread_t *); void vout_ManageWrapper(vout_thread_t *);
void vout_RenderWrapper(vout_thread_t *, picture_t *); void vout_RenderWrapper(vout_thread_t *, picture_t *);
void vout_DisplayWrapper(vout_thread_t *, picture_t *); void vout_DisplayWrapper(vout_thread_t *, picture_t *);
......
...@@ -179,7 +179,7 @@ void vout_EndWrapper(vout_thread_t *vout) ...@@ -179,7 +179,7 @@ void vout_EndWrapper(vout_thread_t *vout)
/***************************************************************************** /*****************************************************************************
* *
*****************************************************************************/ *****************************************************************************/
int vout_ManageWrapper(vout_thread_t *vout) void vout_ManageWrapper(vout_thread_t *vout)
{ {
vout_thread_sys_t *sys = vout->p; vout_thread_sys_t *sys = vout->p;
vout_display_t *vd = sys->display.vd; vout_display_t *vd = sys->display.vd;
...@@ -189,8 +189,6 @@ int vout_ManageWrapper(vout_thread_t *vout) ...@@ -189,8 +189,6 @@ int vout_ManageWrapper(vout_thread_t *vout)
if (reset_display_pool) if (reset_display_pool)
sys->display_pool = vout_display_Pool(vd, 3); sys->display_pool = vout_display_Pool(vd, 3);
return VLC_SUCCESS;
} }
/***************************************************************************** /*****************************************************************************
......
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