summaryrefslogtreecommitdiffstats
path: root/demux/demux_lavf.c
diff options
context:
space:
mode:
Diffstat (limited to 'demux/demux_lavf.c')
-rw-r--r--demux/demux_lavf.c113
1 files changed, 49 insertions, 64 deletions
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 39e1cb28c5..82ca2e24d0 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -73,7 +73,6 @@ typedef struct lavf_priv {
AVFormatContext *avfc;
AVIOContext *pb;
uint8_t buffer[BIO_BUFFER_SIZE];
- int autoselect_sub;
int64_t last_pts;
struct sh_stream **streams; // NULL for unknown streams
int num_streams;
@@ -186,7 +185,7 @@ static char *remove_prefix(char *s, const char **prefixes)
static const char *prefixes[] =
{"ffmpeg://", "lavf://", "avdevice://", "av://", NULL};
-static int lavf_check_file(demuxer_t *demuxer)
+static int lavf_check_file(demuxer_t *demuxer, enum demux_check check)
{
struct MPOpts *opts = demuxer->opts;
struct lavfdopts *lavfdopts = &opts->lavfdopts;
@@ -196,7 +195,6 @@ static int lavf_check_file(demuxer_t *demuxer)
assert(!demuxer->priv);
demuxer->priv = talloc_zero(NULL, lavf_priv_t);
priv = demuxer->priv;
- priv->autoselect_sub = -1;
priv->filename = s->url;
if (!priv->filename) {
@@ -213,7 +211,7 @@ static int lavf_check_file(demuxer_t *demuxer)
if (!sep) {
mp_msg(MSGT_DEMUX, MSGL_FATAL,
"Must specify filename in 'format:filename' form\n");
- return 0;
+ return -1;
}
avdevice_format = talloc_strndup(priv, priv->filename,
sep - priv->filename);
@@ -240,12 +238,12 @@ static int lavf_check_file(demuxer_t *demuxer)
if (format) {
if (strcmp(format, "help") == 0) {
list_formats();
- return 0;
+ return -1;
}
priv->avif = av_find_input_format(format);
if (!priv->avif) {
mp_msg(MSGT_DEMUX, MSGL_FATAL, "Unknown lavf format %s\n", format);
- return 0;
+ return -1;
}
mp_msg(MSGT_DEMUX, MSGL_INFO, "Forced lavf %s demuxer\n",
priv->avif->long_name);
@@ -260,7 +258,8 @@ static int lavf_check_file(demuxer_t *demuxer)
min_probe = lavfdopts->probescore;
AVProbeData avpd = {
- .filename = priv->filename,
+ // Disable file-extension matching with normal checks
+ .filename = check <= DEMUX_CHECK_REQUEST ? priv->filename : NULL,
.buf_size = 0,
.buf = av_mallocz(PROBE_BUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE),
};
@@ -299,7 +298,7 @@ static int lavf_check_file(demuxer_t *demuxer)
if (!priv->avif) {
mp_msg(MSGT_HEADER, MSGL_V,
"No format found, try lowering probescore.\n");
- return 0;
+ return -1;
}
success:
@@ -308,7 +307,7 @@ success:
if (!demuxer->filetype)
demuxer->filetype = priv->avif->name;
- return DEMUXER_TYPE_LAVF;
+ return 0;
}
static bool matches_avinputformat_name(struct lavf_priv *priv,
@@ -347,6 +346,18 @@ static void parse_cryptokey(AVFormatContext *avfc, const char *str)
*key++ = (char2int(str[0]) << 4) | char2int(str[1]);
}
+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];
+ bool selected = stream && demuxer_stream_is_selected(demuxer, stream) &&
+ !stream->attached_picture;
+ st->discard = selected ? AVDISCARD_DEFAULT : AVDISCARD_ALL;
+ }
+}
+
static void handle_stream(demuxer_t *demuxer, int i)
{
lavf_priv_t *priv = demuxer->priv;
@@ -355,8 +366,6 @@ static void handle_stream(demuxer_t *demuxer, int i)
AVCodecContext *codec = st->codec;
struct sh_stream *sh = NULL;
- st->discard = AVDISCARD_ALL;
-
switch (codec->codec_type) {
case AVMEDIA_TYPE_AUDIO: {
sh = new_sh_stream(demuxer, STREAM_AUDIO);
@@ -381,8 +390,12 @@ static void handle_stream(demuxer_t *demuxer, int i)
break;
sh_video_t *sh_video = sh->video;
- if (st->disposition & AV_DISPOSITION_ATTACHED_PIC)
- sh_video->gsh->attached_picture = true;
+ if (st->disposition & AV_DISPOSITION_ATTACHED_PIC) {
+ sh->attached_picture = new_demux_packet_from(st->attached_pic.data,
+ st->attached_pic.size);
+ sh->attached_picture->pts = 0;
+ talloc_steal(sh, sh->attached_picture);
+ }
sh_video->format = codec->codec_tag;
sh_video->disp_w = codec->width;
@@ -402,7 +415,6 @@ static void handle_stream(demuxer_t *demuxer, int i)
av_q2d(st->codec->time_base) *
st->codec->ticks_per_frame);
sh_video->fps = fps;
- sh_video->frametime = 1 / fps;
if (st->sample_aspect_ratio.num)
sh_video->aspect = codec->width * st->sample_aspect_ratio.num
/ (float)(codec->height * st->sample_aspect_ratio.den);
@@ -428,7 +440,6 @@ static void handle_stream(demuxer_t *demuxer, int i)
memcpy(sh_sub->extradata, codec->extradata, codec->extradata_size);
sh_sub->extradata_len = codec->extradata_size;
}
- st->discard = AVDISCARD_DEFAULT;
break;
}
case AVMEDIA_TYPE_ATTACHMENT: {
@@ -464,6 +475,8 @@ static void handle_stream(demuxer_t *demuxer, int i)
if (lang && lang->value)
sh->lang = talloc_strdup(sh, lang->value);
}
+
+ select_tracks(demuxer, i);
}
// Add any new streams that might have been added
@@ -481,19 +494,21 @@ static void add_metadata(demuxer_t *demuxer, AVDictionary *metadata)
demux_info_add(demuxer, t->key, t->value);
}
-static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
+static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
{
struct MPOpts *opts = demuxer->opts;
struct lavfdopts *lavfdopts = &opts->lavfdopts;
AVFormatContext *avfc;
AVDictionaryEntry *t = NULL;
- lavf_priv_t *priv = demuxer->priv;
float analyze_duration = 0;
int i;
- // do not allow forcing the demuxer
- if (!priv->avif)
- return NULL;
+ if (lavf_check_file(demuxer, check) < 0)
+ return -1;
+
+ lavf_priv_t *priv = demuxer->priv;
+ if (!priv)
+ return -1;
stream_seek(demuxer->stream, 0);
@@ -510,7 +525,7 @@ static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
if (opts->user_correct_pts != 0)
avfc->flags |= AVFMT_FLAG_GENPTS;
}
- if (index_mode == 0)
+ if (opts->index_mode == 0)
avfc->flags |= AVFMT_FLAG_IGNIDX;
if (lavfdopts->probesize) {
@@ -536,7 +551,7 @@ static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
mp_msg(MSGT_HEADER, MSGL_ERR,
"Your options /%s/ look like gibberish to me pal\n",
lavfdopts->avopt);
- return NULL;
+ return -1;
}
}
@@ -555,14 +570,14 @@ static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
if (avformat_open_input(&avfc, priv->filename, priv->avif, NULL) < 0) {
mp_msg(MSGT_HEADER, MSGL_ERR,
"LAVF_header: avformat_open_input() failed\n");
- return NULL;
+ return -1;
}
priv->avfc = avfc;
if (avformat_find_stream_info(avfc, NULL) < 0) {
mp_msg(MSGT_HEADER, MSGL_ERR,
"LAVF_header: av_find_stream_info() failed\n");
- return NULL;
+ return -1;
}
mp_msg(MSGT_HEADER, MSGL_V, "demux_lavf: avformat_find_stream_info() "
@@ -628,7 +643,7 @@ static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
#endif
demuxer->accurate_seek = !priv->seek_by_bytes;
- return demuxer;
+ return 0;
}
static int destroy_avpacket(void *pkt)
@@ -637,7 +652,7 @@ static int destroy_avpacket(void *pkt)
return 0;
}
-static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds)
+static int demux_lavf_fill_buffer(demuxer_t *demux)
{
lavf_priv_t *priv = demux->priv;
demux_packet_t *dp;
@@ -658,13 +673,6 @@ static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds)
AVStream *st = priv->avfc->streams[pkt->stream_index];
struct sh_stream *stream = priv->streams[pkt->stream_index];
- if (stream && stream->type == STREAM_SUB && demux->sub->id < 0 &&
- stream->demuxer_id == priv->autoselect_sub)
- {
- priv->autoselect_sub = -1;
- demux->sub->id = stream->stream_index;
- }
-
if (!demuxer_stream_is_selected(demux, stream)) {
talloc_free(pkt);
return 1;
@@ -679,8 +687,6 @@ static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds)
dp->avpacket = pkt;
int64_t ts = priv->use_dts ? pkt->dts : pkt->pts;
- if (ts == AV_NOPTS_VALUE && (st->disposition & AV_DISPOSITION_ATTACHED_PIC))
- ts = 0;
if (ts != AV_NOPTS_VALUE) {
dp->pts = ts * av_q2d(st->time_base);
priv->last_pts = dp->pts * AV_TIME_BASE;
@@ -772,8 +778,6 @@ static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
lavf_priv_t *priv = demuxer->priv;
switch (cmd) {
- case DEMUXER_CTRL_CORRECT_PTS:
- return DEMUXER_CTRL_OK;
case DEMUXER_CTRL_GET_TIME_LENGTH:
if (priv->seek_by_bytes) {
/* Our bitrate estimate may be better than would be used in
@@ -797,20 +801,7 @@ static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
case DEMUXER_CTRL_SWITCHED_TRACKS:
{
- for (int n = 0; n < priv->num_streams; n++) {
- struct sh_stream *stream = priv->streams[n];
- AVStream *st = priv->avfc->streams[n];
- if (stream && stream->type != STREAM_SUB) {
- bool selected = demuxer_stream_is_selected(demuxer, stream);
- st->discard = selected ? AVDISCARD_NONE : AVDISCARD_ALL;
- }
- }
- return DEMUXER_CTRL_OK;
- }
- case DEMUXER_CTRL_AUTOSELECT_SUBTITLE:
- {
- demuxer->sub->id = -1;
- priv->autoselect_sub = *((int *)arg);
+ select_tracks(demuxer, 0);
return DEMUXER_CTRL_OK;
}
case DEMUXER_CTRL_IDENTIFY_PROGRAM:
@@ -909,17 +900,11 @@ static void demux_close_lavf(demuxer_t *demuxer)
const demuxer_desc_t demuxer_desc_lavf = {
- "libavformat demuxer",
- "lavf",
- "libavformat",
- "Michael Niedermayer",
- "supports many formats, requires libavformat",
- DEMUXER_TYPE_LAVF,
- 1,
- lavf_check_file,
- demux_lavf_fill_buffer,
- demux_open_lavf,
- demux_close_lavf,
- demux_seek_lavf,
- demux_lavf_control
+ .name = "lavf",
+ .desc = "libavformat",
+ .fill_buffer = demux_lavf_fill_buffer,
+ .open = demux_open_lavf,
+ .close = demux_close_lavf,
+ .seek = demux_seek_lavf,
+ .control = demux_lavf_control,
};