From patchwork Thu Aug 29 23:14:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Liu X-Patchwork-Id: 14804 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id A8B3B4492A9 for ; Fri, 30 Aug 2019 02:14:58 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 91947687F45; Fri, 30 Aug 2019 02:14:58 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from smtpproxy19.qq.com (smtpproxy19.qq.com [184.105.206.84]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A30D1687F34 for ; Fri, 30 Aug 2019 02:14:51 +0300 (EEST) X-QQ-mid: bizesmtp25t1567120475tuguiu56 Received: from localhost (unknown [47.90.47.25]) by esmtp10.qq.com (ESMTP) with id ; Fri, 30 Aug 2019 07:14:34 +0800 (CST) X-QQ-SSF: 01100000008000K0ZQF1B00A0000000 X-QQ-FEAT: yGNZ4f+HfTBoTXD+VFXBP8BlWVuztPusH3jlWpNZQJC2UjTthsJvxfffKotiU k4aP3qEKsMRTQk8rakwGkiUKnwc6eCIHGi1EkMBefdZJ+eYe/uM2+Bvv7Laif2Cl2goG+lS GsUi6NkGRRJqJ6HxusSVFyvjrYAuFbs5L5BSpUKypTt5Hpo5wyb1Sw+141LKYfH8rQ6Ecip NSnf/YcejONlCAaXZMBQ6gTbjLsxZWuCSSz70xjnkw4wmafXwRnzL+zloS4SukEmn7Ymi2j AUBXOOyIhtN7GZiFMMjaToflcWUshumC8A4nJvtavc8YP1gVckXtB+SnA= X-QQ-GoodBg: 0 From: Steven Liu To: ffmpeg-devel@ffmpeg.org Date: Fri, 30 Aug 2019 07:14:28 +0800 Message-Id: <20190829231428.27877-2-lq@chinaffmpeg.org> X-Mailer: git-send-email 2.10.1.382.ga23ca1b.dirty In-Reply-To: <20190829231428.27877-1-lq@chinaffmpeg.org> References: <20190829231428.27877-1-lq@chinaffmpeg.org> X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:chinaffmpeg.org:qybgforeign:qybgforeign1 X-QQ-Bgrelay: 1 Subject: [FFmpeg-devel] [PATCH v2 2/2] avformat/hlsenc: avformat/hlsenc: reopen new http session for http_persistent 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: 7975 Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 66 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index c6bd664b92..d9b48f0e7c 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -118,6 +118,7 @@ typedef struct VariantStream { AVIOContext *out; int packets_written; int init_range_length; + uint8_t *temp_buffer; AVFormatContext *avf; AVFormatContext *vtt_avf; @@ -262,11 +263,12 @@ static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename, return err; } -static void hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char *filename) { +static int hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char *filename) { HLSContext *hls = s->priv_data; int http_base_proto = filename ? ff_is_http_proto(filename) : 0; + int ret = 0; if (!*pb) - return; + return ret; if (!http_base_proto || !hls->http_persistent || hls->key_info_file || hls->encrypt) { ff_format_io_close(s, pb); #if CONFIG_HTTP_PROTOCOL @@ -275,8 +277,10 @@ static void hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char *filename av_assert0(http_url_context); avio_flush(*pb); ffurl_shutdown(http_url_context, AVIO_FLAG_WRITE); + ret = ff_http_get_shutdown_status(http_url_context); #endif } + return ret; } static void set_http_options(AVFormatContext *s, AVDictionary **options, HLSContext *c) @@ -447,7 +451,6 @@ static void write_styp(AVIOContext *pb) static int flush_dynbuf(VariantStream *vs, int *range_length) { AVFormatContext *ctx = vs->avf; - uint8_t *buffer; if (!ctx->pb) { return AVERROR(EINVAL); @@ -458,15 +461,20 @@ static int flush_dynbuf(VariantStream *vs, int *range_length) avio_flush(ctx->pb); // write out to file - *range_length = avio_close_dyn_buf(ctx->pb, &buffer); + *range_length = avio_close_dyn_buf(ctx->pb, &vs->temp_buffer); ctx->pb = NULL; - avio_write(vs->out, buffer, *range_length); - av_free(buffer); + avio_write(vs->out, vs->temp_buffer, *range_length); // re-open buffer return avio_open_dyn_buf(&ctx->pb); } +static void reflush_dynbuf(VariantStream *vs, int *range_length) +{ + // re-open buffer + avio_write(vs->out, vs->temp_buffer, *range_length);; +} + static int hls_delete_old_segments(AVFormatContext *s, HLSContext *hls, VariantStream *vs) { @@ -1544,7 +1552,10 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs) fail: av_dict_free(&options); - hlsenc_io_close(s, (byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? &hls->m3u8_out : &vs->out, temp_filename); + ret = hlsenc_io_close(s, (byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? &hls->m3u8_out : &vs->out, temp_filename); + if (ret < 0) { + return ret; + } hlsenc_io_close(s, &hls->sub_m3u8_out, vs->vtt_m3u8_name); if (use_temp_file) { ff_rename(temp_filename, vs->m3u8_name, s); @@ -2399,7 +2410,16 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) if (ret < 0) { return ret; } - hlsenc_io_close(s, &vs->out, filename); + ret = hlsenc_io_close(s, &vs->out, filename); + if (ret < 0) { + av_log(s, AV_LOG_WARNING, "upload segment failed," + "and will retry upload by a new http session.\n"); + ff_format_io_close(s, &vs->out); + ret = hlsenc_io_open(s, &vs->out, filename, &options); + reflush_dynbuf(vs, &range_length); + ret = hlsenc_io_close(s, &vs->out, filename); + } + av_free(vs->temp_buffer); av_free(filename); } } @@ -2426,8 +2446,13 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) // if we're building a VOD playlist, skip writing the manifest multiple times, and just wait until the end if (hls->pl_type != PLAYLIST_TYPE_VOD) { if ((ret = hls_window(s, 0, vs)) < 0) { - av_free(old_filename); - return ret; + av_log(s, AV_LOG_WARNING, "update playlist failed, will retry once time\n"); + ff_format_io_close(s, &vs->out); + vs->out = NULL; + if ((ret = hls_window(s, 0, vs)) < 0) { + av_free(old_filename); + return ret; + } } } @@ -2579,6 +2604,20 @@ static int hls_write_trailer(struct AVFormatContext *s) vs->size = range_length; hlsenc_io_close(s, &vs->out, filename); + ret = hlsenc_io_close(s, &vs->out, filename); + if (ret < 0) { + av_log(s, AV_LOG_WARNING, "write segment failed, will close old handle and retry once time\n"); + ff_format_io_close(s, &vs->out); + ret = hlsenc_io_open(s, &vs->out, filename, &options); + if (ret < 0) { + av_log(s, AV_LOG_ERROR, "Failed to open file '%s'\n", vs->avf->url); + goto failed; + } + reflush_dynbuf(vs, &range_length); + ret = hlsenc_io_close(s, &vs->out, filename); + } + av_free(vs->temp_buffer); + failed: av_free(filename); av_write_trailer(oc); @@ -2610,7 +2649,12 @@ failed: ff_format_io_close(s, &vtt_oc->pb); avformat_free_context(vtt_oc); } - hls_window(s, 1, vs); + ret = hls_window(s, 1, vs); + if (ret < 0) { + av_log(s, AV_LOG_WARNING, "update playlist failed, will retry once time\n"); + ff_format_io_close(s, &vs->out); + hls_window(s, 1, vs); + } avformat_free_context(oc); vs->avf = NULL;