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.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,