diff options
Diffstat (limited to 'sub/dec_sub.c')
-rw-r--r-- | sub/dec_sub.c | 67 |
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, |