[FFmpeg-devel] [PATCH 16/17] ffserver.c: Make fileserving independent of publisher to support streams that don't have mkv
Stephan Holljes
klaxa1337 at googlemail.com
Thu Jun 28 03:51:16 EEST 2018
Signed-off-by: Stephan Holljes <klaxa1337 at googlemail.com>
---
ffserver.c | 70 +++++++++++++++++++++++++++++++++++-------------------
1 file changed, 45 insertions(+), 25 deletions(-)
diff --git a/ffserver.c b/ffserver.c
index 38f10b7..3b3451e 100644
--- a/ffserver.c
+++ b/ffserver.c
@@ -51,7 +51,9 @@
struct ReadInfo {
struct PublisherContext *pub;
+ struct StreamConfig *config;
AVFormatContext *ifmt_ctx;
+ struct FileserverContext *fs;
char *input_uri;
char *server_name;
};
@@ -96,6 +98,10 @@ void *read_thread(void *arg)
AVStream *in_stream, *out_stream;
AVRational tb = {1, AV_TIME_BASE};
AVStream *stream;
+ int stream_formats[FMT_NB] = { 0 };
+
+ for (i = 0; i < info->config->nb_formats; i++)
+ stream_formats[info->config->formats[i]] = 1;
if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
av_log(ifmt_ctx, AV_LOG_ERROR, "Could not get input stream info.\n");
@@ -124,9 +130,9 @@ void *read_thread(void *arg)
}
}
- if (info->pub->stream_formats[FMT_HLS]) {
- snprintf(playlist_filename, 1024, "%s/%s/%s_hls.m3u8", info->server_name, info->pub->stream_name,
- info->pub->stream_name);
+ if (stream_formats[FMT_HLS]) {
+ snprintf(playlist_filename, 1024, "%s/%s/%s_hls.m3u8", info->server_name, info->config->stream_name,
+ info->config->stream_name);
avformat_alloc_output_context2(&ofmt_ctx[FMT_HLS], NULL, "hls", playlist_filename);
if (!ofmt_ctx[FMT_HLS]) {
@@ -164,9 +170,9 @@ void *read_thread(void *arg)
av_log(ofmt_ctx[FMT_HLS], AV_LOG_DEBUG, "Initialized hls.\n");
}
- if (info->pub->stream_formats[FMT_DASH]) {
- snprintf(playlist_filename, 1024, "%s/%s/%s_dash.mpd", info->server_name, info->pub->stream_name,
- info->pub->stream_name);
+ if (stream_formats[FMT_DASH]) {
+ snprintf(playlist_filename, 1024, "%s/%s/%s_dash.mpd", info->server_name, info->config->stream_name,
+ info->config->stream_name);
avformat_alloc_output_context2(&ofmt_ctx[FMT_DASH], NULL, "dash", playlist_filename);
if (!ofmt_ctx[FMT_DASH]) {
@@ -235,7 +241,7 @@ void *read_thread(void *arg)
now = av_gettime_relative() - start;
}
- if (info->pub->stream_formats[FMT_MATROSKA]) {
+ if (stream_formats[FMT_MATROSKA]) {
// keyframe or first Segment or audio_only and more than AUDIO_ONLY_SEGMENT_SECONDS passed since last cut
if ((pkt.flags & AV_PKT_FLAG_KEY && pkt.stream_index == video_idx) || !seg ||
(audio_only && pts - last_cut >= AUDIO_ONLY_SEGMENT_SECONDS * AV_TIME_BASE)) {
@@ -282,7 +288,7 @@ void *read_thread(void *arg)
}
}
- if (info->pub->stream_formats[FMT_DASH]) {
+ if (stream_formats[FMT_DASH]) {
pts_tmp = pkt.pts;
dts_tmp = pkt.dts;
pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, ofmt_ctx[FMT_DASH]->streams[pkt.stream_index]->time_base,
@@ -301,7 +307,7 @@ void *read_thread(void *arg)
}
}
- if (info->pub->stream_formats[FMT_HLS]) {
+ if (stream_formats[FMT_HLS]) {
pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, ofmt_ctx[FMT_HLS]->streams[pkt.stream_index]->time_base,
AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, ofmt_ctx[FMT_HLS]->streams[pkt.stream_index]->time_base,
@@ -322,21 +328,27 @@ void *read_thread(void *arg)
av_log(seg->fmt_ctx, AV_LOG_ERROR, "Error occurred during read: %s\n", av_err2str(ret));
goto end;
}
-
- segment_close(seg);
- publisher_push_segment(info->pub, seg);
- publish(info->pub);
+ if (stream_formats[FMT_MATROSKA]) {
+ segment_close(seg);
+ publisher_push_segment(info->pub, seg);
+ publish(info->pub);
+ }
end:
avformat_close_input(&ifmt_ctx);
- info->pub->shutdown = 1;
+ if (info->pub)
+ info->pub->shutdown = 1;
for (i = 0; i < FMT_NB; i++) {
if (ofmt_ctx[i]) {
av_write_trailer(ofmt_ctx[i]);
avformat_free_context(ofmt_ctx[i]);
}
}
+ if (info->fs) {
+ sleep(BUFFER_SECS);
+ info->fs->shutdown = 1;
+ }
return NULL;
}
@@ -471,11 +483,15 @@ void *accept_thread(void *arg)
if (info->pubs[i] && !info->pubs[i]->shutdown)
shutdown = 0;
}
+ if (info->fs && !info->fs->shutdown)
+ shutdown = 0;
if (shutdown)
break;
for (i = 0; i < config->nb_streams; i++) {
- publisher_gen_status_json(info->pubs[i], status);
- av_log(server, AV_LOG_INFO, status);
+ if (info->pubs[i]) {
+ publisher_gen_status_json(info->pubs[i], status);
+ av_log(server, AV_LOG_INFO, status);
+ }
}
client = NULL;
av_log(server, AV_LOG_DEBUG, "Accepting new clients.\n");
@@ -496,7 +512,7 @@ void *accept_thread(void *arg)
resource = client->resource;
snprintf(requested_file, 1024, "%s", resource);
for (i = 0; i < config->nb_streams; i++) {
- stream_name = info->pubs[i]->stream_name;
+ stream_name = info->config->streams[i].stream_name;
// skip leading '/' ---v
if (resource && strlen(resource) > strlen(stream_name)
&& !strncmp(resource + 1, stream_name, strlen(stream_name))) {
@@ -550,7 +566,7 @@ void *accept_thread(void *arg)
// try to serve file
- if (requested_file[0]) {
+ if (info->fs && requested_file[0]) {
snprintf(sanitized_file, 1024, "%s", requested_file);
resource = requested_file;
while(resource && *resource == '/') {
@@ -811,6 +827,8 @@ void *run_server(void *arg) {
int stream_formats[FMT_NB] = { 0 };
rinfo.input_uri = config->streams[stream_index].input_uri;
rinfo.server_name = config->server_name;
+ rinfo.config = &config->streams[stream_index];
+ rinfo.fs = fs;
for (i = 0; i < config->streams[stream_index].nb_formats; i++)
stream_formats[config->streams[stream_index].formats[i]] = 1;
@@ -831,6 +849,15 @@ void *run_server(void *arg) {
rinfo.pub = pub;
rinfos[stream_index] = rinfo;
+
+ ret = pthread_create(&r_thread, NULL, read_thread, &rinfos[stream_index]);
+ if (ret != 0) {
+ pub->shutdown = 1;
+ r_thread = 0;
+ goto end;
+ }
+ r_threads[stream_index] = r_thread;
+
if (stream_formats[FMT_MATROSKA]) {
w_threads = av_mallocz_array(pub->nb_threads, sizeof(pthread_t));
if (!w_threads) {
@@ -856,13 +883,6 @@ void *run_server(void *arg) {
}
}
w_threads_p[stream_index] = w_threads;
- ret = pthread_create(&r_thread, NULL, read_thread, &rinfos[stream_index]);
- if (ret != 0) {
- pub->shutdown = 1;
- r_thread = 0;
- goto end;
- }
- r_threads[stream_index] = r_thread;
}
}
--
2.18.0
More information about the ffmpeg-devel
mailing list