static void *connect_thread(void *data) { struct rtmp_stream *stream = data; int ret; os_set_thread_name("rtmp-stream: connect_thread"); if (!init_connect(stream)) { obs_output_signal_stop(stream->output, OBS_OUTPUT_BAD_PATH); return NULL; } ret = try_connect(stream); if (ret != OBS_OUTPUT_SUCCESS) { obs_output_signal_stop(stream->output, ret); info("Connection to %s failed: %d", stream->path.array, ret); } if (!stopping(stream)) pthread_detach(stream->connect_thread); os_atomic_set_bool(&stream->connecting, false); return NULL; }
static void *send_thread(void *data) { struct rtmp_stream *stream = data; bool disconnected = false; while (os_sem_wait(stream->send_sem) == 0) { struct encoder_packet packet; if (os_event_try(stream->stop_event) != EAGAIN) break; if (!get_next_packet(stream, &packet)) continue; if (send_packet(stream, &packet, false) < 0) { disconnected = true; break; } } if (!disconnected && !send_remaining_packets(stream)) disconnected = true; if (disconnected) { blog(LOG_INFO, "Disconnected from %s", stream->path.array); free_packets(stream); } if (os_event_try(stream->stop_event) == EAGAIN) { pthread_detach(stream->send_thread); obs_output_signal_stop(stream->output, OBS_OUTPUT_DISCONNECTED); } stream->active = false; return NULL; }
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; }
static void signal_failure(struct ffmpeg_muxer *stream) { int ret = deactivate(stream); int code; switch (ret) { case FFM_UNSUPPORTED: code = OBS_OUTPUT_UNSUPPORTED; break; default: code = OBS_OUTPUT_ERROR; } obs_output_signal_stop(stream->output, code); stream->capturing = false; }
static void *connect_thread(void *data) { struct rtmp_stream *stream = data; int ret = try_connect(stream); if (ret != OBS_OUTPUT_SUCCESS) { obs_output_signal_stop(stream->output, ret); info("Connection to %s failed: %d", stream->path.array, ret); } if (os_event_try(stream->stop_event) == EAGAIN) pthread_detach(stream->connect_thread); stream->connecting = false; return NULL; }