From 1fb01424d70e6b99f63d56d5243ef0d6dc458f0d Mon Sep 17 00:00:00 2001 From: Olivier Aubert Date: Mon, 26 Jan 2009 16:57:48 +0100 Subject: [PATCH] embedded snapshot: use condition variable Let's see if this fits courmisch's standards... --- include/vlc_vout.h | 2 + src/control/mediacontrol_audio_video.c | 57 +++++++++++++++++++------- src/video_output/vout_intf.c | 34 ++++----------- 3 files changed, 54 insertions(+), 39 deletions(-) diff --git a/include/vlc_vout.h b/include/vlc_vout.h index e0d3ecb8a1..adab0a6655 100644 --- a/include/vlc_vout.h +++ b/include/vlc_vout.h @@ -714,6 +714,8 @@ typedef struct snapshot_t { int i_height; /* In pixels */ int i_datasize; /* In bytes */ mtime_t date; /* Presentation time */ + vlc_cond_t p_condvar; + vlc_mutex_t p_mutex; } snapshot_t; /**@}*/ diff --git a/src/control/mediacontrol_audio_video.c b/src/control/mediacontrol_audio_video.c index f2367de399..17660340fe 100644 --- a/src/control/mediacontrol_audio_video.c +++ b/src/control/mediacontrol_audio_video.c @@ -56,7 +56,6 @@ mediacontrol_snapshot( mediacontrol_Instance *self, mediacontrol_Exception *exception ) { (void)a_position; - vlc_object_t* p_cache; vout_thread_t* p_vout; input_thread_t *p_input; mediacontrol_RGBPicture *p_pic = NULL; @@ -67,6 +66,13 @@ mediacontrol_snapshot( mediacontrol_Instance *self, libvlc_exception_init( &ex ); mediacontrol_exception_init( exception ); + + p_snapshot = malloc( sizeof( snapshot_t ) ); + if( ! p_snapshot ) + { + RAISE_NULL( mediacontrol_InternalException, "Cannot allocate snapshot" ); + } + p_input = libvlc_get_input_thread( self->p_media_player, &ex ); if( ! p_input ) { @@ -79,26 +85,49 @@ mediacontrol_snapshot( mediacontrol_Instance *self, { RAISE_NULL( mediacontrol_InternalException, "No video output" ); } - p_cache = vlc_object_create( p_input, sizeof( vlc_object_t ) ); - if( p_cache == NULL ) - { - vlc_object_release( p_vout ); - vlc_object_release( p_input ); - RAISE_NULL( mediacontrol_InternalException, "Out of memory" ); - } - snprintf( path, 255, "object:%p", p_cache ); + + /* TODO: + vlc_mutex_lock (&lock); + mutex_cleanup_push (&lock); // release the mutex in case of cancellation + + while (!foobar) + vlc_cond_wait (&wait, &lock); + + --- foobar is now true, do something about it here -- + + vlc_cleanup_run (); // release the mutex + */ + + snprintf( path, 255, "object:%p", p_snapshot ); var_SetString( p_vout, "snapshot-path", path ); var_SetString( p_vout, "snapshot-format", "png" ); - vlc_object_lock( p_cache ); + vlc_mutex_init( &p_snapshot->p_mutex ); + vlc_cond_init( &p_snapshot->p_condvar ); + + vlc_mutex_lock( &p_snapshot->p_mutex ); + mutex_cleanup_push( &p_snapshot->p_mutex ); + + /* Use p_snapshot address as sentinel against spurious vlc_object_wait wakeups. + + If a legitimate wakeup occurs, then p_snapshot->p_data will hold either + NULL (in case of error) or a pointer to valid data. */ + p_snapshot->p_data = ( char* )p_snapshot; + vout_Control( p_vout, VOUT_SNAPSHOT ); + while ( p_snapshot->p_data == ( char* )p_snapshot ) + { + vlc_cond_wait( &p_snapshot->p_condvar, &p_snapshot->p_mutex ); + } + vlc_cleanup_pop(); + vlc_object_release( p_vout ); - p_snapshot = ( snapshot_t* ) p_cache->p_private; - vlc_object_unlock( p_cache ); - vlc_object_release( p_cache ); + vlc_mutex_unlock( &p_snapshot->p_mutex ); + vlc_cond_destroy( &p_snapshot->p_condvar ); + vlc_mutex_destroy( &p_snapshot->p_mutex ); - if( p_snapshot ) + if( p_snapshot->p_data ) { /* Note: p_snapshot->p_data is directly used, not copied. Thus do not free it here. */ diff --git a/src/video_output/vout_intf.c b/src/video_output/vout_intf.c index 0f837ff244..dccbc7ec6b 100644 --- a/src/video_output/vout_intf.c +++ b/src/video_output/vout_intf.c @@ -638,13 +638,12 @@ int vout_Snapshot( vout_thread_t *p_vout, picture_t *p_pic ) */ if( b_embedded_snapshot ) { - vlc_object_t* p_dest = p_obj; block_t *p_block; - snapshot_t *p_snapshot; + snapshot_t *p_snapshot = p_obj; size_t i_size; - vlc_object_lock( p_dest ); - p_dest->p_private = NULL; + vlc_mutex_lock( &p_snapshot->p_mutex ); + p_snapshot->p_data = NULL; /* Save the snapshot to a memory zone */ p_block = image_Write( p_image, p_pic, &fmt_in, &fmt_out ); @@ -652,23 +651,11 @@ int vout_Snapshot( vout_thread_t *p_vout, picture_t *p_pic ) { msg_Err( p_vout, "Could not get snapshot" ); image_HandlerDelete( p_image ); - vlc_object_signal_unlocked( p_dest ); - vlc_object_unlock( p_dest ); + vlc_cond_signal( &p_snapshot->p_condvar ); + vlc_mutex_unlock( &p_snapshot->p_mutex ); return VLC_EGENERIC; } - /* Copy the p_block data to a snapshot structure */ - /* FIXME: get the timestamp */ - p_snapshot = malloc( sizeof( snapshot_t ) ); - if( !p_snapshot ) - { - block_Release( p_block ); - image_HandlerDelete( p_image ); - vlc_object_signal_unlocked( p_dest ); - vlc_object_unlock( p_dest ); - return VLC_ENOMEM; - } - i_size = p_block->i_buffer; p_snapshot->i_width = fmt_out.i_width; @@ -679,21 +666,18 @@ int vout_Snapshot( vout_thread_t *p_vout, picture_t *p_pic ) if( !p_snapshot->p_data ) { block_Release( p_block ); - free( p_snapshot ); image_HandlerDelete( p_image ); - vlc_object_signal_unlocked( p_dest ); - vlc_object_unlock( p_dest ); + vlc_cond_signal( &p_snapshot->p_condvar ); + vlc_mutex_unlock( &p_snapshot->p_mutex ); return VLC_ENOMEM; } memcpy( p_snapshot->p_data, p_block->p_buffer, p_block->i_buffer ); - p_dest->p_private = p_snapshot; - block_Release( p_block ); /* Unlock the object */ - vlc_object_signal_unlocked( p_dest ); - vlc_object_unlock( p_dest ); + vlc_cond_signal( &p_snapshot->p_condvar ); + vlc_mutex_unlock( &p_snapshot->p_mutex ); image_HandlerDelete( p_image ); return VLC_SUCCESS; -- 2.39.2