obs-outputs: Wait for packet before header output

Waiting for the first packet to arrive before sending the headers helps
prevent issues with certain types of encoders that may not get their
header/SEI until the first packet has been received.
master
jp9000 2014-12-18 12:38:37 -08:00
parent 1a95004fe8
commit 3412a0e190
2 changed files with 21 additions and 4 deletions

View File

@ -36,6 +36,7 @@ struct flv_output {
struct dstr path; struct dstr path;
FILE *file; FILE *file;
bool active; bool active;
bool sent_headers;
int64_t last_packet_ts; int64_t last_packet_ts;
}; };
@ -176,7 +177,6 @@ static bool flv_output_start(void *data)
/* write headers and start capture */ /* write headers and start capture */
stream->active = true; stream->active = true;
write_headers(stream);
obs_output_begin_data_capture(stream->output, 0); obs_output_begin_data_capture(stream->output, 0);
info("Writing FLV file '%s'...", stream->path.array); info("Writing FLV file '%s'...", stream->path.array);
@ -188,6 +188,11 @@ static void flv_output_data(void *data, struct encoder_packet *packet)
struct flv_output *stream = data; struct flv_output *stream = data;
struct encoder_packet parsed_packet; struct encoder_packet parsed_packet;
if (!stream->sent_headers) {
write_headers(stream);
stream->sent_headers = true;
}
if (packet->type == OBS_ENCODER_VIDEO) { if (packet->type == OBS_ENCODER_VIDEO) {
obs_parse_avc_packet(&parsed_packet, packet); obs_parse_avc_packet(&parsed_packet, packet);
write_packet(stream, &parsed_packet, false); write_packet(stream, &parsed_packet, false);

View File

@ -43,6 +43,7 @@ struct rtmp_stream {
pthread_mutex_t packets_mutex; pthread_mutex_t packets_mutex;
struct circlebuf packets; struct circlebuf packets;
bool sent_headers;
bool connecting; bool connecting;
pthread_t connect_thread; pthread_t connect_thread;
@ -155,6 +156,8 @@ static void rtmp_stream_stop(void *data)
} }
os_event_reset(stream->stop_event); os_event_reset(stream->stop_event);
stream->sent_headers = false;
} }
static inline void set_rtmp_str(AVal *val, const char *str) static inline void set_rtmp_str(AVal *val, const char *str)
@ -207,10 +210,15 @@ static int send_packet(struct rtmp_stream *stream,
return ret; return ret;
} }
static inline void send_headers(struct rtmp_stream *stream);
static bool send_remaining_packets(struct rtmp_stream *stream) static bool send_remaining_packets(struct rtmp_stream *stream)
{ {
struct encoder_packet packet; struct encoder_packet packet;
if (!stream->sent_headers)
send_headers(stream);
while (get_next_packet(stream, &packet)) while (get_next_packet(stream, &packet))
if (send_packet(stream, &packet, false) < 0) if (send_packet(stream, &packet, false) < 0)
return false; return false;
@ -230,6 +238,10 @@ static void *send_thread(void *data)
break; break;
if (!get_next_packet(stream, &packet)) if (!get_next_packet(stream, &packet))
continue; continue;
if (!stream->sent_headers)
send_headers(stream);
if (send_packet(stream, &packet, false) < 0) { if (send_packet(stream, &packet, false) < 0) {
disconnected = true; disconnected = true;
break; break;
@ -299,9 +311,9 @@ static void send_video_header(struct rtmp_stream *stream)
send_packet(stream, &packet, true); send_packet(stream, &packet, true);
} }
static void send_headers(struct rtmp_stream *stream) static inline void send_headers(struct rtmp_stream *stream)
{ {
send_meta_data(stream); stream->sent_headers = true;
send_audio_header(stream); send_audio_header(stream);
send_video_header(stream); send_video_header(stream);
} }
@ -351,7 +363,7 @@ static int init_send(struct rtmp_stream *stream)
} }
stream->active = true; stream->active = true;
send_headers(stream); send_meta_data(stream);
obs_output_begin_data_capture(stream->output, 0); obs_output_begin_data_capture(stream->output, 0);
return OBS_OUTPUT_SUCCESS; return OBS_OUTPUT_SUCCESS;