summaryrefslogtreecommitdiffstats
path: root/sub/dec_sub.c
diff options
context:
space:
mode:
Diffstat (limited to 'sub/dec_sub.c')
-rw-r--r--sub/dec_sub.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index 75f5509c62..3b1e957038 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -49,10 +49,11 @@ struct dec_sub {
struct mpv_global *global;
struct MPOpts *opts;
- struct demuxer *demuxer;
+ struct attachment_list *attachments;
struct sh_stream *sh;
double last_pkt_pts;
+ bool preload_attempted;
struct mp_codec_params *codec;
double start, end;
@@ -94,8 +95,9 @@ static struct sd *init_decoder(struct dec_sub *sub)
.log = mp_log_new(sd, sub->log, driver->name),
.opts = sub->opts,
.driver = driver,
- .demuxer = sub->demuxer,
+ .attachments = sub->attachments,
.codec = sub->codec,
+ .preload_ok = true,
};
if (sd->driver->init(sd) >= 0)
@@ -112,10 +114,12 @@ static struct sd *init_decoder(struct dec_sub *sub)
// Thread-safety of the returned object: all functions are thread-safe,
// except sub_get_bitmaps() and sub_get_text(). Decoder backends (sd_*)
// do not need to acquire locks.
-struct dec_sub *sub_create(struct mpv_global *global, struct demuxer *demuxer,
- struct sh_stream *sh)
+// Ownership of attachments goes to the caller, and is released with
+// talloc_free() (even on failure).
+struct dec_sub *sub_create(struct mpv_global *global, struct sh_stream *sh,
+ struct attachment_list *attachments)
{
- assert(demuxer && sh && sh->type == STREAM_SUB);
+ assert(sh && sh->type == STREAM_SUB);
struct dec_sub *sub = talloc(NULL, struct dec_sub);
*sub = (struct dec_sub){
@@ -124,7 +128,7 @@ struct dec_sub *sub_create(struct mpv_global *global, struct demuxer *demuxer,
.opts = global->opts,
.sh = sh,
.codec = sh->codec,
- .demuxer = demuxer,
+ .attachments = talloc_steal(sub, attachments),
.last_pkt_pts = MP_NOPTS_VALUE,
.last_vo_pts = MP_NOPTS_VALUE,
.start = MP_NOPTS_VALUE,
@@ -146,6 +150,9 @@ static void update_segment(struct dec_sub *sub)
if (sub->new_segment && sub->last_vo_pts != MP_NOPTS_VALUE &&
sub->last_vo_pts >= sub->new_segment->start)
{
+ MP_VERBOSE(sub, "Switch segment: %f at %f\n", sub->new_segment->start,
+ sub->last_vo_pts);
+
sub->codec = sub->new_segment->codec;
sub->start = sub->new_segment->start;
sub->end = sub->new_segment->end;
@@ -165,16 +172,20 @@ static void update_segment(struct dec_sub *sub)
}
}
-// Read all packets from the demuxer and decode/add them. Returns false if
-// there are circumstances which makes this not possible.
-bool sub_read_all_packets(struct dec_sub *sub)
+bool sub_can_preload(struct dec_sub *sub)
{
+ bool r;
pthread_mutex_lock(&sub->lock);
+ r = sub->sd->driver->accept_packets_in_advance && !sub->preload_attempted;
+ pthread_mutex_unlock(&sub->lock);
+ return r;
+}
- if (!sub->sd->driver->accept_packets_in_advance) {
- pthread_mutex_unlock(&sub->lock);
- return false;
- }
+void sub_preload(struct dec_sub *sub)
+{
+ pthread_mutex_lock(&sub->lock);
+
+ sub->preload_attempted = true;
for (;;) {
struct demux_packet *pkt = demux_read_packet(sub->sh);
@@ -185,7 +196,6 @@ bool sub_read_all_packets(struct dec_sub *sub)
}
pthread_mutex_unlock(&sub->lock);
- return true;
}
// Read packets from the demuxer stream passed to sub_create(). Return true if
@@ -203,6 +213,11 @@ bool sub_read_packets(struct dec_sub *sub, double video_pts)
if (!read_more)
break;
+ if (sub->new_segment && sub->new_segment->start < video_pts) {
+ sub->last_vo_pts = video_pts;
+ update_segment(sub);
+ }
+
if (sub->new_segment)
break;
@@ -228,7 +243,9 @@ bool sub_read_packets(struct dec_sub *sub, double video_pts)
break;
}
- sub->sd->driver->decode(sub->sd, pkt);
+ if (!(sub->preload_attempted && sub->sd->preload_ok))
+ sub->sd->driver->decode(sub->sd, pkt);
+
talloc_free(pkt);
}
pthread_mutex_unlock(&sub->lock);
@@ -243,8 +260,6 @@ void sub_get_bitmaps(struct dec_sub *sub, struct mp_osd_res dim, double pts,
{
struct MPOpts *opts = sub->opts;
- *res = (struct sub_bitmaps) {0};
-
sub->last_vo_pts = pts;
update_segment(sub);