summaryrefslogtreecommitdiffstats
path: root/sub
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-06-11 21:39:54 +0200
committerwm4 <wm4@nowhere>2013-06-23 22:33:59 +0200
commita70d575291d48289669ee8989e0597a94189dd8d (patch)
treefd2ddf88485e40e77183ac8aceb68a7557ddfa49 /sub
parenta792f0d628ea6170ce351fc816a2d71e276a8c49 (diff)
downloadmpv-a70d575291d48289669ee8989e0597a94189dd8d.tar.bz2
mpv-a70d575291d48289669ee8989e0597a94189dd8d.tar.xz
sub: preload external text subtitles
If a subtitle is external, read it completely and add all subtitle events in advance when the subtitle track is selected. This is done for text subtitles only. (Note that subreader.c and subtitles loaded with libass are different and don't have anything to do with this commit.)
Diffstat (limited to 'sub')
-rw-r--r--sub/dec_sub.c60
-rw-r--r--sub/dec_sub.h2
2 files changed, 61 insertions, 1 deletions
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index b72630470c..187ae5f22c 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -21,7 +21,7 @@
#include <assert.h>
#include "config.h"
-#include "demux/stheader.h"
+#include "demux/demux.h"
#include "sd.h"
#include "sub.h"
#include "dec_sub.h"
@@ -56,10 +56,17 @@ struct dec_sub {
struct MPOpts *opts;
struct sd init_sd;
+ double video_fps;
+
struct sd *sd[MAX_NUM_SD];
int num_sd;
};
+struct packet_list {
+ struct demux_packet **packets;
+ int num_packets;
+};
+
struct dec_sub *sub_create(struct MPOpts *opts)
{
struct dec_sub *sub = talloc_zero(NULL, struct dec_sub);
@@ -102,6 +109,11 @@ void sub_set_video_res(struct dec_sub *sub, int w, int h)
sub->init_sd.sub_video_h = h;
}
+void sub_set_video_fps(struct dec_sub *sub, double fps)
+{
+ sub->video_fps = fps;
+}
+
void sub_set_extradata(struct dec_sub *sub, void *data, int data_len)
{
sub->init_sd.extradata = data_len ? talloc_memdup(sub, data, data_len) : NULL;
@@ -249,6 +261,52 @@ void sub_init_from_sh(struct dec_sub *sub, struct sh_sub *sh)
sh->gsh->codec ? sh->gsh->codec : "<unknown>");
}
+static void add_sub_list(struct dec_sub *sub, struct packet_list *subs)
+{
+ struct sd *sd = sub_get_last_sd(sub);
+ assert(sd);
+
+ sd->no_remove_duplicates = true;
+
+ for (int n = 0; n < subs->num_packets; n++)
+ sub_decode(sub, subs->packets[n]);
+
+ // Hack for broken FFmpeg packet format: make sd_ass keep the subtitle
+ // events on reset(), even if broken FFmpeg ASS packets were received
+ // (from sd_lavc_conv.c). Normally, these events are removed on seek/reset,
+ // but this is obviously unwanted in this case.
+ if (sd->driver->fix_events)
+ sd->driver->fix_events(sd);
+
+ sd->no_remove_duplicates = false;
+}
+
+// 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, struct sh_sub *sh)
+{
+ if (!sub_accept_packets_in_advance(sub) || sh->track)
+ return false;
+
+ void *tmp = talloc_new(NULL);
+ struct packet_list subs = {0};
+
+ for (;;) {
+ ds_get_next_pts(sh->ds);
+ struct demux_packet *pkt = ds_get_packet_sub(sh->ds);
+ if (!pkt)
+ break;
+ pkt = demux_copy_packet(pkt);
+ talloc_steal(tmp, pkt);
+ MP_TARRAY_APPEND(tmp, subs.packets, subs.num_packets, pkt);
+ }
+
+ add_sub_list(sub, &subs);
+
+ talloc_free(tmp);
+ return true;
+}
+
bool sub_accept_packets_in_advance(struct dec_sub *sub)
{
// Converters are assumed to always accept packets in advance
diff --git a/sub/dec_sub.h b/sub/dec_sub.h
index 805a87ef5c..c285449f94 100644
--- a/sub/dec_sub.h
+++ b/sub/dec_sub.h
@@ -20,6 +20,7 @@ struct dec_sub *sub_create(struct MPOpts *opts);
void sub_destroy(struct dec_sub *sub);
void sub_set_video_res(struct dec_sub *sub, int w, int h);
+void sub_set_video_fps(struct dec_sub *sub, double fps);
void sub_set_extradata(struct dec_sub *sub, void *data, int data_len);
void sub_set_ass_renderer(struct dec_sub *sub, struct ass_library *ass_library,
struct ass_renderer *ass_renderer);
@@ -27,6 +28,7 @@ void sub_init_from_sh(struct dec_sub *sub, struct sh_sub *sh);
bool sub_is_initialized(struct dec_sub *sub);
+bool sub_read_all_packets(struct dec_sub *sub, struct sh_sub *sh);
bool sub_accept_packets_in_advance(struct dec_sub *sub);
void sub_decode(struct dec_sub *sub, struct demux_packet *packet);
void sub_get_bitmaps(struct dec_sub *sub, struct mp_osd_res dim, double pts,