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.

563 lines
17KB

  1. /*
  2. * Apple HTTP Live Streaming demuxer
  3. * Copyright (c) 2010 Martin Storsjo
  4. *
  5. * This file is part of Libav.
  6. *
  7. * Libav is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * Libav is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with Libav; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. /**
  22. * @file
  23. * Apple HTTP Live Streaming demuxer
  24. * http://tools.ietf.org/html/draft-pantos-http-live-streaming
  25. */
  26. #define _XOPEN_SOURCE 600
  27. #include "libavutil/avstring.h"
  28. #include "avformat.h"
  29. #include "internal.h"
  30. #include <unistd.h>
  31. #include "avio_internal.h"
  32. #define INITIAL_BUFFER_SIZE 32768
  33. /*
  34. * An apple http stream consists of a playlist with media segment files,
  35. * played sequentially. There may be several playlists with the same
  36. * video content, in different bandwidth variants, that are played in
  37. * parallel (preferrably only one bandwidth variant at a time). In this case,
  38. * the user supplied the url to a main playlist that only lists the variant
  39. * playlists.
  40. *
  41. * If the main playlist doesn't point at any variants, we still create
  42. * one anonymous toplevel variant for this, to maintain the structure.
  43. */
  44. struct segment {
  45. int duration;
  46. char url[MAX_URL_SIZE];
  47. };
  48. /*
  49. * Each variant has its own demuxer. If it currently is active,
  50. * it has an open AVIOContext too, and potentially an AVPacket
  51. * containing the next packet from this stream.
  52. */
  53. struct variant {
  54. int bandwidth;
  55. char url[MAX_URL_SIZE];
  56. AVIOContext pb;
  57. uint8_t* read_buffer;
  58. URLContext *input;
  59. AVFormatContext *parent;
  60. int index;
  61. AVFormatContext *ctx;
  62. AVPacket pkt;
  63. int stream_offset;
  64. int finished;
  65. int target_duration;
  66. int start_seq_no;
  67. int n_segments;
  68. struct segment **segments;
  69. int needed, cur_needed;
  70. int cur_seq_no;
  71. int64_t last_load_time;
  72. };
  73. typedef struct AppleHTTPContext {
  74. int n_variants;
  75. struct variant **variants;
  76. int cur_seq_no;
  77. int end_of_segment;
  78. int first_packet;
  79. } AppleHTTPContext;
  80. static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
  81. {
  82. int len = ff_get_line(s, buf, maxlen);
  83. while (len > 0 && isspace(buf[len - 1]))
  84. buf[--len] = '\0';
  85. return len;
  86. }
  87. static void free_segment_list(struct variant *var)
  88. {
  89. int i;
  90. for (i = 0; i < var->n_segments; i++)
  91. av_free(var->segments[i]);
  92. av_freep(&var->segments);
  93. var->n_segments = 0;
  94. }
  95. static void free_variant_list(AppleHTTPContext *c)
  96. {
  97. int i;
  98. for (i = 0; i < c->n_variants; i++) {
  99. struct variant *var = c->variants[i];
  100. free_segment_list(var);
  101. av_free_packet(&var->pkt);
  102. av_free(var->pb.buffer);
  103. if (var->input)
  104. url_close(var->input);
  105. if (var->ctx) {
  106. var->ctx->pb = NULL;
  107. av_close_input_file(var->ctx);
  108. }
  109. av_free(var);
  110. }
  111. av_freep(&c->variants);
  112. c->n_variants = 0;
  113. }
  114. /*
  115. * Used to reset a statically allocated AVPacket to a clean slate,
  116. * containing no data.
  117. */
  118. static void reset_packet(AVPacket *pkt)
  119. {
  120. av_init_packet(pkt);
  121. pkt->data = NULL;
  122. }
  123. static struct variant *new_variant(AppleHTTPContext *c, int bandwidth,
  124. const char *url, const char *base)
  125. {
  126. struct variant *var = av_mallocz(sizeof(struct variant));
  127. if (!var)
  128. return NULL;
  129. reset_packet(&var->pkt);
  130. var->bandwidth = bandwidth;
  131. ff_make_absolute_url(var->url, sizeof(var->url), base, url);
  132. dynarray_add(&c->variants, &c->n_variants, var);
  133. return var;
  134. }
  135. struct variant_info {
  136. char bandwidth[20];
  137. };
  138. static void handle_variant_args(struct variant_info *info, const char *key,
  139. int key_len, char **dest, int *dest_len)
  140. {
  141. if (!strncmp(key, "BANDWIDTH=", key_len)) {
  142. *dest = info->bandwidth;
  143. *dest_len = sizeof(info->bandwidth);
  144. }
  145. }
  146. static int parse_playlist(AppleHTTPContext *c, const char *url,
  147. struct variant *var, AVIOContext *in)
  148. {
  149. int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
  150. char line[1024];
  151. const char *ptr;
  152. int close_in = 0;
  153. if (!in) {
  154. close_in = 1;
  155. if ((ret = avio_open(&in, url, URL_RDONLY)) < 0)
  156. return ret;
  157. }
  158. read_chomp_line(in, line, sizeof(line));
  159. if (strcmp(line, "#EXTM3U")) {
  160. ret = AVERROR_INVALIDDATA;
  161. goto fail;
  162. }
  163. if (var) {
  164. free_segment_list(var);
  165. var->finished = 0;
  166. }
  167. while (!in->eof_reached) {
  168. read_chomp_line(in, line, sizeof(line));
  169. if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
  170. struct variant_info info = {{0}};
  171. is_variant = 1;
  172. ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,
  173. &info);
  174. bandwidth = atoi(info.bandwidth);
  175. } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
  176. if (!var) {
  177. var = new_variant(c, 0, url, NULL);
  178. if (!var) {
  179. ret = AVERROR(ENOMEM);
  180. goto fail;
  181. }
  182. }
  183. var->target_duration = atoi(ptr);
  184. } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
  185. if (!var) {
  186. var = new_variant(c, 0, url, NULL);
  187. if (!var) {
  188. ret = AVERROR(ENOMEM);
  189. goto fail;
  190. }
  191. }
  192. var->start_seq_no = atoi(ptr);
  193. } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
  194. if (var)
  195. var->finished = 1;
  196. } else if (av_strstart(line, "#EXTINF:", &ptr)) {
  197. is_segment = 1;
  198. duration = atoi(ptr);
  199. } else if (av_strstart(line, "#", NULL)) {
  200. continue;
  201. } else if (line[0]) {
  202. if (is_variant) {
  203. if (!new_variant(c, bandwidth, line, url)) {
  204. ret = AVERROR(ENOMEM);
  205. goto fail;
  206. }
  207. is_variant = 0;
  208. bandwidth = 0;
  209. }
  210. if (is_segment) {
  211. struct segment *seg;
  212. if (!var) {
  213. var = new_variant(c, 0, url, NULL);
  214. if (!var) {
  215. ret = AVERROR(ENOMEM);
  216. goto fail;
  217. }
  218. }
  219. seg = av_malloc(sizeof(struct segment));
  220. if (!seg) {
  221. ret = AVERROR(ENOMEM);
  222. goto fail;
  223. }
  224. seg->duration = duration;
  225. ff_make_absolute_url(seg->url, sizeof(seg->url), url, line);
  226. dynarray_add(&var->segments, &var->n_segments, seg);
  227. is_segment = 0;
  228. }
  229. }
  230. }
  231. if (var)
  232. var->last_load_time = av_gettime();
  233. fail:
  234. if (close_in)
  235. avio_close(in);
  236. return ret;
  237. }
  238. static int read_data(void *opaque, uint8_t *buf, int buf_size)
  239. {
  240. struct variant *v = opaque;
  241. AppleHTTPContext *c = v->parent->priv_data;
  242. int ret, i;
  243. restart:
  244. if (!v->input) {
  245. reload:
  246. /* If this is a live stream and target_duration has elapsed since
  247. * the last playlist reload, reload the variant playlists now. */
  248. if (!v->finished &&
  249. av_gettime() - v->last_load_time >= v->target_duration*1000000 &&
  250. (ret = parse_playlist(c, v->url, v, NULL)) < 0)
  251. return ret;
  252. if (v->cur_seq_no < v->start_seq_no) {
  253. av_log(NULL, AV_LOG_WARNING,
  254. "skipping %d segments ahead, expired from playlists\n",
  255. v->start_seq_no - v->cur_seq_no);
  256. v->cur_seq_no = v->start_seq_no;
  257. }
  258. if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
  259. if (v->finished)
  260. return AVERROR_EOF;
  261. while (av_gettime() - v->last_load_time <
  262. v->target_duration*1000000) {
  263. if (url_interrupt_cb())
  264. return AVERROR_EXIT;
  265. usleep(100*1000);
  266. }
  267. /* Enough time has elapsed since the last reload */
  268. goto reload;
  269. }
  270. ret = url_open(&v->input,
  271. v->segments[v->cur_seq_no - v->start_seq_no]->url,
  272. URL_RDONLY);
  273. if (ret < 0)
  274. return ret;
  275. }
  276. ret = url_read(v->input, buf, buf_size);
  277. if (ret > 0)
  278. return ret;
  279. if (ret < 0 && ret != AVERROR_EOF)
  280. return ret;
  281. url_close(v->input);
  282. v->input = NULL;
  283. v->cur_seq_no++;
  284. c->end_of_segment = 1;
  285. c->cur_seq_no = v->cur_seq_no;
  286. v->needed = 0;
  287. for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams; i++) {
  288. if (v->parent->streams[i]->discard < AVDISCARD_ALL)
  289. v->needed = 1;
  290. }
  291. if (!v->needed) {
  292. av_log(v->parent, AV_LOG_INFO, "No longer receiving variant %d\n",
  293. v->index);
  294. return AVERROR_EOF;
  295. }
  296. goto restart;
  297. }
  298. static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
  299. {
  300. AppleHTTPContext *c = s->priv_data;
  301. int ret = 0, i, j, stream_offset = 0;
  302. if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
  303. goto fail;
  304. if (c->n_variants == 0) {
  305. av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
  306. ret = AVERROR_EOF;
  307. goto fail;
  308. }
  309. /* If the playlist only contained variants, parse each individual
  310. * variant playlist. */
  311. if (c->n_variants > 1 || c->variants[0]->n_segments == 0) {
  312. for (i = 0; i < c->n_variants; i++) {
  313. struct variant *v = c->variants[i];
  314. if ((ret = parse_playlist(c, v->url, v, NULL)) < 0)
  315. goto fail;
  316. }
  317. }
  318. if (c->variants[0]->n_segments == 0) {
  319. av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
  320. ret = AVERROR_EOF;
  321. goto fail;
  322. }
  323. /* If this isn't a live stream, calculate the total duration of the
  324. * stream. */
  325. if (c->variants[0]->finished) {
  326. int64_t duration = 0;
  327. for (i = 0; i < c->variants[0]->n_segments; i++)
  328. duration += c->variants[0]->segments[i]->duration;
  329. s->duration = duration * AV_TIME_BASE;
  330. }
  331. /* Open the demuxer for each variant */
  332. for (i = 0; i < c->n_variants; i++) {
  333. struct variant *v = c->variants[i];
  334. AVInputFormat *in_fmt = NULL;
  335. if (v->n_segments == 0)
  336. continue;
  337. v->index = i;
  338. v->needed = 1;
  339. v->parent = s;
  340. /* If this is a live stream with more than 3 segments, start at the
  341. * third last segment. */
  342. v->cur_seq_no = v->start_seq_no;
  343. if (!v->finished && v->n_segments > 3)
  344. v->cur_seq_no = v->start_seq_no + v->n_segments - 3;
  345. v->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
  346. ffio_init_context(&v->pb, v->read_buffer, INITIAL_BUFFER_SIZE, 0, v,
  347. read_data, NULL, NULL);
  348. v->pb.seekable = 0;
  349. ret = av_probe_input_buffer(&v->pb, &in_fmt, v->segments[0]->url,
  350. NULL, 0, 0);
  351. if (ret < 0)
  352. goto fail;
  353. ret = av_open_input_stream(&v->ctx, &v->pb, v->segments[0]->url,
  354. in_fmt, NULL);
  355. if (ret < 0)
  356. goto fail;
  357. v->stream_offset = stream_offset;
  358. /* Create new AVStreams for each stream in this variant */
  359. for (j = 0; j < v->ctx->nb_streams; j++) {
  360. AVStream *st = av_new_stream(s, i);
  361. if (!st) {
  362. ret = AVERROR(ENOMEM);
  363. goto fail;
  364. }
  365. avcodec_copy_context(st->codec, v->ctx->streams[j]->codec);
  366. }
  367. stream_offset += v->ctx->nb_streams;
  368. }
  369. c->first_packet = 1;
  370. return 0;
  371. fail:
  372. free_variant_list(c);
  373. return ret;
  374. }
  375. static int recheck_discard_flags(AVFormatContext *s, int first)
  376. {
  377. AppleHTTPContext *c = s->priv_data;
  378. int i, changed = 0;
  379. /* Check if any new streams are needed */
  380. for (i = 0; i < c->n_variants; i++)
  381. c->variants[i]->cur_needed = 0;;
  382. for (i = 0; i < s->nb_streams; i++) {
  383. AVStream *st = s->streams[i];
  384. struct variant *var = c->variants[s->streams[i]->id];
  385. if (st->discard < AVDISCARD_ALL)
  386. var->cur_needed = 1;
  387. }
  388. for (i = 0; i < c->n_variants; i++) {
  389. struct variant *v = c->variants[i];
  390. if (v->cur_needed && !v->needed) {
  391. v->needed = 1;
  392. changed = 1;
  393. v->cur_seq_no = c->cur_seq_no;
  394. v->pb.eof_reached = 0;
  395. av_log(s, AV_LOG_INFO, "Now receiving variant %d\n", i);
  396. } else if (first && !v->cur_needed && v->needed) {
  397. if (v->input)
  398. url_close(v->input);
  399. v->input = NULL;
  400. v->needed = 0;
  401. changed = 1;
  402. av_log(s, AV_LOG_INFO, "No longer receiving variant %d\n", i);
  403. }
  404. }
  405. return changed;
  406. }
  407. static int applehttp_read_packet(AVFormatContext *s, AVPacket *pkt)
  408. {
  409. AppleHTTPContext *c = s->priv_data;
  410. int ret, i, minvariant = -1;
  411. if (c->first_packet) {
  412. recheck_discard_flags(s, 1);
  413. c->first_packet = 0;
  414. }
  415. start:
  416. c->end_of_segment = 0;
  417. for (i = 0; i < c->n_variants; i++) {
  418. struct variant *var = c->variants[i];
  419. /* Make sure we've got one buffered packet from each open variant
  420. * stream */
  421. if (var->needed && !var->pkt.data) {
  422. ret = av_read_frame(var->ctx, &var->pkt);
  423. if (ret < 0) {
  424. if (!var->pb.eof_reached)
  425. return ret;
  426. reset_packet(&var->pkt);
  427. }
  428. }
  429. /* Check if this stream has the packet with the lowest dts */
  430. if (var->pkt.data) {
  431. if (minvariant < 0 ||
  432. var->pkt.dts < c->variants[minvariant]->pkt.dts)
  433. minvariant = i;
  434. }
  435. }
  436. if (c->end_of_segment) {
  437. if (recheck_discard_flags(s, 0))
  438. goto start;
  439. }
  440. /* If we got a packet, return it */
  441. if (minvariant >= 0) {
  442. *pkt = c->variants[minvariant]->pkt;
  443. pkt->stream_index += c->variants[minvariant]->stream_offset;
  444. reset_packet(&c->variants[minvariant]->pkt);
  445. return 0;
  446. }
  447. return AVERROR_EOF;
  448. }
  449. static int applehttp_close(AVFormatContext *s)
  450. {
  451. AppleHTTPContext *c = s->priv_data;
  452. free_variant_list(c);
  453. return 0;
  454. }
  455. static int applehttp_read_seek(AVFormatContext *s, int stream_index,
  456. int64_t timestamp, int flags)
  457. {
  458. AppleHTTPContext *c = s->priv_data;
  459. int i, j, ret;
  460. if ((flags & AVSEEK_FLAG_BYTE) || !c->variants[0]->finished)
  461. return AVERROR(ENOSYS);
  462. timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ?
  463. s->streams[stream_index]->time_base.den :
  464. AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
  465. AV_ROUND_DOWN : AV_ROUND_UP);
  466. ret = AVERROR(EIO);
  467. for (i = 0; i < c->n_variants; i++) {
  468. /* Reset reading */
  469. struct variant *var = c->variants[i];
  470. int64_t pos = 0;
  471. if (var->input) {
  472. url_close(var->input);
  473. var->input = NULL;
  474. }
  475. av_free_packet(&var->pkt);
  476. reset_packet(&var->pkt);
  477. var->pb.eof_reached = 0;
  478. /* Locate the segment that contains the target timestamp */
  479. for (j = 0; j < var->n_segments; j++) {
  480. if (timestamp >= pos &&
  481. timestamp < pos + var->segments[j]->duration) {
  482. var->cur_seq_no = var->start_seq_no + j;
  483. ret = 0;
  484. break;
  485. }
  486. pos += var->segments[j]->duration;
  487. }
  488. }
  489. return ret;
  490. }
  491. static int applehttp_probe(AVProbeData *p)
  492. {
  493. /* Require #EXTM3U at the start, and either one of the ones below
  494. * somewhere for a proper match. */
  495. if (strncmp(p->buf, "#EXTM3U", 7))
  496. return 0;
  497. if (strstr(p->buf, "#EXT-X-STREAM-INF:") ||
  498. strstr(p->buf, "#EXT-X-TARGETDURATION:") ||
  499. strstr(p->buf, "#EXT-X-MEDIA-SEQUENCE:"))
  500. return AVPROBE_SCORE_MAX;
  501. return 0;
  502. }
  503. AVInputFormat ff_applehttp_demuxer = {
  504. "applehttp",
  505. NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming format"),
  506. sizeof(AppleHTTPContext),
  507. applehttp_probe,
  508. applehttp_read_header,
  509. applehttp_read_packet,
  510. applehttp_close,
  511. applehttp_read_seek,
  512. };