2004-04-11 14:26:04 +00:00
|
|
|
/*
|
2008-05-14 18:01:51 +00:00
|
|
|
* Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
|
|
|
|
*
|
|
|
|
* This file is part of MPlayer.
|
|
|
|
*
|
|
|
|
* MPlayer is free software; you can redistribute it and/or modify
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* MPlayer is distributed in the hope that it will be useful,
|
|
|
|
* 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
|
|
|
|
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
2004-04-11 14:26:04 +00:00
|
|
|
|
|
|
|
// #include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
// #include <unistd.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>
|
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
|
|
|
|
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>
|
|
|
|
#include <libavutil/opt.h>
|
2012-11-09 00:06:43 +00:00
|
|
|
#include "compat/libav.h"
|
2012-01-28 11:41:36 +00:00
|
|
|
|
2004-04-11 14:26:04 +00:00
|
|
|
#include "config.h"
|
2012-11-09 00:06:43 +00:00
|
|
|
#include "core/options.h"
|
|
|
|
#include "core/mp_msg.h"
|
|
|
|
#include "core/av_opts.h"
|
core: redo how codecs are mapped, remove codecs.conf
Use codec names instead of FourCCs to identify codecs. Rewrite how
codecs are selected and initialized. Now each decoder exports a list
of decoders (and the codec it supports) via add_decoders(). The order
matters, and the first decoder for a given decoder is preferred over
the other decoders. E.g. all ad_mpg123 decoders are preferred over
ad_lavc, because it comes first in the mpcodecs_ad_drivers array.
Likewise, decoders within ad_lavc that are enumerated first by
libavcodec (using av_codec_next()) are preferred. (This is actually
critical to select h264 software decoding by default instead of vdpau.
libavcodec and ffmpeg/avconv use the same method to select decoders by
default, so we hope this is sane.)
The codec names follow libavcodec's codec names as defined by
AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders
have names different from the canonical codec name. The AVCodecDescriptor
API is relatively new, so we need a compatibility layer for older
libavcodec versions for codec names that are referenced internally,
and which are different from the decoder name. (Add a configure check
for that, because checking versions is getting way too messy.)
demux/codec_tags.c is generated from the former codecs.conf (minus
"special" decoders like vdpau, and excluding the mappings that are the
same as the mappings libavformat's exported RIFF tables). It contains
all the mappings from FourCCs to codec name. This is needed for
demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the
codec as determined by libavformat, while the other demuxers have to do
this on their own, using the mp_set_audio/video_codec_from_tag()
functions. Note that the sh_audio/video->format members don't uniquely
identify the codec anymore, and sh->codec takes over this role.
Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which
provide cover the functionality of the removed switched.
Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure
container/video combinations (e.g. the sample Film_200_zygo_pro.mov)
are played flipped. ffplay/avplay doesn't handle this properly either,
so we don't care and blame ffmeg/libav instead.
2013-02-09 14:15:19 +00:00
|
|
|
#include "core/av_common.h"
|
2012-11-09 00:06:43 +00:00
|
|
|
#include "core/bstr.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"
|
2012-11-09 00:06:43 +00:00
|
|
|
#include "core/m_option.h"
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2010-03-22 19:38:42 +00:00
|
|
|
#define INITIAL_PROBE_SIZE STREAM_BUFFER_SIZE
|
2011-07-03 12:42:04 +00:00
|
|
|
#define PROBE_BUF_SIZE (2 * 1024 * 1024)
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2013-03-01 10:27:59 +00:00
|
|
|
#define OPT_BASE_STRUCT struct MPOpts
|
|
|
|
|
2007-12-02 21:26:23 +00:00
|
|
|
const m_option_t lavfdopts_conf[] = {
|
2010-04-23 19:08:18 +00:00
|
|
|
OPT_INTRANGE("probesize", lavfdopts.probesize, 0, 32, INT_MAX),
|
|
|
|
OPT_STRING("format", lavfdopts.format, 0),
|
|
|
|
OPT_INTRANGE("analyzeduration", lavfdopts.analyzeduration, 0, 0, INT_MAX),
|
2012-12-08 19:14:13 +00:00
|
|
|
OPT_INTRANGE("probescore", lavfdopts.probescore, 0, 0, 100),
|
2010-04-23 19:08:18 +00:00
|
|
|
OPT_STRING("cryptokey", lavfdopts.cryptokey, 0),
|
|
|
|
OPT_STRING("o", lavfdopts.avopt, 0),
|
|
|
|
{NULL, NULL, 0, 0, 0, 0, NULL}
|
2006-08-30 22:25:40 +00:00
|
|
|
};
|
|
|
|
|
2007-12-22 16:22:54 +00:00
|
|
|
#define BIO_BUFFER_SIZE 32768
|
2006-06-21 19:24:17 +00:00
|
|
|
|
2010-04-23 20:50:34 +00:00
|
|
|
typedef struct lavf_priv {
|
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 *filename;
|
2004-04-11 14:26:04 +00:00
|
|
|
AVInputFormat *avif;
|
|
|
|
AVFormatContext *avfc;
|
2011-12-22 00:06:52 +00:00
|
|
|
AVIOContext *pb;
|
2010-02-12 20:38:29 +00:00
|
|
|
uint8_t buffer[BIO_BUFFER_SIZE];
|
2004-04-11 14:26:04 +00:00
|
|
|
int audio_streams;
|
|
|
|
int video_streams;
|
2007-07-13 21:15:24 +00:00
|
|
|
int sub_streams;
|
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
|
|
|
int autoselect_sub;
|
2004-04-11 17:20:52 +00:00
|
|
|
int64_t last_pts;
|
2006-06-20 19:57:16 +00:00
|
|
|
int astreams[MAX_A_STREAMS];
|
2006-11-20 23:31:01 +00:00
|
|
|
int vstreams[MAX_V_STREAMS];
|
2007-07-13 21:15:24 +00:00
|
|
|
int sstreams[MAX_S_STREAMS];
|
2007-10-27 19:12:59 +00:00
|
|
|
int cur_program;
|
2010-10-04 18:12:36 +00:00
|
|
|
int nb_streams_last;
|
2010-11-06 21:17:16 +00:00
|
|
|
bool use_dts;
|
2010-11-10 05:17:51 +00:00
|
|
|
bool seek_by_bytes;
|
|
|
|
int bitrate;
|
2012-12-10 00:28:20 +00:00
|
|
|
char *mime_type;
|
2011-07-03 12:42:04 +00:00
|
|
|
} lavf_priv_t;
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2012-12-10 00:28:20 +00:00
|
|
|
static const char *map_demuxer_mime_type[][2] = {
|
|
|
|
{"audio/aacp", "aac"},
|
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *find_demuxer_from_mime_type(char *mime_type)
|
|
|
|
{
|
|
|
|
for (int n = 0; map_demuxer_mime_type[n][0]; n++) {
|
|
|
|
if (strcasecmp(map_demuxer_mime_type[n][0], mime_type) == 0)
|
|
|
|
return map_demuxer_mime_type[n][1];
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
struct stream *stream = demuxer->stream;
|
2004-04-11 14:51:10 +00:00
|
|
|
int ret;
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
ret = stream_read(stream, buf, size);
|
2004-04-11 15:04:54 +00:00
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
mp_msg(MSGT_HEADER, MSGL_DBG2,
|
|
|
|
"%d=mp_read(%p, %p, %d), pos: %"PRId64", eof:%d\n",
|
2010-06-05 16:14:56 +00:00
|
|
|
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;
|
|
|
|
struct stream *stream = demuxer->stream;
|
2008-10-03 14:54:22 +00:00
|
|
|
int64_t current_pos;
|
2011-07-03 12:42:04 +00:00
|
|
|
mp_msg(MSGT_HEADER, MSGL_DBG2, "mp_seek(%p, %"PRId64", %d)\n",
|
|
|
|
stream, pos, whence);
|
|
|
|
if (whence == SEEK_CUR)
|
|
|
|
pos += stream_tell(stream);
|
|
|
|
else if (whence == SEEK_END && stream->end_pos > 0)
|
2004-04-11 14:26:04 +00:00
|
|
|
pos += stream->end_pos;
|
2011-07-03 12:42:04 +00:00
|
|
|
else if (whence == SEEK_SET)
|
2007-03-04 16:23:18 +00:00
|
|
|
pos += stream->start_pos;
|
2012-02-26 03:53:13 +00:00
|
|
|
else if (whence == AVSEEK_SIZE && stream->end_pos > 0) {
|
2012-11-18 20:23:17 +00:00
|
|
|
stream_update_size(stream);
|
2007-08-20 09:27:47 +00:00
|
|
|
return stream->end_pos - stream->start_pos;
|
2012-02-26 03:53:13 +00:00
|
|
|
} else
|
2004-04-11 14:26:04 +00:00
|
|
|
return -1;
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
if (pos < 0)
|
2007-08-19 21:22:27 +00:00
|
|
|
return -1;
|
2008-08-13 00:01:31 +00:00
|
|
|
current_pos = stream_tell(stream);
|
2011-07-03 12:42:04 +00:00
|
|
|
if (stream_seek(stream, pos) == 0) {
|
2008-08-13 00:01:31 +00:00
|
|
|
stream_reset(stream);
|
|
|
|
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
|
|
|
|
2007-03-04 16:23:18 +00:00
|
|
|
return pos - stream->start_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;
|
|
|
|
struct stream *stream = demuxer->stream;
|
|
|
|
struct lavf_priv *priv = demuxer->priv;
|
|
|
|
|
|
|
|
AVStream *st = priv->avfc->streams[stream_idx];
|
|
|
|
double pts = (double)ts * st->time_base.num / st->time_base.den;
|
|
|
|
int ret = stream_control(stream, STREAM_CTRL_SEEK_TO_TIME, &pts);
|
|
|
|
if (ret < 0)
|
|
|
|
ret = AVERROR(ENOSYS);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
static void list_formats(void)
|
|
|
|
{
|
2007-02-06 22:15:20 +00:00
|
|
|
mp_msg(MSGT_DEMUX, MSGL_INFO, "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)))
|
2007-02-06 22:15:20 +00:00
|
|
|
mp_msg(MSGT_DEMUX, MSGL_INFO, "%15s : %s\n", fmt->name, fmt->long_name);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
static char *remove_prefix(char *s, const char **prefixes)
|
|
|
|
{
|
|
|
|
for (int n = 0; prefixes[n]; n++) {
|
|
|
|
int len = strlen(prefixes[n]);
|
|
|
|
if (strncmp(s, prefixes[n], len) == 0)
|
|
|
|
return s + len;
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *prefixes[] =
|
|
|
|
{"ffmpeg://", "lavf://", "avdevice://", "av://", NULL};
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
static int lavf_check_file(demuxer_t *demuxer)
|
|
|
|
{
|
2010-04-23 19:08:18 +00:00
|
|
|
struct MPOpts *opts = demuxer->opts;
|
|
|
|
struct lavfdopts *lavfdopts = &opts->lavfdopts;
|
2004-04-11 14:26:04 +00:00
|
|
|
AVProbeData avpd;
|
|
|
|
lavf_priv_t *priv;
|
2010-02-12 20:38:29 +00:00
|
|
|
int probe_data_size = 0;
|
|
|
|
int read_size = INITIAL_PROBE_SIZE;
|
2010-05-01 13:50:49 +00:00
|
|
|
int score;
|
2008-01-26 21:45:31 +00:00
|
|
|
|
2012-12-08 19:14:13 +00:00
|
|
|
assert(!demuxer->priv);
|
|
|
|
demuxer->priv = talloc_zero(NULL, lavf_priv_t);
|
2011-07-03 12:42:04 +00:00
|
|
|
priv = demuxer->priv;
|
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
|
|
|
priv->autoselect_sub = -1;
|
2004-04-11 14:26:04 +00:00
|
|
|
|
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
|
|
|
priv->filename = demuxer->stream->url;
|
|
|
|
if (!priv->filename) {
|
|
|
|
priv->filename = "mp:unknown";
|
|
|
|
mp_msg(MSGT_DEMUX, MSGL_WARN, "Stream url is not set!\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
priv->filename = remove_prefix(priv->filename, prefixes);
|
|
|
|
|
|
|
|
char *avdevice_format = NULL;
|
|
|
|
if (demuxer->stream->type == STREAMTYPE_AVDEVICE) {
|
|
|
|
// always require filename in the form "format:filename"
|
|
|
|
char *sep = strchr(priv->filename, ':');
|
|
|
|
if (!sep) {
|
|
|
|
mp_msg(MSGT_DEMUX, MSGL_FATAL,
|
2012-12-08 19:14:13 +00:00
|
|
|
"Must specify filename in 'format:filename' form\n");
|
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
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
avdevice_format = talloc_strndup(priv, priv->filename,
|
|
|
|
sep - priv->filename);
|
|
|
|
priv->filename = sep + 1;
|
|
|
|
}
|
|
|
|
|
2010-04-23 19:57:25 +00:00
|
|
|
char *format = lavfdopts->format;
|
|
|
|
if (!format)
|
|
|
|
format = demuxer->stream->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;
|
2012-12-10 00:28:20 +00:00
|
|
|
if (!format && demuxer->stream->mime_type)
|
|
|
|
format = (char *)find_demuxer_from_mime_type(demuxer->stream->mime_type);
|
2010-04-23 19:57:25 +00:00
|
|
|
if (format) {
|
|
|
|
if (strcmp(format, "help") == 0) {
|
2011-07-03 12:42:04 +00:00
|
|
|
list_formats();
|
|
|
|
return 0;
|
2007-02-06 22:15:20 +00:00
|
|
|
}
|
2010-04-23 19:57:25 +00:00
|
|
|
priv->avif = av_find_input_format(format);
|
2007-02-06 22:15:20 +00:00
|
|
|
if (!priv->avif) {
|
2010-04-23 19:57:25 +00:00
|
|
|
mp_msg(MSGT_DEMUX, MSGL_FATAL, "Unknown lavf format %s\n", format);
|
2007-02-06 22:15:20 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2011-07-03 12:42:04 +00:00
|
|
|
mp_msg(MSGT_DEMUX, MSGL_INFO, "Forced lavf %s demuxer\n",
|
|
|
|
priv->avif->long_name);
|
2012-12-08 19:14:13 +00:00
|
|
|
goto success;
|
2007-02-06 22:15:20 +00:00
|
|
|
}
|
2009-06-01 09:39:02 +00:00
|
|
|
|
2012-12-13 11:47:19 +00:00
|
|
|
// AVPROBE_SCORE_MAX/4 + 1 is the "recommended" limit. Below that, the user
|
2012-12-08 19:14:13 +00:00
|
|
|
// is supposed to retry with larger probe sizes until a higher value is
|
|
|
|
// reached.
|
2012-12-13 11:47:19 +00:00
|
|
|
int min_probe = AVPROBE_SCORE_MAX/4 + 1;
|
2012-12-08 19:14:13 +00:00
|
|
|
if (lavfdopts->probescore)
|
|
|
|
min_probe = lavfdopts->probescore;
|
|
|
|
|
2010-02-12 20:38:29 +00:00
|
|
|
avpd.buf = av_mallocz(FFMAX(BIO_BUFFER_SIZE, PROBE_BUF_SIZE) +
|
|
|
|
FF_INPUT_BUFFER_PADDING_SIZE);
|
|
|
|
do {
|
2011-07-03 12:42:04 +00:00
|
|
|
read_size = stream_read(demuxer->stream, avpd.buf + probe_data_size,
|
|
|
|
read_size);
|
|
|
|
if (read_size < 0) {
|
2010-03-22 19:39:43 +00:00
|
|
|
av_free(avpd.buf);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
probe_data_size += read_size;
|
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
|
|
|
avpd.filename = priv->filename;
|
2011-07-03 12:42:04 +00:00
|
|
|
avpd.buf_size = probe_data_size;
|
2010-03-22 19:39:43 +00:00
|
|
|
|
2010-05-01 13:50:49 +00:00
|
|
|
score = 0;
|
2011-07-03 12:42:04 +00:00
|
|
|
priv->avif = av_probe_input_format2(&avpd, probe_data_size > 0, &score);
|
2012-12-08 19:14:13 +00:00
|
|
|
|
|
|
|
if (priv->avif) {
|
|
|
|
mp_msg(MSGT_HEADER, MSGL_V, "Found '%s' at score=%d size=%d.\n",
|
|
|
|
priv->avif->name, score, probe_data_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (priv->avif && score >= min_probe)
|
|
|
|
break;
|
|
|
|
|
|
|
|
priv->avif = NULL;
|
2011-07-03 12:42:04 +00:00
|
|
|
read_size = FFMIN(2 * read_size, PROBE_BUF_SIZE - probe_data_size);
|
2012-12-08 19:14:13 +00:00
|
|
|
} while (read_size > 0 && probe_data_size < PROBE_BUF_SIZE);
|
2010-02-12 20:38:29 +00:00
|
|
|
av_free(avpd.buf);
|
|
|
|
|
2012-12-08 19:14:13 +00:00
|
|
|
if (!priv->avif) {
|
2011-07-03 12:42:04 +00:00
|
|
|
mp_msg(MSGT_HEADER, MSGL_V,
|
2012-12-08 19:14:13 +00:00
|
|
|
"No format found, try lowering probescore.\n");
|
2004-04-11 14:26:04 +00:00
|
|
|
return 0;
|
2012-12-08 19:14:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
success:
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2010-11-10 13:38:36 +00:00
|
|
|
demuxer->filetype = priv->avif->long_name;
|
|
|
|
if (!demuxer->filetype)
|
|
|
|
demuxer->filetype = priv->avif->name;
|
|
|
|
|
2005-08-05 19:57:47 +00:00
|
|
|
return DEMUXER_TYPE_LAVF;
|
2004-04-11 14:26:04 +00:00
|
|
|
}
|
2007-04-14 10:03:42 +00:00
|
|
|
|
2010-11-05 10:50:11 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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]);
|
|
|
|
}
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i)
|
|
|
|
{
|
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
|
|
|
AVStream *st = avfc->streams[i];
|
|
|
|
AVCodecContext *codec = st->codec;
|
2013-02-09 14:15:28 +00:00
|
|
|
struct sh_stream *sh = NULL;
|
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_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
|
|
|
sh_audio_t *sh_audio = new_sh_audio_aid(demuxer, i, priv->audio_streams);
|
2011-07-03 12:42:04 +00:00
|
|
|
if (!sh_audio)
|
2007-10-27 19:00:07 +00:00
|
|
|
break;
|
2013-02-09 14:15:28 +00:00
|
|
|
sh = sh_audio->gsh;
|
2011-07-03 12:42:04 +00:00
|
|
|
priv->astreams[priv->audio_streams] = i;
|
|
|
|
sh_audio->ds = demuxer->audio;
|
|
|
|
sh_audio->format = codec->codec_tag;
|
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
|
2011-07-03 12:42:04 +00:00
|
|
|
sh_audio->channels = codec->channels;
|
|
|
|
sh_audio->samplerate = codec->sample_rate;
|
|
|
|
sh_audio->i_bps = codec->bit_rate / 8;
|
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
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
st->discard = AVDISCARD_ALL;
|
2013-02-09 14:15:28 +00:00
|
|
|
priv->audio_streams++;
|
2011-07-03 12:42:04 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AVMEDIA_TYPE_VIDEO: {
|
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
|
|
|
sh_video_t *sh_video = new_sh_video_vid(demuxer, i, priv->video_streams);
|
2011-07-03 12:42:04 +00:00
|
|
|
if (!sh_video)
|
2007-10-27 19:00:07 +00:00
|
|
|
break;
|
2013-02-09 14:15:28 +00:00
|
|
|
sh = sh_video->gsh;
|
2011-07-03 12:42:04 +00:00
|
|
|
priv->vstreams[priv->video_streams] = i;
|
2012-12-10 17:52:06 +00:00
|
|
|
if (st->disposition & AV_DISPOSITION_ATTACHED_PIC)
|
|
|
|
sh_video->gsh->attached_picture = true;
|
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
|
|
|
|
|
|
|
sh_video->format = codec->codec_tag;
|
2011-07-03 12:42:04 +00:00
|
|
|
sh_video->disp_w = codec->width;
|
|
|
|
sh_video->disp_h = codec->height;
|
2012-04-13 23:43:40 +00:00
|
|
|
/* Try to make up some frame rate value, even if it's not reliable.
|
|
|
|
* FPS information is needed to support subtitle formats which base
|
|
|
|
* timing on frame numbers.
|
|
|
|
* Libavformat seems to report no "reliable" FPS value for AVI files,
|
|
|
|
* while they are typically constant enough FPS that the value this
|
|
|
|
* heuristic makes up works with subtitles in practice.
|
|
|
|
*/
|
|
|
|
double fps;
|
|
|
|
if (st->r_frame_rate.num)
|
|
|
|
fps = av_q2d(st->r_frame_rate);
|
|
|
|
else
|
|
|
|
fps = 1.0 / FFMAX(av_q2d(st->time_base),
|
|
|
|
av_q2d(st->codec->time_base) *
|
|
|
|
st->codec->ticks_per_frame);
|
|
|
|
sh_video->fps = fps;
|
|
|
|
sh_video->frametime = 1 / fps;
|
2011-07-03 12:42:04 +00:00
|
|
|
if (st->sample_aspect_ratio.num)
|
|
|
|
sh_video->aspect = codec->width * st->sample_aspect_ratio.num
|
|
|
|
/ (float)(codec->height * st->sample_aspect_ratio.den);
|
|
|
|
else
|
|
|
|
sh_video->aspect = codec->width * codec->sample_aspect_ratio.num
|
|
|
|
/ (float)(codec->height * codec->sample_aspect_ratio.den);
|
|
|
|
sh_video->i_bps = codec->bit_rate / 8;
|
2013-02-09 14:15:28 +00:00
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
mp_msg(MSGT_DEMUX, MSGL_DBG2, "aspect= %d*%d/(%d*%d)\n",
|
|
|
|
codec->width, codec->sample_aspect_ratio.num,
|
|
|
|
codec->height, codec->sample_aspect_ratio.den);
|
|
|
|
|
|
|
|
sh_video->ds = demuxer->video;
|
|
|
|
if (demuxer->video->id != priv->video_streams
|
|
|
|
&& demuxer->video->id != -1)
|
|
|
|
st->discard = AVDISCARD_ALL;
|
|
|
|
else {
|
|
|
|
demuxer->video->id = i;
|
|
|
|
demuxer->video->sh = demuxer->v_streams[i];
|
2007-10-27 19:00:07 +00:00
|
|
|
}
|
2013-02-09 14:15:28 +00:00
|
|
|
priv->video_streams++;
|
2011-07-03 12:42:04 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AVMEDIA_TYPE_SUBTITLE: {
|
|
|
|
sh_sub_t *sh_sub;
|
|
|
|
char type;
|
2012-08-25 10:52:00 +00:00
|
|
|
if (codec->codec_id == CODEC_ID_TEXT ||
|
|
|
|
codec->codec_id == AV_CODEC_ID_SUBRIP)
|
2011-07-03 12:42:04 +00:00
|
|
|
type = 't';
|
|
|
|
else if (codec->codec_id == CODEC_ID_MOV_TEXT)
|
|
|
|
type = 'm';
|
|
|
|
else if (codec->codec_id == CODEC_ID_SSA)
|
|
|
|
type = 'a';
|
|
|
|
else if (codec->codec_id == CODEC_ID_DVD_SUBTITLE)
|
|
|
|
type = 'v';
|
|
|
|
else if (codec->codec_id == CODEC_ID_XSUB)
|
|
|
|
type = 'x';
|
|
|
|
else if (codec->codec_id == CODEC_ID_DVB_SUBTITLE)
|
|
|
|
type = 'b';
|
|
|
|
else if (codec->codec_id == CODEC_ID_DVB_TELETEXT)
|
|
|
|
type = 'd';
|
|
|
|
else if (codec->codec_id == CODEC_ID_HDMV_PGS_SUBTITLE)
|
|
|
|
type = 'p';
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
sh_sub = new_sh_sub_sid(demuxer, i, priv->sub_streams);
|
|
|
|
if (!sh_sub)
|
2008-01-30 08:10:25 +00:00
|
|
|
break;
|
2013-02-09 14:15:28 +00:00
|
|
|
sh = sh_sub->gsh;
|
2011-07-03 12:42:04 +00:00
|
|
|
priv->sstreams[priv->sub_streams] = i;
|
|
|
|
sh_sub->type = type;
|
|
|
|
if (codec->extradata_size) {
|
|
|
|
sh_sub->extradata = malloc(codec->extradata_size);
|
|
|
|
memcpy(sh_sub->extradata, codec->extradata, codec->extradata_size);
|
|
|
|
sh_sub->extradata_len = codec->extradata_size;
|
2008-01-30 08:10:25 +00:00
|
|
|
}
|
2013-02-09 14:15:28 +00:00
|
|
|
priv->sub_streams++;
|
2011-07-03 12:42:04 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AVMEDIA_TYPE_ATTACHMENT: {
|
2011-12-22 00:06:52 +00:00
|
|
|
AVDictionaryEntry *ftag = av_dict_get(st->metadata, "filename",
|
2011-07-03 12:42:04 +00:00
|
|
|
NULL, 0);
|
|
|
|
char *filename = ftag ? ftag->value : NULL;
|
|
|
|
if (st->codec->codec_id == CODEC_ID_TTF)
|
2012-07-28 21:47:42 +00:00
|
|
|
demuxer_add_attachment(demuxer, bstr0(filename),
|
|
|
|
bstr0("application/x-truetype-font"),
|
2011-07-03 12:42:04 +00:00
|
|
|
(struct bstr){codec->extradata,
|
|
|
|
codec->extradata_size});
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
st->discard = AVDISCARD_ALL;
|
2004-04-11 14:26:04 +00:00
|
|
|
}
|
2013-02-09 14:15:28 +00:00
|
|
|
if (sh) {
|
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
|
|
|
sh->codec = mp_codec_from_av_codec_id(codec->codec_id);
|
|
|
|
sh->lav_headers = avcodec_alloc_context3(codec->codec);
|
|
|
|
assert(sh->lav_headers);
|
|
|
|
avcodec_copy_context(sh->lav_headers, codec);
|
|
|
|
|
2013-02-09 14:15:28 +00:00
|
|
|
if (st->disposition & AV_DISPOSITION_DEFAULT)
|
|
|
|
sh->default_track = 1;
|
|
|
|
if (matches_avinputformat_name(priv, "mpeg"))
|
|
|
|
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);
|
|
|
|
AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
|
|
|
|
if (lang && lang->value)
|
|
|
|
sh->lang = talloc_strdup(sh, lang->value);
|
2010-05-03 22:45:00 +00:00
|
|
|
}
|
2007-10-27 19:00:07 +00:00
|
|
|
}
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
|
|
|
|
{
|
2008-04-16 04:11:12 +00:00
|
|
|
struct MPOpts *opts = demuxer->opts;
|
2010-04-23 19:08:18 +00:00
|
|
|
struct lavfdopts *lavfdopts = &opts->lavfdopts;
|
2007-10-27 19:00:07 +00:00
|
|
|
AVFormatContext *avfc;
|
2011-12-22 00:06:52 +00:00
|
|
|
AVDictionaryEntry *t = NULL;
|
2011-07-03 12:42:04 +00:00
|
|
|
lavf_priv_t *priv = demuxer->priv;
|
2007-10-30 15:49:53 +00:00
|
|
|
int i;
|
2007-10-27 19:00:07 +00:00
|
|
|
|
2012-12-08 19:14:13 +00:00
|
|
|
// do not allow forcing the demuxer
|
|
|
|
if (!priv->avif)
|
|
|
|
return NULL;
|
|
|
|
|
2007-10-27 19:00:07 +00:00
|
|
|
stream_seek(demuxer->stream, 0);
|
|
|
|
|
2009-11-22 14:15:41 +00:00
|
|
|
avfc = avformat_alloc_context();
|
2007-10-27 19:00:07 +00:00
|
|
|
|
2010-04-23 19:08:18 +00:00
|
|
|
if (lavfdopts->cryptokey)
|
|
|
|
parse_cryptokey(avfc, lavfdopts->cryptokey);
|
2010-11-06 21:17:16 +00:00
|
|
|
if (matches_avinputformat_name(priv, "avi")) {
|
|
|
|
/* for avi libavformat returns the avi timestamps in .dts,
|
|
|
|
* some made-up stuff that's not really pts in .pts */
|
|
|
|
priv->use_dts = true;
|
2010-11-14 09:53:27 +00:00
|
|
|
demuxer->timestamp_type = TIMESTAMP_TYPE_SORT;
|
2010-11-06 21:17:16 +00:00
|
|
|
} else {
|
|
|
|
if (opts->user_correct_pts != 0)
|
|
|
|
avfc->flags |= AVFMT_FLAG_GENPTS;
|
|
|
|
}
|
2007-10-27 19:00:07 +00:00
|
|
|
if (index_mode == 0)
|
|
|
|
avfc->flags |= AVFMT_FLAG_IGNIDX;
|
|
|
|
|
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)
|
2011-07-03 12:42:04 +00:00
|
|
|
mp_msg(MSGT_HEADER, MSGL_ERR,
|
|
|
|
"demux_lavf, couldn't set option probesize to %u\n",
|
|
|
|
lavfdopts->probesize);
|
2007-10-27 19:00:07 +00:00
|
|
|
}
|
2010-04-23 19:08:18 +00:00
|
|
|
if (lavfdopts->analyzeduration) {
|
2012-01-28 11:41:36 +00:00
|
|
|
if (av_opt_set_int(avfc, "analyzeduration",
|
|
|
|
lavfdopts->analyzeduration * AV_TIME_BASE, 0) < 0)
|
2010-04-23 19:08:18 +00:00
|
|
|
mp_msg(MSGT_HEADER, MSGL_ERR, "demux_lavf, couldn't set option "
|
|
|
|
"analyzeduration to %u\n", lavfdopts->analyzeduration);
|
2007-10-27 19:00:07 +00:00
|
|
|
}
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
if (lavfdopts->avopt) {
|
|
|
|
if (parse_avopts(avfc, lavfdopts->avopt) < 0) {
|
|
|
|
mp_msg(MSGT_HEADER, MSGL_ERR,
|
|
|
|
"Your options /%s/ look like gibberish to me pal\n",
|
|
|
|
lavfdopts->avopt);
|
2008-05-10 19:29:38 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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 (!(priv->avif->flags & AVFMT_NOFILE) &&
|
|
|
|
demuxer->stream->type != STREAMTYPE_AVDEVICE)
|
|
|
|
{
|
2011-12-22 00:06:52 +00:00
|
|
|
priv->pb = avio_alloc_context(priv->buffer, BIO_BUFFER_SIZE, 0,
|
|
|
|
demuxer, mp_read, NULL, mp_seek);
|
2011-06-21 20:28:53 +00:00
|
|
|
priv->pb->read_seek = mp_read_seek;
|
2011-12-22 00:06:52 +00:00
|
|
|
priv->pb->seekable = demuxer->stream->end_pos
|
|
|
|
&& (demuxer->stream->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK
|
|
|
|
? AVIO_SEEKABLE_NORMAL : 0;
|
|
|
|
avfc->pb = priv->pb;
|
2011-06-21 20:28:53 +00:00
|
|
|
}
|
2008-01-26 21:45:31 +00:00
|
|
|
|
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 (avformat_open_input(&avfc, priv->filename, priv->avif, NULL) < 0) {
|
2011-07-03 12:42:04 +00:00
|
|
|
mp_msg(MSGT_HEADER, MSGL_ERR,
|
2011-12-22 00:06:52 +00:00
|
|
|
"LAVF_header: avformat_open_input() failed\n");
|
2007-10-27 19:00:07 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
priv->avfc = avfc;
|
2012-01-28 11:41:36 +00:00
|
|
|
if (avformat_find_stream_info(avfc, NULL) < 0) {
|
2011-07-03 12:42:04 +00:00
|
|
|
mp_msg(MSGT_HEADER, MSGL_ERR,
|
|
|
|
"LAVF_header: av_find_stream_info() failed\n");
|
2007-10-27 19:00:07 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2009-08-11 23:26:42 +00:00
|
|
|
/* Add metadata. */
|
2011-12-22 00:06:52 +00:00
|
|
|
while ((t = av_dict_get(avfc->metadata, "", t,
|
2012-01-28 11:41:36 +00:00
|
|
|
AV_DICT_IGNORE_SUFFIX)))
|
2009-08-11 23:26:42 +00:00
|
|
|
demux_info_add(demuxer, t->key, t->value);
|
2007-10-27 19:00:07 +00:00
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
for (i = 0; i < avfc->nb_chapters; i++) {
|
2008-06-16 15:54:29 +00:00
|
|
|
AVChapter *c = avfc->chapters[i];
|
2011-07-03 12:42:04 +00:00
|
|
|
uint64_t start = av_rescale_q(c->start, c->time_base,
|
|
|
|
(AVRational){1, 1000000000});
|
|
|
|
uint64_t end = av_rescale_q(c->end, c->time_base,
|
|
|
|
(AVRational){1, 1000000000});
|
2011-12-22 00:06:52 +00:00
|
|
|
t = av_dict_get(c->metadata, "title", NULL, 0);
|
2012-07-28 21:47:42 +00:00
|
|
|
demuxer_add_chapter(demuxer, t ? bstr0(t->value) : bstr0(NULL),
|
2011-07-03 12:42:04 +00:00
|
|
|
start, end);
|
2008-06-16 15:54:29 +00:00
|
|
|
}
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
for (i = 0; i < avfc->nb_streams; i++)
|
2009-09-08 08:55:05 +00:00
|
|
|
handle_stream(demuxer, avfc, i);
|
2010-10-04 18:12:36 +00:00
|
|
|
priv->nb_streams_last = avfc->nb_streams;
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
if (avfc->nb_programs) {
|
2009-11-07 11:15:26 +00:00
|
|
|
int p;
|
|
|
|
for (p = 0; p < avfc->nb_programs; p++) {
|
2007-10-27 19:12:59 +00:00
|
|
|
AVProgram *program = avfc->programs[p];
|
2011-12-22 00:06:52 +00:00
|
|
|
t = av_dict_get(program->metadata, "title", NULL, 0);
|
2011-07-03 12:42:04 +00:00
|
|
|
mp_msg(MSGT_HEADER, MSGL_INFO, "LAVF: Program %d %s\n",
|
|
|
|
program->id, t ? t->value : "");
|
2010-11-06 14:41:23 +00:00
|
|
|
mp_msg(MSGT_IDENTIFY, MSGL_V, "PROGRAM_ID=%d\n", program->id);
|
2009-11-07 11:15:26 +00:00
|
|
|
}
|
2009-09-08 08:55:05 +00:00
|
|
|
}
|
2008-01-26 21:45:31 +00:00
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
mp_msg(MSGT_HEADER, MSGL_V, "LAVF: %d audio and %d video streams found\n",
|
|
|
|
priv->audio_streams, priv->video_streams);
|
|
|
|
mp_msg(MSGT_HEADER, MSGL_V, "LAVF: build %d\n", LIBAVFORMAT_BUILD);
|
2011-04-02 19:39:01 +00:00
|
|
|
demuxer->audio->id = -2; // wait for higher-level code to select track
|
2011-07-03 12:42:04 +00:00
|
|
|
if (!priv->video_streams) {
|
2012-11-15 20:09:15 +00:00
|
|
|
demuxer->video->id = -2; // audio-only / sub-only
|
2011-07-03 12:42:04 +00:00
|
|
|
}
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2013-03-01 12:20:33 +00:00
|
|
|
demuxer->ts_resets_possible = priv->avif->flags & AVFMT_TS_DISCONT;
|
|
|
|
|
2011-04-07 23:47:02 +00:00
|
|
|
// disabled because unreliable per-stream bitrate values returned
|
|
|
|
// by libavformat trigger this heuristic incorrectly and break things
|
|
|
|
#if 0
|
2010-11-10 05:17:51 +00:00
|
|
|
/* libavformat sets bitrate for mpeg based on pts at start and end
|
|
|
|
* of file, which fails for files with pts resets. So calculate our
|
|
|
|
* own bitrate estimate. */
|
|
|
|
if (priv->avif->flags & AVFMT_TS_DISCONT) {
|
|
|
|
for (int i = 0; i < avfc->nb_streams; i++)
|
|
|
|
priv->bitrate += avfc->streams[i]->codec->bit_rate;
|
|
|
|
/* pts-based is more accurate if there are no resets; try to make
|
|
|
|
* a somewhat reasonable guess */
|
|
|
|
if (!avfc->duration || avfc->duration == AV_NOPTS_VALUE
|
|
|
|
|| priv->bitrate && (avfc->bit_rate < priv->bitrate / 2
|
|
|
|
|| avfc->bit_rate > priv->bitrate * 2))
|
|
|
|
priv->seek_by_bytes = true;
|
|
|
|
if (!priv->bitrate)
|
|
|
|
priv->bitrate = 1440000;
|
|
|
|
}
|
2011-04-07 23:47:02 +00:00
|
|
|
#endif
|
2010-11-10 05:17:51 +00:00
|
|
|
demuxer->accurate_seek = !priv->seek_by_bytes;
|
2009-03-19 03:25:12 +00:00
|
|
|
|
2005-08-05 19:57:47 +00:00
|
|
|
return demuxer;
|
2004-04-11 14:26:04 +00:00
|
|
|
}
|
|
|
|
|
2011-08-19 01:59:01 +00:00
|
|
|
static int destroy_avpacket(void *pkt)
|
|
|
|
{
|
|
|
|
av_free_packet(pkt);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds)
|
|
|
|
{
|
|
|
|
lavf_priv_t *priv = demux->priv;
|
2004-04-11 14:26:04 +00:00
|
|
|
demux_packet_t *dp;
|
|
|
|
demux_stream_t *ds;
|
|
|
|
int id;
|
2011-07-03 12:42:04 +00:00
|
|
|
mp_msg(MSGT_DEMUX, MSGL_DBG2, "demux_lavf_fill_buffer()\n");
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
demux->filepos = stream_tell(demux->stream);
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2011-08-19 01:59:01 +00:00
|
|
|
AVPacket *pkt = talloc(NULL, AVPacket);
|
|
|
|
if (av_read_frame(priv->avfc, pkt) < 0) {
|
|
|
|
talloc_free(pkt);
|
2004-04-11 14:26:04 +00:00
|
|
|
return 0;
|
2011-08-19 01:59:01 +00:00
|
|
|
}
|
|
|
|
talloc_set_destructor(pkt, destroy_avpacket);
|
2008-01-26 21:45:31 +00:00
|
|
|
|
2010-10-04 18:12:36 +00:00
|
|
|
// handle any new streams that might have been added
|
|
|
|
for (id = priv->nb_streams_last; id < priv->avfc->nb_streams; id++)
|
|
|
|
handle_stream(demux, priv->avfc, id);
|
2010-11-06 01:39:49 +00:00
|
|
|
|
2010-10-04 18:12:36 +00:00
|
|
|
priv->nb_streams_last = priv->avfc->nb_streams;
|
|
|
|
|
2011-08-19 01:59:01 +00:00
|
|
|
id = pkt->stream_index;
|
2004-04-11 14:26:04 +00:00
|
|
|
|
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
|
|
|
assert(id >= 0 && id < MAX_S_STREAMS);
|
|
|
|
if (demux->s_streams[id] && demux->sub->id == -1 &&
|
|
|
|
demux->s_streams[id]->gsh->demuxer_id == priv->autoselect_sub)
|
|
|
|
{
|
|
|
|
priv->autoselect_sub = -1;
|
|
|
|
demux->sub->id = id;
|
|
|
|
}
|
|
|
|
|
2013-02-02 19:48:01 +00:00
|
|
|
if (id == demux->audio->id) {
|
2004-04-11 14:26:04 +00:00
|
|
|
// audio
|
2011-07-03 12:42:04 +00:00
|
|
|
ds = demux->audio;
|
|
|
|
} else if (id == demux->video->id) {
|
2004-04-11 14:26:04 +00:00
|
|
|
// video
|
2011-07-03 12:42:04 +00:00
|
|
|
ds = demux->video;
|
|
|
|
} else if (id == demux->sub->id) {
|
2007-07-13 21:15:24 +00:00
|
|
|
// subtitle
|
2011-07-03 12:42:04 +00:00
|
|
|
ds = demux->sub;
|
2005-01-30 09:13:28 +00:00
|
|
|
} else {
|
2011-08-19 01:59:01 +00:00
|
|
|
talloc_free(pkt);
|
2005-01-30 09:13:28 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2008-01-26 21:45:31 +00:00
|
|
|
|
2011-08-21 18:55:32 +00:00
|
|
|
// If the packet has pointers to temporary fields that could be
|
|
|
|
// overwritten/freed by next av_read_frame(), copy them to persistent
|
|
|
|
// allocations so we can safely queue the packet for any length of time.
|
|
|
|
if (av_dup_packet(pkt) < 0)
|
|
|
|
abort();
|
2011-08-19 01:59:01 +00:00
|
|
|
dp = new_demux_packet_fromdata(pkt->data, pkt->size);
|
|
|
|
dp->avpacket = pkt;
|
2004-04-11 14:26:04 +00:00
|
|
|
|
2013-02-03 15:04:24 +00:00
|
|
|
AVStream *st = priv->avfc->streams[id];
|
|
|
|
|
2011-08-19 01:59:01 +00:00
|
|
|
int64_t ts = priv->use_dts ? pkt->dts : pkt->pts;
|
2013-02-03 15:04:24 +00:00
|
|
|
if (ts == AV_NOPTS_VALUE && (st->disposition & AV_DISPOSITION_ATTACHED_PIC))
|
|
|
|
ts = 0;
|
2011-07-03 12:42:04 +00:00
|
|
|
if (ts != AV_NOPTS_VALUE) {
|
2010-11-06 21:17:16 +00:00
|
|
|
dp->pts = ts * av_q2d(priv->avfc->streams[id]->time_base);
|
2011-07-03 12:42:04 +00:00
|
|
|
priv->last_pts = dp->pts * AV_TIME_BASE;
|
2011-04-19 23:59:45 +00:00
|
|
|
// always set duration for subtitles, even if AV_PKT_FLAG_KEY isn't set,
|
2011-07-03 12:42:04 +00:00
|
|
|
// otherwise they will stay on screen to long if e.g. ASS is demuxed
|
|
|
|
// from mkv
|
2011-08-19 01:59:01 +00:00
|
|
|
if ((ds == demux->sub || (pkt->flags & AV_PKT_FLAG_KEY)) &&
|
|
|
|
pkt->convergence_duration > 0)
|
|
|
|
dp->duration = pkt->convergence_duration *
|
2011-07-03 12:42:04 +00:00
|
|
|
av_q2d(priv->avfc->streams[id]->time_base);
|
2004-10-24 19:17:55 +00:00
|
|
|
}
|
2011-07-03 12:42:04 +00:00
|
|
|
dp->pos = demux->filepos;
|
2012-07-24 21:23:27 +00:00
|
|
|
dp->keyframe = pkt->flags & AV_PKT_FLAG_KEY;
|
2004-04-11 14:26:04 +00:00
|
|
|
// append packet to DS stream:
|
2011-07-03 12:42:04 +00:00
|
|
|
ds_add_packet(ds, dp);
|
2004-04-11 14:26:04 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs,
|
|
|
|
float audio_delay, int flags)
|
|
|
|
{
|
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;
|
2011-07-03 12:42:04 +00:00
|
|
|
mp_msg(MSGT_DEMUX, MSGL_DBG2, "demux_seek_lavf(%p, %f, %f, %d)\n",
|
|
|
|
demuxer, rel_seek_secs, audio_delay, flags);
|
2006-07-13 23:02:03 +00:00
|
|
|
|
2010-11-10 05:17:51 +00:00
|
|
|
if (priv->seek_by_bytes) {
|
|
|
|
int64_t pos = demuxer->filepos;
|
|
|
|
rel_seek_secs *= priv->bitrate / 8;
|
|
|
|
pos += rel_seek_secs;
|
|
|
|
av_seek_frame(priv->avfc, -1, pos, AVSEEK_FLAG_BYTE);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
if (flags & SEEK_ABSOLUTE)
|
|
|
|
priv->last_pts = 0;
|
|
|
|
else if (rel_seek_secs < 0)
|
|
|
|
avsflags = AVSEEK_FLAG_BACKWARD;
|
2013-03-01 12:20:33 +00:00
|
|
|
|
2009-03-19 03:25:12 +00:00
|
|
|
if (flags & SEEK_FORWARD)
|
|
|
|
avsflags = 0;
|
|
|
|
else if (flags & SEEK_BACKWARD)
|
|
|
|
avsflags = AVSEEK_FLAG_BACKWARD;
|
2013-03-01 12:20:33 +00:00
|
|
|
|
2008-01-29 15:11:38 +00:00
|
|
|
if (flags & SEEK_FACTOR) {
|
2013-03-01 12:20:33 +00:00
|
|
|
if (demuxer->movi_end > 0 && demuxer->ts_resets_possible &&
|
|
|
|
!(priv->avif->flags & AVFMT_NO_BYTE_SEEK))
|
|
|
|
{
|
|
|
|
avsflags |= AVSEEK_FLAG_BYTE;
|
|
|
|
priv->last_pts = (demuxer->movi_end - demuxer->movi_start) *
|
|
|
|
rel_seek_secs;
|
|
|
|
} else if (priv->avfc->duration != 0 &&
|
|
|
|
priv->avfc->duration != AV_NOPTS_VALUE)
|
|
|
|
{
|
|
|
|
priv->last_pts = rel_seek_secs * priv->avfc->duration;
|
|
|
|
}
|
|
|
|
} else {
|
2011-07-03 12:42:04 +00:00
|
|
|
priv->last_pts += rel_seek_secs * AV_TIME_BASE;
|
2013-03-01 12:20:33 +00:00
|
|
|
}
|
2012-12-08 12:12:46 +00:00
|
|
|
|
|
|
|
if (!priv->avfc->iformat->read_seek2) {
|
|
|
|
// Normal seeking.
|
2013-02-19 00:43:26 +00:00
|
|
|
int r = av_seek_frame(priv->avfc, -1, priv->last_pts, 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;
|
|
|
|
av_seek_frame(priv->avfc, -1, priv->last_pts, avsflags);
|
|
|
|
}
|
2012-12-08 12:12:46 +00:00
|
|
|
} else {
|
|
|
|
// av_seek_frame() won't work. Use "new" seeking API. We don't use this
|
|
|
|
// API by default, because there are some major issues.
|
|
|
|
// Set max_ts==ts, so that demuxing starts from an earlier position in
|
|
|
|
// the worst case.
|
|
|
|
avformat_seek_file(priv->avfc, -1, INT64_MIN,
|
|
|
|
priv->last_pts, priv->last_pts, avsflags);
|
2009-09-30 08:19:49 +00:00
|
|
|
}
|
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) {
|
2011-07-03 12:42:04 +00:00
|
|
|
case DEMUXER_CTRL_CORRECT_PTS:
|
|
|
|
return DEMUXER_CTRL_OK;
|
2010-11-10 05:17:51 +00:00
|
|
|
case DEMUXER_CTRL_GET_TIME_LENGTH:
|
|
|
|
if (priv->seek_by_bytes) {
|
|
|
|
/* Our bitrate estimate may be better than would be used in
|
|
|
|
* otherwise similar fallback code at higher level */
|
|
|
|
if (demuxer->movi_end <= 0)
|
|
|
|
return DEMUXER_CTRL_DONTKNOW;
|
|
|
|
*(double *)arg = (demuxer->movi_end - demuxer->movi_start) * 8 /
|
2011-07-03 12:42:04 +00:00
|
|
|
priv->bitrate;
|
2010-11-10 05:17:51 +00:00
|
|
|
return DEMUXER_CTRL_GUESS;
|
|
|
|
}
|
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-02-25 23:38:36 +00:00
|
|
|
case DEMUXER_CTRL_GET_START_TIME:
|
2013-03-01 11:55:55 +00:00
|
|
|
*((double *)arg) = priv->avfc->start_time == AV_NOPTS_VALUE ?
|
|
|
|
0 : (double)priv->avfc->start_time / AV_TIME_BASE;
|
2011-07-03 12:42:04 +00:00
|
|
|
return DEMUXER_CTRL_OK;
|
2013-02-25 23:38:36 +00:00
|
|
|
|
2011-07-03 12:42:04 +00:00
|
|
|
case DEMUXER_CTRL_SWITCH_AUDIO:
|
|
|
|
case DEMUXER_CTRL_SWITCH_VIDEO:
|
|
|
|
{
|
|
|
|
int id = *((int *)arg);
|
|
|
|
int newid = -2;
|
|
|
|
int i, curridx = -1;
|
|
|
|
int nstreams, *pstreams;
|
|
|
|
demux_stream_t *ds;
|
|
|
|
|
|
|
|
if (cmd == DEMUXER_CTRL_SWITCH_VIDEO) {
|
|
|
|
ds = demuxer->video;
|
|
|
|
nstreams = priv->video_streams;
|
|
|
|
pstreams = priv->vstreams;
|
|
|
|
} else {
|
|
|
|
ds = demuxer->audio;
|
|
|
|
nstreams = priv->audio_streams;
|
|
|
|
pstreams = priv->astreams;
|
|
|
|
}
|
|
|
|
for (i = 0; i < nstreams; i++) {
|
|
|
|
if (pstreams[i] == ds->id) { //current stream id
|
|
|
|
curridx = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (id == -1) { // next track
|
|
|
|
i = (curridx + 2) % (nstreams + 1) - 1;
|
|
|
|
if (i >= 0)
|
2011-03-30 21:11:28 +00:00
|
|
|
newid = pstreams[i];
|
2011-07-03 12:42:04 +00:00
|
|
|
} else if (id >= 0 && id < nstreams) { // select track by id
|
|
|
|
i = id;
|
|
|
|
newid = pstreams[i];
|
|
|
|
} else // no sound
|
|
|
|
i = -1;
|
|
|
|
|
|
|
|
if (i == curridx) {
|
|
|
|
*(int *) arg = curridx < 0 ? -2 : curridx;
|
|
|
|
return DEMUXER_CTRL_OK;
|
|
|
|
} else {
|
|
|
|
ds_free_packs(ds);
|
|
|
|
if (ds->id >= 0)
|
|
|
|
priv->avfc->streams[ds->id]->discard = AVDISCARD_ALL;
|
|
|
|
ds->id = newid;
|
|
|
|
*(int *) arg = i < 0 ? -2 : i;
|
|
|
|
if (newid >= 0)
|
|
|
|
priv->avfc->streams[newid]->discard = AVDISCARD_NONE;
|
|
|
|
return DEMUXER_CTRL_OK;
|
2006-06-20 19:57:16 +00:00
|
|
|
}
|
2011-07-03 12:42:04 +00:00
|
|
|
}
|
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
|
|
|
case DEMUXER_CTRL_AUTOSELECT_SUBTITLE:
|
|
|
|
{
|
|
|
|
demuxer->sub->id = -1;
|
|
|
|
priv->autoselect_sub = *((int *)arg);
|
|
|
|
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;
|
|
|
|
|
|
|
|
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:
|
2011-07-03 12:42:04 +00:00
|
|
|
program = priv->avfc->programs[p];
|
|
|
|
for (i = 0; i < program->nb_stream_indexes; i++) {
|
|
|
|
switch (priv->avfc->streams[program->stream_index[i]]->codec->codec_type) {
|
|
|
|
case AVMEDIA_TYPE_VIDEO:
|
|
|
|
if (prog->vid == -2)
|
|
|
|
prog->vid = program->stream_index[i];
|
|
|
|
break;
|
|
|
|
case AVMEDIA_TYPE_AUDIO:
|
|
|
|
if (prog->aid == -2)
|
|
|
|
prog->aid = program->stream_index[i];
|
|
|
|
break;
|
|
|
|
case AVMEDIA_TYPE_SUBTITLE:
|
2012-08-25 10:50:50 +00:00
|
|
|
if (prog->sid == -2)
|
2011-07-03 12:42:04 +00:00
|
|
|
prog->sid = program->stream_index[i];
|
|
|
|
break;
|
2007-10-27 19:15:43 +00:00
|
|
|
}
|
|
|
|
}
|
2011-07-03 12:42:04 +00:00
|
|
|
if (prog->aid >= 0 && prog->aid < MAX_A_STREAMS &&
|
|
|
|
demuxer->a_streams[prog->aid]) {
|
|
|
|
sh_audio_t *sh = demuxer->a_streams[prog->aid];
|
|
|
|
prog->aid = sh->aid;
|
|
|
|
} else
|
|
|
|
prog->aid = -2;
|
|
|
|
if (prog->vid >= 0 && prog->vid < MAX_V_STREAMS &&
|
|
|
|
demuxer->v_streams[prog->vid]) {
|
|
|
|
sh_video_t *sh = demuxer->v_streams[prog->vid];
|
|
|
|
prog->vid = sh->vid;
|
|
|
|
} else
|
|
|
|
prog->vid = -2;
|
|
|
|
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;
|
|
|
|
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.
|
|
|
|
*/
|
2013-01-10 11:36:13 +00:00
|
|
|
avio_flush(priv->avfc->pb);
|
2013-01-07 16:39:55 +00:00
|
|
|
av_seek_frame(priv->avfc, 0, avio_tell(priv->avfc->pb),
|
|
|
|
AVSEEK_FLAG_BYTE);
|
2013-01-10 11:36:13 +00:00
|
|
|
avio_flush(priv->avfc->pb);
|
2013-01-07 16:39:55 +00:00
|
|
|
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
|
|
|
}
|
2007-12-22 16:22:54 +00:00
|
|
|
av_freep(&priv->pb);
|
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 = {
|
2011-07-03 12:42:04 +00:00
|
|
|
"libavformat demuxer",
|
|
|
|
"lavf",
|
|
|
|
"libavformat",
|
|
|
|
"Michael Niedermayer",
|
|
|
|
"supports many formats, requires libavformat",
|
|
|
|
DEMUXER_TYPE_LAVF,
|
|
|
|
1,
|
2012-12-08 19:14:13 +00:00
|
|
|
lavf_check_file,
|
2011-07-03 12:42:04 +00:00
|
|
|
demux_lavf_fill_buffer,
|
|
|
|
demux_open_lavf,
|
|
|
|
demux_close_lavf,
|
|
|
|
demux_seek_lavf,
|
|
|
|
demux_lavf_control
|
2007-04-14 10:03:42 +00:00
|
|
|
};
|