From: Ronan Waide <waider@waider.ie>
To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>
Subject: Re: [FFmpeg-devel] [PATCH v5] libavcodec/dvbsubenc.c: add a disable_2bpp option to work around some decoders.
Date: Wed, 25 Jun 2025 20:59:50 +0100
Message-ID: <F77F3C84-94DF-44A2-97C9-5051A95FCECA@waider.ie> (raw)
In-Reply-To: <66719B93-9BE4-4F9F-8270-93B11CBB89B7@waider.ie>
> On 26 May 2025, at 19:41, Ronan Waide <waider@waider.ie> wrote:
>
>>
>> On 14 Apr 2025, at 16:53, softworkz . <softworkz-at-hotmail.com@ffmpeg.org> wrote:
>>
>>
>>
>>> -----Original Message-----
>>> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of
>>> Ronan Waide
>>> Sent: Sonntag, 30. März 2025 12:18
>>> To: FFmpeg development discussions and patches <ffmpeg-
>>> devel@ffmpeg.org>
>>> Subject: Re: [FFmpeg-devel] [PATCH v5] libavcodec/dvbsubenc.c: add a
>>> disable_2bpp option to work around some decoders.
>>>
>>>
>>>
>>>> On 8 Mar 2025, at 08:02, Ronan Waide <waider@waider.ie> wrote:
>>>>
>>>>
>>>>
>>>>> On 2 Mar 2025, at 20:38, Soft Works <softworkz-at-
>>> hotmail.com@ffmpeg.org> wrote:
>>>>>
>>>>>
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of
>>> Ronan
>>>>>> Waide
>>>>>> Sent: Sonntag, 2. März 2025 18:24
>>>>>> To: ffmpeg-devel@ffmpeg.org
>>>>>> Cc: Ronan Waide <waider@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 <waider@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
>>>> waider@waider.ie
>>>>
>>>>
>>>>
>>>>
>>>
>>> Hello again,
>>>
>>> this still applies cleanly to the current HEAD, i.e. no conflicts on
>>> rebase. Would it be possible to merge it, or is there additional work
>>> required?
>>>
>>> cheers,
>>> Waider.
>>> --
>>> Ronan Waide
>>> waider@waider.ie
>>
>>
>> Hello Ronan,
>>
>> I'll try to pick this up next or 2nd-next week. Patch looked good
>> but I want to test it locally before making a last call and applying
>> it - assuming all goes well.
>
> nudge on this. The current patch applies to the current HEAD without changes, so I've not posted a revision.
nudging on this again. Patch continues to apply cleanly, but I can post a rebased version if required.
cheers,
Waider.
--
Ronan Waide
waider@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-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2025-06-25 20:01 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-01 11:43 [FFmpeg-devel] [PATCH] dvbsubenc: " Waider
2025-03-01 11:48 ` Ronan Waide
2025-03-01 12:44 ` Ronan Waide
2025-03-01 12:55 ` Soft Works
2025-03-01 13:52 ` Ronan Waide
2025-03-01 14:10 ` [FFmpeg-devel] [PATCH v3] libavcodec/dvbsubenc.c: " Ronan Waide
2025-03-01 14:29 ` Ronan Waide
2025-03-01 15:00 ` Soft Works
2025-03-01 15:07 ` Ronan Waide
2025-03-01 15:32 ` [FFmpeg-devel] [PATCH v4] " Ronan Waide
2025-03-02 13:13 ` Andreas Rheinhardt
2025-03-02 15:00 ` Soft Works
2025-03-02 17:23 ` [FFmpeg-devel] [PATCH v5] " Ronan Waide
2025-03-02 20:38 ` Soft Works
2025-03-08 8:02 ` Ronan Waide
2025-03-30 10:18 ` Ronan Waide
2025-04-14 15:53 ` softworkz .
2025-05-26 18:41 ` Ronan Waide
2025-06-25 19:59 ` Ronan Waide [this message]
2025-04-21 10:56 ` [FFmpeg-devel] [PATCH v6] avcodec/dvbsubenc: " Ronan Waide
2025-03-02 17:26 ` [FFmpeg-devel] [PATCH v4] libavcodec/dvbsubenc.c: " Ronan Waide
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=F77F3C84-94DF-44A2-97C9-5051A95FCECA@waider.ie \
--to=waider@waider.ie \
--cc=ffmpeg-devel@ffmpeg.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git