summaryrefslogtreecommitdiffstats
path: root/libhb/muxcommon.c
diff options
context:
space:
mode:
authorJohn Stebbins <[email protected]>2016-05-08 10:33:22 -0700
committerJohn Stebbins <[email protected]>2016-05-08 10:33:22 -0700
commit1e119dcaf86804c48da857d2b4673b6c3c8d6b3f (patch)
treee2747f84a85e563bd2ea430dff8bbf0199f76338 /libhb/muxcommon.c
parent36029073fd0196fa4093221310e961f71bae23b3 (diff)
mux: eliminate 2048 byte size limit of SSA subtitles
Diffstat (limited to 'libhb/muxcommon.c')
-rw-r--r--libhb/muxcommon.c145
1 files changed, 111 insertions, 34 deletions
diff --git a/libhb/muxcommon.c b/libhb/muxcommon.c
index 0a846def1..7ae015d99 100644
--- a/libhb/muxcommon.c
+++ b/libhb/muxcommon.c
@@ -706,20 +706,63 @@ hb_work_object_t hb_muxer =
HB_STYLE_FLAG_ITALIC | \
HB_STYLE_FLAG_UNDERLINE)
+struct output_buf_s
+{
+ int alloc;
+ int size;
+ uint8_t * buf;
+};
+
typedef struct style_context_s
{
- uint8_t * style_atoms;
+ struct output_buf_s style_atoms;
int style_atom_count;
hb_subtitle_style_t current_style;
int style_start;
} style_context_t;
-static void update_style_atoms(style_context_t *ctx, int stop)
+static int check_realloc_output(struct output_buf_s * output, int size)
{
- uint8_t *style_entry;
- uint8_t face = 0;
+ if (output->alloc < size)
+ {
+ uint8_t * tmp;
- style_entry = ctx->style_atoms + 10 + (12 * ctx->style_atom_count);
+ if (output->alloc == 0)
+ {
+ output->alloc = 1024;
+ }
+ else
+ {
+ output->alloc *= 2;
+ }
+ output->size = size;
+ tmp = realloc(output->buf, output->alloc);
+ if (tmp == NULL)
+ {
+ hb_error("realloc failed!");
+ free(output->buf);
+ output->size = 0;
+ output->alloc = 0;
+ output->buf = NULL;
+ return 0;
+ }
+ output->buf = tmp;
+ }
+ return 1;
+}
+
+static int update_style_atoms(style_context_t *ctx, int stop)
+{
+ uint8_t * style_entry;
+ uint8_t face = 0;
+ int pos = 10 + (12 * ctx->style_atom_count);
+ int size = 10 + (12 * (ctx->style_atom_count + 1));
+
+ if (!check_realloc_output(&ctx->style_atoms, size))
+ {
+ return 0;
+ }
+ style_entry = ctx->style_atoms.buf + pos;
if (ctx->current_style.flags & HB_STYLE_FLAG_BOLD)
face |= 1;
@@ -741,11 +784,15 @@ static void update_style_atoms(style_context_t *ctx, int stop)
style_entry[10] = (ctx->current_style.fg_rgb) & 0xff; // b
style_entry[11] = ctx->current_style.fg_alpha; // a
+printf("rgb %x face %x alpha %d start %d stop %d\n", ctx->current_style.fg_rgb, face, ctx->current_style.fg_alpha, ctx->style_start, stop);
+
ctx->style_atom_count++;
+
+ return 1;
}
-static void update_style(style_context_t *ctx,
- hb_subtitle_style_t *style, int pos)
+static int update_style(style_context_t *ctx,
+ hb_subtitle_style_t *style, int pos)
{
if (ctx->style_start < pos)
{
@@ -754,7 +801,10 @@ static void update_style(style_context_t *ctx,
ctx->current_style.fg_rgb != style->fg_rgb ||
ctx->current_style.fg_alpha != style->fg_alpha)
{
- update_style_atoms(ctx, pos - 1);
+ if (!update_style_atoms(ctx, pos - 1))
+ {
+ return 0;
+ }
ctx->current_style = *style;
ctx->style_start = pos;
}
@@ -764,13 +814,16 @@ static void update_style(style_context_t *ctx,
ctx->current_style = *style;
ctx->style_start = pos;
}
+ return 1;
}
-static void style_context_init(style_context_t *ctx, uint8_t *style_atoms)
+static void style_context_init(style_context_t *ctx)
{
memset(ctx, 0, sizeof(*ctx));
- ctx->style_atoms = style_atoms;
- ctx->style_start = INT_MAX;
+ ctx->style_atoms.buf = NULL;
+ ctx->style_atoms.size = 0;
+ ctx->style_atoms.alloc = 0;
+ ctx->style_start = INT_MAX;
}
/*
@@ -778,18 +831,25 @@ static void style_context_init(style_context_t *ctx, uint8_t *style_atoms)
* atom where appropriate.
*/
void hb_muxmp4_process_subtitle_style(uint8_t *input,
- uint8_t *output,
- uint8_t *style_atoms, uint16_t *stylesize)
-{
- uint16_t utf8_count = 0; // utf8 count from start of subtitle
- int consumed, in_pos = 0, out_pos = 0, len, ii;
- style_context_t ctx;
- hb_subtitle_style_t style;
- char *text, *tmp;
-
- *stylesize = 0;
- style_context_init(&ctx, style_atoms);
-
+ uint8_t **out_buf,
+ uint8_t **out_style_atoms,
+ uint16_t *stylesize)
+{
+ uint16_t utf8_count = 0; // utf8 count from start of subtitle
+ int consumed, in_pos = 0, out_pos = 0, len, ii;
+ style_context_t ctx;
+ hb_subtitle_style_t style;
+ struct output_buf_s output;
+ char * text, * tmp;
+
+ output.buf = NULL;
+ output.alloc = 0;
+ output.size = 0;
+ *out_buf = NULL;
+ *out_style_atoms = NULL;
+ *stylesize = 0;
+
+ style_context_init(&ctx);
hb_ssa_style_init(&style);
// Skip past the SSA preamble
@@ -821,32 +881,49 @@ void hb_muxmp4_process_subtitle_style(uint8_t *input,
}
len++;
}
- strcpy((char*)output+out_pos, text);
+ if (!check_realloc_output(&output, out_pos + len + 1))
+ {
+ goto fail;
+ }
+ strcpy((char*)output.buf + out_pos, text);
free(text);
out_pos += len;
in_pos += consumed;
- update_style(&ctx, &style, out_pos - utf8_count);
+ if (!update_style(&ctx, &style, out_pos - utf8_count))
+ {
+ goto fail;
+ }
}
// Return to default style at end of line, flushes any pending
// style changes
hb_ssa_style_init(&style);
- update_style(&ctx, &style, out_pos - utf8_count);
+ if (!update_style(&ctx, &style, out_pos - utf8_count))
+ {
+ goto fail;
+ }
// null terminate output string
- output[out_pos] = 0;
+ output.buf[out_pos] = 0;
if (ctx.style_atom_count > 0)
{
*stylesize = 10 + (ctx.style_atom_count * 12);
- memcpy(style_atoms + 4, "styl", 4);
+ memcpy(ctx.style_atoms.buf + 4, "styl", 4);
- style_atoms[0] = 0;
- style_atoms[1] = 0;
- style_atoms[2] = (*stylesize >> 8) & 0xff;
- style_atoms[3] = *stylesize & 0xff;
- style_atoms[8] = (ctx.style_atom_count >> 8) & 0xff;
- style_atoms[9] = ctx.style_atom_count & 0xff;
+ ctx.style_atoms.buf[0] = 0;
+ ctx.style_atoms.buf[1] = 0;
+ ctx.style_atoms.buf[2] = (*stylesize >> 8) & 0xff;
+ ctx.style_atoms.buf[3] = *stylesize & 0xff;
+ ctx.style_atoms.buf[8] = (ctx.style_atom_count >> 8) & 0xff;
+ ctx.style_atoms.buf[9] = ctx.style_atom_count & 0xff;
+ *out_style_atoms = ctx.style_atoms.buf;
}
+ *out_buf = output.buf;
+ return;
+
+fail:
+ free(output.buf);
+ free(ctx.style_atoms.buf);
}