[FFmpeg-devel] [PATCH v4] avformat/hlsenc: merge mpegts and fmp4 workflow to one workflow

Liu Steven lq at chinaffmpeg.org
Sun Aug 18 03:23:28 EEST 2019



> 在 2019年8月9日,下午5:30,Liu Steven <lq at chinaffmpeg.org> 写道:
> 
> 
> 
>> 在 2019年8月5日,上午10:29,Steven Liu <lq at chinaffmpeg.org> 写道:
>> 
>> 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 <lq at chinaffmpeg.org>
>> ---
>> 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);
>> 
>> -- 
>> 2.17.2 (Apple Git-113)
>> 
>> 
>> 
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel at ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>> 
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
> 
> 
> ping?
> 
Pushed
> 
> Thanks
> Steven
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".





More information about the ffmpeg-devel mailing list