You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
535 lines
19 KiB
535 lines
19 KiB
/*****************************************************************************
|
|
* ARIB STD-B24 caption decoder/renderer using libaribcaption.
|
|
*****************************************************************************
|
|
* Copyright (C) 2022 magicxqq
|
|
*
|
|
* Authors: magicxqq <xqq@xqq.im>
|
|
*
|
|
* This program 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.
|
|
*
|
|
* This program 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 this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* Preamble
|
|
*****************************************************************************/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <limits.h>
|
|
|
|
#include <vlc_common.h>
|
|
#include <vlc_plugin.h>
|
|
#include <vlc_atomic.h>
|
|
#include <vlc_codec.h>
|
|
|
|
#include <aribcaption/aribcaption.h>
|
|
|
|
|
|
/*****************************************************************************
|
|
* Local prototypes
|
|
*****************************************************************************/
|
|
typedef struct
|
|
{
|
|
/* The following fields of decoder_sys_t are shared between decoder and spu units */
|
|
vlc_atomic_rc_t rc;
|
|
|
|
bool b_cfg_fadeout;
|
|
|
|
aribcc_context_t *p_context;
|
|
aribcc_decoder_t *p_decoder;
|
|
aribcc_renderer_t *p_renderer;
|
|
|
|
vlc_mutex_t dec_lock; // protect p_dec pointer
|
|
decoder_t* p_dec; // pointer to decoder_t for logcat callback, NULL if decoder closed
|
|
} decoder_sys_t;
|
|
|
|
typedef struct
|
|
{
|
|
decoder_sys_t *p_dec_sys;
|
|
vlc_tick_t i_pts;
|
|
aribcc_render_result_t render_result;
|
|
} libaribcaption_spu_updater_sys_t;
|
|
|
|
|
|
static void DecSysRetain(decoder_sys_t *p_sys)
|
|
{
|
|
vlc_atomic_rc_inc(&p_sys->rc);
|
|
}
|
|
|
|
static void DecSysRelease(decoder_sys_t *p_sys)
|
|
{
|
|
if (!vlc_atomic_rc_dec(&p_sys->rc))
|
|
return;
|
|
|
|
if (p_sys->p_renderer)
|
|
aribcc_renderer_free(p_sys->p_renderer);
|
|
if (p_sys->p_decoder)
|
|
aribcc_decoder_free(p_sys->p_decoder);
|
|
if (p_sys->p_context)
|
|
aribcc_context_free(p_sys->p_context);
|
|
|
|
free(p_sys);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
****************************************************************************/
|
|
static void CopyImageToRegion(picture_t *dst_pic, const aribcc_image_t *image)
|
|
{
|
|
if(image->pixel_format != ARIBCC_PIXELFORMAT_RGBA8888)
|
|
return;
|
|
|
|
plane_t *p_dstplane = &dst_pic->p[0];
|
|
plane_t srcplane;
|
|
srcplane.i_lines = image->height;
|
|
srcplane.i_pitch = image->stride;
|
|
srcplane.i_pixel_pitch = p_dstplane->i_pixel_pitch;
|
|
srcplane.i_visible_lines = image->height;
|
|
srcplane.i_visible_pitch = image->width /* in pixels */ * p_dstplane->i_pixel_pitch;
|
|
srcplane.p_pixels = image->bitmap;
|
|
plane_CopyPixels( p_dstplane, &srcplane );
|
|
}
|
|
|
|
static void SubpictureUpdate(subpicture_t *p_subpic,
|
|
const struct vlc_spu_updater_configuration *cfg)
|
|
{
|
|
libaribcaption_spu_updater_sys_t *p_spusys = p_subpic->updater.sys;
|
|
decoder_sys_t *p_sys = p_spusys->p_dec_sys;
|
|
const video_format_t *p_src_format = cfg->video_src;
|
|
const video_format_t *p_dst_format = cfg->video_dst;
|
|
|
|
bool b_src_changed = p_src_format->i_visible_width != cfg->prev_src->i_visible_width ||
|
|
p_src_format->i_visible_height != cfg->prev_src->i_visible_height;
|
|
bool b_dst_changed = !video_format_IsSimilar(cfg->prev_dst, p_dst_format);
|
|
|
|
unsigned i_render_area_width = p_dst_format->i_visible_width;
|
|
unsigned i_render_area_height = p_src_format->i_visible_height * p_dst_format->i_visible_width /
|
|
p_src_format->i_visible_width;
|
|
if (b_src_changed || b_dst_changed) {
|
|
/* don't let library freely scale using either the min of width or height ratio */
|
|
aribcc_renderer_set_frame_size(p_sys->p_renderer, i_render_area_width,
|
|
i_render_area_height);
|
|
}
|
|
|
|
const vlc_tick_t i_stream_date = p_spusys->i_pts + (cfg->pts - p_subpic->i_start);
|
|
|
|
/* Retrieve the expected render status for detecting whether the subtitle image changed */
|
|
aribcc_render_status_t status = aribcc_renderer_try_render(p_sys->p_renderer,
|
|
MS_FROM_VLC_TICK(i_stream_date));
|
|
if (status == ARIBCC_RENDER_STATUS_GOT_IMAGE_UNCHANGED) {
|
|
/* Skip rendering since images were not changed */
|
|
if (!b_src_changed && !b_dst_changed) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
status = aribcc_renderer_render(p_sys->p_renderer,
|
|
MS_FROM_VLC_TICK(i_stream_date),
|
|
&p_spusys->render_result);
|
|
if (status == ARIBCC_RENDER_STATUS_ERROR) {
|
|
return;
|
|
}
|
|
|
|
vlc_spu_regions_Clear( &p_subpic->regions );
|
|
|
|
aribcc_image_t *p_images = p_spusys->render_result.images;
|
|
uint32_t i_image_count = p_spusys->render_result.image_count;
|
|
|
|
if (!p_images || i_image_count == 0) {
|
|
return;
|
|
}
|
|
|
|
p_subpic->i_original_picture_width = i_render_area_width;
|
|
p_subpic->i_original_picture_height = i_render_area_height;
|
|
|
|
video_format_t fmt_region = *p_dst_format;
|
|
fmt_region.i_chroma = VLC_CODEC_RGBA;
|
|
fmt_region.i_x_offset = 0;
|
|
fmt_region.i_y_offset = 0;
|
|
fmt_region.transfer = TRANSFER_FUNC_SRGB;
|
|
fmt_region.primaries = COLOR_PRIMARIES_SRGB;
|
|
fmt_region.space = COLOR_SPACE_SRGB;
|
|
fmt_region.color_range = COLOR_RANGE_FULL;
|
|
|
|
/* Allocate the regions and draw them */
|
|
for (uint32_t i = 0; i < i_image_count; i++) {
|
|
aribcc_image_t *image = &p_images[i];
|
|
|
|
fmt_region.i_width =
|
|
fmt_region.i_visible_width = image->width;
|
|
fmt_region.i_height =
|
|
fmt_region.i_visible_height = image->height;
|
|
fmt_region.i_sar_num = 1;
|
|
fmt_region.i_sar_den = 1;
|
|
|
|
subpicture_region_t *region = subpicture_region_New(&fmt_region);
|
|
if (!region)
|
|
break;
|
|
|
|
region->b_absolute = true; region->b_in_window = false;
|
|
region->i_x = image->dst_x;
|
|
region->i_y = image->dst_y;
|
|
region->i_align = SUBPICTURE_ALIGN_TOP | SUBPICTURE_ALIGN_LEFT;
|
|
|
|
CopyImageToRegion(region->p_picture, image);
|
|
|
|
vlc_spu_regions_push(&p_subpic->regions, region);
|
|
}
|
|
|
|
aribcc_render_result_cleanup(&p_spusys->render_result);
|
|
}
|
|
|
|
static void SubpictureDestroy(subpicture_t *p_subpic)
|
|
{
|
|
libaribcaption_spu_updater_sys_t *p_spusys = p_subpic->updater.sys;
|
|
DecSysRelease(p_spusys->p_dec_sys);
|
|
free(p_spusys);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Decode:
|
|
****************************************************************************/
|
|
static int Decode(decoder_t *p_dec, block_t *p_block)
|
|
{
|
|
decoder_sys_t *p_sys = p_dec->p_sys;
|
|
|
|
if (p_block == NULL) /* No Drain */
|
|
return VLCDEC_SUCCESS;
|
|
|
|
if (p_block->i_flags & BLOCK_FLAG_CORRUPTED) {
|
|
block_Release(p_block);
|
|
return VLCDEC_SUCCESS;
|
|
}
|
|
|
|
aribcc_caption_t caption;
|
|
aribcc_decode_status_t status = aribcc_decoder_decode(p_sys->p_decoder,
|
|
p_block->p_buffer,
|
|
p_block->i_buffer,
|
|
MS_FROM_VLC_TICK(p_block->i_pts),
|
|
&caption);
|
|
if (status == ARIBCC_DECODE_STATUS_ERROR) {
|
|
msg_Err(p_dec, "aribcc_decoder_decode() returned with error");
|
|
}
|
|
|
|
if (status == ARIBCC_DECODE_STATUS_ERROR || status == ARIBCC_DECODE_STATUS_NO_CAPTION) {
|
|
block_Release(p_block);
|
|
return VLCDEC_SUCCESS;
|
|
}
|
|
|
|
aribcc_renderer_append_caption(p_sys->p_renderer, &caption);
|
|
aribcc_caption_cleanup(&caption);
|
|
|
|
|
|
libaribcaption_spu_updater_sys_t *p_spusys = malloc(sizeof(libaribcaption_spu_updater_sys_t));
|
|
if (!p_spusys) {
|
|
block_Release(p_block);
|
|
return VLCDEC_SUCCESS;
|
|
}
|
|
p_spusys->p_dec_sys = p_sys;
|
|
p_spusys->i_pts = p_block->i_pts;
|
|
memset(&p_spusys->render_result, 0, sizeof(p_spusys->render_result));
|
|
|
|
static const struct vlc_spu_updater_ops spu_ops =
|
|
{
|
|
.update = SubpictureUpdate,
|
|
.destroy = SubpictureDestroy,
|
|
};
|
|
|
|
subpicture_updater_t updater = {
|
|
.sys = p_spusys,
|
|
.ops = &spu_ops,
|
|
};
|
|
|
|
subpicture_t *p_spu = decoder_NewSubpicture(p_dec, &updater);
|
|
if (!p_spu) {
|
|
msg_Warn(p_dec, "can't get spu buffer");
|
|
free(p_spusys);
|
|
block_Release(p_block);
|
|
return VLCDEC_SUCCESS;
|
|
}
|
|
p_spu->i_start = p_block->i_pts;
|
|
p_spu->i_stop = p_block->i_pts;
|
|
p_spu->b_fade = p_sys->b_cfg_fadeout;
|
|
|
|
if (caption.wait_duration == ARIBCC_DURATION_INDEFINITE) {
|
|
p_spu->b_ephemer = true;
|
|
} else {
|
|
p_spu->i_stop = p_block->i_pts + VLC_TICK_FROM_MS(caption.wait_duration);
|
|
}
|
|
|
|
|
|
DecSysRetain(p_sys); /* Keep a reference for the returned subpicture */
|
|
|
|
block_Release(p_block);
|
|
|
|
decoder_QueueSub(p_dec, p_spu);
|
|
|
|
return VLCDEC_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Flush:
|
|
*****************************************************************************/
|
|
static void Flush(decoder_t *p_dec)
|
|
{
|
|
decoder_sys_t *p_sys = p_dec->p_sys;
|
|
aribcc_decoder_flush(p_sys->p_decoder);
|
|
aribcc_renderer_flush(p_sys->p_renderer);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* libaribcaption logcat callback function
|
|
*****************************************************************************/
|
|
static void LogcatCallback(aribcc_loglevel_t level, const char *message, void *userdata)
|
|
{
|
|
decoder_sys_t *p_sys = userdata;
|
|
|
|
if (p_sys->p_dec != NULL) {
|
|
vlc_mutex_lock(&p_sys->dec_lock);
|
|
|
|
if (p_sys->p_dec != NULL) {
|
|
decoder_t* p_dec = p_sys->p_dec;
|
|
|
|
if (level == ARIBCC_LOGLEVEL_ERROR) {
|
|
msg_Err(p_dec, "%s", message);
|
|
} else if (level == ARIBCC_LOGLEVEL_WARNING) {
|
|
msg_Warn(p_dec, "%s", message);
|
|
} else {
|
|
msg_Dbg(p_dec, "%s", message);
|
|
}
|
|
}
|
|
|
|
vlc_mutex_unlock(&p_sys->dec_lock);
|
|
}
|
|
}
|
|
|
|
#define ARIBCAPTION_CFG_PREFIX "aribcaption-"
|
|
|
|
/*****************************************************************************
|
|
* Open: Create libaribcaption context/decoder/renderer.
|
|
*****************************************************************************/
|
|
static int Open(vlc_object_t *p_this)
|
|
{
|
|
decoder_t *p_dec = (decoder_t *)p_this;
|
|
decoder_sys_t *p_sys;
|
|
|
|
if (p_dec->fmt_in->i_codec != VLC_CODEC_ARIB_A &&
|
|
p_dec->fmt_in->i_codec != VLC_CODEC_ARIB_C) {
|
|
return VLC_ENOTSUP;
|
|
}
|
|
|
|
p_sys = malloc(sizeof(decoder_sys_t));
|
|
if (unlikely(p_sys == NULL))
|
|
return VLC_ENOMEM;
|
|
|
|
vlc_atomic_rc_init(&p_sys->rc);
|
|
|
|
p_sys->b_cfg_fadeout = var_InheritBool(p_this, ARIBCAPTION_CFG_PREFIX "fadeout");
|
|
|
|
vlc_mutex_init(&p_sys->dec_lock);
|
|
p_sys->p_dec = p_dec;
|
|
|
|
/* Create libaribcaption context */
|
|
aribcc_context_t *p_ctx = p_sys->p_context = aribcc_context_alloc();
|
|
if (!p_ctx) {
|
|
msg_Err(p_dec, "libaribcaption context allocation failed");
|
|
DecSysRelease(p_sys);
|
|
return VLC_EGENERIC;
|
|
}
|
|
|
|
aribcc_context_set_logcat_callback(p_ctx, LogcatCallback, p_sys);
|
|
|
|
|
|
/* Create the decoder */
|
|
aribcc_decoder_t* p_decoder = p_sys->p_decoder = aribcc_decoder_alloc(p_ctx);
|
|
if (!p_decoder) {
|
|
msg_Err(p_dec, "libaribcaption decoder creation failed");
|
|
DecSysRelease(p_sys);
|
|
return VLC_EGENERIC;
|
|
}
|
|
|
|
aribcc_profile_t i_profile = ARIBCC_PROFILE_A;
|
|
if (p_dec->fmt_in->i_codec == VLC_CODEC_ARIB_C) {
|
|
i_profile = ARIBCC_PROFILE_C;
|
|
}
|
|
|
|
bool b_succ = aribcc_decoder_initialize(p_decoder,
|
|
ARIBCC_ENCODING_SCHEME_AUTO,
|
|
ARIBCC_CAPTIONTYPE_CAPTION,
|
|
i_profile,
|
|
ARIBCC_LANGUAGEID_FIRST);
|
|
if (!b_succ) {
|
|
msg_Err(p_dec, "libaribcaption decoder initialization failed");
|
|
DecSysRelease(p_sys);
|
|
return VLC_EGENERIC;
|
|
}
|
|
|
|
|
|
/* Create the renderer */
|
|
aribcc_renderer_t* p_renderer = p_sys->p_renderer = aribcc_renderer_alloc(p_ctx);
|
|
if (!p_renderer) {
|
|
msg_Err(p_dec, "libaribcaption renderer creation failed");
|
|
DecSysRelease(p_sys);
|
|
return VLC_EGENERIC;
|
|
}
|
|
|
|
int i_cfg_rendering_backend =
|
|
var_InheritInteger(p_this, ARIBCAPTION_CFG_PREFIX "rendering-backend");
|
|
b_succ = aribcc_renderer_initialize(p_renderer,
|
|
ARIBCC_CAPTIONTYPE_CAPTION,
|
|
ARIBCC_FONTPROVIDER_TYPE_AUTO,
|
|
(aribcc_textrenderer_type_t)i_cfg_rendering_backend);
|
|
if (!b_succ) {
|
|
msg_Err(p_dec, "libaribcaption renderer initialization failed");
|
|
DecSysRelease(p_sys);
|
|
return VLC_EGENERIC;
|
|
}
|
|
|
|
aribcc_renderer_set_storage_policy(p_renderer, ARIBCC_CAPTION_STORAGE_POLICY_MINIMUM, 0);
|
|
|
|
bool b_cfg_replace_drcs = var_InheritBool(p_this, ARIBCAPTION_CFG_PREFIX "replace-drcs");
|
|
bool b_cfg_force_stroke_text = var_InheritBool(p_this, ARIBCAPTION_CFG_PREFIX "force-stroke-text");
|
|
bool b_cfg_ignore_background = var_InheritBool(p_this, ARIBCAPTION_CFG_PREFIX "ignore-background");
|
|
bool b_cfg_ignore_ruby = var_InheritBool(p_this, ARIBCAPTION_CFG_PREFIX "ignore-ruby");
|
|
float f_cfg_stroke_width = var_InheritFloat(p_this, ARIBCAPTION_CFG_PREFIX "stroke-width");
|
|
aribcc_renderer_set_replace_drcs(p_renderer, b_cfg_replace_drcs);
|
|
aribcc_renderer_set_force_stroke_text(p_renderer, b_cfg_force_stroke_text);
|
|
aribcc_renderer_set_force_no_background(p_renderer, b_cfg_ignore_background);
|
|
aribcc_renderer_set_force_no_ruby(p_renderer, b_cfg_ignore_ruby);
|
|
aribcc_renderer_set_stroke_width(p_renderer, f_cfg_stroke_width);
|
|
|
|
char *psz_cfg_font_name = var_InheritString(p_this, ARIBCAPTION_CFG_PREFIX "font");
|
|
if (psz_cfg_font_name) {
|
|
const char* font_families[] = { psz_cfg_font_name };
|
|
aribcc_renderer_set_default_font_family(p_renderer,
|
|
font_families,
|
|
ARRAY_SIZE(font_families),
|
|
true);
|
|
free(psz_cfg_font_name);
|
|
}
|
|
|
|
p_dec->p_sys = p_sys;
|
|
p_dec->pf_decode = Decode;
|
|
p_dec->pf_flush = Flush;
|
|
p_dec->fmt_out.i_codec = VLC_CODEC_RGBA;
|
|
|
|
return VLC_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Close: finish
|
|
*****************************************************************************/
|
|
static void Close(vlc_object_t *p_this)
|
|
{
|
|
decoder_t *p_dec = (decoder_t *)p_this;
|
|
decoder_sys_t *p_sys = p_dec->p_sys;
|
|
|
|
vlc_mutex_lock(&p_sys->dec_lock);
|
|
p_sys->p_dec = NULL;
|
|
vlc_mutex_unlock(&p_sys->dec_lock);
|
|
|
|
DecSysRelease(p_sys);
|
|
}
|
|
|
|
|
|
#define CFG_TEXT_RENDERING_BACKEND N_("Text rendering backend")
|
|
#define CFG_LONGTEXT_RENDERING_BACKEND N_("Select text rendering backend")
|
|
|
|
#define CFG_TEXT_FONT N_("Font")
|
|
#define CFG_LONGTEXT_FONT N_("Select font")
|
|
|
|
#define CFG_TEXT_REPLACE_DRCS N_("Replace known DRCS")
|
|
#define CFG_LONGTEXT_REPLACE_DRCS N_("Replace known DRCS in the caption")
|
|
|
|
#define CFG_TEXT_FORCE_STROKE_TEXT N_("Force stroke text")
|
|
#define CFG_LONGTEXT_FORCE_STROKE_TEXT N_("Always render characters with stroke")
|
|
|
|
#define CFG_TEXT_IGNORE_BACKGROUND N_("Ignore background")
|
|
#define CFG_LONGTEXT_IGNORE_BACKGROUND N_("Ignore rendering caption background")
|
|
|
|
#define CFG_TEXT_IGNORE_RUBY N_("Ignore ruby (furigana)")
|
|
#define CFG_LONGTEXT_IGNORE_RUBY N_("Ignore ruby-like characters, like furigana")
|
|
|
|
#define CFG_TEXT_FADEOUT N_("Fadeout")
|
|
#define CFG_LONGTEXT_FADEOUT N_("Enable Fadeout")
|
|
|
|
#define CFG_TEXT_STROKE_WIDTH N_("Stroke width")
|
|
#define CFG_LONGTEXT_STROKE_WIDTH N_("Indicate stroke width for stroke text")
|
|
|
|
|
|
static const int rendering_backend_values[] = {
|
|
ARIBCC_TEXTRENDERER_TYPE_AUTO,
|
|
|
|
#if defined(ARIBCC_USE_CORETEXT)
|
|
ARIBCC_TEXTRENDERER_TYPE_CORETEXT,
|
|
#endif
|
|
|
|
#if defined(ARIBCC_USE_DIRECTWRITE)
|
|
ARIBCC_TEXTRENDERER_TYPE_DIRECTWRITE,
|
|
#endif
|
|
|
|
#if defined(ARIBCC_USE_FREETYPE)
|
|
ARIBCC_TEXTRENDERER_TYPE_FREETYPE
|
|
#endif
|
|
};
|
|
|
|
static const char* const ppsz_rendering_backend_descriptions[] = {
|
|
N_("Auto"),
|
|
|
|
#if defined(ARIBCC_USE_CORETEXT)
|
|
N_("CoreText"),
|
|
#endif
|
|
|
|
#if defined(ARIBCC_USE_DIRECTWRITE)
|
|
N_("DirectWrite"),
|
|
#endif
|
|
|
|
#if defined(ARIBCC_USE_FREETYPE)
|
|
N_("FreeType")
|
|
#endif
|
|
};
|
|
|
|
#ifdef __APPLE__
|
|
# define DEFAULT_FAMILY "Hiragino Maru Gothic ProN"
|
|
#elif defined(_WIN32)
|
|
# define DEFAULT_FAMILY "MS Gothic"
|
|
#else
|
|
# define DEFAULT_FAMILY "sans-serif"
|
|
#endif
|
|
|
|
/*****************************************************************************
|
|
* Module descriptor
|
|
*****************************************************************************/
|
|
vlc_module_begin ()
|
|
set_shortname(N_("ARIB caption"))
|
|
set_description(N_("ARIB caption renderer"))
|
|
set_capability("spu decoder", 60)
|
|
set_subcategory(SUBCAT_INPUT_SCODEC)
|
|
set_callbacks(Open, Close)
|
|
|
|
add_integer(ARIBCAPTION_CFG_PREFIX "rendering-backend", 0, CFG_TEXT_RENDERING_BACKEND, CFG_LONGTEXT_RENDERING_BACKEND)
|
|
change_integer_list(rendering_backend_values, ppsz_rendering_backend_descriptions)
|
|
add_font(ARIBCAPTION_CFG_PREFIX "font", DEFAULT_FAMILY, CFG_TEXT_FONT, CFG_LONGTEXT_FONT)
|
|
add_bool(ARIBCAPTION_CFG_PREFIX "replace-drcs", true, CFG_TEXT_REPLACE_DRCS, CFG_LONGTEXT_REPLACE_DRCS)
|
|
add_bool(ARIBCAPTION_CFG_PREFIX "force-stroke-text", false, CFG_TEXT_FORCE_STROKE_TEXT, CFG_LONGTEXT_FORCE_STROKE_TEXT)
|
|
add_bool(ARIBCAPTION_CFG_PREFIX "ignore-background", false, CFG_TEXT_IGNORE_BACKGROUND, CFG_LONGTEXT_IGNORE_BACKGROUND)
|
|
add_bool(ARIBCAPTION_CFG_PREFIX "ignore-ruby", false, CFG_TEXT_IGNORE_RUBY, CFG_LONGTEXT_IGNORE_RUBY)
|
|
add_bool(ARIBCAPTION_CFG_PREFIX "fadeout", false, CFG_TEXT_FADEOUT, CFG_LONGTEXT_FADEOUT)
|
|
add_float_with_range(ARIBCAPTION_CFG_PREFIX "stroke-width", 1.5f, 0.0f, 3.0f, CFG_TEXT_STROKE_WIDTH, CFG_LONGTEXT_STROKE_WIDTH)
|
|
vlc_module_end ()
|
|
|