summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-08-19 18:11:53 +0200
committerwm4 <wm4@nowhere>2012-09-18 21:04:45 +0200
commitcde59e913f2c1c2cca27d10daddb54b4de6cc90a (patch)
treeb1e97bb2977e50e6d0466c698fcc8b4530113dd8
parent0f155921b046c9e6cfed3fe601aa891c2d2a8b16 (diff)
downloadmpv-cde59e913f2c1c2cca27d10daddb54b4de6cc90a.tar.bz2
mpv-cde59e913f2c1c2cca27d10daddb54b4de6cc90a.tar.xz
core: move implementation for -audiofile to the frontend
This should behave as before, with the same set of caveats.
-rw-r--r--Makefile1
-rw-r--r--libmpdemux/demux_demuxers.c175
-rw-r--r--libmpdemux/demuxer.c153
-rw-r--r--libmpdemux/demuxer.h9
-rw-r--r--mplayer.c102
-rw-r--r--timeline/tl_matroska.c2
6 files changed, 129 insertions, 313 deletions
diff --git a/Makefile b/Makefile
index 99b310d8d2..495a42824e 100644
--- a/Makefile
+++ b/Makefile
@@ -227,7 +227,6 @@ SRCS_COMMON = asxparser.c \
libmpdemux/demuxer.c \
libmpdemux/demux_asf.c \
libmpdemux/demux_avi.c \
- libmpdemux/demux_demuxers.c \
libmpdemux/demux_edl.c \
libmpdemux/demux_cue.c \
libmpdemux/demux_lavf.c \
diff --git a/libmpdemux/demux_demuxers.c b/libmpdemux/demux_demuxers.c
deleted file mode 100644
index b66bf57bdb..0000000000
--- a/libmpdemux/demux_demuxers.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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.
- */
-
-#include "config.h"
-#include "mp_msg.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "stream/stream.h"
-#include "demuxer.h"
-#include "stheader.h"
-#include "talloc.h"
-
-typedef struct dd_priv {
- demuxer_t* vd;
- demuxer_t* ad;
- demuxer_t* sd;
-} dd_priv_t;
-
-extern const demuxer_desc_t demuxer_desc_demuxers;
-
-demuxer_t* new_demuxers_demuxer(demuxer_t* vd, demuxer_t* ad, demuxer_t* sd) {
- demuxer_t* ret;
- dd_priv_t* priv;
-
- ret = talloc_zero(NULL, struct demuxer);
-
- priv = malloc(sizeof(dd_priv_t));
- priv->vd = vd;
- priv->ad = ad;
- priv->sd = sd;
- ret->priv = priv;
-
- ret->type = ret->file_format = DEMUXER_TYPE_DEMUXERS;
- // Video is the most important :-)
- ret->stream = vd->stream;
- ret->seekable = vd->seekable && ad->seekable && sd->seekable;
- ret->stream_pts = MP_NOPTS_VALUE;
-
- ret->video = vd->video;
- ret->audio = ad->audio;
- ret->sub = sd->sub;
- if (sd && sd != vd && sd != ad) sd->sub->non_interleaved = 1;
-
- // without these, demux_demuxers_fill_buffer will never be called,
- // but they break the demuxer-specific code in video.c
-#if 0
- if (vd) vd->video->demuxer = ret;
- if (ad) ad->audio->demuxer = ret;
- if (sd) sd->sub->demuxer = ret;
-
- // HACK?, necessary for subtitle (and audio and video when implemented) switching
- memcpy(ret->v_streams, vd->v_streams, sizeof(ret->v_streams));
- memcpy(ret->a_streams, ad->a_streams, sizeof(ret->a_streams));
- memcpy(ret->s_streams, sd->s_streams, sizeof(ret->s_streams));
-#endif
-
- ret->desc = &demuxer_desc_demuxers;
-
- return ret;
-}
-
-static int demux_demuxers_fill_buffer(demuxer_t *demux,demux_stream_t *ds) {
- dd_priv_t* priv;
-
- priv=demux->priv;
-
- // HACK: make sure the subtitles get properly interleaved if with -subfile
- if (priv->sd && priv->sd->sub != ds &&
- priv->sd != priv->vd && priv->sd != priv->ad)
- ds_get_next_pts(priv->sd->sub);
- if(priv->vd && priv->vd->video == ds)
- return demux_fill_buffer(priv->vd,ds);
- else if(priv->ad && priv->ad->audio == ds)
- return demux_fill_buffer(priv->ad,ds);
- else if(priv->sd && priv->sd->sub == ds)
- return demux_fill_buffer(priv->sd,ds);
-
- mp_tmsg(MSGT_DEMUX,MSGL_WARN,"fill_buffer error: bad demuxer: not vd, ad or sd.\n");
- return 0;
-}
-
-static void demux_demuxers_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags) {
- dd_priv_t* priv;
- float pos;
- priv=demuxer->priv;
-
- priv->ad->stream->eof = 0;
- priv->sd->stream->eof = 0;
-
- // Seek video
- demux_seek(priv->vd,rel_seek_secs,audio_delay,flags);
- // Get the new pos
- pos = demuxer->video->pts;
- if (pos == MP_NOPTS_VALUE) {
- demux_fill_buffer(priv->vd, demuxer->video);
- if (demuxer->video->first)
- pos = demuxer->video->first->pts;
- }
-
- if(priv->ad != priv->vd && demuxer->audio->sh) {
- sh_audio_t* sh = demuxer->audio->sh;
- demux_seek(priv->ad,pos,audio_delay,1);
- // In case the demuxer don't set pts
- if(!demuxer->audio->pts)
- demuxer->audio->pts = pos-((ds_tell_pts(demuxer->audio)-sh->a_in_buffer_len)/(float)sh->i_bps);
- }
-
- if(priv->sd != priv->vd)
- demux_seek(priv->sd,pos,audio_delay,1);
-
-}
-
-static void demux_close_demuxers(demuxer_t* demuxer) {
- dd_priv_t* priv = demuxer->priv;
- stream_t *s;
-
- if(priv->vd)
- free_demuxer(priv->vd);
- if(priv->ad && priv->ad != priv->vd) {
- // That's a hack to free the audio file stream
- // It's ok atm but we shouldn't free that here
- s = priv->ad->stream;
- free_demuxer(priv->ad);
- free_stream(s);
- } if(priv->sd && priv->sd != priv->vd && priv->sd != priv->ad) {
- s = priv->sd->stream;
- free_demuxer(priv->sd);
- free_stream(s);
- }
-
- free(priv);
-}
-
-
-static int demux_demuxers_control(demuxer_t *demuxer,int cmd, void *arg){
- dd_priv_t* priv = demuxer->priv;
- switch (cmd) {
- case DEMUXER_CTRL_GET_TIME_LENGTH:
- case DEMUXER_CTRL_GET_PERCENT_POS:
- return demux_control(priv->vd, cmd, arg);
- }
- return DEMUXER_CTRL_NOTIMPL;
-}
-
-const demuxer_desc_t demuxer_desc_demuxers = {
- "Demuxers demuxer",
- "", // Not selectable
- "",
- "?",
- "internal use only",
- DEMUXER_TYPE_DEMUXERS,
- 0, // no autodetect
- NULL,
- demux_demuxers_fill_buffer,
- NULL,
- demux_close_demuxers,
- demux_demuxers_seek,
- demux_demuxers_control
-};
diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c
index 13f5fab268..798f701305 100644
--- a/libmpdemux/demuxer.c
+++ b/libmpdemux/demuxer.c
@@ -419,9 +419,6 @@ void free_demuxer(demuxer_t *demuxer)
demuxer->desc->shortdesc, demuxer);
if (demuxer->desc->close)
demuxer->desc->close(demuxer);
- // Very ugly hack to make it behave like old implementation
- if (demuxer->desc->type == DEMUXER_TYPE_DEMUXERS)
- goto skip_streamfree;
// free streams:
for (i = 0; i < MAX_A_STREAMS; i++)
if (demuxer->a_streams[i])
@@ -436,7 +433,6 @@ void free_demuxer(demuxer_t *demuxer)
free_demuxer_stream(demuxer->audio);
free_demuxer_stream(demuxer->video);
free_demuxer_stream(demuxer->sub);
- skip_streamfree:
free(demuxer->filename);
talloc_free(demuxer);
}
@@ -888,6 +884,11 @@ static struct demuxer *open_given_type(struct MPOpts *opts,
demuxer = demux2;
}
demuxer->file_format = fformat;
+ opts->correct_pts = opts->user_correct_pts;
+ if (opts->correct_pts < 0)
+ opts->correct_pts =
+ demux_control(demuxer, DEMUXER_CTRL_CORRECT_PTS,
+ NULL) == DEMUXER_CTRL_OK;
return demuxer;
} else {
// demux_mov can return playlist instead of mov
@@ -911,16 +912,25 @@ static struct demuxer *open_given_type(struct MPOpts *opts,
return NULL;
}
-static struct demuxer *demux_open_stream(struct MPOpts *opts,
- struct stream *stream,
- int file_format, bool force,
- int audio_id, int video_id, int sub_id,
- char *filename,
- struct demuxer_params *params)
+struct demuxer *demux_open_withparams(struct MPOpts *opts,
+ struct stream *stream, int file_format,
+ char *force_format, int audio_id,
+ int video_id, int sub_id, char *filename,
+ struct demuxer_params *params)
{
struct demuxer *demuxer = NULL;
const struct demuxer_desc *desc;
+ int force = 0;
+ int demuxer_type;
+ if ((demuxer_type = get_demuxer_type_from_name(force_format, &force)) < 0) {
+ mp_msg(MSGT_DEMUXER, MSGL_ERR, "Demuxer %s does not exist.\n",
+ force_format);
+ return NULL;
+ }
+ if (demuxer_type)
+ file_format = demuxer_type;
+
// Some code (e.g. dvd stuff, network code, or extension.c) explicitly
// request certain file formats. The list of formats are always handled by
// libavformat.
@@ -986,129 +996,10 @@ struct demuxer *demux_open(struct MPOpts *opts, stream_t *vs, int file_format,
int audio_id, int video_id, int sub_id,
char *filename)
{
- return demux_open_withparams(opts, vs, file_format, audio_id, video_id,
- sub_id, filename, NULL);
+ return demux_open_withparams(opts, vs, file_format, opts->demuxer_name,
+ audio_id, video_id, sub_id, filename, NULL);
}
-struct demuxer *demux_open_withparams(struct MPOpts *opts, stream_t *vs,
- int file_format, int audio_id, int video_id, int dvdsub_id,
- char *filename, struct demuxer_params *params)
-{
- stream_t *as = NULL, *ss = NULL;
- demuxer_t *vd, *ad = NULL, *sd = NULL;
- demuxer_t *res;
- int afmt = DEMUXER_TYPE_UNKNOWN, sfmt = DEMUXER_TYPE_UNKNOWN;
- int demuxer_type;
- int audio_demuxer_type = 0, sub_demuxer_type = 0;
- int demuxer_force = 0, audio_demuxer_force = 0, sub_demuxer_force = 0;
-
- if ((demuxer_type =
- get_demuxer_type_from_name(opts->demuxer_name, &demuxer_force)) < 0) {
- mp_msg(MSGT_DEMUXER, MSGL_ERR, "-demuxer %s does not exist.\n",
- opts->demuxer_name);
- return NULL;
- }
- if ((audio_demuxer_type =
- get_demuxer_type_from_name(opts->audio_demuxer_name,
- &audio_demuxer_force)) < 0) {
- mp_msg(MSGT_DEMUXER, MSGL_ERR, "-audio-demuxer %s does not exist.\n",
- opts->audio_demuxer_name);
- if (opts->audio_stream)
- return NULL;
- }
- if ((sub_demuxer_type =
- get_demuxer_type_from_name(opts->sub_demuxer_name,
- &sub_demuxer_force)) < 0) {
- mp_msg(MSGT_DEMUXER, MSGL_ERR, "-sub-demuxer %s does not exist.\n",
- opts->sub_demuxer_name);
- if (opts->sub_stream)
- return NULL;
- }
-
- if (opts->audio_stream) {
- as = open_stream(opts->audio_stream, 0, &afmt);
- if (!as) {
- mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "Cannot open audio stream: %s\n",
- opts->audio_stream);
- return NULL;
- }
- if (opts->audio_stream_cache) {
- if (!stream_enable_cache
- (as, opts->audio_stream_cache * 1024,
- opts->audio_stream_cache * 1024 *
- (opts->stream_cache_min_percent / 100.0),
- opts->audio_stream_cache * 1024 *
- (opts->stream_cache_seek_min_percent / 100.0))) {
- free_stream(as);
- mp_msg(MSGT_DEMUXER, MSGL_ERR,
- "Can't enable audio stream cache\n");
- return NULL;
- }
- }
- }
- if (opts->sub_stream) {
- ss = open_stream(opts->sub_stream, 0, &sfmt);
- if (!ss) {
- mp_tmsg(MSGT_DEMUXER, MSGL_ERR, "Cannot open subtitle stream: %s\n",
- opts->sub_stream);
- return NULL;
- }
- }
-
- vd = demux_open_stream(opts, vs, demuxer_type ? demuxer_type : file_format,
- demuxer_force, opts->audio_stream ? -2 : audio_id,
- video_id, opts->sub_stream ? -2 : dvdsub_id,
- filename, params);
- if (!vd) {
- if (as)
- free_stream(as);
- if (ss)
- free_stream(ss);
- return NULL;
- }
- if (as) {
- ad = demux_open_stream(opts, as,
- audio_demuxer_type ? audio_demuxer_type : afmt,
- audio_demuxer_force, audio_id, -2, -2,
- opts->audio_stream, params);
- if (!ad) {
- mp_tmsg(MSGT_DEMUXER, MSGL_WARN, "Failed to open audio demuxer: %s\n",
- opts->audio_stream);
- free_stream(as);
- } else if (ad->audio->sh
- && ((sh_audio_t *) ad->audio->sh)->format == 0x55) // MP3
- opts->hr_mp3_seek = 1; // Enable high res seeking
- }
- if (ss) {
- sd = demux_open_stream(opts, ss,
- sub_demuxer_type ? sub_demuxer_type : sfmt,
- sub_demuxer_force, -2, -2, dvdsub_id,
- opts->sub_stream, params);
- if (!sd) {
- mp_tmsg(MSGT_DEMUXER, MSGL_WARN,
- "Failed to open subtitle demuxer: %s\n", opts->sub_stream);
- free_stream(ss);
- }
- }
-
- if (ad && sd)
- res = new_demuxers_demuxer(vd, ad, sd);
- else if (ad)
- res = new_demuxers_demuxer(vd, ad, vd);
- else if (sd)
- res = new_demuxers_demuxer(vd, vd, sd);
- else
- res = vd;
-
- opts->correct_pts = opts->user_correct_pts;
- if (opts->correct_pts < 0)
- opts->correct_pts =
- demux_control(vd ? vd : res, DEMUXER_CTRL_CORRECT_PTS,
- NULL) == DEMUXER_CTRL_OK;
- return res;
-}
-
-
void demux_flush(demuxer_t *demuxer)
{
ds_free_packs(demuxer->video);
diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h
index 50ab0525c4..cf81ce988c 100644
--- a/libmpdemux/demuxer.h
+++ b/libmpdemux/demuxer.h
@@ -72,7 +72,6 @@ enum demuxer_type {
* as demuxer type by the user (-demuxer option). */
DEMUXER_TYPE_END,
- DEMUXER_TYPE_DEMUXERS,
DEMUXER_TYPE_PLAYLIST,
};
@@ -352,14 +351,14 @@ struct demuxer *demux_open(struct MPOpts *opts, struct stream *stream,
char *filename);
struct demuxer *demux_open_withparams(struct MPOpts *opts,
- struct stream *stream, int file_format, int aid, int vid, int sid,
- char *filename, struct demuxer_params *params);
+ struct stream *stream, int file_format,
+ char *force_format, int audio_id,
+ int video_id, int sub_id, char *filename,
+ struct demuxer_params *params);
void demux_flush(struct demuxer *demuxer);
int demux_seek(struct demuxer *demuxer, float rel_seek_secs, float audio_delay,
int flags);
-struct demuxer *new_demuxers_demuxer(struct demuxer *vd, struct demuxer *ad,
- struct demuxer *sd);
// AVI demuxer params:
extern int index_mode; // -1=untouched 0=don't use index 1=use (generate) index
diff --git a/mplayer.c b/mplayer.c
index e7565adfc5..06a57b597f 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -2754,6 +2754,33 @@ static int seek(MPContext *mpctx, struct seek_params seek,
return -1;
}
+ // If audio or demuxer subs come from different files, seek them too:
+ bool have_external_tracks = false;
+ for (int type = 0; type < STREAM_TYPE_COUNT; type++) {
+ struct track *track = mpctx->current_track[type];
+ have_external_tracks |= track && track->is_external && track->demuxer;
+ }
+ if (have_external_tracks) {
+ double main_new_pos = MP_NOPTS_VALUE;
+ if (seek.type == MPSEEK_ABSOLUTE)
+ main_new_pos = seek.amount - mpctx->video_offset;
+ for (int type = 0; type < STREAM_TYPE_COUNT; type++) {
+ struct demux_stream *ds = mpctx->demuxer->ds[type];
+ if (ds->sh && main_new_pos == MP_NOPTS_VALUE) {
+ demux_fill_buffer(mpctx->demuxer, ds);
+ if (ds->first)
+ main_new_pos = ds->first->pts;
+ }
+ }
+ assert(main_new_pos != MP_NOPTS_VALUE);
+ for (int type = 0; type < STREAM_TYPE_COUNT; type++) {
+ struct track *track = mpctx->current_track[type];
+ if (track && track->is_external && track->demuxer)
+ demux_seek(track->demuxer, main_new_pos, audio_delay,
+ SEEK_ABSOLUTE);
+ }
+ }
+
if (need_reset)
reinit_audio_chain(mpctx);
/* If we just reinitialized audio it doesn't need to be reset,
@@ -3498,6 +3525,79 @@ static void open_subtitles_from_options(struct MPContext *mpctx)
}
}
+static void open_external_file(struct MPContext *mpctx, char *filename,
+ char *demuxer_name, int stream_cache,
+ enum stream_type filter)
+{
+ if (!filename)
+ return;
+ int format = 0;
+ struct stream *stream = open_stream(filename, &mpctx->opts, &format);
+ if (!stream)
+ goto err_out;
+ if (stream_cache) {
+ if (!stream_enable_cache(stream, stream_cache * 1024,
+ stream_cache * 1024 *
+ (mpctx->opts.stream_cache_min_percent / 100.0),
+ stream_cache * 1024 *
+ (mpctx->opts.stream_cache_seek_min_percent / 100.0)))
+ {
+ free_stream(stream);
+ mp_msg(MSGT_CPLAYER, MSGL_ERR,
+ "Can't enable external file stream cache\n");
+ return;
+ }
+ }
+ // deal with broken demuxers: preselect streams
+ int vs = -2, as = -2, ss = -2;
+ switch (filter) {
+ case STREAM_VIDEO: vs = -1; break;
+ case STREAM_AUDIO: as = -1; break;
+ case STREAM_SUB: ss = -1; break;
+ }
+ vs = -1; // avi can't go without video
+ struct demuxer *demuxer =
+ demux_open_withparams(&mpctx->opts, stream, format, demuxer_name,
+ as, vs, ss, filename, NULL);
+ if (!demuxer) {
+ free_stream(stream);
+ goto err_out;
+ }
+ int num_added = 0;
+ for (int n = 0; n < demuxer->num_streams; n++) {
+ struct sh_stream *stream = demuxer->streams[n];
+ if (stream->type == filter) {
+ struct track *t = add_stream_track(mpctx, stream, false);
+ t->is_external = true;
+ }
+ }
+ if (num_added == 0) {
+ mp_msg(MSGT_CPLAYER, MSGL_WARN, "No streams added from file %s.\n",
+ filename);
+ }
+ MP_TARRAY_APPEND(NULL, mpctx->sources, mpctx->num_sources, demuxer);
+ return;
+
+err_out:
+ mp_msg(MSGT_CPLAYER, MSGL_ERR, "Can not open external file %s.\n",
+ filename);
+}
+
+static void open_audiofiles_from_options(struct MPContext *mpctx)
+{
+ struct MPOpts *opts = &mpctx->opts;
+ open_external_file(mpctx, opts->audio_stream, opts->audio_demuxer_name,
+ opts->audio_stream_cache, STREAM_AUDIO);
+}
+
+// Just for -subfile. open_subtitles_from_options handles -sub text sub files.
+static void open_subfiles_from_options(struct MPContext *mpctx)
+{
+ struct MPOpts *opts = &mpctx->opts;
+ open_external_file(mpctx, opts->sub_stream, opts->sub_demuxer_name,
+ 0, STREAM_SUB);
+}
+
static void print_timeline(struct MPContext *mpctx)
{
if (mpctx->timeline) {
@@ -3714,6 +3814,8 @@ goto_enable_cache:
open_subtitles_from_options(mpctx);
open_vobsubs_from_options(mpctx);
+ open_audiofiles_from_options(mpctx);
+ open_subfiles_from_options(mpctx);
mpctx->current_track[STREAM_VIDEO] =
select_track(mpctx, STREAM_VIDEO, mpctx->opts.video_id, NULL, true);
diff --git a/timeline/tl_matroska.c b/timeline/tl_matroska.c
index 46c6d80ae4..4edc8d494e 100644
--- a/timeline/tl_matroska.c
+++ b/timeline/tl_matroska.c
@@ -141,7 +141,7 @@ static int find_ordered_chapter_sources(struct MPContext *mpctx,
if (!s)
continue;
struct demuxer *d = demux_open_withparams(&mpctx->opts, s,
- DEMUXER_TYPE_MATROSKA, mpctx->opts.audio_id,
+ DEMUXER_TYPE_MATROSKA, NULL, mpctx->opts.audio_id,
mpctx->opts.video_id, mpctx->opts.sub_id, filenames[i],
&(struct demuxer_params){.matroska_wanted_uids = uid_map});