annotate applehttp.c @ 6455:3f50c7effad1 libavformat

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