From patchwork Mon Dec 17 14:23:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrian X-Patchwork-Id: 11449 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 3815A44D517 for ; Mon, 17 Dec 2018 16:30:28 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5D66168AAFE; Mon, 17 Dec 2018 16:30:28 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mx-out.tlen.pl (mx-out.tlen.pl [193.222.135.175]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 055B568A722 for ; Mon, 17 Dec 2018 16:30:21 +0200 (EET) Received: (wp-smtpd smtp.tlen.pl 23159 invoked from network); 17 Dec 2018 15:23:41 +0100 Received: from afax252.neoplus.adsl.tpnet.pl (HELO [192.168.1.44]) (adrian-007@o2.pl@[95.49.23.252]) (envelope-sender ) by smtp.tlen.pl (WP-SMTPD) with ECDHE-RSA-AES256-GCM-SHA384 encrypted SMTP for ; 17 Dec 2018 15:23:41 +0100 To: FFmpeg development discussions and patches From: Adrian Message-ID: Date: Mon, 17 Dec 2018 15:23:41 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.1 MIME-Version: 1.0 Content-Language: en-US X-WP-MailID: 88e53ce84f720de54726e79e3948c704 X-WP-AV: skaner antywirusowy Poczty o2 X-WP-SPAM: NO 000000B [QXPk] Subject: [FFmpeg-devel] [PATCH] Fix usage of temp_file flag in hls_flags option 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Hello, after upgrading FFmpeg from 4.0 to 4.1 I noticed that temp files in HLS muxed stopped working. It looks like a regression introduced by 223d2bde22ce33dcbcb6f17f234b609cb98f1fb6. I've prepared a patch and tested it cross-compiling for my project's target platform (ARM, Buildroot) and it seems like everything is in order. I ran regression tests and nothing seems to be broken. Please review it and possibly include this patch. Regards Adrian Guzowski From 41a7a0d24942ab21338be6a74eec2c7a329d610f Mon Sep 17 00:00:00 2001 From: Adrian Guzowski Date: Mon, 17 Dec 2018 14:23:48 +0100 Subject: [PATCH] Fix usage of temp_file flag in hls_flags option. This is a regression introduced by 223d2bde22ce33dcbcb6f17f234b609cb98f1fb6. It appears that regression was introduced in 4.1, 4.0.x does not share this behaviour. Temp files were not created for MPEG-TS segments options - HLS_TEMP_FILE flag was never set on AVFormatContext, it is however set on HLSContext object. In order to fix this issue, proper flags field must be checked. In addition, renaming code was messed up and apparently was working only for MP4 files. --- libavformat/hlsenc.c | 60 ++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index bdd2a113bd..021cfa884a 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1357,8 +1357,9 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs) int ret = 0; char temp_filename[1024]; int64_t sequence = FFMAX(hls->start_sequence, vs->sequence - vs->nb_entries); - const char *proto = avio_find_protocol_name(s->url); - int use_temp_file = proto && !strcmp(proto, "file") && (s->flags & HLS_TEMP_FILE); + const char *proto = avio_find_protocol_name(vs->m3u8_name); + int is_file_proto = proto && !strcmp(proto, "file"); + int use_temp_file = is_file_proto && (hls->flags & (HLS_TEMP_FILE | HLS_SINGLE_FILE)) == HLS_TEMP_FILE; static unsigned warned_non_file; char *key_uri = NULL; char *iv_string = NULL; @@ -1381,7 +1382,7 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs) hls->version = 7; } - if (!use_temp_file && !warned_non_file++) + if (!is_file_proto && (hls->flags & HLS_TEMP_FILE) && !warned_non_file++) av_log(s, AV_LOG_ERROR, "Cannot use rename on non file protocol, this may lead to races and temporary partial files\n"); set_http_options(s, &options, hls); @@ -1477,8 +1478,8 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) AVFormatContext *oc = vs->avf; AVFormatContext *vtt_oc = vs->vtt_avf; AVDictionary *options = NULL; - const char *proto = avio_find_protocol_name(s->url); - int use_temp_file = proto && !strcmp(proto, "file") && (s->flags & HLS_TEMP_FILE); + const char *proto = NULL; + int use_temp_file = 0; char *filename, iv_string[KEYSIZE*2 + 1]; int err = 0; @@ -1574,6 +1575,9 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) set_http_options(s, &options, c); + proto = avio_find_protocol_name(oc->url); + use_temp_file = proto && !strcmp(proto, "file") && (c->flags & (HLS_TEMP_FILE | HLS_SINGLE_FILE)) == HLS_TEMP_FILE; + if (use_temp_file) { char *new_name = av_asprintf("%s.tmp", oc->url); if (!new_name) @@ -2142,8 +2146,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) int ret = 0, can_split = 1, i, j; int stream_index = 0; int range_length = 0; - const char *proto = avio_find_protocol_name(s->url); - int use_temp_file = proto && !strcmp(proto, "file") && (s->flags & HLS_TEMP_FILE); + const char *proto = NULL; + int use_temp_file = 0; uint8_t *buffer = NULL; VariantStream *vs = NULL; AVDictionary *options = NULL; @@ -2254,19 +2258,22 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) } } + if (oc->url[0]) { + proto = avio_find_protocol_name(oc->url); + use_temp_file = proto && !strcmp(proto, "file") && (hls->flags & (HLS_TEMP_FILE | HLS_SINGLE_FILE)) == HLS_TEMP_FILE; + } + // look to rename the asset name - if (use_temp_file && oc->url[0]) { + if (use_temp_file) { if (!(hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size <= 0)) - if ((vs->avf->oformat->priv_class && vs->avf->priv_data) && hls->segment_type != SEGMENT_TYPE_FMP4) { + if ((vs->avf->oformat->priv_class && vs->avf->priv_data) && hls->segment_type != SEGMENT_TYPE_FMP4) av_opt_set(vs->avf->priv_data, "mpegts_flags", "resend_headers", 0); - } } if (hls->segment_type == SEGMENT_TYPE_FMP4) { if (hls->flags & HLS_SINGLE_FILE) { ret = flush_dynbuf(vs, &range_length); if (ret < 0) { - av_free(old_filename); return ret; } vs->size = range_length; @@ -2284,20 +2291,13 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) return ret; } ff_format_io_close(s, &vs->out); - - // rename that segment from .tmp to the real one - if (use_temp_file && oc->url[0]) { - hls_rename_temp_file(s, oc); - av_free(old_filename); - old_filename = av_strdup(vs->avf->url); - - if (!old_filename) { - return AVERROR(ENOMEM); - } - } } } + if (use_temp_file) { + hls_rename_temp_file(s, oc); + } + old_filename = av_strdup(vs->avf->url); if (!old_filename) { return AVERROR(ENOMEM); @@ -2366,8 +2366,8 @@ static int hls_write_trailer(struct AVFormatContext *s) AVFormatContext *oc = NULL; AVFormatContext *vtt_oc = NULL; char *old_filename = NULL; - const char *proto = avio_find_protocol_name(s->url); - int use_temp_file = proto && !strcmp(proto, "file") && (s->flags & HLS_TEMP_FILE); + const char *proto = NULL; + int use_temp_file = 0; int i; int ret = 0; VariantStream *vs = NULL; @@ -2378,6 +2378,7 @@ static int hls_write_trailer(struct AVFormatContext *s) oc = vs->avf; vtt_oc = vs->vtt_avf; old_filename = av_strdup(vs->avf->url); + use_temp_file = 0; if (!old_filename) { return AVERROR(ENOMEM); @@ -2421,15 +2422,20 @@ static int hls_write_trailer(struct AVFormatContext *s) failed: av_write_trailer(oc); + + if (oc->url[0]) { + proto = avio_find_protocol_name(oc->url); + use_temp_file = proto && !strcmp(proto, "file") && (hls->flags & (HLS_TEMP_FILE | HLS_SINGLE_FILE)) == HLS_TEMP_FILE; + } + if (oc->pb) { if (hls->segment_type != SEGMENT_TYPE_FMP4) { vs->size = avio_tell(vs->avf->pb) - vs->start_pos; - } - if (hls->segment_type != SEGMENT_TYPE_FMP4) ff_format_io_close(s, &oc->pb); + } // rename that segment from .tmp to the real one - if (use_temp_file && oc->url[0] && !(hls->flags & HLS_SINGLE_FILE)) { + if (use_temp_file) { hls_rename_temp_file(s, oc); av_free(old_filename); old_filename = av_strdup(vs->avf->url); -- 2.19.2