From patchwork Mon Aug 5 02:29:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liu Steven X-Patchwork-Id: 14238 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 9D900449852 for ; Mon, 5 Aug 2019 05:29:31 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7A59968A636; Mon, 5 Aug 2019 05:29:31 +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 15AB368978D for ; Mon, 5 Aug 2019 05:29:23 +0300 (EEST) X-QQ-mid: bizesmtp11t1564972154tjjso88k Received: from localhost (unknown [111.200.62.154]) by esmtp6.qq.com (ESMTP) with id ; Mon, 05 Aug 2019 10:29:13 +0800 (CST) X-QQ-SSF: 01100000002000K0ZPF0B00A0000000 X-QQ-FEAT: /YK9kXAO0jc05kHVm7iNukgK5798CwOYZ76hZ7pLL8NF/SwJieoUS9jGY4OX/ nnWkp6DmwVcROeFmdWcmHRu5VIyj46YAHRZJpOOGQYblaymzVGBTcRRV/mdZtops3aLoW60 IqxLTeyOuUiseRy1xlopF/0yQHhpSzz3Zj8bBI2uOrTRp0mqkY1PUTmAvPRJJPjNYNsFUqv Vn/Fu0I7z+jRdXIHjCEAeMYInHB6r45Kp8FMOBOFjQn+zzaR+7Gkue4GN20NfzQ1ARUYQVQ fNRmXwdjUDAuraWfF317rA/eacfV8Ejr33nq5p4suXa7bi3jgKiR28ZPM= X-QQ-GoodBg: 0 From: Steven Liu To: ffmpeg-devel@ffmpeg.org Date: Mon, 5 Aug 2019 10:29:09 +0800 Message-Id: <20190805022909.14900-1-lq@chinaffmpeg.org> X-Mailer: git-send-email 2.17.2 (Apple Git-113) X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:chinaffmpeg.org:qybgforeign:qybgforeign2 X-QQ-Bgrelay: 1 Subject: [FFmpeg-devel] [PATCH v4] avformat/hlsenc: merge mpegts and fmp4 workflow to one workflow 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" just remove the 'i' of the v3 mail subject. write mpegts or fmp4 context into buffer, and flush the buffer into output file when split fragment. merge two format split workflow into one workflow Signed-off-by: Steven Liu --- libavformat/hlsenc.c | 251 +++++++++++++++++++++---------------------- 1 file changed, 124 insertions(+), 127 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 51310fb528..f6f9c8161d 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -815,7 +815,7 @@ static int hls_mux_init(AVFormatContext *s, VariantStream *vs) vs->start_pos = 0; vs->new_start = 1; - if (hls->segment_type == SEGMENT_TYPE_FMP4) { + if (hls->segment_type == SEGMENT_TYPE_FMP4 && hls->max_seg_size > 0) { if (hls->http_persistent > 0) { //TODO: Support fragment fmp4 for http persistent in HLS muxer. av_log(s, AV_LOG_WARNING, "http persistent mode is currently unsupported for fragment mp4 in the HLS muxer.\n"); @@ -824,34 +824,38 @@ static int hls_mux_init(AVFormatContext *s, VariantStream *vs) av_log(s, AV_LOG_WARNING, "Multi-file byterange mode is currently unsupported in the HLS muxer.\n"); return AVERROR_PATCHWELCOME; } + } - vs->packets_written = 0; - vs->init_range_length = 0; - set_http_options(s, &options, hls); - if ((ret = avio_open_dyn_buf(&oc->pb)) < 0) - return ret; + vs->packets_written = 0; + vs->init_range_length = 0; + set_http_options(s, &options, hls); + if ((ret = avio_open_dyn_buf(&oc->pb)) < 0) + return ret; + if (hls->segment_type == SEGMENT_TYPE_FMP4) { if (byterange_mode) { ret = hlsenc_io_open(s, &vs->out, vs->basename, &options); } else { ret = hlsenc_io_open(s, &vs->out, vs->base_output_dirname, &options); } - av_dict_free(&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; + } + + if (hls->format_options_str) { + ret = av_dict_parse_string(&hls->format_options, hls->format_options_str, "=", ":", 0); if (ret < 0) { - av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", vs->fmp4_init_filename); + av_log(s, AV_LOG_ERROR, "Could not parse format options list '%s'\n", + hls->format_options_str); return ret; } + } - if (hls->format_options_str) { - ret = av_dict_parse_string(&hls->format_options, hls->format_options_str, "=", ":", 0); - if (ret < 0) { - av_log(s, AV_LOG_ERROR, "Could not parse format options list '%s'\n", - hls->format_options_str); - return ret; - } - } - - av_dict_copy(&options, hls->format_options, 0); + av_dict_copy(&options, hls->format_options, 0); + if (hls->segment_type == SEGMENT_TYPE_FMP4) { av_dict_set(&options, "fflags", "-autobsf", 0); av_dict_set(&options, "movflags", "+frag_custom+dash+delay_moov", AV_DICT_APPEND); ret = avformat_init_output(oc, &options); @@ -862,9 +866,9 @@ static int hls_mux_init(AVFormatContext *s, VariantStream *vs) av_dict_free(&options); return AVERROR(EINVAL); } - avio_flush(oc->pb); - av_dict_free(&options); } + avio_flush(oc->pb); + av_dict_free(&options); return 0; } @@ -1435,7 +1439,6 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs) { HLSContext *hls = s->priv_data; HLSSegment *en; - AVFormatContext *oc = vs->avf; int target_duration = 0; int ret = 0; char temp_filename[MAX_URL_SIZE]; @@ -1471,7 +1474,7 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs) set_http_options(s, &options, hls); snprintf(temp_filename, sizeof(temp_filename), use_temp_file ? "%s.tmp" : "%s", vs->m3u8_name); - if ((ret = hlsenc_io_open(s, (byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? &hls->m3u8_out : &oc->pb, temp_filename, &options)) < 0) { + if ((ret = hlsenc_io_open(s, (byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? &hls->m3u8_out : &vs->out, temp_filename, &options)) < 0) { if (hls->ignore_io_errors) ret = 0; goto fail; @@ -1483,33 +1486,33 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs) } vs->discontinuity_set = 0; - ff_hls_write_playlist_header((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, hls->version, hls->allowcache, + ff_hls_write_playlist_header((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, hls->version, hls->allowcache, target_duration, sequence, hls->pl_type, hls->flags & HLS_I_FRAMES_ONLY); if((hls->flags & HLS_DISCONT_START) && sequence==hls->start_sequence && vs->discontinuity_set==0 ){ - avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, "#EXT-X-DISCONTINUITY\n"); + avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, "#EXT-X-DISCONTINUITY\n"); vs->discontinuity_set = 1; } if (vs->has_video && (hls->flags & HLS_INDEPENDENT_SEGMENTS)) { - avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, "#EXT-X-INDEPENDENT-SEGMENTS\n"); + avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, "#EXT-X-INDEPENDENT-SEGMENTS\n"); } for (en = vs->segments; en; en = en->next) { if ((hls->encrypt || hls->key_info_file) && (!key_uri || strcmp(en->key_uri, key_uri) || av_strcasecmp(en->iv_string, iv_string))) { - avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, "#EXT-X-KEY:METHOD=AES-128,URI=\"%s\"", en->key_uri); + avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, "#EXT-X-KEY:METHOD=AES-128,URI=\"%s\"", en->key_uri); if (*en->iv_string) - avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, ",IV=0x%s", en->iv_string); - avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, "\n"); + avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, ",IV=0x%s", en->iv_string); + avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, "\n"); key_uri = en->key_uri; iv_string = en->iv_string; } if ((hls->segment_type == SEGMENT_TYPE_FMP4) && (en == vs->segments)) { - ff_hls_write_init_file((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, (hls->flags & HLS_SINGLE_FILE) ? en->filename : vs->fmp4_init_filename, + ff_hls_write_init_file((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, (hls->flags & HLS_SINGLE_FILE) ? en->filename : vs->fmp4_init_filename, hls->flags & HLS_SINGLE_FILE, vs->init_range_length, 0); } - ret = ff_hls_write_file_entry((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, en->discont, byterange_mode, + ret = ff_hls_write_file_entry((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, en->discont, byterange_mode, en->duration, hls->flags & HLS_ROUND_DURATIONS, en->size, en->pos, vs->baseurl, en->filename, prog_date_time_p, en->keyframe_size, en->keyframe_pos, hls->flags & HLS_I_FRAMES_ONLY); @@ -1519,7 +1522,7 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs) } if (last && (hls->flags & HLS_OMIT_ENDLIST)==0) - ff_hls_write_end_list((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb); + ff_hls_write_end_list((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out); if (vs->vtt_m3u8_name) { snprintf(temp_vtt_filename, sizeof(temp_vtt_filename), use_temp_file ? "%s.tmp" : "%s", vs->vtt_m3u8_name); @@ -1546,7 +1549,7 @@ 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 : &oc->pb, temp_filename); + hlsenc_io_close(s, (byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? &hls->m3u8_out : &vs->out, temp_filename); hlsenc_io_close(s, &hls->sub_m3u8_out, vs->vtt_m3u8_name); if (use_temp_file) { ff_rename(temp_filename, vs->m3u8_name, s); @@ -1694,42 +1697,13 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) } c->encrypt_started = 1; } - if ((err = av_dict_set(&options, "encryption_key", c->key_string, 0)) - < 0) - goto fail; err = av_strlcpy(iv_string, c->iv_string, sizeof(iv_string)); - if (!err) + if (!err) { snprintf(iv_string, sizeof(iv_string), "%032"PRIx64, vs->sequence); - if ((err = av_dict_set(&options, "encryption_iv", iv_string, 0)) < 0) - goto fail; - - filename = av_asprintf("crypto:%s", oc->url); - if (!filename) { - err = AVERROR(ENOMEM); - goto fail; - } - err = hlsenc_io_open(s, &oc->pb, filename, &options); - av_free(filename); - av_dict_free(&options); - if (err < 0) - return err; - } else if (c->segment_type != SEGMENT_TYPE_FMP4) { - if ((err = hlsenc_io_open(s, &oc->pb, oc->url, &options)) < 0) { - if (c->ignore_io_errors) - err = 0; - goto fail; + memset(c->iv_string, 0, sizeof(c->iv_string)); + memcpy(c->iv_string, iv_string, sizeof(iv_string)); } } - if (vs->vtt_basename) { - set_http_options(s, &options, c); - if ((err = hlsenc_io_open(s, &vtt_oc->pb, vtt_oc->url, &options)) < 0) { - if (c->ignore_io_errors) - err = 0; - goto fail; - } - } - av_dict_free(&options); - if (c->segment_type != SEGMENT_TYPE_FMP4) { /* We only require one PAT/PMT per segment. */ if (oc->oformat->priv_class && oc->priv_data) { @@ -1741,7 +1715,23 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) av_opt_set(oc->priv_data, "sdt_period", period, 0); av_opt_set(oc->priv_data, "pat_period", period, 0); } + if (c->flags & HLS_SINGLE_FILE) { + if ((err = hlsenc_io_open(s, &vs->out, oc->url, &options)) < 0) { + if (c->ignore_io_errors) + err = 0; + goto fail; + } + } } + if (vs->vtt_basename) { + set_http_options(s, &options, c); + if ((err = hlsenc_io_open(s, &vtt_oc->pb, vtt_oc->url, &options)) < 0) { + if (c->ignore_io_errors) + err = 0; + goto fail; + } + } + av_dict_free(&options); if (vs->vtt_basename) { err = avformat_write_header(vtt_oc,NULL); @@ -2343,20 +2333,12 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) int64_t new_start_pos; int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0); - av_write_frame(vs->avf, NULL); /* Flush any buffered data */ - - new_start_pos = avio_tell(vs->avf->pb); - - if (hls->segment_type != SEGMENT_TYPE_FMP4) { - avio_flush(oc->pb); - vs->size = new_start_pos - vs->start_pos; - } else { - vs->size = new_start_pos; - } - + av_write_frame(oc, NULL); /* Flush any buffered data */ + new_start_pos = avio_tell(oc->pb); + vs->size = new_start_pos - vs->start_pos; + avio_flush(oc->pb); 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); av_free(buffer); @@ -2365,14 +2347,10 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) vs->packets_written = 0; vs->start_pos = range_length; if (!byterange_mode) { - ff_format_io_close(s, &vs->out); +// ff_format_io_close(s, &vs->out); hlsenc_io_close(s, &vs->out, vs->base_output_dirname); } } - } else { - if (!byterange_mode) { - hlsenc_io_close(s, &oc->pb, oc->url); - } } if (!byterange_mode) { if (vs->vtt_avf) { @@ -2387,32 +2365,44 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) // look to rename the asset name 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) - av_opt_set(vs->avf->priv_data, "mpegts_flags", "resend_headers", 0); + av_dict_set(&options, "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) { - return ret; + if (hls->flags & HLS_SINGLE_FILE) { + ret = flush_dynbuf(vs, &range_length); + if (ret < 0) { + return ret; + } + vs->size = range_length; + } else { + set_http_options(s, &options, hls); + if ((hls->max_seg_size > 0 && (vs->size >= hls->max_seg_size)) || !byterange_mode) { + char *filename = NULL; + if (hls->key_info_file || hls->encrypt) { + av_dict_set(&options, "encryption_key", hls->key_string, 0); + av_dict_set(&options, "encryption_iv", hls->iv_string, 0); + filename = av_asprintf("crypto:%s", oc->url); + } else { + filename = av_asprintf("%s", oc->url); } - vs->size = range_length; - } else { - set_http_options(s, &options, hls); - ret = hlsenc_io_open(s, &vs->out, vs->avf->url, &options); + if (!filename) { + return AVERROR(ENOMEM); + } + ret = hlsenc_io_open(s, &vs->out, filename, &options); if (ret < 0) { av_log(s, hls->ignore_io_errors ? AV_LOG_WARNING : AV_LOG_ERROR, - "Failed to open file '%s'\n", vs->avf->url); + "Failed to open file '%s'\n", filename); return hls->ignore_io_errors ? 0 : ret; } - write_styp(vs->out); + if (hls->segment_type == SEGMENT_TYPE_FMP4) { + write_styp(vs->out); + } ret = flush_dynbuf(vs, &range_length); if (ret < 0) { return ret; } - ff_format_io_close(s, &vs->out); + hlsenc_io_close(s, &vs->out, filename); + av_free(filename); } } @@ -2420,7 +2410,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) hls_rename_temp_file(s, oc); } - old_filename = av_strdup(vs->avf->url); + old_filename = av_strdup(oc->url); if (!old_filename) { return AVERROR(ENOMEM); } @@ -2435,11 +2425,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) } } - if (hls->segment_type != SEGMENT_TYPE_FMP4) { - vs->start_pos = new_start_pos; - } else { - vs->start_pos += vs->size; - } // 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) { @@ -2449,8 +2434,10 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) if (hls->flags & HLS_SINGLE_FILE) { vs->number++; + vs->start_pos += vs->size; } else if (hls->max_seg_size > 0) { - if (vs->start_pos >= hls->max_seg_size) { + vs->start_pos = new_start_pos; + if (vs->size >= hls->max_seg_size) { vs->sequence++; sls_flag_file_rename(hls, vs, old_filename); ret = hls_start(s, vs); @@ -2461,6 +2448,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) } vs->number++; } else { + vs->start_pos = new_start_pos; sls_flag_file_rename(hls, vs, old_filename); ret = hls_start(s, vs); } @@ -2475,13 +2463,12 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) vs->packets_written++; if (oc->pb) { ret = ff_write_chained(oc, stream_index, pkt, s, 0); + vs->video_keyframe_size += pkt->size; if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && (pkt->flags & AV_PKT_FLAG_KEY)) { - vs->video_keyframe_size = avio_tell(oc->pb) - vs->video_lastpos; - vs->video_keyframe_pos = vs->start_pos; + vs->video_keyframe_size = avio_tell(oc->pb); } else { - vs->video_lastpos = avio_tell(oc->pb); + vs->video_keyframe_pos = avio_tell(vs->out); } - if (hls->ignore_io_errors) ret = 0; } @@ -2530,10 +2517,12 @@ static int hls_write_trailer(struct AVFormatContext *s) int i; int ret = 0; VariantStream *vs = NULL; + AVDictionary *options = NULL; + int range_length, byterange_mode; for (i = 0; i < hls->nb_varstreams; i++) { + char *filename = NULL; vs = &hls->var_streams[i]; - oc = vs->avf; vtt_oc = vs->vtt_avf; old_filename = av_strdup(vs->avf->url); @@ -2542,11 +2531,22 @@ static int hls_write_trailer(struct AVFormatContext *s) if (!old_filename) { return AVERROR(ENOMEM); } + if (hls->key_info_file || hls->encrypt) { + av_dict_set(&options, "encryption_key", hls->key_string, 0); + av_dict_set(&options, "encryption_iv", hls->iv_string, 0); + filename = av_asprintf("crypto:%s", vs->avf->url); + } else { + filename = av_asprintf("%s", vs->avf->url); + } + if (!filename) { + return AVERROR(ENOMEM); + } + + if ( hls->segment_type == SEGMENT_TYPE_FMP4) { int range_length = 0; if (!vs->init_range_length) { uint8_t *buffer = NULL; - int range_length, byterange_mode; av_write_frame(vs->avf, NULL); /* Flush any buffered data */ avio_flush(oc->pb); @@ -2563,21 +2563,25 @@ static int hls_write_trailer(struct AVFormatContext *s) hlsenc_io_close(s, &vs->out, vs->base_output_dirname); } } - if (!(hls->flags & HLS_SINGLE_FILE)) { - ret = hlsenc_io_open(s, &vs->out, vs->avf->url, NULL); - if (ret < 0) { - av_log(s, AV_LOG_ERROR, "Failed to open file '%s'\n", vs->avf->url); - goto failed; - } - write_styp(vs->out); - } - ret = flush_dynbuf(vs, &range_length); + } + if (!(hls->flags & HLS_SINGLE_FILE)) { + set_http_options(s, &options, hls); + 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; } - vs->size = range_length; - ff_format_io_close(s, &vs->out); + if (hls->segment_type == SEGMENT_TYPE_FMP4) + write_styp(vs->out); } + ret = flush_dynbuf(vs, &range_length); + if (ret < 0) + goto failed; + + vs->size = range_length; + hlsenc_io_close(s, &vs->out, filename); + av_free(filename); + failed: av_write_trailer(oc); @@ -2587,12 +2591,6 @@ failed: use_temp_file = proto && !strcmp(proto, "file") && (hls->flags & HLS_TEMP_FILE); } - if (oc->pb) { - if (hls->segment_type != SEGMENT_TYPE_FMP4) { - vs->size = avio_tell(vs->avf->pb) - vs->start_pos; - hlsenc_io_close(s, &vs->avf->pb, vs->avf->url); - } - // rename that segment from .tmp to the real one if (use_temp_file && !(hls->flags & HLS_SINGLE_FILE)) { hls_rename_temp_file(s, oc); @@ -2606,7 +2604,6 @@ failed: /* after av_write_trailer, then duration + 1 duration per packet */ hls_append_segment(s, hls, vs, vs->duration + vs->dpp, vs->start_pos, vs->size); - } sls_flag_file_rename(hls, vs, old_filename);