From patchwork Mon Dec 18 08:47:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liu Steven X-Patchwork-Id: 6852 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.79.195 with SMTP id r64csp15751jad; Mon, 18 Dec 2017 00:48:56 -0800 (PST) X-Google-Smtp-Source: ACJfBovIKKXd3cljxYPkPglkAYectLpjehi7p7EHO6IY+5T0coz5ttK2srGcLwadpzzlhZog/3zL X-Received: by 10.223.141.226 with SMTP id o89mr9220241wrb.95.1513586936674; Mon, 18 Dec 2017 00:48:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513586936; cv=none; d=google.com; s=arc-20160816; b=LE7RMdYsk69J8QBmFyG5JGjvS0h+T4UPgYmufzJrrlAU3I9PN0K5upCPAp9jGf5Dpk Fp5RUVUGSJJWbQmSKMYDUiSuytxVtEnPLc+Dfk1QKbsLXmCJrjFCWHaUf00Vs0NNMAr8 WYjRbrwXkjLaKCIGvoQJ6As92jGyP4T00Z2AYOEmyzPweJ+4IDLiFTYxiEC1RnmImewj zBwZ0eM6z+QPaQMvyxGzkr5/HIVLV2lg0Ie3naCI6kPNbeOQY1Haua+gvN2ENpxbDSyy TLFyFX76Htr2LRXHFXHzt7RJufqWE8bl4IzIf/OmSTpH7wxgseG9dCRrHqOG6E9wXZ7P fQKw== 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=xbG3vEU4YEIHWPj1feXllh+ZSTgkKMdfH0SPbiiOYcI=; b=XUvpKZesV0ygjhKD8nUmB9+vntkjYG/Y7I4XV3sKFdHCIVjRiC24n1tmT5sfQ00qgC zbgYem5ccpS0NLyJMkrlXbEy0xhJTnCoEa9HcBxcxp/u+mduv9RKwC0oaTh4fmh9k0rX yIj+mZmr74ZCFqu/tXJydLNYuSstrf3UP4XbdxT2fv0G0DK7uX7rH4nNykOeAOsDnT4O 1ffOfMaeoyPdbAhF2Jl+AFYlAATJ0zqa9f4WSk3nKKh/KBtZPKjr6oxbz7412ry9E8s3 NwONhBq2bGeSUOTtwMflFLRGYN6UKFQFLsMhpru4R3Q2S3GGF9TKtBp0z1G18LmVytZe ns4A== 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 a64si7916000wmd.147.2017.12.18.00.48.56; Mon, 18 Dec 2017 00:48:56 -0800 (PST) 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 5BD9D689C8F; Mon, 18 Dec 2017 10:48:45 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from smtpbg340.qq.com (smtpbg340.qq.com [14.17.44.35]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0AD3C6804E8 for ; Mon, 18 Dec 2017 10:48:42 +0200 (EET) X-QQ-mid: bizesmtp14t1513586832tjgw0n39 Received: from localhost (unknown [47.90.47.25]) by esmtp4.qq.com (ESMTP) with id ; Mon, 18 Dec 2017 16:47:12 +0800 (CST) X-QQ-SSF: 01100000008000F0FJ90B00A0000000 X-QQ-FEAT: q8Y1EW3MbKcjbEzt5D9C3ZTdwAweVnNTIiBJwGjzXrJpNVIeimrWyXhMB/M5v btbo9HaSkCEKxmNOpRlevemiWodWXbPu/Ec2IG9hnWpli5OE9r0cTQDcYSPXZWZTbGLJI4d TJDBxfPH++CtfTDhwSdO/BqV4obJx9q06pdPwt9Cmuj/fsO+IV7oqa4MKUazRvrI7IT2z15 W9VD0budM64QDBfPNWFaJAXkK165hSolG7ry/EzsEL2cHlXBlGBNOBszO38jSm9NJLkcZje 9KOS2CBlsqaAzAyasJHCxIk4w= X-QQ-GoodBg: 0 From: Steven Liu To: ffmpeg-devel@ffmpeg.org Date: Mon, 18 Dec 2017 16:47:05 +0800 Message-Id: <20171218084705.13885-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 1/4] avformat/hlsenc: fix first fragment mp4 do not split bug 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" fix ticket id: 6888 Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 72 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index e3442c368f..f51fec1030 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -352,6 +352,29 @@ static void write_styp(AVIOContext *pb) ffio_wfourcc(pb, "msix"); } +static int flush_dynbuf(VariantStream *vs, int *range_length) +{ + AVFormatContext *ctx = vs->avf; + uint8_t *buffer; + + if (!ctx->pb) { + return AVERROR(EINVAL); + } + + // flush + av_write_frame(ctx, NULL); + avio_flush(ctx->pb); + + // write out to file + *range_length = avio_close_dyn_buf(ctx->pb, &buffer); + ctx->pb = NULL; + avio_write(vs->out, buffer, *range_length); + av_free(buffer); + + // re-open buffer + return avio_open_dyn_buf(&ctx->pb); +} + static int hls_delete_old_segments(AVFormatContext *s, HLSContext *hls, VariantStream *vs) { @@ -677,7 +700,9 @@ static int hls_mux_init(AVFormatContext *s, VariantStream *vs) if ((ret = avio_open_dyn_buf(&oc->pb)) < 0) return ret; - if ((ret = s->io_open(s, &vs->out, vs->base_output_dirname, AVIO_FLAG_WRITE, &options)) < 0) { + ret = hlsenc_io_open(s, &vs->out, vs->base_output_dirname, &options); + av_dict_free(&options); + if (ret < 0) { av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", vs->fmp4_init_filename); return ret; } @@ -1404,9 +1429,10 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) av_dict_free(&options); if (err < 0) return err; - } else + } else if (c->segment_type != SEGMENT_TYPE_FMP4) { if ((err = hlsenc_io_open(s, &oc->pb, oc->filename, &options)) < 0) goto fail; + } if (vs->vtt_basename) { set_http_options(s, &options, c); if ((err = hlsenc_io_open(s, &vtt_oc->pb, vtt_oc->filename, &options)) < 0) @@ -1414,9 +1440,7 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) } av_dict_free(&options); - if (c->segment_type == SEGMENT_TYPE_FMP4 && !(c->flags & HLS_SINGLE_FILE)) { - write_styp(oc->pb); - } else { + if (c->segment_type != SEGMENT_TYPE_FMP4) { /* We only require one PAT/PMT per segment. */ if (oc->oformat->priv_class && oc->priv_data) { char period[21]; @@ -1780,7 +1804,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) vs->size = new_start_pos - vs->start_pos; if (!byterange_mode) { - if (hls->segment_type == SEGMENT_TYPE_FMP4 && !vs->init_range_length) { + if (hls->segment_type == SEGMENT_TYPE_FMP4) { + if (!vs->init_range_length) { avio_flush(oc->pb); range_length = avio_close_dyn_buf(oc->pb, &buffer); avio_write(vs->out, buffer, range_length); @@ -1789,6 +1814,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) vs->packets_written = 0; ff_format_io_close(s, &vs->out); hlsenc_io_close(s, &vs->out, vs->base_output_dirname); + } } else { hlsenc_io_close(s, &oc->pb, oc->filename); } @@ -1807,7 +1833,20 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) vs->number--; } - if (!vs->fmp4_init_mode || byterange_mode) + if (hls->segment_type == SEGMENT_TYPE_FMP4) { + ret = hlsenc_io_open(s, &vs->out, vs->avf->filename, NULL); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Failed to open file '%s'\n", + vs->avf->filename); + return ret; + } + write_styp(vs->out); + ret = flush_dynbuf(vs, &range_length); + if (ret < 0) { + return ret; + } + ff_format_io_close(s, &vs->out); + } ret = hls_append_segment(s, hls, vs, vs->duration, vs->start_pos, vs->size); vs->start_pos = new_start_pos; if (ret < 0) { @@ -1861,6 +1900,7 @@ static int hls_write_trailer(struct AVFormatContext *s) AVFormatContext *vtt_oc = NULL; char *old_filename = NULL; int i; + int ret = 0; VariantStream *vs = NULL; for (i = 0; i < hls->nb_varstreams; i++) { @@ -1873,11 +1913,25 @@ static int hls_write_trailer(struct AVFormatContext *s) if (!old_filename) { return AVERROR(ENOMEM); } - + if ( hls->segment_type == SEGMENT_TYPE_FMP4) { + int range_length = 0; + ret = hlsenc_io_open(s, &vs->out, vs->avf->filename, NULL); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Failed to open file '%s'\n", vs->avf->filename); + return AVERROR(ENOENT); + } + write_styp(vs->out); + ret = flush_dynbuf(vs, &range_length); + if (ret < 0) { + return ret; + } + ff_format_io_close(s, &vs->out); + } av_write_trailer(oc); if (oc->pb) { vs->size = avio_tell(vs->avf->pb) - vs->start_pos; + if (hls->segment_type != SEGMENT_TYPE_FMP4) ff_format_io_close(s, &oc->pb); if ((hls->flags & HLS_TEMP_FILE) && oc->filename[0]) { @@ -2238,10 +2292,8 @@ static int hls_init(AVFormatContext *s) } } - if (hls->segment_type != SEGMENT_TYPE_FMP4 || hls->flags & HLS_SINGLE_FILE) { if ((ret = hls_start(s, vs)) < 0) goto fail; - } } fail: