@ -43,37 +43,37 @@ run_buffering(void *data) {
assert ( db - > delay > 0 ) ;
for ( ; ; ) {
sc_mutex_lock ( & db - > b. mutex) ;
sc_mutex_lock ( & db - > mutex) ;
while ( ! db - > b. stopped & & sc_vecdeque_is_empty ( & db - > b . queue ) ) {
sc_cond_wait ( & db - > b. queue_cond, & db - > b . mutex ) ;
while ( ! db - > stopped & & sc_vecdeque_is_empty ( & db - > queue ) ) {
sc_cond_wait ( & db - > queue_cond, & db - > mutex ) ;
}
if ( db - > b. stopped) {
sc_mutex_unlock ( & db - > b. mutex) ;
if ( db - > stopped) {
sc_mutex_unlock ( & db - > mutex) ;
goto stopped ;
}
struct sc_delayed_frame dframe = sc_vecdeque_pop ( & db - > b. queue) ;
struct sc_delayed_frame dframe = sc_vecdeque_pop ( & db - > queue) ;
sc_tick max_deadline = sc_tick_now ( ) + db - > delay ;
// PTS (written by the server) are expressed in microseconds
sc_tick pts = SC_TICK_FROM_US ( dframe . frame - > pts ) ;
bool timed_out = false ;
while ( ! db - > b. stopped & & ! timed_out ) {
sc_tick deadline = sc_clock_to_system_time ( & db - > b. clock, pts )
while ( ! db - > stopped & & ! timed_out ) {
sc_tick deadline = sc_clock_to_system_time ( & db - > clock, pts )
+ db - > delay ;
if ( deadline > max_deadline ) {
deadline = max_deadline ;
}
timed_out =
! sc_cond_timedwait ( & db - > b. wait_cond, & db - > b . mutex , deadline ) ;
! sc_cond_timedwait ( & db - > wait_cond, & db - > mutex , deadline ) ;
}
bool stopped = db - > b. stopped;
sc_mutex_unlock ( & db - > b. mutex) ;
bool stopped = db - > stopped;
sc_mutex_unlock ( & db - > mutex) ;
if ( stopped ) {
sc_delayed_frame_destroy ( & dframe ) ;
@ -89,20 +89,20 @@ run_buffering(void *data) {
sc_delayed_frame_destroy ( & dframe ) ;
if ( ! ok ) {
LOGE ( " Delayed frame could not be pushed, stopping " ) ;
sc_mutex_lock ( & db - > b. mutex) ;
sc_mutex_lock ( & db - > mutex) ;
// Prevent to push any new frame
db - > b. stopped = true ;
sc_mutex_unlock ( & db - > b. mutex) ;
db - > stopped = true ;
sc_mutex_unlock ( & db - > mutex) ;
goto stopped ;
}
}
stopped :
assert ( db - > b. stopped) ;
assert ( db - > stopped) ;
// Flush queue
while ( ! sc_vecdeque_is_empty ( & db - > b. queue) ) {
struct sc_delayed_frame * dframe = sc_vecdeque_popref ( & db - > b. queue) ;
while ( ! sc_vecdeque_is_empty ( & db - > queue) ) {
struct sc_delayed_frame * dframe = sc_vecdeque_popref ( & db - > queue) ;
sc_delayed_frame_destroy ( dframe ) ;
}
@ -117,29 +117,29 @@ sc_delay_buffer_frame_sink_open(struct sc_frame_sink *sink,
struct sc_delay_buffer * db = DOWNCAST ( sink ) ;
( void ) ctx ;
bool ok = sc_mutex_init ( & db - > b. mutex) ;
bool ok = sc_mutex_init ( & db - > mutex) ;
if ( ! ok ) {
return false ;
}
ok = sc_cond_init ( & db - > b. queue_cond) ;
ok = sc_cond_init ( & db - > queue_cond) ;
if ( ! ok ) {
goto error_destroy_mutex ;
}
ok = sc_cond_init ( & db - > b. wait_cond) ;
ok = sc_cond_init ( & db - > wait_cond) ;
if ( ! ok ) {
goto error_destroy_queue_cond ;
}
sc_clock_init ( & db - > b. clock) ;
sc_vecdeque_init ( & db - > b. queue) ;
sc_clock_init ( & db - > clock) ;
sc_vecdeque_init ( & db - > queue) ;
if ( ! sc_frame_source_sinks_open ( & db - > frame_source , ctx ) ) {
goto error_destroy_wait_cond ;
}
ok = sc_thread_create ( & db - > b . thread , run_buffering , " scrcpy-dbuf " , db ) ;
ok = sc_thread_create ( & db - > thread , run_buffering , " scrcpy-dbuf " , db ) ;
if ( ! ok ) {
LOGE ( " Could not start buffering thread " ) ;
goto error_close_sinks ;
@ -150,11 +150,11 @@ sc_delay_buffer_frame_sink_open(struct sc_frame_sink *sink,
error_close_sinks :
sc_frame_source_sinks_close ( & db - > frame_source ) ;
error_destroy_wait_cond :
sc_cond_destroy ( & db - > b. wait_cond) ;
sc_cond_destroy ( & db - > wait_cond) ;
error_destroy_queue_cond :
sc_cond_destroy ( & db - > b. queue_cond) ;
sc_cond_destroy ( & db - > queue_cond) ;
error_destroy_mutex :
sc_mutex_destroy ( & db - > b. mutex) ;
sc_mutex_destroy ( & db - > mutex) ;
return false ;
}
@ -163,19 +163,19 @@ static void
sc_delay_buffer_frame_sink_close ( struct sc_frame_sink * sink ) {
struct sc_delay_buffer * db = DOWNCAST ( sink ) ;
sc_mutex_lock ( & db - > b. mutex) ;
db - > b. stopped = true ;
sc_cond_signal ( & db - > b. queue_cond) ;
sc_cond_signal ( & db - > b. wait_cond) ;
sc_mutex_unlock ( & db - > b. mutex) ;
sc_mutex_lock ( & db - > mutex) ;
db - > stopped = true ;
sc_cond_signal ( & db - > queue_cond) ;
sc_cond_signal ( & db - > wait_cond) ;
sc_mutex_unlock ( & db - > mutex) ;
sc_thread_join ( & db - > b . thread , NULL ) ;
sc_thread_join ( & db - > thread , NULL ) ;
sc_frame_source_sinks_close ( & db - > frame_source ) ;
sc_cond_destroy ( & db - > b. wait_cond) ;
sc_cond_destroy ( & db - > b. queue_cond) ;
sc_mutex_destroy ( & db - > b. mutex) ;
sc_cond_destroy ( & db - > wait_cond) ;
sc_cond_destroy ( & db - > queue_cond) ;
sc_mutex_destroy ( & db - > mutex) ;
}
static bool
@ -183,19 +183,19 @@ sc_delay_buffer_frame_sink_push(struct sc_frame_sink *sink,
const AVFrame * frame ) {
struct sc_delay_buffer * db = DOWNCAST ( sink ) ;
sc_mutex_lock ( & db - > b. mutex) ;
sc_mutex_lock ( & db - > mutex) ;
if ( db - > b. stopped) {
sc_mutex_unlock ( & db - > b. mutex) ;
if ( db - > stopped) {
sc_mutex_unlock ( & db - > mutex) ;
return false ;
}
sc_tick pts = SC_TICK_FROM_US ( frame - > pts ) ;
sc_clock_update ( & db - > b. clock, sc_tick_now ( ) , pts ) ;
sc_cond_signal ( & db - > b. wait_cond) ;
sc_clock_update ( & db - > clock, sc_tick_now ( ) , pts ) ;
sc_cond_signal ( & db - > wait_cond) ;
if ( db - > b. clock. count = = 1 ) {
sc_mutex_unlock ( & db - > b. mutex) ;
if ( db - > clock. count = = 1 ) {
sc_mutex_unlock ( & db - > mutex) ;
// First frame, push it immediately, for two reasons:
// - not to delay the opening of the scrcpy window
// - the buffering estimation needs at least two clock points, so it
@ -206,7 +206,7 @@ sc_delay_buffer_frame_sink_push(struct sc_frame_sink *sink,
struct sc_delayed_frame dframe ;
bool ok = sc_delayed_frame_init ( & dframe , frame ) ;
if ( ! ok ) {
sc_mutex_unlock ( & db - > b. mutex) ;
sc_mutex_unlock ( & db - > mutex) ;
return false ;
}
@ -214,16 +214,16 @@ sc_delay_buffer_frame_sink_push(struct sc_frame_sink *sink,
dframe . push_date = sc_tick_now ( ) ;
# endif
ok = sc_vecdeque_push ( & db - > b. queue, dframe ) ;
ok = sc_vecdeque_push ( & db - > queue, dframe ) ;
if ( ! ok ) {
sc_mutex_unlock ( & db - > b. mutex) ;
sc_mutex_unlock ( & db - > mutex) ;
LOG_OOM ( ) ;
return false ;
}
sc_cond_signal ( & db - > b. queue_cond) ;
sc_cond_signal ( & db - > queue_cond) ;
sc_mutex_unlock ( & db - > b. mutex) ;
sc_mutex_unlock ( & db - > mutex) ;
return true ;
}