unsigned int nb_streams;
int m3u8_created; /* status of media play-list creation */
int is_default; /* default status of audio group */
- char *language; /* audio lauguage name */
- char *agroup; /* audio group name */
- char *sgroup; /* subtitle group name */
- char *ccgroup; /* closed caption group name */
- char *baseurl;
- char *varname; // variant name
+ const char *language; /* audio lauguage name */
+ const char *agroup; /* audio group name */
+ const char *sgroup; /* subtitle group name */
+ const char *ccgroup; /* closed caption group name */
+ const char *varname; /* variant name */
} VariantStream;
typedef struct ClosedCaptionsStream {
- char *ccgroup; /* closed caption group name */
- char *instreamid; /* closed captions INSTREAM-ID */
- char *language; /* closed captions langauge */
+ const char *ccgroup; /* closed caption group name */
+ const char *instreamid; /* closed captions INSTREAM-ID */
+ const char *language; /* closed captions langauge */
} ClosedCaptionsStream;
typedef struct HLSContext {
int addchar_count;
int found_count = 0;
AVBPrint buf;
+ int ret;
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
}
if (!av_bprint_is_complete(&buf)) {
av_bprint_finalize(&buf, NULL);
- return -1;
+ return AVERROR(ENOMEM);
}
- if (av_bprint_finalize(&buf, &new_filename) < 0 || !new_filename)
- return -1;
+ if ((ret = av_bprint_finalize(&buf, &new_filename)) < 0)
+ return ret;
*s = new_filename;
return found_count;
}
int nd, addchar_count;
int found_count = 0;
AVBPrint buf;
+ int ret;
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
}
if (!av_bprint_is_complete(&buf)) {
av_bprint_finalize(&buf, NULL);
- return -1;
+ return AVERROR(ENOMEM);
}
- if (av_bprint_finalize(&buf, &new_filename) < 0 || !new_filename)
- return -1;
+ if ((ret = av_bprint_finalize(&buf, &new_filename)) < 0)
+ return ret;
*s = new_filename;
return found_count;
}
int ret = 0;
int segment_cnt = 0;
AVBPrint path;
- char *dirname = NULL;
+ const char *dirname = NULL;
char *dirname_r = NULL;
char *dirname_repl = NULL;
- char *vtt_dirname = NULL;
+ const char *vtt_dirname = NULL;
char *vtt_dirname_r = NULL;
const char *proto = NULL;
if (segment && !hls->use_localtime_mkdir) {
dirname_r = hls->segment_filename ? av_strdup(hls->segment_filename): av_strdup(vs->avf->url);
- dirname = (char*)av_dirname(dirname_r);
+ dirname = av_dirname(dirname_r);
}
/* if %v is present in the file's directory
if ((segment->sub_filename[0] != '\0')) {
vtt_dirname_r = av_strdup(vs->vtt_avf->url);
- vtt_dirname = (char*)av_dirname(vtt_dirname_r);
+ vtt_dirname = av_dirname(vtt_dirname_r);
av_bprint_clear(&path);
av_bprintf(&path, "%s%c%s", vtt_dirname, SEPARATOR,
av_dict_copy(&st->metadata, vs->streams[i]->metadata, 0);
}
- vs->packets_written = 1;
vs->start_pos = 0;
vs->new_start = 1;
}
}
- vs->packets_written = 0;
- vs->init_range_length = 0;
-
if ((ret = avio_open_dyn_buf(&oc->pb)) < 0)
return ret;
int ret, bandwidth;
const char *m3u8_rel_name = NULL;
const char *vtt_m3u8_rel_name = NULL;
- char *ccgroup;
- char *sgroup = NULL;
+ const char *ccgroup;
+ const char *sgroup = NULL;
ClosedCaptionsStream *ccs;
const char *proto = avio_find_protocol_name(hls->master_m3u8_url);
int is_file_proto = proto && !strcmp(proto, "file");
ret = ff_hls_write_file_entry(byterange_mode ? hls->m3u8_out : vs->out, en->discont, byterange_mode,
en->duration, hls->flags & HLS_ROUND_DURATIONS,
- en->size, en->pos, vs->baseurl,
+ en->size, en->pos, hls->baseurl,
en->filename, prog_date_time_p, en->keyframe_size, en->keyframe_pos, hls->flags & HLS_I_FRAMES_ONLY);
if (ret < 0) {
av_log(s, AV_LOG_WARNING, "ff_hls_write_file_entry get error\n");
for (en = vs->segments; en; en = en->next) {
ret = ff_hls_write_file_entry(hls->sub_m3u8_out, 0, byterange_mode,
en->duration, 0, en->size, en->pos,
- vs->baseurl, en->sub_filename, NULL, 0, 0, 0);
+ hls->baseurl, en->sub_filename, NULL, 0, 0, 0);
if (ret < 0) {
av_log(s, AV_LOG_WARNING, "ff_hls_write_file_entry get error\n");
}
ff_format_set_url(vtt_oc, filename);
}
}
- vs->number++;
proto = avio_find_protocol_name(oc->url);
use_temp_file = proto && !strcmp(proto, "file") && (c->flags & HLS_TEMP_FILE);
return AVERROR(EINVAL);
q = varstr;
- while (q < varstr + strlen(varstr)) {
+ while (1) {
if (!av_strncasecmp(q, "a:", 2) || !av_strncasecmp(q, "v:", 2) ||
!av_strncasecmp(q, "s:", 2))
vs->nb_streams++;
+ q = strchr(q, ',');
+ if (!q)
+ break;
q++;
}
vs->streams = av_mallocz(sizeof(AVStream *) * vs->nb_streams);
char *end;
varstr = NULL;
if (av_strstart(keyval, "language:", &val)) {
- av_free(vs->language);
- vs->language = av_strdup(val);
- if (!vs->language)
- return AVERROR(ENOMEM);
+ vs->language = val;
continue;
} else if (av_strstart(keyval, "default:", &val)) {
vs->is_default = (!av_strncasecmp(val, "YES", strlen("YES")) ||
hls->has_default_key = 1;
continue;
} else if (av_strstart(keyval, "name:", &val)) {
- av_free(vs->varname);
- vs->varname = av_strdup(val);
- if (!vs->varname)
- return AVERROR(ENOMEM);
+ vs->varname = val;
continue;
} else if (av_strstart(keyval, "agroup:", &val)) {
- av_free(vs->agroup);
- vs->agroup = av_strdup(val);
- if (!vs->agroup)
- return AVERROR(ENOMEM);
+ vs->agroup = val;
continue;
} else if (av_strstart(keyval, "sgroup:", &val)) {
- av_free(vs->sgroup);
- vs->sgroup = av_strdup(val);
- if (!vs->sgroup)
- return AVERROR(ENOMEM);
+ vs->sgroup = val;
continue;
} else if (av_strstart(keyval, "ccgroup:", &val)) {
- av_free(vs->ccgroup);
- vs->ccgroup = av_strdup(val);
- if (!vs->ccgroup)
- return AVERROR(ENOMEM);
+ vs->ccgroup = val;
continue;
} else if (av_strstart(keyval, "v:", &val)) {
codec_type = AVMEDIA_TYPE_VIDEO;
return AVERROR(EINVAL);
}
- num = strtoll(val, &end, 0);
+ num = strtoll(val, &end, 10);
if (!av_isdigit(*val) || *end != '\0') {
av_log(s, AV_LOG_ERROR, "Invalid stream number: '%s'\n", val);
return AVERROR(EINVAL);
ccstr = NULL;
if (av_strstart(keyval, "ccgroup:", &val)) {
- av_free(ccs->ccgroup);
- ccs->ccgroup = av_strdup(val);
- if (!ccs->ccgroup)
- return AVERROR(ENOMEM);
+ ccs->ccgroup = val;
} else if (av_strstart(keyval, "instreamid:", &val)) {
- av_free(ccs->instreamid);
- ccs->instreamid = av_strdup(val);
- if (!ccs->instreamid)
- return AVERROR(ENOMEM);
+ ccs->instreamid = val;
} else if (av_strstart(keyval, "language:", &val)) {
- av_free(ccs->language);
- ccs->language = av_strdup(val);
- if (!ccs->language)
- return AVERROR(ENOMEM);
+ ccs->language = val;
} else {
av_log(s, AV_LOG_ERROR, "Invalid keyval %s\n", keyval);
return AVERROR(EINVAL);
return AVERROR(ENOMEM);
//by default, the first available ccgroup is mapped to the variant stream
- if (hls->nb_ccstreams) {
- hls->var_streams[0].ccgroup = av_strdup(hls->cc_streams[0].ccgroup);
- if (!hls->var_streams[0].ccgroup)
- return AVERROR(ENOMEM);
- }
+ if (hls->nb_ccstreams)
+ hls->var_streams[0].ccgroup = hls->cc_streams[0].ccgroup;
for (i = 0; i < s->nb_streams; i++)
hls->var_streams[0].streams[i] = s->streams[i];
vs->start_pts_from_audio = 0;
}
- if (vs->has_video) {
+ if (vs->has_video) {
can_split = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
((pkt->flags & AV_PKT_FLAG_KEY) || (hls->flags & HLS_SPLIT_BY_TIME));
is_ref_pkt = (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && (pkt->stream_index == vs->reference_stream_index);
if (ret < 0) {
av_log(s, hls->ignore_io_errors ? AV_LOG_WARNING : AV_LOG_ERROR,
"Failed to open file '%s'\n", filename);
+ av_freep(&filename);
av_dict_free(&options);
return hls->ignore_io_errors ? 0 : ret;
}
}
ret = flush_dynbuf(vs, &range_length);
if (ret < 0) {
+ av_freep(&filename);
av_dict_free(&options);
return ret;
}
}
if (hls->flags & HLS_SINGLE_FILE) {
- vs->number++;
vs->start_pos += vs->size;
} else if (hls->max_seg_size > 0) {
vs->start_pos = new_start_pos;
vs->start_pos = 0;
/* When split segment by byte, the duration is short than hls_time,
* so it is not enough one segment duration as hls_time, */
- vs->number--;
}
- vs->number++;
} else {
vs->start_pos = new_start_pos;
sls_flag_file_rename(hls, vs, old_filename);
ret = hls_start(s, vs);
}
+ vs->number++;
av_freep(&old_filename);
if (ret < 0) {
hls_free_segments(vs->old_segments);
av_freep(&vs->m3u8_name);
av_freep(&vs->streams);
- av_freep(&vs->agroup);
- av_freep(&vs->sgroup);
- av_freep(&vs->language);
- av_freep(&vs->ccgroup);
- av_freep(&vs->baseurl);
- av_freep(&vs->varname);
- }
-
- for (i = 0; i < hls->nb_ccstreams; i++) {
- ClosedCaptionsStream *ccs = &hls->cc_streams[i];
-
- av_freep(&ccs->ccgroup);
- av_freep(&ccs->instreamid);
- av_freep(&ccs->language);
}
ff_format_io_close(s, &hls->m3u8_out);
if (ret < 0)
av_log(s, AV_LOG_WARNING, "Failed to upload file '%s' at the end.\n", oc->url);
}
- av_freep(&vs->temp_buffer);
failed:
+ av_freep(&vs->temp_buffer);
+ av_dict_free(&options);
av_freep(&filename);
av_write_trailer(oc);
if (oc->url[0]) {
int i = 0;
int j = 0;
HLSContext *hls = s->priv_data;
- const char *pattern = "%d.ts";
+ const char *pattern;
VariantStream *vs = NULL;
- int basename_size = 0;
- const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt(s);
- const char *vtt_pattern = "%d.vtt";
+ const char *vtt_pattern = hls->flags & HLS_SINGLE_FILE ? ".vtt" : "%d.vtt";
char *p = NULL;
- int vtt_basename_size = 0;
int http_base_proto = ff_is_http_proto(s->url);
int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1;
+ if (hls->use_localtime) {
+ pattern = get_default_pattern_localtime_fmt(s);
+ } else {
+ pattern = hls->segment_type == SEGMENT_TYPE_FMP4 ? "%d.m4s" : "%d.ts";
+ if (hls->flags & HLS_SINGLE_FILE)
+ pattern += 2;
+ }
+
hls->has_default_key = 0;
hls->has_video_m3u8 = 0;
ret = update_variant_stream_info(s);
}
}
- 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_MICROSECONDS_SINCE_EPOCH) ||
(hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME)) {
if (ret < 0)
return ret;
} 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(vs->m3u8_name) + strlen(pattern_localtime_fmt) + 1;
- } else {
- basename_size = strlen(vs->m3u8_name) + strlen(pattern) + 1;
- }
+ p = strrchr(vs->m3u8_name, '.');
+ if (p)
+ *p = '\0';
- vs->basename = av_malloc(basename_size);
+ vs->basename = av_asprintf("%s%s", vs->m3u8_name, pattern);
if (!vs->basename)
return AVERROR(ENOMEM);
- av_strlcpy(vs->basename, vs->m3u8_name, 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);
- }
+ *p = '.';
}
if (hls->segment_type == SEGMENT_TYPE_FMP4) {
return ret;
}
- 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)
- return AVERROR(ENOMEM);
-
- av_strlcpy(vs->base_output_dirname, vs->m3u8_name,
- fmp4_init_filename_len);
- p = strrchr(vs->base_output_dirname, '/');
+ p = strrchr(vs->m3u8_name, '/');
if (p) {
- *(p + 1) = '\0';
- av_strlcat(vs->base_output_dirname, vs->fmp4_init_filename,
- fmp4_init_filename_len);
+ char tmp = *(++p);
+ *p = '\0';
+ vs->base_output_dirname = av_asprintf("%s%s", vs->m3u8_name,
+ vs->fmp4_init_filename);
+ *p = tmp;
} else {
- av_strlcpy(vs->base_output_dirname, vs->fmp4_init_filename,
- fmp4_init_filename_len);
+ vs->base_output_dirname = av_strdup(vs->fmp4_init_filename);
}
+ if (!vs->base_output_dirname)
+ return AVERROR(ENOMEM);
}
}
if (!vs->vtt_oformat)
return AVERROR_MUXER_NOT_FOUND;
- if (hls->flags & HLS_SINGLE_FILE)
- vtt_pattern = ".vtt";
- vtt_basename_size = strlen(vs->m3u8_name) + strlen(vtt_pattern) + 1;
+ p = strrchr(vs->m3u8_name, '.');
+ if (p)
+ *p = '\0';
- vs->vtt_basename = av_malloc(vtt_basename_size);
+ vs->vtt_basename = av_asprintf("%s%s", vs->m3u8_name, vtt_pattern);
if (!vs->vtt_basename)
return AVERROR(ENOMEM);
- av_strlcpy(vs->vtt_basename, vs->m3u8_name, vtt_basename_size);
- p = strrchr(vs->vtt_basename, '.');
- if (p)
- *p = '\0';
if (hls->subtitle_filename) {
ret = format_name(hls->subtitle_filename, &vs->vtt_m3u8_name, i, vs->varname);
if (ret < 0)
return ret;
} else {
- vs->vtt_m3u8_name = av_asprintf("%s_vtt.m3u8", vs->vtt_basename);
+ vs->vtt_m3u8_name = av_asprintf("%s_vtt.m3u8", vs->m3u8_name);
if (!vs->vtt_m3u8_name)
return AVERROR(ENOMEM);
}
- av_strlcat(vs->vtt_basename, vtt_pattern, vtt_basename_size);
- }
-
- if (hls->baseurl) {
- vs->baseurl = av_strdup(hls->baseurl);
- if (!vs->baseurl)
- return AVERROR(ENOMEM);
+ if (p)
+ *p = '.';
}
if ((ret = hls_mux_init(s, vs)) < 0)
if ((ret = hls_start(s, vs)) < 0)
return ret;
+ vs->number++;
}
return ret;