2004-04-11 14:26:04 +00:00
|
|
|
/*
|
2008-05-14 18:01:51 +00:00
|
|
|
* Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
|
|
|
|
*
|
2015-04-13 07:36:54 +00:00
|
|
|
* This file is part of mpv.
|
2008-05-14 18:01:51 +00:00
|
|
|
*
|
2015-04-13 07:36:54 +00:00
|
|
|
* mpv is free software; you can redistribute it and/or modify
|
2008-05-14 18:01:51 +00:00
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
2015-04-13 07:36:54 +00:00
|
|
|
* mpv is distributed in the hope that it will be useful,
|
2008-05-14 18:01:51 +00:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
2015-04-13 07:36:54 +00:00
|
|
|
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
2008-05-14 18:01:51 +00:00
|
|
|
*/
|
2004-04-11 14:26:04 +00:00
|
|
|
|
|
|
|
#include <stdlib.h>
|
2006-08-31 21:26:02 +00:00
|
|
|
#include <limits.h>
|
2009-03-19 03:25:12 +00:00
|
|
|
#include <stdbool.h>
|
2010-11-05 10:50:11 +00:00
|
|
|
#include <string.h>
|
2014-07-10 06:28:03 +00:00
|
|
|
#include <strings.h>
|
2016-12-04 22:15:31 +00:00
|
|
|
#include <errno.h>
|
core: fix DVD subtitle selection
Add all subtitle tracks as reported by libdvdread at playback start.
Display language for subtitle and audio tracks. This commit restores
these features to the state when demux_mpg was default for DVD playback,
and makes them work with demux_lavf and the recent changes to subtitle
selection in the frontend.
demux_mpg, which was the default demuxer for DVD playback, reordered
the subtitle streams according to the "logical" subtitle track number,
which conforms to the track layout reported by libdvdread, and is what
stream_dvd expects for the STREAM_CTRL_GET_LANG call. demux_lavf, on
the other hand, adds the streams in the order it encounters them in
the MPEG stream. It seems this order is essentially random, and can't
be mapped easily to what stream_dvd expects.
Solve this by making demux_lavf hand out the MPEG stream IDs (using the
demuxer_id field). The MPEG IDs are mapped by mplayer.c by special
casing DVD playback (map_id_from/to_demuxer() functions). This mapping
is essentially the same what demux_mpg did. Making demux_lavf reorder
the streams is out of the question, because its stream handling is
already messy enough.
(Note that demux_lavf doesn't export stream IDs for other formats,
because most time libavformat demuxers do not set AVStream.id, and we
don't know which demuxers do. But we know that MPEG is safe.)
Another major complication is that subtitle tracks are added lazily, as
soon as the demuxer encounters the first subtitle packet for a given
subtitle stream. Add the streams in advance. If a yet non-existent
stream is selected, demux_lavf must be made to auto-select that subtitle
stream as soon as it is added. Otherwise, the first subtitle packet
would be lost. This is done by DEMUXER_CTRL_PRESELECT_SUBTITLE.
demux_mpg didn't need this: the frontend code could just set ds->id to
the desired stream number. But demux_lavf's stream IDs don't map
directly to the stream number as used by libdvdread, which is why this
hack is needed.
2012-08-30 14:43:31 +00:00
|
|
|
#include <assert.h>
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2014-03-25 10:46:10 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2012-01-28 11:41:36 +00:00
|
|
|
#include <libavformat/avformat.h>
|
|
|
|
#include <libavformat/avio.h>
|
|
|
|
#include <libavutil/avutil.h>
|
|
|
|
#include <libavutil/avstring.h>
|
|
|
|
#include <libavutil/mathematics.h>
|
2015-03-03 11:28:46 +00:00
|
|
|
#include <libavutil/replaygain.h>
|
|
|
|
#include <libavutil/display.h>
|
2012-01-28 11:41:36 +00:00
|
|
|
#include <libavutil/opt.h>
|
|
|
|
|
2013-12-17 01:39:45 +00:00
|
|
|
#include "common/msg.h"
|
2014-04-13 12:01:55 +00:00
|
|
|
#include "common/tags.h"
|
2013-12-17 01:39:45 +00:00
|
|
|
#include "common/av_common.h"
|
2014-08-29 10:09:04 +00:00
|
|
|
#include "misc/bstr.h"
|
2015-12-16 22:54:25 +00:00
|
|
|
#include "misc/charset_conv.h"
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2007-03-15 18:36:36 +00:00
|
|
|
#include "stream/stream.h"
|
2012-11-09 00:06:43 +00:00
|
|
|
#include "demux.h"
|
2004-04-11 14:26:04 +00:00
|
|
|
#include "stheader.h"
|
2016-09-06 18:09:56 +00:00
|
|
|
#include "options/m_config.h"
|
2013-12-17 01:02:25 +00:00
|
|
|
#include "options/m_option.h"
|
2015-05-28 19:51:54 +00:00
|
|
|
#include "options/path.h"
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2014-07-05 14:57:56 +00:00
|
|
|
|
2010-03-22 19:38:42 +00:00
|
|
|
#define INITIAL_PROBE_SIZE STREAM_BUFFER_SIZE
|
2013-05-25 13:00:03 +00:00
|
|
|
#define PROBE_BUF_SIZE FFMIN(STREAM_MAX_BUFFER_SIZE, 2 * 1024 * 1024)
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2013-03-01 10:27:59 +00:00
|
|
|
|
2013-08-04 21:25:54 +00:00
|
|
|
// Should correspond to IO_BUFFER_SIZE in libavformat/aviobuf.c (not public)
|
|
|
|
// libavformat (almost) always reads data in blocks of this size.
|
|
|
|
#define BIO_BUFFER_SIZE 32768
|
|
|
|
|
2014-06-10 23:46:20 +00:00
|
|
|
#define OPT_BASE_STRUCT struct demux_lavf_opts
|
|
|
|
struct demux_lavf_opts {
|
|
|
|
int probesize;
|
|
|
|
int probescore;
|
|
|
|
float analyzeduration;
|
|
|
|
int buffersize;
|
|
|
|
int allow_mimetype;
|
|
|
|
char *format;
|
|
|
|
char *cryptokey;
|
2014-08-02 01:12:09 +00:00
|
|
|
char **avopts;
|
2015-04-17 20:03:25 +00:00
|
|
|
int hacks;
|
2014-06-10 23:46:20 +00:00
|
|
|
int genptsmode;
|
2016-09-06 18:09:56 +00:00
|
|
|
char *sub_cp;
|
|
|
|
int rtsp_transport;
|
2014-06-10 23:46:20 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const struct m_sub_options demux_lavf_conf = {
|
|
|
|
.opts = (const m_option_t[]) {
|
2016-09-06 18:09:56 +00:00
|
|
|
OPT_INTRANGE("demuxer-lavf-probesize", probesize, 0, 32, INT_MAX),
|
|
|
|
OPT_STRING("demuxer-lavf-format", format, 0),
|
|
|
|
OPT_FLOATRANGE("demuxer-lavf-analyzeduration", analyzeduration, 0,
|
|
|
|
0, 3600),
|
|
|
|
OPT_INTRANGE("demuxer-lavf-buffersize", buffersize, 0, 1,
|
|
|
|
10 * 1024 * 1024, OPTDEF_INT(BIO_BUFFER_SIZE)),
|
|
|
|
OPT_FLAG("demuxer-lavf-allow-mimetype", allow_mimetype, 0),
|
|
|
|
OPT_INTRANGE("demuxer-lavf-probescore", probescore, 0,
|
|
|
|
1, AVPROBE_SCORE_MAX),
|
|
|
|
OPT_STRING("demuxer-lavf-cryptokey", cryptokey, 0),
|
|
|
|
OPT_FLAG("demuxer-lavf-hacks", hacks, 0),
|
|
|
|
OPT_CHOICE("demuxer-lavf-genpts-mode", genptsmode, 0,
|
2014-06-10 23:46:20 +00:00
|
|
|
({"lavf", 1}, {"no", 0})),
|
2016-09-06 18:09:56 +00:00
|
|
|
OPT_KEYVALUELIST("demuxer-lavf-o", avopts, 0),
|
|
|
|
OPT_STRING("sub-codepage", sub_cp, 0),
|
|
|
|
OPT_CHOICE("rtsp-transport", rtsp_transport, 0,
|
|
|
|
({"lavf", 0},
|
|
|
|
{"udp", 1},
|
|
|
|
{"tcp", 2},
|
|
|
|
{"http", 3})),
|
2014-06-10 23:46:20 +00:00
|
|
|
{0}
|
|
|
|
},
|
|
|
|
.size = sizeof(struct demux_lavf_opts),
|
|
|
|
.defaults = &(const struct demux_lavf_opts){
|
|
|
|
.allow_mimetype = 1,
|
2015-04-17 20:03:25 +00:00
|
|
|
.hacks = 1,
|
2015-02-20 13:29:56 +00:00
|
|
|
// AVPROBE_SCORE_MAX/4 + 1 is the "recommended" limit. Below that, the
|
|
|
|
// user is supposed to retry with larger probe sizes until a higher
|
|
|
|
// value is reached.
|
|
|
|
.probescore = AVPROBE_SCORE_MAX/4 + 1,
|
2016-09-06 18:09:56 +00:00
|
|
|
.sub_cp = "auto",
|
|
|
|
.rtsp_transport = 2,
|
2014-06-10 23:46:20 +00:00
|
|
|
},
|
2006-08-30 22:25:40 +00:00
|
|
|
};
|
|
|
|
|
2013-05-27 21:26:22 +00:00
|
|
|
struct format_hack {
|
|
|
|
const char *ff_name;
|
|
|
|
const char *mime_type;
|
|
|
|
int probescore;
|
|
|
|
float analyzeduration;
|
2015-03-20 21:10:00 +00:00
|
|
|
unsigned int if_flags; // additional AVInputFormat.flags flags
|
2015-02-18 20:10:15 +00:00
|
|
|
bool max_probe : 1; // use probescore only if max. probe size reached
|
|
|
|
bool ignore : 1; // blacklisted
|
|
|
|
bool no_stream : 1; // do not wrap struct stream as AVIOContext
|
|
|
|
bool use_stream_ids : 1; // export the native stream IDs
|
2015-02-18 20:10:43 +00:00
|
|
|
bool fully_read : 1; // set demuxer.fully_read flag
|
2015-12-16 22:54:25 +00:00
|
|
|
bool detect_charset : 1; // format is a small text file, possibly not UTF8
|
2015-03-02 18:09:40 +00:00
|
|
|
bool image_format : 1; // expected to contain exactly 1 frame
|
2015-02-18 20:10:15 +00:00
|
|
|
// Do not confuse player's position estimation (position is into external
|
|
|
|
// segment, with e.g. HLS, player knows about the playlist main file only).
|
|
|
|
bool clear_filepos : 1;
|
2016-08-18 19:03:01 +00:00
|
|
|
bool ignore_start : 1;
|
2013-05-27 21:26:22 +00:00
|
|
|
};
|
|
|
|
|
2015-02-18 20:10:15 +00:00
|
|
|
#define BLACKLIST(fmt) {fmt, .ignore = true}
|
2015-12-16 22:54:25 +00:00
|
|
|
#define TEXTSUB(fmt) {fmt, .fully_read = true, .detect_charset = true}
|
|
|
|
#define TEXTSUB_UTF8(fmt) {fmt, .fully_read = true}
|
2015-02-18 20:10:15 +00:00
|
|
|
|
2013-05-27 21:26:22 +00:00
|
|
|
static const struct format_hack format_hacks[] = {
|
2014-01-25 21:57:52 +00:00
|
|
|
// for webradios
|
2013-05-27 21:26:22 +00:00
|
|
|
{"aac", "audio/aacp", 25, 0.5},
|
2013-06-24 22:55:20 +00:00
|
|
|
{"aac", "audio/aac", 25, 0.5},
|
2015-02-18 20:10:15 +00:00
|
|
|
|
|
|
|
// some mp3 files don't detect correctly (usually id3v2 too large)
|
2014-05-04 18:38:46 +00:00
|
|
|
{"mp3", "audio/mpeg", 24, 0.5},
|
2014-01-25 22:01:00 +00:00
|
|
|
{"mp3", NULL, 24, .max_probe = true},
|
2015-02-18 20:10:15 +00:00
|
|
|
|
|
|
|
{"hls", .no_stream = true, .clear_filepos = true},
|
|
|
|
{"mpeg", .use_stream_ids = true},
|
|
|
|
{"mpegts", .use_stream_ids = true},
|
|
|
|
|
2015-03-20 21:10:00 +00:00
|
|
|
// In theory, such streams might contain timestamps, but virtually none do.
|
|
|
|
{"h264", .if_flags = AVFMT_NOTIMESTAMPS },
|
|
|
|
{"hevc", .if_flags = AVFMT_NOTIMESTAMPS },
|
|
|
|
|
2016-08-18 19:03:01 +00:00
|
|
|
// Rebasing start time to 0 is very weird with ogg shoutcast streams.
|
|
|
|
{"ogg", .ignore_start = true},
|
|
|
|
|
2015-12-15 20:03:34 +00:00
|
|
|
TEXTSUB("aqtitle"), TEXTSUB("jacosub"), TEXTSUB("microdvd"),
|
2015-02-18 20:10:43 +00:00
|
|
|
TEXTSUB("mpl2"), TEXTSUB("mpsub"), TEXTSUB("pjs"), TEXTSUB("realtext"),
|
|
|
|
TEXTSUB("sami"), TEXTSUB("srt"), TEXTSUB("stl"), TEXTSUB("subviewer"),
|
2016-01-04 13:56:48 +00:00
|
|
|
TEXTSUB("subviewer1"), TEXTSUB("vplayer"), TEXTSUB("ass"),
|
2015-12-15 20:03:34 +00:00
|
|
|
|
|
|
|
TEXTSUB_UTF8("webvtt"),
|
|
|
|
|
2015-02-18 20:10:15 +00:00
|
|
|
// Useless non-sense, sometimes breaks MLP2 subreader.c fallback
|
|
|
|
BLACKLIST("tty"),
|
2015-02-18 20:11:49 +00:00
|
|
|
// Let's open files with extremely generic extensions (.bin) with a
|
|
|
|
// demuxer that doesn't have a probe function! NO.
|
|
|
|
BLACKLIST("bin"),
|
2015-03-02 18:09:40 +00:00
|
|
|
// Useless, does not work with custom streams.
|
|
|
|
BLACKLIST("image2"),
|
2016-12-04 12:18:48 +00:00
|
|
|
// Probably a security risk.
|
|
|
|
BLACKLIST("ffm"),
|
2015-03-02 18:09:40 +00:00
|
|
|
// Image demuxers ("<name>_pipe" is detected explicitly)
|
2015-12-17 00:00:54 +00:00
|
|
|
{"image2pipe", .image_format = true},
|
2012-12-10 00:28:20 +00:00
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
2015-02-18 20:10:15 +00:00
|
|
|
typedef struct lavf_priv {
|
2015-12-28 22:22:58 +00:00
|
|
|
struct stream *stream;
|
2016-08-26 11:05:14 +00:00
|
|
|
bool own_stream;
|
2015-02-18 20:10:15 +00:00
|
|
|
char *filename;
|
|
|
|
struct format_hack format_hack;
|
|
|
|
AVInputFormat *avif;
|
2015-03-20 21:10:00 +00:00
|
|
|
int avif_flags;
|
2015-02-18 20:10:15 +00:00
|
|
|
AVFormatContext *avfc;
|
2017-01-30 18:38:43 +00:00
|
|
|
bstr init_fragment;
|
|
|
|
int64_t stream_pos;
|
2015-02-18 20:10:15 +00:00
|
|
|
AVIOContext *pb;
|
|
|
|
struct sh_stream **streams; // NULL for unknown streams
|
|
|
|
int num_streams;
|
|
|
|
int cur_program;
|
|
|
|
char *mime_type;
|
2016-02-22 19:21:03 +00:00
|
|
|
double seek_delay;
|
2016-09-06 18:09:56 +00:00
|
|
|
|
|
|
|
struct demux_lavf_opts *opts;
|
|
|
|
double mf_fps;
|
2015-02-18 20:10:15 +00:00
|
|
|
} lavf_priv_t;
|
|
|
|
|
|
|
|
// At least mp4 has name="mov,mp4,m4a,3gp,3g2,mj2", so we split the name
|
|
|
|
// on "," in general.
|
|
|
|
static bool matches_avinputformat_name(struct lavf_priv *priv,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
const char *avifname = priv->avif->name;
|
|
|
|
while (1) {
|
|
|
|
const char *next = strchr(avifname, ',');
|
|
|
|
if (!next)
|
|
|
|
return !strcmp(avifname, name);
|
|
|
|
int len = next - avifname;
|
|
|
|
if (len == strlen(name) && !memcmp(avifname, name, len))
|
|
|
|
return true;
|
|
|
|
avifname = next + 1;
|
|
|
|
}
|
|
|
|
}
|
2013-08-07 21:15:11 +00:00
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
static int mp_read(void *opaque, uint8_t *buf, int size)
|
|
|
|
{
|
2010-04-23 20:50:34 +00:00
|
|
|
struct demuxer *demuxer = opaque;
|
2015-12-28 22:22:58 +00:00
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
|
|
|
struct stream *stream = priv->stream;
|
2004-04-11 14:51:10 +00:00
|
|
|
int ret;
|
|
|
|
|
2017-01-30 18:38:43 +00:00
|
|
|
if (priv->stream_pos < priv->init_fragment.len) {
|
|
|
|
ret = MPMIN(size, priv->init_fragment.len - priv->stream_pos);
|
|
|
|
memcpy(buf, priv->init_fragment.start + priv->stream_pos, ret);
|
|
|
|
priv->stream_pos += ret;
|
|
|
|
} else {
|
|
|
|
ret = stream_read(stream, buf, size);
|
|
|
|
priv->stream_pos = priv->init_fragment.len + stream_tell(stream);
|
|
|
|
}
|
2004-04-11 15:04:54 +00:00
|
|
|
|
2014-07-05 14:42:50 +00:00
|
|
|
MP_TRACE(demuxer, "%d=mp_read(%p, %p, %d), pos: %"PRId64", eof:%d\n",
|
|
|
|
ret, stream, buf, size, stream_tell(stream), stream->eof);
|
2004-04-11 14:51:10 +00:00
|
|
|
return ret;
|
2004-04-11 14:26:04 +00:00
|
|
|
}
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
static int64_t mp_seek(void *opaque, int64_t pos, int whence)
|
|
|
|
{
|
2010-04-23 20:50:34 +00:00
|
|
|
struct demuxer *demuxer = opaque;
|
2015-12-28 22:22:58 +00:00
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
|
|
|
struct stream *stream = priv->stream;
|
2017-01-30 18:38:43 +00:00
|
|
|
|
2015-12-21 21:19:57 +00:00
|
|
|
MP_TRACE(demuxer, "mp_seek(%p, %"PRId64", %s)\n", stream, pos,
|
|
|
|
whence == SEEK_END ? "end" :
|
|
|
|
whence == SEEK_CUR ? "cur" :
|
|
|
|
whence == SEEK_SET ? "set" : "size");
|
2014-05-24 12:04:09 +00:00
|
|
|
if (whence == SEEK_END || whence == AVSEEK_SIZE) {
|
2017-01-30 18:38:43 +00:00
|
|
|
int64_t end = stream_get_size(stream) + priv->init_fragment.len;
|
2015-08-17 22:10:54 +00:00
|
|
|
if (end < 0)
|
2014-05-24 12:04:09 +00:00
|
|
|
return -1;
|
|
|
|
if (whence == AVSEEK_SIZE)
|
|
|
|
return end;
|
|
|
|
pos += end;
|
|
|
|
} else if (whence == SEEK_CUR) {
|
2017-01-30 18:38:43 +00:00
|
|
|
pos += priv->stream_pos;
|
2014-05-24 12:04:09 +00:00
|
|
|
} else if (whence != SEEK_SET) {
|
2004-04-11 14:26:04 +00:00
|
|
|
return -1;
|
2014-05-24 12:04:09 +00:00
|
|
|
}
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
if (pos < 0)
|
2007-08-19 21:22:27 +00:00
|
|
|
return -1;
|
2017-01-30 18:38:43 +00:00
|
|
|
|
|
|
|
int64_t stream_target = pos - priv->init_fragment.len;
|
|
|
|
bool seek_before = stream_target < 0;
|
|
|
|
if (seek_before)
|
|
|
|
stream_target = 0; // within init segment - seek real stream to 0
|
|
|
|
|
|
|
|
int64_t current_pos = stream_tell(stream);
|
|
|
|
if (stream_seek(stream, stream_target) == 0) {
|
2008-08-13 00:01:31 +00:00
|
|
|
stream_seek(stream, current_pos);
|
2004-04-11 14:26:04 +00:00
|
|
|
return -1;
|
2008-08-13 00:01:31 +00:00
|
|
|
}
|
2004-04-11 15:04:54 +00:00
|
|
|
|
2017-01-30 18:38:43 +00:00
|
|
|
if (seek_before) {
|
|
|
|
priv->stream_pos = pos;
|
|
|
|
} else {
|
|
|
|
priv->stream_pos = priv->init_fragment.len + stream_tell(stream);
|
|
|
|
}
|
|
|
|
|
2014-05-24 12:03:07 +00:00
|
|
|
return pos;
|
2004-04-11 14:26:04 +00:00
|
|
|
}
|
|
|
|
|
2010-04-23 20:50:34 +00:00
|
|
|
static int64_t mp_read_seek(void *opaque, int stream_idx, int64_t ts, int flags)
|
|
|
|
{
|
|
|
|
struct demuxer *demuxer = opaque;
|
2015-12-28 22:22:58 +00:00
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
|
|
|
struct stream *stream = priv->stream;
|
2010-04-23 20:50:34 +00:00
|
|
|
|
2014-07-30 00:21:35 +00:00
|
|
|
struct stream_avseek cmd = {
|
|
|
|
.stream_index = stream_idx,
|
|
|
|
.timestamp = ts,
|
|
|
|
.flags = flags,
|
|
|
|
};
|
|
|
|
|
2014-10-30 21:50:44 +00:00
|
|
|
if (stream_control(stream, STREAM_CTRL_AVSEEK, &cmd) == STREAM_OK) {
|
|
|
|
stream_drop_buffers(stream);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return AVERROR(ENOSYS);
|
2010-04-23 20:50:34 +00:00
|
|
|
}
|
|
|
|
|
2013-12-21 19:24:20 +00:00
|
|
|
static void list_formats(struct demuxer *demuxer)
|
2011-07-03 12:42:04 +00:00
|
|
|
{
|
2013-12-21 19:24:20 +00:00
|
|
|
MP_INFO(demuxer, "Available lavf input formats:\n");
|
2010-11-06 02:00:10 +00:00
|
|
|
AVInputFormat *fmt = NULL;
|
2011-07-07 21:41:42 +00:00
|
|
|
while ((fmt = av_iformat_next(fmt)))
|
2013-12-21 19:24:20 +00:00
|
|
|
MP_INFO(demuxer, "%15s : %s\n", fmt->name, fmt->long_name);
|
2007-02-06 22:15:20 +00:00
|
|
|
}
|
|
|
|
|
2015-12-28 22:23:30 +00:00
|
|
|
static void convert_charset(struct demuxer *demuxer)
|
2015-12-16 22:54:25 +00:00
|
|
|
{
|
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
2016-09-06 18:09:56 +00:00
|
|
|
char *cp = priv->opts->sub_cp;
|
2015-12-28 22:23:30 +00:00
|
|
|
if (!cp || mp_charset_is_utf8(cp))
|
|
|
|
return;
|
|
|
|
bstr data = stream_read_complete(priv->stream, NULL, 128 * 1024 * 1024);
|
|
|
|
if (!data.start) {
|
|
|
|
MP_WARN(demuxer, "File too big (or error reading) - skip charset probing.\n");
|
|
|
|
return;
|
2015-12-16 22:54:25 +00:00
|
|
|
}
|
2016-01-12 22:50:01 +00:00
|
|
|
void *alloc = data.start;
|
2015-12-28 22:23:30 +00:00
|
|
|
cp = (char *)mp_charset_guess(priv, demuxer->log, data, cp, 0);
|
2015-12-16 22:54:25 +00:00
|
|
|
if (cp && !mp_charset_is_utf8(cp))
|
|
|
|
MP_INFO(demuxer, "Using subtitle charset: %s\n", cp);
|
|
|
|
// libavformat transparently converts UTF-16 to UTF-8
|
2016-01-12 22:50:01 +00:00
|
|
|
if (!mp_charset_is_utf16(cp) && !mp_charset_is_utf8(cp)) {
|
2015-12-28 22:23:30 +00:00
|
|
|
bstr conv = mp_iconv_to_utf8(demuxer->log, data, cp, MP_ICONV_VERBOSE);
|
2016-01-18 10:46:28 +00:00
|
|
|
if (conv.start && conv.start != data.start)
|
|
|
|
talloc_steal(alloc, conv.start);
|
2015-12-28 22:23:30 +00:00
|
|
|
if (conv.start)
|
2016-01-12 22:50:01 +00:00
|
|
|
data = conv;
|
2015-12-28 22:23:30 +00:00
|
|
|
}
|
2016-08-26 11:05:14 +00:00
|
|
|
if (data.start) {
|
2016-01-12 22:50:01 +00:00
|
|
|
priv->stream = open_memory_stream(data.start, data.len);
|
2016-08-26 11:05:14 +00:00
|
|
|
priv->own_stream = true;
|
|
|
|
}
|
2016-01-12 22:50:01 +00:00
|
|
|
talloc_free(alloc);
|
2015-12-16 22:54:25 +00:00
|
|
|
}
|
|
|
|
|
2014-06-10 21:56:05 +00:00
|
|
|
static char *remove_prefix(char *s, const char *const *prefixes)
|
demux_lavf: add support for libavdevice
libavdevice supports various "special" video and audio inputs, such
as screen-capture or libavfilter filter graphs.
libavdevice inputs are implemented as demuxers. They don't use the
custom stream callbacks (in AVFormatContext.pb). Instead, input
parameters are passed as filename. This means the mpv stream layer has
to be disabled. Do this by adding the pseudo stream handler avdevice://,
whose only purpose is passing the filename to demux_lavf, without
actually doing anything.
Change the logic how the filename is passed to libavformat. Remove
handling of the filename from demux_open_lavf() and move it to
lavf_check_file(). (This also fixes a possible bug when skipping the
"lavf://" prefix.)
libavdevice now can be invoked by specifying demuxer and args as in:
mpv avdevice://demuxer:args
The args are passed as filename to libavformat. When using libavdevice
demuxers, their actual meaning is highly implementation specific. They
don't refer to actual filenames.
Note:
libavdevice is disabled by default. There is one problem: libavdevice
pulls in libavfilter, which in turn causes symbol clashes with mpv
internals. The problem is that libavfilter includes a mplayer filter
bridge, which is used to interface with a set of nearly unmodified
mplayer filters copied into libavfilter. This filter bridge uses the
same symbol names as mplayer/mpv's filter chain, which results in symbol
clashes at link-time.
This can be prevented by building ffmpeg with --disable-filter=mp, but
unfortunately this is not the default.
This means linking to libavdevice (which in turn forces linking with
libavfilter by default) must be disabled. We try doing this by compiling
a test file that defines one of the clashing symbols (vf_mpi_clear).
To enable libavdevice input, ffmpeg should be built with the options:
--disable-filter=mp
and mpv with:
--enable-libavdevice
Originally, I tried to auto-detect it. But the resulting complications
in configure did't seem worth the trouble.
2012-11-30 17:41:04 +00:00
|
|
|
{
|
|
|
|
for (int n = 0; prefixes[n]; n++) {
|
|
|
|
int len = strlen(prefixes[n]);
|
|
|
|
if (strncmp(s, prefixes[n], len) == 0)
|
|
|
|
return s + len;
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2014-06-10 21:56:05 +00:00
|
|
|
static const char *const prefixes[] =
|
demux_lavf: add support for libavdevice
libavdevice supports various "special" video and audio inputs, such
as screen-capture or libavfilter filter graphs.
libavdevice inputs are implemented as demuxers. They don't use the
custom stream callbacks (in AVFormatContext.pb). Instead, input
parameters are passed as filename. This means the mpv stream layer has
to be disabled. Do this by adding the pseudo stream handler avdevice://,
whose only purpose is passing the filename to demux_lavf, without
actually doing anything.
Change the logic how the filename is passed to libavformat. Remove
handling of the filename from demux_open_lavf() and move it to
lavf_check_file(). (This also fixes a possible bug when skipping the
"lavf://" prefix.)
libavdevice now can be invoked by specifying demuxer and args as in:
mpv avdevice://demuxer:args
The args are passed as filename to libavformat. When using libavdevice
demuxers, their actual meaning is highly implementation specific. They
don't refer to actual filenames.
Note:
libavdevice is disabled by default. There is one problem: libavdevice
pulls in libavfilter, which in turn causes symbol clashes with mpv
internals. The problem is that libavfilter includes a mplayer filter
bridge, which is used to interface with a set of nearly unmodified
mplayer filters copied into libavfilter. This filter bridge uses the
same symbol names as mplayer/mpv's filter chain, which results in symbol
clashes at link-time.
This can be prevented by building ffmpeg with --disable-filter=mp, but
unfortunately this is not the default.
This means linking to libavdevice (which in turn forces linking with
libavfilter by default) must be disabled. We try doing this by compiling
a test file that defines one of the clashing symbols (vf_mpi_clear).
To enable libavdevice input, ffmpeg should be built with the options:
--disable-filter=mp
and mpv with:
--enable-libavdevice
Originally, I tried to auto-detect it. But the resulting complications
in configure did't seem worth the trouble.
2012-11-30 17:41:04 +00:00
|
|
|
{"ffmpeg://", "lavf://", "avdevice://", "av://", NULL};
|
|
|
|
|
2013-07-12 19:58:11 +00:00
|
|
|
static int lavf_check_file(demuxer_t *demuxer, enum demux_check check)
|
2011-07-03 12:42:04 +00:00
|
|
|
{
|
2015-12-17 00:00:54 +00:00
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
2016-09-06 18:09:56 +00:00
|
|
|
struct demux_lavf_opts *lavfdopts = priv->opts;
|
2015-12-28 22:22:58 +00:00
|
|
|
struct stream *s = priv->stream;
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2015-04-25 18:42:02 +00:00
|
|
|
priv->filename = remove_prefix(s->url, prefixes);
|
demux_lavf: add support for libavdevice
libavdevice supports various "special" video and audio inputs, such
as screen-capture or libavfilter filter graphs.
libavdevice inputs are implemented as demuxers. They don't use the
custom stream callbacks (in AVFormatContext.pb). Instead, input
parameters are passed as filename. This means the mpv stream layer has
to be disabled. Do this by adding the pseudo stream handler avdevice://,
whose only purpose is passing the filename to demux_lavf, without
actually doing anything.
Change the logic how the filename is passed to libavformat. Remove
handling of the filename from demux_open_lavf() and move it to
lavf_check_file(). (This also fixes a possible bug when skipping the
"lavf://" prefix.)
libavdevice now can be invoked by specifying demuxer and args as in:
mpv avdevice://demuxer:args
The args are passed as filename to libavformat. When using libavdevice
demuxers, their actual meaning is highly implementation specific. They
don't refer to actual filenames.
Note:
libavdevice is disabled by default. There is one problem: libavdevice
pulls in libavfilter, which in turn causes symbol clashes with mpv
internals. The problem is that libavfilter includes a mplayer filter
bridge, which is used to interface with a set of nearly unmodified
mplayer filters copied into libavfilter. This filter bridge uses the
same symbol names as mplayer/mpv's filter chain, which results in symbol
clashes at link-time.
This can be prevented by building ffmpeg with --disable-filter=mp, but
unfortunately this is not the default.
This means linking to libavdevice (which in turn forces linking with
libavfilter by default) must be disabled. We try doing this by compiling
a test file that defines one of the clashing symbols (vf_mpi_clear).
To enable libavdevice input, ffmpeg should be built with the options:
--disable-filter=mp
and mpv with:
--enable-libavdevice
Originally, I tried to auto-detect it. But the resulting complications
in configure did't seem worth the trouble.
2012-11-30 17:41:04 +00:00
|
|
|
|
|
|
|
char *avdevice_format = NULL;
|
2017-02-02 17:24:27 +00:00
|
|
|
if (s->info && strcmp(s->info->name, "avdevice") == 0) {
|
demux_lavf: add support for libavdevice
libavdevice supports various "special" video and audio inputs, such
as screen-capture or libavfilter filter graphs.
libavdevice inputs are implemented as demuxers. They don't use the
custom stream callbacks (in AVFormatContext.pb). Instead, input
parameters are passed as filename. This means the mpv stream layer has
to be disabled. Do this by adding the pseudo stream handler avdevice://,
whose only purpose is passing the filename to demux_lavf, without
actually doing anything.
Change the logic how the filename is passed to libavformat. Remove
handling of the filename from demux_open_lavf() and move it to
lavf_check_file(). (This also fixes a possible bug when skipping the
"lavf://" prefix.)
libavdevice now can be invoked by specifying demuxer and args as in:
mpv avdevice://demuxer:args
The args are passed as filename to libavformat. When using libavdevice
demuxers, their actual meaning is highly implementation specific. They
don't refer to actual filenames.
Note:
libavdevice is disabled by default. There is one problem: libavdevice
pulls in libavfilter, which in turn causes symbol clashes with mpv
internals. The problem is that libavfilter includes a mplayer filter
bridge, which is used to interface with a set of nearly unmodified
mplayer filters copied into libavfilter. This filter bridge uses the
same symbol names as mplayer/mpv's filter chain, which results in symbol
clashes at link-time.
This can be prevented by building ffmpeg with --disable-filter=mp, but
unfortunately this is not the default.
This means linking to libavdevice (which in turn forces linking with
libavfilter by default) must be disabled. We try doing this by compiling
a test file that defines one of the clashing symbols (vf_mpi_clear).
To enable libavdevice input, ffmpeg should be built with the options:
--disable-filter=mp
and mpv with:
--enable-libavdevice
Originally, I tried to auto-detect it. But the resulting complications
in configure did't seem worth the trouble.
2012-11-30 17:41:04 +00:00
|
|
|
// always require filename in the form "format:filename"
|
|
|
|
char *sep = strchr(priv->filename, ':');
|
|
|
|
if (!sep) {
|
2013-12-21 19:24:20 +00:00
|
|
|
MP_FATAL(demuxer, "Must specify filename in 'format:filename' form\n");
|
2013-07-11 18:08:12 +00:00
|
|
|
return -1;
|
demux_lavf: add support for libavdevice
libavdevice supports various "special" video and audio inputs, such
as screen-capture or libavfilter filter graphs.
libavdevice inputs are implemented as demuxers. They don't use the
custom stream callbacks (in AVFormatContext.pb). Instead, input
parameters are passed as filename. This means the mpv stream layer has
to be disabled. Do this by adding the pseudo stream handler avdevice://,
whose only purpose is passing the filename to demux_lavf, without
actually doing anything.
Change the logic how the filename is passed to libavformat. Remove
handling of the filename from demux_open_lavf() and move it to
lavf_check_file(). (This also fixes a possible bug when skipping the
"lavf://" prefix.)
libavdevice now can be invoked by specifying demuxer and args as in:
mpv avdevice://demuxer:args
The args are passed as filename to libavformat. When using libavdevice
demuxers, their actual meaning is highly implementation specific. They
don't refer to actual filenames.
Note:
libavdevice is disabled by default. There is one problem: libavdevice
pulls in libavfilter, which in turn causes symbol clashes with mpv
internals. The problem is that libavfilter includes a mplayer filter
bridge, which is used to interface with a set of nearly unmodified
mplayer filters copied into libavfilter. This filter bridge uses the
same symbol names as mplayer/mpv's filter chain, which results in symbol
clashes at link-time.
This can be prevented by building ffmpeg with --disable-filter=mp, but
unfortunately this is not the default.
This means linking to libavdevice (which in turn forces linking with
libavfilter by default) must be disabled. We try doing this by compiling
a test file that defines one of the clashing symbols (vf_mpi_clear).
To enable libavdevice input, ffmpeg should be built with the options:
--disable-filter=mp
and mpv with:
--enable-libavdevice
Originally, I tried to auto-detect it. But the resulting complications
in configure did't seem worth the trouble.
2012-11-30 17:41:04 +00:00
|
|
|
}
|
|
|
|
avdevice_format = talloc_strndup(priv, priv->filename,
|
|
|
|
sep - priv->filename);
|
|
|
|
priv->filename = sep + 1;
|
|
|
|
}
|
|
|
|
|
2015-12-28 22:22:58 +00:00
|
|
|
char *mime_type = s->mime_type;
|
2014-01-25 21:57:52 +00:00
|
|
|
if (!lavfdopts->allow_mimetype || !mime_type)
|
|
|
|
mime_type = "";
|
2013-05-27 21:26:22 +00:00
|
|
|
|
2015-02-20 13:29:56 +00:00
|
|
|
AVInputFormat *forced_format = NULL;
|
2013-05-27 21:26:22 +00:00
|
|
|
const char *format = lavfdopts->format;
|
2010-04-23 19:57:25 +00:00
|
|
|
if (!format)
|
2013-05-25 13:00:03 +00:00
|
|
|
format = s->lavf_type;
|
demux_lavf: add support for libavdevice
libavdevice supports various "special" video and audio inputs, such
as screen-capture or libavfilter filter graphs.
libavdevice inputs are implemented as demuxers. They don't use the
custom stream callbacks (in AVFormatContext.pb). Instead, input
parameters are passed as filename. This means the mpv stream layer has
to be disabled. Do this by adding the pseudo stream handler avdevice://,
whose only purpose is passing the filename to demux_lavf, without
actually doing anything.
Change the logic how the filename is passed to libavformat. Remove
handling of the filename from demux_open_lavf() and move it to
lavf_check_file(). (This also fixes a possible bug when skipping the
"lavf://" prefix.)
libavdevice now can be invoked by specifying demuxer and args as in:
mpv avdevice://demuxer:args
The args are passed as filename to libavformat. When using libavdevice
demuxers, their actual meaning is highly implementation specific. They
don't refer to actual filenames.
Note:
libavdevice is disabled by default. There is one problem: libavdevice
pulls in libavfilter, which in turn causes symbol clashes with mpv
internals. The problem is that libavfilter includes a mplayer filter
bridge, which is used to interface with a set of nearly unmodified
mplayer filters copied into libavfilter. This filter bridge uses the
same symbol names as mplayer/mpv's filter chain, which results in symbol
clashes at link-time.
This can be prevented by building ffmpeg with --disable-filter=mp, but
unfortunately this is not the default.
This means linking to libavdevice (which in turn forces linking with
libavfilter by default) must be disabled. We try doing this by compiling
a test file that defines one of the clashing symbols (vf_mpi_clear).
To enable libavdevice input, ffmpeg should be built with the options:
--disable-filter=mp
and mpv with:
--enable-libavdevice
Originally, I tried to auto-detect it. But the resulting complications
in configure did't seem worth the trouble.
2012-11-30 17:41:04 +00:00
|
|
|
if (!format)
|
|
|
|
format = avdevice_format;
|
2010-04-23 19:57:25 +00:00
|
|
|
if (format) {
|
|
|
|
if (strcmp(format, "help") == 0) {
|
2013-12-21 19:24:20 +00:00
|
|
|
list_formats(demuxer);
|
2013-07-11 18:08:12 +00:00
|
|
|
return -1;
|
2007-02-06 22:15:20 +00:00
|
|
|
}
|
2015-02-20 13:29:56 +00:00
|
|
|
forced_format = av_find_input_format(format);
|
|
|
|
if (!forced_format) {
|
2013-12-21 19:24:20 +00:00
|
|
|
MP_FATAL(demuxer, "Unknown lavf format %s\n", format);
|
2013-07-11 18:08:12 +00:00
|
|
|
return -1;
|
2007-02-06 22:15:20 +00:00
|
|
|
}
|
|
|
|
}
|
2009-06-01 09:39:02 +00:00
|
|
|
|
2013-05-25 13:00:03 +00:00
|
|
|
AVProbeData avpd = {
|
2013-07-12 19:58:11 +00:00
|
|
|
// Disable file-extension matching with normal checks
|
2014-01-31 00:36:09 +00:00
|
|
|
.filename = check <= DEMUX_CHECK_REQUEST ? priv->filename : "",
|
2013-05-25 13:00:03 +00:00
|
|
|
.buf_size = 0,
|
2017-02-08 14:08:49 +00:00
|
|
|
.buf = av_mallocz(PROBE_BUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE),
|
2013-05-25 13:00:03 +00:00
|
|
|
};
|
2014-12-12 16:28:22 +00:00
|
|
|
if (!avpd.buf)
|
|
|
|
return -1;
|
2013-05-25 13:00:03 +00:00
|
|
|
|
2014-01-25 21:57:52 +00:00
|
|
|
bool final_probe = false;
|
|
|
|
do {
|
2013-05-25 13:00:03 +00:00
|
|
|
int score = 0;
|
2015-02-20 13:29:56 +00:00
|
|
|
|
|
|
|
if (forced_format) {
|
|
|
|
priv->avif = forced_format;
|
|
|
|
score = AVPROBE_SCORE_MAX;
|
|
|
|
} else {
|
|
|
|
int nsize = av_clip(avpd.buf_size * 2, INITIAL_PROBE_SIZE,
|
|
|
|
PROBE_BUF_SIZE);
|
|
|
|
bstr buf = stream_peek(s, nsize);
|
|
|
|
if (buf.len <= avpd.buf_size)
|
|
|
|
final_probe = true;
|
|
|
|
memcpy(avpd.buf, buf.start, buf.len);
|
|
|
|
avpd.buf_size = buf.len;
|
|
|
|
|
|
|
|
priv->avif = av_probe_input_format2(&avpd, avpd.buf_size > 0, &score);
|
|
|
|
}
|
2012-12-08 19:14:13 +00:00
|
|
|
|
|
|
|
if (priv->avif) {
|
2015-02-20 13:29:56 +00:00
|
|
|
MP_VERBOSE(demuxer, "Found '%s' at score=%d size=%d%s.\n",
|
|
|
|
priv->avif->name, score, avpd.buf_size,
|
|
|
|
forced_format ? " (forced)" : "");
|
2014-01-25 21:57:52 +00:00
|
|
|
|
|
|
|
for (int n = 0; format_hacks[n].ff_name; n++) {
|
|
|
|
const struct format_hack *entry = &format_hacks[n];
|
2015-04-17 20:03:25 +00:00
|
|
|
if (!lavfdopts->hacks)
|
|
|
|
continue;
|
2015-02-18 20:10:15 +00:00
|
|
|
if (!matches_avinputformat_name(priv, entry->ff_name))
|
2014-01-25 21:57:52 +00:00
|
|
|
continue;
|
|
|
|
if (entry->mime_type && strcasecmp(entry->mime_type, mime_type) != 0)
|
|
|
|
continue;
|
2015-02-18 20:10:15 +00:00
|
|
|
priv->format_hack = *entry;
|
2014-01-25 21:57:52 +00:00
|
|
|
break;
|
|
|
|
}
|
2012-12-08 19:14:13 +00:00
|
|
|
|
2015-02-20 13:29:56 +00:00
|
|
|
if (score >= lavfdopts->probescore)
|
2013-05-27 21:26:22 +00:00
|
|
|
break;
|
2013-05-25 13:00:03 +00:00
|
|
|
|
2015-02-18 20:10:15 +00:00
|
|
|
if (priv->format_hack.probescore &&
|
|
|
|
score >= priv->format_hack.probescore &&
|
|
|
|
(!priv->format_hack.max_probe || final_probe))
|
|
|
|
break;
|
2013-05-27 21:26:22 +00:00
|
|
|
}
|
2012-12-08 19:14:13 +00:00
|
|
|
|
|
|
|
priv->avif = NULL;
|
2015-02-18 20:10:15 +00:00
|
|
|
priv->format_hack = (struct format_hack){0};
|
2014-01-25 21:57:52 +00:00
|
|
|
} while (!final_probe);
|
2013-05-25 13:00:03 +00:00
|
|
|
|
2010-02-12 20:38:29 +00:00
|
|
|
av_free(avpd.buf);
|
|
|
|
|
2015-02-20 13:29:56 +00:00
|
|
|
if (priv->avif && !forced_format && priv->format_hack.ignore) {
|
2015-02-18 20:10:15 +00:00
|
|
|
MP_VERBOSE(demuxer, "Format blacklisted.\n");
|
|
|
|
priv->avif = NULL;
|
2013-08-07 21:15:11 +00:00
|
|
|
}
|
|
|
|
|
2012-12-08 19:14:13 +00:00
|
|
|
if (!priv->avif) {
|
2013-12-21 19:24:20 +00:00
|
|
|
MP_VERBOSE(demuxer, "No format found, try lowering probescore or forcing the format.\n");
|
2013-07-11 18:08:12 +00:00
|
|
|
return -1;
|
2012-12-08 19:14:13 +00:00
|
|
|
}
|
|
|
|
|
2015-03-02 18:09:40 +00:00
|
|
|
if (bstr_endswith0(bstr0(priv->avif->name), "_pipe")) {
|
|
|
|
MP_VERBOSE(demuxer, "Assuming this is an image format.\n");
|
|
|
|
priv->format_hack.image_format = true;
|
|
|
|
}
|
|
|
|
|
2015-03-20 21:10:00 +00:00
|
|
|
priv->avif_flags = priv->avif->flags | priv->format_hack.if_flags;
|
|
|
|
|
2015-01-23 14:59:06 +00:00
|
|
|
demuxer->filetype = priv->avif->name;
|
2010-11-10 13:38:36 +00:00
|
|
|
|
2015-12-16 22:54:25 +00:00
|
|
|
if (priv->format_hack.detect_charset)
|
2015-12-28 22:23:30 +00:00
|
|
|
convert_charset(demuxer);
|
2015-12-16 22:54:25 +00:00
|
|
|
|
2013-07-11 18:08:12 +00:00
|
|
|
return 0;
|
2004-04-11 14:26:04 +00:00
|
|
|
}
|
2007-04-14 10:03:42 +00:00
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
static uint8_t char2int(char c)
|
|
|
|
{
|
2007-10-14 12:11:28 +00:00
|
|
|
if (c >= '0' && c <= '9') return c - '0';
|
|
|
|
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
|
|
|
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
static void parse_cryptokey(AVFormatContext *avfc, const char *str)
|
|
|
|
{
|
2007-10-14 12:11:28 +00:00
|
|
|
int len = strlen(str) / 2;
|
|
|
|
uint8_t *key = av_mallocz(len);
|
|
|
|
int i;
|
|
|
|
avfc->keylen = len;
|
|
|
|
avfc->key = key;
|
|
|
|
for (i = 0; i < len; i++, str += 2)
|
|
|
|
*key++ = (char2int(str[0]) << 4) | char2int(str[1]);
|
|
|
|
}
|
|
|
|
|
2015-05-28 19:51:54 +00:00
|
|
|
static char *replace_idx_ext(void *ta_ctx, bstr f)
|
|
|
|
{
|
|
|
|
if (f.len < 4 || f.start[f.len - 4] != '.')
|
|
|
|
return NULL;
|
|
|
|
char *ext = bstr_endswith0(f, "IDX") ? "SUB" : "sub"; // match case
|
2015-06-02 19:25:51 +00:00
|
|
|
return talloc_asprintf(ta_ctx, "%.*s.%s", BSTR_P(bstr_splice(f, 0, -4)), ext);
|
2015-05-28 19:51:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void guess_and_set_vobsub_name(struct demuxer *demuxer, AVDictionary **d)
|
|
|
|
{
|
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
|
|
|
if (!matches_avinputformat_name(priv, "vobsub"))
|
|
|
|
return;
|
|
|
|
|
|
|
|
void *tmp = talloc_new(NULL);
|
|
|
|
bstr bfilename = bstr0(priv->filename);
|
|
|
|
char *subname = NULL;
|
|
|
|
if (mp_is_url(bfilename)) {
|
|
|
|
// It might be a http URL, which has additional parameters after the
|
|
|
|
// end of the actual file path.
|
|
|
|
bstr start, end;
|
|
|
|
if (bstr_split_tok(bfilename, "?", &start, &end)) {
|
|
|
|
subname = replace_idx_ext(tmp, start);
|
|
|
|
if (subname)
|
|
|
|
subname = talloc_asprintf(tmp, "%s?%.*s", subname, BSTR_P(end));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!subname)
|
|
|
|
subname = replace_idx_ext(tmp, bfilename);
|
|
|
|
if (!subname)
|
|
|
|
subname = talloc_asprintf(tmp, "%.*s.sub", BSTR_P(bfilename));
|
|
|
|
|
|
|
|
MP_VERBOSE(demuxer, "Assuming associated .sub file: %s\n", subname);
|
|
|
|
av_dict_set(d, "sub_name", subname, 0);
|
|
|
|
talloc_free(tmp);
|
|
|
|
}
|
|
|
|
|
2013-07-11 17:23:31 +00:00
|
|
|
static void select_tracks(struct demuxer *demuxer, int start)
|
|
|
|
{
|
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
|
|
|
for (int n = start; n < priv->num_streams; n++) {
|
|
|
|
struct sh_stream *stream = priv->streams[n];
|
|
|
|
AVStream *st = priv->avfc->streams[n];
|
2014-07-06 17:02:21 +00:00
|
|
|
bool selected = stream && demux_stream_is_selected(stream) &&
|
core: completely change handling of attached picture pseudo video
Before this commit, we tried to play along with libavformat and tried
to pretend that attached pictures are video streams with a single
frame, and that the frame magically appeared at the seek position when
seeking. The playback core would then switch to a mode where the video
has ended, and the "remaining" audio is played.
This didn't work very well:
- we needed a hack in demux.c, because we tried to read more packets in
order to find the "next" video frame (libavformat doesn't tell us if
a stream has ended)
- switching the video stream didn't work, because we can't tell
libavformat to send the packet again
- seeking and resuming after was hacky (for some reason libavformat sets
the returned packet's PTS to that of the previously returned audio
packet in generic code not related to attached pictures, and this
happened to work)
- if the user did something stupid and e.g. inserted a deinterlacer by
default, a picture was never displayed, only an inactive VO window)
- same when using a command that reconfigured the VO (like switching
aspect or video filters)
- hr-seek didn't work
For this reason, handle attached pictures as separate case with a
separate video decoding function, which doesn't read packets. Also,
do not synchronize audio to video start in this case.
2013-07-11 17:23:56 +00:00
|
|
|
!stream->attached_picture;
|
2013-07-11 17:23:31 +00:00
|
|
|
st->discard = selected ? AVDISCARD_DEFAULT : AVDISCARD_ALL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-12 19:39:32 +00:00
|
|
|
static void export_replaygain(demuxer_t *demuxer, struct sh_stream *sh,
|
2016-01-12 22:48:19 +00:00
|
|
|
AVStream *st)
|
2014-03-25 10:46:10 +00:00
|
|
|
{
|
|
|
|
for (int i = 0; i < st->nb_side_data; i++) {
|
|
|
|
AVReplayGain *av_rgain;
|
|
|
|
struct replaygain_data *rgain;
|
|
|
|
AVPacketSideData *src_sd = &st->side_data[i];
|
|
|
|
|
|
|
|
if (src_sd->type != AV_PKT_DATA_REPLAYGAIN)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
av_rgain = (AVReplayGain*)src_sd->data;
|
|
|
|
rgain = talloc_ptrtype(demuxer, rgain);
|
|
|
|
|
|
|
|
rgain->track_gain = (av_rgain->track_gain != INT32_MIN) ?
|
|
|
|
av_rgain->track_gain / 100000.0f : 0.0;
|
|
|
|
|
|
|
|
rgain->track_peak = (av_rgain->track_peak != 0.0) ?
|
|
|
|
av_rgain->track_peak / 100000.0f : 1.0;
|
|
|
|
|
|
|
|
rgain->album_gain = (av_rgain->album_gain != INT32_MIN) ?
|
|
|
|
av_rgain->album_gain / 100000.0f : 0.0;
|
|
|
|
|
|
|
|
rgain->album_peak = (av_rgain->album_peak != 0.0) ?
|
|
|
|
av_rgain->album_peak / 100000.0f : 1.0;
|
|
|
|
|
2016-08-12 19:39:32 +00:00
|
|
|
// This must be run only before the stream was added, otherwise there
|
|
|
|
// will be race conditions with accesses from the user thread.
|
|
|
|
assert(!sh->ds);
|
|
|
|
sh->codec->replaygain_data = rgain;
|
2014-03-25 10:46:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-01 21:47:27 +00:00
|
|
|
// Return a dictionary entry as (decimal) integer.
|
|
|
|
static int dict_get_decimal(AVDictionary *dict, const char *entry, int def)
|
|
|
|
{
|
|
|
|
AVDictionaryEntry *e = av_dict_get(dict, entry, NULL, 0);
|
|
|
|
if (e && e->value) {
|
|
|
|
char *end = NULL;
|
|
|
|
long int r = strtol(e->value, &end, 10);
|
|
|
|
if (end && !end[0] && r >= INT_MIN && r <= INT_MAX)
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
2015-12-22 01:14:48 +00:00
|
|
|
static void handle_new_stream(demuxer_t *demuxer, int i)
|
2011-07-03 12:42:04 +00:00
|
|
|
{
|
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
2013-04-14 18:53:03 +00:00
|
|
|
AVFormatContext *avfc = priv->avfc;
|
2011-07-03 12:42:04 +00:00
|
|
|
AVStream *st = avfc->streams[i];
|
2013-02-09 14:15:28 +00:00
|
|
|
struct sh_stream *sh = NULL;
|
2016-03-31 20:00:45 +00:00
|
|
|
AVCodecParameters *codec = st->codecpar;
|
|
|
|
int lavc_delay = codec->initial_padding;
|
2012-07-29 19:04:57 +00:00
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
switch (codec->codec_type) {
|
|
|
|
case AVMEDIA_TYPE_AUDIO: {
|
demux: remove weird tripple-buffering for the sh_stream list
The demuxer infrastructure was originally single-threaded. To make it
suitable for multithreading (specifically, demuxing and decoding on
separate threads), some sort of tripple-buffering was introduced. There
are separate "struct demuxer" allocations. The demuxer thread sets the
state on d_thread. If anything changes, the state is copied to d_buffer
(the copy is protected by a lock), and the decoder thread is notified.
Then the decoder thread copies the state from d_buffer to d_user (again
while holding a lock). This avoids the need for locking in the
demuxer/decoder code itself (only demux.c needs an internal, "invisible"
lock.)
Remove the streams/num_streams fields from this tripple-buffering
schema. Move them to the internal struct, and protect them with the
internal lock. Use accessors for read access outside of demux.c.
Other than replacing all field accesses with accessors, this separates
allocating and adding sh_streams. This is needed to avoid race
conditions. Before this change, this was awkwardly handled by first
initializing the sh_stream, and then sending a stream change event. Now
the stream is allocated, then initialized, and then declared as
immutable and added (at which point it becomes visible to the decoder
thread immediately).
This change is useful for PR #2626. And eventually, we should probably
get entirely of the tripple buffering, and this makes a nice first step.
2015-12-23 20:44:53 +00:00
|
|
|
sh = demux_alloc_sh_stream(STREAM_AUDIO);
|
2013-04-14 18:53:03 +00:00
|
|
|
|
demux_lavf, ad_lavc, vd_lavc: pass codec header data directly
Instead of putting codec header data into WAVEFORMATEX and
BITMAPINFOHEADER, pass it directly via AVCodecContext. To do this, we
add mp_copy_lav_codec_headers(), which copies the codec header data
from one AVCodecContext to another (originally, the plan was to use
avcodec_copy_context() for this, but it looks like this would turn
decoder initialization into an even worse mess).
Get rid of the silly CodecID <-> codec_tag mapping. This was originally
needed for codecs.conf: codec tags were used to identify codecs, but
libavformat didn't always return useful codec tags (different file
formats can have different, overlapping tag numbers). Since we don't
go through WAVEFORMATEX etc. and pass all header data directly via
AVCodecContext, we can be absolutely sure that the codec tag mapping is
not needed anymore.
Note that this also destroys the "standard" MPlayer method of exporting
codec header data. WAVEFORMATEX and BITMAPINFOHEADER made sure that
other non-libavcodec decoders could be initialized. However, all these
decoders have been removed, so this is just cruft full of old hacks that
are not needed anymore. There's still ad_spdif and ad_mpg123, bu neither
of these need codec header data. Should we ever add non-libavcodec
decoders, better data structures without the past hacks could be added
to export the headers.
2013-02-09 14:15:37 +00:00
|
|
|
// probably unneeded
|
2016-01-12 22:48:19 +00:00
|
|
|
mp_chmap_set_unknown(&sh->codec->channels, codec->channels);
|
2013-04-06 20:43:12 +00:00
|
|
|
if (codec->channel_layout)
|
2016-01-12 22:48:19 +00:00
|
|
|
mp_chmap_from_lavc(&sh->codec->channels, codec->channel_layout);
|
|
|
|
sh->codec->samplerate = codec->sample_rate;
|
|
|
|
sh->codec->bitrate = codec->bit_rate;
|
demux_lavf, ad_lavc, vd_lavc: pass codec header data directly
Instead of putting codec header data into WAVEFORMATEX and
BITMAPINFOHEADER, pass it directly via AVCodecContext. To do this, we
add mp_copy_lav_codec_headers(), which copies the codec header data
from one AVCodecContext to another (originally, the plan was to use
avcodec_copy_context() for this, but it looks like this would turn
decoder initialization into an even worse mess).
Get rid of the silly CodecID <-> codec_tag mapping. This was originally
needed for codecs.conf: codec tags were used to identify codecs, but
libavformat didn't always return useful codec tags (different file
formats can have different, overlapping tag numbers). Since we don't
go through WAVEFORMATEX etc. and pass all header data directly via
AVCodecContext, we can be absolutely sure that the codec tag mapping is
not needed anymore.
Note that this also destroys the "standard" MPlayer method of exporting
codec header data. WAVEFORMATEX and BITMAPINFOHEADER made sure that
other non-libavcodec decoders could be initialized. However, all these
decoders have been removed, so this is just cruft full of old hacks that
are not needed anymore. There's still ad_spdif and ad_mpg123, bu neither
of these need codec header data. Should we ever add non-libavcodec
decoders, better data structures without the past hacks could be added
to export the headers.
2013-02-09 14:15:37 +00:00
|
|
|
|
2016-02-22 19:21:03 +00:00
|
|
|
double delay = 0;
|
|
|
|
if (codec->sample_rate > 0)
|
2016-03-31 20:00:45 +00:00
|
|
|
delay = lavc_delay / (double)codec->sample_rate;
|
2016-02-22 19:21:03 +00:00
|
|
|
priv->seek_delay = MPMAX(priv->seek_delay, delay);
|
|
|
|
|
2016-08-12 19:39:32 +00:00
|
|
|
export_replaygain(demuxer, sh, st);
|
2014-03-25 10:46:10 +00:00
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AVMEDIA_TYPE_VIDEO: {
|
demux: remove weird tripple-buffering for the sh_stream list
The demuxer infrastructure was originally single-threaded. To make it
suitable for multithreading (specifically, demuxing and decoding on
separate threads), some sort of tripple-buffering was introduced. There
are separate "struct demuxer" allocations. The demuxer thread sets the
state on d_thread. If anything changes, the state is copied to d_buffer
(the copy is protected by a lock), and the decoder thread is notified.
Then the decoder thread copies the state from d_buffer to d_user (again
while holding a lock). This avoids the need for locking in the
demuxer/decoder code itself (only demux.c needs an internal, "invisible"
lock.)
Remove the streams/num_streams fields from this tripple-buffering
schema. Move them to the internal struct, and protect them with the
internal lock. Use accessors for read access outside of demux.c.
Other than replacing all field accesses with accessors, this separates
allocating and adding sh_streams. This is needed to avoid race
conditions. Before this change, this was awkwardly handled by first
initializing the sh_stream, and then sending a stream change event. Now
the stream is allocated, then initialized, and then declared as
immutable and added (at which point it becomes visible to the decoder
thread immediately).
This change is useful for PR #2626. And eventually, we should probably
get entirely of the tripple buffering, and this makes a nice first step.
2015-12-23 20:44:53 +00:00
|
|
|
sh = demux_alloc_sh_stream(STREAM_VIDEO);
|
2013-04-14 18:53:03 +00:00
|
|
|
|
core: completely change handling of attached picture pseudo video
Before this commit, we tried to play along with libavformat and tried
to pretend that attached pictures are video streams with a single
frame, and that the frame magically appeared at the seek position when
seeking. The playback core would then switch to a mode where the video
has ended, and the "remaining" audio is played.
This didn't work very well:
- we needed a hack in demux.c, because we tried to read more packets in
order to find the "next" video frame (libavformat doesn't tell us if
a stream has ended)
- switching the video stream didn't work, because we can't tell
libavformat to send the packet again
- seeking and resuming after was hacky (for some reason libavformat sets
the returned packet's PTS to that of the previously returned audio
packet in generic code not related to attached pictures, and this
happened to work)
- if the user did something stupid and e.g. inserted a deinterlacer by
default, a picture was never displayed, only an inactive VO window)
- same when using a command that reconfigured the VO (like switching
aspect or video filters)
- hr-seek didn't work
For this reason, handle attached pictures as separate case with a
separate video decoding function, which doesn't read packets. Also,
do not synchronize audio to video start in this case.
2013-07-11 17:23:56 +00:00
|
|
|
if (st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
|
2016-03-03 10:04:32 +00:00
|
|
|
sh->attached_picture =
|
|
|
|
new_demux_packet_from_avpacket(&st->attached_pic);
|
2014-09-16 16:11:00 +00:00
|
|
|
if (sh->attached_picture) {
|
|
|
|
sh->attached_picture->pts = 0;
|
|
|
|
talloc_steal(sh, sh->attached_picture);
|
|
|
|
sh->attached_picture->keyframe = true;
|
|
|
|
}
|
core: completely change handling of attached picture pseudo video
Before this commit, we tried to play along with libavformat and tried
to pretend that attached pictures are video streams with a single
frame, and that the frame magically appeared at the seek position when
seeking. The playback core would then switch to a mode where the video
has ended, and the "remaining" audio is played.
This didn't work very well:
- we needed a hack in demux.c, because we tried to read more packets in
order to find the "next" video frame (libavformat doesn't tell us if
a stream has ended)
- switching the video stream didn't work, because we can't tell
libavformat to send the packet again
- seeking and resuming after was hacky (for some reason libavformat sets
the returned packet's PTS to that of the previously returned audio
packet in generic code not related to attached pictures, and this
happened to work)
- if the user did something stupid and e.g. inserted a deinterlacer by
default, a picture was never displayed, only an inactive VO window)
- same when using a command that reconfigured the VO (like switching
aspect or video filters)
- hr-seek didn't work
For this reason, handle attached pictures as separate case with a
separate video decoding function, which doesn't read packets. Also,
do not synchronize audio to video start in this case.
2013-07-11 17:23:56 +00:00
|
|
|
}
|
demux_lavf, ad_lavc, vd_lavc: pass codec header data directly
Instead of putting codec header data into WAVEFORMATEX and
BITMAPINFOHEADER, pass it directly via AVCodecContext. To do this, we
add mp_copy_lav_codec_headers(), which copies the codec header data
from one AVCodecContext to another (originally, the plan was to use
avcodec_copy_context() for this, but it looks like this would turn
decoder initialization into an even worse mess).
Get rid of the silly CodecID <-> codec_tag mapping. This was originally
needed for codecs.conf: codec tags were used to identify codecs, but
libavformat didn't always return useful codec tags (different file
formats can have different, overlapping tag numbers). Since we don't
go through WAVEFORMATEX etc. and pass all header data directly via
AVCodecContext, we can be absolutely sure that the codec tag mapping is
not needed anymore.
Note that this also destroys the "standard" MPlayer method of exporting
codec header data. WAVEFORMATEX and BITMAPINFOHEADER made sure that
other non-libavcodec decoders could be initialized. However, all these
decoders have been removed, so this is just cruft full of old hacks that
are not needed anymore. There's still ad_spdif and ad_mpg123, bu neither
of these need codec header data. Should we ever add non-libavcodec
decoders, better data structures without the past hacks could be added
to export the headers.
2013-02-09 14:15:37 +00:00
|
|
|
|
2016-01-12 22:48:19 +00:00
|
|
|
sh->codec->disp_w = codec->width;
|
|
|
|
sh->codec->disp_h = codec->height;
|
2013-03-09 07:52:53 +00:00
|
|
|
if (st->avg_frame_rate.num)
|
2016-03-31 19:37:32 +00:00
|
|
|
sh->codec->fps = av_q2d(st->avg_frame_rate);
|
2015-03-02 18:09:40 +00:00
|
|
|
if (priv->format_hack.image_format)
|
2016-09-06 18:09:56 +00:00
|
|
|
sh->codec->fps = priv->mf_fps;
|
2016-01-12 22:48:19 +00:00
|
|
|
sh->codec->par_w = st->sample_aspect_ratio.num;
|
|
|
|
sh->codec->par_h = st->sample_aspect_ratio.den;
|
2014-05-07 18:55:02 +00:00
|
|
|
|
2014-06-01 15:56:10 +00:00
|
|
|
uint8_t *sd = av_stream_get_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
|
2015-06-30 17:35:19 +00:00
|
|
|
if (sd) {
|
|
|
|
double r = av_display_rotation_get((uint32_t *)sd);
|
|
|
|
if (!isnan(r))
|
2016-01-12 22:48:19 +00:00
|
|
|
sh->codec->rotate = (((int)(-r) % 360) + 360) % 360;
|
2015-06-30 17:35:19 +00:00
|
|
|
}
|
2014-04-20 19:29:22 +00:00
|
|
|
|
video: add insane hack to work around FFmpeg/Libav insanity
So, FFmpeg/Libav requires us to figure out video timestamps ourselves
(see last 10 commits or so), but the methods it provides for this aren't
even sufficient. In particular, everything that uses AVI-style DTS (avi,
vfw-muxed mkv, possibly mpeg4-in-ogm) with a codec that has an internal
frame delay is broken. In this case, libavcodec will shift the packet-
to-image correspondence by the codec delay, meaning that with a delay=1,
the first AVFrame.pkt_dts is not 0, but that of the second packet. All
timestamps will appear shifted. The start time (e.g. the time displayed
when doing "mpv file.avi --pause") will not be exactly 0.
(According to Libav developers, this is how it's supposed to work; just
that the first DTS values are normally negative with formats that use
DTS "properly". Who cares if it doesn't work at all with very common
video formats? There's no indication that they'll fix this soon,
either. An elegant workaround is missing too.)
Add a hack to re-enable the old PTS code for AVI and vfw-muxed MKV.
Since these timestamps are not reorderd, we wouldn't need to sort them,
but it's less code this way (and possibly more robust, should a demuxer
unexpectedly output PTS).
The original intention of all the timestamp changes recently was
actually to get rid of demuxer-specific hacks and the old timestamp
sorting code, but it looks like this didn't work out. Yet another case
where trying to replace native MPlayer functionality with FFmpeg/Libav
led to disadvantages and bugs. (Note that the old PTS sorting code
doesn't and can't handle frame dropping correctly, though.)
Bug reports:
https://trac.ffmpeg.org/ticket/3178
https://bugzilla.libav.org/show_bug.cgi?id=600
2013-11-28 14:10:45 +00:00
|
|
|
// This also applies to vfw-muxed mkv, but we can't detect these easily.
|
2016-01-12 22:48:19 +00:00
|
|
|
sh->codec->avi_dts = matches_avinputformat_name(priv, "avi");
|
video: add insane hack to work around FFmpeg/Libav insanity
So, FFmpeg/Libav requires us to figure out video timestamps ourselves
(see last 10 commits or so), but the methods it provides for this aren't
even sufficient. In particular, everything that uses AVI-style DTS (avi,
vfw-muxed mkv, possibly mpeg4-in-ogm) with a codec that has an internal
frame delay is broken. In this case, libavcodec will shift the packet-
to-image correspondence by the codec delay, meaning that with a delay=1,
the first AVFrame.pkt_dts is not 0, but that of the second packet. All
timestamps will appear shifted. The start time (e.g. the time displayed
when doing "mpv file.avi --pause") will not be exactly 0.
(According to Libav developers, this is how it's supposed to work; just
that the first DTS values are normally negative with formats that use
DTS "properly". Who cares if it doesn't work at all with very common
video formats? There's no indication that they'll fix this soon,
either. An elegant workaround is missing too.)
Add a hack to re-enable the old PTS code for AVI and vfw-muxed MKV.
Since these timestamps are not reorderd, we wouldn't need to sort them,
but it's less code this way (and possibly more robust, should a demuxer
unexpectedly output PTS).
The original intention of all the timestamp changes recently was
actually to get rid of demuxer-specific hacks and the old timestamp
sorting code, but it looks like this didn't work out. Yet another case
where trying to replace native MPlayer functionality with FFmpeg/Libav
led to disadvantages and bugs. (Note that the old PTS sorting code
doesn't and can't handle frame dropping correctly, though.)
Bug reports:
https://trac.ffmpeg.org/ticket/3178
https://bugzilla.libav.org/show_bug.cgi?id=600
2013-11-28 14:10:45 +00:00
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AVMEDIA_TYPE_SUBTITLE: {
|
demux: remove weird tripple-buffering for the sh_stream list
The demuxer infrastructure was originally single-threaded. To make it
suitable for multithreading (specifically, demuxing and decoding on
separate threads), some sort of tripple-buffering was introduced. There
are separate "struct demuxer" allocations. The demuxer thread sets the
state on d_thread. If anything changes, the state is copied to d_buffer
(the copy is protected by a lock), and the decoder thread is notified.
Then the decoder thread copies the state from d_buffer to d_user (again
while holding a lock). This avoids the need for locking in the
demuxer/decoder code itself (only demux.c needs an internal, "invisible"
lock.)
Remove the streams/num_streams fields from this tripple-buffering
schema. Move them to the internal struct, and protect them with the
internal lock. Use accessors for read access outside of demux.c.
Other than replacing all field accesses with accessors, this separates
allocating and adding sh_streams. This is needed to avoid race
conditions. Before this change, this was awkwardly handled by first
initializing the sh_stream, and then sending a stream change event. Now
the stream is allocated, then initialized, and then declared as
immutable and added (at which point it becomes visible to the decoder
thread immediately).
This change is useful for PR #2626. And eventually, we should probably
get entirely of the tripple buffering, and this makes a nice first step.
2015-12-23 20:44:53 +00:00
|
|
|
sh = demux_alloc_sh_stream(STREAM_SUB);
|
2013-04-14 18:53:03 +00:00
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
if (codec->extradata_size) {
|
2016-01-12 22:48:19 +00:00
|
|
|
sh->codec->extradata = talloc_size(sh, codec->extradata_size);
|
|
|
|
memcpy(sh->codec->extradata, codec->extradata, codec->extradata_size);
|
|
|
|
sh->codec->extradata_size = codec->extradata_size;
|
2008-01-30 08:10:25 +00:00
|
|
|
}
|
2014-01-09 23:02:06 +00:00
|
|
|
|
2014-03-03 23:28:10 +00:00
|
|
|
if (matches_avinputformat_name(priv, "microdvd")) {
|
|
|
|
AVRational r;
|
|
|
|
if (av_opt_get_q(avfc, "subfps", AV_OPT_SEARCH_CHILDREN, &r) >= 0) {
|
|
|
|
// File headers don't have a FPS set.
|
|
|
|
if (r.num < 1 || r.den < 1)
|
2016-03-31 19:43:59 +00:00
|
|
|
sh->codec->frame_based = 23.976; // default timebase
|
2014-03-03 23:28:10 +00:00
|
|
|
}
|
|
|
|
}
|
2011-07-03 12:42:04 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AVMEDIA_TYPE_ATTACHMENT: {
|
2015-04-05 18:52:14 +00:00
|
|
|
AVDictionaryEntry *ftag = av_dict_get(st->metadata, "filename", NULL, 0);
|
2011-07-03 12:42:04 +00:00
|
|
|
char *filename = ftag ? ftag->value : NULL;
|
2015-04-05 18:52:14 +00:00
|
|
|
AVDictionaryEntry *mt = av_dict_get(st->metadata, "mimetype", NULL, 0);
|
|
|
|
char *mimetype = mt ? mt->value : NULL;
|
2014-07-05 14:44:14 +00:00
|
|
|
if (mimetype) {
|
2015-06-24 12:18:51 +00:00
|
|
|
demuxer_add_attachment(demuxer, filename, mimetype,
|
|
|
|
codec->extradata, codec->extradata_size);
|
2014-07-05 14:44:14 +00:00
|
|
|
}
|
2011-07-03 12:42:04 +00:00
|
|
|
break;
|
|
|
|
}
|
2013-04-14 18:53:03 +00:00
|
|
|
default: ;
|
2004-04-11 14:26:04 +00:00
|
|
|
}
|
2013-04-14 18:53:03 +00:00
|
|
|
|
|
|
|
assert(priv->num_streams == i); // directly mapped
|
|
|
|
MP_TARRAY_APPEND(priv, priv->streams, priv->num_streams, sh);
|
|
|
|
|
2013-02-09 14:15:28 +00:00
|
|
|
if (sh) {
|
2014-10-21 11:16:48 +00:00
|
|
|
sh->ff_index = st->index;
|
2016-01-12 22:48:19 +00:00
|
|
|
sh->codec->codec = mp_codec_from_av_codec_id(codec->codec_id);
|
|
|
|
sh->codec->codec_tag = codec->codec_tag;
|
2016-03-31 20:00:45 +00:00
|
|
|
sh->codec->lav_codecpar = avcodec_parameters_alloc();
|
|
|
|
if (sh->codec->lav_codecpar)
|
|
|
|
avcodec_parameters_copy(sh->codec->lav_codecpar, codec);
|
2016-08-19 12:19:46 +00:00
|
|
|
sh->codec->native_tb_num = st->time_base.num;
|
|
|
|
sh->codec->native_tb_den = st->time_base.den;
|
demux_lavf, ad_lavc, vd_lavc: pass codec header data directly
Instead of putting codec header data into WAVEFORMATEX and
BITMAPINFOHEADER, pass it directly via AVCodecContext. To do this, we
add mp_copy_lav_codec_headers(), which copies the codec header data
from one AVCodecContext to another (originally, the plan was to use
avcodec_copy_context() for this, but it looks like this would turn
decoder initialization into an even worse mess).
Get rid of the silly CodecID <-> codec_tag mapping. This was originally
needed for codecs.conf: codec tags were used to identify codecs, but
libavformat didn't always return useful codec tags (different file
formats can have different, overlapping tag numbers). Since we don't
go through WAVEFORMATEX etc. and pass all header data directly via
AVCodecContext, we can be absolutely sure that the codec tag mapping is
not needed anymore.
Note that this also destroys the "standard" MPlayer method of exporting
codec header data. WAVEFORMATEX and BITMAPINFOHEADER made sure that
other non-libavcodec decoders could be initialized. However, all these
decoders have been removed, so this is just cruft full of old hacks that
are not needed anymore. There's still ad_spdif and ad_mpg123, bu neither
of these need codec header data. Should we ever add non-libavcodec
decoders, better data structures without the past hacks could be added
to export the headers.
2013-02-09 14:15:37 +00:00
|
|
|
|
2013-02-09 14:15:28 +00:00
|
|
|
if (st->disposition & AV_DISPOSITION_DEFAULT)
|
2015-06-27 20:02:24 +00:00
|
|
|
sh->default_track = true;
|
|
|
|
if (st->disposition & AV_DISPOSITION_FORCED)
|
|
|
|
sh->forced_track = true;
|
2015-02-18 20:10:15 +00:00
|
|
|
if (priv->format_hack.use_stream_ids)
|
2013-02-09 14:15:28 +00:00
|
|
|
sh->demuxer_id = st->id;
|
|
|
|
AVDictionaryEntry *title = av_dict_get(st->metadata, "title", NULL, 0);
|
2010-05-03 22:45:00 +00:00
|
|
|
if (title && title->value)
|
2013-02-09 14:15:28 +00:00
|
|
|
sh->title = talloc_strdup(sh, title->value);
|
2016-10-19 18:54:47 +00:00
|
|
|
if (!sh->title && st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
|
|
|
|
sh->title = talloc_asprintf(sh, "visual impaired");
|
|
|
|
if (!sh->title && st->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
|
|
|
|
sh->title = talloc_asprintf(sh, "hearing impaired");
|
2013-02-09 14:15:28 +00:00
|
|
|
AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
|
|
|
|
if (lang && lang->value)
|
|
|
|
sh->lang = talloc_strdup(sh, lang->value);
|
2014-09-01 21:47:27 +00:00
|
|
|
sh->hls_bitrate = dict_get_decimal(st->metadata, "variant_bitrate", 0);
|
2014-09-01 21:50:25 +00:00
|
|
|
if (!sh->title && sh->hls_bitrate > 0)
|
|
|
|
sh->title = talloc_asprintf(sh, "bitrate %d", sh->hls_bitrate);
|
2015-03-20 21:10:00 +00:00
|
|
|
sh->missing_timestamps = !!(priv->avif_flags & AVFMT_NOTIMESTAMPS);
|
2016-08-12 19:39:32 +00:00
|
|
|
mp_tags_copy_from_av_dictionary(sh->tags, st->metadata);
|
demux: remove weird tripple-buffering for the sh_stream list
The demuxer infrastructure was originally single-threaded. To make it
suitable for multithreading (specifically, demuxing and decoding on
separate threads), some sort of tripple-buffering was introduced. There
are separate "struct demuxer" allocations. The demuxer thread sets the
state on d_thread. If anything changes, the state is copied to d_buffer
(the copy is protected by a lock), and the decoder thread is notified.
Then the decoder thread copies the state from d_buffer to d_user (again
while holding a lock). This avoids the need for locking in the
demuxer/decoder code itself (only demux.c needs an internal, "invisible"
lock.)
Remove the streams/num_streams fields from this tripple-buffering
schema. Move them to the internal struct, and protect them with the
internal lock. Use accessors for read access outside of demux.c.
Other than replacing all field accesses with accessors, this separates
allocating and adding sh_streams. This is needed to avoid race
conditions. Before this change, this was awkwardly handled by first
initializing the sh_stream, and then sending a stream change event. Now
the stream is allocated, then initialized, and then declared as
immutable and added (at which point it becomes visible to the decoder
thread immediately).
This change is useful for PR #2626. And eventually, we should probably
get entirely of the tripple buffering, and this makes a nice first step.
2015-12-23 20:44:53 +00:00
|
|
|
demux_add_sh_stream(demuxer, sh);
|
2010-05-03 22:45:00 +00:00
|
|
|
}
|
2013-07-11 17:22:24 +00:00
|
|
|
|
2013-07-11 17:23:31 +00:00
|
|
|
select_tracks(demuxer, i);
|
2007-10-27 19:00:07 +00:00
|
|
|
}
|
|
|
|
|
2013-04-14 18:53:03 +00:00
|
|
|
// Add any new streams that might have been added
|
|
|
|
static void add_new_streams(demuxer_t *demuxer)
|
|
|
|
{
|
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
|
|
|
while (priv->num_streams < priv->avfc->nb_streams)
|
2015-12-22 01:14:48 +00:00
|
|
|
handle_new_stream(demuxer, priv->num_streams);
|
2013-04-14 18:53:03 +00:00
|
|
|
}
|
|
|
|
|
2013-10-19 01:50:08 +00:00
|
|
|
static void update_metadata(demuxer_t *demuxer, AVPacket *pkt)
|
|
|
|
{
|
2014-08-13 23:18:18 +00:00
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
|
|
|
if (priv->avfc->event_flags & AVFMT_EVENT_FLAG_METADATA_UPDATED) {
|
|
|
|
mp_tags_copy_from_av_dictionary(demuxer->metadata, priv->avfc->metadata);
|
|
|
|
priv->avfc->event_flags = 0;
|
|
|
|
demux_changed(demuxer, DEMUX_EVENT_METADATA);
|
|
|
|
}
|
2016-08-12 19:39:32 +00:00
|
|
|
|
|
|
|
for (int n = 0; n < priv->num_streams; n++) {
|
|
|
|
AVStream *st = priv->streams[n] ? priv->avfc->streams[n] : NULL;
|
|
|
|
if (st && st->event_flags & AVSTREAM_EVENT_FLAG_METADATA_UPDATED) {
|
|
|
|
st->event_flags = 0;
|
|
|
|
struct mp_tags *tags = talloc_zero(NULL, struct mp_tags);
|
|
|
|
mp_tags_copy_from_av_dictionary(tags, st->metadata);
|
|
|
|
demux_set_stream_tags(demuxer, priv->streams[n], tags);
|
2014-08-13 23:18:18 +00:00
|
|
|
}
|
|
|
|
}
|
2013-10-19 01:50:08 +00:00
|
|
|
}
|
|
|
|
|
2015-02-18 20:09:47 +00:00
|
|
|
static int interrupt_cb(void *ctx)
|
|
|
|
{
|
|
|
|
struct demuxer *demuxer = ctx;
|
2015-12-28 22:22:58 +00:00
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
|
|
|
return mp_cancel_test(priv->stream->cancel);
|
2015-02-18 20:09:47 +00:00
|
|
|
}
|
|
|
|
|
2016-12-04 22:15:31 +00:00
|
|
|
static int block_io_open(struct AVFormatContext *s, AVIOContext **pb,
|
|
|
|
const char *url, int flags, AVDictionary **options)
|
|
|
|
{
|
|
|
|
struct demuxer *demuxer = s->opaque;
|
|
|
|
MP_ERR(demuxer, "Not opening '%s' due to --access-references=no.\n", url);
|
|
|
|
return AVERROR(EACCES);
|
|
|
|
}
|
|
|
|
|
2013-07-12 19:58:11 +00:00
|
|
|
static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
|
2011-07-03 12:42:04 +00:00
|
|
|
{
|
2007-10-27 19:00:07 +00:00
|
|
|
AVFormatContext *avfc;
|
2011-12-22 00:06:52 +00:00
|
|
|
AVDictionaryEntry *t = NULL;
|
2013-05-27 21:26:22 +00:00
|
|
|
float analyze_duration = 0;
|
2015-12-17 00:00:54 +00:00
|
|
|
lavf_priv_t *priv = talloc_zero(NULL, lavf_priv_t);
|
|
|
|
demuxer->priv = priv;
|
2015-12-28 22:22:58 +00:00
|
|
|
priv->stream = demuxer->stream;
|
2007-10-27 19:00:07 +00:00
|
|
|
|
2016-09-06 18:09:56 +00:00
|
|
|
priv->opts = mp_get_config_group(priv, demuxer->global, &demux_lavf_conf);
|
|
|
|
struct demux_lavf_opts *lavfdopts = priv->opts;
|
|
|
|
|
|
|
|
int index_mode;
|
|
|
|
mp_read_option_raw(demuxer->global, "index", &m_option_type_choice,
|
|
|
|
&index_mode);
|
|
|
|
mp_read_option_raw(demuxer->global, "mf-fps", &m_option_type_double,
|
|
|
|
&priv->mf_fps);
|
|
|
|
|
2013-07-12 19:58:11 +00:00
|
|
|
if (lavf_check_file(demuxer, check) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2017-01-30 18:38:43 +00:00
|
|
|
if (demuxer->params)
|
|
|
|
priv->init_fragment = bstrdup(priv, demuxer->params->init_fragment);
|
|
|
|
|
2009-11-22 14:15:41 +00:00
|
|
|
avfc = avformat_alloc_context();
|
2014-12-12 16:28:22 +00:00
|
|
|
if (!avfc)
|
|
|
|
return -1;
|
2007-10-27 19:00:07 +00:00
|
|
|
|
2010-04-23 19:08:18 +00:00
|
|
|
if (lavfdopts->cryptokey)
|
|
|
|
parse_cryptokey(avfc, lavfdopts->cryptokey);
|
2013-11-25 22:13:46 +00:00
|
|
|
if (lavfdopts->genptsmode)
|
|
|
|
avfc->flags |= AVFMT_FLAG_GENPTS;
|
2016-09-06 18:09:56 +00:00
|
|
|
if (index_mode != 1)
|
2007-10-27 19:00:07 +00:00
|
|
|
avfc->flags |= AVFMT_FLAG_IGNIDX;
|
2014-02-08 00:04:37 +00:00
|
|
|
|
|
|
|
#if LIBAVFORMAT_VERSION_MICRO >= 100
|
2013-10-19 01:50:08 +00:00
|
|
|
/* Keep side data as side data instead of mashing it into the packet
|
2014-02-08 00:04:37 +00:00
|
|
|
* stream.
|
|
|
|
* Note: Libav doesn't have this horrible insanity. */
|
2014-02-06 13:05:04 +00:00
|
|
|
av_opt_set(avfc, "fflags", "+keepside", 0);
|
2014-02-08 00:04:37 +00:00
|
|
|
#endif
|
2007-10-27 19:00:07 +00:00
|
|
|
|
2010-04-23 19:08:18 +00:00
|
|
|
if (lavfdopts->probesize) {
|
2012-01-28 11:41:36 +00:00
|
|
|
if (av_opt_set_int(avfc, "probesize", lavfdopts->probesize, 0) < 0)
|
2014-07-05 14:42:50 +00:00
|
|
|
MP_ERR(demuxer, "couldn't set option probesize to %u\n",
|
2011-07-03 12:42:04 +00:00
|
|
|
lavfdopts->probesize);
|
2007-10-27 19:00:07 +00:00
|
|
|
}
|
2013-05-27 21:26:22 +00:00
|
|
|
|
2015-02-18 20:10:15 +00:00
|
|
|
if (priv->format_hack.analyzeduration)
|
|
|
|
analyze_duration = priv->format_hack.analyzeduration;
|
2013-05-27 21:26:22 +00:00
|
|
|
if (lavfdopts->analyzeduration)
|
|
|
|
analyze_duration = lavfdopts->analyzeduration;
|
|
|
|
if (analyze_duration > 0) {
|
2012-01-28 11:41:36 +00:00
|
|
|
if (av_opt_set_int(avfc, "analyzeduration",
|
2013-05-27 21:26:22 +00:00
|
|
|
analyze_duration * AV_TIME_BASE, 0) < 0)
|
2013-12-21 19:24:20 +00:00
|
|
|
MP_ERR(demuxer, "demux_lavf, couldn't set option "
|
2013-05-27 21:26:22 +00:00
|
|
|
"analyzeduration to %f\n", analyze_duration);
|
2007-10-27 19:00:07 +00:00
|
|
|
}
|
|
|
|
|
2014-10-14 19:01:30 +00:00
|
|
|
AVDictionary *dopts = NULL;
|
|
|
|
|
2017-02-02 17:24:27 +00:00
|
|
|
if ((priv->avif_flags & AVFMT_NOFILE) || priv->format_hack.no_stream) {
|
2016-09-06 18:09:56 +00:00
|
|
|
mp_setup_av_network_options(&dopts, demuxer->global, demuxer->log);
|
2013-11-03 18:21:47 +00:00
|
|
|
// This might be incorrect.
|
|
|
|
demuxer->seekable = true;
|
|
|
|
} else {
|
2013-08-04 21:25:54 +00:00
|
|
|
void *buffer = av_malloc(lavfdopts->buffersize);
|
2013-08-04 21:21:50 +00:00
|
|
|
if (!buffer)
|
|
|
|
return -1;
|
2013-08-04 21:25:54 +00:00
|
|
|
priv->pb = avio_alloc_context(buffer, lavfdopts->buffersize, 0,
|
2011-12-22 00:06:52 +00:00
|
|
|
demuxer, mp_read, NULL, mp_seek);
|
2013-08-04 21:21:50 +00:00
|
|
|
if (!priv->pb) {
|
|
|
|
av_free(buffer);
|
|
|
|
return -1;
|
|
|
|
}
|
2011-06-21 20:28:53 +00:00
|
|
|
priv->pb->read_seek = mp_read_seek;
|
2013-11-03 18:21:47 +00:00
|
|
|
priv->pb->seekable = demuxer->seekable ? AVIO_SEEKABLE_NORMAL : 0;
|
2011-12-22 00:06:52 +00:00
|
|
|
avfc->pb = priv->pb;
|
2015-12-28 22:22:58 +00:00
|
|
|
if (stream_control(priv->stream, STREAM_CTRL_HAS_AVSEEK, NULL) > 0)
|
2014-10-30 21:46:25 +00:00
|
|
|
demuxer->seekable = true;
|
2016-06-08 09:49:56 +00:00
|
|
|
demuxer->seekable |= priv->format_hack.fully_read;
|
2011-06-21 20:28:53 +00:00
|
|
|
}
|
2008-01-26 21:45:31 +00:00
|
|
|
|
2013-09-22 00:40:29 +00:00
|
|
|
if (matches_avinputformat_name(priv, "rtsp")) {
|
|
|
|
const char *transport = NULL;
|
2016-09-06 18:09:56 +00:00
|
|
|
switch (lavfdopts->rtsp_transport) {
|
2013-09-22 00:40:29 +00:00
|
|
|
case 1: transport = "udp"; break;
|
|
|
|
case 2: transport = "tcp"; break;
|
|
|
|
case 3: transport = "http"; break;
|
|
|
|
}
|
|
|
|
if (transport)
|
|
|
|
av_dict_set(&dopts, "rtsp_transport", transport, 0);
|
|
|
|
}
|
|
|
|
|
2015-05-28 19:51:54 +00:00
|
|
|
guess_and_set_vobsub_name(demuxer, &dopts);
|
|
|
|
|
2015-02-18 20:09:47 +00:00
|
|
|
avfc->interrupt_callback = (AVIOInterruptCB){
|
|
|
|
.callback = interrupt_cb,
|
|
|
|
.opaque = demuxer,
|
|
|
|
};
|
|
|
|
|
2016-12-04 22:15:31 +00:00
|
|
|
avfc->opaque = demuxer;
|
|
|
|
if (!demuxer->access_references)
|
|
|
|
avfc->io_open = block_io_open;
|
|
|
|
|
2014-08-02 01:12:09 +00:00
|
|
|
mp_set_avdict(&dopts, lavfdopts->avopts);
|
|
|
|
|
2013-09-22 00:40:29 +00:00
|
|
|
if (avformat_open_input(&avfc, priv->filename, priv->avif, &dopts) < 0) {
|
2014-07-05 14:42:50 +00:00
|
|
|
MP_ERR(demuxer, "avformat_open_input() failed\n");
|
2013-09-22 00:40:29 +00:00
|
|
|
av_dict_free(&dopts);
|
2013-07-11 18:08:12 +00:00
|
|
|
return -1;
|
2007-10-27 19:00:07 +00:00
|
|
|
}
|
|
|
|
|
2014-08-02 01:12:09 +00:00
|
|
|
mp_avdict_print_unset(demuxer->log, MSGL_V, dopts);
|
2013-09-22 00:40:29 +00:00
|
|
|
av_dict_free(&dopts);
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
priv->avfc = avfc;
|
2017-01-30 18:38:43 +00:00
|
|
|
|
|
|
|
if (!demuxer->params || !demuxer->params->skip_lavf_probing) {
|
|
|
|
if (avformat_find_stream_info(avfc, NULL) < 0) {
|
|
|
|
MP_ERR(demuxer, "av_find_stream_info() failed\n");
|
|
|
|
return -1;
|
|
|
|
}
|
2007-10-27 19:00:07 +00:00
|
|
|
}
|
2013-05-24 10:00:44 +00:00
|
|
|
|
2014-07-05 14:42:50 +00:00
|
|
|
MP_VERBOSE(demuxer, "avformat_find_stream_info() finished after %"PRId64
|
2015-12-28 22:22:58 +00:00
|
|
|
" bytes.\n", stream_tell(priv->stream));
|
2013-05-24 10:00:44 +00:00
|
|
|
|
2015-12-17 00:00:54 +00:00
|
|
|
for (int i = 0; i < avfc->nb_chapters; i++) {
|
2008-06-16 15:54:29 +00:00
|
|
|
AVChapter *c = avfc->chapters[i];
|
2011-12-22 00:06:52 +00:00
|
|
|
t = av_dict_get(c->metadata, "title", NULL, 0);
|
2015-06-24 14:51:19 +00:00
|
|
|
int index = demuxer_add_chapter(demuxer, t ? t->value : "",
|
2014-11-02 16:20:04 +00:00
|
|
|
c->start * av_q2d(c->time_base), i);
|
2014-04-13 12:01:55 +00:00
|
|
|
mp_tags_copy_from_av_dictionary(demuxer->chapters[index].metadata, c->metadata);
|
2008-06-16 15:54:29 +00:00
|
|
|
}
|
|
|
|
|
2013-04-14 18:53:03 +00:00
|
|
|
add_new_streams(demuxer);
|
2010-10-04 18:12:36 +00:00
|
|
|
|
2014-08-13 23:18:18 +00:00
|
|
|
mp_tags_copy_from_av_dictionary(demuxer->metadata, avfc->metadata);
|
|
|
|
update_metadata(demuxer, NULL);
|
|
|
|
|
2015-03-20 21:07:26 +00:00
|
|
|
demuxer->ts_resets_possible =
|
2015-03-20 21:10:00 +00:00
|
|
|
priv->avif_flags & (AVFMT_TS_DISCONT | AVFMT_NOTIMESTAMPS);
|
2013-03-01 12:20:33 +00:00
|
|
|
|
2016-08-18 19:03:01 +00:00
|
|
|
if (avfc->start_time != AV_NOPTS_VALUE && !priv->format_hack.ignore_start)
|
|
|
|
demuxer->start_time = avfc->start_time / (double)AV_TIME_BASE;
|
2014-07-05 14:54:49 +00:00
|
|
|
|
2015-02-18 20:10:43 +00:00
|
|
|
demuxer->fully_read = priv->format_hack.fully_read;
|
demux: hack for instant stream switching
This removes the delay when switching audio tracks in mkv or mp4 files.
Other formats are not enabled, because it's not clear whether the
demuxers fulfill the requirements listed in demux.h. (Many formats
definitely do not with libavformat.)
Background:
The demuxer packet cache buffers a certain amount of packets. This
includes only packets from selected streams. We discard packets from
other streams for various reasons. This introduces a problem: switching
to a different audio track introduces a delay. The delay is as big as
the demuxer packet cache buffer, because while the file was read ahead
to fill the packet buffer, the process of reading packets also discarded
all packets from the previously not selected audio stream. Once the
remaining packet buffer has been played, new audio packets are available
and you hear audio again.
We could probably just not discard packets from unselected streams. But
this would require additional memory and CPU resources, and also it's
hard to tell when packets from unused streams should be discarded (we
don't want to keep them forever; it'd be a memory leak).
We could also issue a player hr-seek to the current playback position,
which would solve the problem in 1 line of code or so. But this can be
rather slow.
So what we do in this commit instead is: we just seek back to the
position where our current packet buffer starts, and start demuxing from
this position again. This way we can get the "past" packets for the
newly selected stream. For streams which were already selected the
packets are simply discarded until the previous position is reached
again.
That latter part is the hard part. We really want to skip packets
exactly until the position where we left off previously, or we will skip
packets or feed packets to the decoder twice. If we assume that the
demuxer is deterministic (returns exactly the same packets after a seek
to a previous position), then we can try to check whether it's the same
packet as the one at the end of the packet buffer. If it is, we know
that the packet after it is where we left off last time.
Unfortunately, this is not very robust, and maybe it can't be made
robust. Currently we use the demux_packet.pos field as unique packet
ID - which works fine in some scenarios, but will break in arbitrary
ways if the basic requirement to the demuxer (as listed in the demux.h
additions) are broken. Thus, this is enabled only for the internal mkv
demuxer and the libavformat mp4 demuxer.
(libavformat mkv does not work, because the packet positions are not
unique. Probably could be fixed upstream, but it's not clear whether
it's a bug or a feature.)
2015-02-13 20:17:17 +00:00
|
|
|
|
2013-07-11 18:08:12 +00:00
|
|
|
return 0;
|
2004-04-11 14:26:04 +00:00
|
|
|
}
|
|
|
|
|
2013-11-25 22:13:46 +00:00
|
|
|
static int demux_lavf_fill_buffer(demuxer_t *demux)
|
2011-07-03 12:42:04 +00:00
|
|
|
{
|
|
|
|
lavf_priv_t *priv = demux->priv;
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2014-08-24 15:45:28 +00:00
|
|
|
AVPacket *pkt = &(AVPacket){0};
|
2014-07-30 01:32:56 +00:00
|
|
|
int r = av_read_frame(priv->avfc, pkt);
|
|
|
|
if (r < 0) {
|
2015-10-28 22:48:56 +00:00
|
|
|
av_packet_unref(pkt);
|
2014-08-30 13:15:14 +00:00
|
|
|
if (r == AVERROR(EAGAIN))
|
|
|
|
return 1;
|
|
|
|
if (r == AVERROR_EOF)
|
|
|
|
return 0;
|
|
|
|
MP_WARN(demux, "error reading packet.\n");
|
|
|
|
return -1;
|
2011-08-19 01:59:01 +00:00
|
|
|
}
|
2008-01-26 21:45:31 +00:00
|
|
|
|
2013-04-14 18:53:03 +00:00
|
|
|
add_new_streams(demux);
|
2014-02-06 13:11:12 +00:00
|
|
|
update_metadata(demux, pkt);
|
2010-10-04 18:12:36 +00:00
|
|
|
|
2013-04-14 18:53:03 +00:00
|
|
|
assert(pkt->stream_index >= 0 && pkt->stream_index < priv->num_streams);
|
|
|
|
struct sh_stream *stream = priv->streams[pkt->stream_index];
|
2013-11-25 22:13:46 +00:00
|
|
|
AVStream *st = priv->avfc->streams[pkt->stream_index];
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2014-07-06 17:02:21 +00:00
|
|
|
if (!demux_stream_is_selected(stream)) {
|
2015-10-28 22:48:56 +00:00
|
|
|
av_packet_unref(pkt);
|
2013-11-25 22:13:46 +00:00
|
|
|
return 1; // don't signal EOF if skipping a packet
|
2005-01-30 09:13:28 +00:00
|
|
|
}
|
2008-01-26 21:45:31 +00:00
|
|
|
|
2014-08-24 15:45:28 +00:00
|
|
|
struct demux_packet *dp = new_demux_packet_from_avpacket(pkt);
|
2014-09-16 16:11:00 +00:00
|
|
|
if (!dp) {
|
2015-10-28 22:48:56 +00:00
|
|
|
av_packet_unref(pkt);
|
2014-09-16 16:11:00 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2013-12-12 22:36:52 +00:00
|
|
|
if (pkt->pts != AV_NOPTS_VALUE)
|
2013-11-25 22:13:01 +00:00
|
|
|
dp->pts = pkt->pts * av_q2d(st->time_base);
|
2013-12-12 22:36:52 +00:00
|
|
|
if (pkt->dts != AV_NOPTS_VALUE)
|
2013-11-25 22:13:01 +00:00
|
|
|
dp->dts = pkt->dts * av_q2d(st->time_base);
|
|
|
|
dp->duration = pkt->duration * av_q2d(st->time_base);
|
2013-11-16 20:04:28 +00:00
|
|
|
dp->pos = pkt->pos;
|
2012-07-24 21:23:27 +00:00
|
|
|
dp->keyframe = pkt->flags & AV_PKT_FLAG_KEY;
|
2016-12-07 18:44:29 +00:00
|
|
|
#if LIBAVFORMAT_VERSION_MICRO >= 100
|
2016-10-18 14:56:50 +00:00
|
|
|
if (pkt->flags & AV_PKT_FLAG_DISCARD)
|
|
|
|
MP_ERR(demux, "Edit lists are not correctly supported (FFmpeg issue).\n");
|
|
|
|
#endif
|
2015-10-28 22:48:56 +00:00
|
|
|
av_packet_unref(pkt);
|
2015-02-17 22:42:04 +00:00
|
|
|
|
2015-02-18 20:10:15 +00:00
|
|
|
if (priv->format_hack.clear_filepos)
|
2015-02-17 22:42:04 +00:00
|
|
|
dp->pos = -1;
|
|
|
|
|
2014-07-05 14:59:44 +00:00
|
|
|
demux_add_packet(stream, dp);
|
2004-04-11 14:26:04 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-02-28 18:14:23 +00:00
|
|
|
static void demux_seek_lavf(demuxer_t *demuxer, double seek_pts, int flags)
|
2011-07-03 12:42:04 +00:00
|
|
|
{
|
2004-04-11 17:20:52 +00:00
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
2006-10-05 21:25:22 +00:00
|
|
|
int avsflags = 0;
|
2016-02-28 18:14:23 +00:00
|
|
|
int64_t seek_pts_av = 0;
|
2014-11-25 18:07:52 +00:00
|
|
|
|
2016-02-28 18:14:23 +00:00
|
|
|
if (flags & SEEK_BACKWARD)
|
2009-03-19 03:25:12 +00:00
|
|
|
avsflags = AVSEEK_FLAG_BACKWARD;
|
2013-03-01 12:20:33 +00:00
|
|
|
|
2008-01-29 15:11:38 +00:00
|
|
|
if (flags & SEEK_FACTOR) {
|
2015-12-28 22:22:58 +00:00
|
|
|
struct stream *s = priv->stream;
|
2015-08-17 22:10:54 +00:00
|
|
|
int64_t end = stream_get_size(s);
|
2014-05-24 12:04:09 +00:00
|
|
|
if (end > 0 && demuxer->ts_resets_possible &&
|
2015-03-20 21:10:00 +00:00
|
|
|
!(priv->avif_flags & AVFMT_NO_BYTE_SEEK))
|
2013-03-01 12:20:33 +00:00
|
|
|
{
|
|
|
|
avsflags |= AVSEEK_FLAG_BYTE;
|
2016-02-28 18:14:23 +00:00
|
|
|
seek_pts_av = end * seek_pts;
|
2013-03-01 12:20:33 +00:00
|
|
|
} else if (priv->avfc->duration != 0 &&
|
|
|
|
priv->avfc->duration != AV_NOPTS_VALUE)
|
|
|
|
{
|
2016-02-28 18:14:23 +00:00
|
|
|
seek_pts_av = seek_pts * priv->avfc->duration;
|
2013-03-01 12:20:33 +00:00
|
|
|
}
|
|
|
|
} else {
|
2016-02-22 19:21:03 +00:00
|
|
|
if (flags & SEEK_BACKWARD)
|
2016-02-28 18:14:23 +00:00
|
|
|
seek_pts -= priv->seek_delay;
|
|
|
|
seek_pts_av = seek_pts * AV_TIME_BASE;
|
2013-03-01 12:20:33 +00:00
|
|
|
}
|
2012-12-08 12:12:46 +00:00
|
|
|
|
2016-07-24 16:41:55 +00:00
|
|
|
int r = av_seek_frame(priv->avfc, -1, seek_pts_av, avsflags);
|
|
|
|
if (r < 0 && (avsflags & AVSEEK_FLAG_BACKWARD)) {
|
|
|
|
// When seeking before the beginning of the file, and seeking fails,
|
|
|
|
// try again without the backwards flag to make it seek to the
|
|
|
|
// beginning.
|
|
|
|
avsflags &= ~AVSEEK_FLAG_BACKWARD;
|
2016-02-28 18:14:23 +00:00
|
|
|
r = av_seek_frame(priv->avfc, -1, seek_pts_av, avsflags);
|
2009-09-30 08:19:49 +00:00
|
|
|
}
|
2016-07-24 16:41:55 +00:00
|
|
|
|
2015-03-24 14:39:51 +00:00
|
|
|
if (r < 0) {
|
|
|
|
char buf[180];
|
|
|
|
av_strerror(r, buf, sizeof(buf));
|
|
|
|
MP_VERBOSE(demuxer, "Seek failed (%s)\n", buf);
|
|
|
|
}
|
2004-04-11 14:26:04 +00:00
|
|
|
}
|
|
|
|
|
2005-08-05 19:57:47 +00:00
|
|
|
static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
|
2004-04-11 14:26:04 +00:00
|
|
|
{
|
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
2008-01-26 21:45:31 +00:00
|
|
|
|
2004-04-11 14:26:04 +00:00
|
|
|
switch (cmd) {
|
2010-11-10 05:17:51 +00:00
|
|
|
case DEMUXER_CTRL_GET_TIME_LENGTH:
|
2011-07-03 12:42:04 +00:00
|
|
|
if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
|
|
|
|
return DEMUXER_CTRL_DONTKNOW;
|
2008-01-26 21:45:31 +00:00
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
*((double *)arg) = (double)priv->avfc->duration / AV_TIME_BASE;
|
|
|
|
return DEMUXER_CTRL_OK;
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2013-04-14 18:53:03 +00:00
|
|
|
case DEMUXER_CTRL_SWITCHED_TRACKS:
|
2011-07-03 12:42:04 +00:00
|
|
|
{
|
2013-07-11 17:23:31 +00:00
|
|
|
select_tracks(demuxer, 0);
|
2013-04-14 18:53:03 +00:00
|
|
|
return DEMUXER_CTRL_OK;
|
2011-07-03 12:42:04 +00:00
|
|
|
}
|
|
|
|
case DEMUXER_CTRL_IDENTIFY_PROGRAM:
|
|
|
|
{
|
|
|
|
demux_program_t *prog = arg;
|
|
|
|
AVProgram *program;
|
|
|
|
int p, i;
|
|
|
|
int start;
|
|
|
|
|
2013-04-14 18:53:03 +00:00
|
|
|
add_new_streams(demuxer);
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
prog->vid = prog->aid = prog->sid = -2;
|
|
|
|
if (priv->avfc->nb_programs < 1)
|
|
|
|
return DEMUXER_CTRL_DONTKNOW;
|
|
|
|
|
|
|
|
if (prog->progid == -1) {
|
|
|
|
p = 0;
|
|
|
|
while (p < priv->avfc->nb_programs && priv->avfc->programs[p]->id != priv->cur_program)
|
|
|
|
p++;
|
|
|
|
p = (p + 1) % priv->avfc->nb_programs;
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < priv->avfc->nb_programs; i++)
|
|
|
|
if (priv->avfc->programs[i]->id == prog->progid)
|
|
|
|
break;
|
|
|
|
if (i == priv->avfc->nb_programs)
|
2009-11-07 11:09:23 +00:00
|
|
|
return DEMUXER_CTRL_DONTKNOW;
|
2011-07-03 12:42:04 +00:00
|
|
|
p = i;
|
|
|
|
}
|
|
|
|
start = p;
|
2007-10-27 19:15:43 +00:00
|
|
|
redo:
|
2013-04-14 18:53:03 +00:00
|
|
|
prog->vid = prog->aid = prog->sid = -2;
|
2011-07-03 12:42:04 +00:00
|
|
|
program = priv->avfc->programs[p];
|
|
|
|
for (i = 0; i < program->nb_stream_indexes; i++) {
|
2013-04-14 18:53:03 +00:00
|
|
|
struct sh_stream *stream = priv->streams[program->stream_index[i]];
|
|
|
|
if (stream) {
|
|
|
|
switch (stream->type) {
|
|
|
|
case STREAM_VIDEO:
|
|
|
|
if (prog->vid == -2)
|
|
|
|
prog->vid = stream->demuxer_id;
|
|
|
|
break;
|
|
|
|
case STREAM_AUDIO:
|
|
|
|
if (prog->aid == -2)
|
|
|
|
prog->aid = stream->demuxer_id;
|
|
|
|
break;
|
|
|
|
case STREAM_SUB:
|
|
|
|
if (prog->sid == -2)
|
|
|
|
prog->sid = stream->demuxer_id;
|
|
|
|
break;
|
|
|
|
}
|
2007-10-27 19:15:43 +00:00
|
|
|
}
|
|
|
|
}
|
2011-07-03 12:42:04 +00:00
|
|
|
if (prog->progid == -1 && prog->vid == -2 && prog->aid == -2) {
|
|
|
|
p = (p + 1) % priv->avfc->nb_programs;
|
|
|
|
if (p == start)
|
|
|
|
return DEMUXER_CTRL_DONTKNOW;
|
|
|
|
goto redo;
|
|
|
|
}
|
|
|
|
priv->cur_program = prog->progid = program->id;
|
2016-01-13 00:47:12 +00:00
|
|
|
|
|
|
|
mp_tags_copy_from_av_dictionary(demuxer->metadata, priv->avfc->programs[p]->metadata);
|
|
|
|
update_metadata(demuxer, NULL);
|
|
|
|
// Enforce metadata update even if no explicit METADATA_UPDATED since we switched program.
|
|
|
|
demux_changed(demuxer, DEMUX_EVENT_METADATA);
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
return DEMUXER_CTRL_OK;
|
|
|
|
}
|
2013-01-07 16:39:55 +00:00
|
|
|
case DEMUXER_CTRL_RESYNC:
|
|
|
|
/* NOTE:
|
|
|
|
*
|
|
|
|
* We actually want to call ff_read_frame_flush() here, but it is
|
|
|
|
* internal.
|
|
|
|
*
|
|
|
|
* This function call seems to do the same for now.
|
|
|
|
*
|
|
|
|
* Once ff_read_frame_flush() is exported in some way, change this to
|
|
|
|
* call the new API instead of relying on av_seek_frame() to do this
|
|
|
|
* for us.
|
|
|
|
*/
|
2014-07-05 14:58:48 +00:00
|
|
|
// avio_flush() is designed for write-only streams, and does the wrong
|
|
|
|
// thing when reading. Flush it manually instead.
|
2015-12-28 22:22:58 +00:00
|
|
|
stream_drop_buffers(priv->stream);
|
demux_lavf: bluray: don't skip stream data when flushing
This code meant to flush demuxer internal buffers by doing a byte seek
to the current position. In theory this shouldn't drop any stream data.
However, if the stream positions mismatch, then avio_seek() (called by
av_seek_frame()) stops being a no-op, and might for example read some
data to skip to the seek target. (This can happen if the distance is
less than SHORT_SEEK_THRESHOLD.)
The positions get out of sync because we drop data at one point (which
is what we _want_ to do). Strictly speaking, the AVIOContext flushing is
done incorrectly, becuase pb->pos points to the start of the buffer, not
the current position. So we have to increment pb->pos by the buffered
amount.
Since there are other weird reasons why the positions might go out of
sync (such as stream_dvd.c dropping buffers itself), and they don't
necessarily need to be in sync in the first place unless AVIOContext has
nothing buffered internally, just use the sledgehammer approach and
correct the position manually.
Also run av_seek_frame() after this. Currently, it shouldn't read
anything, but who knows how that might change with future libavformat
development.
This whole change didn't have any observable effect for me, but I'm
hoping it fixes a reported problem.
2014-09-29 15:52:11 +00:00
|
|
|
priv->avfc->pb->buf_ptr = priv->avfc->pb->buf_end = priv->avfc->pb->buffer;
|
2015-12-28 22:22:58 +00:00
|
|
|
priv->avfc->pb->pos = stream_tell(priv->stream);
|
|
|
|
av_seek_frame(priv->avfc, 0, stream_tell(priv->stream),
|
demux_lavf: bluray: don't skip stream data when flushing
This code meant to flush demuxer internal buffers by doing a byte seek
to the current position. In theory this shouldn't drop any stream data.
However, if the stream positions mismatch, then avio_seek() (called by
av_seek_frame()) stops being a no-op, and might for example read some
data to skip to the seek target. (This can happen if the distance is
less than SHORT_SEEK_THRESHOLD.)
The positions get out of sync because we drop data at one point (which
is what we _want_ to do). Strictly speaking, the AVIOContext flushing is
done incorrectly, becuase pb->pos points to the start of the buffer, not
the current position. So we have to increment pb->pos by the buffered
amount.
Since there are other weird reasons why the positions might go out of
sync (such as stream_dvd.c dropping buffers itself), and they don't
necessarily need to be in sync in the first place unless AVIOContext has
nothing buffered internally, just use the sledgehammer approach and
correct the position manually.
Also run av_seek_frame() after this. Currently, it shouldn't read
anything, but who knows how that might change with future libavformat
development.
This whole change didn't have any observable effect for me, but I'm
hoping it fixes a reported problem.
2014-09-29 15:52:11 +00:00
|
|
|
AVSEEK_FLAG_BYTE);
|
2013-01-07 16:39:55 +00:00
|
|
|
return DEMUXER_CTRL_OK;
|
2016-08-26 11:05:14 +00:00
|
|
|
case DEMUXER_CTRL_REPLACE_STREAM:
|
|
|
|
if (priv->own_stream)
|
|
|
|
free_stream(priv->stream);
|
|
|
|
priv->own_stream = false;
|
|
|
|
priv->stream = demuxer->stream;
|
|
|
|
return DEMUXER_CTRL_OK;
|
2011-07-03 12:42:04 +00:00
|
|
|
default:
|
|
|
|
return DEMUXER_CTRL_NOTIMPL;
|
2004-04-11 14:26:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-05 19:57:47 +00:00
|
|
|
static void demux_close_lavf(demuxer_t *demuxer)
|
2004-04-11 14:26:04 +00:00
|
|
|
{
|
2011-07-03 12:42:04 +00:00
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
|
|
|
if (priv) {
|
|
|
|
if (priv->avfc) {
|
|
|
|
av_freep(&priv->avfc->key);
|
2012-01-28 11:41:36 +00:00
|
|
|
avformat_close_input(&priv->avfc);
|
2004-04-26 19:55:55 +00:00
|
|
|
}
|
2013-08-04 21:21:50 +00:00
|
|
|
if (priv->pb)
|
|
|
|
av_freep(&priv->pb->buffer);
|
2007-12-22 16:22:54 +00:00
|
|
|
av_freep(&priv->pb);
|
2015-10-19 13:27:42 +00:00
|
|
|
for (int n = 0; n < priv->num_streams; n++) {
|
2016-12-07 18:44:29 +00:00
|
|
|
if (priv->streams[n])
|
2016-05-08 11:24:22 +00:00
|
|
|
avcodec_parameters_free(&priv->streams[n]->codec->lav_codecpar);
|
2015-10-19 13:27:42 +00:00
|
|
|
}
|
2016-08-26 11:05:14 +00:00
|
|
|
if (priv->own_stream)
|
2015-12-28 22:23:30 +00:00
|
|
|
free_stream(priv->stream);
|
demux_lavf: add support for libavdevice
libavdevice supports various "special" video and audio inputs, such
as screen-capture or libavfilter filter graphs.
libavdevice inputs are implemented as demuxers. They don't use the
custom stream callbacks (in AVFormatContext.pb). Instead, input
parameters are passed as filename. This means the mpv stream layer has
to be disabled. Do this by adding the pseudo stream handler avdevice://,
whose only purpose is passing the filename to demux_lavf, without
actually doing anything.
Change the logic how the filename is passed to libavformat. Remove
handling of the filename from demux_open_lavf() and move it to
lavf_check_file(). (This also fixes a possible bug when skipping the
"lavf://" prefix.)
libavdevice now can be invoked by specifying demuxer and args as in:
mpv avdevice://demuxer:args
The args are passed as filename to libavformat. When using libavdevice
demuxers, their actual meaning is highly implementation specific. They
don't refer to actual filenames.
Note:
libavdevice is disabled by default. There is one problem: libavdevice
pulls in libavfilter, which in turn causes symbol clashes with mpv
internals. The problem is that libavfilter includes a mplayer filter
bridge, which is used to interface with a set of nearly unmodified
mplayer filters copied into libavfilter. This filter bridge uses the
same symbol names as mplayer/mpv's filter chain, which results in symbol
clashes at link-time.
This can be prevented by building ffmpeg with --disable-filter=mp, but
unfortunately this is not the default.
This means linking to libavdevice (which in turn forces linking with
libavfilter by default) must be disabled. We try doing this by compiling
a test file that defines one of the clashing symbols (vf_mpi_clear).
To enable libavdevice input, ffmpeg should be built with the options:
--disable-filter=mp
and mpv with:
--enable-libavdevice
Originally, I tried to auto-detect it. But the resulting complications
in configure did't seem worth the trouble.
2012-11-30 17:41:04 +00:00
|
|
|
talloc_free(priv);
|
2011-07-03 12:42:04 +00:00
|
|
|
demuxer->priv = NULL;
|
2004-04-11 14:26:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-05 19:57:47 +00:00
|
|
|
|
2008-01-13 16:00:39 +00:00
|
|
|
const demuxer_desc_t demuxer_desc_lavf = {
|
2013-07-11 18:08:12 +00:00
|
|
|
.name = "lavf",
|
2013-07-12 20:12:02 +00:00
|
|
|
.desc = "libavformat",
|
2013-07-11 18:08:12 +00:00
|
|
|
.fill_buffer = demux_lavf_fill_buffer,
|
|
|
|
.open = demux_open_lavf,
|
|
|
|
.close = demux_close_lavf,
|
|
|
|
.seek = demux_seek_lavf,
|
|
|
|
.control = demux_lavf_control,
|
2007-04-14 10:03:42 +00:00
|
|
|
};
|