static void rtmp_stream_destroy(void *data) { struct rtmp_stream *stream = data; if (stopping(stream) && !connecting(stream)) { pthread_join(stream->send_thread, NULL); } else if (connecting(stream) || active(stream)) { if (stream->connecting) pthread_join(stream->connect_thread, NULL); os_event_signal(stream->stop_event); if (active(stream)) { os_sem_post(stream->send_sem); obs_output_end_data_capture(stream->output); pthread_join(stream->send_thread, NULL); } } if (stream) { free_packets(stream); dstr_free(&stream->path); dstr_free(&stream->key); dstr_free(&stream->username); dstr_free(&stream->password); dstr_free(&stream->encoder_name); os_event_destroy(stream->stop_event); os_sem_destroy(stream->send_sem); pthread_mutex_destroy(&stream->packets_mutex); circlebuf_free(&stream->packets); bfree(stream); } }
static void *send_thread(void *data) { struct rtmp_stream *stream = data; os_set_thread_name("rtmp-stream: send_thread"); while (os_sem_wait(stream->send_sem) == 0) { struct encoder_packet packet; if (stopping(stream) && stream->stop_ts == 0) { break; } if (!get_next_packet(stream, &packet)) continue; if (stopping(stream)) { if (can_shutdown_stream(stream, &packet)) { obs_free_encoder_packet(&packet); break; } } if (!stream->sent_headers) { if (!send_headers(stream)) { os_atomic_set_bool(&stream->disconnected, true); break; } } if (send_packet(stream, &packet, false, packet.track_idx) < 0) { os_atomic_set_bool(&stream->disconnected, true); break; } } if (disconnected(stream)) { info("Disconnected from %s", stream->path.array); } else { info("User stopped the stream"); } RTMP_Close(&stream->rtmp); if (!stopping(stream)) { pthread_detach(stream->send_thread); obs_output_signal_stop(stream->output, OBS_OUTPUT_DISCONNECTED); } else { obs_output_end_data_capture(stream->output); } free_packets(stream); os_event_reset(stream->stop_event); os_atomic_set_bool(&stream->active, false); stream->sent_headers = false; return NULL; }
void obs_output_signal_stop(obs_output_t *output, int code) { if (!obs_output_valid(output, "obs_output_signal_stop")) return; obs_output_end_data_capture(output); if ((output->reconnecting && code != OBS_OUTPUT_SUCCESS) || code == OBS_OUTPUT_DISCONNECTED) { output_reconnect(output); } else { if (output->delay_active) { output->delay_active = false; obs_output_end_data_capture(output); } signal_stop(output, code); } }
void obs_output_signal_stop(obs_output_t output, int code) { if (!output) return; obs_output_end_data_capture(output); if (code == OBS_OUTPUT_DISCONNECTED) output_reconnect(output); else signal_stop(output, code); }
static void ffmpeg_mux_stop(void *data) { struct ffmpeg_muxer *stream = data; if (stream->capturing) { obs_output_end_data_capture(stream->output); stream->capturing = false; } deactivate(stream); }
void obs_output_signal_stop(obs_output_t *output, int code) { if (!output) return; obs_output_end_data_capture(output); if ((output->reconnecting && code != OBS_OUTPUT_SUCCESS) || code == OBS_OUTPUT_DISCONNECTED) output_reconnect(output); else signal_stop(output, code); }
static void rtmp_stream_stop(void *data) { struct rtmp_stream *stream = data; if (stopping(stream)) return; if (connecting(stream)) pthread_join(stream->connect_thread, NULL); os_event_signal(stream->stop_event); if (active(stream)) { os_sem_post(stream->send_sem); obs_output_end_data_capture(stream->output); } }
static void flv_output_stop(void *data) { struct flv_output *stream = data; if (stream->active) { if (stream->file) write_file_info(stream->file, stream->last_packet_ts, os_ftelli64(stream->file)); fclose(stream->file); obs_output_end_data_capture(stream->output); stream->active = false; stream->sent_headers = false; info("FLV file output complete"); } }
static void rtmp_stream_destroy(void *data) { struct rtmp_stream *stream = data; if (stopping(stream) && !connecting(stream)) { pthread_join(stream->send_thread, NULL); } else if (connecting(stream) || active(stream)) { if (stream->connecting) pthread_join(stream->connect_thread, NULL); stream->stop_ts = 0; os_event_signal(stream->stop_event); if (active(stream)) { os_sem_post(stream->send_sem); obs_output_end_data_capture(stream->output); pthread_join(stream->send_thread, NULL); } } free_packets(stream); dstr_free(&stream->path); dstr_free(&stream->key); dstr_free(&stream->username); dstr_free(&stream->password); dstr_free(&stream->encoder_name); dstr_free(&stream->bind_ip); os_event_destroy(stream->stop_event); os_sem_destroy(stream->send_sem); pthread_mutex_destroy(&stream->packets_mutex); circlebuf_free(&stream->packets); #ifdef TEST_FRAMEDROPS circlebuf_free(&stream->droptest_info); #endif os_event_destroy(stream->buffer_space_available_event); os_event_destroy(stream->buffer_has_data_event); os_event_destroy(stream->socket_available_event); os_event_destroy(stream->send_thread_signaled_exit); pthread_mutex_destroy(&stream->write_buf_mutex); if (stream->write_buf) bfree(stream->write_buf); bfree(stream); }
static void output_reconnect(struct obs_output *output) { int ret; if (!reconnecting(output)) { output->reconnect_retry_cur_sec = output->reconnect_retry_sec; output->reconnect_retries = 0; } if (output->reconnect_retries >= output->reconnect_retry_max) { output->stop_code = OBS_OUTPUT_DISCONNECTED; os_atomic_set_bool(&output->reconnecting, false); if (delay_active(output)) os_atomic_set_bool(&output->delay_active, false); obs_output_end_data_capture(output); return; } if (!reconnecting(output)) { os_atomic_set_bool(&output->reconnecting, true); os_event_reset(output->reconnect_stop_event); } if (output->reconnect_retries) { output->reconnect_retry_cur_sec *= 2; if (output->reconnect_retry_cur_sec > MAX_RETRY_SEC) output->reconnect_retry_cur_sec = MAX_RETRY_SEC; } output->reconnect_retries++; output->stop_code = OBS_OUTPUT_DISCONNECTED; ret = pthread_create(&output->reconnect_thread, NULL, &reconnect_thread, output); if (ret < 0) { blog(LOG_WARNING, "Failed to create reconnect thread"); os_atomic_set_bool(&output->reconnecting, false); } else { blog(LOG_INFO, "Output '%s': Reconnecting in %d seconds..", output->context.name, output->reconnect_retry_sec); signal_reconnect(output); } }
void obs_output_signal_stop(obs_output_t *output, int code) { if (!obs_output_valid(output, "obs_output_signal_stop")) return; output->stop_code = code; if (can_reconnect(output, code)) { if (delay_active(output)) os_atomic_inc_long(&output->delay_restart_refs); obs_output_end_data_capture_internal(output, false); output_reconnect(output); } else { if (delay_active(output)) os_atomic_set_bool(&output->delay_active, false); obs_output_end_data_capture(output); } }
static void output_reconnect(struct obs_output *output) { int ret; if (!output->reconnecting) { output->reconnect_retry_cur_sec = output->reconnect_retry_sec; output->reconnect_retries = 0; } if (output->reconnect_retries >= output->reconnect_retry_max) { output->reconnecting = false; if (output->delay_active) { output->delay_active = false; obs_output_end_data_capture(output); } signal_stop(output, OBS_OUTPUT_DISCONNECTED); return; } if (!output->reconnecting) { output->reconnecting = true; os_event_reset(output->reconnect_stop_event); } if (output->reconnect_retries) { output->reconnect_retry_cur_sec *= 2; } output->reconnect_retries++; ret = pthread_create(&output->reconnect_thread, NULL, &reconnect_thread, output); if (ret < 0) { blog(LOG_WARNING, "Failed to create reconnect thread"); output->reconnecting = false; signal_stop(output, OBS_OUTPUT_DISCONNECTED); } else { blog(LOG_INFO, "Output '%s': Reconnecting in %d seconds..", output->context.name, output->reconnect_retry_sec); signal_reconnect(output); } }
static void rtmp_stream_stop(void *data) { struct rtmp_stream *stream = data; void *ret; os_event_signal(stream->stop_event); if (stream->connecting) pthread_join(stream->connect_thread, &ret); if (stream->active) { obs_output_end_data_capture(stream->output); os_sem_post(stream->send_sem); pthread_join(stream->send_thread, &ret); RTMP_Close(&stream->rtmp); } os_event_reset(stream->stop_event); stream->sent_headers = false; }
void obs_output_actual_stop(obs_output_t *output, bool force, uint64_t ts) { bool call_stop = true; bool was_reconnecting = false; if (stopping(output)) return; os_event_reset(output->stopping_event); was_reconnecting = reconnecting(output) && !delay_active(output); if (reconnecting(output)) { os_event_signal(output->reconnect_stop_event); if (output->reconnect_thread_active) pthread_join(output->reconnect_thread, NULL); } if (force) { if (delay_active(output)) { call_stop = delay_capturing(output); os_atomic_set_bool(&output->delay_active, false); os_atomic_set_bool(&output->delay_capturing, false); output->stop_code = OBS_OUTPUT_SUCCESS; obs_output_end_data_capture(output); os_event_signal(output->stopping_event); } else { call_stop = data_active(output); } } else { call_stop = data_active(output); } if (output->context.data && call_stop) { output->info.stop(output->context.data, ts); } else if (was_reconnecting) { output->stop_code = OBS_OUTPUT_SUCCESS; signal_stop(output); os_event_signal(output->stopping_event); } }
void obs_output_actual_stop(obs_output_t *output, bool force) { output->stopped = true; os_event_signal(output->reconnect_stop_event); if (output->reconnect_thread_active) pthread_join(output->reconnect_thread, NULL); if (output->context.data) output->info.stop(output->context.data); if (output->video) log_frame_info(output); if (output->delay_active && (force || !output->delay_restart_refs)) { output->delay_active = false; obs_output_end_data_capture(output); } if (force || !output->delay_active) signal_stop(output, OBS_OUTPUT_SUCCESS); }