diff options
Diffstat (limited to 'libmpdemux/demux_lavf.c')
-rw-r--r-- | libmpdemux/demux_lavf.c | 129 |
1 files changed, 69 insertions, 60 deletions
diff --git a/libmpdemux/demux_lavf.c b/libmpdemux/demux_lavf.c index 72363ef520..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; @@ -730,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; |