You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2821 lines
99KB

  1. /*
  2. * Apple HTTP Live Streaming segmenter
  3. * Copyright (c) 2012, Luca Barbato
  4. * Copyright (c) 2017 Akamai Technologies, Inc.
  5. *
  6. * This file is part of FFmpeg.
  7. *
  8. * FFmpeg is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * FFmpeg is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with FFmpeg; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  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. #if CONFIG_GCRYPT
  29. #include <gcrypt.h>
  30. #elif CONFIG_OPENSSL
  31. #include <openssl/rand.h>
  32. #endif
  33. #include "libavutil/avassert.h"
  34. #include "libavutil/mathematics.h"
  35. #include "libavutil/parseutils.h"
  36. #include "libavutil/avstring.h"
  37. #include "libavutil/intreadwrite.h"
  38. #include "libavutil/random_seed.h"
  39. #include "libavutil/opt.h"
  40. #include "libavutil/log.h"
  41. #include "libavutil/time_internal.h"
  42. #include "avformat.h"
  43. #include "avio_internal.h"
  44. #if CONFIG_HTTP_PROTOCOL
  45. #include "http.h"
  46. #endif
  47. #include "hlsplaylist.h"
  48. #include "internal.h"
  49. #include "os_support.h"
  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. typedef enum {
  56. CODEC_ATTRIBUTE_WRITTEN = 0,
  57. CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN,
  58. } CodecAttributeStatus;
  59. #define KEYSIZE 16
  60. #define LINE_BUFFER_SIZE 1024
  61. #define HLS_MICROSECOND_UNIT 1000000
  62. #define POSTFIX_PATTERN "_%d"
  63. typedef struct HLSSegment {
  64. char filename[1024];
  65. char sub_filename[1024];
  66. double duration; /* in seconds */
  67. int discont;
  68. int64_t pos;
  69. int64_t size;
  70. char key_uri[LINE_BUFFER_SIZE + 1];
  71. char iv_string[KEYSIZE*2 + 1];
  72. struct HLSSegment *next;
  73. } HLSSegment;
  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. HLS_INDEPENDENT_SEGMENTS = (1 << 13),
  90. } HLSFlags;
  91. typedef enum {
  92. SEGMENT_TYPE_MPEGTS,
  93. SEGMENT_TYPE_FMP4,
  94. } SegmentType;
  95. typedef struct VariantStream {
  96. unsigned number;
  97. int64_t sequence;
  98. AVOutputFormat *oformat;
  99. AVOutputFormat *vtt_oformat;
  100. AVIOContext *out;
  101. int packets_written;
  102. int init_range_length;
  103. AVFormatContext *avf;
  104. AVFormatContext *vtt_avf;
  105. int has_video;
  106. int has_subtitle;
  107. int new_start;
  108. double dpp; // duration per packet
  109. int64_t start_pts;
  110. int64_t end_pts;
  111. double duration; // last segment duration computed so far, in seconds
  112. int64_t start_pos; // last segment starting position
  113. int64_t size; // last segment size
  114. int nb_entries;
  115. int discontinuity_set;
  116. int discontinuity;
  117. int reference_stream_index;
  118. HLSSegment *segments;
  119. HLSSegment *last_segment;
  120. HLSSegment *old_segments;
  121. char *basename;
  122. char *vtt_basename;
  123. char *vtt_m3u8_name;
  124. char *m3u8_name;
  125. double initial_prog_date_time;
  126. char current_segment_final_filename_fmt[1024]; // when renaming segments
  127. char *fmp4_init_filename;
  128. char *base_output_dirname;
  129. int fmp4_init_mode;
  130. AVStream **streams;
  131. char codec_attr[128];
  132. CodecAttributeStatus attr_status;
  133. unsigned int nb_streams;
  134. int m3u8_created; /* status of media play-list creation */
  135. char *agroup; /* audio group name */
  136. char *ccgroup; /* closed caption group name */
  137. char *baseurl;
  138. } VariantStream;
  139. typedef struct ClosedCaptionsStream {
  140. char *ccgroup; /* closed caption group name */
  141. char *instreamid; /* closed captions INSTREAM-ID */
  142. char *language; /* closed captions langauge */
  143. } ClosedCaptionsStream;
  144. typedef struct HLSContext {
  145. const AVClass *class; // Class for private options.
  146. int64_t start_sequence;
  147. uint32_t start_sequence_source_type; // enum StartSequenceSourceType
  148. float time; // Set by a private option.
  149. float init_time; // Set by a private option.
  150. int max_nb_segments; // Set by a private option.
  151. #if FF_API_HLS_WRAP
  152. int wrap; // Set by a private option.
  153. #endif
  154. uint32_t flags; // enum HLSFlags
  155. uint32_t pl_type; // enum PlaylistType
  156. char *segment_filename;
  157. char *fmp4_init_filename;
  158. int segment_type;
  159. int use_localtime; ///< flag to expand filename with localtime
  160. int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename
  161. int allowcache;
  162. int64_t recording_time;
  163. int64_t max_seg_size; // every segment file max size
  164. char *baseurl;
  165. char *format_options_str;
  166. char *vtt_format_options_str;
  167. char *subtitle_filename;
  168. AVDictionary *format_options;
  169. int encrypt;
  170. char *key;
  171. char *key_url;
  172. char *iv;
  173. char *key_basename;
  174. int encrypt_started;
  175. char *key_info_file;
  176. char key_file[LINE_BUFFER_SIZE + 1];
  177. char key_uri[LINE_BUFFER_SIZE + 1];
  178. char key_string[KEYSIZE*2 + 1];
  179. char iv_string[KEYSIZE*2 + 1];
  180. AVDictionary *vtt_format_options;
  181. char *method;
  182. char *user_agent;
  183. VariantStream *var_streams;
  184. unsigned int nb_varstreams;
  185. ClosedCaptionsStream *cc_streams;
  186. unsigned int nb_ccstreams;
  187. int master_m3u8_created; /* status of master play-list creation */
  188. char *master_m3u8_url; /* URL of the master m3u8 file */
  189. int version; /* HLS version */
  190. char *var_stream_map; /* user specified variant stream map string */
  191. char *cc_stream_map; /* user specified closed caption streams map string */
  192. char *master_pl_name;
  193. unsigned int master_publish_rate;
  194. int http_persistent;
  195. AVIOContext *m3u8_out;
  196. AVIOContext *sub_m3u8_out;
  197. } HLSContext;
  198. static int mkdir_p(const char *path) {
  199. int ret = 0;
  200. char *temp = av_strdup(path);
  201. char *pos = temp;
  202. char tmp_ch = '\0';
  203. if (!path || !temp) {
  204. return -1;
  205. }
  206. if (!strncmp(temp, "/", 1) || !strncmp(temp, "\\", 1)) {
  207. pos++;
  208. } else if (!strncmp(temp, "./", 2) || !strncmp(temp, ".\\", 2)) {
  209. pos += 2;
  210. }
  211. for ( ; *pos != '\0'; ++pos) {
  212. if (*pos == '/' || *pos == '\\') {
  213. tmp_ch = *pos;
  214. *pos = '\0';
  215. ret = mkdir(temp, 0755);
  216. *pos = tmp_ch;
  217. }
  218. }
  219. if ((*(pos - 1) != '/') || (*(pos - 1) != '\\')) {
  220. ret = mkdir(temp, 0755);
  221. }
  222. av_free(temp);
  223. return ret;
  224. }
  225. static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename,
  226. AVDictionary **options) {
  227. HLSContext *hls = s->priv_data;
  228. int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
  229. int err = AVERROR_MUXER_NOT_FOUND;
  230. if (!*pb || !http_base_proto || !hls->http_persistent) {
  231. err = s->io_open(s, pb, filename, AVIO_FLAG_WRITE, options);
  232. #if CONFIG_HTTP_PROTOCOL
  233. } else {
  234. URLContext *http_url_context = ffio_geturlcontext(*pb);
  235. av_assert0(http_url_context);
  236. err = ff_http_do_new_request(http_url_context, filename);
  237. #endif
  238. }
  239. return err;
  240. }
  241. static void hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char *filename) {
  242. HLSContext *hls = s->priv_data;
  243. int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
  244. if (!http_base_proto || !hls->http_persistent || hls->key_info_file || hls->encrypt) {
  245. ff_format_io_close(s, pb);
  246. #if CONFIG_HTTP_PROTOCOL
  247. } else {
  248. URLContext *http_url_context = ffio_geturlcontext(*pb);
  249. av_assert0(http_url_context);
  250. avio_flush(*pb);
  251. ffurl_shutdown(http_url_context, AVIO_FLAG_WRITE);
  252. #endif
  253. }
  254. }
  255. static void set_http_options(AVFormatContext *s, AVDictionary **options, HLSContext *c)
  256. {
  257. int http_base_proto = ff_is_http_proto(s->url);
  258. if (c->method) {
  259. av_dict_set(options, "method", c->method, 0);
  260. } else if (http_base_proto) {
  261. av_log(c, AV_LOG_WARNING, "No HTTP method set, hls muxer defaulting to method PUT.\n");
  262. av_dict_set(options, "method", "PUT", 0);
  263. }
  264. if (c->user_agent)
  265. av_dict_set(options, "user_agent", c->user_agent, 0);
  266. if (c->http_persistent)
  267. av_dict_set_int(options, "multiple_requests", 1, 0);
  268. }
  269. static void write_codec_attr(AVStream *st, VariantStream *vs) {
  270. int codec_strlen = strlen(vs->codec_attr);
  271. char attr[32];
  272. if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
  273. return;
  274. if (vs->attr_status == CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN)
  275. return;
  276. if (st->codecpar->codec_id == AV_CODEC_ID_H264) {
  277. uint8_t *data = st->codecpar->extradata;
  278. if (data && (data[0] | data[1] | data[2]) == 0 && data[3] == 1 && (data[4] & 0x1F) == 7) {
  279. snprintf(attr, sizeof(attr),
  280. "avc1.%02x%02x%02x", data[5], data[6], data[7]);
  281. } else {
  282. goto fail;
  283. }
  284. } else if (st->codecpar->codec_id == AV_CODEC_ID_MP2) {
  285. snprintf(attr, sizeof(attr), "mp4a.40.33");
  286. } else if (st->codecpar->codec_id == AV_CODEC_ID_MP3) {
  287. snprintf(attr, sizeof(attr), "mp4a.40.34");
  288. } else if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
  289. /* TODO : For HE-AAC, HE-AACv2, the last digit needs to be set to 5 and 29 respectively */
  290. snprintf(attr, sizeof(attr), "mp4a.40.2");
  291. } else if (st->codecpar->codec_id == AV_CODEC_ID_AC3) {
  292. snprintf(attr, sizeof(attr), "ac-3");
  293. } else if (st->codecpar->codec_id == AV_CODEC_ID_EAC3) {
  294. snprintf(attr, sizeof(attr), "ec-3");
  295. } else {
  296. goto fail;
  297. }
  298. // Don't write the same attribute multiple times
  299. if (!av_stristr(vs->codec_attr, attr)) {
  300. snprintf(vs->codec_attr + codec_strlen,
  301. sizeof(vs->codec_attr) - codec_strlen,
  302. "%s%s", codec_strlen ? "," : "", attr);
  303. }
  304. return;
  305. fail:
  306. vs->codec_attr[0] = '\0';
  307. vs->attr_status = CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN;
  308. return;
  309. }
  310. static int replace_int_data_in_filename(char **s, const char *filename, char placeholder, int64_t number)
  311. {
  312. const char *p;
  313. char *new_filename;
  314. char c;
  315. int nd, addchar_count;
  316. int found_count = 0;
  317. AVBPrint buf;
  318. av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
  319. p = filename;
  320. for (;;) {
  321. c = *p;
  322. if (c == '\0')
  323. break;
  324. if (c == '%' && *(p+1) == '%') // %%
  325. addchar_count = 2;
  326. else if (c == '%' && (av_isdigit(*(p+1)) || *(p+1) == placeholder)) {
  327. nd = 0;
  328. addchar_count = 1;
  329. while (av_isdigit(*(p + addchar_count))) {
  330. nd = nd * 10 + *(p + addchar_count) - '0';
  331. addchar_count++;
  332. }
  333. if (*(p + addchar_count) == placeholder) {
  334. av_bprintf(&buf, "%0*"PRId64, (number < 0) ? nd : nd++, number);
  335. p += (addchar_count + 1);
  336. addchar_count = 0;
  337. found_count++;
  338. }
  339. } else
  340. addchar_count = 1;
  341. av_bprint_append_data(&buf, p, addchar_count);
  342. p += addchar_count;
  343. }
  344. if (!av_bprint_is_complete(&buf)) {
  345. av_bprint_finalize(&buf, NULL);
  346. return -1;
  347. }
  348. if (av_bprint_finalize(&buf, &new_filename) < 0 || !new_filename)
  349. return -1;
  350. *s = new_filename;
  351. return found_count;
  352. }
  353. static void write_styp(AVIOContext *pb)
  354. {
  355. avio_wb32(pb, 24);
  356. ffio_wfourcc(pb, "styp");
  357. ffio_wfourcc(pb, "msdh");
  358. avio_wb32(pb, 0); /* minor */
  359. ffio_wfourcc(pb, "msdh");
  360. ffio_wfourcc(pb, "msix");
  361. }
  362. static int flush_dynbuf(VariantStream *vs, int *range_length)
  363. {
  364. AVFormatContext *ctx = vs->avf;
  365. uint8_t *buffer;
  366. if (!ctx->pb) {
  367. return AVERROR(EINVAL);
  368. }
  369. // flush
  370. av_write_frame(ctx, NULL);
  371. avio_flush(ctx->pb);
  372. // write out to file
  373. *range_length = avio_close_dyn_buf(ctx->pb, &buffer);
  374. ctx->pb = NULL;
  375. avio_write(vs->out, buffer, *range_length);
  376. av_free(buffer);
  377. // re-open buffer
  378. return avio_open_dyn_buf(&ctx->pb);
  379. }
  380. static int hls_delete_old_segments(AVFormatContext *s, HLSContext *hls,
  381. VariantStream *vs) {
  382. HLSSegment *segment, *previous_segment = NULL;
  383. float playlist_duration = 0.0f;
  384. int ret = 0, path_size, sub_path_size;
  385. char *dirname = NULL, *p, *sub_path;
  386. char *path = NULL;
  387. AVDictionary *options = NULL;
  388. AVIOContext *out = NULL;
  389. const char *proto = NULL;
  390. segment = vs->segments;
  391. while (segment) {
  392. playlist_duration += segment->duration;
  393. segment = segment->next;
  394. }
  395. segment = vs->old_segments;
  396. while (segment) {
  397. playlist_duration -= segment->duration;
  398. previous_segment = segment;
  399. segment = previous_segment->next;
  400. if (playlist_duration <= -previous_segment->duration) {
  401. previous_segment->next = NULL;
  402. break;
  403. }
  404. }
  405. if (segment && !hls->use_localtime_mkdir) {
  406. if (hls->segment_filename) {
  407. dirname = av_strdup(hls->segment_filename);
  408. } else {
  409. dirname = av_strdup(vs->avf->url);
  410. }
  411. if (!dirname) {
  412. ret = AVERROR(ENOMEM);
  413. goto fail;
  414. }
  415. p = (char *)av_basename(dirname);
  416. *p = '\0';
  417. }
  418. while (segment) {
  419. av_log(hls, AV_LOG_DEBUG, "deleting old segment %s\n",
  420. segment->filename);
  421. path_size = (hls->use_localtime_mkdir ? 0 : strlen(dirname)) + strlen(segment->filename) + 1;
  422. path = av_malloc(path_size);
  423. if (!path) {
  424. ret = AVERROR(ENOMEM);
  425. goto fail;
  426. }
  427. if (hls->use_localtime_mkdir)
  428. av_strlcpy(path, segment->filename, path_size);
  429. else { // segment->filename contains basename only
  430. av_strlcpy(path, dirname, path_size);
  431. av_strlcat(path, segment->filename, path_size);
  432. }
  433. proto = avio_find_protocol_name(s->url);
  434. if (hls->method || (proto && !av_strcasecmp(proto, "http"))) {
  435. av_dict_set(&options, "method", "DELETE", 0);
  436. if ((ret = vs->avf->io_open(vs->avf, &out, path, AVIO_FLAG_WRITE, &options)) < 0)
  437. goto fail;
  438. ff_format_io_close(vs->avf, &out);
  439. } else if (unlink(path) < 0) {
  440. av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n",
  441. path, strerror(errno));
  442. }
  443. if ((segment->sub_filename[0] != '\0')) {
  444. sub_path_size = strlen(segment->sub_filename) + 1 + (dirname ? strlen(dirname) : 0);
  445. sub_path = av_malloc(sub_path_size);
  446. if (!sub_path) {
  447. ret = AVERROR(ENOMEM);
  448. goto fail;
  449. }
  450. av_strlcpy(sub_path, dirname, sub_path_size);
  451. av_strlcat(sub_path, segment->sub_filename, sub_path_size);
  452. if (hls->method || (proto && !av_strcasecmp(proto, "http"))) {
  453. av_dict_set(&options, "method", "DELETE", 0);
  454. if ((ret = vs->avf->io_open(vs->avf, &out, sub_path, AVIO_FLAG_WRITE, &options)) < 0) {
  455. av_free(sub_path);
  456. goto fail;
  457. }
  458. ff_format_io_close(vs->avf, &out);
  459. } else if (unlink(sub_path) < 0) {
  460. av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n",
  461. sub_path, strerror(errno));
  462. }
  463. av_free(sub_path);
  464. }
  465. av_freep(&path);
  466. previous_segment = segment;
  467. segment = previous_segment->next;
  468. av_free(previous_segment);
  469. }
  470. fail:
  471. av_free(path);
  472. av_free(dirname);
  473. return ret;
  474. }
  475. static int randomize(uint8_t *buf, int len)
  476. {
  477. #if CONFIG_GCRYPT
  478. gcry_randomize(buf, len, GCRY_VERY_STRONG_RANDOM);
  479. return 0;
  480. #elif CONFIG_OPENSSL
  481. if (RAND_bytes(buf, len))
  482. return 0;
  483. #else
  484. return AVERROR(ENOSYS);
  485. #endif
  486. return AVERROR(EINVAL);
  487. }
  488. static int do_encrypt(AVFormatContext *s, VariantStream *vs)
  489. {
  490. HLSContext *hls = s->priv_data;
  491. int ret;
  492. int len;
  493. AVIOContext *pb;
  494. uint8_t key[KEYSIZE];
  495. len = strlen(s->url) + 4 + 1;
  496. hls->key_basename = av_mallocz(len);
  497. if (!hls->key_basename)
  498. return AVERROR(ENOMEM);
  499. av_strlcpy(hls->key_basename, s->url, len);
  500. av_strlcat(hls->key_basename, ".key", len);
  501. if (hls->key_url) {
  502. av_strlcpy(hls->key_file, hls->key_url, sizeof(hls->key_file));
  503. av_strlcpy(hls->key_uri, hls->key_url, sizeof(hls->key_uri));
  504. } else {
  505. av_strlcpy(hls->key_file, hls->key_basename, sizeof(hls->key_file));
  506. av_strlcpy(hls->key_uri, hls->key_basename, sizeof(hls->key_uri));
  507. }
  508. if (!*hls->iv_string) {
  509. uint8_t iv[16] = { 0 };
  510. char buf[33];
  511. if (!hls->iv) {
  512. AV_WB64(iv + 8, vs->sequence);
  513. } else {
  514. memcpy(iv, hls->iv, sizeof(iv));
  515. }
  516. ff_data_to_hex(buf, iv, sizeof(iv), 0);
  517. buf[32] = '\0';
  518. memcpy(hls->iv_string, buf, sizeof(hls->iv_string));
  519. }
  520. if (!*hls->key_uri) {
  521. av_log(hls, AV_LOG_ERROR, "no key URI specified in key info file\n");
  522. return AVERROR(EINVAL);
  523. }
  524. if (!*hls->key_file) {
  525. av_log(hls, AV_LOG_ERROR, "no key file specified in key info file\n");
  526. return AVERROR(EINVAL);
  527. }
  528. if (!*hls->key_string) {
  529. if (!hls->key) {
  530. if ((ret = randomize(key, sizeof(key))) < 0) {
  531. av_log(s, AV_LOG_ERROR, "Cannot generate a strong random key\n");
  532. return ret;
  533. }
  534. } else {
  535. memcpy(key, hls->key, sizeof(key));
  536. }
  537. ff_data_to_hex(hls->key_string, key, sizeof(key), 0);
  538. if ((ret = s->io_open(s, &pb, hls->key_file, AVIO_FLAG_WRITE, NULL)) < 0)
  539. return ret;
  540. avio_seek(pb, 0, SEEK_CUR);
  541. avio_write(pb, key, KEYSIZE);
  542. avio_close(pb);
  543. }
  544. return 0;
  545. }
  546. static int hls_encryption_start(AVFormatContext *s)
  547. {
  548. HLSContext *hls = s->priv_data;
  549. int ret;
  550. AVIOContext *pb;
  551. uint8_t key[KEYSIZE];
  552. if ((ret = s->io_open(s, &pb, hls->key_info_file, AVIO_FLAG_READ, NULL)) < 0) {
  553. av_log(hls, AV_LOG_ERROR,
  554. "error opening key info file %s\n", hls->key_info_file);
  555. return ret;
  556. }
  557. ff_get_line(pb, hls->key_uri, sizeof(hls->key_uri));
  558. hls->key_uri[strcspn(hls->key_uri, "\r\n")] = '\0';
  559. ff_get_line(pb, hls->key_file, sizeof(hls->key_file));
  560. hls->key_file[strcspn(hls->key_file, "\r\n")] = '\0';
  561. ff_get_line(pb, hls->iv_string, sizeof(hls->iv_string));
  562. hls->iv_string[strcspn(hls->iv_string, "\r\n")] = '\0';
  563. ff_format_io_close(s, &pb);
  564. if (!*hls->key_uri) {
  565. av_log(hls, AV_LOG_ERROR, "no key URI specified in key info file\n");
  566. return AVERROR(EINVAL);
  567. }
  568. if (!*hls->key_file) {
  569. av_log(hls, AV_LOG_ERROR, "no key file specified in key info file\n");
  570. return AVERROR(EINVAL);
  571. }
  572. if ((ret = s->io_open(s, &pb, hls->key_file, AVIO_FLAG_READ, NULL)) < 0) {
  573. av_log(hls, AV_LOG_ERROR, "error opening key file %s\n", hls->key_file);
  574. return ret;
  575. }
  576. ret = avio_read(pb, key, sizeof(key));
  577. ff_format_io_close(s, &pb);
  578. if (ret != sizeof(key)) {
  579. av_log(hls, AV_LOG_ERROR, "error reading key file %s\n", hls->key_file);
  580. if (ret >= 0 || ret == AVERROR_EOF)
  581. ret = AVERROR(EINVAL);
  582. return ret;
  583. }
  584. ff_data_to_hex(hls->key_string, key, sizeof(key), 0);
  585. return 0;
  586. }
  587. static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
  588. {
  589. int len = ff_get_line(s, buf, maxlen);
  590. while (len > 0 && av_isspace(buf[len - 1]))
  591. buf[--len] = '\0';
  592. return len;
  593. }
  594. static int hls_mux_init(AVFormatContext *s, VariantStream *vs)
  595. {
  596. AVDictionary *options = NULL;
  597. HLSContext *hls = s->priv_data;
  598. AVFormatContext *oc;
  599. AVFormatContext *vtt_oc = NULL;
  600. int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
  601. int i, ret;
  602. ret = avformat_alloc_output_context2(&vs->avf, vs->oformat, NULL, NULL);
  603. if (ret < 0)
  604. return ret;
  605. oc = vs->avf;
  606. oc->url = av_strdup("");
  607. if (!oc->url)
  608. return AVERROR(ENOMEM);
  609. oc->oformat = vs->oformat;
  610. oc->interrupt_callback = s->interrupt_callback;
  611. oc->max_delay = s->max_delay;
  612. oc->opaque = s->opaque;
  613. oc->io_open = s->io_open;
  614. oc->io_close = s->io_close;
  615. av_dict_copy(&oc->metadata, s->metadata, 0);
  616. if(vs->vtt_oformat) {
  617. ret = avformat_alloc_output_context2(&vs->vtt_avf, vs->vtt_oformat, NULL, NULL);
  618. if (ret < 0)
  619. return ret;
  620. vtt_oc = vs->vtt_avf;
  621. vtt_oc->oformat = vs->vtt_oformat;
  622. av_dict_copy(&vtt_oc->metadata, s->metadata, 0);
  623. }
  624. for (i = 0; i < vs->nb_streams; i++) {
  625. AVStream *st;
  626. AVFormatContext *loc;
  627. if (vs->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
  628. loc = vtt_oc;
  629. else
  630. loc = oc;
  631. if (!(st = avformat_new_stream(loc, NULL)))
  632. return AVERROR(ENOMEM);
  633. avcodec_parameters_copy(st->codecpar, vs->streams[i]->codecpar);
  634. if (!oc->oformat->codec_tag ||
  635. av_codec_get_id (oc->oformat->codec_tag, vs->streams[i]->codecpar->codec_tag) == st->codecpar->codec_id ||
  636. av_codec_get_tag(oc->oformat->codec_tag, vs->streams[i]->codecpar->codec_id) <= 0) {
  637. st->codecpar->codec_tag = vs->streams[i]->codecpar->codec_tag;
  638. } else {
  639. st->codecpar->codec_tag = 0;
  640. }
  641. st->sample_aspect_ratio = vs->streams[i]->sample_aspect_ratio;
  642. st->time_base = vs->streams[i]->time_base;
  643. av_dict_copy(&st->metadata, vs->streams[i]->metadata, 0);
  644. }
  645. vs->packets_written = 1;
  646. vs->start_pos = 0;
  647. vs->new_start = 1;
  648. vs->fmp4_init_mode = 0;
  649. if (hls->segment_type == SEGMENT_TYPE_FMP4) {
  650. if (hls->max_seg_size > 0) {
  651. av_log(s, AV_LOG_WARNING, "Multi-file byterange mode is currently unsupported in the HLS muxer.\n");
  652. return AVERROR_PATCHWELCOME;
  653. }
  654. vs->packets_written = 0;
  655. vs->init_range_length = 0;
  656. vs->fmp4_init_mode = !byterange_mode;
  657. set_http_options(s, &options, hls);
  658. if ((ret = avio_open_dyn_buf(&oc->pb)) < 0)
  659. return ret;
  660. ret = hlsenc_io_open(s, &vs->out, vs->base_output_dirname, &options);
  661. av_dict_free(&options);
  662. if (ret < 0) {
  663. av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", vs->fmp4_init_filename);
  664. return ret;
  665. }
  666. if (hls->format_options_str) {
  667. ret = av_dict_parse_string(&hls->format_options, hls->format_options_str, "=", ":", 0);
  668. if (ret < 0) {
  669. av_log(s, AV_LOG_ERROR, "Could not parse format options list '%s'\n",
  670. hls->format_options_str);
  671. return ret;
  672. }
  673. }
  674. av_dict_copy(&options, hls->format_options, 0);
  675. av_dict_set(&options, "fflags", "-autobsf", 0);
  676. av_dict_set(&options, "movflags", "frag_custom+dash+delay_moov", 0);
  677. ret = avformat_init_output(oc, &options);
  678. if (ret < 0)
  679. return ret;
  680. if (av_dict_count(options)) {
  681. av_log(s, AV_LOG_ERROR, "Some of the provided format options in '%s' are not recognized\n", hls->format_options_str);
  682. av_dict_free(&options);
  683. return AVERROR(EINVAL);
  684. }
  685. avio_flush(oc->pb);
  686. av_dict_free(&options);
  687. }
  688. return 0;
  689. }
  690. static HLSSegment *find_segment_by_filename(HLSSegment *segment, const char *filename)
  691. {
  692. while (segment) {
  693. if (!av_strcasecmp(segment->filename,filename))
  694. return segment;
  695. segment = segment->next;
  696. }
  697. return (HLSSegment *) NULL;
  698. }
  699. static int sls_flags_filename_process(struct AVFormatContext *s, HLSContext *hls,
  700. VariantStream *vs, HLSSegment *en,
  701. double duration, int64_t pos, int64_t size)
  702. {
  703. if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
  704. strlen(vs->current_segment_final_filename_fmt)) {
  705. char * new_url = av_strdup(vs->current_segment_final_filename_fmt);
  706. if (!new_url) {
  707. av_free(en);
  708. return AVERROR(ENOMEM);
  709. }
  710. ff_format_set_url(vs->avf, new_url);
  711. if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
  712. char *filename = NULL;
  713. if (replace_int_data_in_filename(&filename, vs->avf->url, 's', pos + size) < 1) {
  714. av_log(hls, AV_LOG_ERROR,
  715. "Invalid second level segment filename template '%s', "
  716. "you can try to remove second_level_segment_size flag\n",
  717. vs->avf->url);
  718. av_free(filename);
  719. av_free(en);
  720. return AVERROR(EINVAL);
  721. }
  722. ff_format_set_url(vs->avf, filename);
  723. }
  724. if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
  725. char *filename = NULL;
  726. if (replace_int_data_in_filename(&filename, vs->avf->url,
  727. 't', (int64_t)round(duration * HLS_MICROSECOND_UNIT)) < 1) {
  728. av_log(hls, AV_LOG_ERROR,
  729. "Invalid second level segment filename template '%s', "
  730. "you can try to remove second_level_segment_time flag\n",
  731. vs->avf->url);
  732. av_free(filename);
  733. av_free(en);
  734. return AVERROR(EINVAL);
  735. }
  736. ff_format_set_url(vs->avf, filename);
  737. }
  738. }
  739. return 0;
  740. }
  741. static int sls_flag_check_duration_size_index(HLSContext *hls)
  742. {
  743. int ret = 0;
  744. if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
  745. av_log(hls, AV_LOG_ERROR,
  746. "second_level_segment_duration hls_flag requires use_localtime to be true\n");
  747. ret = AVERROR(EINVAL);
  748. }
  749. if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
  750. av_log(hls, AV_LOG_ERROR,
  751. "second_level_segment_size hls_flag requires use_localtime to be true\n");
  752. ret = AVERROR(EINVAL);
  753. }
  754. if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {
  755. av_log(hls, AV_LOG_ERROR,
  756. "second_level_segment_index hls_flag requires use_localtime to be true\n");
  757. ret = AVERROR(EINVAL);
  758. }
  759. return ret;
  760. }
  761. static int sls_flag_check_duration_size(HLSContext *hls, VariantStream *vs)
  762. {
  763. const char *proto = avio_find_protocol_name(vs->basename);
  764. int segment_renaming_ok = proto && !strcmp(proto, "file");
  765. int ret = 0;
  766. if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) && !segment_renaming_ok) {
  767. av_log(hls, AV_LOG_ERROR,
  768. "second_level_segment_duration hls_flag works only with file protocol segment names\n");
  769. ret = AVERROR(EINVAL);
  770. }
  771. if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) && !segment_renaming_ok) {
  772. av_log(hls, AV_LOG_ERROR,
  773. "second_level_segment_size hls_flag works only with file protocol segment names\n");
  774. ret = AVERROR(EINVAL);
  775. }
  776. return ret;
  777. }
  778. static void sls_flag_file_rename(HLSContext *hls, VariantStream *vs, char *old_filename) {
  779. if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&
  780. strlen(vs->current_segment_final_filename_fmt)) {
  781. ff_rename(old_filename, vs->avf->url, hls);
  782. }
  783. }
  784. static int sls_flag_use_localtime_filename(AVFormatContext *oc, HLSContext *c, VariantStream *vs)
  785. {
  786. if (c->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {
  787. char *filename = NULL;
  788. if (replace_int_data_in_filename(&filename,
  789. #if FF_API_HLS_WRAP
  790. oc->url, 'd', c->wrap ? vs->sequence % c->wrap : vs->sequence) < 1) {
  791. #else
  792. oc->url, 'd', vs->sequence) < 1) {
  793. #endif
  794. av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
  795. "you can try to remove second_level_segment_index flag\n",
  796. oc->url);
  797. av_free(filename);
  798. return AVERROR(EINVAL);
  799. }
  800. ff_format_set_url(oc, filename);
  801. }
  802. if (c->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) {
  803. av_strlcpy(vs->current_segment_final_filename_fmt, oc->url,
  804. sizeof(vs->current_segment_final_filename_fmt));
  805. if (c->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
  806. char *filename = NULL;
  807. if (replace_int_data_in_filename(&filename, oc->url, 's', 0) < 1) {
  808. av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
  809. "you can try to remove second_level_segment_size flag\n",
  810. oc->url);
  811. av_free(filename);
  812. return AVERROR(EINVAL);
  813. }
  814. ff_format_set_url(oc, filename);
  815. }
  816. if (c->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
  817. char *filename = NULL;
  818. if (replace_int_data_in_filename(&filename, oc->url, 't', 0) < 1) {
  819. av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
  820. "you can try to remove second_level_segment_time flag\n",
  821. oc->url);
  822. av_free(filename);
  823. return AVERROR(EINVAL);
  824. }
  825. ff_format_set_url(oc, filename);
  826. }
  827. }
  828. return 0;
  829. }
  830. /* Create a new segment and append it to the segment list */
  831. static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls,
  832. VariantStream *vs, double duration, int64_t pos,
  833. int64_t size)
  834. {
  835. HLSSegment *en = av_malloc(sizeof(*en));
  836. const char *filename;
  837. int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
  838. int ret;
  839. if (!en)
  840. return AVERROR(ENOMEM);
  841. ret = sls_flags_filename_process(s, hls, vs, en, duration, pos, size);
  842. if (ret < 0) {
  843. return ret;
  844. }
  845. filename = av_basename(vs->avf->url);
  846. if (hls->use_localtime_mkdir) {
  847. filename = vs->avf->url;
  848. }
  849. if ((find_segment_by_filename(vs->segments, filename) || find_segment_by_filename(vs->old_segments, filename))
  850. && !byterange_mode) {
  851. av_log(hls, AV_LOG_WARNING, "Duplicated segment filename detected: %s\n", filename);
  852. }
  853. av_strlcpy(en->filename, filename, sizeof(en->filename));
  854. if(vs->has_subtitle)
  855. av_strlcpy(en->sub_filename, av_basename(vs->vtt_avf->url), sizeof(en->sub_filename));
  856. else
  857. en->sub_filename[0] = '\0';
  858. en->duration = duration;
  859. en->pos = pos;
  860. en->size = size;
  861. en->next = NULL;
  862. en->discont = 0;
  863. if (vs->discontinuity) {
  864. en->discont = 1;
  865. vs->discontinuity = 0;
  866. }
  867. if (hls->key_info_file || hls->encrypt) {
  868. av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri));
  869. av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string));
  870. }
  871. if (!vs->segments)
  872. vs->segments = en;
  873. else
  874. vs->last_segment->next = en;
  875. vs->last_segment = en;
  876. // EVENT or VOD playlists imply sliding window cannot be used
  877. if (hls->pl_type != PLAYLIST_TYPE_NONE)
  878. hls->max_nb_segments = 0;
  879. if (hls->max_nb_segments && vs->nb_entries >= hls->max_nb_segments) {
  880. en = vs->segments;
  881. vs->initial_prog_date_time += en->duration;
  882. vs->segments = en->next;
  883. if (en && hls->flags & HLS_DELETE_SEGMENTS &&
  884. #if FF_API_HLS_WRAP
  885. !(hls->flags & HLS_SINGLE_FILE || hls->wrap)) {
  886. #else
  887. !(hls->flags & HLS_SINGLE_FILE)) {
  888. #endif
  889. en->next = vs->old_segments;
  890. vs->old_segments = en;
  891. if ((ret = hls_delete_old_segments(s, hls, vs)) < 0)
  892. return ret;
  893. } else
  894. av_free(en);
  895. } else
  896. vs->nb_entries++;
  897. if (hls->max_seg_size > 0) {
  898. return 0;
  899. }
  900. vs->sequence++;
  901. return 0;
  902. }
  903. static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs)
  904. {
  905. HLSContext *hls = s->priv_data;
  906. AVIOContext *in;
  907. int ret = 0, is_segment = 0;
  908. int64_t new_start_pos;
  909. char line[1024];
  910. const char *ptr;
  911. const char *end;
  912. if ((ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ,
  913. &s->interrupt_callback, NULL,
  914. s->protocol_whitelist, s->protocol_blacklist)) < 0)
  915. return ret;
  916. read_chomp_line(in, line, sizeof(line));
  917. if (strcmp(line, "#EXTM3U")) {
  918. ret = AVERROR_INVALIDDATA;
  919. goto fail;
  920. }
  921. vs->discontinuity = 0;
  922. while (!avio_feof(in)) {
  923. read_chomp_line(in, line, sizeof(line));
  924. if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
  925. int64_t tmp_sequence = strtoll(ptr, NULL, 10);
  926. if (tmp_sequence < vs->sequence)
  927. av_log(hls, AV_LOG_VERBOSE,
  928. "Found playlist sequence number was smaller """
  929. "than specified start sequence number: %"PRId64" < %"PRId64", "
  930. "omitting\n", tmp_sequence, hls->start_sequence);
  931. else {
  932. av_log(hls, AV_LOG_DEBUG, "Found playlist sequence number: %"PRId64"\n", tmp_sequence);
  933. vs->sequence = tmp_sequence;
  934. }
  935. } else if (av_strstart(line, "#EXT-X-DISCONTINUITY", &ptr)) {
  936. is_segment = 1;
  937. vs->discontinuity = 1;
  938. } else if (av_strstart(line, "#EXTINF:", &ptr)) {
  939. is_segment = 1;
  940. vs->duration = atof(ptr);
  941. } else if (av_stristart(line, "#EXT-X-KEY:", &ptr)) {
  942. ptr = av_stristr(line, "URI=\"");
  943. if (ptr) {
  944. ptr += strlen("URI=\"");
  945. end = av_stristr(ptr, ",");
  946. if (end) {
  947. av_strlcpy(hls->key_uri, ptr, end - ptr);
  948. } else {
  949. av_strlcpy(hls->key_uri, ptr, sizeof(hls->key_uri));
  950. }
  951. }
  952. ptr = av_stristr(line, "IV=0x");
  953. if (ptr) {
  954. ptr += strlen("IV=0x");
  955. end = av_stristr(ptr, ",");
  956. if (end) {
  957. av_strlcpy(hls->iv_string, ptr, end - ptr);
  958. } else {
  959. av_strlcpy(hls->iv_string, ptr, sizeof(hls->iv_string));
  960. }
  961. }
  962. } else if (av_strstart(line, "#", NULL)) {
  963. continue;
  964. } else if (line[0]) {
  965. if (is_segment) {
  966. char *new_file = av_strdup(line);
  967. if (!new_file) {
  968. ret = AVERROR(ENOMEM);
  969. goto fail;
  970. }
  971. ff_format_set_url(vs->avf, new_file);
  972. is_segment = 0;
  973. new_start_pos = avio_tell(vs->avf->pb);
  974. vs->size = new_start_pos - vs->start_pos;
  975. ret = hls_append_segment(s, hls, vs, vs->duration, vs->start_pos, vs->size);
  976. if (ret < 0)
  977. goto fail;
  978. vs->start_pos = new_start_pos;
  979. }
  980. }
  981. }
  982. fail:
  983. avio_close(in);
  984. return ret;
  985. }
  986. static void hls_free_segments(HLSSegment *p)
  987. {
  988. HLSSegment *en;
  989. while(p) {
  990. en = p;
  991. p = p->next;
  992. av_free(en);
  993. }
  994. }
  995. static int hls_rename_temp_file(AVFormatContext *s, AVFormatContext *oc)
  996. {
  997. size_t len = strlen(oc->url);
  998. char *final_filename = av_strdup(oc->url);
  999. int ret;
  1000. if (!final_filename)
  1001. return AVERROR(ENOMEM);
  1002. final_filename[len-4] = '\0';
  1003. ret = ff_rename(oc->url, final_filename, s);
  1004. oc->url[len-4] = '\0';
  1005. av_freep(&final_filename);
  1006. return ret;
  1007. }
  1008. static int get_relative_url(const char *master_url, const char *media_url,
  1009. char *rel_url, int rel_url_buf_size)
  1010. {
  1011. char *p = NULL;
  1012. int base_len = -1;
  1013. p = strrchr(master_url, '/') ? strrchr(master_url, '/') :\
  1014. strrchr(master_url, '\\');
  1015. if (p) {
  1016. base_len = FFABS(p - master_url);
  1017. if (av_strncasecmp(master_url, media_url, base_len)) {
  1018. av_log(NULL, AV_LOG_WARNING, "Unable to find relative url\n");
  1019. return AVERROR(EINVAL);
  1020. }
  1021. }
  1022. av_strlcpy(rel_url, &(media_url[base_len + 1]), rel_url_buf_size);
  1023. return 0;
  1024. }
  1025. static int create_master_playlist(AVFormatContext *s,
  1026. VariantStream * const input_vs)
  1027. {
  1028. HLSContext *hls = s->priv_data;
  1029. VariantStream *vs, *temp_vs;
  1030. AVStream *vid_st, *aud_st;
  1031. AVDictionary *options = NULL;
  1032. unsigned int i, j;
  1033. int m3u8_name_size, ret, bandwidth;
  1034. char *m3u8_rel_name, *ccgroup;
  1035. ClosedCaptionsStream *ccs;
  1036. input_vs->m3u8_created = 1;
  1037. if (!hls->master_m3u8_created) {
  1038. /* For the first time, wait until all the media playlists are created */
  1039. for (i = 0; i < hls->nb_varstreams; i++)
  1040. if (!hls->var_streams[i].m3u8_created)
  1041. return 0;
  1042. } else {
  1043. /* Keep publishing the master playlist at the configured rate */
  1044. if (&hls->var_streams[0] != input_vs || !hls->master_publish_rate ||
  1045. input_vs->number % hls->master_publish_rate)
  1046. return 0;
  1047. }
  1048. set_http_options(s, &options, hls);
  1049. ret = hlsenc_io_open(s, &hls->m3u8_out, hls->master_m3u8_url, &options);
  1050. av_dict_free(&options);
  1051. if (ret < 0) {
  1052. av_log(NULL, AV_LOG_ERROR, "Failed to open master play list file '%s'\n",
  1053. hls->master_m3u8_url);
  1054. goto fail;
  1055. }
  1056. ff_hls_write_playlist_version(hls->m3u8_out, hls->version);
  1057. for (i = 0; i < hls->nb_ccstreams; i++) {
  1058. ccs = &(hls->cc_streams[i]);
  1059. avio_printf(hls->m3u8_out, "#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS");
  1060. avio_printf(hls->m3u8_out, ",GROUP-ID=\"%s\"", ccs->ccgroup);
  1061. avio_printf(hls->m3u8_out, ",NAME=\"%s\"", ccs->instreamid);
  1062. if (ccs->language)
  1063. avio_printf(hls->m3u8_out, ",LANGUAGE=\"%s\"", ccs->language);
  1064. avio_printf(hls->m3u8_out, ",INSTREAM-ID=\"%s\"\n", ccs->instreamid);
  1065. }
  1066. /* For audio only variant streams add #EXT-X-MEDIA tag with attributes*/
  1067. for (i = 0; i < hls->nb_varstreams; i++) {
  1068. vs = &(hls->var_streams[i]);
  1069. if (vs->has_video || vs->has_subtitle || !vs->agroup)
  1070. continue;
  1071. m3u8_name_size = strlen(vs->m3u8_name) + 1;
  1072. m3u8_rel_name = av_malloc(m3u8_name_size);
  1073. if (!m3u8_rel_name) {
  1074. ret = AVERROR(ENOMEM);
  1075. goto fail;
  1076. }
  1077. av_strlcpy(m3u8_rel_name, vs->m3u8_name, m3u8_name_size);
  1078. ret = get_relative_url(hls->master_m3u8_url, vs->m3u8_name,
  1079. m3u8_rel_name, m3u8_name_size);
  1080. if (ret < 0) {
  1081. av_log(s, AV_LOG_ERROR, "Unable to find relative URL\n");
  1082. goto fail;
  1083. }
  1084. ff_hls_write_audio_rendition(hls->m3u8_out, vs->agroup, m3u8_rel_name, 0, 1);
  1085. av_freep(&m3u8_rel_name);
  1086. }
  1087. /* For variant streams with video add #EXT-X-STREAM-INF tag with attributes*/
  1088. for (i = 0; i < hls->nb_varstreams; i++) {
  1089. vs = &(hls->var_streams[i]);
  1090. m3u8_name_size = strlen(vs->m3u8_name) + 1;
  1091. m3u8_rel_name = av_malloc(m3u8_name_size);
  1092. if (!m3u8_rel_name) {
  1093. ret = AVERROR(ENOMEM);
  1094. goto fail;
  1095. }
  1096. av_strlcpy(m3u8_rel_name, vs->m3u8_name, m3u8_name_size);
  1097. ret = get_relative_url(hls->master_m3u8_url, vs->m3u8_name,
  1098. m3u8_rel_name, m3u8_name_size);
  1099. if (ret < 0) {
  1100. av_log(NULL, AV_LOG_ERROR, "Unable to find relative URL\n");
  1101. goto fail;
  1102. }
  1103. vid_st = NULL;
  1104. aud_st = NULL;
  1105. for (j = 0; j < vs->nb_streams; j++) {
  1106. if (vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
  1107. vid_st = vs->streams[j];
  1108. else if (vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
  1109. aud_st = vs->streams[j];
  1110. }
  1111. if (!vid_st && !aud_st) {
  1112. av_log(NULL, AV_LOG_WARNING, "Media stream not found\n");
  1113. continue;
  1114. }
  1115. /**
  1116. * Traverse through the list of audio only rendition streams and find
  1117. * the rendition which has highest bitrate in the same audio group
  1118. */
  1119. if (vs->agroup) {
  1120. for (j = 0; j < hls->nb_varstreams; j++) {
  1121. temp_vs = &(hls->var_streams[j]);
  1122. if (!temp_vs->has_video && !temp_vs->has_subtitle &&
  1123. temp_vs->agroup &&
  1124. !av_strcasecmp(temp_vs->agroup, vs->agroup)) {
  1125. if (!aud_st)
  1126. aud_st = temp_vs->streams[0];
  1127. if (temp_vs->streams[0]->codecpar->bit_rate >
  1128. aud_st->codecpar->bit_rate)
  1129. aud_st = temp_vs->streams[0];
  1130. }
  1131. }
  1132. }
  1133. bandwidth = 0;
  1134. if (vid_st)
  1135. bandwidth += vid_st->codecpar->bit_rate;
  1136. if (aud_st)
  1137. bandwidth += aud_st->codecpar->bit_rate;
  1138. bandwidth += bandwidth / 10;
  1139. ccgroup = NULL;
  1140. if (vid_st && vs->ccgroup) {
  1141. /* check if this group name is available in the cc map string */
  1142. for (j = 0; j < hls->nb_ccstreams; j++) {
  1143. ccs = &(hls->cc_streams[j]);
  1144. if (!av_strcasecmp(ccs->ccgroup, vs->ccgroup)) {
  1145. ccgroup = vs->ccgroup;
  1146. break;
  1147. }
  1148. }
  1149. if (j == hls->nb_ccstreams)
  1150. av_log(NULL, AV_LOG_WARNING, "mapping ccgroup %s not found\n",
  1151. vs->ccgroup);
  1152. }
  1153. ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, m3u8_rel_name,
  1154. aud_st ? vs->agroup : NULL, vs->codec_attr, ccgroup);
  1155. av_freep(&m3u8_rel_name);
  1156. }
  1157. fail:
  1158. if(ret >=0)
  1159. hls->master_m3u8_created = 1;
  1160. av_freep(&m3u8_rel_name);
  1161. hlsenc_io_close(s, &hls->m3u8_out, hls->master_m3u8_url);
  1162. return ret;
  1163. }
  1164. static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
  1165. {
  1166. HLSContext *hls = s->priv_data;
  1167. HLSSegment *en;
  1168. int target_duration = 0;
  1169. int ret = 0;
  1170. char temp_filename[1024];
  1171. int64_t sequence = FFMAX(hls->start_sequence, vs->sequence - vs->nb_entries);
  1172. const char *proto = avio_find_protocol_name(s->url);
  1173. int use_rename = proto && !strcmp(proto, "file");
  1174. static unsigned warned_non_file;
  1175. char *key_uri = NULL;
  1176. char *iv_string = NULL;
  1177. AVDictionary *options = NULL;
  1178. double prog_date_time = vs->initial_prog_date_time;
  1179. double *prog_date_time_p = (hls->flags & HLS_PROGRAM_DATE_TIME) ? &prog_date_time : NULL;
  1180. int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
  1181. hls->version = 3;
  1182. if (byterange_mode) {
  1183. hls->version = 4;
  1184. sequence = 0;
  1185. }
  1186. if (hls->flags & HLS_INDEPENDENT_SEGMENTS) {
  1187. hls->version = 6;
  1188. }
  1189. if (hls->segment_type == SEGMENT_TYPE_FMP4) {
  1190. hls->version = 7;
  1191. }
  1192. if (!use_rename && !warned_non_file++)
  1193. av_log(s, AV_LOG_ERROR, "Cannot use rename on non file protocol, this may lead to races and temporary partial files\n");
  1194. set_http_options(s, &options, hls);
  1195. snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", vs->m3u8_name);
  1196. if ((ret = hlsenc_io_open(s, &hls->m3u8_out, temp_filename, &options)) < 0)
  1197. goto fail;
  1198. for (en = vs->segments; en; en = en->next) {
  1199. if (target_duration <= en->duration)
  1200. target_duration = lrint(en->duration);
  1201. }
  1202. vs->discontinuity_set = 0;
  1203. ff_hls_write_playlist_header(hls->m3u8_out, hls->version, hls->allowcache,
  1204. target_duration, sequence, hls->pl_type);
  1205. if((hls->flags & HLS_DISCONT_START) && sequence==hls->start_sequence && vs->discontinuity_set==0 ){
  1206. avio_printf(hls->m3u8_out, "#EXT-X-DISCONTINUITY\n");
  1207. vs->discontinuity_set = 1;
  1208. }
  1209. if (vs->has_video && (hls->flags & HLS_INDEPENDENT_SEGMENTS)) {
  1210. avio_printf(hls->m3u8_out, "#EXT-X-INDEPENDENT-SEGMENTS\n");
  1211. }
  1212. for (en = vs->segments; en; en = en->next) {
  1213. if ((hls->encrypt || hls->key_info_file) && (!key_uri || strcmp(en->key_uri, key_uri) ||
  1214. av_strcasecmp(en->iv_string, iv_string))) {
  1215. avio_printf(hls->m3u8_out, "#EXT-X-KEY:METHOD=AES-128,URI=\"%s\"", en->key_uri);
  1216. if (*en->iv_string)
  1217. avio_printf(hls->m3u8_out, ",IV=0x%s", en->iv_string);
  1218. avio_printf(hls->m3u8_out, "\n");
  1219. key_uri = en->key_uri;
  1220. iv_string = en->iv_string;
  1221. }
  1222. if ((hls->segment_type == SEGMENT_TYPE_FMP4) && (en == vs->segments)) {
  1223. ff_hls_write_init_file(hls->m3u8_out, vs->fmp4_init_filename,
  1224. hls->flags & HLS_SINGLE_FILE, en->size, en->pos);
  1225. }
  1226. ret = ff_hls_write_file_entry(hls->m3u8_out, en->discont, byterange_mode,
  1227. en->duration, hls->flags & HLS_ROUND_DURATIONS,
  1228. en->size, en->pos, vs->baseurl,
  1229. en->filename, prog_date_time_p);
  1230. if (ret < 0) {
  1231. av_log(s, AV_LOG_WARNING, "ff_hls_write_file_entry get error\n");
  1232. }
  1233. }
  1234. if (last && (hls->flags & HLS_OMIT_ENDLIST)==0)
  1235. ff_hls_write_end_list(hls->m3u8_out);
  1236. if( vs->vtt_m3u8_name ) {
  1237. if ((ret = hlsenc_io_open(s, &hls->sub_m3u8_out, vs->vtt_m3u8_name, &options)) < 0)
  1238. goto fail;
  1239. ff_hls_write_playlist_header(hls->sub_m3u8_out, hls->version, hls->allowcache,
  1240. target_duration, sequence, PLAYLIST_TYPE_NONE);
  1241. for (en = vs->segments; en; en = en->next) {
  1242. ret = ff_hls_write_file_entry(hls->sub_m3u8_out, 0, byterange_mode,
  1243. en->duration, 0, en->size, en->pos,
  1244. vs->baseurl, en->sub_filename, NULL);
  1245. if (ret < 0) {
  1246. av_log(s, AV_LOG_WARNING, "ff_hls_write_file_entry get error\n");
  1247. }
  1248. }
  1249. if (last)
  1250. ff_hls_write_end_list(hls->sub_m3u8_out);
  1251. }
  1252. fail:
  1253. av_dict_free(&options);
  1254. hlsenc_io_close(s, &hls->m3u8_out, temp_filename);
  1255. hlsenc_io_close(s, &hls->sub_m3u8_out, vs->vtt_m3u8_name);
  1256. if (ret >= 0 && use_rename)
  1257. ff_rename(temp_filename, vs->m3u8_name, s);
  1258. if (ret >= 0 && hls->master_pl_name)
  1259. if (create_master_playlist(s, vs) < 0)
  1260. av_log(s, AV_LOG_WARNING, "Master playlist creation failed\n");
  1261. return ret;
  1262. }
  1263. static int hls_start(AVFormatContext *s, VariantStream *vs)
  1264. {
  1265. HLSContext *c = s->priv_data;
  1266. AVFormatContext *oc = vs->avf;
  1267. AVFormatContext *vtt_oc = vs->vtt_avf;
  1268. AVDictionary *options = NULL;
  1269. char *filename, iv_string[KEYSIZE*2 + 1];
  1270. int err = 0;
  1271. if (c->flags & HLS_SINGLE_FILE) {
  1272. char *new_name = av_strdup(vs->basename);
  1273. if (!new_name)
  1274. return AVERROR(ENOMEM);
  1275. ff_format_set_url(oc, new_name);
  1276. if (vs->vtt_basename) {
  1277. new_name = av_strdup(vs->vtt_basename);
  1278. if (!new_name)
  1279. return AVERROR(ENOMEM);
  1280. ff_format_set_url(vtt_oc, new_name);
  1281. }
  1282. } else if (c->max_seg_size > 0) {
  1283. char *filename = NULL;
  1284. if (replace_int_data_in_filename(&filename,
  1285. #if FF_API_HLS_WRAP
  1286. vs->basename, 'd', c->wrap ? vs->sequence % c->wrap : vs->sequence) < 1) {
  1287. #else
  1288. vs->basename, 'd', vs->sequence) < 1) {
  1289. #endif
  1290. av_free(filename);
  1291. av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s', you can try to use -use_localtime 1 with it\n", vs->basename);
  1292. return AVERROR(EINVAL);
  1293. }
  1294. ff_format_set_url(oc, filename);
  1295. } else {
  1296. if (c->use_localtime) {
  1297. time_t now0;
  1298. struct tm *tm, tmpbuf;
  1299. int bufsize = strlen(vs->basename) + 1024;
  1300. char *buf = av_mallocz(bufsize);
  1301. if (!buf)
  1302. return AVERROR(ENOMEM);
  1303. time(&now0);
  1304. tm = localtime_r(&now0, &tmpbuf);
  1305. ff_format_set_url(oc, buf);
  1306. if (!strftime(oc->url, bufsize, vs->basename, tm)) {
  1307. av_log(oc, AV_LOG_ERROR, "Could not get segment filename with use_localtime\n");
  1308. return AVERROR(EINVAL);
  1309. }
  1310. err = sls_flag_use_localtime_filename(oc, c, vs);
  1311. if (err < 0) {
  1312. return AVERROR(ENOMEM);
  1313. }
  1314. if (c->use_localtime_mkdir) {
  1315. const char *dir;
  1316. char *fn_copy = av_strdup(oc->url);
  1317. if (!fn_copy) {
  1318. return AVERROR(ENOMEM);
  1319. }
  1320. dir = av_dirname(fn_copy);
  1321. if (mkdir_p(dir) == -1 && errno != EEXIST) {
  1322. av_log(oc, AV_LOG_ERROR, "Could not create directory %s with use_localtime_mkdir\n", dir);
  1323. av_free(fn_copy);
  1324. return AVERROR(errno);
  1325. }
  1326. av_free(fn_copy);
  1327. }
  1328. } else {
  1329. char *filename = NULL;
  1330. if (replace_int_data_in_filename(&filename,
  1331. #if FF_API_HLS_WRAP
  1332. vs->basename, 'd', c->wrap ? vs->sequence % c->wrap : vs->sequence) < 1) {
  1333. #else
  1334. vs->basename, 'd', vs->sequence) < 1) {
  1335. #endif
  1336. av_free(filename);
  1337. av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s' you can try to use -use_localtime 1 with it\n", vs->basename);
  1338. return AVERROR(EINVAL);
  1339. }
  1340. ff_format_set_url(oc, filename);
  1341. }
  1342. if( vs->vtt_basename) {
  1343. char *filename = NULL;
  1344. if (replace_int_data_in_filename(&filename,
  1345. #if FF_API_HLS_WRAP
  1346. vs->vtt_basename, 'd', c->wrap ? vs->sequence % c->wrap : vs->sequence) < 1) {
  1347. #else
  1348. vs->vtt_basename, 'd', vs->sequence) < 1) {
  1349. #endif
  1350. av_free(filename);
  1351. av_log(vtt_oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", vs->vtt_basename);
  1352. return AVERROR(EINVAL);
  1353. }
  1354. ff_format_set_url(vtt_oc, filename);
  1355. }
  1356. }
  1357. vs->number++;
  1358. set_http_options(s, &options, c);
  1359. if (c->flags & HLS_TEMP_FILE) {
  1360. char *new_name = av_asprintf("%s.tmp", oc->url);
  1361. if (!new_name)
  1362. return AVERROR(ENOMEM);
  1363. ff_format_set_url(oc, new_name);
  1364. }
  1365. if (c->key_info_file || c->encrypt) {
  1366. if (c->key_info_file && c->encrypt) {
  1367. av_log(s, AV_LOG_WARNING, "Cannot use both -hls_key_info_file and -hls_enc,"
  1368. " will use -hls_key_info_file priority\n");
  1369. }
  1370. if (!c->encrypt_started || (c->flags & HLS_PERIODIC_REKEY)) {
  1371. if (c->key_info_file) {
  1372. if ((err = hls_encryption_start(s)) < 0)
  1373. goto fail;
  1374. } else {
  1375. if ((err = do_encrypt(s, vs)) < 0)
  1376. goto fail;
  1377. }
  1378. c->encrypt_started = 1;
  1379. }
  1380. if ((err = av_dict_set(&options, "encryption_key", c->key_string, 0))
  1381. < 0)
  1382. goto fail;
  1383. err = av_strlcpy(iv_string, c->iv_string, sizeof(iv_string));
  1384. if (!err)
  1385. snprintf(iv_string, sizeof(iv_string), "%032"PRIx64, vs->sequence);
  1386. if ((err = av_dict_set(&options, "encryption_iv", iv_string, 0)) < 0)
  1387. goto fail;
  1388. filename = av_asprintf("crypto:%s", oc->url);
  1389. if (!filename) {
  1390. err = AVERROR(ENOMEM);
  1391. goto fail;
  1392. }
  1393. err = hlsenc_io_open(s, &oc->pb, filename, &options);
  1394. av_free(filename);
  1395. av_dict_free(&options);
  1396. if (err < 0)
  1397. return err;
  1398. } else if (c->segment_type != SEGMENT_TYPE_FMP4) {
  1399. if ((err = hlsenc_io_open(s, &oc->pb, oc->url, &options)) < 0)
  1400. goto fail;
  1401. }
  1402. if (vs->vtt_basename) {
  1403. set_http_options(s, &options, c);
  1404. if ((err = hlsenc_io_open(s, &vtt_oc->pb, vtt_oc->url, &options)) < 0)
  1405. goto fail;
  1406. }
  1407. av_dict_free(&options);
  1408. if (c->segment_type != SEGMENT_TYPE_FMP4) {
  1409. /* We only require one PAT/PMT per segment. */
  1410. if (oc->oformat->priv_class && oc->priv_data) {
  1411. char period[21];
  1412. snprintf(period, sizeof(period), "%d", (INT_MAX / 2) - 1);
  1413. av_opt_set(oc->priv_data, "mpegts_flags", "resend_headers", 0);
  1414. av_opt_set(oc->priv_data, "sdt_period", period, 0);
  1415. av_opt_set(oc->priv_data, "pat_period", period, 0);
  1416. }
  1417. }
  1418. if (vs->vtt_basename) {
  1419. err = avformat_write_header(vtt_oc,NULL);
  1420. if (err < 0)
  1421. return err;
  1422. }
  1423. return 0;
  1424. fail:
  1425. av_dict_free(&options);
  1426. return err;
  1427. }
  1428. static const char * get_default_pattern_localtime_fmt(AVFormatContext *s)
  1429. {
  1430. char b[21];
  1431. time_t t = time(NULL);
  1432. struct tm *p, tmbuf;
  1433. HLSContext *hls = s->priv_data;
  1434. p = localtime_r(&t, &tmbuf);
  1435. // no %s support when strftime returned error or left format string unchanged
  1436. // also no %s support on MSVC, which invokes the invalid parameter handler on unsupported format strings, instead of returning an error
  1437. if (hls->segment_type == SEGMENT_TYPE_FMP4) {
  1438. return (HAVE_LIBC_MSVCRT || !strftime(b, sizeof(b), "%s", p) || !strcmp(b, "%s")) ? "-%Y%m%d%H%M%S.m4s" : "-%s.m4s";
  1439. }
  1440. return (HAVE_LIBC_MSVCRT || !strftime(b, sizeof(b), "%s", p) || !strcmp(b, "%s")) ? "-%Y%m%d%H%M%S.ts" : "-%s.ts";
  1441. }
  1442. static int append_postfix(char *name, int name_buf_len, int i)
  1443. {
  1444. char *p;
  1445. char extension[10] = {'\0'};
  1446. p = strrchr(name, '.');
  1447. if (p) {
  1448. av_strlcpy(extension, p, sizeof(extension));
  1449. *p = '\0';
  1450. }
  1451. snprintf(name + strlen(name), name_buf_len - strlen(name), POSTFIX_PATTERN, i);
  1452. if (strlen(extension))
  1453. av_strlcat(name, extension, name_buf_len);
  1454. return 0;
  1455. }
  1456. static int validate_name(int nb_vs, const char *fn)
  1457. {
  1458. const char *filename, *subdir_name;
  1459. char *fn_dup = NULL;
  1460. int ret = 0;
  1461. if (!fn) {
  1462. ret = AVERROR(EINVAL);
  1463. goto fail;
  1464. }
  1465. fn_dup = av_strdup(fn);
  1466. if (!fn_dup) {
  1467. ret = AVERROR(ENOMEM);
  1468. goto fail;
  1469. }
  1470. filename = av_basename(fn);
  1471. subdir_name = av_dirname(fn_dup);
  1472. if (nb_vs > 1 && !av_stristr(filename, "%v") && !av_stristr(subdir_name, "%v")) {
  1473. av_log(NULL, AV_LOG_ERROR, "More than 1 variant streams are present, %%v is expected in the filename %s\n",
  1474. fn);
  1475. ret = AVERROR(EINVAL);
  1476. goto fail;
  1477. }
  1478. if (av_stristr(filename, "%v") && av_stristr(subdir_name, "%v")) {
  1479. av_log(NULL, AV_LOG_ERROR, "%%v is expected either in filename or in the sub-directory name of file %s\n",
  1480. fn);
  1481. ret = AVERROR(EINVAL);
  1482. goto fail;
  1483. }
  1484. fail:
  1485. av_freep(&fn_dup);
  1486. return ret;
  1487. }
  1488. static int format_name(char *buf, int buf_len, int index)
  1489. {
  1490. const char *proto, *dir;
  1491. char *orig_buf_dup = NULL, *mod_buf = NULL, *mod_buf_dup = NULL;
  1492. int ret = 0;
  1493. if (!av_stristr(buf, "%v"))
  1494. return ret;
  1495. orig_buf_dup = av_strdup(buf);
  1496. if (!orig_buf_dup) {
  1497. ret = AVERROR(ENOMEM);
  1498. goto fail;
  1499. }
  1500. if (replace_int_data_in_filename(&mod_buf, orig_buf_dup, 'v', index) < 1) {
  1501. ret = AVERROR(EINVAL);
  1502. goto fail;
  1503. }
  1504. av_strlcpy(buf, mod_buf, buf_len);
  1505. proto = avio_find_protocol_name(orig_buf_dup);
  1506. dir = av_dirname(orig_buf_dup);
  1507. /* if %v is present in the file's directory, create sub-directory */
  1508. if (av_stristr(dir, "%v") && proto && !strcmp(proto, "file")) {
  1509. mod_buf_dup = av_strdup(buf);
  1510. if (!mod_buf_dup) {
  1511. ret = AVERROR(ENOMEM);
  1512. goto fail;
  1513. }
  1514. dir = av_dirname(mod_buf_dup);
  1515. if (mkdir_p(dir) == -1 && errno != EEXIST) {
  1516. ret = AVERROR(errno);
  1517. goto fail;
  1518. }
  1519. }
  1520. fail:
  1521. av_freep(&orig_buf_dup);
  1522. av_freep(&mod_buf_dup);
  1523. av_freep(&mod_buf);
  1524. return ret;
  1525. }
  1526. static int get_nth_codec_stream_index(AVFormatContext *s,
  1527. enum AVMediaType codec_type,
  1528. int stream_id)
  1529. {
  1530. unsigned int stream_index, cnt;
  1531. if (stream_id < 0 || stream_id > s->nb_streams - 1)
  1532. return -1;
  1533. cnt = 0;
  1534. for (stream_index = 0; stream_index < s->nb_streams; stream_index++) {
  1535. if (s->streams[stream_index]->codecpar->codec_type != codec_type)
  1536. continue;
  1537. if (cnt == stream_id)
  1538. return stream_index;
  1539. cnt++;
  1540. }
  1541. return -1;
  1542. }
  1543. static int parse_variant_stream_mapstring(AVFormatContext *s)
  1544. {
  1545. HLSContext *hls = s->priv_data;
  1546. VariantStream *vs;
  1547. int stream_index;
  1548. enum AVMediaType codec_type;
  1549. int nb_varstreams, nb_streams;
  1550. char *p, *q, *saveptr1, *saveptr2, *varstr, *keyval;
  1551. const char *val;
  1552. /**
  1553. * Expected format for var_stream_map string is as below:
  1554. * "a:0,v:0 a:1,v:1"
  1555. * "a:0,agroup:a0 a:1,agroup:a1 v:0,agroup:a0 v:1,agroup:a1"
  1556. * This string specifies how to group the audio, video and subtitle streams
  1557. * into different variant streams. The variant stream groups are separated
  1558. * by space.
  1559. *
  1560. * a:, v:, s: are keys to specify audio, video and subtitle streams
  1561. * respectively. Allowed values are 0 to 9 digits (limited just based on
  1562. * practical usage)
  1563. *
  1564. * agroup: is key to specify audio group. A string can be given as value.
  1565. */
  1566. p = av_strdup(hls->var_stream_map);
  1567. q = p;
  1568. while(av_strtok(q, " \t", &saveptr1)) {
  1569. q = NULL;
  1570. hls->nb_varstreams++;
  1571. }
  1572. av_freep(&p);
  1573. hls->var_streams = av_mallocz(sizeof(*hls->var_streams) * hls->nb_varstreams);
  1574. if (!hls->var_streams)
  1575. return AVERROR(ENOMEM);
  1576. p = hls->var_stream_map;
  1577. nb_varstreams = 0;
  1578. while (varstr = av_strtok(p, " \t", &saveptr1)) {
  1579. p = NULL;
  1580. if (nb_varstreams < hls->nb_varstreams)
  1581. vs = &(hls->var_streams[nb_varstreams++]);
  1582. else
  1583. return AVERROR(EINVAL);
  1584. q = varstr;
  1585. while (q < varstr + strlen(varstr)) {
  1586. if (!av_strncasecmp(q, "a:", 2) || !av_strncasecmp(q, "v:", 2) ||
  1587. !av_strncasecmp(q, "s:", 2))
  1588. vs->nb_streams++;
  1589. q++;
  1590. }
  1591. vs->streams = av_mallocz(sizeof(AVStream *) * vs->nb_streams);
  1592. if (!vs->streams)
  1593. return AVERROR(ENOMEM);
  1594. nb_streams = 0;
  1595. while (keyval = av_strtok(varstr, ",", &saveptr2)) {
  1596. varstr = NULL;
  1597. if (av_strstart(keyval, "agroup:", &val)) {
  1598. vs->agroup = av_strdup(val);
  1599. if (!vs->agroup)
  1600. return AVERROR(ENOMEM);
  1601. continue;
  1602. } else if (av_strstart(keyval, "ccgroup:", &val)) {
  1603. vs->ccgroup = av_strdup(val);
  1604. if (!vs->ccgroup)
  1605. return AVERROR(ENOMEM);
  1606. continue;
  1607. } else if (av_strstart(keyval, "v:", &val)) {
  1608. codec_type = AVMEDIA_TYPE_VIDEO;
  1609. } else if (av_strstart(keyval, "a:", &val)) {
  1610. codec_type = AVMEDIA_TYPE_AUDIO;
  1611. } else if (av_strstart(keyval, "s:", &val)) {
  1612. codec_type = AVMEDIA_TYPE_SUBTITLE;
  1613. } else {
  1614. av_log(s, AV_LOG_ERROR, "Invalid keyval %s\n", keyval);
  1615. return AVERROR(EINVAL);
  1616. }
  1617. stream_index = -1;
  1618. if (av_isdigit(*val))
  1619. stream_index = get_nth_codec_stream_index (s, codec_type,
  1620. atoi(val));
  1621. if (stream_index >= 0 && nb_streams < vs->nb_streams) {
  1622. vs->streams[nb_streams++] = s->streams[stream_index];
  1623. } else {
  1624. av_log(s, AV_LOG_ERROR, "Unable to map stream at %s\n", keyval);
  1625. return AVERROR(EINVAL);
  1626. }
  1627. }
  1628. }
  1629. av_log(s, AV_LOG_DEBUG, "Number of variant streams %d\n",
  1630. hls->nb_varstreams);
  1631. return 0;
  1632. }
  1633. static int parse_cc_stream_mapstring(AVFormatContext *s)
  1634. {
  1635. HLSContext *hls = s->priv_data;
  1636. int nb_ccstreams;
  1637. char *p, *q, *saveptr1, *saveptr2, *ccstr, *keyval;
  1638. const char *val;
  1639. ClosedCaptionsStream *ccs;
  1640. p = av_strdup(hls->cc_stream_map);
  1641. q = p;
  1642. while(av_strtok(q, " \t", &saveptr1)) {
  1643. q = NULL;
  1644. hls->nb_ccstreams++;
  1645. }
  1646. av_freep(&p);
  1647. hls->cc_streams = av_mallocz(sizeof(*hls->cc_streams) * hls->nb_ccstreams);
  1648. if (!hls->cc_streams)
  1649. return AVERROR(ENOMEM);
  1650. p = hls->cc_stream_map;
  1651. nb_ccstreams = 0;
  1652. while (ccstr = av_strtok(p, " \t", &saveptr1)) {
  1653. p = NULL;
  1654. if (nb_ccstreams < hls->nb_ccstreams)
  1655. ccs = &(hls->cc_streams[nb_ccstreams++]);
  1656. else
  1657. return AVERROR(EINVAL);
  1658. while (keyval = av_strtok(ccstr, ",", &saveptr2)) {
  1659. ccstr = NULL;
  1660. if (av_strstart(keyval, "ccgroup:", &val)) {
  1661. ccs->ccgroup = av_strdup(val);
  1662. if (!ccs->ccgroup)
  1663. return AVERROR(ENOMEM);
  1664. } else if (av_strstart(keyval, "instreamid:", &val)) {
  1665. ccs->instreamid = av_strdup(val);
  1666. if (!ccs->instreamid)
  1667. return AVERROR(ENOMEM);
  1668. } else if (av_strstart(keyval, "language:", &val)) {
  1669. ccs->language = av_strdup(val);
  1670. if (!ccs->language)
  1671. return AVERROR(ENOMEM);
  1672. } else {
  1673. av_log(s, AV_LOG_ERROR, "Invalid keyval %s\n", keyval);
  1674. return AVERROR(EINVAL);
  1675. }
  1676. }
  1677. if (!ccs->ccgroup || !ccs->instreamid) {
  1678. av_log(s, AV_LOG_ERROR, "Insufficient parameters in cc stream map string\n");
  1679. return AVERROR(EINVAL);
  1680. }
  1681. if (av_strstart(ccs->instreamid, "CC", &val)) {
  1682. if(atoi(val) < 1 || atoi(val) > 4) {
  1683. av_log(s, AV_LOG_ERROR, "Invalid instream ID CC index %d in %s, range 1-4\n",
  1684. atoi(val), ccs->instreamid);
  1685. return AVERROR(EINVAL);
  1686. }
  1687. } else if (av_strstart(ccs->instreamid, "SERVICE", &val)) {
  1688. if(atoi(val) < 1 || atoi(val) > 63) {
  1689. av_log(s, AV_LOG_ERROR, "Invalid instream ID SERVICE index %d in %s, range 1-63 \n",
  1690. atoi(val), ccs->instreamid);
  1691. return AVERROR(EINVAL);
  1692. }
  1693. } else {
  1694. av_log(s, AV_LOG_ERROR, "Invalid instream ID %s, supported are CCn or SERIVICEn\n",
  1695. ccs->instreamid);
  1696. return AVERROR(EINVAL);
  1697. }
  1698. }
  1699. return 0;
  1700. }
  1701. static int update_variant_stream_info(AVFormatContext *s) {
  1702. HLSContext *hls = s->priv_data;
  1703. unsigned int i;
  1704. int ret = 0;
  1705. if (hls->cc_stream_map) {
  1706. ret = parse_cc_stream_mapstring(s);
  1707. if (ret < 0)
  1708. return ret;
  1709. }
  1710. if (hls->var_stream_map) {
  1711. return parse_variant_stream_mapstring(s);
  1712. } else {
  1713. //By default, a single variant stream with all the codec streams is created
  1714. hls->nb_varstreams = 1;
  1715. hls->var_streams = av_mallocz(sizeof(*hls->var_streams) *
  1716. hls->nb_varstreams);
  1717. if (!hls->var_streams)
  1718. return AVERROR(ENOMEM);
  1719. hls->var_streams[0].nb_streams = s->nb_streams;
  1720. hls->var_streams[0].streams = av_mallocz(sizeof(AVStream *) *
  1721. hls->var_streams[0].nb_streams);
  1722. if (!hls->var_streams[0].streams)
  1723. return AVERROR(ENOMEM);
  1724. //by default, the first available ccgroup is mapped to the variant stream
  1725. if (hls->nb_ccstreams) {
  1726. hls->var_streams[0].ccgroup = av_strdup(hls->cc_streams[0].ccgroup);
  1727. if (!hls->var_streams[0].ccgroup)
  1728. return AVERROR(ENOMEM);
  1729. }
  1730. for (i = 0; i < s->nb_streams; i++)
  1731. hls->var_streams[0].streams[i] = s->streams[i];
  1732. }
  1733. return 0;
  1734. }
  1735. static int update_master_pl_info(AVFormatContext *s) {
  1736. HLSContext *hls = s->priv_data;
  1737. const char *dir;
  1738. char *fn1= NULL, *fn2 = NULL;
  1739. int ret = 0;
  1740. fn1 = av_strdup(s->url);
  1741. if (!fn1) {
  1742. ret = AVERROR(ENOMEM);
  1743. goto fail;
  1744. }
  1745. dir = av_dirname(fn1);
  1746. /**
  1747. * if output file's directory has %v, variants are created in sub-directories
  1748. * then master is created at the sub-directories level
  1749. */
  1750. if (dir && av_stristr(av_basename(dir), "%v")) {
  1751. fn2 = av_strdup(dir);
  1752. if (!fn2) {
  1753. ret = AVERROR(ENOMEM);
  1754. goto fail;
  1755. }
  1756. dir = av_dirname(fn2);
  1757. }
  1758. if (dir && strcmp(dir, "."))
  1759. hls->master_m3u8_url = av_append_path_component(dir, hls->master_pl_name);
  1760. else
  1761. hls->master_m3u8_url = av_strdup(hls->master_pl_name);
  1762. if (!hls->master_m3u8_url) {
  1763. ret = AVERROR(ENOMEM);
  1764. goto fail;
  1765. }
  1766. fail:
  1767. av_freep(&fn1);
  1768. av_freep(&fn2);
  1769. return ret;
  1770. }
  1771. static int hls_write_header(AVFormatContext *s)
  1772. {
  1773. HLSContext *hls = s->priv_data;
  1774. int ret, i, j;
  1775. AVDictionary *options = NULL;
  1776. VariantStream *vs = NULL;
  1777. for (i = 0; i < hls->nb_varstreams; i++) {
  1778. vs = &hls->var_streams[i];
  1779. av_dict_copy(&options, hls->format_options, 0);
  1780. ret = avformat_write_header(vs->avf, &options);
  1781. if (av_dict_count(options)) {
  1782. av_log(s, AV_LOG_ERROR, "Some of provided format options in '%s' are not recognized\n", hls->format_options_str);
  1783. ret = AVERROR(EINVAL);
  1784. av_dict_free(&options);
  1785. goto fail;
  1786. }
  1787. av_dict_free(&options);
  1788. //av_assert0(s->nb_streams == hls->avf->nb_streams);
  1789. for (j = 0; j < vs->nb_streams; j++) {
  1790. AVStream *inner_st;
  1791. AVStream *outer_st = vs->streams[j];
  1792. if (hls->max_seg_size > 0) {
  1793. if ((outer_st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) &&
  1794. (outer_st->codecpar->bit_rate > hls->max_seg_size)) {
  1795. av_log(s, AV_LOG_WARNING, "Your video bitrate is bigger than hls_segment_size, "
  1796. "(%"PRId64 " > %"PRId64 "), the result maybe not be what you want.",
  1797. outer_st->codecpar->bit_rate, hls->max_seg_size);
  1798. }
  1799. }
  1800. if (outer_st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE)
  1801. inner_st = vs->avf->streams[j];
  1802. else if (vs->vtt_avf)
  1803. inner_st = vs->vtt_avf->streams[0];
  1804. else {
  1805. /* We have a subtitle stream, when the user does not want one */
  1806. inner_st = NULL;
  1807. continue;
  1808. }
  1809. avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, inner_st->time_base.num, inner_st->time_base.den);
  1810. write_codec_attr(outer_st, vs);
  1811. }
  1812. /* Update the Codec Attr string for the mapped audio groups */
  1813. if (vs->has_video && vs->agroup) {
  1814. for (j = 0; j < hls->nb_varstreams; j++) {
  1815. VariantStream *vs_agroup = &(hls->var_streams[j]);
  1816. if (!vs_agroup->has_video && !vs_agroup->has_subtitle &&
  1817. vs_agroup->agroup &&
  1818. !av_strcasecmp(vs_agroup->agroup, vs->agroup)) {
  1819. write_codec_attr(vs_agroup->streams[0], vs);
  1820. }
  1821. }
  1822. }
  1823. }
  1824. fail:
  1825. return ret;
  1826. }
  1827. static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
  1828. {
  1829. HLSContext *hls = s->priv_data;
  1830. AVFormatContext *oc = NULL;
  1831. AVStream *st = s->streams[pkt->stream_index];
  1832. int64_t end_pts = 0;
  1833. int is_ref_pkt = 1;
  1834. int ret = 0, can_split = 1, i, j;
  1835. int stream_index = 0;
  1836. int range_length = 0;
  1837. uint8_t *buffer = NULL;
  1838. VariantStream *vs = NULL;
  1839. for (i = 0; i < hls->nb_varstreams; i++) {
  1840. vs = &hls->var_streams[i];
  1841. for (j = 0; j < vs->nb_streams; j++) {
  1842. if (vs->streams[j] == st) {
  1843. if( st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE ) {
  1844. oc = vs->vtt_avf;
  1845. stream_index = 0;
  1846. } else {
  1847. oc = vs->avf;
  1848. stream_index = j;
  1849. }
  1850. break;
  1851. }
  1852. }
  1853. if (oc)
  1854. break;
  1855. }
  1856. if (!oc) {
  1857. av_log(s, AV_LOG_ERROR, "Unable to find mapping variant stream\n");
  1858. return AVERROR(ENOMEM);
  1859. }
  1860. end_pts = hls->recording_time * vs->number;
  1861. if (vs->sequence - vs->nb_entries > hls->start_sequence && hls->init_time > 0) {
  1862. /* reset end_pts, hls->recording_time at end of the init hls list */
  1863. int init_list_dur = hls->init_time * vs->nb_entries * AV_TIME_BASE;
  1864. int after_init_list_dur = (vs->sequence - vs->nb_entries ) * hls->time * AV_TIME_BASE;
  1865. hls->recording_time = hls->time * AV_TIME_BASE;
  1866. end_pts = init_list_dur + after_init_list_dur ;
  1867. }
  1868. if (vs->start_pts == AV_NOPTS_VALUE) {
  1869. vs->start_pts = pkt->pts;
  1870. }
  1871. if (vs->has_video) {
  1872. can_split = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
  1873. ((pkt->flags & AV_PKT_FLAG_KEY) || (hls->flags & HLS_SPLIT_BY_TIME));
  1874. is_ref_pkt = (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && (pkt->stream_index == vs->reference_stream_index);
  1875. }
  1876. if (pkt->pts == AV_NOPTS_VALUE)
  1877. is_ref_pkt = can_split = 0;
  1878. if (is_ref_pkt) {
  1879. if (vs->end_pts == AV_NOPTS_VALUE)
  1880. vs->end_pts = pkt->pts;
  1881. if (vs->new_start) {
  1882. vs->new_start = 0;
  1883. vs->duration = (double)(pkt->pts - vs->end_pts)
  1884. * st->time_base.num / st->time_base.den;
  1885. vs->dpp = (double)(pkt->duration) * st->time_base.num / st->time_base.den;
  1886. } else {
  1887. if (pkt->duration) {
  1888. vs->duration += (double)(pkt->duration) * st->time_base.num / st->time_base.den;
  1889. } else {
  1890. av_log(s, AV_LOG_WARNING, "pkt->duration = 0, maybe the hls segment duration will not precise\n");
  1891. vs->duration = (double)(pkt->pts - vs->end_pts) * st->time_base.num / st->time_base.den;
  1892. }
  1893. }
  1894. }
  1895. if (vs->packets_written && can_split && av_compare_ts(pkt->pts - vs->start_pts, st->time_base,
  1896. end_pts, AV_TIME_BASE_Q) >= 0) {
  1897. int64_t new_start_pos;
  1898. char *old_filename = NULL;
  1899. int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
  1900. av_write_frame(vs->avf, NULL); /* Flush any buffered data */
  1901. new_start_pos = avio_tell(vs->avf->pb);
  1902. vs->size = new_start_pos - vs->start_pos;
  1903. if (!byterange_mode) {
  1904. if (hls->segment_type == SEGMENT_TYPE_FMP4) {
  1905. if (!vs->init_range_length) {
  1906. avio_flush(oc->pb);
  1907. range_length = avio_close_dyn_buf(oc->pb, &buffer);
  1908. avio_write(vs->out, buffer, range_length);
  1909. vs->init_range_length = range_length;
  1910. avio_open_dyn_buf(&oc->pb);
  1911. vs->packets_written = 0;
  1912. ff_format_io_close(s, &vs->out);
  1913. hlsenc_io_close(s, &vs->out, vs->base_output_dirname);
  1914. }
  1915. } else {
  1916. hlsenc_io_close(s, &oc->pb, oc->url);
  1917. }
  1918. if (vs->vtt_avf) {
  1919. hlsenc_io_close(s, &vs->vtt_avf->pb, vs->vtt_avf->url);
  1920. }
  1921. }
  1922. if ((hls->flags & HLS_TEMP_FILE) && oc->url[0]) {
  1923. if (!(hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size <= 0))
  1924. if ((vs->avf->oformat->priv_class && vs->avf->priv_data) && hls->segment_type != SEGMENT_TYPE_FMP4)
  1925. av_opt_set(vs->avf->priv_data, "mpegts_flags", "resend_headers", 0);
  1926. hls_rename_temp_file(s, oc);
  1927. }
  1928. if (vs->fmp4_init_mode) {
  1929. vs->number--;
  1930. }
  1931. if (hls->segment_type == SEGMENT_TYPE_FMP4) {
  1932. ret = hlsenc_io_open(s, &vs->out, vs->avf->url, NULL);
  1933. if (ret < 0) {
  1934. av_log(NULL, AV_LOG_ERROR, "Failed to open file '%s'\n",
  1935. vs->avf->url);
  1936. return ret;
  1937. }
  1938. write_styp(vs->out);
  1939. ret = flush_dynbuf(vs, &range_length);
  1940. if (ret < 0) {
  1941. return ret;
  1942. }
  1943. ff_format_io_close(s, &vs->out);
  1944. }
  1945. old_filename = av_strdup(vs->avf->url);
  1946. if (!old_filename) {
  1947. return AVERROR(ENOMEM);
  1948. }
  1949. ret = hls_append_segment(s, hls, vs, vs->duration, vs->start_pos, vs->size);
  1950. vs->start_pos = new_start_pos;
  1951. if (ret < 0) {
  1952. av_free(old_filename);
  1953. return ret;
  1954. }
  1955. vs->end_pts = pkt->pts;
  1956. vs->duration = 0;
  1957. vs->fmp4_init_mode = 0;
  1958. if (hls->flags & HLS_SINGLE_FILE) {
  1959. vs->number++;
  1960. } else if (hls->max_seg_size > 0) {
  1961. if (vs->start_pos >= hls->max_seg_size) {
  1962. vs->sequence++;
  1963. sls_flag_file_rename(hls, vs, old_filename);
  1964. ret = hls_start(s, vs);
  1965. vs->start_pos = 0;
  1966. /* When split segment by byte, the duration is short than hls_time,
  1967. * so it is not enough one segment duration as hls_time, */
  1968. vs->number--;
  1969. }
  1970. vs->number++;
  1971. } else {
  1972. sls_flag_file_rename(hls, vs, old_filename);
  1973. ret = hls_start(s, vs);
  1974. }
  1975. av_free(old_filename);
  1976. if (ret < 0) {
  1977. return ret;
  1978. }
  1979. if (!vs->fmp4_init_mode || byterange_mode)
  1980. if ((ret = hls_window(s, 0, vs)) < 0) {
  1981. return ret;
  1982. }
  1983. }
  1984. vs->packets_written++;
  1985. ret = ff_write_chained(oc, stream_index, pkt, s, 0);
  1986. return ret;
  1987. }
  1988. static int hls_write_trailer(struct AVFormatContext *s)
  1989. {
  1990. HLSContext *hls = s->priv_data;
  1991. AVFormatContext *oc = NULL;
  1992. AVFormatContext *vtt_oc = NULL;
  1993. char *old_filename = NULL;
  1994. int i;
  1995. int ret = 0;
  1996. VariantStream *vs = NULL;
  1997. for (i = 0; i < hls->nb_varstreams; i++) {
  1998. vs = &hls->var_streams[i];
  1999. oc = vs->avf;
  2000. vtt_oc = vs->vtt_avf;
  2001. old_filename = av_strdup(vs->avf->url);
  2002. if (!old_filename) {
  2003. return AVERROR(ENOMEM);
  2004. }
  2005. if ( hls->segment_type == SEGMENT_TYPE_FMP4) {
  2006. int range_length = 0;
  2007. ret = hlsenc_io_open(s, &vs->out, vs->avf->url, NULL);
  2008. if (ret < 0) {
  2009. av_log(NULL, AV_LOG_ERROR, "Failed to open file '%s'\n", vs->avf->url);
  2010. goto failed;
  2011. }
  2012. write_styp(vs->out);
  2013. ret = flush_dynbuf(vs, &range_length);
  2014. if (ret < 0) {
  2015. goto failed;
  2016. }
  2017. ff_format_io_close(s, &vs->out);
  2018. }
  2019. failed:
  2020. av_write_trailer(oc);
  2021. if (oc->pb) {
  2022. vs->size = avio_tell(vs->avf->pb) - vs->start_pos;
  2023. if (hls->segment_type != SEGMENT_TYPE_FMP4)
  2024. ff_format_io_close(s, &oc->pb);
  2025. if ((hls->flags & HLS_TEMP_FILE) && oc->url[0]) {
  2026. hls_rename_temp_file(s, oc);
  2027. av_free(old_filename);
  2028. old_filename = av_strdup(vs->avf->url);
  2029. if (!old_filename) {
  2030. return AVERROR(ENOMEM);
  2031. }
  2032. }
  2033. /* after av_write_trailer, then duration + 1 duration per packet */
  2034. hls_append_segment(s, hls, vs, vs->duration + vs->dpp, vs->start_pos, vs->size);
  2035. }
  2036. sls_flag_file_rename(hls, vs, old_filename);
  2037. if (vtt_oc) {
  2038. if (vtt_oc->pb)
  2039. av_write_trailer(vtt_oc);
  2040. vs->size = avio_tell(vs->vtt_avf->pb) - vs->start_pos;
  2041. ff_format_io_close(s, &vtt_oc->pb);
  2042. }
  2043. av_freep(&vs->basename);
  2044. av_freep(&vs->base_output_dirname);
  2045. avformat_free_context(oc);
  2046. vs->avf = NULL;
  2047. hls_window(s, 1, vs);
  2048. av_freep(&vs->fmp4_init_filename);
  2049. if (vtt_oc) {
  2050. av_freep(&vs->vtt_basename);
  2051. av_freep(&vs->vtt_m3u8_name);
  2052. avformat_free_context(vtt_oc);
  2053. }
  2054. hls_free_segments(vs->segments);
  2055. hls_free_segments(vs->old_segments);
  2056. av_free(old_filename);
  2057. av_freep(&vs->m3u8_name);
  2058. av_freep(&vs->streams);
  2059. av_freep(&vs->agroup);
  2060. av_freep(&vs->ccgroup);
  2061. av_freep(&vs->baseurl);
  2062. }
  2063. for (i = 0; i < hls->nb_ccstreams; i++) {
  2064. ClosedCaptionsStream *ccs = &hls->cc_streams[i];
  2065. av_freep(&ccs->ccgroup);
  2066. av_freep(&ccs->instreamid);
  2067. av_freep(&ccs->language);
  2068. }
  2069. ff_format_io_close(s, &hls->m3u8_out);
  2070. ff_format_io_close(s, &hls->sub_m3u8_out);
  2071. av_freep(&hls->key_basename);
  2072. av_freep(&hls->var_streams);
  2073. av_freep(&hls->cc_streams);
  2074. av_freep(&hls->master_m3u8_url);
  2075. return 0;
  2076. }
  2077. static int hls_init(AVFormatContext *s)
  2078. {
  2079. int ret = 0;
  2080. int i = 0;
  2081. int j = 0;
  2082. HLSContext *hls = s->priv_data;
  2083. const char *pattern = "%d.ts";
  2084. VariantStream *vs = NULL;
  2085. int basename_size = 0;
  2086. const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt(s);
  2087. const char *vtt_pattern = "%d.vtt";
  2088. char *p = NULL;
  2089. int vtt_basename_size = 0;
  2090. int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1;
  2091. ret = update_variant_stream_info(s);
  2092. if (ret < 0) {
  2093. av_log(s, AV_LOG_ERROR, "Variant stream info update failed with status %x\n",
  2094. ret);
  2095. goto fail;
  2096. }
  2097. //TODO: Updates needed to encryption functionality with periodic re-key when more than one variant streams are present
  2098. if (hls->nb_varstreams > 1 && hls->flags & HLS_PERIODIC_REKEY) {
  2099. ret = AVERROR(EINVAL);
  2100. av_log(s, AV_LOG_ERROR, "Periodic re-key not supported when more than one variant streams are present\n");
  2101. goto fail;
  2102. }
  2103. ret = validate_name(hls->nb_varstreams, s->url);
  2104. if (ret < 0)
  2105. goto fail;
  2106. if (hls->segment_filename) {
  2107. ret = validate_name(hls->nb_varstreams, hls->segment_filename);
  2108. if (ret < 0)
  2109. goto fail;
  2110. }
  2111. if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) {
  2112. ret = validate_name(hls->nb_varstreams, hls->fmp4_init_filename);
  2113. if (ret < 0)
  2114. goto fail;
  2115. }
  2116. if (hls->subtitle_filename) {
  2117. ret = validate_name(hls->nb_varstreams, hls->subtitle_filename);
  2118. if (ret < 0)
  2119. goto fail;
  2120. }
  2121. if (hls->master_pl_name) {
  2122. ret = update_master_pl_info(s);
  2123. if (ret < 0) {
  2124. av_log(s, AV_LOG_ERROR, "Master stream info update failed with status %x\n",
  2125. ret);
  2126. goto fail;
  2127. }
  2128. }
  2129. if (hls->segment_type == SEGMENT_TYPE_FMP4) {
  2130. pattern = "%d.m4s";
  2131. }
  2132. if ((hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) ||
  2133. (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME)) {
  2134. time_t t = time(NULL); // we will need it in either case
  2135. if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH) {
  2136. hls->start_sequence = (int64_t)t;
  2137. } else if (hls->start_sequence_source_type == HLS_START_SEQUENCE_AS_FORMATTED_DATETIME) {
  2138. char b[15];
  2139. struct tm *p, tmbuf;
  2140. if (!(p = localtime_r(&t, &tmbuf)))
  2141. return AVERROR(ENOMEM);
  2142. if (!strftime(b, sizeof(b), "%Y%m%d%H%M%S", p))
  2143. return AVERROR(ENOMEM);
  2144. hls->start_sequence = strtoll(b, NULL, 10);
  2145. }
  2146. av_log(hls, AV_LOG_DEBUG, "start_number evaluated to %"PRId64"\n", hls->start_sequence);
  2147. }
  2148. hls->recording_time = (hls->init_time ? hls->init_time : hls->time) * AV_TIME_BASE;
  2149. for (i = 0; i < hls->nb_varstreams; i++) {
  2150. vs = &hls->var_streams[i];
  2151. vs->m3u8_name = av_strdup(s->url);
  2152. if (!vs->m3u8_name ) {
  2153. ret = AVERROR(ENOMEM);
  2154. goto fail;
  2155. }
  2156. ret = format_name(vs->m3u8_name, strlen(s->url) + 1, i);
  2157. if (ret < 0)
  2158. goto fail;
  2159. vs->sequence = hls->start_sequence;
  2160. vs->start_pts = AV_NOPTS_VALUE;
  2161. vs->end_pts = AV_NOPTS_VALUE;
  2162. vs->current_segment_final_filename_fmt[0] = '\0';
  2163. if (hls->flags & HLS_SPLIT_BY_TIME && hls->flags & HLS_INDEPENDENT_SEGMENTS) {
  2164. // Independent segments cannot be guaranteed when splitting by time
  2165. hls->flags &= ~HLS_INDEPENDENT_SEGMENTS;
  2166. av_log(s, AV_LOG_WARNING,
  2167. "'split_by_time' and 'independent_segments' cannot be enabled together. "
  2168. "Disabling 'independent_segments' flag\n");
  2169. }
  2170. if (hls->flags & HLS_PROGRAM_DATE_TIME) {
  2171. time_t now0;
  2172. time(&now0);
  2173. vs->initial_prog_date_time = now0;
  2174. }
  2175. if (hls->format_options_str) {
  2176. ret = av_dict_parse_string(&hls->format_options, hls->format_options_str, "=", ":", 0);
  2177. if (ret < 0) {
  2178. av_log(s, AV_LOG_ERROR, "Could not parse format options list '%s'\n", hls->format_options_str);
  2179. goto fail;
  2180. }
  2181. }
  2182. for (j = 0; j < vs->nb_streams; j++) {
  2183. vs->has_video += vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO;
  2184. /* Get one video stream to reference for split segments
  2185. * so use the first video stream index. */
  2186. if ((vs->has_video == 1) && (vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)) {
  2187. vs->reference_stream_index = j;
  2188. }
  2189. vs->has_subtitle += vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE;
  2190. }
  2191. if (vs->has_video > 1)
  2192. av_log(s, AV_LOG_WARNING, "More than a single video stream present, expect issues decoding it.\n");
  2193. if (hls->segment_type == SEGMENT_TYPE_FMP4) {
  2194. vs->oformat = av_guess_format("mp4", NULL, NULL);
  2195. } else {
  2196. vs->oformat = av_guess_format("mpegts", NULL, NULL);
  2197. }
  2198. if (!vs->oformat) {
  2199. ret = AVERROR_MUXER_NOT_FOUND;
  2200. goto fail;
  2201. }
  2202. if (vs->has_subtitle) {
  2203. vs->vtt_oformat = av_guess_format("webvtt", NULL, NULL);
  2204. if (!vs->oformat) {
  2205. ret = AVERROR_MUXER_NOT_FOUND;
  2206. goto fail;
  2207. }
  2208. }
  2209. if (hls->segment_filename) {
  2210. basename_size = strlen(hls->segment_filename) + 1;
  2211. vs->basename = av_malloc(basename_size);
  2212. if (!vs->basename) {
  2213. ret = AVERROR(ENOMEM);
  2214. goto fail;
  2215. }
  2216. av_strlcpy(vs->basename, hls->segment_filename, basename_size);
  2217. ret = format_name(vs->basename, basename_size, i);
  2218. if (ret < 0)
  2219. goto fail;
  2220. } else {
  2221. if (hls->flags & HLS_SINGLE_FILE) {
  2222. if (hls->segment_type == SEGMENT_TYPE_FMP4) {
  2223. pattern = ".m4s";
  2224. } else {
  2225. pattern = ".ts";
  2226. }
  2227. }
  2228. if (hls->use_localtime) {
  2229. basename_size = strlen(vs->m3u8_name) + strlen(pattern_localtime_fmt) + 1;
  2230. } else {
  2231. basename_size = strlen(vs->m3u8_name) + strlen(pattern) + 1;
  2232. }
  2233. vs->basename = av_malloc(basename_size);
  2234. if (!vs->basename) {
  2235. ret = AVERROR(ENOMEM);
  2236. goto fail;
  2237. }
  2238. av_strlcpy(vs->basename, vs->m3u8_name, basename_size);
  2239. p = strrchr(vs->basename, '.');
  2240. if (p)
  2241. *p = '\0';
  2242. if (hls->use_localtime) {
  2243. av_strlcat(vs->basename, pattern_localtime_fmt, basename_size);
  2244. } else {
  2245. av_strlcat(vs->basename, pattern, basename_size);
  2246. }
  2247. }
  2248. if (hls->segment_type == SEGMENT_TYPE_FMP4) {
  2249. if (hls->nb_varstreams > 1)
  2250. fmp4_init_filename_len += strlen(POSTFIX_PATTERN);
  2251. vs->fmp4_init_filename = av_malloc(fmp4_init_filename_len);
  2252. if (!vs->fmp4_init_filename ) {
  2253. ret = AVERROR(ENOMEM);
  2254. goto fail;
  2255. }
  2256. av_strlcpy(vs->fmp4_init_filename, hls->fmp4_init_filename,
  2257. fmp4_init_filename_len);
  2258. if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) {
  2259. ret = format_name(vs->fmp4_init_filename, fmp4_init_filename_len, i);
  2260. if (ret < 0)
  2261. goto fail;
  2262. fmp4_init_filename_len = strlen(vs->fmp4_init_filename) + 1;
  2263. vs->base_output_dirname = av_malloc(fmp4_init_filename_len);
  2264. if (!vs->base_output_dirname) {
  2265. ret = AVERROR(ENOMEM);
  2266. goto fail;
  2267. }
  2268. av_strlcpy(vs->base_output_dirname, vs->fmp4_init_filename,
  2269. fmp4_init_filename_len);
  2270. } else {
  2271. if (hls->nb_varstreams > 1) {
  2272. ret = append_postfix(vs->fmp4_init_filename, fmp4_init_filename_len, i);
  2273. if (ret < 0)
  2274. goto fail;
  2275. }
  2276. fmp4_init_filename_len = strlen(vs->m3u8_name) +
  2277. strlen(vs->fmp4_init_filename) + 1;
  2278. vs->base_output_dirname = av_malloc(fmp4_init_filename_len);
  2279. if (!vs->base_output_dirname) {
  2280. ret = AVERROR(ENOMEM);
  2281. goto fail;
  2282. }
  2283. av_strlcpy(vs->base_output_dirname, vs->m3u8_name,
  2284. fmp4_init_filename_len);
  2285. p = strrchr(vs->base_output_dirname, '/');
  2286. if (p) {
  2287. *(p + 1) = '\0';
  2288. av_strlcat(vs->base_output_dirname, vs->fmp4_init_filename,
  2289. fmp4_init_filename_len);
  2290. } else {
  2291. av_strlcpy(vs->base_output_dirname, vs->fmp4_init_filename,
  2292. fmp4_init_filename_len);
  2293. }
  2294. }
  2295. }
  2296. if (!hls->use_localtime) {
  2297. ret = sls_flag_check_duration_size_index(hls);
  2298. if (ret < 0) {
  2299. goto fail;
  2300. }
  2301. } else {
  2302. ret = sls_flag_check_duration_size(hls, vs);
  2303. if (ret < 0) {
  2304. goto fail;
  2305. }
  2306. }
  2307. if (vs->has_subtitle) {
  2308. if (hls->flags & HLS_SINGLE_FILE)
  2309. vtt_pattern = ".vtt";
  2310. vtt_basename_size = strlen(vs->m3u8_name) + strlen(vtt_pattern) + 1;
  2311. vs->vtt_basename = av_malloc(vtt_basename_size);
  2312. if (!vs->vtt_basename) {
  2313. ret = AVERROR(ENOMEM);
  2314. goto fail;
  2315. }
  2316. vs->vtt_m3u8_name = av_malloc(vtt_basename_size);
  2317. if (!vs->vtt_m3u8_name ) {
  2318. ret = AVERROR(ENOMEM);
  2319. goto fail;
  2320. }
  2321. av_strlcpy(vs->vtt_basename, vs->m3u8_name, vtt_basename_size);
  2322. p = strrchr(vs->vtt_basename, '.');
  2323. if (p)
  2324. *p = '\0';
  2325. if ( hls->subtitle_filename ) {
  2326. strcpy(vs->vtt_m3u8_name, hls->subtitle_filename);
  2327. ret = format_name(vs->vtt_m3u8_name, vtt_basename_size, i);
  2328. if (ret < 0)
  2329. goto fail;
  2330. } else {
  2331. strcpy(vs->vtt_m3u8_name, vs->vtt_basename);
  2332. av_strlcat(vs->vtt_m3u8_name, "_vtt.m3u8", vtt_basename_size);
  2333. }
  2334. av_strlcat(vs->vtt_basename, vtt_pattern, vtt_basename_size);
  2335. }
  2336. if (hls->baseurl) {
  2337. vs->baseurl = av_strdup(hls->baseurl);
  2338. if (!vs->baseurl) {
  2339. ret = AVERROR(ENOMEM);
  2340. goto fail;
  2341. }
  2342. }
  2343. if ((hls->flags & HLS_SINGLE_FILE) && (hls->segment_type == SEGMENT_TYPE_FMP4)) {
  2344. vs->fmp4_init_filename = av_strdup(vs->basename);
  2345. if (!vs->fmp4_init_filename) {
  2346. ret = AVERROR(ENOMEM);
  2347. goto fail;
  2348. }
  2349. }
  2350. if ((ret = hls_mux_init(s, vs)) < 0)
  2351. goto fail;
  2352. if (hls->flags & HLS_APPEND_LIST) {
  2353. parse_playlist(s, vs->m3u8_name, vs);
  2354. vs->discontinuity = 1;
  2355. if (hls->init_time > 0) {
  2356. av_log(s, AV_LOG_WARNING, "append_list mode does not support hls_init_time,"
  2357. " hls_init_time value will have no effect\n");
  2358. hls->init_time = 0;
  2359. hls->recording_time = hls->time * AV_TIME_BASE;
  2360. }
  2361. }
  2362. if ((ret = hls_start(s, vs)) < 0)
  2363. goto fail;
  2364. }
  2365. fail:
  2366. if (ret < 0) {
  2367. av_freep(&hls->key_basename);
  2368. for (i = 0; i < hls->nb_varstreams && hls->var_streams; i++) {
  2369. vs = &hls->var_streams[i];
  2370. av_freep(&vs->basename);
  2371. av_freep(&vs->vtt_basename);
  2372. av_freep(&vs->fmp4_init_filename);
  2373. av_freep(&vs->m3u8_name);
  2374. av_freep(&vs->vtt_m3u8_name);
  2375. av_freep(&vs->streams);
  2376. av_freep(&vs->agroup);
  2377. av_freep(&vs->ccgroup);
  2378. av_freep(&vs->baseurl);
  2379. if (vs->avf)
  2380. avformat_free_context(vs->avf);
  2381. if (vs->vtt_avf)
  2382. avformat_free_context(vs->vtt_avf);
  2383. }
  2384. for (i = 0; i < hls->nb_ccstreams; i++) {
  2385. ClosedCaptionsStream *ccs = &hls->cc_streams[i];
  2386. av_freep(&ccs->ccgroup);
  2387. av_freep(&ccs->instreamid);
  2388. av_freep(&ccs->language);
  2389. }
  2390. av_freep(&hls->var_streams);
  2391. av_freep(&hls->cc_streams);
  2392. av_freep(&hls->master_m3u8_url);
  2393. }
  2394. return ret;
  2395. }
  2396. #define OFFSET(x) offsetof(HLSContext, x)
  2397. #define E AV_OPT_FLAG_ENCODING_PARAM
  2398. static const AVOption options[] = {
  2399. {"start_number", "set first number in the sequence", OFFSET(start_sequence),AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, E},
  2400. {"hls_time", "set segment length in seconds", OFFSET(time), AV_OPT_TYPE_FLOAT, {.dbl = 2}, 0, FLT_MAX, E},
  2401. {"hls_init_time", "set segment length in seconds at init list", OFFSET(init_time), AV_OPT_TYPE_FLOAT, {.dbl = 0}, 0, FLT_MAX, E},
  2402. {"hls_list_size", "set maximum number of playlist entries", OFFSET(max_nb_segments), AV_OPT_TYPE_INT, {.i64 = 5}, 0, INT_MAX, E},
  2403. {"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},
  2404. {"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},
  2405. #if FF_API_HLS_WRAP
  2406. {"hls_wrap", "set number after which the index wraps (will be deprecated)", OFFSET(wrap), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E},
  2407. #endif
  2408. {"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},
  2409. {"hls_base_url", "url to prepend to each playlist entry", OFFSET(baseurl), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
  2410. {"hls_segment_filename", "filename template for segment files", OFFSET(segment_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
  2411. {"hls_segment_size", "maximum size per segment file, (in bytes)", OFFSET(max_seg_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E},
  2412. {"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},
  2413. {"hls_enc", "enable AES128 encryption support", OFFSET(encrypt), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E},
  2414. {"hls_enc_key", "hex-coded 16 byte key to encrypt the segments", OFFSET(key), AV_OPT_TYPE_STRING, .flags = E},
  2415. {"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},
  2416. {"hls_enc_iv", "hex-coded 16 byte initialization vector", OFFSET(iv), AV_OPT_TYPE_STRING, .flags = E},
  2417. {"hls_subtitle_path", "set path of hls subtitles", OFFSET(subtitle_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
  2418. {"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"},
  2419. {"mpegts", "make segment file to mpegts files in m3u8", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_MPEGTS }, 0, UINT_MAX, E, "segment_type"},
  2420. {"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"},
  2421. {"hls_fmp4_init_filename", "set fragment mp4 file init filename", OFFSET(fmp4_init_filename), AV_OPT_TYPE_STRING, {.str = "init.mp4"}, 0, 0, E},
  2422. {"hls_flags", "set flags affecting HLS playlist and media file generation", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, 0, UINT_MAX, E, "flags"},
  2423. {"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"},
  2424. {"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"},
  2425. {"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"},
  2426. {"round_durations", "round durations in m3u8 to whole numbers", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_ROUND_DURATIONS }, 0, UINT_MAX, E, "flags"},
  2427. {"discont_start", "start the playlist with a discontinuity tag", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_DISCONT_START }, 0, UINT_MAX, E, "flags"},
  2428. {"omit_endlist", "Do not append an endlist when ending stream", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_OMIT_ENDLIST }, 0, UINT_MAX, E, "flags"},
  2429. {"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"},
  2430. {"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"},
  2431. {"program_date_time", "add EXT-X-PROGRAM-DATE-TIME", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PROGRAM_DATE_TIME }, 0, UINT_MAX, E, "flags"},
  2432. {"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"},
  2433. {"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"},
  2434. {"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"},
  2435. {"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX, E, "flags"},
  2436. {"independent_segments", "add EXT-X-INDEPENDENT-SEGMENTS, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_INDEPENDENT_SEGMENTS }, 0, UINT_MAX, E, "flags"},
  2437. {"use_localtime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
  2438. {"use_localtime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
  2439. {"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" },
  2440. {"event", "EVENT playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_EVENT }, INT_MIN, INT_MAX, E, "pl_type" },
  2441. {"vod", "VOD playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_VOD }, INT_MIN, INT_MAX, E, "pl_type" },
  2442. {"method", "set the HTTP method(default: PUT)", OFFSET(method), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
  2443. {"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" },
  2444. {"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" },
  2445. {"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" },
  2446. {"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" },
  2447. {"http_user_agent", "override User-Agent field in HTTP header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
  2448. {"var_stream_map", "Variant stream map string", OFFSET(var_stream_map), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
  2449. {"cc_stream_map", "Closed captions stream map string", OFFSET(cc_stream_map), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
  2450. {"master_pl_name", "Create HLS master playlist with this name", OFFSET(master_pl_name), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
  2451. {"master_pl_publish_rate", "Publish master play list every after this many segment intervals", OFFSET(master_publish_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, UINT_MAX, E},
  2452. {"http_persistent", "Use persistent HTTP connections", OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
  2453. { NULL },
  2454. };
  2455. static const AVClass hls_class = {
  2456. .class_name = "hls muxer",
  2457. .item_name = av_default_item_name,
  2458. .option = options,
  2459. .version = LIBAVUTIL_VERSION_INT,
  2460. };
  2461. AVOutputFormat ff_hls_muxer = {
  2462. .name = "hls",
  2463. .long_name = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
  2464. .extensions = "m3u8",
  2465. .priv_data_size = sizeof(HLSContext),
  2466. .audio_codec = AV_CODEC_ID_AAC,
  2467. .video_codec = AV_CODEC_ID_H264,
  2468. .subtitle_codec = AV_CODEC_ID_WEBVTT,
  2469. .flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
  2470. .init = hls_init,
  2471. .write_header = hls_write_header,
  2472. .write_packet = hls_write_packet,
  2473. .write_trailer = hls_write_trailer,
  2474. .priv_class = &hls_class,
  2475. };