From 2e7a684e7214a9245532472f5d13e71f4f0de30f Mon Sep 17 00:00:00 2001 From: Niklesh Date: Thu, 6 Aug 2015 09:11:12 +0530 Subject: movtextdec.c: Add support for font names Signed-off-by: Niklesh --- libavcodec/movtextdec.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 108 insertions(+), 3 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c index 869358cb91..15dd43490a 100644 --- a/libavcodec/movtextdec.c +++ b/libavcodec/movtextdec.c @@ -31,15 +31,23 @@ #define STYLE_FLAG_ITALIC (1<<1) #define STYLE_FLAG_UNDERLINE (1<<2) +#define BOX_SIZE_INITIAL 40 + #define STYL_BOX (1<<0) #define HLIT_BOX (1<<1) #define HCLR_BOX (1<<2) +typedef struct { + uint16_t fontID; + char *font; +} FontRecord; + typedef struct { uint16_t style_start; uint16_t style_end; uint8_t style_flag; uint8_t fontsize; + uint16_t style_fontID; } StyleBox; typedef struct { @@ -56,11 +64,13 @@ typedef struct { StyleBox *s_temp; HighlightBox h; HilightcolorBox c; + FontRecord **ftab; + FontRecord *ftab_temp; uint8_t box_flags; - uint16_t style_entries; + uint16_t style_entries, ftab_entries; uint64_t tracksize; int size_var; - int count_s; + int count_s, count_f; } MovTextContext; typedef struct { @@ -80,6 +90,85 @@ static void mov_text_cleanup(MovTextContext *m) } } +static void mov_text_cleanup_ftab(MovTextContext *m) +{ + int i; + for(i = 0; i < m->count_f; i++) { + av_freep(&m->ftab[i]->font); + av_freep(&m->ftab[i]); + } + av_freep(&m->ftab); +} + +static int mov_text_tx3g(AVCodecContext *avctx, MovTextContext *m) +{ + char *tx3g_ptr = avctx->extradata; + int i, box_size, font_length; + + m->ftab_entries = 0; + box_size = BOX_SIZE_INITIAL; /* Size till ftab_entries */ + if (avctx->extradata_size < box_size) + return -1; + + // Display Flags + tx3g_ptr += 4; + // Alignment + tx3g_ptr += 2; + // Background Color + tx3g_ptr += 4; + // BoxRecord + tx3g_ptr += 8; + // StyleRecord + tx3g_ptr += 12; + // FontRecord + // FontRecord Size + tx3g_ptr += 4; + // ftab + tx3g_ptr += 4; + + m->ftab_entries = AV_RB16(tx3g_ptr); + tx3g_ptr += 2; + + for (i = 0; i < m->ftab_entries; i++) { + + box_size += 3; + if (avctx->extradata_size < box_size) { + mov_text_cleanup_ftab(m); + m->ftab_entries = 0; + return -1; + } + m->ftab_temp = av_malloc(sizeof(*m->ftab_temp)); + if (!m->ftab_temp) { + mov_text_cleanup_ftab(m); + return AVERROR(ENOMEM); + } + m->ftab_temp->fontID = AV_RB16(tx3g_ptr); + tx3g_ptr += 2; + font_length = *tx3g_ptr++; + + box_size = box_size + font_length; + if (avctx->extradata_size < box_size) { + mov_text_cleanup_ftab(m); + m->ftab_entries = 0; + return -1; + } + m->ftab_temp->font = av_malloc(font_length + 1); + if (!m->ftab_temp->font) { + mov_text_cleanup_ftab(m); + return AVERROR(ENOMEM); + } + memcpy(m->ftab_temp->font, tx3g_ptr, font_length); + m->ftab_temp->font[font_length] = '\0'; + av_dynarray_add(&m->ftab, &m->count_f, m->ftab_temp); + if (!m->ftab) { + mov_text_cleanup_ftab(m); + return AVERROR(ENOMEM); + } + tx3g_ptr = tx3g_ptr + font_length; + } + return 0; +} + static int decode_hlit(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt) { m->box_flags |= HLIT_BOX; @@ -118,7 +207,7 @@ static int decode_styl(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt) tsmb += 2; m->s_temp->style_end = AV_RB16(tsmb); tsmb += 2; - // fontID = AV_RB16(tsmb); + m->s_temp->style_fontID = AV_RB16(tsmb); tsmb += 2; m->s_temp->style_flag = AV_RB8(tsmb); tsmb++; @@ -147,6 +236,7 @@ static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end, MovTextContext *m) { int i = 0; + int j = 0; int text_pos = 0; while (text < text_end) { if (m->box_flags & STYL_BOX) { @@ -164,6 +254,10 @@ static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end, if (m->s[i]->style_flag & STYLE_FLAG_UNDERLINE) av_bprintf(buf, "{\\u1}"); av_bprintf(buf, "{\\fs%d}", m->s[i]->fontsize); + for (j = 0; j < m->ftab_entries; j++) { + if (m->s[i]->style_fontID == m->ftab[j]->fontID) + av_bprintf(buf, "{\\fn%s}", m->ftab[j]->font); + } } } } @@ -215,6 +309,8 @@ static int mov_text_init(AVCodecContext *avctx) { * it's very common to find files where the default style is broken * and respecting it results in a worse experience than ignoring it. */ + MovTextContext *m = avctx->priv_data; + mov_text_tx3g(avctx, m); return ff_ass_subtitle_header_default(avctx); } @@ -265,6 +361,7 @@ static int mov_text_decode_frame(AVCodecContext *avctx, m->style_entries = 0; m->box_flags = 0; m->count_s = 0; + m->count_f = 0; // Note that the spec recommends lines be no longer than 2048 characters. av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); if (text_length + 2 != avpkt->size) { @@ -313,6 +410,13 @@ static int mov_text_decode_frame(AVCodecContext *avctx, return avpkt->size; } +static int mov_text_decode_close(AVCodecContext *avctx) +{ + MovTextContext *m = avctx->priv_data; + mov_text_cleanup_ftab(m); + return 0; +} + AVCodec ff_movtext_decoder = { .name = "mov_text", .long_name = NULL_IF_CONFIG_SMALL("3GPP Timed Text subtitle"), @@ -321,4 +425,5 @@ AVCodec ff_movtext_decoder = { .priv_data_size = sizeof(MovTextContext), .init = mov_text_init, .decode = mov_text_decode_frame, + .close = mov_text_decode_close, }; -- cgit v1.2.3