Commit d9f72e53 authored by Marton Balint's avatar Marton Balint

avcodec/libzvbi-teletextdec: add support for selecting subtitle pages only

Signed-off-by: 's avatarMarton Balint <cus@passwd.hu>
parent 3a56ade1
...@@ -248,8 +248,9 @@ configuration. You need to explicitly configure the build with ...@@ -248,8 +248,9 @@ configuration. You need to explicitly configure the build with
@table @option @table @option
@item txt_page @item txt_page
List of teletext page numbers to decode. You may use the special * string to List of teletext page numbers to decode. Pages that do not match the specified
match all pages. Pages that do not match the specified list are dropped. list are dropped. You may use the special @code{*} string to match all pages,
or @code{subtitle} to match all subtitle pages.
Default value is *. Default value is *.
@item txt_chop_top @item txt_chop_top
Discards the top teletext line. Default value is 1. Discards the top teletext line. Default value is 1.
......
...@@ -73,6 +73,7 @@ typedef struct TeletextContext ...@@ -73,6 +73,7 @@ typedef struct TeletextContext
vbi_sliced sliced[MAX_SLICES]; vbi_sliced sliced[MAX_SLICES];
int readorder; int readorder;
uint8_t subtitle_map[2048];
} TeletextContext; } TeletextContext;
static int chop_spaces_utf8(const unsigned char* t, int len) static int chop_spaces_utf8(const unsigned char* t, int len)
...@@ -281,16 +282,14 @@ static void handler(vbi_event *ev, void *user_data) ...@@ -281,16 +282,14 @@ static void handler(vbi_event *ev, void *user_data)
vbi_page page; vbi_page page;
int res; int res;
char pgno_str[12]; char pgno_str[12];
vbi_subno subno;
vbi_page_type vpt;
int chop_top; int chop_top;
char *lang; int is_subtitle_page = ctx->subtitle_map[ev->ev.ttx_page.pgno & 0x7ff];
snprintf(pgno_str, sizeof pgno_str, "%03x", ev->ev.ttx_page.pgno); snprintf(pgno_str, sizeof pgno_str, "%03x", ev->ev.ttx_page.pgno);
av_log(ctx, AV_LOG_DEBUG, "decoded page %s.%02x\n", av_log(ctx, AV_LOG_DEBUG, "decoded page %s.%02x\n",
pgno_str, ev->ev.ttx_page.subno & 0xFF); pgno_str, ev->ev.ttx_page.subno & 0xFF);
if (strcmp(ctx->pgno, "*") && !strstr(ctx->pgno, pgno_str)) if (strcmp(ctx->pgno, "*") && (strcmp(ctx->pgno, "subtitle") || !is_subtitle_page) && !strstr(ctx->pgno, pgno_str))
return; return;
if (ctx->handler_ret < 0) if (ctx->handler_ret < 0)
return; return;
...@@ -303,9 +302,7 @@ static void handler(vbi_event *ev, void *user_data) ...@@ -303,9 +302,7 @@ static void handler(vbi_event *ev, void *user_data)
if (!res) if (!res)
return; return;
vpt = vbi_classify_page(ctx->vbi, ev->ev.ttx_page.pgno, &subno, &lang); chop_top = ctx->chop_top || ((page.rows > 1) && is_subtitle_page);
chop_top = ctx->chop_top ||
((page.rows > 1) && (vpt == VBI_SUBTITLE_PAGE));
av_log(ctx, AV_LOG_DEBUG, "%d x %d page chop:%d\n", av_log(ctx, AV_LOG_DEBUG, "%d x %d page chop:%d\n",
page.columns, page.rows, chop_top); page.columns, page.rows, chop_top);
...@@ -357,11 +354,26 @@ static int slice_to_vbi_lines(TeletextContext *ctx, uint8_t* buf, int size) ...@@ -357,11 +354,26 @@ static int slice_to_vbi_lines(TeletextContext *ctx, uint8_t* buf, int size)
else { else {
int line_offset = buf[2] & 0x1f; int line_offset = buf[2] & 0x1f;
int field_parity = buf[2] & 0x20; int field_parity = buf[2] & 0x20;
int i; uint8_t *p = ctx->sliced[lines].data;
int i, pmag;
ctx->sliced[lines].id = VBI_SLICED_TELETEXT_B; ctx->sliced[lines].id = VBI_SLICED_TELETEXT_B;
ctx->sliced[lines].line = (line_offset > 0 ? (line_offset + (field_parity ? 0 : 313)) : 0); ctx->sliced[lines].line = (line_offset > 0 ? (line_offset + (field_parity ? 0 : 313)) : 0);
for (i = 0; i < 42; i++) for (i = 0; i < 42; i++)
ctx->sliced[lines].data[i] = vbi_rev8(buf[4 + i]); p[i] = vbi_rev8(buf[4 + i]);
/* Unfortunately libzvbi does not expose page flags, and
* vbi_classify_page only checks MIP, so we have to manually
* decode the page flags and store the results. */
pmag = vbi_unham16p(p);
if (pmag >= 0 && pmag >> 3 == 0) { // We found a row 0 header
int page = vbi_unham16p(p + 2);
int flags1 = vbi_unham16p(p + 6);
int flags2 = vbi_unham16p(p + 8);
if (page >= 0 && flags1 >= 0 && flags2 >= 0) {
int pgno = ((pmag & 7) << 8) + page;
// Check for disabled NEWSFLASH flag and enabled SUBTITLE and SUPRESS_HEADER flags
ctx->subtitle_map[pgno] = (!(flags1 & 0x40) && flags1 & 0x80 && flags2 & 0x01);
}
}
lines++; lines++;
} }
} }
...@@ -502,6 +514,7 @@ static int teletext_close_decoder(AVCodecContext *avctx) ...@@ -502,6 +514,7 @@ static int teletext_close_decoder(AVCodecContext *avctx)
vbi_decoder_delete(ctx->vbi); vbi_decoder_delete(ctx->vbi);
ctx->vbi = NULL; ctx->vbi = NULL;
ctx->pts = AV_NOPTS_VALUE; ctx->pts = AV_NOPTS_VALUE;
memset(ctx->subtitle_map, 0, sizeof(ctx->subtitle_map));
if (!(avctx->flags2 & AV_CODEC_FLAG2_RO_FLUSH_NOOP)) if (!(avctx->flags2 & AV_CODEC_FLAG2_RO_FLUSH_NOOP))
ctx->readorder = 0; ctx->readorder = 0;
return 0; return 0;
...@@ -515,7 +528,7 @@ static void teletext_flush(AVCodecContext *avctx) ...@@ -515,7 +528,7 @@ static void teletext_flush(AVCodecContext *avctx)
#define OFFSET(x) offsetof(TeletextContext, x) #define OFFSET(x) offsetof(TeletextContext, x)
#define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM #define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = { static const AVOption options[] = {
{"txt_page", "list of teletext page numbers to decode, * is all", OFFSET(pgno), AV_OPT_TYPE_STRING, {.str = "*"}, 0, 0, SD}, {"txt_page", "page numbers to decode, subtitle for subtitles, * for all", OFFSET(pgno), AV_OPT_TYPE_STRING, {.str = "*"}, 0, 0, SD},
{"txt_chop_top", "discards the top teletext line", OFFSET(chop_top), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, SD}, {"txt_chop_top", "discards the top teletext line", OFFSET(chop_top), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, SD},
{"txt_format", "format of the subtitles (bitmap or text)", OFFSET(format_id), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SD, "txt_format"}, {"txt_format", "format of the subtitles (bitmap or text)", OFFSET(format_id), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SD, "txt_format"},
{"bitmap", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, SD, "txt_format"}, {"bitmap", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, SD, "txt_format"},
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#define LIBAVCODEC_VERSION_MAJOR 58 #define LIBAVCODEC_VERSION_MAJOR 58
#define LIBAVCODEC_VERSION_MINOR 20 #define LIBAVCODEC_VERSION_MINOR 20
#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_MICRO 101
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \ LIBAVCODEC_VERSION_MINOR, \
......
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