]> git.sesse.net Git - ffmpeg/blob - libavformat/hlsenc.c
Merge commit '9e48de3cc86c732d9cebd496d6f0a2b7e7732754'
[ffmpeg] / libavformat / hlsenc.c
1 /*
2  * Apple HTTP Live Streaming segmenter
3  * Copyright (c) 2012, Luca Barbato
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include "config.h"
23 #include <float.h>
24 #include <stdint.h>
25 #if HAVE_UNISTD_H
26 #include <unistd.h>
27 #endif
28
29 #if CONFIG_GCRYPT
30 #include <gcrypt.h>
31 #elif CONFIG_OPENSSL
32 #include <openssl/rand.h>
33 #endif
34
35 #include "libavutil/avassert.h"
36 #include "libavutil/mathematics.h"
37 #include "libavutil/parseutils.h"
38 #include "libavutil/avstring.h"
39 #include "libavutil/intreadwrite.h"
40 #include "libavutil/random_seed.h"
41 #include "libavutil/opt.h"
42 #include "libavutil/log.h"
43 #include "libavutil/time_internal.h"
44
45 #include "avformat.h"
46 #include "avio_internal.h"
47 #include "internal.h"
48 #include "os_support.h"
49
50 typedef enum {
51   HLS_START_SEQUENCE_AS_START_NUMBER = 0,
52   HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH = 1,
53   HLS_START_SEQUENCE_AS_FORMATTED_DATETIME = 2,  // YYYYMMDDhhmmss
54 } StartSequenceSourceType;
55
56 #define KEYSIZE 16
57 #define LINE_BUFFER_SIZE 1024
58 #define HLS_MICROSECOND_UNIT   1000000
59
60 typedef struct HLSSegment {
61     char filename[1024];
62     char sub_filename[1024];
63     double duration; /* in seconds */
64     int discont;
65     int64_t pos;
66     int64_t size;
67
68     char key_uri[LINE_BUFFER_SIZE + 1];
69     char iv_string[KEYSIZE*2 + 1];
70
71     struct HLSSegment *next;
72 } HLSSegment;
73
74 typedef enum HLSFlags {
75     // Generate a single media file and use byte ranges in the playlist.
76     HLS_SINGLE_FILE = (1 << 0),
77     HLS_DELETE_SEGMENTS = (1 << 1),
78     HLS_ROUND_DURATIONS = (1 << 2),
79     HLS_DISCONT_START = (1 << 3),
80     HLS_OMIT_ENDLIST = (1 << 4),
81     HLS_SPLIT_BY_TIME = (1 << 5),
82     HLS_APPEND_LIST = (1 << 6),
83     HLS_PROGRAM_DATE_TIME = (1 << 7),
84     HLS_SECOND_LEVEL_SEGMENT_INDEX = (1 << 8), // include segment index in segment filenames when use_localtime  e.g.: %%03d
85     HLS_SECOND_LEVEL_SEGMENT_DURATION = (1 << 9), // include segment duration (microsec) in segment filenames when use_localtime  e.g.: %%09t
86     HLS_SECOND_LEVEL_SEGMENT_SIZE = (1 << 10), // include segment size (bytes) in segment filenames when use_localtime  e.g.: %%014s
87     HLS_TEMP_FILE = (1 << 11),
88     HLS_PERIODIC_REKEY = (1 << 12),
89 } HLSFlags;
90
91 typedef enum {
92     SEGMENT_TYPE_MPEGTS,
93     SEGMENT_TYPE_FMP4,
94 } SegmentType;
95
96 typedef enum {
97     PLAYLIST_TYPE_NONE,
98     PLAYLIST_TYPE_EVENT,
99     PLAYLIST_TYPE_VOD,
100     PLAYLIST_TYPE_NB,
101 } PlaylistType;
102
103 typedef struct HLSContext {
104     const AVClass *class;  // Class for private options.
105     unsigned number;
106     int64_t sequence;
107     int64_t start_sequence;
108     uint32_t start_sequence_source_type;  // enum StartSequenceSourceType
109     AVOutputFormat *oformat;
110     AVOutputFormat *vtt_oformat;
111     AVIOContext *out;
112     int packets_written;
113     int init_range_length;
114
115     AVFormatContext *avf;
116     AVFormatContext *vtt_avf;
117
118     float time;            // Set by a private option.
119     float init_time;       // Set by a private option.
120     int max_nb_segments;   // Set by a private option.
121 #if FF_API_HLS_WRAP
122     int  wrap;             // Set by a private option.
123 #endif
124     uint32_t flags;        // enum HLSFlags
125     uint32_t pl_type;      // enum PlaylistType
126     char *segment_filename;
127     char *fmp4_init_filename;
128     int segment_type;
129     int fmp4_init_mode;
130
131     int use_localtime;      ///< flag to expand filename with localtime
132     int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename
133     int allowcache;
134     int64_t recording_time;
135     int has_video;
136     int has_subtitle;
137     int new_start;
138     double dpp;           // duration per packet
139     int64_t start_pts;
140     int64_t end_pts;
141     double duration;      // last segment duration computed so far, in seconds
142     int64_t start_pos;    // last segment starting position
143     int64_t size;         // last segment size
144     int64_t max_seg_size; // every segment file max size
145     int nb_entries;
146     int discontinuity_set;
147     int discontinuity;
148
149     HLSSegment *segments;
150     HLSSegment *last_segment;
151     HLSSegment *old_segments;
152
153     char *basename;
154     char *base_output_dirname;
155     char *vtt_basename;
156     char *vtt_m3u8_name;
157     char *baseurl;
158     char *format_options_str;
159     char *vtt_format_options_str;
160     char *subtitle_filename;
161     AVDictionary *format_options;
162
163     int encrypt;
164     char *key;
165     char *key_url;
166     char *iv;
167     char *key_basename;
168
169     char *key_info_file;
170     char key_file[LINE_BUFFER_SIZE + 1];
171     char key_uri[LINE_BUFFER_SIZE + 1];
172     char key_string[KEYSIZE*2 + 1];
173     char iv_string[KEYSIZE*2 + 1];
174     AVDictionary *vtt_format_options;
175
176     char *method;
177
178     double initial_prog_date_time;
179     char current_segment_final_filename_fmt[1024]; // when renaming segments
180     char *user_agent;
181 } HLSContext;
182
183 static int get_int_from_double(double val)
184 {
185     return (int)((val - (int)val) >= 0.001) ? (int)(val + 1) : (int)val;
186 }
187
188 static int mkdir_p(const char *path) {
189     int ret = 0;
190     char *temp = av_strdup(path);
191     char *pos = temp;
192     char tmp_ch = '\0';
193
194     if (!path || !temp) {
195         return -1;
196     }
197
198     if (!strncmp(temp, "/", 1) || !strncmp(temp, "\\", 1)) {
199         pos++;
200     } else if (!strncmp(temp, "./", 2) || !strncmp(temp, ".\\", 2)) {
201         pos += 2;
202     }
203
204     for ( ; *pos != '\0'; ++pos) {
205         if (*pos == '/' || *pos == '\\') {
206             tmp_ch = *pos;
207             *pos = '\0';
208             ret = mkdir(temp, 0755);
209             *pos = tmp_ch;
210         }
211     }
212
213     if ((*(pos - 1) != '/') || (*(pos - 1) != '\\')) {
214         ret = mkdir(temp, 0755);
215     }
216
217     av_free(temp);
218     return ret;
219 }
220
221 static void set_http_options(AVFormatContext *s, AVDictionary **options, HLSContext *c)
222 {
223     const char *proto = avio_find_protocol_name(s->filename);
224     int http_base_proto = proto ? (!av_strcasecmp(proto, "http") || !av_strcasecmp(proto, "https")) : 0;
225
226     if (c->method) {
227         av_dict_set(options, "method", c->method, 0);
228     } else if (http_base_proto) {
229         av_log(c, AV_LOG_WARNING, "No HTTP method set, hls muxer defaulting to method PUT.\n");
230         av_dict_set(options, "method", "PUT", 0);
231     }
232     if (c->user_agent)
233         av_dict_set(options, "user_agent", c->user_agent, 0);
234
235 }
236
237 static int replace_int_data_in_filename(char *buf, int buf_size, const char *filename, char placeholder, int64_t number)
238 {
239     const char *p;
240     char *q, buf1[20], c;
241     int nd, len, addchar_count;
242     int found_count = 0;
243
244     q = buf;
245     p = filename;
246     for (;;) {
247         c = *p;
248         if (c == '\0')
249             break;
250         if (c == '%' && *(p+1) == '%')  // %%
251             addchar_count = 2;
252         else if (c == '%' && (av_isdigit(*(p+1)) || *(p+1) == placeholder)) {
253             nd = 0;
254             addchar_count = 1;
255             while (av_isdigit(*(p + addchar_count))) {
256                 nd = nd * 10 + *(p + addchar_count) - '0';
257                 addchar_count++;
258             }
259
260             if (*(p + addchar_count) == placeholder) {
261                 len = snprintf(buf1, sizeof(buf1), "%0*"PRId64, (number < 0) ? nd : nd++, number);
262                 if (len < 1)  // returned error or empty buf1
263                     goto fail;
264                 if ((q - buf + len) > buf_size - 1)
265                     goto fail;
266                 memcpy(q, buf1, len);
267                 q += len;
268                 p += (addchar_count + 1);
269                 addchar_count = 0;
270                 found_count++;
271             }
272
273         } else
274             addchar_count = 1;
275
276         while (addchar_count--)
277             if ((q - buf) < buf_size - 1)
278                 *q++ = *p++;
279             else
280                 goto fail;
281     }
282     *q = '\0';
283     return found_count;
284 fail:
285     *q = '\0';
286     return -1;
287 }
288
289 static void write_styp(AVIOContext *pb)
290 {
291     avio_wb32(pb, 24);
292     ffio_wfourcc(pb, "styp");
293     ffio_wfourcc(pb, "msdh");
294     avio_wb32(pb, 0); /* minor */
295     ffio_wfourcc(pb, "msdh");
296     ffio_wfourcc(pb, "msix");
297 }
298
299 static int hls_delete_old_segments(AVFormatContext *s, HLSContext *hls) {
300
301     HLSSegment *segment, *previous_segment = NULL;
302     float playlist_duration = 0.0f;
303     int ret = 0, path_size, sub_path_size;
304     char *dirname = NULL, *p, *sub_path;
305     char *path = NULL;
306     AVDictionary *options = NULL;
307     AVIOContext *out = NULL;
308     const char *proto = NULL;
309
310     segment = hls->segments;
311     while (segment) {
312         playlist_duration += segment->duration;
313         segment = segment->next;
314     }
315
316     segment = hls->old_segments;
317     while (segment) {
318         playlist_duration -= segment->duration;
319         previous_segment = segment;
320         segment = previous_segment->next;
321         if (playlist_duration <= -previous_segment->duration) {
322             previous_segment->next = NULL;
323             break;
324         }
325     }
326
327     if (segment && !hls->use_localtime_mkdir) {
328         if (hls->segment_filename) {
329             dirname = av_strdup(hls->segment_filename);
330         } else {
331             dirname = av_strdup(hls->avf->filename);
332         }
333         if (!dirname) {
334             ret = AVERROR(ENOMEM);
335             goto fail;
336         }
337         p = (char *)av_basename(dirname);
338         *p = '\0';
339     }
340
341     while (segment) {
342         av_log(hls, AV_LOG_DEBUG, "deleting old segment %s\n",
343                                   segment->filename);
344         path_size =  (hls->use_localtime_mkdir ? 0 : strlen(dirname)) + strlen(segment->filename) + 1;
345         path = av_malloc(path_size);
346         if (!path) {
347             ret = AVERROR(ENOMEM);
348             goto fail;
349         }
350
351         if (hls->use_localtime_mkdir)
352             av_strlcpy(path, segment->filename, path_size);
353         else { // segment->filename contains basename only
354             av_strlcpy(path, dirname, path_size);
355             av_strlcat(path, segment->filename, path_size);
356         }
357
358         proto = avio_find_protocol_name(s->filename);
359         if (hls->method || (proto && !av_strcasecmp(proto, "http"))) {
360             av_dict_set(&options, "method", "DELETE", 0);
361             if ((ret = hls->avf->io_open(hls->avf, &out, path, AVIO_FLAG_WRITE, &options)) < 0)
362                 goto fail;
363             ff_format_io_close(hls->avf, &out);
364         } else if (unlink(path) < 0) {
365             av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n",
366                                      path, strerror(errno));
367         }
368
369         if ((segment->sub_filename[0] != '\0')) {
370             sub_path_size = strlen(segment->sub_filename) + 1 + (dirname ? strlen(dirname) : 0);
371             sub_path = av_malloc(sub_path_size);
372             if (!sub_path) {
373                 ret = AVERROR(ENOMEM);
374                 goto fail;
375             }
376
377             av_strlcpy(sub_path, dirname, sub_path_size);
378             av_strlcat(sub_path, segment->sub_filename, sub_path_size);
379
380             if (hls->method || (proto && !av_strcasecmp(proto, "http"))) {
381                 av_dict_set(&options, "method", "DELETE", 0);
382                 if ((ret = hls->avf->io_open(hls->avf, &out, sub_path, AVIO_FLAG_WRITE, &options)) < 0) {
383                     av_free(sub_path);
384                     goto fail;
385                 }
386                 ff_format_io_close(hls->avf, &out);
387             } else if (unlink(sub_path) < 0) {
388                 av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n",
389                                          sub_path, strerror(errno));
390             }
391             av_free(sub_path);
392         }
393         av_freep(&path);
394         previous_segment = segment;
395         segment = previous_segment->next;
396         av_free(previous_segment);
397     }
398
399 fail:
400     av_free(path);
401     av_free(dirname);
402
403     return ret;
404 }
405
406 static int randomize(uint8_t *buf, int len)
407 {
408 #if CONFIG_GCRYPT
409     gcry_randomize(buf, len, GCRY_VERY_STRONG_RANDOM);
410     return 0;
411 #elif CONFIG_OPENSSL
412     if (RAND_bytes(buf, len))
413         return 0;
414 #else
415     return AVERROR(ENOSYS);
416 #endif
417     return AVERROR(EINVAL);
418 }
419
420 static int do_encrypt(AVFormatContext *s)
421 {
422     HLSContext *hls = s->priv_data;
423     int ret;
424     int len;
425     AVIOContext *pb;
426     uint8_t key[KEYSIZE];
427
428     len = strlen(hls->basename) + 4 + 1;
429     hls->key_basename = av_mallocz(len);
430     if (!hls->key_basename)
431         return AVERROR(ENOMEM);
432
433     av_strlcpy(hls->key_basename, s->filename, len);
434     av_strlcat(hls->key_basename, ".key", len);
435
436     if (hls->key_url) {
437         av_strlcpy(hls->key_file, hls->key_url, sizeof(hls->key_file));
438         av_strlcpy(hls->key_uri, hls->key_url, sizeof(hls->key_uri));
439     } else {
440         av_strlcpy(hls->key_file, hls->key_basename, sizeof(hls->key_file));
441         av_strlcpy(hls->key_uri, hls->key_basename, sizeof(hls->key_uri));
442     }
443
444     if (!*hls->iv_string) {
445         uint8_t iv[16] = { 0 };
446         char buf[33];
447
448         if (!hls->iv) {
449             AV_WB64(iv + 8, hls->sequence);
450         } else {
451             memcpy(iv, hls->iv, sizeof(iv));
452         }
453         ff_data_to_hex(buf, iv, sizeof(iv), 0);
454         buf[32] = '\0';
455         memcpy(hls->iv_string, buf, sizeof(hls->iv_string));
456     }
457
458     if (!*hls->key_uri) {
459         av_log(hls, AV_LOG_ERROR, "no key URI specified in key info file\n");
460         return AVERROR(EINVAL);
461     }
462
463     if (!*hls->key_file) {
464         av_log(hls, AV_LOG_ERROR, "no key file specified in key info file\n");
465         return AVERROR(EINVAL);
466     }
467
468     if (!*hls->key_string) {
469         if (!hls->key) {
470             if ((ret = randomize(key, sizeof(key))) < 0) {
471                 av_log(s, AV_LOG_ERROR, "Cannot generate a strong random key\n");
472                 return ret;
473             }
474         } else {
475             memcpy(key, hls->key, sizeof(key));
476         }
477
478         ff_data_to_hex(hls->key_string, key, sizeof(key), 0);
479         if ((ret = s->io_open(s, &pb, hls->key_file, AVIO_FLAG_WRITE, NULL)) < 0)
480             return ret;
481         avio_seek(pb, 0, SEEK_CUR);
482         avio_write(pb, key, KEYSIZE);
483         avio_close(pb);
484     }
485     return 0;
486 }
487
488
489 static int hls_encryption_start(AVFormatContext *s)
490 {
491     HLSContext *hls = s->priv_data;
492     int ret;
493     AVIOContext *pb;
494     uint8_t key[KEYSIZE];
495
496     if ((ret = s->io_open(s, &pb, hls->key_info_file, AVIO_FLAG_READ, NULL)) < 0) {
497         av_log(hls, AV_LOG_ERROR,
498                 "error opening key info file %s\n", hls->key_info_file);
499         return ret;
500     }
501
502     ff_get_line(pb, hls->key_uri, sizeof(hls->key_uri));
503     hls->key_uri[strcspn(hls->key_uri, "\r\n")] = '\0';
504
505     ff_get_line(pb, hls->key_file, sizeof(hls->key_file));
506     hls->key_file[strcspn(hls->key_file, "\r\n")] = '\0';
507
508     ff_get_line(pb, hls->iv_string, sizeof(hls->iv_string));
509     hls->iv_string[strcspn(hls->iv_string, "\r\n")] = '\0';
510
511     ff_format_io_close(s, &pb);
512
513     if (!*hls->key_uri) {
514         av_log(hls, AV_LOG_ERROR, "no key URI specified in key info file\n");
515         return AVERROR(EINVAL);
516     }
517
518     if (!*hls->key_file) {
519         av_log(hls, AV_LOG_ERROR, "no key file specified in key info file\n");
520         return AVERROR(EINVAL);
521     }
522
523     if ((ret = s->io_open(s, &pb, hls->key_file, AVIO_FLAG_READ, NULL)) < 0) {
524         av_log(hls, AV_LOG_ERROR, "error opening key file %s\n", hls->key_file);
525         return ret;
526     }
527
528     ret = avio_read(pb, key, sizeof(key));
529     ff_format_io_close(s, &pb);
530     if (ret != sizeof(key)) {
531         av_log(hls, AV_LOG_ERROR, "error reading key file %s\n", hls->key_file);
532         if (ret >= 0 || ret == AVERROR_EOF)
533             ret = AVERROR(EINVAL);
534         return ret;
535     }
536     ff_data_to_hex(hls->key_string, key, sizeof(key), 0);
537
538     return 0;
539 }
540
541 static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
542 {
543     int len = ff_get_line(s, buf, maxlen);
544     while (len > 0 && av_isspace(buf[len - 1]))
545         buf[--len] = '\0';
546     return len;
547 }
548
549 static int hls_mux_init(AVFormatContext *s)
550 {
551     AVDictionary *options = NULL;
552     HLSContext *hls = s->priv_data;
553     AVFormatContext *oc;
554     AVFormatContext *vtt_oc = NULL;
555     int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
556     int i, ret;
557
558     ret = avformat_alloc_output_context2(&hls->avf, hls->oformat, NULL, NULL);
559     if (ret < 0)
560         return ret;
561     oc = hls->avf;
562
563     oc->filename[0]        = '\0';
564     oc->oformat            = hls->oformat;
565     oc->interrupt_callback = s->interrupt_callback;
566     oc->max_delay          = s->max_delay;
567     oc->opaque             = s->opaque;
568     oc->io_open            = s->io_open;
569     oc->io_close           = s->io_close;
570     av_dict_copy(&oc->metadata, s->metadata, 0);
571
572     if(hls->vtt_oformat) {
573         ret = avformat_alloc_output_context2(&hls->vtt_avf, hls->vtt_oformat, NULL, NULL);
574         if (ret < 0)
575             return ret;
576         vtt_oc          = hls->vtt_avf;
577         vtt_oc->oformat = hls->vtt_oformat;
578         av_dict_copy(&vtt_oc->metadata, s->metadata, 0);
579     }
580
581     for (i = 0; i < s->nb_streams; i++) {
582         AVStream *st;
583         AVFormatContext *loc;
584         if (s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
585             loc = vtt_oc;
586         else
587             loc = oc;
588
589         if (!(st = avformat_new_stream(loc, NULL)))
590             return AVERROR(ENOMEM);
591         avcodec_parameters_copy(st->codecpar, s->streams[i]->codecpar);
592         if (!oc->oformat->codec_tag ||
593             av_codec_get_id (oc->oformat->codec_tag, s->streams[i]->codecpar->codec_tag) == st->codecpar->codec_id ||
594             av_codec_get_tag(oc->oformat->codec_tag, s->streams[i]->codecpar->codec_id) <= 0) {
595             st->codecpar->codec_tag = s->streams[i]->codecpar->codec_tag;
596         } else {
597             st->codecpar->codec_tag = 0;
598         }
599
600         st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
601         st->time_base = s->streams[i]->time_base;
602         av_dict_copy(&st->metadata, s->streams[i]->metadata, 0);
603     }
604     hls->packets_written = 1;
605     hls->start_pos = 0;
606     hls->new_start = 1;
607     hls->fmp4_init_mode = 0;
608
609     if (hls->segment_type == SEGMENT_TYPE_FMP4) {
610         if (hls->max_seg_size > 0) {
611             av_log(s, AV_LOG_WARNING, "Multi-file byterange mode is currently unsupported in the HLS muxer.\n");
612             return AVERROR_PATCHWELCOME;
613         }
614         hls->packets_written = 0;
615         hls->init_range_length = 0;
616         hls->fmp4_init_mode = !byterange_mode;
617         set_http_options(s, &options, hls);
618         if ((ret = avio_open_dyn_buf(&oc->pb)) < 0)
619             return ret;
620
621         if ((ret = s->io_open(s, &hls->out, hls->base_output_dirname, AVIO_FLAG_WRITE, &options)) < 0) {
622             av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", hls->fmp4_init_filename);
623             return ret;
624         }
625
626         if (hls->format_options_str) {
627             ret = av_dict_parse_string(&hls->format_options, hls->format_options_str, "=", ":", 0);
628             if (ret < 0) {
629                 av_log(s, AV_LOG_ERROR, "Could not parse format options list '%s'\n",
630                        hls->format_options_str);
631                 return ret;
632             }
633         }
634
635         av_dict_copy(&options, hls->format_options, 0);
636         av_dict_set(&options, "fflags", "-autobsf", 0);
637         av_dict_set(&options, "movflags", "frag_custom+dash+delay_moov", 0);
638         ret = avformat_init_output(oc, &options);
639         if (ret < 0)
640             return ret;
641         if (av_dict_count(options)) {
642             av_log(s, AV_LOG_ERROR, "Some of the provided format options in '%s' are not recognized\n", hls->format_options_str);
643             av_dict_free(&options);
644             return AVERROR(EINVAL);
645         }
646         avio_flush(oc->pb);
647         av_dict_free(&options);
648     }
649     return 0;
650 }
651
652 static HLSSegment *find_segment_by_filename(HLSSegment *segment, const char *filename)
653 {
654     while (segment) {
655         if (!av_strcasecmp(segment->filename,filename))
656             return segment;
657         segment = segment->next;
658     }
659     return (HLSSegment *) NULL;
660 }
661
662 static int sls_flags_filename_process(struct AVFormatContext *s, HLSContext *hls, HLSSegment *en, double duration,
663                                          int64_t pos, int64_t size)
664 {
665     if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
666         strlen(hls->current_segment_final_filename_fmt)) {
667         av_strlcpy(hls->avf->filename, hls->current_segment_final_filename_fmt, sizeof(hls->avf->filename));
668         if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
669             char * filename = av_strdup(hls->avf->filename);  // %%s will be %s after strftime
670             if (!filename) {
671                 av_free(en);
672                 return AVERROR(ENOMEM);
673             }
674             if (replace_int_data_in_filename(hls->avf->filename, sizeof(hls->avf->filename),
675                 filename, 's', pos + size) < 1) {
676                 av_log(hls, AV_LOG_ERROR,
677                        "Invalid second level segment filename template '%s', "
678                         "you can try to remove second_level_segment_size flag\n",
679                        filename);
680                 av_free(filename);
681                 av_free(en);
682                 return AVERROR(EINVAL);
683             }
684             av_free(filename);
685         }
686         if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
687             char * filename = av_strdup(hls->avf->filename);  // %%t will be %t after strftime
688             if (!filename) {
689                 av_free(en);
690                 return AVERROR(ENOMEM);
691             }
692             if (replace_int_data_in_filename(hls->avf->filename, sizeof(hls->avf->filename),
693                 filename, 't',  (int64_t)round(duration * HLS_MICROSECOND_UNIT)) < 1) {
694                 av_log(hls, AV_LOG_ERROR,
695                        "Invalid second level segment filename template '%s', "
696                         "you can try to remove second_level_segment_time flag\n",
697                        filename);
698                 av_free(filename);
699                 av_free(en);
700                 return AVERROR(EINVAL);
701             }
702             av_free(filename);
703         }
704     }
705     return 0;
706 }
707
708 static int sls_flag_check_duration_size_index(HLSContext *hls)
709 {
710     int ret = 0;
711
712     if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
713          av_log(hls, AV_LOG_ERROR,
714                 "second_level_segment_duration hls_flag requires use_localtime to be true\n");
715          ret = AVERROR(EINVAL);
716     }
717     if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
718          av_log(hls, AV_LOG_ERROR,
719                 "second_level_segment_size hls_flag requires use_localtime to be true\n");
720          ret = AVERROR(EINVAL);
721     }
722     if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {
723         av_log(hls, AV_LOG_ERROR,
724                "second_level_segment_index hls_flag requires use_localtime to be true\n");
725         ret = AVERROR(EINVAL);
726     }
727
728     return ret;
729 }
730
731 static int sls_flag_check_duration_size(HLSContext *hls)
732 {
733     const char *proto = avio_find_protocol_name(hls->basename);
734     int segment_renaming_ok = proto && !strcmp(proto, "file");
735     int ret = 0;
736
737     if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) && !segment_renaming_ok) {
738          av_log(hls, AV_LOG_ERROR,
739                 "second_level_segment_duration hls_flag works only with file protocol segment names\n");
740          ret = AVERROR(EINVAL);
741     }
742     if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) && !segment_renaming_ok) {
743          av_log(hls, AV_LOG_ERROR,
744                 "second_level_segment_size hls_flag works only with file protocol segment names\n");
745          ret = AVERROR(EINVAL);
746     }
747
748     return ret;
749 }
750
751 static void sls_flag_file_rename(HLSContext *hls, char *old_filename) {
752     if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
753         strlen(hls->current_segment_final_filename_fmt)) {
754         ff_rename(old_filename, hls->avf->filename, hls);
755     }
756 }
757
758 static int sls_flag_use_localtime_filename(AVFormatContext *oc, HLSContext *c)
759 {
760     if (c->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {
761         char * filename = av_strdup(oc->filename);  // %%d will be %d after strftime
762         if (!filename)
763             return AVERROR(ENOMEM);
764         if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename),
765 #if FF_API_HLS_WRAP
766             filename, 'd', c->wrap ? c->sequence % c->wrap : c->sequence) < 1) {
767 #else
768             filename, 'd', c->sequence) < 1) {
769 #endif
770             av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
771                     "you can try to remove second_level_segment_index flag\n",
772                    filename);
773             av_free(filename);
774             return AVERROR(EINVAL);
775         }
776         av_free(filename);
777     }
778     if (c->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) {
779         av_strlcpy(c->current_segment_final_filename_fmt, oc->filename,
780                    sizeof(c->current_segment_final_filename_fmt));
781         if (c->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
782             char * filename = av_strdup(oc->filename);  // %%s will be %s after strftime
783             if (!filename)
784                 return AVERROR(ENOMEM);
785             if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 's', 0) < 1) {
786                 av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
787                         "you can try to remove second_level_segment_size flag\n",
788                        filename);
789                 av_free(filename);
790                 return AVERROR(EINVAL);
791             }
792             av_free(filename);
793         }
794         if (c->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
795             char * filename = av_strdup(oc->filename);  // %%t will be %t after strftime
796             if (!filename)
797                 return AVERROR(ENOMEM);
798             if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 't', 0) < 1) {
799                 av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
800                         "you can try to remove second_level_segment_time flag\n",
801                        filename);
802                 av_free(filename);
803                 return AVERROR(EINVAL);
804             }
805             av_free(filename);
806         }
807     }
808     return 0;
809 }
810
811 /* Create a new segment and append it to the segment list */
812 static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration,
813                               int64_t pos, int64_t size)
814 {
815     HLSSegment *en = av_malloc(sizeof(*en));
816     const char  *filename;
817     int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
818     int ret;
819
820     if (!en)
821         return AVERROR(ENOMEM);
822
823     ret = sls_flags_filename_process(s, hls, en, duration, pos, size);
824     if (ret < 0) {
825         return ret;
826     }
827
828     filename = av_basename(hls->avf->filename);
829
830     if (hls->use_localtime_mkdir) {
831         filename = hls->avf->filename;
832     }
833     if ((find_segment_by_filename(hls->segments, filename) || find_segment_by_filename(hls->old_segments, filename))
834         && !byterange_mode) {
835         av_log(hls, AV_LOG_WARNING, "Duplicated segment filename detected: %s\n", filename);
836     }
837     av_strlcpy(en->filename, filename, sizeof(en->filename));
838
839     if(hls->has_subtitle)
840         av_strlcpy(en->sub_filename, av_basename(hls->vtt_avf->filename), sizeof(en->sub_filename));
841     else
842         en->sub_filename[0] = '\0';
843
844     en->duration = duration;
845     en->pos      = pos;
846     en->size     = size;
847     en->next     = NULL;
848     en->discont  = 0;
849
850     if (hls->discontinuity) {
851         en->discont = 1;
852         hls->discontinuity = 0;
853     }
854
855     if (hls->key_info_file || hls->encrypt) {
856         av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri));
857         av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string));
858     }
859
860     if (!hls->segments)
861         hls->segments = en;
862     else
863         hls->last_segment->next = en;
864
865     hls->last_segment = en;
866
867     // EVENT or VOD playlists imply sliding window cannot be used
868     if (hls->pl_type != PLAYLIST_TYPE_NONE)
869         hls->max_nb_segments = 0;
870
871     if (hls->max_nb_segments && hls->nb_entries >= hls->max_nb_segments) {
872         en = hls->segments;
873         hls->initial_prog_date_time += en->duration;
874         hls->segments = en->next;
875         if (en && hls->flags & HLS_DELETE_SEGMENTS &&
876 #if FF_API_HLS_WRAP
877                 !(hls->flags & HLS_SINGLE_FILE || hls->wrap)) {
878 #else
879                 !(hls->flags & HLS_SINGLE_FILE)) {
880 #endif
881             en->next = hls->old_segments;
882             hls->old_segments = en;
883             if ((ret = hls_delete_old_segments(s, hls)) < 0)
884                 return ret;
885         } else
886             av_free(en);
887     } else
888         hls->nb_entries++;
889
890     if (hls->max_seg_size > 0) {
891         return 0;
892     }
893     hls->sequence++;
894
895     return 0;
896 }
897
898 static int parse_playlist(AVFormatContext *s, const char *url)
899 {
900     HLSContext *hls = s->priv_data;
901     AVIOContext *in;
902     int ret = 0, is_segment = 0;
903     int64_t new_start_pos;
904     char line[1024];
905     const char *ptr;
906     const char *end;
907
908     if ((ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ,
909                                    &s->interrupt_callback, NULL,
910                                    s->protocol_whitelist, s->protocol_blacklist)) < 0)
911         return ret;
912
913     read_chomp_line(in, line, sizeof(line));
914     if (strcmp(line, "#EXTM3U")) {
915         ret = AVERROR_INVALIDDATA;
916         goto fail;
917     }
918
919     hls->discontinuity = 0;
920     while (!avio_feof(in)) {
921         read_chomp_line(in, line, sizeof(line));
922         if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
923             int64_t tmp_sequence = strtoll(ptr, NULL, 10);
924             if (tmp_sequence < hls->sequence)
925               av_log(hls, AV_LOG_VERBOSE,
926                      "Found playlist sequence number was smaller """
927                      "than specified start sequence number: %"PRId64" < %"PRId64", "
928                      "omitting\n", tmp_sequence, hls->start_sequence);
929             else {
930               av_log(hls, AV_LOG_DEBUG, "Found playlist sequence number: %"PRId64"\n", tmp_sequence);
931               hls->sequence = tmp_sequence;
932             }
933         } else if (av_strstart(line, "#EXT-X-DISCONTINUITY", &ptr)) {
934             is_segment = 1;
935             hls->discontinuity = 1;
936         } else if (av_strstart(line, "#EXTINF:", &ptr)) {
937             is_segment = 1;
938             hls->duration = atof(ptr);
939         } else if (av_stristart(line, "#EXT-X-KEY:", &ptr)) {
940             ptr = av_stristr(line, "URI=\"");
941             if (ptr) {
942                 ptr += strlen("URI=\"");
943                 end = av_stristr(ptr, ",");
944                 if (end) {
945                     av_strlcpy(hls->key_uri, ptr, end - ptr);
946                 } else {
947                     av_strlcpy(hls->key_uri, ptr, sizeof(hls->key_uri));
948                 }
949             }
950
951             ptr = av_stristr(line, "IV=0x");
952             if (ptr) {
953                 ptr += strlen("IV=0x");
954                 end = av_stristr(ptr, ",");
955                 if (end) {
956                     av_strlcpy(hls->iv_string, ptr, end - ptr);
957                 } else {
958                     av_strlcpy(hls->iv_string, ptr, sizeof(hls->iv_string));
959                 }
960             }
961
962         } else if (av_strstart(line, "#", NULL)) {
963             continue;
964         } else if (line[0]) {
965             if (is_segment) {
966                 is_segment = 0;
967                 new_start_pos = avio_tell(hls->avf->pb);
968                 hls->size = new_start_pos - hls->start_pos;
969                 av_strlcpy(hls->avf->filename, line, sizeof(line));
970                 ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, hls->size);
971                 if (ret < 0)
972                     goto fail;
973                 hls->start_pos = new_start_pos;
974             }
975         }
976     }
977
978 fail:
979     avio_close(in);
980     return ret;
981 }
982
983 static void hls_free_segments(HLSSegment *p)
984 {
985     HLSSegment *en;
986
987     while(p) {
988         en = p;
989         p = p->next;
990         av_free(en);
991     }
992 }
993
994 static void write_m3u8_head_block(HLSContext *hls, AVIOContext *out, int version,
995                                   int target_duration, int64_t sequence)
996 {
997     avio_printf(out, "#EXTM3U\n");
998     avio_printf(out, "#EXT-X-VERSION:%d\n", version);
999     if (hls->allowcache == 0 || hls->allowcache == 1) {
1000         avio_printf(out, "#EXT-X-ALLOW-CACHE:%s\n", hls->allowcache == 0 ? "NO" : "YES");
1001     }
1002     avio_printf(out, "#EXT-X-TARGETDURATION:%d\n", target_duration);
1003     avio_printf(out, "#EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence);
1004     av_log(hls, AV_LOG_VERBOSE, "EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence);
1005 }
1006
1007 static void hls_rename_temp_file(AVFormatContext *s, AVFormatContext *oc)
1008 {
1009     size_t len = strlen(oc->filename);
1010     char final_filename[sizeof(oc->filename)];
1011
1012     av_strlcpy(final_filename, oc->filename, len);
1013     final_filename[len-4] = '\0';
1014     ff_rename(oc->filename, final_filename, s);
1015     oc->filename[len-4] = '\0';
1016 }
1017
1018 static int hls_window(AVFormatContext *s, int last)
1019 {
1020     HLSContext *hls = s->priv_data;
1021     HLSSegment *en;
1022     int target_duration = 0;
1023     int ret = 0;
1024     AVIOContext *out = NULL;
1025     AVIOContext *sub_out = NULL;
1026     char temp_filename[1024];
1027     int64_t sequence = FFMAX(hls->start_sequence, hls->sequence - hls->nb_entries);
1028     int version = 3;
1029     const char *proto = avio_find_protocol_name(s->filename);
1030     int use_rename = proto && !strcmp(proto, "file");
1031     static unsigned warned_non_file;
1032     char *key_uri = NULL;
1033     char *iv_string = NULL;
1034     AVDictionary *options = NULL;
1035     double prog_date_time = hls->initial_prog_date_time;
1036     int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
1037
1038     if (byterange_mode) {
1039         version = 4;
1040         sequence = 0;
1041     }
1042
1043     if (hls->segment_type == SEGMENT_TYPE_FMP4) {
1044         version = 7;
1045     }
1046
1047     if (!use_rename && !warned_non_file++)
1048         av_log(s, AV_LOG_ERROR, "Cannot use rename on non file protocol, this may lead to races and temporary partial files\n");
1049
1050     set_http_options(s, &options, hls);
1051     snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", s->filename);
1052     if ((ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, &options)) < 0)
1053         goto fail;
1054
1055     for (en = hls->segments; en; en = en->next) {
1056         if (target_duration <= en->duration)
1057             target_duration = get_int_from_double(en->duration);
1058     }
1059
1060     hls->discontinuity_set = 0;
1061     write_m3u8_head_block(hls, out, version, target_duration, sequence);
1062     if (hls->pl_type == PLAYLIST_TYPE_EVENT) {
1063         avio_printf(out, "#EXT-X-PLAYLIST-TYPE:EVENT\n");
1064     } else if (hls->pl_type == PLAYLIST_TYPE_VOD) {
1065         avio_printf(out, "#EXT-X-PLAYLIST-TYPE:VOD\n");
1066     }
1067
1068     if((hls->flags & HLS_DISCONT_START) && sequence==hls->start_sequence && hls->discontinuity_set==0 ){
1069         avio_printf(out, "#EXT-X-DISCONTINUITY\n");
1070         hls->discontinuity_set = 1;
1071     }
1072     for (en = hls->segments; en; en = en->next) {
1073         if ((hls->encrypt || hls->key_info_file) && (!key_uri || strcmp(en->key_uri, key_uri) ||
1074                                     av_strcasecmp(en->iv_string, iv_string))) {
1075             avio_printf(out, "#EXT-X-KEY:METHOD=AES-128,URI=\"%s\"", en->key_uri);
1076             if (*en->iv_string)
1077                 avio_printf(out, ",IV=0x%s", en->iv_string);
1078             avio_printf(out, "\n");
1079             key_uri = en->key_uri;
1080             iv_string = en->iv_string;
1081         }
1082
1083         if (en->discont) {
1084             avio_printf(out, "#EXT-X-DISCONTINUITY\n");
1085         }
1086
1087         if ((hls->segment_type == SEGMENT_TYPE_FMP4) && (en == hls->segments)) {
1088             avio_printf(out, "#EXT-X-MAP:URI=\"%s\"", hls->fmp4_init_filename);
1089             if (hls->flags & HLS_SINGLE_FILE) {
1090                 avio_printf(out, ",BYTERANGE=\"%"PRId64"@%"PRId64"\"", en->size, en->pos);
1091             }
1092             avio_printf(out, "\n");
1093         }
1094         if (hls->flags & HLS_ROUND_DURATIONS)
1095             avio_printf(out, "#EXTINF:%ld,\n",  lrint(en->duration));
1096         else
1097             avio_printf(out, "#EXTINF:%f,\n", en->duration);
1098         if (byterange_mode)
1099             avio_printf(out, "#EXT-X-BYTERANGE:%"PRId64"@%"PRId64"\n",
1100                         en->size, en->pos);
1101
1102         if (hls->flags & HLS_PROGRAM_DATE_TIME) {
1103             time_t tt, wrongsecs;
1104             int milli;
1105             struct tm *tm, tmpbuf;
1106             char buf0[128], buf1[128];
1107             tt = (int64_t)prog_date_time;
1108             milli = av_clip(lrint(1000*(prog_date_time - tt)), 0, 999);
1109             tm = localtime_r(&tt, &tmpbuf);
1110             strftime(buf0, sizeof(buf0), "%Y-%m-%dT%H:%M:%S", tm);
1111             if (!strftime(buf1, sizeof(buf1), "%z", tm) || buf1[1]<'0' ||buf1[1]>'2') {
1112                 int tz_min, dst = tm->tm_isdst;
1113                 tm = gmtime_r(&tt, &tmpbuf);
1114                 tm->tm_isdst = dst;
1115                 wrongsecs = mktime(tm);
1116                 tz_min = (abs(wrongsecs - tt) + 30) / 60;
1117                 snprintf(buf1, sizeof(buf1),
1118                          "%c%02d%02d",
1119                          wrongsecs <= tt ? '+' : '-',
1120                          tz_min / 60,
1121                          tz_min % 60);
1122             }
1123             avio_printf(out, "#EXT-X-PROGRAM-DATE-TIME:%s.%03d%s\n", buf0, milli, buf1);
1124             prog_date_time += en->duration;
1125         }
1126         if (hls->baseurl)
1127             avio_printf(out, "%s", hls->baseurl);
1128         avio_printf(out, "%s\n", en->filename);
1129     }
1130
1131     if (last && (hls->flags & HLS_OMIT_ENDLIST)==0)
1132         avio_printf(out, "#EXT-X-ENDLIST\n");
1133
1134     if( hls->vtt_m3u8_name ) {
1135         if ((ret = s->io_open(s, &sub_out, hls->vtt_m3u8_name, AVIO_FLAG_WRITE, &options)) < 0)
1136             goto fail;
1137         write_m3u8_head_block(hls, sub_out, version, target_duration, sequence);
1138
1139         for (en = hls->segments; en; en = en->next) {
1140             avio_printf(sub_out, "#EXTINF:%f,\n", en->duration);
1141             if (byterange_mode)
1142                  avio_printf(sub_out, "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n",
1143                          en->size, en->pos);
1144             if (hls->baseurl)
1145                 avio_printf(sub_out, "%s", hls->baseurl);
1146             avio_printf(sub_out, "%s\n", en->sub_filename);
1147         }
1148
1149         if (last)
1150             avio_printf(sub_out, "#EXT-X-ENDLIST\n");
1151
1152     }
1153
1154 fail:
1155     av_dict_free(&options);
1156     ff_format_io_close(s, &out);
1157     ff_format_io_close(s, &sub_out);
1158     if (ret >= 0 && use_rename)
1159         ff_rename(temp_filename, s->filename, s);
1160     return ret;
1161 }
1162
1163 static int hls_start(AVFormatContext *s)
1164 {
1165     HLSContext *c = s->priv_data;
1166     AVFormatContext *oc = c->avf;
1167     AVFormatContext *vtt_oc = c->vtt_avf;
1168     AVDictionary *options = NULL;
1169     char *filename, iv_string[KEYSIZE*2 + 1];
1170     int err = 0;
1171
1172     if (c->flags & HLS_SINGLE_FILE) {
1173         av_strlcpy(oc->filename, c->basename,
1174                    sizeof(oc->filename));
1175         if (c->vtt_basename)
1176             av_strlcpy(vtt_oc->filename, c->vtt_basename,
1177                   sizeof(vtt_oc->filename));
1178     } else if (c->max_seg_size > 0) {
1179         if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename),
1180 #if FF_API_HLS_WRAP
1181             c->basename, 'd', c->wrap ? c->sequence % c->wrap : c->sequence) < 1) {
1182 #else
1183             c->basename, 'd', c->sequence) < 1) {
1184 #endif
1185                 av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s', you can try to use -use_localtime 1 with it\n", c->basename);
1186                 return AVERROR(EINVAL);
1187         }
1188     } else {
1189         if (c->use_localtime) {
1190             time_t now0;
1191             struct tm *tm, tmpbuf;
1192             time(&now0);
1193             tm = localtime_r(&now0, &tmpbuf);
1194             if (!strftime(oc->filename, sizeof(oc->filename), c->basename, tm)) {
1195                 av_log(oc, AV_LOG_ERROR, "Could not get segment filename with use_localtime\n");
1196                 return AVERROR(EINVAL);
1197             }
1198
1199             err = sls_flag_use_localtime_filename(oc, c);
1200             if (err < 0) {
1201                 return AVERROR(ENOMEM);
1202             }
1203
1204             if (c->use_localtime_mkdir) {
1205                 const char *dir;
1206                 char *fn_copy = av_strdup(oc->filename);
1207                 if (!fn_copy) {
1208                     return AVERROR(ENOMEM);
1209                 }
1210                 dir = av_dirname(fn_copy);
1211                 if (mkdir_p(dir) == -1 && errno != EEXIST) {
1212                     av_log(oc, AV_LOG_ERROR, "Could not create directory %s with use_localtime_mkdir\n", dir);
1213                     av_free(fn_copy);
1214                     return AVERROR(errno);
1215                 }
1216                 av_free(fn_copy);
1217             }
1218         } else if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename),
1219 #if FF_API_HLS_WRAP
1220                    c->basename, 'd', c->wrap ? c->sequence % c->wrap : c->sequence) < 1) {
1221 #else
1222                    c->basename, 'd', c->sequence) < 1) {
1223 #endif
1224             av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s' you can try to use -use_localtime 1 with it\n", c->basename);
1225             return AVERROR(EINVAL);
1226         }
1227         if( c->vtt_basename) {
1228             if (replace_int_data_in_filename(vtt_oc->filename, sizeof(vtt_oc->filename),
1229 #if FF_API_HLS_WRAP
1230                 c->vtt_basename, 'd', c->wrap ? c->sequence % c->wrap : c->sequence) < 1) {
1231 #else
1232                 c->vtt_basename, 'd', c->sequence) < 1) {
1233 #endif
1234                 av_log(vtt_oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", c->vtt_basename);
1235                 return AVERROR(EINVAL);
1236             }
1237        }
1238     }
1239     c->number++;
1240
1241     set_http_options(s, &options, c);
1242
1243     if (c->flags & HLS_TEMP_FILE) {
1244         av_strlcat(oc->filename, ".tmp", sizeof(oc->filename));
1245     }
1246
1247     if (c->key_info_file || c->encrypt) {
1248         if (c->key_info_file && c->encrypt) {
1249             av_log(s, AV_LOG_WARNING, "Cannot use both -hls_key_info_file and -hls_enc,"
1250                   " will use -hls_key_info_file priority\n");
1251         }
1252
1253         if (c->number <= 1 || (c->flags & HLS_PERIODIC_REKEY)) {
1254             if (c->key_info_file) {
1255                 if ((err = hls_encryption_start(s)) < 0)
1256                     goto fail;
1257             } else {
1258                 if ((err = do_encrypt(s)) < 0)
1259                     goto fail;
1260             }
1261         }
1262         if ((err = av_dict_set(&options, "encryption_key", c->key_string, 0))
1263                 < 0)
1264             goto fail;
1265         err = av_strlcpy(iv_string, c->iv_string, sizeof(iv_string));
1266         if (!err)
1267             snprintf(iv_string, sizeof(iv_string), "%032"PRIx64, c->sequence);
1268         if ((err = av_dict_set(&options, "encryption_iv", iv_string, 0)) < 0)
1269            goto fail;
1270
1271         filename = av_asprintf("crypto:%s", oc->filename);
1272         if (!filename) {
1273             err = AVERROR(ENOMEM);
1274             goto fail;
1275         }
1276         err = s->io_open(s, &oc->pb, filename, AVIO_FLAG_WRITE, &options);
1277         av_free(filename);
1278         av_dict_free(&options);
1279         if (err < 0)
1280             return err;
1281     } else
1282         if ((err = s->io_open(s, &oc->pb, oc->filename, AVIO_FLAG_WRITE, &options)) < 0)
1283             goto fail;
1284     if (c->vtt_basename) {
1285         set_http_options(s, &options, c);
1286         if ((err = s->io_open(s, &vtt_oc->pb, vtt_oc->filename, AVIO_FLAG_WRITE, &options)) < 0)
1287             goto fail;
1288     }
1289     av_dict_free(&options);
1290
1291     if (c->segment_type == SEGMENT_TYPE_FMP4 && !(c->flags & HLS_SINGLE_FILE)) {
1292             write_styp(oc->pb);
1293     } else {
1294         /* We only require one PAT/PMT per segment. */
1295         if (oc->oformat->priv_class && oc->priv_data) {
1296             char period[21];
1297
1298             snprintf(period, sizeof(period), "%d", (INT_MAX / 2) - 1);
1299
1300             av_opt_set(oc->priv_data, "mpegts_flags", "resend_headers", 0);
1301             av_opt_set(oc->priv_data, "sdt_period", period, 0);
1302             av_opt_set(oc->priv_data, "pat_period", period, 0);
1303         }
1304     }
1305
1306     if (c->vtt_basename) {
1307         err = avformat_write_header(vtt_oc,NULL);
1308         if (err < 0)
1309             return err;
1310     }
1311
1312     return 0;
1313 fail:
1314     av_dict_free(&options);
1315
1316     return err;
1317 }
1318
1319 static const char * get_default_pattern_localtime_fmt(AVFormatContext *s)
1320 {
1321     char b[21];
1322     time_t t = time(NULL);
1323     struct tm *p, tmbuf;
1324     HLSContext *hls = s->priv_data;
1325
1326     p = localtime_r(&t, &tmbuf);
1327     // no %s support when strftime returned error or left format string unchanged
1328     // also no %s support on MSVC, which invokes the invalid parameter handler on unsupported format strings, instead of returning an error
1329     if (hls->segment_type == SEGMENT_TYPE_FMP4) {
1330         return (HAVE_LIBC_MSVCRT || !strftime(b, sizeof(b), "%s", p) || !strcmp(b, "%s")) ? "-%Y%m%d%H%M%S.m4s" : "-%s.m4s";
1331     }
1332     return (HAVE_LIBC_MSVCRT || !strftime(b, sizeof(b), "%s", p) || !strcmp(b, "%s")) ? "-%Y%m%d%H%M%S.ts" : "-%s.ts";
1333 }
1334
1335 static int hls_write_header(AVFormatContext *s)
1336 {
1337     HLSContext *hls = s->priv_data;
1338     int ret, i;
1339     char *p = NULL;
1340     const char *pattern = "%d.ts";
1341     const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt(s);
1342     const char *vtt_pattern = "%d.vtt";
1343     AVDictionary *options = NULL;
1344     int basename_size = 0;
1345     int vtt_basename_size = 0;
1346     int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1;
1347
1348     if (hls->segment_type == SEGMENT_TYPE_FMP4) {
1349         pattern = "%d.m4s";
1350     }
1351     if ((hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) ||
1352         (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME)) {
1353         time_t t = time(NULL); // we will need it in either case
1354         if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) {
1355             hls->start_sequence = (int64_t)t;
1356         } else if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME) {
1357             char b[15];
1358             struct tm *p, tmbuf;
1359             if (!(p = localtime_r(&t, &tmbuf)))
1360                 return AVERROR(ENOMEM);
1361             if (!strftime(b, sizeof(b), "%Y%m%d%H%M%S", p))
1362                 return AVERROR(ENOMEM);
1363             hls->start_sequence = strtoll(b, NULL, 10);
1364         }
1365         av_log(hls, AV_LOG_DEBUG, "start_number evaluated to %"PRId64"\n", hls->start_sequence);
1366     }
1367
1368     hls->sequence       = hls->start_sequence;
1369     hls->recording_time = (hls->init_time ? hls->init_time : hls->time) * AV_TIME_BASE;
1370     hls->start_pts      = AV_NOPTS_VALUE;
1371     hls->current_segment_final_filename_fmt[0] = '\0';
1372
1373     if (hls->flags & HLS_PROGRAM_DATE_TIME) {
1374         time_t now0;
1375         time(&now0);
1376         hls->initial_prog_date_time = now0;
1377     }
1378
1379     if (hls->format_options_str) {
1380         ret = av_dict_parse_string(&hls->format_options, hls->format_options_str, "=", ":", 0);
1381         if (ret < 0) {
1382             av_log(s, AV_LOG_ERROR, "Could not parse format options list '%s'\n", hls->format_options_str);
1383             goto fail;
1384         }
1385     }
1386
1387     for (i = 0; i < s->nb_streams; i++) {
1388         hls->has_video +=
1389             s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO;
1390         hls->has_subtitle +=
1391             s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE;
1392     }
1393
1394     if (hls->has_video > 1)
1395         av_log(s, AV_LOG_WARNING,
1396                "More than a single video stream present, "
1397                "expect issues decoding it.\n");
1398
1399     if (hls->segment_type == SEGMENT_TYPE_FMP4) {
1400         hls->oformat = av_guess_format("mp4", NULL, NULL);
1401     } else {
1402         hls->oformat = av_guess_format("mpegts", NULL, NULL);
1403     }
1404
1405     if (!hls->oformat) {
1406         ret = AVERROR_MUXER_NOT_FOUND;
1407         goto fail;
1408     }
1409
1410     if(hls->has_subtitle) {
1411         hls->vtt_oformat = av_guess_format("webvtt", NULL, NULL);
1412         if (!hls->oformat) {
1413             ret = AVERROR_MUXER_NOT_FOUND;
1414             goto fail;
1415         }
1416     }
1417
1418     if (hls->segment_filename) {
1419         hls->basename = av_strdup(hls->segment_filename);
1420         if (!hls->basename) {
1421             ret = AVERROR(ENOMEM);
1422             goto fail;
1423         }
1424     } else {
1425         if (hls->flags & HLS_SINGLE_FILE) {
1426             if (hls->segment_type == SEGMENT_TYPE_FMP4) {
1427                 pattern = ".m4s";
1428             } else {
1429                 pattern = ".ts";
1430             }
1431         }
1432
1433         if (hls->use_localtime) {
1434             basename_size = strlen(s->filename) + strlen(pattern_localtime_fmt) + 1;
1435         } else {
1436             basename_size = strlen(s->filename) + strlen(pattern) + 1;
1437         }
1438         hls->basename = av_malloc(basename_size);
1439         if (!hls->basename) {
1440             ret = AVERROR(ENOMEM);
1441             goto fail;
1442         }
1443
1444         av_strlcpy(hls->basename, s->filename, basename_size);
1445
1446         p = strrchr(hls->basename, '.');
1447         if (p)
1448             *p = '\0';
1449         if (hls->use_localtime) {
1450             av_strlcat(hls->basename, pattern_localtime_fmt, basename_size);
1451         } else {
1452             av_strlcat(hls->basename, pattern, basename_size);
1453         }
1454     }
1455
1456     if (hls->segment_type == SEGMENT_TYPE_FMP4) {
1457         if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) {
1458             hls->base_output_dirname = av_malloc(fmp4_init_filename_len);
1459             if (!hls->base_output_dirname) {
1460                 ret = AVERROR(ENOMEM);
1461                 goto fail;
1462             }
1463             av_strlcpy(hls->base_output_dirname, hls->fmp4_init_filename, fmp4_init_filename_len);
1464         } else {
1465             if (basename_size > 0) {
1466                 hls->base_output_dirname = av_malloc(basename_size);
1467             } else {
1468                 hls->base_output_dirname = av_malloc(strlen(hls->fmp4_init_filename) + 1);
1469             }
1470             if (!hls->base_output_dirname) {
1471                 ret = AVERROR(ENOMEM);
1472                 goto fail;
1473             }
1474
1475             if (basename_size > 0) {
1476                 av_strlcpy(hls->base_output_dirname, s->filename, basename_size);
1477                 p = strrchr(hls->base_output_dirname, '/');
1478             }
1479             if (p) {
1480                 *(p + 1) = '\0';
1481                 av_strlcat(hls->base_output_dirname, hls->fmp4_init_filename, basename_size);
1482             } else {
1483                 av_strlcpy(hls->base_output_dirname, hls->fmp4_init_filename, fmp4_init_filename_len);
1484             }
1485         }
1486     }
1487
1488     if (!hls->use_localtime) {
1489         ret = sls_flag_check_duration_size_index(hls);
1490         if (ret < 0) {
1491              goto fail;
1492         }
1493     } else {
1494         ret = sls_flag_check_duration_size(hls);
1495         if (ret < 0) {
1496              goto fail;
1497         }
1498     }
1499     if(hls->has_subtitle) {
1500
1501         if (hls->flags & HLS_SINGLE_FILE)
1502             vtt_pattern = ".vtt";
1503         vtt_basename_size = strlen(s->filename) + strlen(vtt_pattern) + 1;
1504         hls->vtt_basename = av_malloc(vtt_basename_size);
1505         if (!hls->vtt_basename) {
1506             ret = AVERROR(ENOMEM);
1507             goto fail;
1508         }
1509         hls->vtt_m3u8_name = av_malloc(vtt_basename_size);
1510         if (!hls->vtt_m3u8_name ) {
1511             ret = AVERROR(ENOMEM);
1512             goto fail;
1513         }
1514         av_strlcpy(hls->vtt_basename, s->filename, vtt_basename_size);
1515         p = strrchr(hls->vtt_basename, '.');
1516         if (p)
1517             *p = '\0';
1518
1519         if( hls->subtitle_filename ) {
1520             strcpy(hls->vtt_m3u8_name, hls->subtitle_filename);
1521         } else {
1522             strcpy(hls->vtt_m3u8_name, hls->vtt_basename);
1523             av_strlcat(hls->vtt_m3u8_name, "_vtt.m3u8", vtt_basename_size);
1524         }
1525         av_strlcat(hls->vtt_basename, vtt_pattern, vtt_basename_size);
1526     }
1527
1528     if ((hls->flags & HLS_SINGLE_FILE) && (hls->segment_type == SEGMENT_TYPE_FMP4)) {
1529         hls->fmp4_init_filename  = av_strdup(hls->basename);
1530         if (!hls->fmp4_init_filename) {
1531             ret = AVERROR(ENOMEM);
1532             goto fail;
1533         }
1534     }
1535
1536     if ((ret = hls_mux_init(s)) < 0)
1537         goto fail;
1538
1539     if (hls->flags & HLS_APPEND_LIST) {
1540         parse_playlist(s, s->filename);
1541         hls->discontinuity = 1;
1542         if (hls->init_time > 0) {
1543             av_log(s, AV_LOG_WARNING, "append_list mode does not support hls_init_time,"
1544                    " hls_init_time value will have no effect\n");
1545             hls->init_time = 0;
1546             hls->recording_time = hls->time * AV_TIME_BASE;
1547         }
1548     }
1549
1550     if (hls->segment_type != SEGMENT_TYPE_FMP4 || hls->flags & HLS_SINGLE_FILE) {
1551         if ((ret = hls_start(s)) < 0)
1552             goto fail;
1553     }
1554
1555     av_dict_copy(&options, hls->format_options, 0);
1556     ret = avformat_write_header(hls->avf, &options);
1557     if (av_dict_count(options)) {
1558         av_log(s, AV_LOG_ERROR, "Some of provided format options in '%s' are not recognized\n", hls->format_options_str);
1559         ret = AVERROR(EINVAL);
1560         goto fail;
1561     }
1562     //av_assert0(s->nb_streams == hls->avf->nb_streams);
1563     for (i = 0; i < s->nb_streams; i++) {
1564         AVStream *inner_st;
1565         AVStream *outer_st = s->streams[i];
1566
1567         if (hls->max_seg_size > 0) {
1568             if ((outer_st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) &&
1569                 (outer_st->codecpar->bit_rate > hls->max_seg_size)) {
1570                 av_log(s, AV_LOG_WARNING, "Your video bitrate is bigger than hls_segment_size, "
1571                        "(%"PRId64 " > %"PRId64 "), the result maybe not be what you want.",
1572                        outer_st->codecpar->bit_rate, hls->max_seg_size);
1573             }
1574         }
1575
1576         if (outer_st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE)
1577             inner_st = hls->avf->streams[i];
1578         else if (hls->vtt_avf)
1579             inner_st = hls->vtt_avf->streams[0];
1580         else {
1581             /* We have a subtitle stream, when the user does not want one */
1582             inner_st = NULL;
1583             continue;
1584         }
1585         avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, inner_st->time_base.num, inner_st->time_base.den);
1586     }
1587 fail:
1588
1589     av_dict_free(&options);
1590     if (ret < 0) {
1591         av_freep(&hls->fmp4_init_filename);
1592         av_freep(&hls->basename);
1593         av_freep(&hls->vtt_basename);
1594         av_freep(&hls->key_basename);
1595         if (hls->avf)
1596             avformat_free_context(hls->avf);
1597         if (hls->vtt_avf)
1598             avformat_free_context(hls->vtt_avf);
1599
1600     }
1601     return ret;
1602 }
1603
1604 static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
1605 {
1606     HLSContext *hls = s->priv_data;
1607     AVFormatContext *oc = NULL;
1608     AVStream *st = s->streams[pkt->stream_index];
1609     int64_t end_pts = hls->recording_time * hls->number;
1610     int is_ref_pkt = 1;
1611     int ret = 0, can_split = 1;
1612     int stream_index = 0;
1613     int range_length = 0;
1614     uint8_t *buffer = NULL;
1615
1616     if (hls->sequence - hls->nb_entries > hls->start_sequence && hls->init_time > 0) {
1617         /* reset end_pts, hls->recording_time at end of the init hls list */
1618         int init_list_dur = hls->init_time * hls->nb_entries * AV_TIME_BASE;
1619         int after_init_list_dur = (hls->sequence - hls->nb_entries ) * hls->time * AV_TIME_BASE;
1620         hls->recording_time = hls->time * AV_TIME_BASE;
1621         end_pts = init_list_dur + after_init_list_dur ;
1622     }
1623
1624     if( st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE ) {
1625         oc = hls->vtt_avf;
1626         stream_index = 0;
1627     } else {
1628         oc = hls->avf;
1629         stream_index = pkt->stream_index;
1630     }
1631     if (hls->start_pts == AV_NOPTS_VALUE) {
1632         hls->start_pts = pkt->pts;
1633         hls->end_pts   = pkt->pts;
1634     }
1635
1636     if (hls->has_video) {
1637         can_split = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
1638                     ((pkt->flags & AV_PKT_FLAG_KEY) || (hls->flags & HLS_SPLIT_BY_TIME));
1639         is_ref_pkt = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO;
1640     }
1641     if (pkt->pts == AV_NOPTS_VALUE)
1642         is_ref_pkt = can_split = 0;
1643
1644     if (is_ref_pkt) {
1645         if (hls->new_start) {
1646             hls->new_start = 0;
1647             hls->duration = (double)(pkt->pts - hls->end_pts)
1648                                        * st->time_base.num / st->time_base.den;
1649             hls->dpp = (double)(pkt->duration) * st->time_base.num / st->time_base.den;
1650         } else {
1651             if (pkt->duration) {
1652                 hls->duration += (double)(pkt->duration) * st->time_base.num / st->time_base.den;
1653             } else {
1654                 av_log(s, AV_LOG_WARNING, "pkt->duration = 0, maybe the hls segment duration will not precise\n");
1655                 hls->duration = (double)(pkt->pts - hls->end_pts) * st->time_base.num / st->time_base.den;
1656             }
1657         }
1658
1659     }
1660     if (hls->packets_written && can_split && av_compare_ts(pkt->pts - hls->start_pts, st->time_base,
1661                                    end_pts, AV_TIME_BASE_Q) >= 0) {
1662         int64_t new_start_pos;
1663         char *old_filename = av_strdup(hls->avf->filename);
1664         int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
1665
1666         if (!old_filename) {
1667             return AVERROR(ENOMEM);
1668         }
1669
1670         av_write_frame(hls->avf, NULL); /* Flush any buffered data */
1671
1672         new_start_pos = avio_tell(hls->avf->pb);
1673         hls->size = new_start_pos - hls->start_pos;
1674
1675         if (!byterange_mode) {
1676             if (hls->segment_type == SEGMENT_TYPE_FMP4 && !hls->init_range_length) {
1677                 avio_flush(oc->pb);
1678                 range_length = avio_close_dyn_buf(oc->pb, &buffer);
1679                 avio_write(hls->out, buffer, range_length);
1680                 hls->init_range_length = range_length;
1681                 avio_open_dyn_buf(&oc->pb);
1682                 hls->packets_written = 0;
1683                 ff_format_io_close(s, &hls->out);
1684             } else {
1685                 ff_format_io_close(s, &oc->pb);
1686             }
1687             if (hls->vtt_avf) {
1688                 ff_format_io_close(s, &hls->vtt_avf->pb);
1689             }
1690         }
1691         if ((hls->flags & HLS_TEMP_FILE) && oc->filename[0]) {
1692             if (!(hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size <= 0))
1693                 if ((hls->avf->oformat->priv_class && hls->avf->priv_data) && hls->segment_type != SEGMENT_TYPE_FMP4)
1694                     av_opt_set(hls->avf->priv_data, "mpegts_flags", "resend_headers", 0);
1695             hls_rename_temp_file(s, oc);
1696         }
1697
1698         if (hls->fmp4_init_mode) {
1699             hls->number--;
1700         }
1701
1702         if (!hls->fmp4_init_mode || byterange_mode)
1703             ret = hls_append_segment(s, hls, hls->duration, hls->start_pos, hls->size);
1704
1705         hls->start_pos = new_start_pos;
1706         if (ret < 0) {
1707             av_free(old_filename);
1708             return ret;
1709         }
1710
1711         hls->end_pts = pkt->pts;
1712         hls->duration = 0;
1713
1714         hls->fmp4_init_mode = 0;
1715         if (hls->flags & HLS_SINGLE_FILE) {
1716             hls->number++;
1717         } else if (hls->max_seg_size > 0) {
1718             if (hls->start_pos >= hls->max_seg_size) {
1719                 hls->sequence++;
1720                 sls_flag_file_rename(hls, old_filename);
1721                 ret = hls_start(s);
1722                 hls->start_pos = 0;
1723                 /* When split segment by byte, the duration is short than hls_time,
1724                  * so it is not enough one segment duration as hls_time, */
1725                 hls->number--;
1726             }
1727             hls->number++;
1728         } else {
1729             sls_flag_file_rename(hls, old_filename);
1730             ret = hls_start(s);
1731         }
1732         av_free(old_filename);
1733
1734         if (ret < 0) {
1735             return ret;
1736         }
1737
1738         if (!hls->fmp4_init_mode || byterange_mode)
1739             if ((ret = hls_window(s, 0)) < 0) {
1740                 return ret;
1741             }
1742     }
1743
1744     hls->packets_written++;
1745     ret = ff_write_chained(oc, stream_index, pkt, s, 0);
1746
1747     return ret;
1748 }
1749
1750 static int hls_write_trailer(struct AVFormatContext *s)
1751 {
1752     HLSContext *hls = s->priv_data;
1753     AVFormatContext *oc = hls->avf;
1754     AVFormatContext *vtt_oc = hls->vtt_avf;
1755     char *old_filename = av_strdup(hls->avf->filename);
1756
1757     if (!old_filename) {
1758         return AVERROR(ENOMEM);
1759     }
1760
1761
1762     av_write_trailer(oc);
1763     if (oc->pb) {
1764         hls->size = avio_tell(hls->avf->pb) - hls->start_pos;
1765         ff_format_io_close(s, &oc->pb);
1766
1767         if ((hls->flags & HLS_TEMP_FILE) && oc->filename[0]) {
1768             hls_rename_temp_file(s, oc);
1769         }
1770
1771         /* after av_write_trailer, then duration + 1 duration per packet */
1772         hls_append_segment(s, hls, hls->duration + hls->dpp, hls->start_pos, hls->size);
1773     }
1774
1775     sls_flag_file_rename(hls, old_filename);
1776
1777     if (vtt_oc) {
1778         if (vtt_oc->pb)
1779             av_write_trailer(vtt_oc);
1780         hls->size = avio_tell(hls->vtt_avf->pb) - hls->start_pos;
1781         ff_format_io_close(s, &vtt_oc->pb);
1782     }
1783     av_freep(&hls->basename);
1784     av_freep(&hls->base_output_dirname);
1785     av_freep(&hls->key_basename);
1786     avformat_free_context(oc);
1787
1788     hls->avf = NULL;
1789     hls_window(s, 1);
1790
1791     av_freep(&hls->fmp4_init_filename);
1792     if (vtt_oc) {
1793         av_freep(&hls->vtt_basename);
1794         av_freep(&hls->vtt_m3u8_name);
1795         avformat_free_context(vtt_oc);
1796     }
1797
1798     hls_free_segments(hls->segments);
1799     hls_free_segments(hls->old_segments);
1800     av_free(old_filename);
1801     return 0;
1802 }
1803
1804 #define OFFSET(x) offsetof(HLSContext, x)
1805 #define E AV_OPT_FLAG_ENCODING_PARAM
1806 static const AVOption options[] = {
1807     {"start_number",  "set first number in the sequence",        OFFSET(start_sequence),AV_OPT_TYPE_INT64,  {.i64 = 0},     0, INT64_MAX, E},
1808     {"hls_time",      "set segment length in seconds",           OFFSET(time),    AV_OPT_TYPE_FLOAT,  {.dbl = 2},     0, FLT_MAX, E},
1809     {"hls_init_time", "set segment length in seconds at init list",           OFFSET(init_time),    AV_OPT_TYPE_FLOAT,  {.dbl = 0},     0, FLT_MAX, E},
1810     {"hls_list_size", "set maximum number of playlist entries",  OFFSET(max_nb_segments),    AV_OPT_TYPE_INT,    {.i64 = 5},     0, INT_MAX, E},
1811     {"hls_ts_options","set hls mpegts list of options for the container format used for hls", OFFSET(format_options_str), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,    E},
1812     {"hls_vtt_options","set hls vtt list of options for the container format used for hls", OFFSET(vtt_format_options_str), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,    E},
1813 #if FF_API_HLS_WRAP
1814     {"hls_wrap",      "set number after which the index wraps (will be deprecated)",  OFFSET(wrap),    AV_OPT_TYPE_INT,    {.i64 = 0},     0, INT_MAX, E},
1815 #endif
1816     {"hls_allow_cache", "explicitly set whether the client MAY (1) or MUST NOT (0) cache media segments", OFFSET(allowcache), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, E},
1817     {"hls_base_url",  "url to prepend to each playlist entry",   OFFSET(baseurl), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E},
1818     {"hls_segment_filename", "filename template for segment files", OFFSET(segment_filename),   AV_OPT_TYPE_STRING, {.str = NULL},            0,       0,         E},
1819     {"hls_segment_size", "maximum size per segment file, (in bytes)",  OFFSET(max_seg_size),    AV_OPT_TYPE_INT,    {.i64 = 0},               0,       INT_MAX,   E},
1820     {"hls_key_info_file",    "file with key URI and key file path", OFFSET(key_info_file),      AV_OPT_TYPE_STRING, {.str = NULL},            0,       0,         E},
1821     {"hls_enc",    "enable AES128 encryption support", OFFSET(encrypt),      AV_OPT_TYPE_BOOL, {.i64 = 0},            0,       1,         E},
1822     {"hls_enc_key",    "hex-coded 16 byte key to encrypt the segments", OFFSET(key),      AV_OPT_TYPE_STRING, .flags = E},
1823     {"hls_enc_key_url",    "url to access the key to decrypt the segments", OFFSET(key_url),      AV_OPT_TYPE_STRING, {.str = NULL},            0,       0,         E},
1824     {"hls_enc_iv",    "hex-coded 16 byte initialization vector", OFFSET(iv),      AV_OPT_TYPE_STRING, .flags = E},
1825     {"hls_subtitle_path",     "set path of hls subtitles", OFFSET(subtitle_filename), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,    E},
1826     {"hls_segment_type",     "set hls segment files type", OFFSET(segment_type), AV_OPT_TYPE_INT, {.i64 = SEGMENT_TYPE_MPEGTS }, 0, SEGMENT_TYPE_FMP4, E, "segment_type"},
1827     {"mpegts",   "make segment file to mpegts files in m3u8", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_MPEGTS }, 0, UINT_MAX,   E, "segment_type"},
1828     {"fmp4",   "make segment file to fragment mp4 files in m3u8", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_FMP4 }, 0, UINT_MAX,   E, "segment_type"},
1829     {"hls_fmp4_init_filename", "set fragment mp4 file init filename", OFFSET(fmp4_init_filename),   AV_OPT_TYPE_STRING, {.str = "init.mp4"},            0,       0,         E},
1830     {"hls_flags",     "set flags affecting HLS playlist and media file generation", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, 0, UINT_MAX, E, "flags"},
1831     {"single_file",   "generate a single media file indexed with byte ranges", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SINGLE_FILE }, 0, UINT_MAX,   E, "flags"},
1832     {"temp_file", "write segment to temporary file and rename when complete", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_TEMP_FILE }, 0, UINT_MAX,   E, "flags"},
1833     {"delete_segments", "delete segment files that are no longer part of the playlist", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_DELETE_SEGMENTS }, 0, UINT_MAX,   E, "flags"},
1834     {"round_durations", "round durations in m3u8 to whole numbers", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_ROUND_DURATIONS }, 0, UINT_MAX,   E, "flags"},
1835     {"discont_start", "start the playlist with a discontinuity tag", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_DISCONT_START }, 0, UINT_MAX,   E, "flags"},
1836     {"omit_endlist", "Do not append an endlist when ending stream", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_OMIT_ENDLIST }, 0, UINT_MAX,   E, "flags"},
1837     {"split_by_time", "split the hls segment by time which user set by hls_time", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SPLIT_BY_TIME }, 0, UINT_MAX,   E, "flags"},
1838     {"append_list", "append the new segments into old hls segment list", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_APPEND_LIST }, 0, UINT_MAX,   E, "flags"},
1839     {"program_date_time", "add EXT-X-PROGRAM-DATE-TIME", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PROGRAM_DATE_TIME }, 0, UINT_MAX,   E, "flags"},
1840     {"second_level_segment_index", "include segment index in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_INDEX }, 0, UINT_MAX,   E, "flags"},
1841     {"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"},
1842     {"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"},
1843     {"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX,   E, "flags"},
1844     {"use_localtime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
1845     {"use_localtime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
1846     {"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" },
1847     {"event", "EVENT playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_EVENT }, INT_MIN, INT_MAX, E, "pl_type" },
1848     {"vod", "VOD playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_VOD }, INT_MIN, INT_MAX, E, "pl_type" },
1849     {"method", "set the HTTP method(default: PUT)", OFFSET(method), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,    E},
1850     {"hls_start_number_source", "set source of first number in sequence", OFFSET(start_sequence_source_type), AV_OPT_TYPE_INT, {.i64 = HLS_START_SEQUENCE_AS_START_NUMBER }, 0, HLS_START_SEQUENCE_AS_FORMATTED_DATETIME, E, "start_sequence_source_type" },
1851     {"generic", "start_number value (default)", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_START_NUMBER }, INT_MIN, INT_MAX, E, "start_sequence_source_type" },
1852     {"epoch", "seconds since epoch", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH }, INT_MIN, INT_MAX, E, "start_sequence_source_type" },
1853     {"datetime", "current datetime as YYYYMMDDhhmmss", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_FORMATTED_DATETIME }, INT_MIN, INT_MAX, E, "start_sequence_source_type" },
1854     {"http_user_agent", "override User-Agent field in HTTP header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,    E},
1855     { NULL },
1856 };
1857
1858 static const AVClass hls_class = {
1859     .class_name = "hls muxer",
1860     .item_name  = av_default_item_name,
1861     .option     = options,
1862     .version    = LIBAVUTIL_VERSION_INT,
1863 };
1864
1865
1866 AVOutputFormat ff_hls_muxer = {
1867     .name           = "hls",
1868     .long_name      = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
1869     .extensions     = "m3u8",
1870     .priv_data_size = sizeof(HLSContext),
1871     .audio_codec    = AV_CODEC_ID_AAC,
1872     .video_codec    = AV_CODEC_ID_H264,
1873     .subtitle_codec = AV_CODEC_ID_WEBVTT,
1874     .flags          = AVFMT_NOFILE | AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
1875     .write_header   = hls_write_header,
1876     .write_packet   = hls_write_packet,
1877     .write_trailer  = hls_write_trailer,
1878     .priv_class     = &hls_class,
1879 };