player: enable cache and demuxer thread for subtitles too

Includes some logic for not starting the demuxer thread for fully read
subtitles. (Well, the cache will still waste _lots_ of resources, and
the cache always has to be created, because we don't know whether it'll
be needed _before_ opening the file.)

See #1597.
This commit is contained in:
wm4 2015-02-18 21:10:43 +01:00
parent 37a0c9140a
commit 102946ee03
10 changed files with 26 additions and 3 deletions

View File

@ -820,6 +820,7 @@ static void demux_copy(struct demuxer *dst, struct demuxer *src)
dst->ts_resets_possible = src->ts_resets_possible;
dst->rel_seeks = src->rel_seeks;
dst->allow_refresh_seeks = src->allow_refresh_seeks;
dst->fully_read = src->fully_read;
dst->start_time = src->start_time;
dst->priv = src->priv;
}

View File

@ -192,6 +192,11 @@ typedef struct demuxer {
// monotonically increasing
// - seeking leaves packet positions invariant
bool allow_refresh_seeks;
// The file data was fully read, and there is no need to keep the stream
// open, keep the cache active, or to run the demuxer thread. Generating
// packets is not slow either (unlike e.g. libavdevice pseudo-demuxers).
// Typical examples: text subtitles, playlists
bool fully_read;
// Bitmask of DEMUX_EVENT_*
int events;

View File

@ -433,6 +433,7 @@ static int try_open_file(struct demuxer *demuxer, enum demux_check check)
}
struct priv *p = talloc_zero(demuxer, struct priv);
demuxer->priv = p;
demuxer->fully_read = true;
p->data = stream_read_complete(s, demuxer, 1000000);
if (p->data.start == NULL)
return -1;

View File

@ -311,6 +311,7 @@ static int try_open_file(struct demuxer *demuxer, enum demux_check check)
{
struct priv *p = talloc_zero(demuxer, struct priv);
demuxer->priv = p;
demuxer->fully_read = true;
struct stream *s = demuxer->stream;
if (s->uncached_type == STREAMTYPE_EDL) {

View File

@ -103,12 +103,14 @@ struct format_hack {
bool ignore : 1; // blacklisted
bool no_stream : 1; // do not wrap struct stream as AVIOContext
bool use_stream_ids : 1; // export the native stream IDs
bool fully_read : 1; // set demuxer.fully_read flag
// Do not confuse player's position estimation (position is into external
// segment, with e.g. HLS, player knows about the playlist main file only).
bool clear_filepos : 1;
};
#define BLACKLIST(fmt) {fmt, .ignore = true}
#define TEXTSUB(fmt) {fmt, .fully_read = true}
static const struct format_hack format_hacks[] = {
// for webradios
@ -123,6 +125,11 @@ static const struct format_hack format_hacks[] = {
{"mpeg", .use_stream_ids = true},
{"mpegts", .use_stream_ids = true},
TEXTSUB("aqtitle"), TEXTSUB("ass"), TEXTSUB("jacosub"), TEXTSUB("microdvd"),
TEXTSUB("mpl2"), TEXTSUB("mpsub"), TEXTSUB("pjs"), TEXTSUB("realtext"),
TEXTSUB("sami"), TEXTSUB("srt"), TEXTSUB("stl"), TEXTSUB("subviewer"),
TEXTSUB("subviewer1"), TEXTSUB("vplayer"), TEXTSUB("webvtt"),
// Useless non-sense, sometimes breaks MLP2 subreader.c fallback
BLACKLIST("tty"),
// Image demuxers, disabled in favor of demux_mf (for now):
@ -815,6 +822,7 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
0 : (double)priv->avfc->start_time / AV_TIME_BASE;
demuxer->allow_refresh_seeks = matches_avinputformat_name(priv, "mp4");
demuxer->fully_read = priv->format_hack.fully_read;
return 0;
}

View File

@ -99,6 +99,7 @@ static int d_check_file(struct demuxer *demuxer, enum demux_check check)
sh->sub->extradata_len = cbuf.len;
demuxer->seekable = true;
demuxer->fully_read = true;
return 0;
}

View File

@ -273,6 +273,7 @@ static int open_file(struct demuxer *demuxer, enum demux_check check)
playlist_add_base_path(p->pl, mp_dirname(demuxer->filename));
demuxer->playlist = talloc_steal(demuxer, p->pl);
demuxer->filetype = fmt->name;
demuxer->fully_read = true;
talloc_free(p);
return ok ? 0 : -1;
}

View File

@ -791,6 +791,7 @@ static int d_open_file(struct demuxer *demuxer, enum demux_check check)
subdata_free(sd);
demuxer->seekable = true;
demuxer->fully_read = true;
return 0;
}

View File

@ -291,8 +291,8 @@ static void enable_demux_thread(struct MPContext *mpctx)
demux_start_thread(mpctx->demuxer);
for (int n = 0; n < mpctx->num_tracks; n++) {
struct track *track = mpctx->tracks[n];
if (track->is_external && track->stream &&
track->stream->type != STREAM_SUB)
if (track->is_external && track->stream && !track->preloaded &&
!track->demuxer->fully_read)
{
demux_set_wakeup_cb(track->demuxer, wakeup_demux, mpctx);
demux_start_thread(track->demuxer);
@ -689,6 +689,7 @@ struct track *mp_add_external_file(struct MPContext *mpctx, char *filename,
struct stream *stream = stream_open(filename, mpctx->global);
if (!stream)
goto err_out;
stream_enable_cache(&stream, &opts->stream_cache);
char *demuxer_name = NULL;
switch (filter) {
@ -697,7 +698,6 @@ struct track *mp_add_external_file(struct MPContext *mpctx, char *filename,
break;
case STREAM_AUDIO:
demuxer_name = opts->audio_demuxer_name;
stream_enable_cache(&stream, &opts->stream_cache);
break;
}
@ -731,6 +731,8 @@ struct track *mp_add_external_file(struct MPContext *mpctx, char *filename,
}
MP_TARRAY_APPEND(NULL, mpctx->sources, mpctx->num_sources, demuxer);
if (mpctx->playback_initialized)
enable_demux_thread(mpctx);
return first;
err_out:

View File

@ -321,6 +321,8 @@ static void reinit_subdec(struct MPContext *mpctx, struct track *track,
if (!track->preloaded && track->is_external && !opts->sub_clear_on_seek) {
demux_seek(track->demuxer, 0, SEEK_ABSOLUTE);
track->preloaded = sub_read_all_packets(dec_sub, track->stream);
if (track->preloaded)
demux_stop_thread(track->demuxer);
}
}