/src/mpv/demux/demux_lavf.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at> |
3 | | * |
4 | | * This file is part of mpv. |
5 | | * |
6 | | * mpv is free software; you can redistribute it and/or |
7 | | * modify it under the terms of the GNU Lesser General Public |
8 | | * License as published by the Free Software Foundation; either |
9 | | * version 2.1 of the License, or (at your option) any later version. |
10 | | * |
11 | | * mpv is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public |
17 | | * License along with mpv. If not, see <http://www.gnu.org/licenses/>. |
18 | | */ |
19 | | |
20 | | #include <stdlib.h> |
21 | | #include <limits.h> |
22 | | #include <stdbool.h> |
23 | | #include <string.h> |
24 | | #include <errno.h> |
25 | | #include <assert.h> |
26 | | |
27 | | #include "config.h" |
28 | | |
29 | | #include <libavformat/avformat.h> |
30 | | #include <libavformat/avio.h> |
31 | | |
32 | | #include <libavutil/avutil.h> |
33 | | #include <libavutil/avstring.h> |
34 | | #include <libavutil/display.h> |
35 | | #include <libavutil/dovi_meta.h> |
36 | | #include <libavutil/mathematics.h> |
37 | | #include <libavutil/opt.h> |
38 | | #include <libavutil/pixdesc.h> |
39 | | #include <libavutil/replaygain.h> |
40 | | |
41 | | #include "audio/chmap_avchannel.h" |
42 | | |
43 | | #include "common/common.h" |
44 | | #include "common/msg.h" |
45 | | #include "common/tags.h" |
46 | | #include "common/av_common.h" |
47 | | #include "misc/bstr.h" |
48 | | #include "misc/charset_conv.h" |
49 | | #include "misc/thread_tools.h" |
50 | | |
51 | | #include "stream/stream.h" |
52 | | #include "demux.h" |
53 | | #include "stheader.h" |
54 | | #include "options/m_config.h" |
55 | | #include "options/m_option.h" |
56 | | #include "options/path.h" |
57 | | |
58 | 238k | #define INITIAL_PROBE_SIZE STREAM_BUFFER_SIZE |
59 | 387k | #define PROBE_BUF_SIZE (10 * 1024 * 1024) |
60 | | |
61 | | |
62 | | // Should correspond to IO_BUFFER_SIZE in libavformat/aviobuf.c (not public) |
63 | | // libavformat (almost) always reads data in blocks of this size. |
64 | | #define BIO_BUFFER_SIZE 32768 |
65 | | |
66 | | #define OPT_BASE_STRUCT struct demux_lavf_opts |
67 | | struct demux_lavf_opts { |
68 | | int probesize; |
69 | | int probeinfo; |
70 | | int probescore; |
71 | | float analyzeduration; |
72 | | int buffersize; |
73 | | bool allow_mimetype; |
74 | | char *format; |
75 | | char **avopts; |
76 | | bool hacks; |
77 | | char *sub_cp; |
78 | | int rtsp_transport; |
79 | | int linearize_ts; |
80 | | bool propagate_opts; |
81 | | }; |
82 | | |
83 | | const struct m_sub_options demux_lavf_conf = { |
84 | | .opts = (const m_option_t[]) { |
85 | | {"demuxer-lavf-probesize", OPT_INT(probesize), M_RANGE(32, INT_MAX)}, |
86 | | {"demuxer-lavf-probe-info", OPT_CHOICE(probeinfo, |
87 | | {"no", 0}, {"yes", 1}, {"auto", -1}, {"nostreams", -2})}, |
88 | | {"demuxer-lavf-format", OPT_STRING(format)}, |
89 | | {"demuxer-lavf-analyzeduration", OPT_FLOAT(analyzeduration), |
90 | | M_RANGE(0, 3600)}, |
91 | | {"demuxer-lavf-buffersize", OPT_INT(buffersize), |
92 | | M_RANGE(1, 10 * 1024 * 1024), OPTDEF_INT(BIO_BUFFER_SIZE)}, |
93 | | {"demuxer-lavf-allow-mimetype", OPT_BOOL(allow_mimetype)}, |
94 | | {"demuxer-lavf-probescore", OPT_INT(probescore), |
95 | | M_RANGE(1, AVPROBE_SCORE_MAX)}, |
96 | | {"demuxer-lavf-hacks", OPT_BOOL(hacks)}, |
97 | | #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
98 | | {"demuxer-lavf-o", OPT_KEYVALUELIST(avopts)}, |
99 | | #endif |
100 | | {"sub-codepage", OPT_STRING(sub_cp)}, |
101 | | {"rtsp-transport", OPT_CHOICE(rtsp_transport, |
102 | | {"lavf", 0}, |
103 | | {"udp", 1}, |
104 | | {"tcp", 2}, |
105 | | {"http", 3}, |
106 | | {"udp_multicast", 4})}, |
107 | | {"demuxer-lavf-linearize-timestamps", OPT_CHOICE(linearize_ts, |
108 | | {"no", 0}, {"auto", -1}, {"yes", 1})}, |
109 | | {"demuxer-lavf-propagate-opts", OPT_BOOL(propagate_opts)}, |
110 | | {0} |
111 | | }, |
112 | | .size = sizeof(struct demux_lavf_opts), |
113 | | .defaults = &(const struct demux_lavf_opts){ |
114 | | .probeinfo = -1, |
115 | | .allow_mimetype = true, |
116 | | .hacks = true, |
117 | | // AVPROBE_SCORE_MAX/4 + 1 is the "recommended" limit. Below that, the |
118 | | // user is supposed to retry with larger probe sizes until a higher |
119 | | // value is reached. |
120 | | .probescore = AVPROBE_SCORE_MAX/4 + 1, |
121 | | .sub_cp = "auto", |
122 | | .rtsp_transport = 2, |
123 | | .linearize_ts = -1, |
124 | | .propagate_opts = true, |
125 | | }, |
126 | | .change_flags = UPDATE_DEMUXER, |
127 | | }; |
128 | | |
129 | | struct format_hack { |
130 | | const char *ff_name; |
131 | | const char *mime_type; |
132 | | int probescore; |
133 | | float analyzeduration; |
134 | | bool skipinfo : 1; // skip avformat_find_stream_info() |
135 | | unsigned int if_flags; // additional AVInputFormat.flags flags |
136 | | bool max_probe : 1; // use probescore only if max. probe size reached |
137 | | bool ignore : 1; // blacklisted |
138 | | bool no_stream : 1; // do not wrap struct stream as AVIOContext |
139 | | bool use_stream_ids : 1; // has a meaningful native stream IDs (export it) |
140 | | bool fully_read : 1; // set demuxer.fully_read flag |
141 | | bool detect_charset : 1; // format is a small text file, possibly not UTF8 |
142 | | // Do not confuse player's position estimation (position is into external |
143 | | // segment, with e.g. HLS, player knows about the playlist main file only). |
144 | | bool clear_filepos : 1; |
145 | | bool linearize_audio_ts : 1;// compensate timestamp resets (audio only) |
146 | | bool is_network : 1; |
147 | | bool no_seek : 1; |
148 | | bool no_pcm_seek : 1; |
149 | | bool no_seek_on_no_duration : 1; |
150 | | bool readall_on_no_streamseek : 1; |
151 | | bool first_frame_only : 1; |
152 | | bool no_ext_picky : 1; // set "extension_picky" to false |
153 | | }; |
154 | | |
155 | | #define BLACKLIST(fmt) {fmt, .ignore = true} |
156 | | #define TEXTSUB(fmt) {fmt, .fully_read = true, .detect_charset = true} |
157 | | #define TEXTSUB_UTF8(fmt) {fmt, .fully_read = true} |
158 | | |
159 | | static const struct format_hack format_hacks[] = { |
160 | | // for webradios |
161 | | {"aac", "audio/aacp", 25, 0.5}, |
162 | | {"aac", "audio/aac", 25, 0.5}, |
163 | | |
164 | | // some mp3 files don't detect correctly (usually id3v2 too large) |
165 | | {"mp3", "audio/mpeg", 24, 0.5}, |
166 | | {"mp3", NULL, 24, .max_probe = true}, |
167 | | |
168 | | {"hls", .no_stream = true, .clear_filepos = true, .no_ext_picky = true}, |
169 | | {"dash", .no_stream = true, .clear_filepos = true}, |
170 | | {"sdp", .clear_filepos = true, .is_network = true, .no_seek = true}, |
171 | | {"mpeg", .use_stream_ids = true}, |
172 | | {"mpegts", .use_stream_ids = true}, |
173 | | {"mxf", .use_stream_ids = true}, |
174 | | {"avi", .use_stream_ids = true}, |
175 | | {"asf", .use_stream_ids = true}, |
176 | | {"mp4", .skipinfo = true, .no_pcm_seek = true, .use_stream_ids = true}, |
177 | | {"matroska", .skipinfo = true, .no_pcm_seek = true, .use_stream_ids = true}, |
178 | | |
179 | | {"v4l2", .no_seek = true}, |
180 | | {"rtsp", .no_seek_on_no_duration = true}, |
181 | | |
182 | | // In theory, such streams might contain timestamps, but virtually none do. |
183 | | {"h264", .if_flags = AVFMT_NOTIMESTAMPS }, |
184 | | {"hevc", .if_flags = AVFMT_NOTIMESTAMPS }, |
185 | | {"vvc", .if_flags = AVFMT_NOTIMESTAMPS }, |
186 | | |
187 | | // Some Ogg shoutcast streams are essentially concatenated OGG files. They |
188 | | // reset timestamps, which causes all sorts of problems. |
189 | | {"ogg", .linearize_audio_ts = true, .use_stream_ids = true}, |
190 | | |
191 | | // Ignore additional metadata as frames from some single frame JPEGs |
192 | | // (e.g. gain map) |
193 | | {"jpeg_pipe", .first_frame_only = true}, |
194 | | |
195 | | // At some point, FFmpeg lost the ability to read gif from unseekable |
196 | | // streams. |
197 | | {"gif", .readall_on_no_streamseek = true}, |
198 | | |
199 | | TEXTSUB("aqtitle"), TEXTSUB("jacosub"), TEXTSUB("microdvd"), |
200 | | TEXTSUB("mpl2"), TEXTSUB("mpsub"), TEXTSUB("pjs"), TEXTSUB("realtext"), |
201 | | TEXTSUB("sami"), TEXTSUB("srt"), TEXTSUB("stl"), TEXTSUB("subviewer"), |
202 | | TEXTSUB("subviewer1"), TEXTSUB("vplayer"), TEXTSUB("ass"), |
203 | | |
204 | | TEXTSUB_UTF8("webvtt"), |
205 | | |
206 | | // Useless non-sense, sometimes breaks MLP2 subreader.c fallback |
207 | | BLACKLIST("tty"), |
208 | | // Useless, does not work with custom streams. |
209 | | BLACKLIST("image2"), |
210 | | {0} |
211 | | }; |
212 | | |
213 | | struct nested_stream { |
214 | | AVIOContext *id; |
215 | | int64_t last_bytes; |
216 | | }; |
217 | | |
218 | | struct stream_info { |
219 | | struct sh_stream *sh; |
220 | | double last_key_pts; |
221 | | double highest_pts; |
222 | | double ts_offset; |
223 | | }; |
224 | | |
225 | | typedef struct lavf_priv { |
226 | | struct stream *stream; |
227 | | bool own_stream; |
228 | | bool is_dvd_bd; |
229 | | char *filename; |
230 | | struct format_hack format_hack; |
231 | | const AVInputFormat *avif; |
232 | | int avif_flags; |
233 | | AVFormatContext *avfc; |
234 | | AVIOContext *pb; |
235 | | struct stream_info **streams; // NULL for unknown streams |
236 | | int num_streams; |
237 | | char *mime_type; |
238 | | double seek_delay; |
239 | | |
240 | | struct demux_lavf_opts *opts; |
241 | | |
242 | | bool pcm_seek_hack_disabled; |
243 | | AVStream *pcm_seek_hack; |
244 | | int pcm_seek_hack_packet_size; |
245 | | |
246 | | int linearize_ts; |
247 | | bool any_ts_fixed; |
248 | | |
249 | | int retry_counter; |
250 | | |
251 | | AVDictionary *av_opts; |
252 | | |
253 | | // Proxying nested streams. |
254 | | struct nested_stream *nested; |
255 | | int num_nested; |
256 | | int (*default_io_open)(struct AVFormatContext *s, AVIOContext **pb, |
257 | | const char *url, int flags, AVDictionary **options); |
258 | | int (*default_io_close2)(struct AVFormatContext *s, AVIOContext *pb); |
259 | | } lavf_priv_t; |
260 | | |
261 | | static void update_read_stats(struct demuxer *demuxer) |
262 | 5.66M | { |
263 | 5.66M | lavf_priv_t *priv = demuxer->priv; |
264 | | |
265 | 5.66M | for (int n = 0; n < priv->num_nested; n++) { |
266 | 0 | struct nested_stream *nest = &priv->nested[n]; |
267 | |
|
268 | 0 | int64_t cur = nest->id->bytes_read; |
269 | 0 | int64_t new = cur - nest->last_bytes; |
270 | 0 | nest->last_bytes = cur; |
271 | 0 | demux_report_unbuffered_read_bytes(demuxer, new); |
272 | 0 | } |
273 | 5.66M | } |
274 | | |
275 | | // At least mp4 has name="mov,mp4,m4a,3gp,3g2,mj2", so we split the name |
276 | | // on "," in general. |
277 | | static bool matches_avinputformat_name(struct lavf_priv *priv, |
278 | | const char *name) |
279 | 4.18M | { |
280 | 4.18M | const char *avifname = priv->avif->name; |
281 | 4.43M | while (1) { |
282 | 4.43M | const char *next = strchr(avifname, ','); |
283 | 4.43M | if (!next) |
284 | 4.17M | return !strcmp(avifname, name); |
285 | 252k | int len = next - avifname; |
286 | 252k | if (len == strlen(name) && !memcmp(avifname, name, len)) |
287 | 4.14k | return true; |
288 | 248k | avifname = next + 1; |
289 | 248k | } |
290 | 4.18M | } |
291 | | |
292 | | static int mp_read(void *opaque, uint8_t *buf, int size) |
293 | 599k | { |
294 | 599k | struct demuxer *demuxer = opaque; |
295 | 599k | lavf_priv_t *priv = demuxer->priv; |
296 | 599k | struct stream *stream = priv->stream; |
297 | 599k | if (!stream) |
298 | 0 | return 0; |
299 | | |
300 | 599k | int ret = stream_read_partial(stream, buf, size); |
301 | | |
302 | 599k | MP_TRACE(demuxer, "%d=mp_read(%p, %p, %d), pos: %"PRId64", eof:%d\n", |
303 | 599k | ret, stream, buf, size, stream_tell(stream), stream->eof); |
304 | 599k | return ret ? ret : AVERROR_EOF; |
305 | 599k | } |
306 | | |
307 | | static int64_t mp_seek(void *opaque, int64_t pos, int whence) |
308 | 900k | { |
309 | 900k | struct demuxer *demuxer = opaque; |
310 | 900k | lavf_priv_t *priv = demuxer->priv; |
311 | 900k | struct stream *stream = priv->stream; |
312 | 900k | if (!stream) |
313 | 0 | return -1; |
314 | | |
315 | 900k | MP_TRACE(demuxer, "mp_seek(%p, %"PRId64", %s)\n", stream, pos, |
316 | 900k | whence == SEEK_END ? "end" : |
317 | 900k | whence == SEEK_CUR ? "cur" : |
318 | 900k | whence == SEEK_SET ? "set" : "size"); |
319 | 900k | if (whence == SEEK_END || whence == AVSEEK_SIZE) { |
320 | 204k | int64_t end = stream_get_size(stream); |
321 | 204k | if (end < 0) |
322 | 69.1k | return -1; |
323 | 134k | if (whence == AVSEEK_SIZE) |
324 | 134k | return end; |
325 | 0 | pos += end; |
326 | 696k | } else if (whence == SEEK_CUR) { |
327 | 0 | pos += stream_tell(stream); |
328 | 696k | } else if (whence != SEEK_SET) { |
329 | 0 | return -1; |
330 | 0 | } |
331 | | |
332 | 696k | if (pos < 0) |
333 | 0 | return -1; |
334 | | |
335 | 696k | int64_t current_pos = stream_tell(stream); |
336 | 696k | if (!priv->is_dvd_bd) { |
337 | 696k | if (stream_seek(stream, pos) == 0) { |
338 | 689k | stream_seek(stream, current_pos); |
339 | 689k | return -1; |
340 | 689k | } |
341 | 696k | } else { |
342 | 0 | stream_drop_buffers(stream); |
343 | 0 | stream->pos = current_pos; |
344 | 0 | } |
345 | | |
346 | 7.64k | return pos; |
347 | 696k | } |
348 | | |
349 | | static int64_t mp_read_seek(void *opaque, int stream_idx, int64_t ts, int flags) |
350 | 0 | { |
351 | 0 | struct demuxer *demuxer = opaque; |
352 | 0 | lavf_priv_t *priv = demuxer->priv; |
353 | 0 | struct stream *stream = priv->stream; |
354 | |
|
355 | 0 | struct stream_avseek cmd = { |
356 | 0 | .stream_index = stream_idx, |
357 | 0 | .timestamp = ts, |
358 | 0 | .flags = flags, |
359 | 0 | }; |
360 | |
|
361 | 0 | if (stream && stream_control(stream, STREAM_CTRL_AVSEEK, &cmd) == STREAM_OK) { |
362 | 0 | stream_drop_buffers(stream); |
363 | 0 | return 0; |
364 | 0 | } |
365 | 0 | return AVERROR(ENOSYS); |
366 | 0 | } |
367 | | |
368 | | static void list_formats(struct demuxer *demuxer) |
369 | 0 | { |
370 | 0 | MP_INFO(demuxer, "Available lavf input formats:\n"); |
371 | 0 | const AVInputFormat *fmt; |
372 | 0 | void *iter = NULL; |
373 | 0 | while ((fmt = av_demuxer_iterate(&iter))) |
374 | 0 | MP_INFO(demuxer, "%15s : %s\n", fmt->name, fmt->long_name); |
375 | 0 | } |
376 | | |
377 | | static void convert_charset(struct demuxer *demuxer) |
378 | 5.84k | { |
379 | 5.84k | lavf_priv_t *priv = demuxer->priv; |
380 | 5.84k | char *cp = priv->opts->sub_cp; |
381 | 5.84k | if (!cp || !cp[0] || mp_charset_is_utf8(cp)) |
382 | 0 | return; |
383 | 5.84k | bstr data = stream_read_complete(priv->stream, NULL, 128 * 1024 * 1024); |
384 | 5.84k | if (!data.start) { |
385 | 0 | MP_WARN(demuxer, "File too big (or error reading) - skip charset probing.\n"); |
386 | 0 | return; |
387 | 0 | } |
388 | 5.84k | void *alloc = data.start; |
389 | 5.84k | cp = (char *)mp_charset_guess(priv, demuxer->log, data, cp, 0); |
390 | 5.84k | if (cp && !mp_charset_is_utf8(cp)) |
391 | 5.84k | MP_INFO(demuxer, "Using subtitle charset: %s\n", cp); |
392 | | // libavformat transparently converts UTF-16 to UTF-8 |
393 | 5.84k | if (!mp_charset_is_utf16(cp) && !mp_charset_is_utf8(cp)) { |
394 | 5.27k | bstr conv = mp_iconv_to_utf8(demuxer->log, data, cp, MP_ICONV_VERBOSE); |
395 | 5.27k | if (conv.start && conv.start != data.start) |
396 | 5.27k | talloc_steal(alloc, conv.start); |
397 | 5.27k | if (conv.start) |
398 | 5.27k | data = conv; |
399 | 5.27k | } |
400 | 5.84k | if (data.start) { |
401 | 5.84k | priv->stream = stream_memory_open(demuxer->global, data.start, data.len); |
402 | 5.84k | priv->own_stream = true; |
403 | 5.84k | } |
404 | 5.84k | talloc_free(alloc); |
405 | 5.84k | } |
406 | | |
407 | | static char *remove_prefix(char *s, const char *const *prefixes) |
408 | 149k | { |
409 | 653k | for (int n = 0; prefixes[n]; n++) { |
410 | 551k | int len = strlen(prefixes[n]); |
411 | 551k | if (strncmp(s, prefixes[n], len) == 0) |
412 | 47.9k | return s + len; |
413 | 551k | } |
414 | 101k | return s; |
415 | 149k | } |
416 | | |
417 | | static const char *const prefixes[] = |
418 | | {"ffmpeg://", "lavf://", "avdevice://", "av://", NULL}; |
419 | | |
420 | | static int lavf_check_file(demuxer_t *demuxer, enum demux_check check) |
421 | 149k | { |
422 | 149k | lavf_priv_t *priv = demuxer->priv; |
423 | 149k | struct demux_lavf_opts *lavfdopts = priv->opts; |
424 | 149k | struct stream *s = priv->stream; |
425 | | |
426 | 149k | priv->filename = remove_prefix(s->url, prefixes); |
427 | | |
428 | 149k | char *avdevice_format = NULL; |
429 | 149k | if (s->info && strcmp(s->info->name, "avdevice") == 0) { |
430 | | // always require filename in the form "format:filename" |
431 | 23.9k | char *sep = strchr(priv->filename, ':'); |
432 | 23.9k | if (!sep) { |
433 | 3 | MP_FATAL(demuxer, "Must specify filename in 'format:filename' form\n"); |
434 | 3 | return -1; |
435 | 3 | } |
436 | 23.9k | avdevice_format = talloc_strndup(priv, priv->filename, |
437 | 23.9k | sep - priv->filename); |
438 | 23.9k | priv->filename = sep + 1; |
439 | 23.9k | } |
440 | | |
441 | 149k | char *mime_type = s->mime_type; |
442 | 149k | if (!lavfdopts->allow_mimetype || !mime_type) |
443 | 149k | mime_type = ""; |
444 | | |
445 | 149k | const AVInputFormat *forced_format = NULL; |
446 | 149k | const char *format = lavfdopts->format; |
447 | 149k | if (!format || !format[0]) |
448 | 149k | format = s->lavf_type; |
449 | 149k | if (!format) |
450 | 149k | format = avdevice_format; |
451 | 149k | if (format) { |
452 | 23.9k | if (strcmp(format, "help") == 0) { |
453 | 0 | list_formats(demuxer); |
454 | 0 | return -1; |
455 | 0 | } |
456 | 23.9k | forced_format = av_find_input_format(format); |
457 | 23.9k | if (!forced_format) { |
458 | 18 | MP_FATAL(demuxer, "Unknown lavf format %s\n", format); |
459 | 18 | return -1; |
460 | 18 | } |
461 | 23.9k | } |
462 | | |
463 | | // HLS streams seems to be not well tagged, so matching mime type is not |
464 | | // enough. Strip URL parameters and match extension. |
465 | 149k | bstr ext = bstr_get_ext(bstr_split(bstr0(priv->filename), "?#", NULL)); |
466 | 149k | AVProbeData avpd = { |
467 | | // Disable file-extension matching with normal checks, except for HLS |
468 | 149k | .filename = !bstrcasecmp0(ext, "m3u8") || !bstrcasecmp0(ext, "m3u") || |
469 | 148k | check <= DEMUX_CHECK_REQUEST ? priv->filename : "", |
470 | 149k | .buf_size = 0, |
471 | 149k | .buf = av_mallocz(PROBE_BUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE), |
472 | 149k | .mime_type = lavfdopts->allow_mimetype ? mime_type : NULL, |
473 | 149k | }; |
474 | 149k | if (!avpd.buf) |
475 | 0 | return -1; |
476 | | |
477 | 149k | bool final_probe = false; |
478 | 262k | do { |
479 | 262k | int score = 0; |
480 | | |
481 | 262k | if (forced_format) { |
482 | 23.9k | priv->avif = forced_format; |
483 | 23.9k | score = AVPROBE_SCORE_MAX; |
484 | 238k | } else { |
485 | 238k | int nsize = av_clip(avpd.buf_size * 2, INITIAL_PROBE_SIZE, |
486 | 238k | PROBE_BUF_SIZE); |
487 | 238k | nsize = stream_read_peek(s, avpd.buf, nsize); |
488 | 238k | if (nsize <= avpd.buf_size) |
489 | 60.2k | final_probe = true; |
490 | 238k | avpd.buf_size = nsize; |
491 | | |
492 | 238k | priv->avif = av_probe_input_format2(&avpd, avpd.buf_size > 0, &score); |
493 | 238k | } |
494 | | |
495 | 262k | if (priv->avif) { |
496 | 140k | MP_VERBOSE(demuxer, "Found '%s' at score=%d size=%d%s.\n", |
497 | 140k | priv->avif->name, score, avpd.buf_size, |
498 | 140k | forced_format ? " (forced)" : ""); |
499 | | |
500 | 4.03M | for (int n = 0; lavfdopts->hacks && format_hacks[n].ff_name; n++) { |
501 | 3.95M | const struct format_hack *entry = &format_hacks[n]; |
502 | 3.95M | if (!matches_avinputformat_name(priv, entry->ff_name)) |
503 | 3.86M | continue; |
504 | 88.8k | if (entry->mime_type && strcasecmp(entry->mime_type, mime_type) != 0) |
505 | 32.7k | continue; |
506 | 56.1k | priv->format_hack = *entry; |
507 | 56.1k | break; |
508 | 88.8k | } |
509 | | |
510 | | // AVIF always needs to find stream info |
511 | 140k | if (bstrcasecmp0(ext, "avif") == 0) |
512 | 16 | priv->format_hack.skipinfo = false; |
513 | | |
514 | 140k | if (score >= lavfdopts->probescore) |
515 | 89.5k | break; |
516 | | |
517 | 51.0k | if (priv->format_hack.probescore && |
518 | 31.9k | score >= priv->format_hack.probescore && |
519 | 8.42k | (!priv->format_hack.max_probe || final_probe)) |
520 | 3.92k | break; |
521 | 51.0k | } |
522 | | |
523 | 168k | priv->avif = NULL; |
524 | 168k | priv->format_hack = (struct format_hack){0}; |
525 | 168k | } while (!final_probe); |
526 | | |
527 | 149k | av_free(avpd.buf); |
528 | | |
529 | 149k | if (priv->avif && !forced_format && priv->format_hack.ignore) { |
530 | 2.97k | MP_VERBOSE(demuxer, "Format blacklisted.\n"); |
531 | 2.97k | priv->avif = NULL; |
532 | 2.97k | } |
533 | | |
534 | 149k | if (!priv->avif) { |
535 | 59.2k | MP_VERBOSE(demuxer, "No format found, try lowering probescore or forcing the format.\n"); |
536 | 59.2k | return -1; |
537 | 59.2k | } |
538 | | |
539 | 90.5k | if (lavfdopts->hacks) |
540 | 90.5k | priv->avif_flags = priv->avif->flags | priv->format_hack.if_flags; |
541 | | |
542 | 90.5k | priv->linearize_ts = lavfdopts->linearize_ts; |
543 | 90.5k | if (priv->linearize_ts < 0 && !priv->format_hack.linearize_audio_ts) |
544 | 90.4k | priv->linearize_ts = 0; |
545 | | |
546 | 90.5k | demuxer->filetype = priv->avif->name; |
547 | | |
548 | 90.5k | if (priv->format_hack.detect_charset) |
549 | 5.84k | convert_charset(demuxer); |
550 | | |
551 | 90.5k | return 0; |
552 | 149k | } |
553 | | |
554 | | static char *replace_idx_ext(void *ta_ctx, bstr f) |
555 | 101 | { |
556 | 101 | if (f.len < 4 || f.start[f.len - 4] != '.') |
557 | 88 | return NULL; |
558 | 13 | char *ext = bstr_endswith0(f, "IDX") ? "SUB" : "sub"; // match case |
559 | 13 | return talloc_asprintf(ta_ctx, "%.*s.%s", BSTR_P(bstr_splice(f, 0, -4)), ext); |
560 | 101 | } |
561 | | |
562 | | static void guess_and_set_vobsub_name(struct demuxer *demuxer, AVDictionary **d) |
563 | 90.5k | { |
564 | 90.5k | lavf_priv_t *priv = demuxer->priv; |
565 | 90.5k | if (!matches_avinputformat_name(priv, "vobsub")) |
566 | 90.4k | return; |
567 | | |
568 | 92 | void *tmp = talloc_new(NULL); |
569 | 92 | bstr bfilename = bstr0(priv->filename); |
570 | 92 | char *subname = NULL; |
571 | 92 | if (mp_is_url(bfilename)) { |
572 | | // It might be a http URL, which has additional parameters after the |
573 | | // end of the actual file path. |
574 | 34 | bstr start, end; |
575 | 34 | if (bstr_split_tok(bfilename, "?", &start, &end)) { |
576 | 10 | subname = replace_idx_ext(tmp, start); |
577 | 10 | if (subname) |
578 | 1 | subname = talloc_asprintf(tmp, "%s?%.*s", subname, BSTR_P(end)); |
579 | 10 | } |
580 | 34 | } |
581 | 92 | if (!subname) |
582 | 91 | subname = replace_idx_ext(tmp, bfilename); |
583 | 92 | if (!subname) |
584 | 79 | subname = talloc_asprintf(tmp, "%.*s.sub", BSTR_P(bfilename)); |
585 | | |
586 | 92 | MP_VERBOSE(demuxer, "Assuming associated .sub file: %s\n", subname); |
587 | 92 | av_dict_set(d, "sub_name", subname, 0); |
588 | 92 | talloc_free(tmp); |
589 | 92 | } |
590 | | |
591 | | static void select_tracks(struct demuxer *demuxer, int start) |
592 | 175k | { |
593 | 175k | lavf_priv_t *priv = demuxer->priv; |
594 | 378k | for (int n = start; n < priv->num_streams; n++) { |
595 | 203k | struct sh_stream *stream = priv->streams[n]->sh; |
596 | 203k | AVStream *st = priv->avfc->streams[n]; |
597 | 203k | bool selected = stream && demux_stream_is_selected(stream) && |
598 | 76.3k | !stream->attached_picture; |
599 | 203k | st->discard = selected ? AVDISCARD_DEFAULT : AVDISCARD_ALL; |
600 | 203k | } |
601 | 175k | } |
602 | | |
603 | | static inline const uint8_t *mp_av_stream_get_side_data(const AVStream *st, |
604 | | enum AVPacketSideDataType type) |
605 | 131k | { |
606 | 131k | const AVPacketSideData *sd; |
607 | 131k | sd = av_packet_side_data_get(st->codecpar->coded_side_data, |
608 | 131k | st->codecpar->nb_coded_side_data, |
609 | 131k | type); |
610 | 131k | return sd ? sd->data : NULL; |
611 | 131k | } |
612 | | |
613 | | static void export_replaygain(demuxer_t *demuxer, struct sh_stream *sh, |
614 | | AVStream *st) |
615 | 43.0k | { |
616 | 43.0k | const AVReplayGain *av_rgain = |
617 | 43.0k | (const AVReplayGain *)mp_av_stream_get_side_data(st, AV_PKT_DATA_REPLAYGAIN); |
618 | 43.0k | if (!av_rgain) |
619 | 43.0k | return; |
620 | | |
621 | 43.0k | bool track_data_available = |
622 | 0 | av_rgain->track_gain != INT32_MIN && av_rgain->track_peak != 0; |
623 | 0 | bool album_data_available = |
624 | 0 | av_rgain->album_gain != INT32_MIN && av_rgain->album_peak != 0; |
625 | |
|
626 | 0 | if (!track_data_available && !album_data_available) |
627 | 0 | return; |
628 | | |
629 | 0 | struct replaygain_data *rgain = talloc_ptrtype(demuxer, rgain); |
630 | 0 | rgain->track_gain = rgain->album_gain = 0; |
631 | 0 | rgain->track_peak = rgain->album_peak = 1; |
632 | | |
633 | | // Set values in *rgain, using track gain as a fallback for album gain |
634 | | // if the latter is not present. This behavior matches that in |
635 | | // demux/demux.c's decode_rgain; if you change this, please make |
636 | | // equivalent changes there too. |
637 | 0 | if (track_data_available) { |
638 | 0 | rgain->track_gain = rgain->album_gain = |
639 | 0 | av_rgain->track_gain / 100000.0f; |
640 | 0 | rgain->track_peak = rgain->album_peak = |
641 | 0 | av_rgain->track_peak / 100000.0f; |
642 | 0 | } |
643 | | |
644 | | // If album data is actually available, fill it in with proper values. |
645 | 0 | if (album_data_available) { |
646 | 0 | rgain->album_gain = av_rgain->album_gain / 100000.0f; |
647 | 0 | rgain->album_peak = av_rgain->album_peak / 100000.0f; |
648 | 0 | } |
649 | | |
650 | | // This must be run only before the stream was added, otherwise there |
651 | | // will be race conditions with accesses from the user thread. |
652 | 0 | mp_assert(!sh->ds); |
653 | 0 | sh->codec->replaygain_data = rgain; |
654 | 0 | } |
655 | | |
656 | | // Return a dictionary entry as (decimal) integer. |
657 | | static int dict_get_decimal(AVDictionary *dict, const char *entry, int def) |
658 | 93.1k | { |
659 | 93.1k | AVDictionaryEntry *e = av_dict_get(dict, entry, NULL, 0); |
660 | 93.1k | if (e && e->value) { |
661 | 0 | char *end = NULL; |
662 | 0 | long int r = strtol(e->value, &end, 10); |
663 | 0 | if (end && !end[0] && r >= INT_MIN && r <= INT_MAX) |
664 | 0 | return r; |
665 | 0 | } |
666 | 93.1k | return def; |
667 | 93.1k | } |
668 | | |
669 | | static bool is_image(AVStream *st, bool attached_picture, const AVInputFormat *avif) |
670 | 44.4k | { |
671 | 44.4k | return st->nb_frames <= 1 && ( |
672 | 43.7k | attached_picture || |
673 | 43.6k | bstr_endswith0(bstr0(avif->name), "_pipe") || |
674 | 32.7k | strcmp(avif->name, "alias_pix") == 0 || |
675 | 32.7k | strcmp(avif->name, "gif") == 0 || |
676 | 31.6k | strcmp(avif->name, "ico") == 0 || |
677 | 31.6k | strcmp(avif->name, "image2pipe") == 0 || |
678 | 31.6k | ((st->codecpar->codec_id == AV_CODEC_ID_HEVC || |
679 | 31.0k | st->codecpar->codec_id == AV_CODEC_ID_AV1) |
680 | 3.77k | && st->nb_frames == 1) |
681 | 43.7k | ); |
682 | 44.4k | } |
683 | | |
684 | | static void handle_new_stream(demuxer_t *demuxer, int i) |
685 | 101k | { |
686 | 101k | lavf_priv_t *priv = demuxer->priv; |
687 | 101k | AVFormatContext *avfc = priv->avfc; |
688 | 101k | AVStream *st = avfc->streams[i]; |
689 | 101k | struct sh_stream *sh = NULL; |
690 | 101k | AVCodecParameters *codec = st->codecpar; |
691 | 101k | int lavc_delay = codec->initial_padding; |
692 | | |
693 | 101k | switch (codec->codec_type) { |
694 | 43.0k | case AVMEDIA_TYPE_AUDIO: { |
695 | 43.0k | sh = demux_alloc_sh_stream(STREAM_AUDIO); |
696 | 43.0k | if (!mp_chmap_from_av_layout(&sh->codec->channels, &codec->ch_layout)) { |
697 | 720 | char layout[128] = {0}; |
698 | 720 | MP_WARN(demuxer, |
699 | 720 | "Failed to convert channel layout %s to mpv one!\n", |
700 | 720 | av_channel_layout_describe(&codec->ch_layout, |
701 | 720 | layout, 128) < 0 ? |
702 | 720 | "undefined" : layout); |
703 | 720 | } |
704 | | |
705 | 43.0k | sh->codec->samplerate = codec->sample_rate; |
706 | 43.0k | sh->codec->bitrate = codec->bit_rate; |
707 | 43.0k | sh->codec->format_name = talloc_strdup(sh, av_get_sample_fmt_name(codec->format)); |
708 | | |
709 | 43.0k | double delay = 0; |
710 | 43.0k | if (codec->sample_rate > 0) |
711 | 30.9k | delay = lavc_delay / (double)codec->sample_rate; |
712 | 43.0k | priv->seek_delay = MPMAX(priv->seek_delay, delay); |
713 | | |
714 | 43.0k | export_replaygain(demuxer, sh, st); |
715 | | |
716 | 43.0k | sh->seek_preroll = delay; |
717 | | |
718 | 43.0k | break; |
719 | 0 | } |
720 | 44.4k | case AVMEDIA_TYPE_VIDEO: { |
721 | 44.4k | sh = demux_alloc_sh_stream(STREAM_VIDEO); |
722 | | |
723 | 44.4k | if ((st->disposition & AV_DISPOSITION_ATTACHED_PIC) && |
724 | 89 | !(st->disposition & AV_DISPOSITION_TIMED_THUMBNAILS)) |
725 | 44 | { |
726 | 44 | sh->attached_picture = |
727 | 44 | new_demux_packet_from_avpacket(demuxer->packet_pool, &st->attached_pic); |
728 | 44 | if (sh->attached_picture) { |
729 | 44 | sh->attached_picture->pts = 0; |
730 | 44 | talloc_steal(sh, sh->attached_picture); |
731 | 44 | sh->attached_picture->keyframe = true; |
732 | 44 | } |
733 | 44 | } |
734 | | |
735 | 44.4k | if (!sh->attached_picture) { |
736 | | // A real video stream probably means it's a packet based format. |
737 | 44.4k | priv->pcm_seek_hack_disabled = true; |
738 | 44.4k | priv->pcm_seek_hack = NULL; |
739 | | // Also, we don't want to do this shit for ogv videos. |
740 | 44.4k | if (priv->linearize_ts < 0) |
741 | 0 | priv->linearize_ts = 0; |
742 | 44.4k | } |
743 | | |
744 | 44.4k | sh->codec->disp_w = codec->width; |
745 | 44.4k | sh->codec->disp_h = codec->height; |
746 | 44.4k | sh->codec->format_name = talloc_strdup(sh, av_get_pix_fmt_name(codec->format)); |
747 | 44.4k | if (st->avg_frame_rate.num) |
748 | 34.0k | sh->codec->fps = av_q2d(st->avg_frame_rate); |
749 | 44.4k | if (is_image(st, sh->attached_picture, priv->avif)) { |
750 | 12.7k | MP_VERBOSE(demuxer, "Assuming this is an image format.\n"); |
751 | 12.7k | sh->image = true; |
752 | 12.7k | sh->codec->fps = demuxer->opts->mf_fps; |
753 | 12.7k | } |
754 | 44.4k | sh->codec->par_w = st->sample_aspect_ratio.num; |
755 | 44.4k | sh->codec->par_h = st->sample_aspect_ratio.den; |
756 | | |
757 | 44.4k | const uint8_t *sd = mp_av_stream_get_side_data(st, AV_PKT_DATA_DISPLAYMATRIX); |
758 | 44.4k | if (sd) { |
759 | 317 | double r = av_display_rotation_get((int32_t *)sd); |
760 | 317 | if (!isnan(r)) |
761 | 247 | sh->codec->rotate = (((int)(-r) % 360) + 360) % 360; |
762 | 317 | } |
763 | | |
764 | 44.4k | if ((sd = mp_av_stream_get_side_data(st, AV_PKT_DATA_DOVI_CONF))) { |
765 | 1 | const AVDOVIDecoderConfigurationRecord *cfg = (void *) sd; |
766 | 1 | MP_VERBOSE(demuxer, "Found Dolby Vision config record: profile " |
767 | 1 | "%d level %d\n", cfg->dv_profile, cfg->dv_level); |
768 | 1 | sh->codec->dovi = true; |
769 | 1 | sh->codec->dv_profile = cfg->dv_profile; |
770 | 1 | sh->codec->dv_level = cfg->dv_level; |
771 | 1 | } |
772 | | |
773 | | // This also applies to vfw-muxed mkv, but we can't detect these easily. |
774 | 44.4k | sh->codec->avi_dts = matches_avinputformat_name(priv, "avi"); |
775 | | |
776 | 44.4k | break; |
777 | 0 | } |
778 | 5.70k | case AVMEDIA_TYPE_SUBTITLE: { |
779 | 5.70k | sh = demux_alloc_sh_stream(STREAM_SUB); |
780 | | |
781 | 5.70k | if (codec->extradata_size) { |
782 | 679 | sh->codec->extradata = talloc_size(sh, codec->extradata_size); |
783 | 679 | memcpy(sh->codec->extradata, codec->extradata, codec->extradata_size); |
784 | 679 | sh->codec->extradata_size = codec->extradata_size; |
785 | 679 | } |
786 | | |
787 | 5.70k | if (matches_avinputformat_name(priv, "microdvd")) { |
788 | 0 | AVRational r; |
789 | 0 | if (av_opt_get_q(avfc, "subfps", AV_OPT_SEARCH_CHILDREN, &r) >= 0) { |
790 | | // File headers don't have a FPS set. |
791 | 0 | if (r.num < 1 || r.den < 1) |
792 | 0 | sh->codec->frame_based = 23.976; // default timebase |
793 | 0 | } |
794 | 0 | } |
795 | 5.70k | break; |
796 | 0 | } |
797 | 4 | case AVMEDIA_TYPE_ATTACHMENT: { |
798 | 4 | AVDictionaryEntry *ftag = av_dict_get(st->metadata, "filename", NULL, 0); |
799 | 4 | char *filename = ftag ? ftag->value : NULL; |
800 | 4 | AVDictionaryEntry *mt = av_dict_get(st->metadata, "mimetype", NULL, 0); |
801 | 4 | char *mimetype = mt ? mt->value : NULL; |
802 | 4 | if (mimetype) { |
803 | 4 | demuxer_add_attachment(demuxer, filename, mimetype, |
804 | 4 | codec->extradata, codec->extradata_size); |
805 | 4 | } |
806 | 4 | break; |
807 | 0 | } |
808 | 7.83k | default: ; |
809 | 101k | } |
810 | | |
811 | 101k | struct stream_info *info = talloc_zero(priv, struct stream_info); |
812 | 101k | *info = (struct stream_info){ |
813 | 101k | .sh = sh, |
814 | 101k | .last_key_pts = MP_NOPTS_VALUE, |
815 | 101k | .highest_pts = MP_NOPTS_VALUE, |
816 | 101k | }; |
817 | 101k | mp_assert(priv->num_streams == i); // directly mapped |
818 | 101k | MP_TARRAY_APPEND(priv, priv->streams, priv->num_streams, info); |
819 | | |
820 | 101k | if (sh) { |
821 | 93.1k | sh->ff_index = st->index; |
822 | 93.1k | sh->codec->codec = mp_codec_from_av_codec_id(codec->codec_id); |
823 | 93.1k | sh->codec->codec_tag = codec->codec_tag; |
824 | 93.1k | sh->codec->lav_codecpar = avcodec_parameters_alloc(); |
825 | 93.1k | if (sh->codec->lav_codecpar) |
826 | 93.1k | avcodec_parameters_copy(sh->codec->lav_codecpar, codec); |
827 | 93.1k | sh->codec->native_tb_num = st->time_base.num; |
828 | 93.1k | sh->codec->native_tb_den = st->time_base.den; |
829 | | |
830 | 93.1k | if (st->disposition & AV_DISPOSITION_DEFAULT) |
831 | 10.5k | sh->default_track = true; |
832 | 93.1k | if (st->disposition & AV_DISPOSITION_FORCED) |
833 | 0 | sh->forced_track = true; |
834 | 93.1k | if (st->disposition & AV_DISPOSITION_DEPENDENT) |
835 | 9 | sh->dependent_track = true; |
836 | 93.1k | if (st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED) |
837 | 24 | sh->visual_impaired_track = true; |
838 | 93.1k | if (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED) |
839 | 48 | sh->hearing_impaired_track = true; |
840 | 93.1k | if (st->disposition & AV_DISPOSITION_STILL_IMAGE) |
841 | 0 | sh->still_image = true; |
842 | 93.1k | if (priv->format_hack.use_stream_ids) |
843 | 12.2k | sh->demuxer_id = st->id; |
844 | 93.1k | AVDictionaryEntry *title = av_dict_get(st->metadata, "title", NULL, 0); |
845 | 93.1k | if (title && title->value) |
846 | 454 | sh->title = talloc_strdup(sh, title->value); |
847 | 93.1k | if (!sh->title && st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED) |
848 | 24 | sh->title = talloc_asprintf(sh, "visual impaired"); |
849 | 93.1k | if (!sh->title && st->disposition & AV_DISPOSITION_HEARING_IMPAIRED) |
850 | 48 | sh->title = talloc_asprintf(sh, "hearing impaired"); |
851 | 93.1k | AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0); |
852 | 93.1k | if (lang && lang->value && strcmp(lang->value, "und") != 0) |
853 | 9.70k | sh->lang = talloc_strdup(sh, lang->value); |
854 | 93.1k | sh->hls_bitrate = dict_get_decimal(st->metadata, "variant_bitrate", 0); |
855 | 93.1k | AVProgram *prog = av_find_program_from_stream(avfc, NULL, i); |
856 | 93.1k | if (prog) |
857 | 0 | sh->program_id = prog->id; |
858 | 93.1k | sh->missing_timestamps = !!(priv->avif_flags & AVFMT_NOTIMESTAMPS); |
859 | 93.1k | mp_tags_move_from_av_dictionary(sh->tags, &st->metadata); |
860 | 93.1k | demux_add_sh_stream(demuxer, sh); |
861 | | |
862 | | // Unfortunately, there is no better way to detect PCM codecs, other |
863 | | // than listing them all manually. (Or other "frameless" codecs. Or |
864 | | // rather, codecs with frames so small libavformat will put multiple of |
865 | | // them into a single packet, but not preserve these artificial packet |
866 | | // boundaries on seeking.) |
867 | 93.1k | if (sh->codec->codec && strncmp(sh->codec->codec, "pcm_", 4) == 0 && |
868 | 20.6k | codec->block_align && !priv->pcm_seek_hack_disabled && |
869 | 469 | priv->opts->hacks && !priv->format_hack.no_pcm_seek && |
870 | 408 | st->time_base.num == 1 && st->time_base.den == codec->sample_rate) |
871 | 401 | { |
872 | 401 | if (priv->pcm_seek_hack) { |
873 | | // More than 1 audio stream => usually doesn't apply. |
874 | 0 | priv->pcm_seek_hack_disabled = true; |
875 | 0 | priv->pcm_seek_hack = NULL; |
876 | 401 | } else { |
877 | 401 | priv->pcm_seek_hack = st; |
878 | 401 | } |
879 | 401 | } |
880 | 93.1k | } |
881 | | |
882 | 101k | select_tracks(demuxer, i); |
883 | 101k | } |
884 | | |
885 | | // Add any new streams that might have been added |
886 | | static void add_new_streams(demuxer_t *demuxer) |
887 | 5.54M | { |
888 | 5.54M | lavf_priv_t *priv = demuxer->priv; |
889 | 5.64M | while (priv->num_streams < priv->avfc->nb_streams) |
890 | 101k | handle_new_stream(demuxer, priv->num_streams); |
891 | 5.54M | } |
892 | | |
893 | | static void update_metadata(demuxer_t *demuxer) |
894 | 5.46M | { |
895 | 5.46M | lavf_priv_t *priv = demuxer->priv; |
896 | 5.46M | if (priv->avfc->event_flags & AVFMT_EVENT_FLAG_METADATA_UPDATED) { |
897 | 15 | mp_tags_move_from_av_dictionary(demuxer->metadata, &priv->avfc->metadata); |
898 | 15 | priv->avfc->event_flags = 0; |
899 | 15 | demux_metadata_changed(demuxer); |
900 | 15 | } |
901 | 5.46M | } |
902 | | |
903 | | static int interrupt_cb(void *ctx) |
904 | 1.00M | { |
905 | 1.00M | struct demuxer *demuxer = ctx; |
906 | 1.00M | return mp_cancel_test(demuxer->cancel); |
907 | 1.00M | } |
908 | | |
909 | | static int block_io_open(struct AVFormatContext *s, AVIOContext **pb, |
910 | | const char *url, int flags, AVDictionary **options) |
911 | 0 | { |
912 | 0 | struct demuxer *demuxer = s->opaque; |
913 | 0 | mp_require(demuxer); |
914 | 0 | MP_ERR(demuxer, "Not opening '%s' due to --access-references=no.\n", url); |
915 | 0 | return AVERROR(EACCES); |
916 | 0 | } |
917 | | |
918 | | static int nested_io_open(struct AVFormatContext *s, AVIOContext **pb, |
919 | | const char *url, int flags, AVDictionary **options) |
920 | 0 | { |
921 | 0 | struct demuxer *demuxer = s->opaque; |
922 | 0 | mp_require(demuxer); |
923 | 0 | lavf_priv_t *priv = demuxer->priv; |
924 | |
|
925 | 0 | if (options && priv->opts->propagate_opts) { |
926 | | // Copy av_opts to options, but only entries that are not present in |
927 | | // options. (Hope this will break less by not overwriting important |
928 | | // settings.) |
929 | 0 | AVDictionaryEntry *cur = NULL; |
930 | 0 | while ((cur = av_dict_get(priv->av_opts, "", cur, AV_DICT_IGNORE_SUFFIX))) |
931 | 0 | { |
932 | 0 | if (!*options || !av_dict_get(*options, cur->key, NULL, 0)) { |
933 | 0 | MP_TRACE(demuxer, "Nested option: '%s'='%s'\n", |
934 | 0 | cur->key, cur->value); |
935 | 0 | av_dict_set(options, cur->key, cur->value, 0); |
936 | 0 | } else { |
937 | 0 | MP_TRACE(demuxer, "Skipping nested option: '%s'\n", cur->key); |
938 | 0 | } |
939 | 0 | } |
940 | 0 | } |
941 | |
|
942 | 0 | int r = priv->default_io_open(s, pb, url, flags, options); |
943 | 0 | if (r >= 0) { |
944 | 0 | if (options) |
945 | 0 | mp_avdict_print_unset(demuxer->log, MSGL_TRACE, *options); |
946 | 0 | struct nested_stream nest = { |
947 | 0 | .id = *pb, |
948 | 0 | }; |
949 | 0 | MP_TARRAY_APPEND(priv, priv->nested, priv->num_nested, nest); |
950 | 0 | } |
951 | 0 | return r; |
952 | 0 | } |
953 | | |
954 | | static int nested_io_close2(struct AVFormatContext *s, AVIOContext *pb) |
955 | 0 | { |
956 | 0 | struct demuxer *demuxer = s->opaque; |
957 | 0 | mp_require(demuxer); |
958 | 0 | lavf_priv_t *priv = demuxer->priv; |
959 | |
|
960 | 0 | for (int n = 0; n < priv->num_nested; n++) { |
961 | 0 | if (priv->nested[n].id == pb) { |
962 | 0 | MP_TARRAY_REMOVE_AT(priv->nested, priv->num_nested, n); |
963 | 0 | break; |
964 | 0 | } |
965 | 0 | } |
966 | | |
967 | 0 | return priv->default_io_close2(s, pb); |
968 | 0 | } |
969 | | |
970 | | static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check) |
971 | 149k | { |
972 | 149k | AVFormatContext *avfc = NULL; |
973 | 149k | AVDictionaryEntry *t = NULL; |
974 | 149k | float analyze_duration = 0; |
975 | 149k | lavf_priv_t *priv = talloc_zero(NULL, lavf_priv_t); |
976 | 149k | AVDictionary *dopts = NULL; |
977 | | |
978 | 149k | demuxer->priv = priv; |
979 | 149k | priv->stream = demuxer->stream; |
980 | | |
981 | 149k | priv->opts = mp_get_config_group(priv, demuxer->global, &demux_lavf_conf); |
982 | 149k | struct demux_lavf_opts *lavfdopts = priv->opts; |
983 | | |
984 | 149k | if (lavf_check_file(demuxer, check) < 0) |
985 | 59.2k | goto fail; |
986 | | |
987 | 90.5k | avfc = avformat_alloc_context(); |
988 | 90.5k | if (!avfc) |
989 | 0 | goto fail; |
990 | | |
991 | 90.5k | if (demuxer->opts->index_mode != 1) |
992 | 0 | avfc->flags |= AVFMT_FLAG_IGNIDX; |
993 | | |
994 | 90.5k | if (lavfdopts->probesize) { |
995 | 80 | if (av_opt_set_int(avfc, "probesize", lavfdopts->probesize, 0) < 0) |
996 | 80 | MP_ERR(demuxer, "couldn't set option probesize to %u\n", |
997 | 80 | lavfdopts->probesize); |
998 | 80 | } |
999 | | |
1000 | 90.5k | if (priv->format_hack.analyzeduration) |
1001 | 0 | analyze_duration = priv->format_hack.analyzeduration; |
1002 | 90.5k | if (lavfdopts->analyzeduration) |
1003 | 30 | analyze_duration = lavfdopts->analyzeduration; |
1004 | 90.5k | if (analyze_duration > 0) { |
1005 | 30 | if (av_opt_set_int(avfc, "analyzeduration", |
1006 | 30 | analyze_duration * AV_TIME_BASE, 0) < 0) |
1007 | 30 | MP_ERR(demuxer, "demux_lavf, couldn't set option " |
1008 | 30 | "analyzeduration to %f\n", analyze_duration); |
1009 | 30 | } |
1010 | | |
1011 | 90.5k | if (priv->format_hack.no_ext_picky) { |
1012 | 0 | bool user_set_ext_picky = false; |
1013 | 0 | for (int i = 0; lavfdopts->avopts && lavfdopts->avopts[i * 2]; i++) { |
1014 | 0 | if (bstr_startswith0(bstr0(lavfdopts->avopts[i * 2]), "extension_picky")) { |
1015 | 0 | user_set_ext_picky = true; |
1016 | 0 | break; |
1017 | 0 | } |
1018 | 0 | } |
1019 | 0 | if (!user_set_ext_picky && av_dict_set(&dopts, "extension_picky", "0", 0) >= 0) |
1020 | 0 | MP_VERBOSE(demuxer, "Option extension_picky=0 was set due to known FFmpeg bugs\n"); |
1021 | 0 | } |
1022 | | |
1023 | 90.5k | if ((priv->avif_flags & AVFMT_NOFILE) || priv->format_hack.no_stream) { |
1024 | 23.8k | mp_setup_av_network_options(&dopts, priv->avif->name, |
1025 | 23.8k | demuxer->global, demuxer->log); |
1026 | | // This might be incorrect. |
1027 | 23.8k | demuxer->seekable = true; |
1028 | 66.6k | } else { |
1029 | 66.6k | void *buffer = av_malloc(lavfdopts->buffersize); |
1030 | 66.6k | if (!buffer) |
1031 | 0 | goto fail; |
1032 | 66.6k | priv->pb = avio_alloc_context(buffer, lavfdopts->buffersize, 0, |
1033 | 66.6k | demuxer, mp_read, NULL, mp_seek); |
1034 | 66.6k | if (!priv->pb) { |
1035 | 0 | av_free(buffer); |
1036 | 0 | goto fail; |
1037 | 0 | } |
1038 | 66.6k | priv->pb->read_seek = mp_read_seek; |
1039 | 66.6k | priv->pb->seekable = demuxer->seekable ? AVIO_SEEKABLE_NORMAL : 0; |
1040 | 66.6k | avfc->pb = priv->pb; |
1041 | 66.6k | if (stream_control(priv->stream, STREAM_CTRL_HAS_AVSEEK, NULL) > 0) |
1042 | 0 | demuxer->seekable = true; |
1043 | 66.6k | demuxer->seekable |= priv->format_hack.fully_read; |
1044 | 66.6k | } |
1045 | | |
1046 | 90.5k | if (matches_avinputformat_name(priv, "rtsp")) { |
1047 | 0 | const char *transport = NULL; |
1048 | 0 | switch (lavfdopts->rtsp_transport) { |
1049 | 0 | case 1: transport = "udp"; break; |
1050 | 0 | case 2: transport = "tcp"; break; |
1051 | 0 | case 3: transport = "http"; break; |
1052 | 0 | case 4: transport = "udp_multicast"; break; |
1053 | 0 | } |
1054 | 0 | if (transport) |
1055 | 0 | av_dict_set(&dopts, "rtsp_transport", transport, 0); |
1056 | 0 | } |
1057 | | |
1058 | 90.5k | guess_and_set_vobsub_name(demuxer, &dopts); |
1059 | | |
1060 | 90.5k | avfc->interrupt_callback = (AVIOInterruptCB){ |
1061 | 90.5k | .callback = interrupt_cb, |
1062 | 90.5k | .opaque = demuxer, |
1063 | 90.5k | }; |
1064 | | |
1065 | 90.5k | avfc->opaque = demuxer; |
1066 | 90.5k | if (demuxer->access_references) { |
1067 | 90.5k | priv->default_io_open = avfc->io_open; |
1068 | 90.5k | avfc->io_open = nested_io_open; |
1069 | 90.5k | priv->default_io_close2 = avfc->io_close2; |
1070 | 90.5k | avfc->io_close2 = nested_io_close2; |
1071 | 90.5k | } else { |
1072 | 0 | avfc->io_open = block_io_open; |
1073 | 0 | } |
1074 | | |
1075 | 90.5k | mp_set_avdict(&dopts, lavfdopts->avopts); |
1076 | | |
1077 | 90.5k | if (av_dict_copy(&priv->av_opts, dopts, 0) < 0) { |
1078 | 0 | MP_ERR(demuxer, "av_dict_copy() failed\n"); |
1079 | 0 | goto fail; |
1080 | 0 | } |
1081 | | |
1082 | 90.5k | if (priv->format_hack.readall_on_no_streamseek && priv->pb && |
1083 | 1.15k | !priv->pb->seekable) |
1084 | 0 | { |
1085 | 0 | MP_VERBOSE(demuxer, "Non-seekable demuxer pre-read hack...\n"); |
1086 | | // Read incremental to avoid unnecessary large buffer sizes. |
1087 | 0 | int r = 0; |
1088 | 0 | for (int n = 16; n < 29; n++) { |
1089 | 0 | r = stream_peek(priv->stream, 1 << n); |
1090 | 0 | if (r < (1 << n)) |
1091 | 0 | break; |
1092 | 0 | } |
1093 | 0 | MP_VERBOSE(demuxer, "...did read %d bytes.\n", r); |
1094 | 0 | } |
1095 | | |
1096 | 90.5k | if (avformat_open_input(&avfc, priv->filename, priv->avif, &dopts) < 0) { |
1097 | 9.74k | MP_ERR(demuxer, "avformat_open_input() failed\n"); |
1098 | 9.74k | goto fail; |
1099 | 9.74k | } |
1100 | | |
1101 | 80.7k | mp_avdict_print_unset(demuxer->log, MSGL_V, dopts); |
1102 | 80.7k | av_dict_free(&dopts); |
1103 | | |
1104 | 80.7k | priv->avfc = avfc; |
1105 | | |
1106 | 80.7k | bool probeinfo = lavfdopts->probeinfo != 0; |
1107 | 80.7k | switch (lavfdopts->probeinfo) { |
1108 | 0 | case -2: probeinfo = priv->avfc->nb_streams == 0; break; |
1109 | 80.7k | case -1: probeinfo = !priv->format_hack.skipinfo; break; |
1110 | 80.7k | } |
1111 | 80.7k | if (demuxer->params && demuxer->params->skip_lavf_probing) |
1112 | 1.01k | probeinfo = false; |
1113 | 80.7k | if (probeinfo) { |
1114 | 77.7k | if (avformat_find_stream_info(avfc, NULL) < 0) { |
1115 | 2.66k | MP_ERR(demuxer, "av_find_stream_info() failed\n"); |
1116 | 2.66k | goto fail; |
1117 | 2.66k | } |
1118 | | |
1119 | 75.0k | MP_VERBOSE(demuxer, "avformat_find_stream_info() finished after %"PRId64 |
1120 | 75.0k | " bytes.\n", stream_tell(priv->stream)); |
1121 | 75.0k | } |
1122 | | |
1123 | 88.9k | for (int i = 0; i < avfc->nb_chapters; i++) { |
1124 | 10.8k | AVChapter *c = avfc->chapters[i]; |
1125 | 10.8k | t = av_dict_get(c->metadata, "title", NULL, 0); |
1126 | 10.8k | int index = demuxer_add_chapter(demuxer, t ? t->value : "", |
1127 | 10.8k | c->start * av_q2d(c->time_base), i); |
1128 | 10.8k | mp_tags_move_from_av_dictionary(demuxer->chapters[index].metadata, &c->metadata); |
1129 | 10.8k | } |
1130 | | |
1131 | 78.0k | add_new_streams(demuxer); |
1132 | | |
1133 | 78.0k | mp_tags_move_from_av_dictionary(demuxer->metadata, &avfc->metadata); |
1134 | | |
1135 | 78.0k | demuxer->ts_resets_possible = |
1136 | 78.0k | priv->avif_flags & (AVFMT_TS_DISCONT | AVFMT_NOTIMESTAMPS); |
1137 | | |
1138 | 78.0k | if (avfc->start_time != AV_NOPTS_VALUE) |
1139 | 36.4k | demuxer->start_time = avfc->start_time / (double)AV_TIME_BASE; |
1140 | | |
1141 | 78.0k | demuxer->fully_read = priv->format_hack.fully_read; |
1142 | | |
1143 | 78.0k | #ifdef AVFMTCTX_UNSEEKABLE |
1144 | 78.0k | if (avfc->ctx_flags & AVFMTCTX_UNSEEKABLE) |
1145 | 0 | demuxer->seekable = false; |
1146 | 78.0k | #endif |
1147 | | |
1148 | 78.0k | demuxer->is_network |= priv->format_hack.is_network; |
1149 | 78.0k | demuxer->seekable &= !priv->format_hack.no_seek; |
1150 | | |
1151 | | // We initially prefer track durations over container durations because they |
1152 | | // have a higher degree of precision over the container duration which are |
1153 | | // only accurate to the 6th decimal place. This is probably a lavf bug. |
1154 | 78.0k | double total_duration = -1; |
1155 | 78.0k | double av_duration = -1; |
1156 | 179k | for (int n = 0; n < priv->avfc->nb_streams; n++) { |
1157 | 101k | AVStream *st = priv->avfc->streams[n]; |
1158 | 101k | if (st->duration <= 0) |
1159 | 82.1k | continue; |
1160 | 18.8k | double f_duration = st->duration * av_q2d(st->time_base); |
1161 | 18.8k | total_duration = MPMAX(total_duration, f_duration); |
1162 | 18.8k | if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || |
1163 | 7.54k | st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) |
1164 | 18.6k | av_duration = MPMAX(av_duration, f_duration); |
1165 | 18.8k | } |
1166 | 78.0k | double duration = av_duration > 0 ? av_duration : total_duration; |
1167 | 78.0k | if (duration <= 0 && priv->avfc->duration > 0) |
1168 | 16 | duration = (double)priv->avfc->duration / AV_TIME_BASE; |
1169 | 78.0k | demuxer->duration = duration; |
1170 | | |
1171 | 78.0k | if (demuxer->duration < 0 && priv->format_hack.no_seek_on_no_duration) |
1172 | 0 | demuxer->seekable = false; |
1173 | | |
1174 | | // In some cases, libavformat will export bogus bullshit timestamps anyway, |
1175 | | // such as with mjpeg. |
1176 | 78.0k | if (priv->avif_flags & AVFMT_NOTIMESTAMPS) { |
1177 | 9.01k | MP_WARN(demuxer, |
1178 | 9.01k | "This format is marked by FFmpeg as having no timestamps!\n" |
1179 | 9.01k | "FFmpeg will likely make up its own broken timestamps. For\n" |
1180 | 9.01k | "video streams you can correct this with:\n" |
1181 | 9.01k | " --no-correct-pts --container-fps-override=VALUE\n" |
1182 | 9.01k | "with VALUE being the real framerate of the stream. You can\n" |
1183 | 9.01k | "expect seeking and buffering estimation to be generally\n" |
1184 | 9.01k | "broken as well.\n"); |
1185 | 9.01k | } |
1186 | | |
1187 | 78.0k | if (demuxer->fully_read) { |
1188 | 4.64k | demux_close_stream(demuxer); |
1189 | 4.64k | if (priv->own_stream) |
1190 | 4.53k | free_stream(priv->stream); |
1191 | 4.64k | priv->own_stream = false; |
1192 | 4.64k | priv->stream = NULL; |
1193 | 4.64k | } |
1194 | | |
1195 | 78.0k | if (priv->stream) { |
1196 | 73.4k | const char *sname = priv->stream->info->name; |
1197 | 73.4k | priv->is_dvd_bd = strcmp(sname, "dvdnav") == 0 || |
1198 | 73.4k | strcmp(sname, "ifo_dvdnav") == 0 || |
1199 | 73.4k | strcmp(sname, "bd") == 0 || |
1200 | 73.4k | strcmp(sname, "bdnav") == 0 || |
1201 | 73.4k | strcmp(sname, "bdmv/bluray") == 0; |
1202 | 73.4k | } |
1203 | | |
1204 | 78.0k | return 0; |
1205 | | |
1206 | 71.7k | fail: |
1207 | 71.7k | if (!priv->avfc) |
1208 | 69.0k | avformat_free_context(avfc); |
1209 | 71.7k | av_dict_free(&dopts); |
1210 | | |
1211 | 71.7k | return -1; |
1212 | 80.7k | } |
1213 | | |
1214 | | static bool demux_lavf_read_packet(struct demuxer *demux, |
1215 | | struct demux_packet **mp_pkt) |
1216 | 5.63M | { |
1217 | 5.63M | lavf_priv_t *priv = demux->priv; |
1218 | | |
1219 | 5.63M | AVPacket *pkt = av_packet_alloc(); |
1220 | 5.63M | MP_HANDLE_OOM(pkt); |
1221 | 5.63M | int r = av_read_frame(priv->avfc, pkt); |
1222 | 5.63M | update_read_stats(demux); |
1223 | 5.63M | if (r < 0) { |
1224 | 164k | av_packet_free(&pkt); |
1225 | 164k | if (r == AVERROR_EOF) |
1226 | 49.2k | return false; |
1227 | 114k | MP_WARN(demux, "error reading packet: %s.\n", av_err2str(r)); |
1228 | 114k | if (priv->retry_counter >= 10) { |
1229 | 9.77k | MP_ERR(demux, "...treating it as fatal error.\n"); |
1230 | 9.77k | return false; |
1231 | 9.77k | } |
1232 | 105k | priv->retry_counter += 1; |
1233 | 105k | return true; |
1234 | 114k | } |
1235 | 5.46M | priv->retry_counter = 0; |
1236 | | |
1237 | 5.46M | add_new_streams(demux); |
1238 | 5.46M | update_metadata(demux); |
1239 | | |
1240 | 5.46M | mp_assert(pkt->stream_index >= 0 && pkt->stream_index < priv->num_streams); |
1241 | 5.46M | struct stream_info *info = priv->streams[pkt->stream_index]; |
1242 | 5.46M | struct sh_stream *stream = info->sh; |
1243 | 5.46M | AVStream *st = priv->avfc->streams[pkt->stream_index]; |
1244 | | |
1245 | 5.46M | if (!demux_stream_is_selected(stream)) { |
1246 | 26.7k | av_packet_free(&pkt); |
1247 | 26.7k | return true; // don't signal EOF if skipping a packet |
1248 | 26.7k | } |
1249 | | |
1250 | | // Never send additional frames for streams that are a single frame. |
1251 | 5.44M | if (stream->image && priv->format_hack.first_frame_only && pkt->pos != 0) { |
1252 | 3 | av_packet_free(&pkt); |
1253 | 3 | return true; |
1254 | 3 | } |
1255 | | |
1256 | 5.44M | struct demux_packet *dp = new_demux_packet_from_avpacket(demux->packet_pool, pkt); |
1257 | 5.44M | if (!dp) { |
1258 | 0 | av_packet_free(&pkt); |
1259 | 0 | return true; |
1260 | 0 | } |
1261 | | |
1262 | 5.44M | if (priv->pcm_seek_hack == st && !priv->pcm_seek_hack_packet_size) |
1263 | 0 | priv->pcm_seek_hack_packet_size = pkt->size; |
1264 | | |
1265 | 5.44M | dp->pts = mp_pts_from_av(pkt->pts, &st->time_base); |
1266 | 5.44M | dp->dts = mp_pts_from_av(pkt->dts, &st->time_base); |
1267 | 5.44M | dp->duration = pkt->duration * av_q2d(st->time_base); |
1268 | 5.44M | dp->pos = pkt->pos; |
1269 | 5.44M | dp->keyframe = pkt->flags & AV_PKT_FLAG_KEY; |
1270 | 5.44M | dp->is_wrapped_avframe = st->codecpar->codec_id == AV_CODEC_ID_WRAPPED_AVFRAME; |
1271 | 5.44M | av_packet_free(&pkt); |
1272 | | |
1273 | 5.44M | if (priv->format_hack.clear_filepos) |
1274 | 0 | dp->pos = -1; |
1275 | | |
1276 | 5.44M | dp->stream = stream->index; |
1277 | | |
1278 | 5.44M | if (priv->linearize_ts) { |
1279 | 7 | dp->pts = MP_ADD_PTS(dp->pts, info->ts_offset); |
1280 | 7 | dp->dts = MP_ADD_PTS(dp->dts, info->ts_offset); |
1281 | | |
1282 | 7 | double pts = MP_PTS_OR_DEF(dp->pts, dp->dts); |
1283 | 7 | if (pts != MP_NOPTS_VALUE) { |
1284 | 7 | if (dp->keyframe) { |
1285 | 4 | if (pts < info->highest_pts) { |
1286 | 0 | MP_WARN(demux, "Linearizing discontinuity: %f -> %f\n", |
1287 | 0 | pts, info->highest_pts); |
1288 | | // Note: introduces a small discontinuity by a frame size. |
1289 | 0 | double diff = info->highest_pts - pts; |
1290 | 0 | dp->pts = MP_ADD_PTS(dp->pts, diff); |
1291 | 0 | dp->dts = MP_ADD_PTS(dp->dts, diff); |
1292 | 0 | pts += diff; |
1293 | 0 | info->ts_offset += diff; |
1294 | 0 | priv->any_ts_fixed = true; |
1295 | 0 | } |
1296 | 4 | info->last_key_pts = pts; |
1297 | 4 | } |
1298 | 7 | info->highest_pts = MP_PTS_MAX(info->highest_pts, pts); |
1299 | 7 | } |
1300 | 7 | } |
1301 | | |
1302 | 5.44M | if (st->event_flags & AVSTREAM_EVENT_FLAG_METADATA_UPDATED) { |
1303 | 21 | st->event_flags = 0; |
1304 | 21 | struct mp_tags *tags = talloc_zero(NULL, struct mp_tags); |
1305 | 21 | mp_tags_move_from_av_dictionary(tags, &st->metadata); |
1306 | 21 | double pts = MP_PTS_OR_DEF(dp->pts, dp->dts); |
1307 | 21 | demux_stream_tags_changed(demux, stream, tags, pts); |
1308 | 21 | } |
1309 | | |
1310 | 5.44M | *mp_pkt = dp; |
1311 | 5.44M | return true; |
1312 | 5.44M | } |
1313 | | |
1314 | | static void demux_drop_buffers_lavf(demuxer_t *demuxer) |
1315 | 0 | { |
1316 | 0 | lavf_priv_t *priv = demuxer->priv; |
1317 | 0 | av_seek_frame(priv->avfc, -1, 0, 1); |
1318 | 0 | demux_flush(demuxer); |
1319 | 0 | stream_drop_buffers(priv->stream); |
1320 | 0 | avio_flush(priv->avfc->pb); |
1321 | 0 | avformat_flush(priv->avfc); |
1322 | 0 | } |
1323 | | |
1324 | | static void demux_seek_lavf(demuxer_t *demuxer, double seek_pts, int flags) |
1325 | 32.7k | { |
1326 | 32.7k | lavf_priv_t *priv = demuxer->priv; |
1327 | 32.7k | int avsflags = 0; |
1328 | 32.7k | int64_t seek_pts_av = 0; |
1329 | 32.7k | int seek_stream = -1; |
1330 | | |
1331 | 32.7k | if (priv->any_ts_fixed) { |
1332 | | // helpful message to piss of users |
1333 | 0 | MP_WARN(demuxer, "Some timestamps returned by the demuxer were linearized. " |
1334 | 0 | "A low level seek was requested; this won't work due to " |
1335 | 0 | "restrictions in libavformat's API. You may have more " |
1336 | 0 | "luck by enabling or enlarging the mpv cache.\n"); |
1337 | 0 | } |
1338 | | |
1339 | 32.7k | if (priv->linearize_ts < 0) |
1340 | 21 | priv->linearize_ts = 0; |
1341 | | |
1342 | 32.7k | if (!(flags & SEEK_FORWARD)) |
1343 | 32.7k | avsflags = AVSEEK_FLAG_BACKWARD; |
1344 | | |
1345 | 32.7k | if (flags & SEEK_FACTOR) { |
1346 | 0 | struct stream *s = priv->stream; |
1347 | 0 | int64_t end = s ? stream_get_size(s) : -1; |
1348 | 0 | if (end > 0 && demuxer->ts_resets_possible && |
1349 | 0 | !(priv->avif_flags & AVFMT_NO_BYTE_SEEK)) |
1350 | 0 | { |
1351 | 0 | avsflags |= AVSEEK_FLAG_BYTE; |
1352 | 0 | seek_pts_av = end * seek_pts; |
1353 | 0 | } else if (priv->avfc->duration != 0 && |
1354 | 0 | priv->avfc->duration != AV_NOPTS_VALUE) |
1355 | 0 | { |
1356 | 0 | seek_pts_av = seek_pts * priv->avfc->duration; |
1357 | 0 | } |
1358 | 32.7k | } else { |
1359 | 32.7k | if (!(flags & SEEK_FORWARD)) |
1360 | 32.7k | seek_pts -= priv->seek_delay; |
1361 | 32.7k | seek_pts_av = seek_pts * AV_TIME_BASE; |
1362 | 32.7k | } |
1363 | | |
1364 | | // Hack to make wav seeking "deterministic". Without this, features like |
1365 | | // backward playback won't work. |
1366 | 32.7k | if (priv->pcm_seek_hack && !priv->pcm_seek_hack_packet_size) { |
1367 | | // This might for example be the initial seek. Fuck it up like the |
1368 | | // bullshit it is. |
1369 | 389 | AVPacket *pkt = av_packet_alloc(); |
1370 | 389 | MP_HANDLE_OOM(pkt); |
1371 | 389 | if (av_read_frame(priv->avfc, pkt) >= 0) |
1372 | 388 | priv->pcm_seek_hack_packet_size = pkt->size; |
1373 | 389 | av_packet_free(&pkt); |
1374 | 389 | add_new_streams(demuxer); |
1375 | 389 | } |
1376 | 32.7k | if (priv->pcm_seek_hack && priv->pcm_seek_hack_packet_size && |
1377 | 388 | !(avsflags & AVSEEK_FLAG_BYTE)) |
1378 | 388 | { |
1379 | 388 | int samples = priv->pcm_seek_hack_packet_size / |
1380 | 388 | priv->pcm_seek_hack->codecpar->block_align; |
1381 | 388 | if (samples > 0) { |
1382 | 383 | MP_VERBOSE(demuxer, "using bullshit libavformat PCM seek hack\n"); |
1383 | 383 | double pts = seek_pts_av / (double)AV_TIME_BASE; |
1384 | 383 | seek_pts_av = pts / av_q2d(priv->pcm_seek_hack->time_base); |
1385 | 383 | int64_t align = seek_pts_av % samples; |
1386 | 383 | seek_pts_av -= align; |
1387 | 383 | seek_stream = priv->pcm_seek_hack->index; |
1388 | 383 | } |
1389 | 388 | } |
1390 | | |
1391 | 32.7k | int r = av_seek_frame(priv->avfc, seek_stream, seek_pts_av, avsflags); |
1392 | 32.7k | if (r < 0 && (avsflags & AVSEEK_FLAG_BACKWARD)) { |
1393 | | // When seeking before the beginning of the file, and seeking fails, |
1394 | | // try again without the backwards flag to make it seek to the |
1395 | | // beginning. |
1396 | 20.1k | avsflags &= ~AVSEEK_FLAG_BACKWARD; |
1397 | 20.1k | r = av_seek_frame(priv->avfc, seek_stream, seek_pts_av, avsflags); |
1398 | 20.1k | } |
1399 | | |
1400 | 32.7k | if (r < 0) { |
1401 | 18.9k | char buf[180]; |
1402 | 18.9k | av_strerror(r, buf, sizeof(buf)); |
1403 | 18.9k | MP_VERBOSE(demuxer, "Seek failed (%s)\n", buf); |
1404 | 18.9k | } |
1405 | | |
1406 | 32.7k | update_read_stats(demuxer); |
1407 | 32.7k | } |
1408 | | |
1409 | | static void demux_lavf_switched_tracks(struct demuxer *demuxer) |
1410 | 74.7k | { |
1411 | 74.7k | select_tracks(demuxer, 0); |
1412 | 74.7k | } |
1413 | | |
1414 | | static void demux_close_lavf(demuxer_t *demuxer) |
1415 | 149k | { |
1416 | 149k | lavf_priv_t *priv = demuxer->priv; |
1417 | 149k | if (priv) { |
1418 | | // This will be a dangling pointer; but see below. |
1419 | 149k | AVIOContext *leaking = priv->avfc ? priv->avfc->pb : NULL; |
1420 | 149k | avformat_close_input(&priv->avfc); |
1421 | | // The ffmpeg garbage breaks its own API yet again: hls.c will call |
1422 | | // io_open on the main playlist, but never calls io_close. This happens |
1423 | | // to work out for us (since we don't really use custom I/O), but it's |
1424 | | // still weird. Compensate. |
1425 | 149k | if (priv->num_nested == 1 && priv->nested[0].id == leaking) |
1426 | 0 | priv->num_nested = 0; |
1427 | 149k | if (priv->num_nested) { |
1428 | 0 | MP_WARN(demuxer, "Leaking %d nested connections (FFmpeg bug).\n", |
1429 | 0 | priv->num_nested); |
1430 | 0 | } |
1431 | 149k | if (priv->pb) |
1432 | 66.6k | av_freep(&priv->pb->buffer); |
1433 | 149k | av_freep(&priv->pb); |
1434 | 250k | for (int n = 0; n < priv->num_streams; n++) { |
1435 | 101k | struct stream_info *info = priv->streams[n]; |
1436 | 101k | if (info->sh) |
1437 | 93.1k | avcodec_parameters_free(&info->sh->codec->lav_codecpar); |
1438 | 101k | } |
1439 | 149k | if (priv->own_stream) |
1440 | 1.30k | free_stream(priv->stream); |
1441 | 149k | if (priv->av_opts) |
1442 | 23.9k | av_dict_free(&priv->av_opts); |
1443 | 149k | talloc_free(priv); |
1444 | | demuxer->priv = NULL; |
1445 | 149k | } |
1446 | 149k | } |
1447 | | |
1448 | | |
1449 | | const demuxer_desc_t demuxer_desc_lavf = { |
1450 | | .name = "lavf", |
1451 | | .desc = "libavformat", |
1452 | | .read_packet = demux_lavf_read_packet, |
1453 | | .open = demux_open_lavf, |
1454 | | .drop_buffers = demux_drop_buffers_lavf, |
1455 | | .close = demux_close_lavf, |
1456 | | .seek = demux_seek_lavf, |
1457 | | .switched_tracks = demux_lavf_switched_tracks, |
1458 | | }; |