From patchwork Mon Jul 31 04:03:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liu Steven X-Patchwork-Id: 4526 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.1.85 with SMTP id 82csp1961835vsb; Sun, 30 Jul 2017 21:04:11 -0700 (PDT) X-Received: by 10.223.150.108 with SMTP id c41mr10776168wra.115.1501473851374; Sun, 30 Jul 2017 21:04:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501473851; cv=none; d=google.com; s=arc-20160816; b=ZeNESYoAwgoghjg040sBhCdrz5bSoYs0CIvFDDl6Xkr2S34Ki3SMHLrpm/EY4AkR1P CsqZZFL38Y/xY8aSpDH0o3TSkUG9EzeBZrpgDSgpVNplTqfbXo0mHlGplfEVOhvGKzmp A4o2/q08mB8+oS2/Sao/4GcNaKMfIb+BeRLblXb1ju0JQ6rdWQBS5SCMRWCwPL/nP66X zobzzMnUIMCs9TVY8/Mni136pocCihmCqO9BQGWXJiTQp6gF0BLf6W7KZzjpSEr1ogoP laJUeW0TOAqyZE6eZcuVY6LG0obTaB9vsY33FUPTNYmQ/ETdqW/qgEDz3rqEuySOXEHS +NwA== 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:feedback-id:message-id:date:to:from :delivered-to:arc-authentication-results; bh=+GzHL6/ciR1at7Go4mDeVLROnymcGnacZOC2wYKS3NQ=; b=q3NpvcG5OfhmpArjdqIcTyGI+u9Li/VMwdxmD+IXFCtatianv5b+JlClHOpW0kFWZu rt7osU6BePl9DHxsmiDKlBLSprhUyYE1qgmWCeoJQE0wXzfOmmpjxr1i3PNL5Jvo46Oj FTIFtC7lRBL3DOAuXTEfBxZzdbABZJ34aUtHTJPcK5p6Lcep2pm5nGT/AlBdma1HJxDl KaP/cHscmOFGumgJvG8xUXjQOiRQ1tik+McoGyOZeeBYMuXwyTjjFKQHj/EqhkXsX3Hr LcTIAclFxhSkIyU9Ij9vlNTG7jY/PylnI2RxlbIEbmdvF66TG2RadP1gUAJLKGPNQ5t0 7biQ== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id n35si6588113wrn.214.2017.07.30.21.04.10; Sun, 30 Jul 2017 21:04:11 -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; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4700A68A0C1; Mon, 31 Jul 2017 07:04:05 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from smtpbg291.qq.com (smtpbg291.qq.com [113.108.11.223]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6340068A077 for ; Mon, 31 Jul 2017 07:03:57 +0300 (EEST) X-QQ-mid: bizesmtp1t1501473798t872zq1sz Received: from localhost (unknown [47.90.47.25]) by esmtp4.qq.com (ESMTP) with id ; Mon, 31 Jul 2017 12:03:17 +0800 (CST) X-QQ-SSF: 01100000004000F0FG50B00A0000000 X-QQ-FEAT: /A5Igf99+LRFWL6N7UI2PlGtmae1tNmtTVLP2h87cQjZOfO9u210zAHQ0D23t OS4e8re2Rbl5moez4P7Gz7KQtkEq9DKMQ9Puk18kkLO6UJNDALvVGHHZMzO1j00b11lToGy 58Jsjn0ZB3A8RCQJqArzd6PAT3WCGpp1PJicQ6Gwb3zFciB+0jtyOpTTKnAFErPXHlt3CP1 OH4k/eLC6W06uZux+x7/7xh32kPgcs09seFnWPT6MLb61Y6DFvuN134vlfYF6/k03FjdiOk wqbC466aQezRXo X-QQ-GoodBg: 0 From: Steven Liu To: ffmpeg-devel@ffmpeg.org Date: Mon, 31 Jul 2017 12:03:15 +0800 Message-Id: <20170731040315.9496-1-lq@chinaffmpeg.org> X-Mailer: git-send-email 2.10.1.382.ga23ca1b.dirty X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:chinaffmpeg.org:qybgforeign:qybgforeign4 X-QQ-Bgrelay: 1 Subject: [FFmpeg-devel] [PATCH] avformat/hlsenc: support fmp4 single file mode 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: Steven Liu , Steven Liu MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" add byterange mode of the hls fmp4 Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 72 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index f98f041..cfc28d2 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -531,6 +531,7 @@ static int hls_mux_init(AVFormatContext *s) HLSContext *hls = s->priv_data; AVFormatContext *oc; AVFormatContext *vtt_oc = NULL; + int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0); int i, ret; ret = avformat_alloc_output_context2(&hls->avf, hls->oformat, NULL, NULL); @@ -584,7 +585,11 @@ static int hls_mux_init(AVFormatContext *s) hls->fmp4_init_mode = 0; if (hls->segment_type == SEGMENT_TYPE_FMP4) { - hls->fmp4_init_mode = 1; + if (byterange_mode) { + hls->fmp4_init_mode = 0; + } else { + hls->fmp4_init_mode = 1; + } if ((ret = s->io_open(s, &oc->pb, hls->base_output_dirname, AVIO_FLAG_WRITE, NULL)) < 0) { av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", hls->fmp4_init_filename); return ret; @@ -980,9 +985,6 @@ static void write_m3u8_head_block(HLSContext *hls, AVIOContext *out, int version } avio_printf(out, "#EXT-X-TARGETDURATION:%d\n", target_duration); avio_printf(out, "#EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence); - if (hls->segment_type == SEGMENT_TYPE_FMP4) { - avio_printf(out, "#EXT-X-MAP:URI=\"%s\"\n", hls->fmp4_init_filename); - } av_log(hls, AV_LOG_VERBOSE, "EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence); } @@ -1066,13 +1068,21 @@ static int hls_window(AVFormatContext *s, int last) avio_printf(out, "#EXT-X-DISCONTINUITY\n"); } - if (hls->flags & HLS_ROUND_DURATIONS) - avio_printf(out, "#EXTINF:%ld,\n", lrint(en->duration)); - else - avio_printf(out, "#EXTINF:%f,\n", en->duration); - if (byterange_mode) - avio_printf(out, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n", - en->size, en->pos); + if ((hls->segment_type == SEGMENT_TYPE_FMP4) && (en == hls->segments)) { + avio_printf(out, "#EXT-X-MAP:URI=\"%s\"", hls->fmp4_init_filename); + if (hls->flags & HLS_SINGLE_FILE) { + avio_printf(out, ",BYTERANGE=\"%"PRId64"@%"PRId64"\"", en->size, en->pos); + } + avio_printf(out, "\n"); + } else { + if (hls->flags & HLS_ROUND_DURATIONS) + avio_printf(out, "#EXTINF:%ld,\n", lrint(en->duration)); + else + avio_printf(out, "#EXTINF:%f,\n", en->duration); + if (byterange_mode) + avio_printf(out, "#EXT-X-BYTERANGE:%"PRId64"@%"PRId64"\n", + en->size, en->pos); + } if (hls->flags & HLS_PROGRAM_DATE_TIME) { time_t tt, wrongsecs; int milli; @@ -1097,9 +1107,11 @@ static int hls_window(AVFormatContext *s, int last) avio_printf(out, "#EXT-X-PROGRAM-DATE-TIME:%s.%03d%s\n", buf0, milli, buf1); prog_date_time += en->duration; } - if (hls->baseurl) - avio_printf(out, "%s", hls->baseurl); - avio_printf(out, "%s\n", en->filename); + if (!((hls->segment_type == SEGMENT_TYPE_FMP4) && (en == hls->segments))) { + if (hls->baseurl) + avio_printf(out, "%s", hls->baseurl); + avio_printf(out, "%s\n", en->filename); + } } if (last && (hls->flags & HLS_OMIT_ENDLIST)==0) @@ -1262,7 +1274,7 @@ static int hls_start(AVFormatContext *s) } av_dict_free(&options); - if (c->segment_type == SEGMENT_TYPE_FMP4) { + if (c->segment_type == SEGMENT_TYPE_FMP4 && !(c->flags & HLS_SINGLE_FILE)) { write_styp(oc->pb); } else { /* We only require one PAT/PMT per segment. */ @@ -1315,15 +1327,10 @@ static int hls_write_header(AVFormatContext *s) const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt(s); const char *vtt_pattern = "%d.vtt"; AVDictionary *options = NULL; - int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0); int basename_size; int vtt_basename_size; if (hls->segment_type == SEGMENT_TYPE_FMP4) { - if (byterange_mode) { - av_log(s, AV_LOG_WARNING, "Have not support fmp4 byterange mode yet now\n"); - return AVERROR_PATCHWELCOME; - } pattern = "%d.m4s"; } if ((hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) || @@ -1400,8 +1407,13 @@ static int hls_write_header(AVFormatContext *s) goto fail; } } else { - if (hls->flags & HLS_SINGLE_FILE) - pattern = ".ts"; + if (hls->flags & HLS_SINGLE_FILE) { + if (hls->segment_type == SEGMENT_TYPE_FMP4) { + pattern = ".m4s"; + } else { + pattern = ".ts"; + } + } if (hls->use_localtime) { basename_size = strlen(s->filename) + strlen(pattern_localtime_fmt) + 1; @@ -1462,7 +1474,6 @@ static int hls_write_header(AVFormatContext *s) } } if(hls->has_subtitle) { - if (hls->flags & HLS_SINGLE_FILE) vtt_pattern = ".vtt"; vtt_basename_size = strlen(s->filename) + strlen(vtt_pattern) + 1; @@ -1490,6 +1501,10 @@ static int hls_write_header(AVFormatContext *s) av_strlcat(hls->vtt_basename, vtt_pattern, vtt_basename_size); } + if ((hls->flags & HLS_SINGLE_FILE) && (hls->segment_type == SEGMENT_TYPE_FMP4)) { + hls->fmp4_init_filename = av_strdup(hls->basename); + } + if ((ret = hls_mux_init(s)) < 0) goto fail; @@ -1504,7 +1519,7 @@ static int hls_write_header(AVFormatContext *s) } } - if (hls->segment_type != SEGMENT_TYPE_FMP4) { + if (hls->segment_type != SEGMENT_TYPE_FMP4 || hls->flags & HLS_SINGLE_FILE) { if ((ret = hls_start(s)) < 0) goto fail; } @@ -1643,7 +1658,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) hls->number--; } - if (!hls->fmp4_init_mode) + if (!hls->fmp4_init_mode || byterange_mode) ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, hls->size); hls->start_pos = new_start_pos; @@ -1679,9 +1694,10 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) return ret; } - if ((ret = hls_window(s, 0)) < 0) { - return ret; - } + if (!hls->fmp4_init_mode || byterange_mode) + if ((ret = hls_window(s, 0)) < 0) { + return ret; + } } ret = ff_write_chained(oc, stream_index, pkt, s, 0);