void obs_encoder_stop(obs_encoder_t *encoder, void (*new_packet)(void *param, struct encoder_packet *packet), void *param) { bool last = false; size_t idx; if (!encoder) return; pthread_mutex_lock(&encoder->callbacks_mutex); idx = get_callback_idx(encoder, new_packet, param); if (idx != DARRAY_INVALID) { da_erase(encoder->callbacks, idx); last = (encoder->callbacks.num == 0); } pthread_mutex_unlock(&encoder->callbacks_mutex); if (last) { remove_connection(encoder); if (encoder->destroy_on_stop) obs_encoder_actually_destroy(encoder); } }
static inline bool obs_encoder_stop_internal(obs_encoder_t *encoder, void (*new_packet)(void *param, struct encoder_packet *packet), void *param) { bool last = false; size_t idx; pthread_mutex_lock(&encoder->callbacks_mutex); idx = get_callback_idx(encoder, new_packet, param); if (idx != DARRAY_INVALID) { da_erase(encoder->callbacks, idx); last = (encoder->callbacks.num == 0); } pthread_mutex_unlock(&encoder->callbacks_mutex); if (last) { remove_connection(encoder); encoder->initialized = false; if (encoder->destroy_on_stop) { pthread_mutex_unlock(&encoder->init_mutex); obs_encoder_actually_destroy(encoder); return true; } } return false; }
/* does not actually destroy the encoder until all connections to it have been * removed. (full reference counting really would have been superfluous) */ void obs_encoder_destroy(obs_encoder_t *encoder) { if (encoder) { bool destroy; obs_context_data_remove(&encoder->context); pthread_mutex_lock(&encoder->callbacks_mutex); destroy = encoder->callbacks.num == 0; if (!destroy) encoder->destroy_on_stop = true; pthread_mutex_unlock(&encoder->callbacks_mutex); if (destroy) obs_encoder_actually_destroy(encoder); } }