| 2142 | } |
| 2143 | |
| 2144 | static int hls_read_header(AVFormatContext *s) |
| 2145 | { |
| 2146 | HLSContext *c = s->priv_data; |
| 2147 | int ret = 0, i; |
| 2148 | int64_t highest_cur_seq_no = 0; |
| 2149 | |
| 2150 | c->ctx = s; |
| 2151 | c->interrupt_callback = &s->interrupt_callback; |
| 2152 | |
| 2153 | c->first_packet = 1; |
| 2154 | c->first_timestamp = AV_NOPTS_VALUE; |
| 2155 | c->cur_timestamp = AV_NOPTS_VALUE; |
| 2156 | |
| 2157 | if ((ret = ffio_copy_url_options(s->pb, &c->avio_opts)) < 0) |
| 2158 | return ret; |
| 2159 | |
| 2160 | /* XXX: Some HLS servers don't like being sent the range header, |
| 2161 | in this case, we need to set http_seekable = 0 to disable |
| 2162 | the range header */ |
| 2163 | av_dict_set_int(&c->avio_opts, "seekable", c->http_seekable, 0); |
| 2164 | |
| 2165 | if ((ret = parse_playlist(c, s->url, NULL, s->pb)) < 0) |
| 2166 | return ret; |
| 2167 | |
| 2168 | if (c->n_variants == 0) { |
| 2169 | av_log(s, AV_LOG_WARNING, "Empty playlist\n"); |
| 2170 | return AVERROR_EOF; |
| 2171 | } |
| 2172 | /* If the playlist only contained playlists (Master Playlist), |
| 2173 | * parse each individual playlist. */ |
| 2174 | if (c->n_playlists > 1 || c->playlists[0]->n_segments == 0) { |
| 2175 | for (i = 0; i < c->n_playlists; i++) { |
| 2176 | struct playlist *pls = c->playlists[i]; |
| 2177 | pls->m3u8_hold_counters = 0; |
| 2178 | if ((ret = parse_playlist(c, pls->url, pls, NULL)) < 0) { |
| 2179 | av_log(s, AV_LOG_WARNING, "parse_playlist error %s [%s]\n", av_err2str(ret), pls->url); |
| 2180 | pls->broken = 1; |
| 2181 | if (c->n_playlists > 1) |
| 2182 | continue; |
| 2183 | return ret; |
| 2184 | } |
| 2185 | } |
| 2186 | } |
| 2187 | |
| 2188 | for (i = 0; i < c->n_variants; i++) { |
| 2189 | if (c->variants[i]->playlists[0]->n_segments == 0) { |
| 2190 | av_log(s, AV_LOG_WARNING, "Empty segment [%s]\n", c->variants[i]->playlists[0]->url); |
| 2191 | c->variants[i]->playlists[0]->broken = 1; |
| 2192 | } |
| 2193 | } |
| 2194 | |
| 2195 | /* If this isn't a live stream, calculate the total duration of the |
| 2196 | * stream. */ |
| 2197 | if (c->variants[0]->playlists[0]->finished) { |
| 2198 | int64_t duration = 0; |
| 2199 | for (i = 0; i < c->variants[0]->playlists[0]->n_segments; i++) |
| 2200 | duration += c->variants[0]->playlists[0]->segments[i]->duration; |
| 2201 | s->duration = duration; |
nothing calls this directly
no test coverage detected