summaryrefslogtreecommitdiffstats
path: root/libmpdemux/demux_lavf.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmpdemux/demux_lavf.c')
-rw-r--r--libmpdemux/demux_lavf.c133
1 files changed, 69 insertions, 64 deletions
diff --git a/libmpdemux/demux_lavf.c b/libmpdemux/demux_lavf.c
index dad7208c3d..497ff563bf 100644
--- a/libmpdemux/demux_lavf.c
+++ b/libmpdemux/demux_lavf.c
@@ -22,11 +22,13 @@
#include <stdlib.h>
// #include <unistd.h>
#include <limits.h>
+#include <stdbool.h>
#include "config.h"
+#include "options.h"
#include "mp_msg.h"
-#include "help_mp.h"
#include "av_opts.h"
+#include "bstr.h"
#include "stream/stream.h"
#include "aviprint.h"
@@ -47,22 +49,13 @@
#define SMALL_MAX_PROBE_SIZE (32 * 1024)
#define PROBE_BUF_SIZE (2*1024*1024)
-extern char *audio_lang;
-extern char *dvdsub_lang;
-extern int dvdsub_id;
-static unsigned int opt_probesize = 0;
-static unsigned int opt_analyzeduration = 0;
-static char *opt_format;
-static char *opt_cryptokey;
-static char *opt_avopt = NULL;
-
const m_option_t lavfdopts_conf[] = {
- {"probesize", &(opt_probesize), CONF_TYPE_INT, CONF_RANGE, 32, INT_MAX, NULL},
- {"format", &(opt_format), CONF_TYPE_STRING, 0, 0, 0, NULL},
- {"analyzeduration", &(opt_analyzeduration), CONF_TYPE_INT, CONF_RANGE, 0, INT_MAX, NULL},
- {"cryptokey", &(opt_cryptokey), CONF_TYPE_STRING, 0, 0, 0, NULL},
- {"o", &opt_avopt, CONF_TYPE_STRING, 0, 0, 0, NULL},
- {NULL, NULL, 0, 0, 0, 0, NULL}
+ OPT_INTRANGE("probesize", lavfdopts.probesize, 0, 32, INT_MAX),
+ OPT_STRING("format", lavfdopts.format, 0),
+ OPT_INTRANGE("analyzeduration", lavfdopts.analyzeduration, 0, 0, INT_MAX),
+ OPT_STRING("cryptokey", lavfdopts.cryptokey, 0),
+ OPT_STRING("o", lavfdopts.avopt, 0),
+ {NULL, NULL, 0, 0, 0, 0, NULL}
};
#define BIO_BUFFER_SIZE 32768
@@ -83,8 +76,8 @@ typedef struct lavf_priv {
}lavf_priv_t;
static int mp_read(void *opaque, uint8_t *buf, int size) {
- demuxer_t *demuxer = opaque;
- stream_t *stream = demuxer->stream;
+ struct demuxer *demuxer = opaque;
+ struct stream *stream = demuxer->stream;
int ret;
if(stream_eof(stream)) //needed?
@@ -96,8 +89,8 @@ static int mp_read(void *opaque, uint8_t *buf, int size) {
}
static int64_t mp_seek(void *opaque, int64_t pos, int whence) {
- demuxer_t *demuxer = opaque;
- stream_t *stream = demuxer->stream;
+ struct demuxer *demuxer = opaque;
+ struct stream *stream = demuxer->stream;
int64_t current_pos;
mp_msg(MSGT_HEADER,MSGL_DBG2,"mp_seek(%p, %"PRId64", %d)\n", stream, pos, whence);
if(whence == SEEK_CUR)
@@ -125,16 +118,15 @@ static int64_t mp_seek(void *opaque, int64_t pos, int whence) {
return pos - stream->start_pos;
}
-static int64_t mp_read_seek(void *opaque, int stream_idx, int64_t ts, int flags) {
- demuxer_t *demuxer = opaque;
- stream_t *stream = demuxer->stream;
- lavf_priv_t *priv = demuxer->priv;
- AVStream *st = priv->avfc->streams[stream_idx];
- int ret;
- double pts;
+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;
- pts = (double)ts * st->time_base.num / st->time_base.den;
- ret = stream_control(stream, STREAM_CTRL_SEEK_TO_TIME, &pts);
+ 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;
@@ -148,6 +140,8 @@ static void list_formats(void) {
}
static int lavf_check_file(demuxer_t *demuxer){
+ struct MPOpts *opts = demuxer->opts;
+ struct lavfdopts *lavfdopts = &opts->lavfdopts;
AVProbeData avpd;
lavf_priv_t *priv;
int probe_data_size = 0;
@@ -160,14 +154,17 @@ static int lavf_check_file(demuxer_t *demuxer){
av_register_all();
- if (opt_format) {
- if (strcmp(opt_format, "help") == 0) {
+ char *format = lavfdopts->format;
+ if (!format)
+ format = demuxer->stream->lavf_type;
+ if (format) {
+ if (strcmp(format, "help") == 0) {
list_formats();
return 0;
}
- priv->avif= av_find_input_format(opt_format);
+ priv->avif = av_find_input_format(format);
if (!priv->avif) {
- mp_msg(MSGT_DEMUX,MSGL_FATAL,"Unknown lavf format %s\n", opt_format);
+ mp_msg(MSGT_DEMUX, MSGL_FATAL, "Unknown lavf format %s\n", format);
return 0;
}
mp_msg(MSGT_DEMUX,MSGL_INFO,"Forced lavf %s demuxer\n", priv->avif->long_name);
@@ -212,7 +209,6 @@ static const char * const preferred_list[] = {
"gxf",
"nut",
"nuv",
- "matroska",
"mov,mp4,m4a,3gp,3g2,mj2",
"mpc",
"mpc8",
@@ -263,8 +259,8 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) {
int stream_id;
AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL, 0);
AVMetadataTag *title= av_metadata_get(st->metadata, "title", NULL, 0);
- int g, override_tag = av_codec_get_tag(mp_codecid_override_taglists,
- codec->codec_id);
+ int g, override_tag = mp_av_codec_get_tag(mp_codecid_override_taglists,
+ codec->codec_id);
// For some formats (like PCM) always trust CODEC_ID_* more than codec_tag
if (override_tag)
codec->codec_tag = override_tag;
@@ -283,7 +279,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) {
if(codec->codec_tag == MKTAG('m', 'p', '4', 'a'))
codec->codec_tag= 0;
if(!codec->codec_tag)
- codec->codec_tag= av_codec_get_tag(mp_wav_taglists, codec->codec_id);
+ codec->codec_tag= mp_av_codec_get_tag(mp_wav_taglists, codec->codec_id);
wf->wFormatTag= codec->codec_tag;
wf->nChannels= codec->channels;
wf->nSamplesPerSec= codec->sample_rate;
@@ -363,7 +359,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) {
}
}
if(!codec->codec_tag)
- codec->codec_tag= av_codec_get_tag(mp_bmp_taglists, codec->codec_id);
+ codec->codec_tag= mp_av_codec_get_tag(mp_bmp_taglists, codec->codec_id);
bih->biSize= sizeof(BITMAPINFOHEADER) + codec->extradata_size;
bih->biWidth= codec->width;
bih->biHeight= codec->height;
@@ -455,9 +451,10 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) {
}
case CODEC_TYPE_ATTACHMENT:{
if (st->codec->codec_id == CODEC_ID_TTF)
- demuxer_add_attachment(demuxer, st->filename,
- "application/x-truetype-font",
- codec->extradata, codec->extradata_size);
+ demuxer_add_attachment(demuxer, BSTR(st->filename),
+ BSTR("application/x-truetype-font"),
+ (struct bstr){codec->extradata,
+ codec->extradata_size});
break;
}
default:
@@ -475,6 +472,8 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) {
}
static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
+ struct MPOpts *opts = demuxer->opts;
+ struct lavfdopts *lavfdopts = &opts->lavfdopts;
AVFormatContext *avfc;
AVFormatParameters ap;
const AVOption *opt;
@@ -489,26 +488,29 @@ static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
avfc = avformat_alloc_context();
- if (opt_cryptokey)
- parse_cryptokey(avfc, opt_cryptokey);
- if (user_correct_pts != 0)
+ if (lavfdopts->cryptokey)
+ parse_cryptokey(avfc, lavfdopts->cryptokey);
+ if (opts->user_correct_pts != 0)
avfc->flags |= AVFMT_FLAG_GENPTS;
if (index_mode == 0)
avfc->flags |= AVFMT_FLAG_IGNIDX;
ap.prealloced_context = 1;
- if(opt_probesize) {
- opt = av_set_int(avfc, "probesize", opt_probesize);
- if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option probesize to %u\n", opt_probesize);
+ if (lavfdopts->probesize) {
+ opt = av_set_int(avfc, "probesize", lavfdopts->probesize);
+ if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option probesize to %u\n", lavfdopts->probesize);
}
- if(opt_analyzeduration) {
- opt = av_set_int(avfc, "analyzeduration", opt_analyzeduration * AV_TIME_BASE);
- if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option analyzeduration to %u\n", opt_analyzeduration);
+ if (lavfdopts->analyzeduration) {
+ opt = av_set_int(avfc, "analyzeduration",
+ lavfdopts->analyzeduration * AV_TIME_BASE);
+ if (!opt)
+ mp_msg(MSGT_HEADER, MSGL_ERR, "demux_lavf, couldn't set option "
+ "analyzeduration to %u\n", lavfdopts->analyzeduration);
}
- if(opt_avopt){
- if(parse_avopts(avfc, opt_avopt) < 0){
- mp_msg(MSGT_HEADER,MSGL_ERR, "Your options /%s/ look like gibberish to me pal\n", opt_avopt);
+ 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);
return NULL;
}
}
@@ -548,7 +550,7 @@ static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
uint64_t start = av_rescale_q(c->start, c->time_base, (AVRational){1,1000});
uint64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,1000});
t = av_metadata_get(c->metadata, "title", NULL, 0);
- demuxer_add_chapter(demuxer, t ? t->value : NULL, start, end);
+ demuxer_add_chapter(demuxer, t ? BSTR(t->value) : BSTR(NULL), start, end);
}
for(i=0; i<avfc->nb_streams; i++)
@@ -574,6 +576,8 @@ static demuxer_t* demux_open_lavf(demuxer_t *demuxer){
demuxer->video->id=-2; // audio-only
} //else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video;
+ demuxer->accurate_seek = true;
+
return demuxer;
}
@@ -649,10 +653,14 @@ static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, float audio
mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_seek_lavf(%p, %f, %f, %d)\n", demuxer, rel_seek_secs, audio_delay, flags);
if (flags & SEEK_ABSOLUTE) {
- priv->last_pts = priv->avfc->start_time;
+ priv->last_pts = 0;
} else {
if (rel_seek_secs < 0) avsflags = AVSEEK_FLAG_BACKWARD;
}
+ if (flags & SEEK_FORWARD)
+ avsflags = 0;
+ else if (flags & SEEK_BACKWARD)
+ avsflags = AVSEEK_FLAG_BACKWARD;
if (flags & SEEK_FACTOR) {
if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
return;
@@ -672,10 +680,6 @@ static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
switch (cmd) {
case DEMUXER_CTRL_CORRECT_PTS:
- if (!strcmp("matroska", priv->avif->name) ||
- !strcmp("mpeg", priv->avif->name) ||
- !strcmp("mpegts", priv->avif->name))
- return DEMUXER_CTRL_NOTIMPL;
return DEMUXER_CTRL_OK;
case DEMUXER_CTRL_GET_TIME_LENGTH:
if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
@@ -734,14 +738,15 @@ static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
newid = pstreams[i];
}
}
- if(i == curridx)
- return DEMUXER_CTRL_NOTIMPL;
- else
- {
+ if (i == curridx) {
+ *(int *) arg = curridx;
+ return DEMUXER_CTRL_OK;
+ } else {
ds_free_packs(ds);
if(ds->id >= 0)
priv->avfc->streams[ds->id]->discard = AVDISCARD_ALL;
- *((int*)arg) = ds->id = newid;
+ ds->id = newid;
+ *(int *) arg = i < 0 ? -2 : i;
if(newid >= 0)
priv->avfc->streams[newid]->discard = AVDISCARD_NONE;
return DEMUXER_CTRL_OK;