[FFmpeg-devel] [PATCH 09/11] libzvbi-teletextdec: output ass subtitles instead of plain text

Marton Balint cus at passwd.hu
Thu Oct 31 21:28:55 CET 2013


Signed-off-by: Marton Balint <cus at passwd.hu>
---
 libavcodec/libzvbi-teletextdec.c | 50 +++++++++++++++++++++++++++++++++-------
 1 file changed, 42 insertions(+), 8 deletions(-)

diff --git a/libavcodec/libzvbi-teletextdec.c b/libavcodec/libzvbi-teletextdec.c
index 6180192..4678d5f 100644
--- a/libavcodec/libzvbi-teletextdec.c
+++ b/libavcodec/libzvbi-teletextdec.c
@@ -19,6 +19,7 @@
  */
 
 #include "avcodec.h"
+#include "libavcodec/ass.h"
 #include "libavutil/opt.h"
 #include "libavutil/bprint.h"
 #include "libavutil/intreadwrite.h"
@@ -49,7 +50,7 @@ typedef struct TeletextContext
     char           *pgno;
     int             x_offset;
     int             y_offset;
-    int             format_id; /* 0 = bitmap, 1 = text */
+    int             format_id; /* 0 = bitmap, 1 = text/ass */
     int             chop_top;
     int             sub_duration; /* in msec */
     int             transparent_bg;
@@ -88,10 +89,41 @@ subtitle_rect_free(AVSubtitleRect **sub_rect)
 {
     av_freep(&(*sub_rect)->pict.data[0]);
     av_freep(&(*sub_rect)->pict.data[1]);
-    av_freep(&(*sub_rect)->text);
+    av_freep(&(*sub_rect)->ass);
     av_freep(sub_rect);
 }
 
+static int
+create_ass_text(TeletextContext *ctx, const char *text, char **ass)
+{
+    int ret;
+    AVBPrint buf, buf2;
+    const int ts_start    = av_rescale_q(ctx->pts,          AV_TIME_BASE_Q,        (AVRational){1, 100});
+    const int ts_duration = av_rescale_q(ctx->sub_duration, (AVRational){1, 1000}, (AVRational){1, 100});
+
+    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
+    ff_ass_bprint_text_event(&buf, text, strlen(text), "", 0);
+
+    if (!av_bprint_is_complete(&buf)) {
+        av_bprint_finalize(&buf, NULL);
+        return AVERROR(ENOMEM);
+    }
+
+    av_bprint_init(&buf2, 0, AV_BPRINT_SIZE_UNLIMITED);
+    ff_ass_bprint_dialog(&buf2, buf.str, ts_start, ts_duration, 0);
+    av_bprint_finalize(&buf, NULL);
+
+    if (!av_bprint_is_complete(&buf2)) {
+        av_bprint_finalize(&buf2, NULL);
+        return AVERROR(ENOMEM);
+    }
+
+    if ((ret = av_bprint_finalize(&buf2, ass)) < 0)
+        return ret;
+
+    return 0;
+}
+
 // draw a page as text
 static int
 gen_sub_text(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top)
@@ -147,14 +179,16 @@ gen_sub_text(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int
 
     if (buf.len) {
         int ret;
-        sub_rect->type = SUBTITLE_TEXT;
-        if ((ret = av_bprint_finalize(&buf, &sub_rect->text)) < 0)
+        sub_rect->type = SUBTITLE_ASS;
+        if ((ret = create_ass_text(ctx, buf.str, &sub_rect->ass)) < 0) {
+            av_bprint_finalize(&buf, NULL);
             return ret;
-        av_log(ctx, AV_LOG_DEBUG, "subtext:%s:txetbus\n", sub_rect->text);
+        }
+        av_log(ctx, AV_LOG_DEBUG, "subtext:%s:txetbus\n", sub_rect->ass);
     } else {
         sub_rect->type = SUBTITLE_NONE;
-        av_bprint_finalize(&buf, NULL);
     }
+    av_bprint_finalize(&buf, NULL);
     return 0;
 }
 
@@ -393,7 +427,7 @@ teletext_decode_frame(AVCodecContext *avctx,
     // is there a subtitle to pass?
     if (ctx->nb_pages) {
         int i;
-        sub->format = (ctx->pages->sub_rect->type == SUBTITLE_TEXT ? 1: 0);
+        sub->format = ctx->format_id;
         sub->start_display_time = 0;
         sub->end_display_time = ctx->sub_duration;
         sub->num_rects = 0;
@@ -445,7 +479,7 @@ static int teletext_init_decoder(AVCodecContext *avctx)
     }
 #endif
     av_log(avctx, AV_LOG_VERBOSE, "page filter: %s\n", ctx->pgno);
-    return 0;
+    return (ctx->format_id == 1) ? ff_ass_subtitle_header_default(avctx) : 0;
 }
 
 static int teletext_close_decoder(AVCodecContext *avctx)
-- 
1.8.1.4



More information about the ffmpeg-devel mailing list