@@ -86,6 +86,7 @@ typedef struct {
8686 /* Statistics */
8787 ArvStreamStatistics statistics ;
8888
89+ gint n_buffer_in_use ;
8990} ArvUvStreamThreadData ;
9091
9192typedef struct {
@@ -129,6 +130,8 @@ typedef struct {
129130 gboolean is_aborting ;
130131
131132 ArvStreamStatistics * statistics ;
133+
134+ gint * n_buffer_in_use ;
132135} ArvUvStreamBufferContext ;
133136
134137G_DEFINE_TYPE_WITH_CODE (ArvUvStream , arv_uv_stream , ARV_TYPE_STREAM , G_ADD_PRIVATE (ArvUvStream ))
@@ -299,6 +302,7 @@ void LIBUSB_CALL arv_uv_stream_trailer_cb (struct libusb_transfer *transfer)
299302 ctx -> callback (ctx -> callback_data ,
300303 ARV_STREAM_CALLBACK_TYPE_BUFFER_DONE ,
301304 ctx -> buffer );
305+ g_atomic_int_dec_and_test (ctx -> n_buffer_in_use );
302306 ctx -> buffer = NULL ;
303307 }
304308
@@ -321,6 +325,7 @@ arv_uv_stream_buffer_context_new (ArvBuffer *buffer, ArvUvStreamThreadData *thre
321325 ctx -> callback_data = thread_data -> callback_data ;
322326 ctx -> transfer_completed_mtx = & thread_data -> stream_mtx ;
323327 ctx -> transfer_completed_event = & thread_data -> stream_event ;
328+ ctx -> n_buffer_in_use = & thread_data -> n_buffer_in_use ;
324329
325330 ctx -> leader_buffer = g_malloc (thread_data -> leader_size );
326331 ctx -> leader_transfer = libusb_alloc_transfer (0 );
@@ -387,6 +392,7 @@ arv_uv_stream_buffer_context_free (gpointer data)
387392 ctx -> callback (ctx -> callback_data ,
388393 ARV_STREAM_CALLBACK_TYPE_BUFFER_DONE ,
389394 ctx -> buffer );
395+ g_atomic_int_dec_and_test (ctx -> n_buffer_in_use );
390396 ctx -> buffer = NULL ;
391397 }
392398
@@ -509,11 +515,14 @@ arv_uv_stream_thread_async (void *data)
509515 ARV_UV_STREAM_POP_INPUT_BUFFER_TIMEOUT_MS * 1000 );
510516
511517 if ( buffer == NULL ) {
512- thread_data -> statistics .n_underruns += 1 ;
518+ if (thread_data -> n_buffer_in_use == 0 )
519+ thread_data -> statistics .n_underruns += 1 ;
513520 /* NOTE: n_ignored_bytes is not accumulated because it doesn't submit next USB transfer if
514521 * buffer is shortage. It means back pressure might be hanlded by USB slave side. */
515522 continue ;
516- }
523+ } else {
524+ g_atomic_int_inc (& thread_data -> n_buffer_in_use );
525+ }
517526
518527 ctx = g_hash_table_lookup ( ctx_lookup , buffer );
519528 if (!ctx ) {
@@ -612,10 +621,12 @@ arv_uv_stream_thread_sync (void *data)
612621 ARV_STREAM_CALLBACK_TYPE_BUFFER_DONE ,
613622 buffer );
614623 thread_data -> statistics .n_failures ++ ;
624+ g_atomic_int_dec_and_test (& thread_data -> n_buffer_in_use );
615625 buffer = NULL ;
616626 }
617627 buffer = arv_stream_pop_input_buffer (thread_data -> stream );
618628 if (buffer != NULL ) {
629+ g_atomic_int_inc (& thread_data -> n_buffer_in_use );
619630 buffer -> priv -> system_timestamp_ns = g_get_real_time () * 1000LL ;
620631 buffer -> priv -> status = ARV_BUFFER_STATUS_FILLING ;
621632 buffer -> priv -> received_size = 0 ;
@@ -671,6 +682,7 @@ arv_uv_stream_thread_sync (void *data)
671682 buffer );
672683 thread_data -> statistics .n_failures ++ ;
673684 thread_data -> statistics .n_ignored_bytes += transferred ;
685+ g_atomic_int_dec_and_test (& thread_data -> n_buffer_in_use );
674686 buffer = NULL ;
675687 } else {
676688 buffer -> priv -> status = ARV_BUFFER_STATUS_SUCCESS ;
@@ -683,6 +695,7 @@ arv_uv_stream_thread_sync (void *data)
683695 buffer );
684696 thread_data -> statistics .n_completed_buffers ++ ;
685697 thread_data -> statistics .n_transferred_bytes += transferred ;
698+ g_atomic_int_dec_and_test (& thread_data -> n_buffer_in_use );
686699 buffer = NULL ;
687700 }
688701 }
@@ -718,6 +731,7 @@ arv_uv_stream_thread_sync (void *data)
718731 thread_data -> callback (thread_data -> callback_data ,
719732 ARV_STREAM_CALLBACK_TYPE_BUFFER_DONE ,
720733 buffer );
734+ g_atomic_int_dec_and_test (& thread_data -> n_buffer_in_use );
721735 }
722736
723737 if (thread_data -> callback != NULL )
@@ -840,6 +854,7 @@ arv_uv_stream_start_thread (ArvStream *stream)
840854 thread_data -> payload_count = si_payload_count ;
841855 thread_data -> transfer1_size = si_transfer1_size ;
842856 thread_data -> trailer_size = si_trailer_size ;
857+ thread_data -> n_buffer_in_use = 0 ;
843858 thread_data -> cancel = FALSE;
844859
845860 switch (priv -> usb_mode ) {
@@ -887,7 +902,6 @@ arv_uv_stream_stop_thread (ArvStream *stream)
887902 si_control = 0x0 ;
888903 arv_device_write_memory (ARV_DEVICE (thread_data -> uv_device ),
889904 priv -> sirm_address + ARV_SIRM_CONTROL , sizeof (si_control ), & si_control , NULL );
890-
891905}
892906
893907/**
0 commit comments