> On 2 Mar 2025, at 20:38, Soft Works <softworkz-at-hotmail....@ffmpeg.org> > wrote: > > > >> -----Original Message----- >> From: ffmpeg-devel <ffmpeg-devel-boun...@ffmpeg.org> On Behalf Of Ronan >> Waide >> Sent: Sonntag, 2. März 2025 18:24 >> To: ffmpeg-devel@ffmpeg.org >> Cc: Ronan Waide <wai...@waider.ie> >> Subject: [FFmpeg-devel] [PATCH v5] libavcodec/dvbsubenc.c: add a >> disable_2bpp option to work around some decoders. >> >> As noted in the code in several places, some DVB subtitle decoders >> don't handle 2bpp color. This patch adds a disable_2bpp option which >> disables the 2bpp format; subtitles which would use 2bpp will be bumped >> up to 4bpp. Per suggestion from sw, disable_2pp defaults to true. >> >> Signed-off-by: Ronan Waide <wai...@waider.ie> >> --- >> doc/encoders.texi | 27 +++++++++++++++++ >> libavcodec/dvbsubenc.c | 69 +++++++++++++++++++++++++++++++----------- >> 2 files changed, 78 insertions(+), 18 deletions(-) >> >> diff --git a/doc/encoders.texi b/doc/encoders.texi >> index f3fcc1aa60..6ee0065c7d 100644 >> --- a/doc/encoders.texi >> +++ b/doc/encoders.texi >> @@ -4484,6 +4484,33 @@ Reduces detail but attempts to preserve color at >> extremely low bitrates. >> @chapter Subtitles Encoders >> @c man begin SUBTITLES ENCODERS >> >> +@section dvbsub >> + >> +This codec encodes the bitmap subtitle format that is used in DVB >> +broadcasts and recordings. The bitmaps are typically embedded in a >> +container such as MPEG-TS as a separate stream. >> + >> +@subsection Options >> + >> +@table @option >> +@item disable_2bpp @var{boolean} >> +Disable the 2 bits-per-pixel encoding format. >> + >> +DVB supports 2, 4, and 8 bits-per-pixel color lookup tables. However, >> +not all players support or properly support 2 bits-per-pixel, >> +resulting in unusable subtitles. >> +@table @option >> +@item 0 >> +The 2 bits-per-pixel encoding format will be used for subtitles with 4 >> +colors or less. >> + >> +@item 1 >> +The 2 bits-per-pixel encoding format will be disabled, and subtitles >> +with 4 colors or less will use a 4 bits-per-pixel format. (default) >> +@end table >> + >> +@end table >> + >> @section dvdsub >> >> This codec encodes the bitmap subtitle format that is used in DVDs. >> diff --git a/libavcodec/dvbsubenc.c b/libavcodec/dvbsubenc.c >> index 822e3a5309..4db2e1ddda 100644 >> --- a/libavcodec/dvbsubenc.c >> +++ b/libavcodec/dvbsubenc.c >> @@ -22,9 +22,12 @@ >> #include "bytestream.h" >> #include "codec_internal.h" >> #include "libavutil/colorspace.h" >> +#include "libavutil/opt.h" >> >> typedef struct DVBSubtitleContext { >> + AVClass * class; >> int object_version; >> + int disable_2bpp; >> } DVBSubtitleContext; >> >> #define PUTBITS2(val)\ >> @@ -274,13 +277,15 @@ static int dvbsub_encode(AVCodecContext *avctx, >> uint8_t *outbuf, int buf_size, >> { >> DVBSubtitleContext *s = avctx->priv_data; >> uint8_t *q, *pseg_len; >> - int page_id, region_id, clut_id, object_id, i, bpp_index, >> page_state; >> + int page_id, region_id, clut_id, object_id, i, bpp_index, >> page_state, min_colors; >> >> >> q = outbuf; >> >> page_id = 1; >> >> + min_colors = s->disable_2bpp ? 16 : 0; >> + >> if (h->num_rects && !h->rects) >> return AVERROR(EINVAL); >> >> @@ -326,18 +331,20 @@ static int dvbsub_encode(AVCodecContext *avctx, >> uint8_t *outbuf, int buf_size, >> >> if (h->num_rects) { >> for (clut_id = 0; clut_id < h->num_rects; clut_id++) { >> - if (buf_size < 6 + h->rects[clut_id]->nb_colors * 6) >> + int nb_colors = FFMAX(min_colors, h->rects[clut_id]- >>> nb_colors); >> + >> + if (buf_size < 6 + nb_colors * 6) >> return AVERROR_BUFFER_TOO_SMALL; >> >> /* CLUT segment */ >> >> - if (h->rects[clut_id]->nb_colors <= 4) { >> + if (nb_colors <= 4) { >> /* 2 bpp, some decoders do not support it correctly */ >> bpp_index = 0; >> - } else if (h->rects[clut_id]->nb_colors <= 16) { >> + } else if (nb_colors <= 16) { >> /* 4 bpp, standard encoding */ >> bpp_index = 1; >> - } else if (h->rects[clut_id]->nb_colors <= 256) { >> + } else if (nb_colors <= 256) { >> /* 8 bpp, standard encoding */ >> bpp_index = 2; >> } else { >> @@ -354,16 +361,24 @@ static int dvbsub_encode(AVCodecContext *avctx, >> uint8_t *outbuf, int buf_size, >> *q++ = clut_id; >> *q++ = (0 << 4) | 0xf; /* version = 0 */ >> >> - for(i = 0; i < h->rects[clut_id]->nb_colors; i++) { >> + for(i = 0; i < nb_colors; i++) { >> *q++ = i; /* clut_entry_id */ >> *q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 >> bits/pixel full range */ >> { >> int a, r, g, b; >> - uint32_t x= ((uint32_t*)h->rects[clut_id]- >>> data[1])[i]; >> - a = (x >> 24) & 0xff; >> - r = (x >> 16) & 0xff; >> - g = (x >> 8) & 0xff; >> - b = (x >> 0) & 0xff; >> + if (i < h->rects[clut_id]->nb_colors) { >> + uint32_t x= ((uint32_t*)h->rects[clut_id]- >>> data[1])[i]; >> + a = (x >> 24) & 0xff; >> + r = (x >> 16) & 0xff; >> + g = (x >> 8) & 0xff; >> + b = (x >> 0) & 0xff; >> + } else { >> + /* pad out the CLUT */ >> + a = 0; >> + r = 0; >> + g = 0; >> + b = 0; >> + } >> >> *q++ = RGB_TO_Y_CCIR(r, g, b); >> *q++ = RGB_TO_V_CCIR(r, g, b, 0); >> @@ -373,7 +388,7 @@ static int dvbsub_encode(AVCodecContext *avctx, >> uint8_t *outbuf, int buf_size, >> } >> >> bytestream_put_be16(&pseg_len, q - pseg_len - 2); >> - buf_size -= 6 + h->rects[clut_id]->nb_colors * 6; >> + buf_size -= 6 + nb_colors * 6; >> } >> >> if (buf_size < h->num_rects * 22) >> @@ -381,14 +396,15 @@ static int dvbsub_encode(AVCodecContext *avctx, >> uint8_t *outbuf, int buf_size, >> for (region_id = 0; region_id < h->num_rects; region_id++) { >> >> /* region composition segment */ >> + int nb_colors = FFMAX(min_colors, h->rects[region_id]- >>> nb_colors); >> >> - if (h->rects[region_id]->nb_colors <= 4) { >> + if (nb_colors <= 4) { >> /* 2 bpp, some decoders do not support it correctly */ >> bpp_index = 0; >> - } else if (h->rects[region_id]->nb_colors <= 16) { >> + } else if (nb_colors <= 16) { >> /* 4 bpp, standard encoding */ >> bpp_index = 1; >> - } else if (h->rects[region_id]->nb_colors <= 256) { >> + } else if (nb_colors <= 256) { >> /* 8 bpp, standard encoding */ >> bpp_index = 2; >> } else { >> @@ -424,17 +440,19 @@ static int dvbsub_encode(AVCodecContext *avctx, >> uint8_t *outbuf, int buf_size, >> const uint8_t *bitmap, int linesize, >> int w, int h); >> >> + int nb_colors = FFMAX(min_colors, h->rects[object_id]- >>> nb_colors); >> + >> if (buf_size < 13) >> return AVERROR_BUFFER_TOO_SMALL; >> >> /* bpp_index maths */ >> - if (h->rects[object_id]->nb_colors <= 4) { >> + if (nb_colors <= 4) { >> /* 2 bpp, some decoders do not support it correctly */ >> dvb_encode_rle = dvb_encode_rle2; >> - } else if (h->rects[object_id]->nb_colors <= 16) { >> + } else if (nb_colors <= 16) { >> /* 4 bpp, standard encoding */ >> dvb_encode_rle = dvb_encode_rle4; >> - } else if (h->rects[object_id]->nb_colors <= 256) { >> + } else if (nb_colors <= 256) { >> /* 8 bpp, standard encoding */ >> dvb_encode_rle = dvb_encode_rle8; >> } else { >> @@ -506,6 +524,20 @@ static int dvbsub_encode(AVCodecContext *avctx, >> uint8_t *outbuf, int buf_size, >> return q - outbuf; >> } >> >> +#define OFFSET(x) offsetof(DVBSubtitleContext, x) >> +#define SE AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM >> +static const AVOption options[] = { >> + {"disable_2bpp", "disable the 2bpp subtitle encoder", >> OFFSET(disable_2bpp), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, SE}, >> + { NULL }, >> +}; >> + >> +static const AVClass dvbsubenc_class = { >> + .class_name = "DVBSUB subtitle encoder", >> + .item_name = av_default_item_name, >> + .option = options, >> + .version = LIBAVUTIL_VERSION_INT, >> +}; >> + >> const FFCodec ff_dvbsub_encoder = { >> .p.name = "dvbsub", >> CODEC_LONG_NAME("DVB subtitles"), >> @@ -513,4 +545,5 @@ const FFCodec ff_dvbsub_encoder = { >> .p.id = AV_CODEC_ID_DVB_SUBTITLE, >> .priv_data_size = sizeof(DVBSubtitleContext), >> FF_CODEC_ENCODE_SUB_CB(dvbsub_encode), >> + .p.priv_class = &dvbsubenc_class, >> }; >> -- > > Tested & LGTM > > Thanks for the patch!
Hello, nudging on this - does it need any more work, or will it be merged? Cheers, Waider. -- Ronan Waide wai...@waider.ie _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".