0
0
mirror of https://github.com/obsproject/obs-studio.git synced 2024-09-20 04:42:18 +02:00

libobs: Fix potential crash on output stop

In certain circumstances where the output was stopping, and where data
took a long enough time to send (such as when using an encoding preset
that causes high CPU usage), the output would sometimes still send data
even after it was stopped, typically causing the output to crash.
This commit is contained in:
jp9000 2014-12-31 01:30:54 -08:00
parent 8e1549820b
commit 244280335b
2 changed files with 19 additions and 5 deletions

View File

@ -395,6 +395,7 @@ struct obs_output {
int total_frames; int total_frames;
bool active; bool active;
volatile bool stopped;
video_t *video; video_t *video;
audio_t *audio; audio_t *audio;
obs_encoder_t *video_encoder; obs_encoder_t *video_encoder;

View File

@ -159,6 +159,8 @@ bool obs_output_start(obs_output_t *output)
if (!output) if (!output)
return false; return false;
output->stopped = false;
success = output->info.start(output->context.data); success = output->info.start(output->context.data);
if (success && output->video) { if (success && output->video) {
@ -207,6 +209,8 @@ static void log_frame_info(struct obs_output *output)
void obs_output_stop(obs_output_t *output) void obs_output_stop(obs_output_t *output)
{ {
if (output) { if (output) {
output->stopped = true;
os_event_signal(output->reconnect_stop_event); os_event_signal(output->reconnect_stop_event);
if (output->reconnect_thread_active) if (output->reconnect_thread_active)
pthread_join(output->reconnect_thread, NULL); pthread_join(output->reconnect_thread, NULL);
@ -617,7 +621,8 @@ static inline void send_interleaved(struct obs_output *output)
output->total_frames++; output->total_frames++;
da_erase(output->interleaved_packets, 0); da_erase(output->interleaved_packets, 0);
output->info.encoded_packet(output->context.data, &out); if (!output->stopped)
output->info.encoded_packet(output->context.data, &out);
obs_free_encoder_packet(&out); obs_free_encoder_packet(&out);
} }
@ -787,7 +792,8 @@ static void interleave_packets(void *data, struct encoder_packet *packet)
static void default_encoded_callback(void *param, struct encoder_packet *packet) static void default_encoded_callback(void *param, struct encoder_packet *packet)
{ {
struct obs_output *output = param; struct obs_output *output = param;
output->info.encoded_packet(output->context.data, packet); if (!output->stopped)
output->info.encoded_packet(output->context.data, packet);
if (packet->type == OBS_ENCODER_VIDEO) if (packet->type == OBS_ENCODER_VIDEO)
output->total_frames++; output->total_frames++;
@ -796,10 +802,18 @@ static void default_encoded_callback(void *param, struct encoder_packet *packet)
static void default_raw_video_callback(void *param, struct video_data *frame) static void default_raw_video_callback(void *param, struct video_data *frame)
{ {
struct obs_output *output = param; struct obs_output *output = param;
output->info.raw_video(output->context.data, frame); if (!output->stopped)
output->info.raw_video(output->context.data, frame);
output->total_frames++; output->total_frames++;
} }
static void default_raw_audio_callback(void *param, struct audio_data *frames)
{
struct obs_output *output = param;
if (!output->stopped)
output->info.raw_audio(output->context.data, frames);
}
static void hook_data_capture(struct obs_output *output, bool encoded, static void hook_data_capture(struct obs_output *output, bool encoded,
bool has_video, bool has_audio) bool has_video, bool has_audio)
{ {
@ -831,8 +845,7 @@ static void hook_data_capture(struct obs_output *output, bool encoded,
if (has_audio) if (has_audio)
audio_output_connect(output->audio, audio_output_connect(output->audio,
get_audio_conversion(output), get_audio_conversion(output),
output->info.raw_audio, default_raw_audio_callback, output);
output->context.data);
} }
} }