From: <bc...@us...> - 2007-12-12 22:13:54
|
Revision: 1306 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1306&view=rev Author: bcholew Date: 2007-12-12 14:13:49 -0800 (Wed, 12 Dec 2007) Log Message: ----------- Use iaxc_lock to protect struct iaxc_call calls[] array from concurrent access by libvidcap's callback thread and main processing thread. Make put_iaxc_lock() not static - to allow video.c to call it. Add try_iaxc_lock(). Modified Paths: -------------- trunk/lib/iaxclient_lib.c trunk/lib/video.c Modified: trunk/lib/iaxclient_lib.c =================================================================== --- trunk/lib/iaxclient_lib.c 2007-12-07 15:41:28 UTC (rev 1305) +++ trunk/lib/iaxclient_lib.c 2007-12-12 22:13:49 UTC (rev 1306) @@ -138,8 +138,13 @@ MUTEXLOCK(&iaxc_lock); } +int try_iaxc_lock() +{ + return MUTEXTRYLOCK(&iaxc_lock); +} + // Unlock the library and post any events that were queued in the meantime -static void put_iaxc_lock() +void put_iaxc_lock() { iaxc_event *prev, *event; Modified: trunk/lib/video.c =================================================================== --- trunk/lib/video.c 2007-12-07 15:41:28 UTC (rev 1305) +++ trunk/lib/video.c 2007-12-12 22:13:49 UTC (rev 1306) @@ -123,6 +123,10 @@ extern int test_mode; extern struct iaxc_call * calls; +/* to prevent clearing a call while in capture callback */ +extern __inline int try_iaxc_lock(); +extern __inline void put_iaxc_lock(); + EXPORT unsigned int iaxc_get_video_prefs(void) { return vinfo.prefs; @@ -643,22 +647,37 @@ 0); /* timestamp (ms) */ } + /* Don't block waiting for this lock. If the main thread has the lock + * for the purpose of dumping the call, it may request that video + * capture stop - which would block until this callback returned. + */ + if ( try_iaxc_lock() ) + { + /* give it a second try */ + iaxc_millisleep(5); + if ( try_iaxc_lock() ) + { + fprintf(stderr, "skipping processing of a video frame\n"); + return 0; + } + } + if ( selected_call < 0 ) - return 0; + goto callback_done; call = &calls[selected_call]; if ( !call || !(call->state & (IAXC_CALL_STATE_COMPLETE | IAXC_CALL_STATE_OUTGOING)) ) { - return 0; + goto callback_done; } if ( call->vformat == 0 ) { fprintf(stderr, "video format not set for call %d\n", selected_call); - return -1; + goto callback_failed; } if ( !need_encode ) @@ -675,7 +694,7 @@ call->vencoder = 0; } - return 0; + goto callback_done; } else { @@ -694,7 +713,8 @@ fprintf(stderr, "ERROR: failed to create codec " "for format 0x%08x\n", call->vformat); - return -1; + + goto callback_failed; } fprintf(stderr, "created encoder codec %s\n", @@ -706,7 +726,7 @@ &slice_set) ) { fprintf(stderr, "failed to encode captured video\n"); - return -1; + goto callback_failed; } } @@ -725,7 +745,7 @@ if ( !call->session ) { fprintf(stderr, "not sending video to sessionless call\n"); - return -1; + goto callback_failed; } for ( i = 0; i < slice_set.num_slices; ++i ) @@ -753,7 +773,7 @@ fprintf(stderr, "failed sending slice call %d " "size %d\n", selected_call, slice_set.size[i]); - return -1; + goto callback_failed; } /* More statistics */ @@ -769,7 +789,13 @@ maybe_send_stats(call); +callback_done: + put_iaxc_lock(); return 0; + +callback_failed: + put_iaxc_lock(); + return -1; } static int prepare_for_capture() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |