[FFmpeg-devel] [PATCH 2/2] Encoding of styles - Bold, Italic, Underlined for timed-text subttiles
Dewangan, Hitesh Kumar
hitesh.dewangan at pearson.com
Thu Jun 11 07:23:11 CEST 2015
Hi All,
Please unsubscribe me from this list.
Thanks,
HItesh
On Thu, Jun 11, 2015 at 10:18 AM, Niklesh Lalwani <
niklesh.lalwani at iitb.ac.in> wrote:
> From: Niklesh <niklesh.lalwani at iitb.ac.in>
>
> Encoding of bold, Italic, underlined styles for 3gpp timed text subtitles.
> All the formatting information is appended into the buffer after the text,
> unlike other encoders like srt, which can write out styling information as
> it goes. Another tricky part is to take care of the Endianness properly
> while writing into the buffer.
>
> Signed-off-by: Niklesh <niklesh.lalwani at iitb.ac.in>
> ---
> libavcodec/movtextenc.c | 104
> +++++++++++++++++++++++++++++++++++-------------
> 1 file changed, 76 insertions(+), 28 deletions(-)
>
> diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c
> index 1b8f454..adbe19d 100644
> --- a/libavcodec/movtextenc.c
> +++ b/libavcodec/movtextenc.c
> @@ -24,14 +24,27 @@
> #include "libavutil/avassert.h"
> #include "libavutil/avstring.h"
> #include "libavutil/intreadwrite.h"
> +#include "libavutil/common.h"
> #include "ass_split.h"
> #include "ass.h"
>
> +#define STYLE_FLAG_BOLD 1
> +#define STYLE_FLAG_ITALIC 2
> +#define STYLE_FLAG_UNDERLINE 4
> +
> typedef struct {
> ASSSplitContext *ass_ctx;
> - char buffer[2048];
> - char *ptr;
> - char *end;
> + AVBPrint buffer;
> + uint32_t tsmb_size;
> + uint32_t tsmb_type;
> + uint16_t style_entries;
> + uint16_t style_start;
> + uint16_t style_end;
> + uint16_t style_fontID;
> + uint8_t style_flag;
> + uint8_t style_fontsize;
> + uint32_t style_color;
> + uint16_t text_pos;
> } MovTextContext;
>
>
> @@ -47,10 +60,10 @@ static av_cold int mov_text_encode_init(AVCodecContext
> *avctx)
> 0xFF, // int8_t vertical-justification
> 0x00, 0x00, 0x00, 0x00, // uint8_t background-color-rgba[4]
> // BoxRecord {
> - 0x00, 0x00, // int16_t top
> - 0x00, 0x00, // int16_t left
> - 0x00, 0x00, // int16_t bottom
> - 0x00, 0x00, // int16_t right
> + 0x00, 0x01, // int16_t top
> + 0x00, 0x01, // int16_t left
> + 0x00, 0x1E, // int16_t bottom
> + 0x00, 0xC8, // int16_t right
> // };
> // StyleRecord {
> 0x00, 0x00, // uint16_t startChar
> @@ -79,32 +92,54 @@ static av_cold int mov_text_encode_init(AVCodecContext
> *avctx)
> if (!avctx->extradata)
> return AVERROR(ENOMEM);
>
> + av_bprint_init(&s->buffer, 0, AV_BPRINT_SIZE_UNLIMITED);
> +
> memcpy(avctx->extradata, text_sample_entry, avctx->extradata_size);
>
> s->ass_ctx = ff_ass_split(avctx->subtitle_header);
> return s->ass_ctx ? 0 : AVERROR_INVALIDDATA;
> }
>
> +static void mov_text_style_cb(void *priv, const char style, int close)
> +{
> + MovTextContext *s = priv;
> + s->tsmb_type = MKTAG('s','t','y','l');
> + if (!close) {
> + s->style_start = AV_RB16(&s->text_pos);
> + switch (style){
> + case 'b':
> + s->style_flag += STYLE_FLAG_BOLD;
> + break;
> + case 'i':
> + s->style_flag += STYLE_FLAG_ITALIC;
> + break;
> + case 'u':
> + s->style_flag += STYLE_FLAG_UNDERLINE;
> + break;
> + }
> + } else {
> + s->style_end = AV_RB16(&s->text_pos);
> + }
> +}
> +
> static void mov_text_text_cb(void *priv, const char *text, int len)
> {
> MovTextContext *s = priv;
> - av_assert0(s->end >= s->ptr);
> - av_strlcpy(s->ptr, text, FFMIN(s->end - s->ptr, len + 1));
> - s->ptr += FFMIN(s->end - s->ptr, len);
> + av_bprint_append_data(&s->buffer, text, len);
> + s->text_pos += len;
> }
>
> static void mov_text_new_line_cb(void *priv, int forced)
> {
> MovTextContext *s = priv;
> - av_assert0(s->end >= s->ptr);
> - av_strlcpy(s->ptr, "\n", FFMIN(s->end - s->ptr, 2));
> - if (s->end > s->ptr)
> - s->ptr++;
> + av_bprint_append_data(&s->buffer, "\n", 2);
> + s->text_pos += 2;
> }
>
> static const ASSCodesCallbacks mov_text_callbacks = {
> .text = mov_text_text_cb,
> .new_line = mov_text_new_line_cb,
> + .style = mov_text_style_cb,
> };
>
> static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char
> *buf,
> @@ -112,10 +147,9 @@ static int mov_text_encode_frame(AVCodecContext
> *avctx, unsigned char *buf,
> {
> MovTextContext *s = avctx->priv_data;
> ASSDialog *dialog;
> - int i, len, num;
> + int i, num;
>
> - s->ptr = s->buffer;
> - s->end = s->ptr + sizeof(s->buffer);
> + av_bprint_clear(&s->buffer);
>
> for (i = 0; i < sub->num_rects; i++) {
>
> @@ -123,33 +157,47 @@ static int mov_text_encode_frame(AVCodecContext
> *avctx, unsigned char *buf,
> av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type
> supported.\n");
> return AVERROR(ENOSYS);
> }
> + s->text_pos = 0;
>
> dialog = ff_ass_split_dialog(s->ass_ctx, sub->rects[i]->ass, 0,
> &num);
> for (; dialog && num--; dialog++) {
> ff_ass_split_override_codes(&mov_text_callbacks, s,
> dialog->text);
> }
> + if (s->tsmb_type == MKTAG('s','t','y','l') && s->style_end) {
> + s->tsmb_size = MKTAG(0x00, 0x00, 0x00, 0x16);
> + s->style_entries = 0x00 | 0x01<<8;
> + s->style_fontID = 0x00 | 0x01<<8;
> + s->style_fontsize = 0x12;
> + s->style_color = MKTAG(0xFF, 0xFF, 0xFF, 0xFF);
> + av_bprint_append_data(&s->buffer, &s->tsmb_size, 4);
> + av_bprint_append_data(&s->buffer, &s->tsmb_type, 4);
> + av_bprint_append_data(&s->buffer, &s->style_entries, 2);
> + av_bprint_append_data(&s->buffer, &s->style_start, 2);
> + av_bprint_append_data(&s->buffer, &s->style_end, 2);
> + av_bprint_append_data(&s->buffer, &s->style_fontID, 2);
> + av_bprint_append_data(&s->buffer, &s->style_flag, 1);
> + av_bprint_append_data(&s->buffer, &s->style_fontsize, 1);
> + av_bprint_append_data(&s->buffer, &s->style_color, 4);
> + }
> }
>
> - if (s->ptr == s->buffer)
> - return 0;
> -
> - AV_WB16(buf, strlen(s->buffer));
> + AV_WB16(buf, s->text_pos);
> buf += 2;
>
> - len = av_strlcpy(buf, s->buffer, bufsize - 2);
> -
> - if (len > bufsize-3) {
> - av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n");
> - return AVERROR(EINVAL);
> - }
> + if (!av_bprint_is_complete(&s->buffer))
> + return AVERROR(ENOMEM);
> + if (!s->buffer.len)
> + return 0;
>
> - return len + 2;
> + memcpy(buf, s->buffer.str, s->buffer.len);
> + return s->buffer.len + 2;
> }
>
> static int mov_text_encode_close(AVCodecContext *avctx)
> {
> MovTextContext *s = avctx->priv_data;
> ff_ass_split_free(s->ass_ctx);
> + av_bprint_finalize(&s->buffer, NULL);
> return 0;
> }
>
> --
> 1.9.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
More information about the ffmpeg-devel
mailing list