From patchwork Thu Jun 28 00:51:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Holljes X-Patchwork-Id: 9545 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:a02:104:0:0:0:0:0 with SMTP id c4-v6csp1483037jad; Wed, 27 Jun 2018 17:58:26 -0700 (PDT) X-Google-Smtp-Source: AAOMgpej4TRUmdyyqieCRU8oIDlbgSCh+17HaI/94KUqx999XhED7FoNgbfOjJUi2vEbzjKiIURv X-Received: by 2002:a1c:b4c1:: with SMTP id d184-v6mr545913wmf.126.1530147506401; Wed, 27 Jun 2018 17:58:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530147506; cv=none; d=google.com; s=arc-20160816; b=M0JbBrx3M4K/ZpKD+m8VlH5iwKkvLmuX4+OorRd/hB8u4PcFVWI/iTlLQgdyrBS/0F DDgiJuf1rE/nr+pwH1uHaxyEQhqVHJ6Pv0P3ohGzwjHKedmHVboX0C9JPJVNx4niQjVU n8dbPfGSi0zL/wN/hHqESGbUHh/VnJgheqcqKFHnGB26MWuT+1cI+DPloBY2eCCBOkWE 21AWsyV8iz6bSDiCHH9VhUUfozwHL6WCgsfnelhLjEsaxSn1bY3jP+lER+0BHYwMjbkx Vf8cOHUA1kEn7iwPcFjFYvzASpJOHRS+gbV87lBhpyYu+2dhJjgr/XQZ2IQnujsj+fT9 K1Iw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=3QO6UHGAM0A7VM54PYIn4b5PzDrbIcwMGQ8DaNPs0b0=; b=HSaeYWfxivoqiPy3hfYM5JvTw2/qxdZm97jRWYl6swJKTtykYQE8LH6cqXdlzITXEA yXBzTfnTrs4p4p3pWXL03Gm4bFRf85LAW2f346bmfarbr710WRjlVvIKSIqdUwdrHy0H hQvnC9qEv7BtrDsftn5AliKiQrH5cdQ70LdJz0fZS1A8VMHC8UCcBMiWePRwZvy4qSSt DVdI1xQ8+dkVwrS4VWnSI4Cu2ZzCRqTFp9ovjOE9p+ImF4xzbIpbqjhzBmgh9V2RV8+i rvdxJRtErF5GezDoPcvolg6njRY8htps8sfZzm85iBtmexaZ+70G8B5ECzwug9lARrCH Xt/Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@googlemail.com header.s=20161025 header.b=C1r2bodX; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=googlemail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id b62-v6si4996107wmc.115.2018.06.27.17.58.26; Wed, 27 Jun 2018 17:58:26 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@googlemail.com header.s=20161025 header.b=C1r2bodX; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=googlemail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id BC02168A626; Thu, 28 Jun 2018 03:58:23 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm0-f67.google.com (mail-wm0-f67.google.com [74.125.82.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id F1CFD68A09E for ; Thu, 28 Jun 2018 03:58:16 +0300 (EEST) Received: by mail-wm0-f67.google.com with SMTP id n17-v6so6696014wmh.2 for ; Wed, 27 Jun 2018 17:58:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=eRmNd2Wlwkb4J84kJ+TYMtftDdJbf8nLpMqCtxU8M2w=; b=C1r2bodX+JrCBmEkcu94yYtcAzeczgqkmwUiKmZkxlzoNtPCn5Tv2ERUdZ/GvsAWRB cTSbqogxjfSeTdKUW3TyeY1FV/MPlUJ2VB6omgQnBZk8T4eHkDY+7LEf1NHOlSu5NmnA V3Or2ZghJx28QLNhTGQ4wvDhgMFBKU4QRFqP6f6iFnWiKRJIRNEt8MSR5Q3+o2GRoPu6 4Bpo4B0BgEdKxsLplyXCMmMiTT5Cb472GnuVDyGdTrzkr0hCpjWEWvl4rBBp+4dmslIG GnyFaqK/iHzd1Z1bvkz8+P9gR8nisofnczzySCaEkBkFPDmYwKEhv6dvVWaVZ5/cx13E qTyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=eRmNd2Wlwkb4J84kJ+TYMtftDdJbf8nLpMqCtxU8M2w=; b=LDe6LWlbaTFoCHxxADaAwiCsWU1hOdh1OH3m8ZUPsOKDGvoAkNQ4qbcfcPfdbuvP9L DRUxFY57c4rJjerE6+IUSIGxZVlQ5IwXc6M+dhGtv0gNIKDf1RUrOhyr8+FMlcyiU2OK bRCGkB9uJ0lL+Yo19wx0q1HTqYAvdzYLMp+ye5DoG9NjUMRPdLXZcdoYvQ2HBtApqOl3 u589JujU/840gbDYCkguPEDFahhWftXE2KIXnhUphQVAQR/l+UUjrsk/Uzglj4jKYus6 PHTHdD++UKGWb7vEDS2MgfoNyuOwpejXmT2OG9LbJhNKLW0uEyrKh0JufGmMFfQ0JBN6 W0Yw== X-Gm-Message-State: APt69E0dEFovN0JH8iYRWJ3NxHA/qGPJH0uEG1rd864GWt5djWAq81IY GPgGoG6/oyef54hv49X7LDlwNA== X-Received: by 2002:a1c:a845:: with SMTP id r66-v6mr6831750wme.2.1530147105923; Wed, 27 Jun 2018 17:51:45 -0700 (PDT) Received: from localhost.localdomain ([46.5.2.0]) by smtp.gmail.com with ESMTPSA id a9-v6sm1363017wrq.1.2018.06.27.17.51.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Jun 2018 17:51:45 -0700 (PDT) From: Stephan Holljes To: ffmpeg-devel@ffmpeg.org Date: Thu, 28 Jun 2018 02:51:16 +0200 Message-Id: <20180628005117.18902-17-klaxa1337@googlemail.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180628005117.18902-1-klaxa1337@googlemail.com> References: <20180628005117.18902-1-klaxa1337@googlemail.com> Subject: [FFmpeg-devel] [PATCH 16/17] ffserver.c: Make fileserving independent of publisher to support streams that don't have mkv X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Stephan Holljes MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Stephan Holljes --- 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; } }