summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-12-29 01:35:52 +0100
committerwm4 <wm4@nowhere>2015-12-29 01:35:52 +0100
commitb47bf06f9734c6a7c0a6b95721a9e3200d0f6bbb (patch)
tree7e60cf54f359ac5bc70babb26e2dcd98e056fe78 /player
parent9b3daa49745dfdc8e53940a2a449f7107940e8c4 (diff)
downloadmpv-b47bf06f9734c6a7c0a6b95721a9e3200d0f6bbb.tar.bz2
mpv-b47bf06f9734c6a7c0a6b95721a9e3200d0f6bbb.tar.xz
sub: change how subtitles are read
Slightly change how it is decided when a new packet should be read. Switch to demux_read_packet_async(), and let the player "wait properly" until required subtitle packets arrive, instead of blocking everything. Move distinguishing the cases of passive and active reading into the demuxer, where it belongs.
Diffstat (limited to 'player')
-rw-r--r--player/core.h2
-rw-r--r--player/playloop.c3
-rw-r--r--player/sub.c70
-rw-r--r--player/video.c6
4 files changed, 24 insertions, 57 deletions
diff --git a/player/core.h b/player/core.h
index 6228732bd9..fe87658d81 100644
--- a/player/core.h
+++ b/player/core.h
@@ -515,7 +515,7 @@ void reinit_subs(struct MPContext *mpctx, int order);
void uninit_sub(struct MPContext *mpctx, int order);
void uninit_sub_all(struct MPContext *mpctx);
void update_osd_msg(struct MPContext *mpctx);
-void update_subtitles(struct MPContext *mpctx);
+bool update_subtitles(struct MPContext *mpctx, double video_pts);
// video.c
void reset_video_state(struct MPContext *mpctx);
diff --git a/player/playloop.c b/player/playloop.c
index 892baf1a09..c81f720122 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -1036,7 +1036,8 @@ void run_playloop(struct MPContext *mpctx)
handle_dummy_ticks(mpctx);
update_osd_msg(mpctx);
- update_subtitles(mpctx);
+ if (!mpctx->video_out)
+ update_subtitles(mpctx, mpctx->playback_pts);
handle_segment_switch(mpctx, end_is_new_segment);
diff --git a/player/sub.c b/player/sub.c
index 42f602f754..dd1ba6d384 100644
--- a/player/sub.c
+++ b/player/sub.c
@@ -68,32 +68,14 @@ void uninit_sub_all(struct MPContext *mpctx)
uninit_sub(mpctx, 1);
}
-// When reading subtitles from a demuxer, and we read video or audio from the
-// demuxer, we should not explicitly read subtitle packets. (With external
-// subs, we have to.)
-static bool is_interleaved(struct MPContext *mpctx, struct track *track)
-{
- if (track->is_external || !track->demuxer)
- return false;
-
- struct demuxer *demuxer = track->demuxer;
- for (int t = 0; t < mpctx->num_tracks; t++) {
- struct track *other = mpctx->tracks[t];
- if (other != track && other->selected && other->demuxer == demuxer &&
- (other->type == STREAM_VIDEO || other->type == STREAM_AUDIO))
- return true;
- }
- return track->demuxer == mpctx->demuxer;
-}
-
-static void update_subtitle(struct MPContext *mpctx, int order)
+static bool update_subtitle(struct MPContext *mpctx, double video_pts, int order)
{
struct MPOpts *opts = mpctx->opts;
struct track *track = mpctx->current_track[order][STREAM_SUB];
struct dec_sub *dec_sub = mpctx->d_sub[order];
- if (!track || !dec_sub)
- return;
+ if (!track || !dec_sub || video_pts == MP_NOPTS_VALUE)
+ return true;
if (mpctx->d_video) {
struct mp_image_params params = mpctx->d_video->vfilter->override_params;
@@ -101,46 +83,26 @@ static void update_subtitle(struct MPContext *mpctx, int order)
sub_control(dec_sub, SD_CTRL_SET_VIDEO_PARAMS, &params);
}
- double refpts_s = mpctx->playback_pts;
- double curpts_s = refpts_s - opts->sub_delay;
-
- if (!track->preloaded && track->stream) {
- struct sh_stream *sh_stream = track->stream;
- bool interleaved = is_interleaved(mpctx, track);
-
- while (1) {
- if (interleaved && !demux_has_packet(sh_stream))
- break;
- double subpts_s = demux_get_next_pts(sh_stream);
- if (!demux_has_packet(sh_stream))
- break;
- if (subpts_s > curpts_s) {
- MP_DBG(mpctx, "Sub early: c_pts=%5.3f s_pts=%5.3f\n",
- curpts_s, subpts_s);
- // Often subs can be handled in advance
- if (!sub_accepts_packet_in_advance(dec_sub))
- break;
- // Try to avoid demuxing whole file at once
- if (subpts_s > curpts_s + 1 && !interleaved)
- break;
- }
- struct demux_packet *pkt = demux_read_packet(sh_stream);
- MP_DBG(mpctx, "Sub: c_pts=%5.3f s_pts=%5.3f duration=%5.3f len=%d\n",
- curpts_s, pkt->pts, pkt->duration, pkt->len);
- sub_decode(dec_sub, pkt);
- talloc_free(pkt);
- }
+ video_pts -= opts->sub_delay;
+
+ if (!track->preloaded) {
+ if (!sub_read_packets(dec_sub, video_pts))
+ return false;
}
// Handle displaying subtitles on terminal; never done for secondary subs
if (order == 0 && !mpctx->video_out)
- term_osd_set_subs(mpctx, sub_get_text(dec_sub, curpts_s));
+ term_osd_set_subs(mpctx, sub_get_text(dec_sub, video_pts));
+
+ return true;
}
-void update_subtitles(struct MPContext *mpctx)
+// Return true if the subtitles for the given PTS are ready; false if the player
+// should wait for new demuxer data, and then should retry.
+bool update_subtitles(struct MPContext *mpctx, double video_pts)
{
- update_subtitle(mpctx, 0);
- update_subtitle(mpctx, 1);
+ return update_subtitle(mpctx, video_pts, 0) &
+ update_subtitle(mpctx, video_pts, 1);
}
static bool init_subdec(struct MPContext *mpctx, struct track *track)
diff --git a/player/video.c b/player/video.c
index 1178557e24..84981b1144 100644
--- a/player/video.c
+++ b/player/video.c
@@ -1206,6 +1206,11 @@ void write_video(struct MPContext *mpctx, double endpts)
mpctx->time_frame -= get_relative_time(mpctx);
update_avsync_before_frame(mpctx);
+ if (!update_subtitles(mpctx, mpctx->next_frames[0]->pts)) {
+ MP_WARN(mpctx, "subt wait\n");
+ return;
+ }
+
double time_frame = MPMAX(mpctx->time_frame, -1);
int64_t pts = mp_time_us() + (int64_t)(time_frame * 1e6);
@@ -1262,7 +1267,6 @@ void write_video(struct MPContext *mpctx, double endpts)
mpctx->osd_force_update = true;
update_osd_msg(mpctx);
- update_subtitles(mpctx);
vo_queue_frame(vo, frame);