avformat/hlsenc: Added option to add EXT-X-INDEPENDENT-SEGMENTS tag

This commit is contained in:
Karthick J 2017-11-24 06:57:36 +08:00 committed by Steven Liu
parent 241c1192d6
commit efb51c8ebb
2 changed files with 21 additions and 0 deletions

View File

@ -737,6 +737,10 @@ The file specified by @code{hls_key_info_file} will be checked periodically and
detect updates to the encryption info. Be sure to replace this file atomically, detect updates to the encryption info. Be sure to replace this file atomically,
including the file containing the AES encryption key. including the file containing the AES encryption key.
@item independent_segments
Add the @code{#EXT-X-INDEPENDENT-SEGMENTS} to playlists that has video segments
and when all the segments of that playlist are guaranteed to start with a Key frame.
@item split_by_time @item split_by_time
Allow segments to start on frames other than keyframes. This improves Allow segments to start on frames other than keyframes. This improves
behavior on some players when the time between keyframes is inconsistent, behavior on some players when the time between keyframes is inconsistent,

View File

@ -88,6 +88,7 @@ typedef enum HLSFlags {
HLS_SECOND_LEVEL_SEGMENT_SIZE = (1 << 10), // include segment size (bytes) in segment filenames when use_localtime e.g.: %%014s HLS_SECOND_LEVEL_SEGMENT_SIZE = (1 << 10), // include segment size (bytes) in segment filenames when use_localtime e.g.: %%014s
HLS_TEMP_FILE = (1 << 11), HLS_TEMP_FILE = (1 << 11),
HLS_PERIODIC_REKEY = (1 << 12), HLS_PERIODIC_REKEY = (1 << 12),
HLS_INDEPENDENT_SEGMENTS = (1 << 13),
} HLSFlags; } HLSFlags;
typedef enum { typedef enum {
@ -1190,6 +1191,10 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
sequence = 0; sequence = 0;
} }
if (hls->flags & HLS_INDEPENDENT_SEGMENTS) {
hls->version = 6;
}
if (hls->segment_type == SEGMENT_TYPE_FMP4) { if (hls->segment_type == SEGMENT_TYPE_FMP4) {
hls->version = 7; hls->version = 7;
} }
@ -1219,6 +1224,9 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
avio_printf(out, "#EXT-X-DISCONTINUITY\n"); avio_printf(out, "#EXT-X-DISCONTINUITY\n");
vs->discontinuity_set = 1; vs->discontinuity_set = 1;
} }
if (vs->has_video && (hls->flags & HLS_INDEPENDENT_SEGMENTS)) {
avio_printf(out, "#EXT-X-INDEPENDENT-SEGMENTS\n");
}
for (en = vs->segments; en; en = en->next) { for (en = vs->segments; en; en = en->next) {
if ((hls->encrypt || hls->key_info_file) && (!key_uri || strcmp(en->key_uri, key_uri) || if ((hls->encrypt || hls->key_info_file) && (!key_uri || strcmp(en->key_uri, key_uri) ||
av_strcasecmp(en->iv_string, iv_string))) { av_strcasecmp(en->iv_string, iv_string))) {
@ -1731,6 +1739,14 @@ static int hls_write_header(AVFormatContext *s)
vs->start_pts = AV_NOPTS_VALUE; vs->start_pts = AV_NOPTS_VALUE;
vs->current_segment_final_filename_fmt[0] = '\0'; 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) { if (hls->flags & HLS_PROGRAM_DATE_TIME) {
time_t now0; time_t now0;
time(&now0); time(&now0);
@ -2322,6 +2338,7 @@ static const AVOption options[] = {
{"second_level_segment_duration", "include segment duration in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_DURATION }, 0, UINT_MAX, E, "flags"}, {"second_level_segment_duration", "include segment duration in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_DURATION }, 0, UINT_MAX, E, "flags"},
{"second_level_segment_size", "include segment size in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_SIZE }, 0, UINT_MAX, E, "flags"}, {"second_level_segment_size", "include segment size in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_SIZE }, 0, UINT_MAX, E, "flags"},
{"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX, E, "flags"}, {"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX, E, "flags"},
{"independent_segments", "add EXT-X-INDEPENDENT-SEGMENTS, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_INDEPENDENT_SEGMENTS }, 0, UINT_MAX, E, "flags"},
{"use_localtime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, {"use_localtime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
{"use_localtime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, {"use_localtime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
{"hls_playlist_type", "set the HLS playlist type", OFFSET(pl_type), AV_OPT_TYPE_INT, {.i64 = PLAYLIST_TYPE_NONE }, 0, PLAYLIST_TYPE_NB-1, E, "pl_type" }, {"hls_playlist_type", "set the HLS playlist type", OFFSET(pl_type), AV_OPT_TYPE_INT, {.i64 = PLAYLIST_TYPE_NONE }, 0, PLAYLIST_TYPE_NB-1, E, "pl_type" },