[FFmpeg-devel] [PATCH] avformat/hlsenc: move init operations from write_header to init

Dixit, Vishwanath vdixit at akamai.com
Wed Dec 6 07:16:34 EET 2017


>
>
>
>On 12/4/17, 3:20 PM, "Steven Liu" <lq at chinaffmpeg.org> wrote:
>
>
>
>Signed-off-by: Steven Liu <lq at chinaffmpeg.org>
>
>---
>
> libavformat/hlsenc.c | 681 ++++++++++++++++++++++++++-------------------------
>
> 1 file changed, 345 insertions(+), 336 deletions(-)
>
>
>
>diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
>
>index aeeed5bcd2..852663d28f 100644
>
>--- a/libavformat/hlsenc.c
>
>+++ b/libavformat/hlsenc.c
>
>@@ -1636,329 +1636,12 @@ static int hls_write_header(AVFormatContext *s)
>
> {
>
>     HLSContext *hls = s->priv_data;
>
>     int ret, i, j;
>
>-    char *p = NULL;
>
>-    const char *pattern = "%d.ts";
>
>-    const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt(s);
>
>-    const char *vtt_pattern = "%d.vtt";
>
>     AVDictionary *options = NULL;
>
>-    int basename_size = 0;
>
>-    int vtt_basename_size = 0, m3u8_name_size = 0;
>
>     VariantStream *vs = NULL;
>
>-    int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1;
>
>-
>
>-    ret = update_variant_stream_info(s);
>
>-    if (ret < 0) {
>
>-        av_log(s, AV_LOG_ERROR, "Variant stream info update failed with status %x\n",
>
>-                ret);
>
>-        goto fail;
>
>-    }
>
>-
>
>-    //TODO: Updates needed to encryption functionality with periodic re-key when more than one variant streams are present
>
>-    if (hls->nb_varstreams > 1 && hls->flags & HLS_PERIODIC_REKEY) {
>
>-        ret = AVERROR(EINVAL);
>
>-        av_log(s, AV_LOG_ERROR, "Periodic re-key not supported when more than one variant streams are present\n");
>
>-        goto fail;
>
>-    }
>
>-
>
>-    if (hls->master_pl_name) {
>
>-        ret = update_master_pl_info(s);
>
>-        if (ret < 0) {
>
>-            av_log(s, AV_LOG_ERROR, "Master stream info update failed with status %x\n",
>
>-                    ret);
>
>-            goto fail;
>
>-        }
>
>-    }
>
>-
>
>-    if (hls->segment_type == SEGMENT_TYPE_FMP4) {
>
>-        pattern = "%d.m4s";
>
>-    }
>
>-    if ((hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) ||
>
>-        (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME)) {
>
>-        time_t t = time(NULL); // we will need it in either case
>
>-        if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) {
>
>-            hls->start_sequence = (int64_t)t;
>
>-        } else if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME) {
>
>-            char b[15];
>
>-            struct tm *p, tmbuf;
>
>-            if (!(p = localtime_r(&t, &tmbuf)))
>
>-                return AVERROR(ENOMEM);
>
>-            if (!strftime(b, sizeof(b), "%Y%m%d%H%M%S", p))
>
>-                return AVERROR(ENOMEM);
>
>-            hls->start_sequence = strtoll(b, NULL, 10);
>
>-        }
>
>-        av_log(hls, AV_LOG_DEBUG, "start_number evaluated to %"PRId64"\n", hls->start_sequence);
>
>-    }
>
> 
>
>     for (i = 0; i < hls->nb_varstreams; i++) {
>
>         vs = &hls->var_streams[i];
>
> 
>
>-    vs->sequence       = hls->start_sequence;
>
>-    hls->recording_time = (hls->init_time ? hls->init_time : hls->time) * AV_TIME_BASE;
>
>-    vs->start_pts      = AV_NOPTS_VALUE;
>
>-    vs->end_pts      = AV_NOPTS_VALUE;
>
>-    vs->current_segment_final_filename_fmt[0] = '\0';
>
>-
>
>-    if (hls->flags & HLS_SPLIT_BY_TIME && hls->flags & HLS_INDEPENDENT_SEGMENTS) {
>
>-        // Independent segments cannot be guaranteed when splitting by time
>
>-        hls->flags &= ~HLS_INDEPENDENT_SEGMENTS;
>
>-        av_log(s, AV_LOG_WARNING,
>
>-               "'split_by_time' and 'independent_segments' cannot be enabled together. "
>
>-               "Disabling 'independent_segments' flag\n");
>
>-    }
>
>-
>
>-    if (hls->flags & HLS_PROGRAM_DATE_TIME) {
>
>-        time_t now0;
>
>-        time(&now0);
>
>-        vs->initial_prog_date_time = now0;
>
>-    }
>
>-
>
>-    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);
>
>-            goto fail;
>
>-        }
>
>-    }
>
>-
>
>-    for (j = 0; j < vs->nb_streams; j++) {
>
>-        vs->has_video +=
>
>-            vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO;
>
>-        vs->has_subtitle +=
>
>-            vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE;
>
>-    }
>
>-
>
>-    if (vs->has_video > 1)
>
>-        av_log(s, AV_LOG_WARNING,
>
>-               "More than a single video stream present, "
>
>-               "expect issues decoding it.\n");
>
>-
>
>-    if (hls->segment_type == SEGMENT_TYPE_FMP4) {
>
>-        vs->oformat = av_guess_format("mp4", NULL, NULL);
>
>-    } else {
>
>-        vs->oformat = av_guess_format("mpegts", NULL, NULL);
>
>-    }
>
>-
>
>-    if (!vs->oformat) {
>
>-        ret = AVERROR_MUXER_NOT_FOUND;
>
>-        goto fail;
>
>-    }
>
>-
>
>-    if(vs->has_subtitle) {
>
>-        vs->vtt_oformat = av_guess_format("webvtt", NULL, NULL);
>
>-        if (!vs->oformat) {
>
>-            ret = AVERROR_MUXER_NOT_FOUND;
>
>-            goto fail;
>
>-        }
>
>-    }
>
>-
>
>-    if (hls->segment_filename) {
>
>-        basename_size = strlen(hls->segment_filename) + 1;
>
>-        if (hls->nb_varstreams > 1) {
>
>-            basename_size += strlen(POSTFIX_PATTERN);
>
>-        }
>
>-        vs->basename = av_malloc(basename_size);
>
>-        if (!vs->basename) {
>
>-            ret = AVERROR(ENOMEM);
>
>-            goto fail;
>
>-        }
>
>-
>
>-        av_strlcpy(vs->basename, hls->segment_filename, basename_size);
>
>-    } else {
>
>-        if (hls->flags & HLS_SINGLE_FILE) {
>
>-            if (hls->segment_type == SEGMENT_TYPE_FMP4) {
>
>-                pattern = ".m4s";
>
>-            } else {
>
>-                pattern = ".ts";
>
>-            }
>
>-        }
>
>-
>
>-        if (hls->use_localtime) {
>
>-            basename_size = strlen(s->filename) + strlen(pattern_localtime_fmt) + 1;
>
>-        } else {
>
>-            basename_size = strlen(s->filename) + strlen(pattern) + 1;
>
>-        }
>
>-
>
>-        if (hls->nb_varstreams > 1) {
>
>-            basename_size += strlen(POSTFIX_PATTERN);
>
>-        }
>
>-
>
>-        vs->basename = av_malloc(basename_size);
>
>-        if (!vs->basename) {
>
>-            ret = AVERROR(ENOMEM);
>
>-            goto fail;
>
>-        }
>
>-
>
>-        av_strlcpy(vs->basename, s->filename, basename_size);
>
>-
>
>-        p = strrchr(vs->basename, '.');
>
>-        if (p)
>
>-            *p = '\0';
>
>-        if (hls->use_localtime) {
>
>-            av_strlcat(vs->basename, pattern_localtime_fmt, basename_size);
>
>-        } else {
>
>-            av_strlcat(vs->basename, pattern, basename_size);
>
>-        }
>
>-    }
>
>-
>
>-    m3u8_name_size = strlen(s->filename) + 1;
>
>-    if (hls->nb_varstreams > 1) {
>
>-        m3u8_name_size += strlen(POSTFIX_PATTERN);
>
>-    }
>
>-
>
>-    vs->m3u8_name = av_malloc(m3u8_name_size);
>
>-    if (!vs->m3u8_name ) {
>
>-        ret = AVERROR(ENOMEM);
>
>-        goto fail;
>
>-    }
>
>-
>
>-    av_strlcpy(vs->m3u8_name, s->filename, m3u8_name_size);
>
>-
>
>-    if (hls->nb_varstreams > 1) {
>
>-        ret = format_name(vs->basename, basename_size, i);
>
>-        if (ret < 0)
>
>-             goto fail;
>
>-        ret = format_name(vs->m3u8_name, m3u8_name_size, i);
>
>-        if (ret < 0)
>
>-             goto fail;
>
>-    }
>
>-
>
>-    if (hls->segment_type == SEGMENT_TYPE_FMP4) {
>
>-        if (hls->nb_varstreams > 1)
>
>-            fmp4_init_filename_len += strlen(POSTFIX_PATTERN);
>
>-        vs->fmp4_init_filename = av_malloc(fmp4_init_filename_len);
>
>-        if (!vs->fmp4_init_filename ) {
>
>-            ret = AVERROR(ENOMEM);
>
>-            goto fail;
>
>-        }
>
>-        av_strlcpy(vs->fmp4_init_filename, hls->fmp4_init_filename,
>
>-                fmp4_init_filename_len);
>
>-        if (hls->nb_varstreams > 1) {
>
>-            ret = format_name(vs->fmp4_init_filename, fmp4_init_filename_len, i);
>
>-            if (ret < 0)
>
>-                 goto fail;
>
>-        }
>
>-
>
>-        if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) {
>
>-            fmp4_init_filename_len = strlen(vs->fmp4_init_filename) + 1;
>
>-            vs->base_output_dirname = av_malloc(fmp4_init_filename_len);
>
>-            if (!vs->base_output_dirname) {
>
>-                ret = AVERROR(ENOMEM);
>
>-                goto fail;
>
>-            }
>
>-            av_strlcpy(vs->base_output_dirname, vs->fmp4_init_filename,
>
>-                    fmp4_init_filename_len);
>
>-        } else {
>
>-            fmp4_init_filename_len = strlen(vs->m3u8_name) +
>
>-                                         strlen(vs->fmp4_init_filename) + 1;
>
>-
>
>-            vs->base_output_dirname = av_malloc(fmp4_init_filename_len);
>
>-            if (!vs->base_output_dirname) {
>
>-                ret = AVERROR(ENOMEM);
>
>-                goto fail;
>
>-            }
>
>-
>
>-            av_strlcpy(vs->base_output_dirname, vs->m3u8_name,
>
>-                    fmp4_init_filename_len);
>
>-            p = strrchr(vs->base_output_dirname, '/');
>
>-            if (p) {
>
>-                *(p + 1) = '\0';
>
>-                av_strlcat(vs->base_output_dirname, vs->fmp4_init_filename,
>
>-                        fmp4_init_filename_len);
>
>-            } else {
>
>-                av_strlcpy(vs->base_output_dirname, vs->fmp4_init_filename,
>
>-                        fmp4_init_filename_len);
>
>-            }
>
>-        }
>
>-    }
>
>-
>
>-    if (!hls->use_localtime) {
>
>-        ret = sls_flag_check_duration_size_index(hls);
>
>-        if (ret < 0) {
>
>-             goto fail;
>
>-        }
>
>-    } else {
>
>-        ret = sls_flag_check_duration_size(hls, vs);
>
>-        if (ret < 0) {
>
>-             goto fail;
>
>-        }
>
>-    }
>
>-    if(vs->has_subtitle) {
>
>-
>
>-        if (hls->flags & HLS_SINGLE_FILE)
>
>-            vtt_pattern = ".vtt";
>
>-        vtt_basename_size = strlen(s->filename) + strlen(vtt_pattern) + 1;
>
>-        if (hls->nb_varstreams > 1) {
>
>-            vtt_basename_size += strlen(POSTFIX_PATTERN);
>
>-        }
>
>-
>
>-        vs->vtt_basename = av_malloc(vtt_basename_size);
>
>-        if (!vs->vtt_basename) {
>
>-            ret = AVERROR(ENOMEM);
>
>-            goto fail;
>
>-        }
>
>-        vs->vtt_m3u8_name = av_malloc(vtt_basename_size);
>
>-        if (!vs->vtt_m3u8_name ) {
>
>-            ret = AVERROR(ENOMEM);
>
>-            goto fail;
>
>-        }
>
>-        av_strlcpy(vs->vtt_basename, s->filename, vtt_basename_size);
>
>-        p = strrchr(vs->vtt_basename, '.');
>
>-        if (p)
>
>-            *p = '\0';
>
>-
>
>-        if( hls->subtitle_filename ) {
>
>-            strcpy(vs->vtt_m3u8_name, hls->subtitle_filename);
>
>-        } else {
>
>-            strcpy(vs->vtt_m3u8_name, vs->vtt_basename);
>
>-            av_strlcat(vs->vtt_m3u8_name, "_vtt.m3u8", vtt_basename_size);
>
>-        }
>
>-        av_strlcat(vs->vtt_basename, vtt_pattern, vtt_basename_size);
>
>-
>
>-        if (hls->nb_varstreams > 1) {
>
>-            ret= format_name(vs->vtt_basename, vtt_basename_size, i);
>
>-            if (ret < 0)
>
>-                 goto fail;
>
>-            ret = format_name(vs->vtt_m3u8_name, vtt_basename_size, i);
>
>-            if (ret < 0)
>
>-                 goto fail;
>
>-        }
>
>-    }
>
>-
>
>-    if (hls->baseurl) {
>
>-        vs->baseurl = av_strdup(hls->baseurl);
>
>-        if (!vs->baseurl) {
>
>-            ret = AVERROR(ENOMEM);
>
>-            goto fail;
>
>-        }
>
>-    }
>
>-
>
>-    if ((hls->flags & HLS_SINGLE_FILE) && (hls->segment_type == SEGMENT_TYPE_FMP4)) {
>
>-        vs->fmp4_init_filename  = av_strdup(vs->basename);
>
>-        if (!vs->fmp4_init_filename) {
>
>-            ret = AVERROR(ENOMEM);
>
>-            goto fail;
>
>-        }
>
>-    }
>
>-
>
>-    if ((ret = hls_mux_init(s, vs)) < 0)
>
>-        goto fail;
>
>-
>
>-    if (hls->flags & HLS_APPEND_LIST) {
>
>-        parse_playlist(s, vs->m3u8_name, vs);
>
>-        vs->discontinuity = 1;
>
>-        if (hls->init_time > 0) {
>
>-            av_log(s, AV_LOG_WARNING, "append_list mode does not support hls_init_time,"
>
>-                   " hls_init_time value will have no effect\n");
>
>-            hls->init_time = 0;
>
>-            hls->recording_time = hls->time * AV_TIME_BASE;
>
>-        }
>
>-    }
>
>-
>
>-    if (hls->segment_type != SEGMENT_TYPE_FMP4 || hls->flags & HLS_SINGLE_FILE) {
>
>-        if ((ret = hls_start(s, vs)) < 0)
>
>-            goto fail;
>
>-    }
>
>-
>
>     av_dict_copy(&options, hls->format_options, 0);
>
>     ret = avformat_write_header(vs->avf, &options);
>
>     if (av_dict_count(options)) {
>
>@@ -1996,25 +1679,6 @@ static int hls_write_header(AVFormatContext *s)
>
>     }
>
> fail:
>
> 
>
>-    if (ret < 0) {
>
>-        av_freep(&hls->key_basename);
>
>-        for (i = 0; i < hls->nb_varstreams && hls->var_streams; i++) {
>
>-            vs = &hls->var_streams[i];
>
>-            av_freep(&vs->basename);
>
>-            av_freep(&vs->vtt_basename);
>
>-            av_freep(&vs->fmp4_init_filename);
>
>-            av_freep(&vs->m3u8_name);
>
>-            av_freep(&vs->vtt_m3u8_name);
>
>-            av_freep(&vs->streams);
>
>-            av_freep(&vs->baseurl);
>
>-            if (vs->avf)
>
>-                avformat_free_context(vs->avf);
>
>-            if (vs->vtt_avf)
>
>-                avformat_free_context(vs->vtt_avf);
>
>-        }
>
>-        av_freep(&hls->var_streams);
>
>-        av_freep(&hls->master_m3u8_url);
>
>-    }
>
>     return ret;
>
> }
>
> 
>
>@@ -2256,6 +1920,350 @@ static int hls_write_trailer(struct AVFormatContext *s)
>
>     return 0;
>
> }
>
> 
>
>+
>
>+static int hls_init(AVFormatContext *s)
>
>+{
>
>+    int ret = 0;
>
>+    int i = 0;
>
>+    int j = 0;
>
>+    HLSContext *hls = s->priv_data;
>
>+    const char *pattern = "%d.ts";
>
>+    VariantStream *vs = NULL;
>
>+    int basename_size = 0;
>
>+    const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt(s);
>
>+    const char *vtt_pattern = "%d.vtt";
>
>+    char *p = NULL;
>
>+    int vtt_basename_size = 0, m3u8_name_size = 0;
>
>+    int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1;
>
>+
>
>+    ret = update_variant_stream_info(s);
>
>+    if (ret < 0) {
>
>+        av_log(s, AV_LOG_ERROR, "Variant stream info update failed with status %x\n",
>
>+                ret);
>
>+        goto fail;
>
>+    }
>
>+    //TODO: Updates needed to encryption functionality with periodic re-key when more than one variant streams are present
>
>+    if (hls->nb_varstreams > 1 && hls->flags & HLS_PERIODIC_REKEY) {
>
>+        ret = AVERROR(EINVAL);
>
>+        av_log(s, AV_LOG_ERROR, "Periodic re-key not supported when more than one variant streams are present\n");
>
>+        goto fail;
>
>+    }
>
>+
>
>+    if (hls->master_pl_name) {
>
>+        ret = update_master_pl_info(s);
>
>+        if (ret < 0) {
>
>+            av_log(s, AV_LOG_ERROR, "Master stream info update failed with status %x\n",
>
>+                    ret);
>
>+            goto fail;
>
>+        }
>
>+    }
>
>+
>
>+    if (hls->segment_type == SEGMENT_TYPE_FMP4) {
>
>+        pattern = "%d.m4s";
>
>+    }
>
>+    if ((hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) ||
>
>+        (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME)) {
>
>+        time_t t = time(NULL); // we will need it in either case
>
>+        if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) {
>
>+            hls->start_sequence = (int64_t)t;
>
>+        } else if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME) {
>
>+            char b[15];
>
>+            struct tm *p, tmbuf;
>
>+            if (!(p = localtime_r(&t, &tmbuf)))
>
>+                return AVERROR(ENOMEM);
>
>+            if (!strftime(b, sizeof(b), "%Y%m%d%H%M%S", p))
>
>+                return AVERROR(ENOMEM);
>
>+            hls->start_sequence = strtoll(b, NULL, 10);
>
>+        }
>
>+        av_log(hls, AV_LOG_DEBUG, "start_number evaluated to %"PRId64"\n", hls->start_sequence);
>
>+    }
>
>+
>
>+    hls->recording_time = (hls->init_time ? hls->init_time : hls->time) * AV_TIME_BASE;
>
>+    for (i = 0; i < hls->nb_varstreams; i++) {
>
>+        vs = &hls->var_streams[i];
>
>+        vs->sequence       = hls->start_sequence;
>
>+        vs->start_pts      = AV_NOPTS_VALUE;
>
>+        vs->end_pts      = AV_NOPTS_VALUE;
>
>+        vs->current_segment_final_filename_fmt[0] = '\0';
>
>+
>
>+        if (hls->flags & HLS_SPLIT_BY_TIME && hls->flags & HLS_INDEPENDENT_SEGMENTS) {
>
>+            // Independent segments cannot be guaranteed when splitting by time
>
>+            hls->flags &= ~HLS_INDEPENDENT_SEGMENTS;
>
>+            av_log(s, AV_LOG_WARNING,
>
>+                   "'split_by_time' and 'independent_segments' cannot be enabled together. "
>
>+                   "Disabling 'independent_segments' flag\n");
>
>+        }
>
>+
>
>+        if (hls->flags & HLS_PROGRAM_DATE_TIME) {
>
>+            time_t now0;
>
>+            time(&now0);
>
>+            vs->initial_prog_date_time = now0;
>
>+        }
>
>+        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);
>
>+                goto fail;
>
>+            }
>
>+        }
>
>+
>
>+        for (j = 0; j < vs->nb_streams; j++) {
>
>+            vs->has_video += vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO;
>
>+            vs->has_subtitle += vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE;
>
>+        }
>
>+
>
>+        if (vs->has_video > 1)
>
>+            av_log(s, AV_LOG_WARNING, "More than a single video stream present, expect issues decoding it.\n");
>
>+        if (hls->segment_type == SEGMENT_TYPE_FMP4) {
>
>+            vs->oformat = av_guess_format("mp4", NULL, NULL);
>
>+        } else {
>
>+            vs->oformat = av_guess_format("mpegts", NULL, NULL);
>
>+        }
>
>+
>
>+        if (!vs->oformat) {
>
>+            ret = AVERROR_MUXER_NOT_FOUND;
>
>+            goto fail;
>
>+        }
>
>+
>
>+        if (vs->has_subtitle) {
>
>+            vs->vtt_oformat = av_guess_format("webvtt", NULL, NULL);
>
>+            if (!vs->oformat) {
>
>+                ret = AVERROR_MUXER_NOT_FOUND;
>
>+                goto fail;
>
>+            }
>
>+        }
>
>+        if (hls->segment_filename) {
>
>+            basename_size = strlen(hls->segment_filename) + 1;
>
>+            if (hls->nb_varstreams > 1) {
>
>+                basename_size += strlen(POSTFIX_PATTERN);
>
>+            }
>
>+            vs->basename = av_malloc(basename_size);
>
>+            if (!vs->basename) {
>
>+                ret = AVERROR(ENOMEM);
>
>+                goto fail;
>
>+            }
>
>+
>
>+            av_strlcpy(vs->basename, hls->segment_filename, basename_size);
>
>+        } else {
>
>+            if (hls->flags & HLS_SINGLE_FILE) {
>
>+                if (hls->segment_type == SEGMENT_TYPE_FMP4) {
>
>+                    pattern = ".m4s";
>
>+                } else {
>
>+                    pattern = ".ts";
>
>+                }
>
>+            }
>
>+
>
>+            if (hls->use_localtime) {
>
>+                basename_size = strlen(s->filename) + strlen(pattern_localtime_fmt) + 1;
>
>+            } else {
>
>+                basename_size = strlen(s->filename) + strlen(pattern) + 1;
>
>+            }
>
>+
>
>+            if (hls->nb_varstreams > 1) {
>
>+                basename_size += strlen(POSTFIX_PATTERN);
>
>+            }
>
>+
>
>+            vs->basename = av_malloc(basename_size);
>
>+            if (!vs->basename) {
>
>+                ret = AVERROR(ENOMEM);
>
>+                goto fail;
>
>+            }
>
>+
>
>+            av_strlcpy(vs->basename, s->filename, basename_size);
>
>+
>
>+            p = strrchr(vs->basename, '.');
>
>+            if (p)
>
>+                *p = '\0';
>
>+            if (hls->use_localtime) {
>
>+                av_strlcat(vs->basename, pattern_localtime_fmt, basename_size);
>
>+            } else {
>
>+                av_strlcat(vs->basename, pattern, basename_size);
>
>+            }
>
>+        }
>
>+
>
>+        m3u8_name_size = strlen(s->filename) + 1;
>
>+        if (hls->nb_varstreams > 1) {
>
>+            m3u8_name_size += strlen(POSTFIX_PATTERN);
>
>+        }
>
>+
>
>+        vs->m3u8_name = av_malloc(m3u8_name_size);
>
>+        if (!vs->m3u8_name ) {
>
>+            ret = AVERROR(ENOMEM);
>
>+            goto fail;
>
>+        }
>
>+
>
>+        av_strlcpy(vs->m3u8_name, s->filename, m3u8_name_size);
>
>+
>
>+        if (hls->nb_varstreams > 1) {
>
>+            ret = format_name(vs->basename, basename_size, i);
>
>+            if (ret < 0)
>
>+                goto fail;
>
>+            ret = format_name(vs->m3u8_name, m3u8_name_size, i);
>
>+            if (ret < 0)
>
>+                goto fail;
>
>+        }
>
>+
>
>+        if (hls->segment_type == SEGMENT_TYPE_FMP4) {
>
>+            if (hls->nb_varstreams > 1)
>
>+                fmp4_init_filename_len += strlen(POSTFIX_PATTERN);
>
>+            vs->fmp4_init_filename = av_malloc(fmp4_init_filename_len);
>
>+            if (!vs->fmp4_init_filename ) {
>
>+                ret = AVERROR(ENOMEM);
>
>+                goto fail;
>
>+            }
>
>+            av_strlcpy(vs->fmp4_init_filename, hls->fmp4_init_filename,
>
>+                       fmp4_init_filename_len);
>
>+            if (hls->nb_varstreams > 1) {
>
>+                ret = format_name(vs->fmp4_init_filename, fmp4_init_filename_len, i);
>
>+                if (ret < 0)
>
>+                    goto fail;
>
>+            }
>
>+
>
>+            if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) {
>
>+                fmp4_init_filename_len = strlen(vs->fmp4_init_filename) + 1;
>
>+                vs->base_output_dirname = av_malloc(fmp4_init_filename_len);
>
>+                if (!vs->base_output_dirname) {
>
>+                    ret = AVERROR(ENOMEM);
>
>+                    goto fail;
>
>+                }
>
>+                av_strlcpy(vs->base_output_dirname, vs->fmp4_init_filename,
>
>+                           fmp4_init_filename_len);
>
>+            } else {
>
>+                fmp4_init_filename_len = strlen(vs->m3u8_name) +
>
>+                    strlen(vs->fmp4_init_filename) + 1;
>
>+
>
>+                vs->base_output_dirname = av_malloc(fmp4_init_filename_len);
>
>+                if (!vs->base_output_dirname) {
>
>+                    ret = AVERROR(ENOMEM);
>
>+                    goto fail;
>
>+                }
>
>+
>
>+                av_strlcpy(vs->base_output_dirname, vs->m3u8_name,
>
>+                           fmp4_init_filename_len);
>
>+                p = strrchr(vs->base_output_dirname, '/');
>
>+                if (p) {
>
>+                    *(p + 1) = '\0';
>
>+                    av_strlcat(vs->base_output_dirname, vs->fmp4_init_filename,
>
>+                               fmp4_init_filename_len);
>
>+                } else {
>
>+                    av_strlcpy(vs->base_output_dirname, vs->fmp4_init_filename,
>
>+                               fmp4_init_filename_len);
>
>+                }
>
>+            }
>
>+        }
>
>+
>
>+        if (!hls->use_localtime) {
>
>+            ret = sls_flag_check_duration_size_index(hls);
>
>+            if (ret < 0) {
>
>+                goto fail;
>
>+            }
>
>+        } else {
>
>+            ret = sls_flag_check_duration_size(hls, vs);
>
>+            if (ret < 0) {
>
>+                goto fail;
>
>+            }
>
>+        }
>
>+        if (vs->has_subtitle) {
>
>+
>
>+            if (hls->flags & HLS_SINGLE_FILE)
>
>+                vtt_pattern = ".vtt";
>
>+            vtt_basename_size = strlen(s->filename) + strlen(vtt_pattern) + 1;
>
>+            if (hls->nb_varstreams > 1) {
>
>+                vtt_basename_size += strlen(POSTFIX_PATTERN);
>
>+            }
>
>+
>
>+            vs->vtt_basename = av_malloc(vtt_basename_size);
>
>+            if (!vs->vtt_basename) {
>
>+                ret = AVERROR(ENOMEM);
>
>+                goto fail;
>
>+            }
>
>+            vs->vtt_m3u8_name = av_malloc(vtt_basename_size);
>
>+            if (!vs->vtt_m3u8_name ) {
>
>+                ret = AVERROR(ENOMEM);
>
>+                goto fail;
>
>+            }
>
>+            av_strlcpy(vs->vtt_basename, s->filename, vtt_basename_size);
>
>+            p = strrchr(vs->vtt_basename, '.');
>
>+            if (p)
>
>+                *p = '\0';
>
>+
>
>+            if ( hls->subtitle_filename ) {
>
>+                strcpy(vs->vtt_m3u8_name, hls->subtitle_filename);
>
>+            } else {
>
>+                strcpy(vs->vtt_m3u8_name, vs->vtt_basename);
>
>+                av_strlcat(vs->vtt_m3u8_name, "_vtt.m3u8", vtt_basename_size);
>
>+            }
>
>+            av_strlcat(vs->vtt_basename, vtt_pattern, vtt_basename_size);
>
>+
>
>+            if (hls->nb_varstreams > 1) {
>
>+                ret= format_name(vs->vtt_basename, vtt_basename_size, i);
>
>+                if (ret < 0)
>
>+                    goto fail;
>
>+                ret = format_name(vs->vtt_m3u8_name, vtt_basename_size, i);
>
>+                if (ret < 0)
>
>+                    goto fail;
>
>+            }
>
>+        }
>
>+
>
>+        if (hls->baseurl) {
>
>+            vs->baseurl = av_strdup(hls->baseurl);
>
>+            if (!vs->baseurl) {
>
>+                ret = AVERROR(ENOMEM);
>
>+                goto fail;
>
>+            }
>
>+        }
>
>+
>
>+        if ((hls->flags & HLS_SINGLE_FILE) && (hls->segment_type == SEGMENT_TYPE_FMP4)) {
>
>+            vs->fmp4_init_filename  = av_strdup(vs->basename);
>
>+            if (!vs->fmp4_init_filename) {
>
>+                ret = AVERROR(ENOMEM);
>
>+                goto fail;
>
>+            }
>
>+        }
>
>+        if ((ret = hls_mux_init(s, vs)) < 0)
>
>+            goto fail;
>
>+
>
>+        if (hls->flags & HLS_APPEND_LIST) {
>
>+            parse_playlist(s, vs->m3u8_name, vs);
>
>+            vs->discontinuity = 1;
>
>+            if (hls->init_time > 0) {
>
>+                av_log(s, AV_LOG_WARNING, "append_list mode does not support hls_init_time,"
>
>+                       " hls_init_time value will have no effect\n");
>
>+                hls->init_time = 0;
>
>+                hls->recording_time = hls->time * AV_TIME_BASE;
>
>+            }
>
>+        }
>
>+
>
>+        if (hls->segment_type != SEGMENT_TYPE_FMP4 || hls->flags & HLS_SINGLE_FILE) {
>
>+            if ((ret = hls_start(s, vs)) < 0)
>
>+                goto fail;
>
>+        }
>
>+    }
>
>+
>
>+fail:
>
>+    if (ret < 0) {
>
>+        av_freep(&hls->key_basename);
>
>+        for (i = 0; i < hls->nb_varstreams && hls->var_streams; i++) {
>
>+            vs = &hls->var_streams[i];
>
>+            av_freep(&vs->basename);
>
>+            av_freep(&vs->vtt_basename);
>
>+            av_freep(&vs->fmp4_init_filename);
>
>+            av_freep(&vs->m3u8_name);
>
>+            av_freep(&vs->vtt_m3u8_name);
>
>+            av_freep(&vs->streams);
>
>+            av_freep(&vs->baseurl);
>
>+            if (vs->avf)
>
>+                avformat_free_context(vs->avf);
>
>+            if (vs->vtt_avf)
>
>+                avformat_free_context(vs->vtt_avf);
>
>+        }
>
>+        av_freep(&hls->var_streams);
>
>+        av_freep(&hls->master_m3u8_url);
>
>+    }
>
>+
>
>+    return ret;
>
>+}
>
>+
>
> #define OFFSET(x) offsetof(HLSContext, x)
>
> #define E AV_OPT_FLAG_ENCODING_PARAM
>
> static const AVOption options[] = {
>
>@@ -2332,6 +2340,7 @@ AVOutputFormat ff_hls_muxer = {
>
>     .video_codec    = AV_CODEC_ID_H264,
>
>     .subtitle_codec = AV_CODEC_ID_WEBVTT,
>
>     .flags          = AVFMT_NOFILE | AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
>
>+    .init           = hls_init,
>
>     .write_header   = hls_write_header,
>
>     .write_packet   = hls_write_packet,
>
>     .write_trailer  = hls_write_trailer,
>
>-- 
>
>2.13.6 (Apple Git-96)
>
>
>
>
>
>
>
>_______________________________________________
>
>ffmpeg-devel mailing list
>
>ffmpeg-devel at ffmpeg.org
>
>http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>
>
>
LGTM



More information about the ffmpeg-devel mailing list