summaryrefslogtreecommitdiffstats
path: root/mpvcore
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-11-23 21:37:15 +0100
committerwm4 <wm4@nowhere>2013-11-23 21:37:15 +0100
commit639e672bd153e06cfc01ced6c2a48b45870e8f31 (patch)
tree7b683231216221252860c9b686f744ad7354fa2f /mpvcore
parent3486302514db31b8086f46226d9b46d53810d1e7 (diff)
downloadmpv-639e672bd153e06cfc01ced6c2a48b45870e8f31.tar.bz2
mpv-639e672bd153e06cfc01ced6c2a48b45870e8f31.tar.xz
player: rearrange how subtitle context and stream headers are used
Use sh_stream over sh_sub. Use dec_sub (and mpctx->d_sub) instead of the stream header. This aligns the subtitle code with the recent audio and video refactoring. sh_sub still has the decoder context, though. This is because we want to avoid reinit when switching segments with ordered chapters. (Reinit is fast, except for creating the ASS_Renderer, which in turn triggers fontconfig.) Not sure how much this matters, though, because the initial segment switch will lazily initialize the decoder anyway.
Diffstat (limited to 'mpvcore')
-rw-r--r--mpvcore/player/loadfile.c27
-rw-r--r--mpvcore/player/mp_core.h2
-rw-r--r--mpvcore/player/sub.c50
3 files changed, 40 insertions, 39 deletions
diff --git a/mpvcore/player/loadfile.c b/mpvcore/player/loadfile.c
index 51d3f2ec7e..33ee770b08 100644
--- a/mpvcore/player/loadfile.c
+++ b/mpvcore/player/loadfile.c
@@ -80,9 +80,10 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
if (mask & INITIALIZED_SUB) {
mpctx->initialized_flags &= ~INITIALIZED_SUB;
- if (mpctx->sh_sub)
- sub_reset(mpctx->sh_sub->dec_sub);
+ if (mpctx->d_sub)
+ sub_reset(mpctx->d_sub);
cleanup_demux_stream(mpctx, STREAM_SUB);
+ mpctx->d_sub = NULL; // Note: not free'd.
mpctx->osd->dec_sub = NULL;
reset_subtitles(mpctx);
}
@@ -108,13 +109,15 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
if (mask & INITIALIZED_DEMUXER) {
mpctx->initialized_flags &= ~INITIALIZED_DEMUXER;
+ assert(!(mpctx->initialized_flags &
+ (INITIALIZED_VCODEC | INITIALIZED_ACODEC | INITIALIZED_SUB)));
for (int i = 0; i < mpctx->num_tracks; i++) {
talloc_free(mpctx->tracks[i]);
}
mpctx->num_tracks = 0;
for (int t = 0; t < STREAM_TYPE_COUNT; t++)
mpctx->current_track[t] = NULL;
- assert(!mpctx->d_video && !mpctx->d_audio && !mpctx->sh_sub);
+ assert(!mpctx->d_video && !mpctx->d_audio && !mpctx->d_sub);
mpctx->master_demuxer = NULL;
for (int i = 0; i < mpctx->num_sources; i++) {
uninit_subs(mpctx->sources[i]);
@@ -264,22 +267,12 @@ static void print_file_properties(struct MPContext *mpctx)
}
}
-static void set_demux_field(struct MPContext *mpctx, enum stream_type type,
- struct sh_stream *s)
-{
- mpctx->sh[type] = s;
- // redundant fields for convenience access
- switch(type) {
- case STREAM_SUB: mpctx->sh_sub = s ? s->sub : NULL; break;
- }
-}
-
struct sh_stream *init_demux_stream(struct MPContext *mpctx,
enum stream_type type)
{
struct track *track = mpctx->current_track[type];
- set_demux_field(mpctx, type, track ? track->stream : NULL);
- struct sh_stream *stream = mpctx->sh[type];
+ struct sh_stream *stream = track ? track->stream : NULL;
+ mpctx->sh[type] = stream;
if (stream) {
demuxer_switch_track(stream->demuxer, type, stream);
if (track->is_external) {
@@ -295,7 +288,7 @@ void cleanup_demux_stream(struct MPContext *mpctx, enum stream_type type)
struct sh_stream *stream = mpctx->sh[type];
if (stream)
demuxer_switch_track(stream->demuxer, type, NULL);
- set_demux_field(mpctx, type, NULL);
+ mpctx->sh[type] = NULL;
}
// Switch the demuxers to current track selection. This is possibly important
@@ -1051,7 +1044,7 @@ static void play_current_file(struct MPContext *mpctx)
assert(mpctx->demuxer == NULL);
assert(mpctx->d_audio == NULL);
assert(mpctx->d_video == NULL);
- assert(mpctx->sh_sub == NULL);
+ assert(mpctx->d_sub == NULL);
char *stream_filename = mpctx->filename;
mpctx->resolve_result = resolve_url(stream_filename, opts);
diff --git a/mpvcore/player/mp_core.h b/mpvcore/player/mp_core.h
index f372c4e137..0be7e1df1f 100644
--- a/mpvcore/player/mp_core.h
+++ b/mpvcore/player/mp_core.h
@@ -199,10 +199,10 @@ typedef struct MPContext {
struct track *current_track[STREAM_TYPE_COUNT];
struct sh_stream *sh[STREAM_TYPE_COUNT];
- struct sh_sub *sh_sub; // same as sh[STREAM_SUB]->sub
struct dec_video *d_video;
struct dec_audio *d_audio;
+ struct dec_sub *d_sub;
// Uses: accessing metadata (consider ordered chapters case, where the main
// demuxer defines metadata), or special purpose demuxers like TV.
diff --git a/mpvcore/player/sub.c b/mpvcore/player/sub.c
index d659e74851..bdcb9def09 100644
--- a/mpvcore/player/sub.c
+++ b/mpvcore/player/sub.c
@@ -67,8 +67,8 @@ static bool is_interleaved(struct MPContext *mpctx, struct track *track)
void reset_subtitles(struct MPContext *mpctx)
{
- if (mpctx->sh_sub)
- sub_reset(mpctx->sh_sub->dec_sub);
+ if (mpctx->d_sub)
+ sub_reset(mpctx->d_sub);
set_osd_subtitle(mpctx, NULL);
osd_changed(mpctx->osd, OSDTYPE_SUB);
}
@@ -80,9 +80,8 @@ void update_subtitles(struct MPContext *mpctx)
return;
struct track *track = mpctx->current_track[STREAM_SUB];
- struct sh_sub *sh_sub = mpctx->sh_sub;
- assert(track && sh_sub);
- struct dec_sub *dec_sub = sh_sub->dec_sub;
+ struct dec_sub *dec_sub = mpctx->d_sub;
+ assert(track && dec_sub);
if (mpctx->d_video && mpctx->d_video->vf_input) {
struct mp_image_params params = *mpctx->d_video->vf_input;
@@ -94,14 +93,17 @@ void update_subtitles(struct MPContext *mpctx)
double refpts_s = mpctx->playback_pts - mpctx->osd->video_offset;
double curpts_s = refpts_s + opts->sub_delay;
- if (!track->preloaded) {
+ if (!track->preloaded && track->stream) {
+ struct sh_stream *sh_stream = track->stream;
bool interleaved = is_interleaved(mpctx, track);
+ assert(sh_stream->sub->dec_sub == dec_sub);
+
while (1) {
- if (interleaved && !demux_has_packet(sh_sub->gsh))
+ if (interleaved && !demux_has_packet(sh_stream))
break;
- double subpts_s = demux_get_next_pts(sh_sub->gsh);
- if (!demux_has_packet(sh_sub->gsh))
+ double subpts_s = demux_get_next_pts(sh_stream);
+ if (!demux_has_packet(sh_stream))
break;
if (subpts_s > curpts_s) {
mp_dbg(MSGT_CPLAYER, MSGL_DBG2,
@@ -114,7 +116,7 @@ void update_subtitles(struct MPContext *mpctx)
if (subpts_s > curpts_s + 1 && !interleaved)
break;
}
- struct demux_packet *pkt = demux_read_packet(sh_sub->gsh);
+ struct demux_packet *pkt = demux_read_packet(sh_stream);
mp_dbg(MSGT_CPLAYER, MSGL_V, "Sub: c_pts=%5.3f s_pts=%5.3f "
"duration=%5.3f len=%d\n", curpts_s, pkt->pts, pkt->duration,
pkt->len);
@@ -177,21 +179,27 @@ void reinit_subs(struct MPContext *mpctx)
assert(!(mpctx->initialized_flags & INITIALIZED_SUB));
init_demux_stream(mpctx, STREAM_SUB);
- if (!mpctx->sh_sub)
+ struct sh_stream *sh = mpctx->sh[STREAM_SUB];
+
+ // No track selected, or lazily added DVD track (will actually be created
+ // on first sub packet)
+ if (!sh)
return;
- if (!mpctx->sh_sub->dec_sub)
- mpctx->sh_sub->dec_sub = sub_create(opts);
+ if (!sh->sub->dec_sub) {
+ assert(!mpctx->d_sub);
+ sh->sub->dec_sub = sub_create(opts);
+ }
- assert(track->demuxer);
- // Lazily added DVD track - will be created on first sub packet
- if (!track->stream)
- return;
+ assert(!mpctx->d_sub || sh->sub->dec_sub == mpctx->d_sub);
+
+ // The decoder is kept in the stream header in order to make ordered
+ // chapters work well.
+ mpctx->d_sub = sh->sub->dec_sub;
mpctx->initialized_flags |= INITIALIZED_SUB;
- struct sh_sub *sh_sub = mpctx->sh_sub;
- struct dec_sub *dec_sub = sh_sub->dec_sub;
+ struct dec_sub *dec_sub = mpctx->d_sub;
assert(dec_sub);
if (!sub_is_initialized(dec_sub)) {
@@ -206,14 +214,14 @@ void reinit_subs(struct MPContext *mpctx)
sub_set_video_fps(dec_sub, fps);
sub_set_ass_renderer(dec_sub, mpctx->osd->ass_library,
mpctx->osd->ass_renderer);
- sub_init_from_sh(dec_sub, sh_sub);
+ sub_init_from_sh(dec_sub, sh);
// Don't do this if the file has video/audio streams. Don't do it even
// if it has only sub streams, because reading packets will change the
// demuxer position.
if (!track->preloaded && track->is_external) {
demux_seek(track->demuxer, 0, SEEK_ABSOLUTE);
- track->preloaded = sub_read_all_packets(dec_sub, sh_sub);
+ track->preloaded = sub_read_all_packets(dec_sub, sh);
}
}