summaryrefslogtreecommitdiffstats
path: root/sub/dec_sub.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-06-01 19:54:18 +0200
committerwm4 <wm4@nowhere>2013-06-03 22:40:02 +0200
commite19ffa02aa370cbc3b559f85b286ea09b06ab29b (patch)
tree3335cdcc8664d9e3b98631fe8128b138c095069a /sub/dec_sub.c
parent14dd95154820d4ec9afb5200335177b011233049 (diff)
downloadmpv-e19ffa02aa370cbc3b559f85b286ea09b06ab29b.tar.bz2
mpv-e19ffa02aa370cbc3b559f85b286ea09b06ab29b.tar.xz
sub: turn subassconvert_ functions into sub converters
This means subassconvert.c is split in sd_srt.c and sd_microdvd.c. Now this code is involved in the sub conversion chain like sd_movtext is. The invocation of the converter in sd_ass.c is removed. This requires some other changes to make the new sub converter code work with loading external subtitles. Until now, subtitles loaded via subreader.c was assumed to be in plaintext, or for some formats, in ASS (except in -no-ass mode). Then these were added to an ASS_Track. Change this so that subtitles are always in their original format (as far as decoders/converters for them are available), and turn every sub event read by subreader.c as packet to the dec_sub.c subtitle chain. This removes differences between external/demuxed and -ass/-no-ass code paths further.
Diffstat (limited to 'sub/dec_sub.c')
-rw-r--r--sub/dec_sub.c67
1 files changed, 62 insertions, 5 deletions
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index 6ef1e4a8cf..49ecd5c009 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -22,9 +22,10 @@
#include "config.h"
#include "demux/stheader.h"
-#include "sub/sd.h"
-#include "sub/sub.h"
-#include "sub/dec_sub.h"
+#include "sd.h"
+#include "sub.h"
+#include "dec_sub.h"
+#include "subreader.h"
#include "core/options.h"
#include "core/mp_msg.h"
@@ -32,6 +33,8 @@ extern const struct sd_functions sd_ass;
extern const struct sd_functions sd_lavc;
extern const struct sd_functions sd_spu;
extern const struct sd_functions sd_movtext;
+extern const struct sd_functions sd_srt;
+extern const struct sd_functions sd_microdvd;
static const struct sd_functions *sd_list[] = {
#ifdef CONFIG_ASS
@@ -40,10 +43,12 @@ static const struct sd_functions *sd_list[] = {
&sd_lavc,
&sd_spu,
&sd_movtext,
+ &sd_srt,
+ &sd_microdvd,
NULL
};
-#define MAX_NUM_SD 2
+#define MAX_NUM_SD 3
struct dec_sub {
struct MPOpts *opts;
@@ -108,6 +113,55 @@ void sub_set_ass_renderer(struct dec_sub *sub, struct ass_library *ass_library,
sub->init_sd.ass_renderer = ass_renderer;
}
+// Subtitles read with subreader.c
+static void read_sub_data(struct dec_sub *sub, struct sub_data *subdata)
+{
+ assert(sub_accept_packets_in_advance(sub));
+ char *temp = NULL;
+
+ for (int i = 0; i < subdata->sub_num; i++) {
+ subtitle *st = &subdata->subtitles[i];
+ // subdata is in 10 ms ticks, pts is in seconds
+ double t = subdata->sub_uses_time ? 0.01 : (1 / subdata->fallback_fps);
+
+ int len = 0;
+ for (int j = 0; j < st->lines; j++)
+ len += st->text[j] ? strlen(st->text[j]) : 0;
+
+ len += 2 * st->lines; // '\N', including the one after the last line
+ len += 6; // {\anX}
+ len += 1; // '\0'
+
+ if (talloc_get_size(temp) < len) {
+ talloc_free(temp);
+ temp = talloc_array(NULL, char, len);
+ }
+
+ char *p = temp;
+ char *end = p + len;
+
+ if (st->alignment)
+ p += snprintf(p, end - p, "{\\an%d}", st->alignment);
+
+ for (int j = 0; j < st->lines; j++)
+ p += snprintf(p, end - p, "%s\\N", st->text[j]);
+
+ if (st->lines > 0)
+ p -= 2; // remove last "\N"
+ *p = 0;
+
+ struct demux_packet pkt = {0};
+ pkt.pts = st->start * t;
+ pkt.duration = (st->end - st->start) * t;
+ pkt.buffer = temp;
+ pkt.len = strlen(temp);
+
+ sub_decode(sub, &pkt);
+ }
+
+ talloc_free(temp);
+}
+
static int sub_init_decoder(struct dec_sub *sub, struct sd *sd)
{
sd->driver = NULL;
@@ -148,8 +202,11 @@ void sub_init_from_sh(struct dec_sub *sub, struct sh_sub *sh)
sub->sd[sub->num_sd] = sd;
sub->num_sd++;
// Try adding new converters until a decoder is reached
- if (sd->driver->get_bitmaps || sd->driver->get_text)
+ if (sd->driver->get_bitmaps || sd->driver->get_text) {
+ if (sh->sub_data)
+ read_sub_data(sub, sh->sub_data);
return;
+ }
init_sd = (struct sd) {
.codec = sd->output_codec,
.extradata = sd->output_extradata,