[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