From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id DD5B54804B for ; Fri, 9 Feb 2024 07:25:21 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7958E68D09F; Fri, 9 Feb 2024 09:25:06 +0200 (EET) Received: from mail-yb1-f227.google.com (mail-yb1-f227.google.com [209.85.219.227]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 653F768D09F for ; Fri, 9 Feb 2024 09:24:59 +0200 (EET) Received: by mail-yb1-f227.google.com with SMTP id 3f1490d57ef6-dc7510bcf22so257329276.1 for ; Thu, 08 Feb 2024 23:24:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proxyid.net; s=google; t=1707463498; x=1708068298; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=cpyVBYF5PIF9xAreWoTYlD2pTHTUQhCJlwVQ3NwmlfI=; b=LjK4GViWiLn18skXCKRQgGT92YZfyCsVNJLXRBGmQE1jOUffc6Gy0lZqKNQqhQJEen FM9VkmSu0bt3MZgOIOjcj1YdPDLonU7fk501yxpulX/ljlmq55SV8zMYfIuoGPA1ZF26 yQMHlQiNOH8OlC106EGfzlikoIj2eRmdCjwVG24XUb2tnbD+4JUadvfzihfc1tW78EsV 16PnSOrrOm1mRgJ0mKjzNt9ndJz2Td4eztB9v9vxpbHrrp1FAyQMEmTIzgJ/wuXZqeXd An0ZU8hshPF16ip9L0HYxMyvXZLABorXLUX6c3IjZUel7Uv51tsiJxtQEmqFsSPSYWd/ wcBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707463498; x=1708068298; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cpyVBYF5PIF9xAreWoTYlD2pTHTUQhCJlwVQ3NwmlfI=; b=Qp2b9n5F/irrKaXyIRLDrX+KX01c4lcHxpM93gZGAv9pwuCvDRGideKpN+NSFPzlpq JunDrM1Hp8acmpAcvuySMGOtT1cCZKVVqT3RywvDJkOmfWDxzmqN5CH2D4xxSZW7V0oH 6Lu0HmTKdGWVNc7o2ZUxss/CeS0goXbnwcBOM7TWSN8lPd2X83PwakhqNlmzp2mdCZAC vvNHFWcgT08tQE6eglGxtOL7UWcmNhCvCEUAePlMKlP7YGSJled5fA0UtfedaM+fkYL4 0uY49t/8mfsVz/AbRRbG4lvIvP7HIlgUn01iJ+qFxP7VN5wGxiAmRkWtAgLCAjIagmuW /ycw== X-Gm-Message-State: AOJu0YzjfCMBAXwXdzBMr94T3IXw13k3VEHw9lDzcVkW32J/r3ET3btK j5SaOUoRiyh1eDUmXmEaxBYZtfTtTctypoEYbx6hWt68yBpl8k70DirR/lqJfQJs9M3w1bxQKSi ONHijVnvlceIvmxplzgjlaoeuBAF5t2algO64YOQk X-Google-Smtp-Source: AGHT+IFc7M7q9ghiz+RwY+X8+HgjozVUlX6nZAoFSX2tNdkdhkfQcAVJ1Farjf6xsbRv0PpsGJDI/F+le0oK X-Received: by 2002:a05:6902:1ac4:b0:dc7:4806:4fb with SMTP id db4-20020a0569021ac400b00dc7480604fbmr736083ybb.8.1707463497900; Thu, 08 Feb 2024 23:24:57 -0800 (PST) Received: from wsx-cc1-001.. (c-76-141-249-38.hsd1.il.comcast.net. [76.141.249.38]) by smtp-relay.gmail.com with ESMTPS id h187-20020a253ac4000000b00dc6a61186b0sm26328yba.20.2024.02.08.23.24.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 08 Feb 2024 23:24:57 -0800 (PST) X-Relaying-Domain: proxyid.net From: Marth64 To: ffmpeg-devel@ffmpeg.org Date: Fri, 9 Feb 2024 01:24:46 -0600 Message-Id: <20240209072446.1513009-2-marth64@proxyid.net> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240209072446.1513009-1-marth64@proxyid.net> References: <20240209072446.1513009-1-marth64@proxyid.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v10 2/2] libavformat/dvdvideo: add DVD CLUT utilities and subtitle palette support X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Marth64 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: DVD subtitle palettes, which are natively YUV, are currently carried as a hex string in their respective subtitle streams and have no concept of colorspace tagging. In fact, the convention is to convert them to RGB prior to storage. Common players will only render the palettes properly if they are stored as RGB. Even ffmpeg itself expects this, and already does -in libavformat- the YUV-RGB conversions, specifically in mov.c and movenc.c. The point of this patch is to provide a consolidation of the code that deals with creating the extradata as well as the RGB conversion. That can then (1) enable usable palette support for DVD demuxer if it is merged and (2) start the process of consolidating the related conversions in MOV muxer/demuxer and eventually find a way to properly tag the colorspace. Signed-off-by: Marth64 --- doc/demuxers.texi | 5 ++ libavformat/Makefile | 2 +- libavformat/dvdclut.c | 103 ++++++++++++++++++++++++++++++++++++++ libavformat/dvdclut.h | 37 ++++++++++++++ libavformat/dvdvideodec.c | 14 ++++++ 5 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 libavformat/dvdclut.c create mode 100644 libavformat/dvdclut.h diff --git a/doc/demuxers.texi b/doc/demuxers.texi index 062ea2ea42..d3c7675631 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -391,6 +391,11 @@ often with junk data intended for controlling a real DVD player's buffering speed and with no other material data value. Default is 1, true. +@item clut_rgb @var{bool} +Output subtitle palettes (CLUTs) as RGB, required for Matroska. +Disable to output the palette in its original YUV colorspace. +Default is 1, true. + @end table @subsection Examples diff --git a/libavformat/Makefile b/libavformat/Makefile index df69734877..8f17e43e49 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -192,7 +192,7 @@ OBJS-$(CONFIG_DTS_MUXER) += rawenc.o OBJS-$(CONFIG_DV_MUXER) += dvenc.o OBJS-$(CONFIG_DVBSUB_DEMUXER) += dvbsub.o rawdec.o OBJS-$(CONFIG_DVBTXT_DEMUXER) += dvbtxt.o rawdec.o -OBJS-$(CONFIG_DVDVIDEO_DEMUXER) += dvdvideodec.o +OBJS-$(CONFIG_DVDVIDEO_DEMUXER) += dvdvideodec.o dvdclut.o OBJS-$(CONFIG_DXA_DEMUXER) += dxa.o OBJS-$(CONFIG_EA_CDATA_DEMUXER) += eacdata.o OBJS-$(CONFIG_EA_DEMUXER) += electronicarts.o diff --git a/libavformat/dvdclut.c b/libavformat/dvdclut.c new file mode 100644 index 0000000000..91da5ad4e9 --- /dev/null +++ b/libavformat/dvdclut.c @@ -0,0 +1,103 @@ +/* + * DVD-Video subpicture CLUT (Color Lookup Table) utilities + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/bprint.h" +#include "libavutil/colorspace.h" + +#include "dvdclut.h" +#include "internal.h" + +/* crop table for YUV to RGB subpicture palette conversion */ +#define DVDCLUT_YUV_NEG_CROP_MAX 1024 +#define times4(x) x, x, x, x +#define times1024(x) times4(times4(times4(times4(times4(x))))) + +static const uint8_t dvdclut_yuv_crop_tab[256 + 2 * DVDCLUT_YUV_NEG_CROP_MAX] = { +times1024(0x00), +0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, +0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, +0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, +0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, +0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, +0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F, +0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F, +0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F, +0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, +0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, +0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, +0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, +0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, +0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, +0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, +0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, +times1024(0xFF) +}; + +int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, + const size_t clut_size, + AVCodecParameters *par) +{ + int ret = 0; + AVBPrint bp; + + if (clut_size != FF_DVDCLUT_CLUT_SIZE) + return AVERROR(EINVAL); + + av_bprint_init(&bp, 0, FF_DVDCLUT_EXTRADATA_SIZE); + + av_bprintf(&bp, "palette: "); + + for (int i = 0; i < FF_DVDCLUT_CLUT_LEN; i++) + av_bprintf(&bp, "%06"PRIx32"%s", clut[i], + i != (FF_DVDCLUT_CLUT_LEN - 1) ? ", " : ""); + + av_bprintf(&bp, "\n"); + + ret = ff_bprint_to_codecpar_extradata(par, &bp); + + av_bprint_finalize(&bp, NULL); + + return ret; +} + +int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size) +{ + const uint8_t *cm = dvdclut_yuv_crop_tab + DVDCLUT_YUV_NEG_CROP_MAX; + + int y, cb, cr; + uint8_t r, g, b; + int r_add, g_add, b_add; + + if (clut_size != FF_DVDCLUT_CLUT_SIZE) + return AVERROR(EINVAL); + + for (int i = 0; i < FF_DVDCLUT_CLUT_LEN; i++) { + y = (clut[i] >> 16) & 0xFF; + cr = (clut[i] >> 8) & 0xFF; + cb = clut[i] & 0xFF; + + YUV_TO_RGB1_CCIR(cb, cr); + YUV_TO_RGB2_CCIR(r, g, b, y); + + clut[i] = (r << 16) | (g << 8) | b; + } + + return 0; +} diff --git a/libavformat/dvdclut.h b/libavformat/dvdclut.h new file mode 100644 index 0000000000..41cea7e2c9 --- /dev/null +++ b/libavformat/dvdclut.h @@ -0,0 +1,37 @@ +/* + * DVD-Video subpicture CLUT (Color Lookup Table) utilities + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFORMAT_DVDCLUT_H +#define AVFORMAT_DVDCLUT_H + +#include "libavcodec/codec_par.h" + +/* ("palette: ") + ("rrggbb, "*15) + ("rrggbb") + \n + \0 */ +#define FF_DVDCLUT_EXTRADATA_SIZE (9 + (8 * 15) + 6 + 1 + 1) +#define FF_DVDCLUT_CLUT_LEN 16 +#define FF_DVDCLUT_CLUT_SIZE FF_DVDCLUT_CLUT_LEN * sizeof(uint32_t) + +int ff_dvdclut_palette_extradata_cat(const uint32_t *clut, + const size_t clut_size, + AVCodecParameters *par); + +int ff_dvdclut_yuv_to_rgb(uint32_t *clut, const size_t clut_size); + +#endif /* AVFORMAT_DVDCLUT_H */ diff --git a/libavformat/dvdvideodec.c b/libavformat/dvdvideodec.c index c8628609c9..a2eba0c05d 100644 --- a/libavformat/dvdvideodec.c +++ b/libavformat/dvdvideodec.c @@ -50,6 +50,7 @@ #include "avio_internal.h" #include "avlanguage.h" #include "demux.h" +#include "dvdclut.h" #include "internal.h" #include "url.h" @@ -96,6 +97,7 @@ typedef struct DVDVideoPGCSubtitleStreamEntry { int startcode; enum DVDVideoSubpictureViewport viewport; int disposition; + uint32_t clut[FF_DVDCLUT_CLUT_LEN]; const char *lang_iso; } DVDVideoPGCSubtitleStreamEntry; @@ -129,6 +131,7 @@ typedef struct DVDVideoDemuxContext { int opt_angle; /* the user-provided angle number (1-indexed) */ int opt_chapter_end; /* the user-provided exit PTT (0 for last) */ int opt_chapter_start; /* the user-provided entry PTT (1-indexed) */ + int opt_clut_rgb; /* output subtitle palette (CLUT) as RGB */ int opt_pg; /* the user-provided PG number (1-indexed) */ int opt_pgc; /* the user-provided PGC number (1-indexed) */ int opt_preindex; /* pre-indexing mode (2-pass read) */ @@ -1041,6 +1044,8 @@ break_error: static int dvdvideo_subp_stream_analyze(AVFormatContext *s, uint32_t offset, subp_attr_t subp_attr, DVDVideoPGCSubtitleStreamEntry *entry) { + DVDVideoDemuxContext *c = s->priv_data; + char lang_dvd[3] = {0}; entry->startcode = 0x20 + (offset & 0x1F); @@ -1048,6 +1053,11 @@ static int dvdvideo_subp_stream_analyze(AVFormatContext *s, uint32_t offset, sub if (subp_attr.lang_extension == 9) entry->disposition |= AV_DISPOSITION_FORCED; + memcpy(&entry->clut, c->play_state.pgc->palette, FF_DVDCLUT_CLUT_SIZE); + + if (c->opt_clut_rgb) + ff_dvdclut_yuv_to_rgb(entry->clut, FF_DVDCLUT_CLUT_SIZE); + AV_WB16(lang_dvd, subp_attr.lang_code); entry->lang_iso = ff_convert_lang_to(lang_dvd, AV_LANG_ISO639_2_BIBL); @@ -1069,6 +1079,9 @@ static int dvdvideo_subp_stream_add(AVFormatContext *s, DVDVideoPGCSubtitleStrea st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codecpar->codec_id = AV_CODEC_ID_DVD_SUBTITLE; + if ((ret = ff_dvdclut_palette_extradata_cat(entry->clut, FF_DVDCLUT_CLUT_SIZE, st->codecpar)) < 0) + return ret; + if (entry->lang_iso) av_dict_set(&st->metadata, "language", entry->lang_iso, 0); @@ -1390,6 +1403,7 @@ static const AVOption dvdvideo_options[] = { {"angle", "playback angle number", OFFSET(opt_angle), AV_OPT_TYPE_INT, { .i64=1 }, 1, 9, AV_OPT_FLAG_DECODING_PARAM }, {"chapter_end", "exit chapter (PTT) number (0=end)", OFFSET(opt_chapter_end), AV_OPT_TYPE_INT, { .i64=0 }, 0, 99, AV_OPT_FLAG_DECODING_PARAM }, {"chapter_start", "entry chapter (PTT) number", OFFSET(opt_chapter_start), AV_OPT_TYPE_INT, { .i64=1 }, 1, 99, AV_OPT_FLAG_DECODING_PARAM }, + {"clut_rgb", "output subtitle palette (CLUT) as RGB", OFFSET(opt_clut_rgb), AV_OPT_TYPE_BOOL, { .i64=1 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM }, {"pg", "entry PG number (0=auto)", OFFSET(opt_pg), AV_OPT_TYPE_INT, { .i64=0 }, 0, 255, AV_OPT_FLAG_DECODING_PARAM }, {"pgc", "entry PGC number (0=auto)", OFFSET(opt_pgc), AV_OPT_TYPE_INT, { .i64=0 }, 0, 999, AV_OPT_FLAG_DECODING_PARAM }, {"preindex", "enable for accurate chapter markers, slow (2-pass read)", OFFSET(opt_preindex), AV_OPT_TYPE_BOOL, { .i64=0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM }, -- 2.34.1 _______________________________________________ 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".