bool obs_output_initialize_encoders(obs_output_t *output, uint32_t flags) { bool encoded, has_video, has_audio, has_service; size_t num_mixes = num_audio_mixes(output); if (!obs_output_valid(output, "obs_output_initialize_encoders")) return false; if (active(output)) return delay_active(output); convert_flags(output, flags, &encoded, &has_video, &has_audio, &has_service); if (!encoded) return false; if (has_service && !obs_service_initialize(output->service, output)) return false; if (has_video && !obs_encoder_initialize(output->video_encoder)) return false; if (has_audio && !initialize_audio_encoders(output, num_mixes)) return false; if (has_video && has_audio) pair_encoders(output, num_mixes); return true; }
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); } }
bool obs_output_begin_data_capture(obs_output_t *output, uint32_t flags) { bool encoded, has_video, has_audio, has_service; if (!obs_output_valid(output, "obs_output_begin_data_capture")) return false; if (delay_active(output)) return begin_delayed_capture(output); if (active(output)) return false; output->total_frames = 0; convert_flags(output, flags, &encoded, &has_video, &has_audio, &has_service); if (!can_begin_data_capture(output, encoded, has_video, has_audio, has_service)) return false; os_atomic_set_bool(&output->data_active, true); hook_data_capture(output, encoded, has_video, has_audio); if (has_service) obs_service_activate(output->service); do_output_signal(output, "activate"); os_atomic_set_bool(&output->active, true); if (reconnecting(output)) { signal_reconnect_success(output); os_atomic_set_bool(&output->reconnecting, false); } else if (delay_active(output)) { do_output_signal(output, "starting"); } else { signal_start(output); } return true; }
uint64_t obs_output_get_total_bytes(const obs_output_t *output) { if (!obs_output_valid(output, "obs_output_get_total_bytes")) return 0; if (!output->info.get_total_bytes) return 0; if (delay_active(output) && !delay_capturing(output)) return 0; return output->info.get_total_bytes(output->context.data); }
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); } }
static void obs_output_end_data_capture_internal(obs_output_t *output, bool signal) { int ret; if (!obs_output_valid(output, "obs_output_end_data_capture")) return; if (!active(output) || !data_active(output)) { if (signal) { signal_stop(output); output->stop_code = OBS_OUTPUT_SUCCESS; } return; } if (delay_active(output)) { os_atomic_set_bool(&output->delay_capturing, false); if (!os_atomic_load_long(&output->delay_restart_refs)) { os_atomic_set_bool(&output->delay_active, false); } else { os_event_signal(output->stopping_event); return; } } os_atomic_set_bool(&output->data_active, false); if (output->video) log_frame_info(output); if (data_capture_ending(output)) pthread_join(output->end_data_capture_thread, NULL); os_atomic_set_bool(&output->end_data_capture_thread_active, true); ret = pthread_create(&output->end_data_capture_thread, NULL, end_data_capture_thread, output); if (ret != 0) { blog(LOG_WARNING, "Failed to create end_data_capture_thread " "for output '%s'!", output->context.name); end_data_capture_thread(output); } if (signal) { signal_stop(output); output->stop_code = OBS_OUTPUT_SUCCESS; } }
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); } }
bool obs_output_can_begin_data_capture(const obs_output_t *output, uint32_t flags) { bool encoded, has_video, has_audio, has_service; if (!obs_output_valid(output, "obs_output_can_begin_data_capture")) return false; if (delay_active(output)) return true; if (active(output)) return false; if (data_capture_ending(output)) pthread_join(output->end_data_capture_thread, NULL); convert_flags(output, flags, &encoded, &has_video, &has_audio, &has_service); return can_begin_data_capture(output, encoded, has_video, has_audio, has_service); }