Commit 3c4b5275 authored by Marton Balint's avatar Marton Balint

libzvbi-teletextdec: output ass subtitles instead of plain text

Signed-off-by: 's avatarMarton Balint <cus@passwd.hu>
parent b96325e0
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
*/ */
#include "avcodec.h" #include "avcodec.h"
#include "libavcodec/ass.h"
#include "libavutil/opt.h" #include "libavutil/opt.h"
#include "libavutil/bprint.h" #include "libavutil/bprint.h"
#include "libavutil/intreadwrite.h" #include "libavutil/intreadwrite.h"
...@@ -49,7 +50,7 @@ typedef struct TeletextContext ...@@ -49,7 +50,7 @@ typedef struct TeletextContext
char *pgno; char *pgno;
int x_offset; int x_offset;
int y_offset; int y_offset;
int format_id; /* 0 = bitmap, 1 = text */ int format_id; /* 0 = bitmap, 1 = text/ass */
int chop_top; int chop_top;
int sub_duration; /* in msec */ int sub_duration; /* in msec */
int transparent_bg; int transparent_bg;
...@@ -88,10 +89,43 @@ subtitle_rect_free(AVSubtitleRect **sub_rect) ...@@ -88,10 +89,43 @@ subtitle_rect_free(AVSubtitleRect **sub_rect)
{ {
av_freep(&(*sub_rect)->pict.data[0]); av_freep(&(*sub_rect)->pict.data[0]);
av_freep(&(*sub_rect)->pict.data[1]); av_freep(&(*sub_rect)->pict.data[1]);
av_freep(&(*sub_rect)->text); av_freep(&(*sub_rect)->ass);
av_freep(sub_rect); 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});
/* First we escape the plain text into buf. */
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);
}
/* Then we create the ass dialog line in buf2 from the escaped text in buf. */
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 // draw a page as text
static int static int
gen_sub_text(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top) gen_sub_text(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top)
...@@ -147,14 +181,16 @@ gen_sub_text(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int ...@@ -147,14 +181,16 @@ gen_sub_text(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int
if (buf.len) { if (buf.len) {
int ret; int ret;
sub_rect->type = SUBTITLE_TEXT; sub_rect->type = SUBTITLE_ASS;
if ((ret = av_bprint_finalize(&buf, &sub_rect->text)) < 0) if ((ret = create_ass_text(ctx, buf.str, &sub_rect->ass)) < 0) {
av_bprint_finalize(&buf, NULL);
return ret; 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 { } else {
sub_rect->type = SUBTITLE_NONE; sub_rect->type = SUBTITLE_NONE;
av_bprint_finalize(&buf, NULL);
} }
av_bprint_finalize(&buf, NULL);
return 0; return 0;
} }
...@@ -393,7 +429,7 @@ teletext_decode_frame(AVCodecContext *avctx, ...@@ -393,7 +429,7 @@ teletext_decode_frame(AVCodecContext *avctx,
// is there a subtitle to pass? // is there a subtitle to pass?
if (ctx->nb_pages) { if (ctx->nb_pages) {
int i; int i;
sub->format = (ctx->pages->sub_rect->type == SUBTITLE_TEXT ? 1: 0); sub->format = ctx->format_id;
sub->start_display_time = 0; sub->start_display_time = 0;
sub->end_display_time = ctx->sub_duration; sub->end_display_time = ctx->sub_duration;
sub->num_rects = 0; sub->num_rects = 0;
...@@ -445,7 +481,7 @@ static int teletext_init_decoder(AVCodecContext *avctx) ...@@ -445,7 +481,7 @@ static int teletext_init_decoder(AVCodecContext *avctx)
} }
#endif #endif
av_log(avctx, AV_LOG_VERBOSE, "page filter: %s\n", ctx->pgno); 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) static int teletext_close_decoder(AVCodecContext *avctx)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment