Message ID | 20170217214336.99700-1-josh@itanimul.li |
---|---|
State | Rejected |
Headers | show |
On Fri, 17 Feb 2017, Josh de Kock wrote: > Also add support for level 1.0 explicitly. > What is the use case for this? Reducing the number of colors? I don't think you can reduce the number of colors based on teletext level, because libzvbi uses high (>32) colors for navigation, which is also part of level 1.0. Also, I don't think you can skip fix_transparency. And by reducing to level 1.0, you are excluding a lot of users, many countries use the extra international characters level 1.5 provides. If you only want to reduce the number of colors, then I prefer an option which makes the code go through every pixel, find the minimum color value, and sets nb_colors to that. Still a hack, but IMHO small enough to be acceptable, until subtitle filters are implemented, and you can do this with a filter. Regards, Marton > Signed-off-by: Josh de Kock <josh@itanimul.li> > --- > libavcodec/libzvbi-teletextdec.c | 60 ++++++++++++++++++++++++++++------------ > 1 file changed, 42 insertions(+), 18 deletions(-) > > diff --git a/libavcodec/libzvbi-teletextdec.c b/libavcodec/libzvbi-teletextdec.c > index 687b6af..b4316f4 100644 > --- a/libavcodec/libzvbi-teletextdec.c > +++ b/libavcodec/libzvbi-teletextdec.c > @@ -76,6 +76,7 @@ typedef struct TeletextContext > vbi_sliced sliced[MAX_SLICES]; > > int readorder; > + int wst_level; > } TeletextContext; > > static int chop_spaces_utf8(const unsigned char* t, int len) > @@ -248,32 +249,51 @@ static int gen_sub_bitmap(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_pa > sub_rect->data[0], sub_rect->linesize[0], > 0, chop_top, page->columns, page->rows - chop_top, > /*reveal*/ 1, /*flash*/ 1); > - > - fix_transparency(ctx, sub_rect, page, chop_top, resx, resy); > + if (ctx->opacity != -1) > + fix_transparency(ctx, sub_rect, page, chop_top, resx, resy); > sub_rect->x = ctx->x_offset; > sub_rect->y = ctx->y_offset + chop_top * BITMAP_CHAR_HEIGHT; > sub_rect->w = resx; > sub_rect->h = resy; > - sub_rect->nb_colors = ctx->opacity > 0 && ctx->opacity < 255 ? 2 * VBI_NB_COLORS : VBI_NB_COLORS; > + sub_rect->type = SUBTITLE_BITMAP; > + > sub_rect->data[1] = av_mallocz(AVPALETTE_SIZE); > if (!sub_rect->data[1]) { > av_freep(&sub_rect->data[0]); > return AVERROR(ENOMEM); > } > - for (ci = 0; ci < VBI_NB_COLORS; ci++) { > - int r, g, b, a; > - > - r = VBI_R(page->color_map[ci]); > - g = VBI_G(page->color_map[ci]); > - b = VBI_B(page->color_map[ci]); > - a = VBI_A(page->color_map[ci]); > - ((uint32_t *)sub_rect->data[1])[ci] = RGBA(r, g, b, a); > - ((uint32_t *)sub_rect->data[1])[ci + VBI_NB_COLORS] = RGBA(r, g, b, ctx->opacity); > - ff_dlog(ctx, "palette %0x\n", ((uint32_t *)sub_rect->data[1])[ci]); > + > + switch (ctx->wst_level) { > + case VBI_WST_LEVEL_1: > + sub_rect->nb_colors = 16; > + for (ci = 0; ci < VBI_NB_COLORS; ci ++) > + ((uint32_t *)sub_rect->data[1])[ci] = ci < 16 ? RGBA(VBI_R(page->color_map[ci]), VBI_G(page->color_map[ci]), > + VBI_B(page->color_map[ci]), VBI_A(page->color_map[ci])) : > + RGBA(0, 0, 0, 0); > + break; > + case VBI_WST_LEVEL_1p5: > + case VBI_WST_LEVEL_2p5: > + return AVERROR_PATCHWELCOME; > + break; > + case VBI_WST_LEVEL_3p5: > + sub_rect->nb_colors = ctx->opacity > 0 && ctx->opacity < 255 ? 2 * VBI_NB_COLORS : VBI_NB_COLORS; > + for (ci = 0; ci < VBI_NB_COLORS; ci++) { > + int r, g, b, a; > + > + r = VBI_R(page->color_map[ci]); > + g = VBI_G(page->color_map[ci]); > + b = VBI_B(page->color_map[ci]); > + a = VBI_A(page->color_map[ci]); > + ((uint32_t *)sub_rect->data[1])[ci] = RGBA(r, g, b, a); > + ((uint32_t *)sub_rect->data[1])[ci + VBI_NB_COLORS] = RGBA(r, g, b, ctx->opacity); > + av_log(ctx, AV_LOG_DEBUG, "palette %08x pallete opacity %08x\n", > + ((uint32_t *)sub_rect->data[1])[ci], ((uint32_t *)sub_rect->data[1])[ci + VBI_NB_COLORS]); > + } > } > + > ((uint32_t *)sub_rect->data[1])[VBI_TRANSPARENT_BLACK] = RGBA(0, 0, 0, 0); > ((uint32_t *)sub_rect->data[1])[VBI_TRANSPARENT_BLACK + VBI_NB_COLORS] = RGBA(0, 0, 0, 0); > - sub_rect->type = SUBTITLE_BITMAP; > + > return 0; > } > > @@ -301,7 +321,7 @@ static void handler(vbi_event *ev, void *user_data) > res = vbi_fetch_vt_page(ctx->vbi, &page, > ev->ev.ttx_page.pgno, > ev->ev.ttx_page.subno, > - VBI_WST_LEVEL_3p5, 25, TRUE); > + ctx->wst_level, 25, TRUE); > > if (!res) > return; > @@ -549,9 +569,13 @@ static const AVOption options[] = { > {"txt_top", "y offset of generated bitmaps", OFFSET(y_offset), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 65535, SD}, > {"txt_chop_spaces", "chops leading and trailing spaces from text", OFFSET(chop_spaces), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, SD}, > {"txt_duration", "display duration of teletext pages in msecs", OFFSET(sub_duration), AV_OPT_TYPE_INT, {.i64 = 30000}, 0, 86400000, SD}, > - {"txt_transparent", "force transparent background of the teletext", OFFSET(transparent_bg), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SD}, > - {"txt_opacity", "set opacity of the transparent background", OFFSET(opacity), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, SD}, > - { NULL }, > + {"txt_transparent", "force transparent background of the teletext (doesn't work with level 1.0)", OFFSET(transparent_bg), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SD}, > + {"txt_opacity", "set opacity of the transparent background (doesn't work with level 1.0)", OFFSET(opacity), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, SD}, > + {"txt_level", "set the output level of the teletext bitmap", OFFSET(wst_level), AV_OPT_TYPE_INT, {.i64 = VBI_WST_LEVEL_3p5}, VBI_WST_LEVEL_1, VBI_WST_LEVEL_3p5, SD, "txt_level"}, > + {"1.0", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VBI_WST_LEVEL_1}, 0, 0, SD, "txt_level"}, > + {"1.5", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VBI_WST_LEVEL_1p5}, 0, 0, SD, "txt_level"}, > + {"2.5", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VBI_WST_LEVEL_2p5}, 0, 0, SD, "txt_level"}, > + {"3.5", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VBI_WST_LEVEL_3p5}, 0, 0, SD, "txt_level"}, > }; > > static const AVClass teletext_class = { > -- > 2.10.1 (Apple Git-78) > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
On 18/02/2017 00:51, Marton Balint wrote: > > On Fri, 17 Feb 2017, Josh de Kock wrote: > >> Also add support for level 1.0 explicitly. >> > > What is the use case for this? Reducing the number of colors? > Pretty much. > I don't think you can reduce the number of colors based on teletext > level, because libzvbi uses high (>32) colors for navigation, which is > also part of level 1.0. > > Also, I don't think you can skip fix_transparency. > Does level 1.0 support transparency? > And by reducing to level 1.0, you are excluding a lot of users, many > countries use the extra international characters level 1.5 provides. > 1.5 could be done instead. > If you only want to reduce the number of colors, then I prefer an option > which makes the code go through every pixel, find the minimum color > value, and sets nb_colors to that. Still a hack, but IMHO small enough > to be acceptable, until subtitle filters are implemented, and you can do > this with a filter. > Not entirely sure what you mean by this, shouldn't the nb_colors be set based on the CLUT? > > [...] >
On Sat, 18 Feb 2017, Josh de Kock wrote: > On 18/02/2017 00:51, Marton Balint wrote: >> >> On Fri, 17 Feb 2017, Josh de Kock wrote: >> >>> Also add support for level 1.0 explicitly. >>> >> >> What is the use case for this? Reducing the number of colors? >> > > Pretty much. > >> I don't think you can reduce the number of colors based on teletext >> level, because libzvbi uses high (>32) colors for navigation, which is >> also part of level 1.0. >> >> Also, I don't think you can skip fix_transparency. >> > > Does level 1.0 support transparency? Not as a color, but as a feature. See Start Box/End Box. Typical for subtitles. > >> And by reducing to level 1.0, you are excluding a lot of users, many >> countries use the extra international characters level 1.5 provides. >> > > 1.5 could be done instead. > >> If you only want to reduce the number of colors, then I prefer an option >> which makes the code go through every pixel, find the minimum color >> value, and sets nb_colors to that. Still a hack, but IMHO small enough >> to be acceptable, until subtitle filters are implemented, and you can do >> this with a filter. >> > > Not entirely sure what you mean by this, shouldn't the nb_colors be set > based on the CLUT? As long as according to zvbi docs it has internal colors from index 32 to 39 for navigation, it does not matter how many CLUT the page uses. What I am saying is that it's simpler to add a txt_reduce_colors option, and if that is set, find the maximum used color index, and set nb_colors to that + 1. I think the original teletext patch had such a feature, but I removed it, hoping that it can be achieved with a subtitle filter later in the future... Or if you are specifically aiming for 16 colors, then the txt_reduce_colors option can do a modulo 16 for each color index instead of finding the maximum index, which may vary between different pages, and I don't know how the dvb subtitle encoder would behave in that case. Regards, Marton
diff --git a/libavcodec/libzvbi-teletextdec.c b/libavcodec/libzvbi-teletextdec.c index 687b6af..b4316f4 100644 --- a/libavcodec/libzvbi-teletextdec.c +++ b/libavcodec/libzvbi-teletextdec.c @@ -76,6 +76,7 @@ typedef struct TeletextContext vbi_sliced sliced[MAX_SLICES]; int readorder; + int wst_level; } TeletextContext; static int chop_spaces_utf8(const unsigned char* t, int len) @@ -248,32 +249,51 @@ static int gen_sub_bitmap(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_pa sub_rect->data[0], sub_rect->linesize[0], 0, chop_top, page->columns, page->rows - chop_top, /*reveal*/ 1, /*flash*/ 1); - - fix_transparency(ctx, sub_rect, page, chop_top, resx, resy); + if (ctx->opacity != -1) + fix_transparency(ctx, sub_rect, page, chop_top, resx, resy); sub_rect->x = ctx->x_offset; sub_rect->y = ctx->y_offset + chop_top * BITMAP_CHAR_HEIGHT; sub_rect->w = resx; sub_rect->h = resy; - sub_rect->nb_colors = ctx->opacity > 0 && ctx->opacity < 255 ? 2 * VBI_NB_COLORS : VBI_NB_COLORS; + sub_rect->type = SUBTITLE_BITMAP; + sub_rect->data[1] = av_mallocz(AVPALETTE_SIZE); if (!sub_rect->data[1]) { av_freep(&sub_rect->data[0]); return AVERROR(ENOMEM); } - for (ci = 0; ci < VBI_NB_COLORS; ci++) { - int r, g, b, a; - - r = VBI_R(page->color_map[ci]); - g = VBI_G(page->color_map[ci]); - b = VBI_B(page->color_map[ci]); - a = VBI_A(page->color_map[ci]); - ((uint32_t *)sub_rect->data[1])[ci] = RGBA(r, g, b, a); - ((uint32_t *)sub_rect->data[1])[ci + VBI_NB_COLORS] = RGBA(r, g, b, ctx->opacity); - ff_dlog(ctx, "palette %0x\n", ((uint32_t *)sub_rect->data[1])[ci]); + + switch (ctx->wst_level) { + case VBI_WST_LEVEL_1: + sub_rect->nb_colors = 16; + for (ci = 0; ci < VBI_NB_COLORS; ci ++) + ((uint32_t *)sub_rect->data[1])[ci] = ci < 16 ? RGBA(VBI_R(page->color_map[ci]), VBI_G(page->color_map[ci]), + VBI_B(page->color_map[ci]), VBI_A(page->color_map[ci])) : + RGBA(0, 0, 0, 0); + break; + case VBI_WST_LEVEL_1p5: + case VBI_WST_LEVEL_2p5: + return AVERROR_PATCHWELCOME; + break; + case VBI_WST_LEVEL_3p5: + sub_rect->nb_colors = ctx->opacity > 0 && ctx->opacity < 255 ? 2 * VBI_NB_COLORS : VBI_NB_COLORS; + for (ci = 0; ci < VBI_NB_COLORS; ci++) { + int r, g, b, a; + + r = VBI_R(page->color_map[ci]); + g = VBI_G(page->color_map[ci]); + b = VBI_B(page->color_map[ci]); + a = VBI_A(page->color_map[ci]); + ((uint32_t *)sub_rect->data[1])[ci] = RGBA(r, g, b, a); + ((uint32_t *)sub_rect->data[1])[ci + VBI_NB_COLORS] = RGBA(r, g, b, ctx->opacity); + av_log(ctx, AV_LOG_DEBUG, "palette %08x pallete opacity %08x\n", + ((uint32_t *)sub_rect->data[1])[ci], ((uint32_t *)sub_rect->data[1])[ci + VBI_NB_COLORS]); + } } + ((uint32_t *)sub_rect->data[1])[VBI_TRANSPARENT_BLACK] = RGBA(0, 0, 0, 0); ((uint32_t *)sub_rect->data[1])[VBI_TRANSPARENT_BLACK + VBI_NB_COLORS] = RGBA(0, 0, 0, 0); - sub_rect->type = SUBTITLE_BITMAP; + return 0; } @@ -301,7 +321,7 @@ static void handler(vbi_event *ev, void *user_data) res = vbi_fetch_vt_page(ctx->vbi, &page, ev->ev.ttx_page.pgno, ev->ev.ttx_page.subno, - VBI_WST_LEVEL_3p5, 25, TRUE); + ctx->wst_level, 25, TRUE); if (!res) return; @@ -549,9 +569,13 @@ static const AVOption options[] = { {"txt_top", "y offset of generated bitmaps", OFFSET(y_offset), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 65535, SD}, {"txt_chop_spaces", "chops leading and trailing spaces from text", OFFSET(chop_spaces), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, SD}, {"txt_duration", "display duration of teletext pages in msecs", OFFSET(sub_duration), AV_OPT_TYPE_INT, {.i64 = 30000}, 0, 86400000, SD}, - {"txt_transparent", "force transparent background of the teletext", OFFSET(transparent_bg), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SD}, - {"txt_opacity", "set opacity of the transparent background", OFFSET(opacity), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, SD}, - { NULL }, + {"txt_transparent", "force transparent background of the teletext (doesn't work with level 1.0)", OFFSET(transparent_bg), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SD}, + {"txt_opacity", "set opacity of the transparent background (doesn't work with level 1.0)", OFFSET(opacity), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, SD}, + {"txt_level", "set the output level of the teletext bitmap", OFFSET(wst_level), AV_OPT_TYPE_INT, {.i64 = VBI_WST_LEVEL_3p5}, VBI_WST_LEVEL_1, VBI_WST_LEVEL_3p5, SD, "txt_level"}, + {"1.0", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VBI_WST_LEVEL_1}, 0, 0, SD, "txt_level"}, + {"1.5", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VBI_WST_LEVEL_1p5}, 0, 0, SD, "txt_level"}, + {"2.5", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VBI_WST_LEVEL_2p5}, 0, 0, SD, "txt_level"}, + {"3.5", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VBI_WST_LEVEL_3p5}, 0, 0, SD, "txt_level"}, }; static const AVClass teletext_class = {
Also add support for level 1.0 explicitly. Signed-off-by: Josh de Kock <josh@itanimul.li> --- libavcodec/libzvbi-teletextdec.c | 60 ++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 18 deletions(-)