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.
152 lines
4.9 KiB
152 lines
4.9 KiB
/*****************************************************************************
|
|
* imageupdater.h : TTML image to SPU updater
|
|
*****************************************************************************
|
|
* Copyright © 2018 Videolabs, VideoLAN and VLC authors
|
|
*
|
|
* 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, see <http://www.gnu.org/licenses/>.
|
|
*****************************************************************************/
|
|
#include <vlc_subpicture.h>
|
|
|
|
typedef struct ttml_image_updater_region_t ttml_image_updater_region_t;
|
|
|
|
struct ttml_image_updater_region_t
|
|
{
|
|
struct
|
|
{
|
|
float x;
|
|
float y;
|
|
} origin, extent;
|
|
int i_flags;
|
|
picture_t *p_pic;
|
|
ttml_image_updater_region_t *p_next;
|
|
};
|
|
|
|
enum ttml_image_updater_region_flags_e
|
|
{
|
|
ORIGIN_X_IS_RATIO = 1 << 0,
|
|
ORIGIN_Y_IS_RATIO = 1 << 1,
|
|
EXTENT_X_IS_RATIO = 1 << 2,
|
|
EXTENT_Y_IS_RATIO = 1 << 3,
|
|
};
|
|
|
|
static void TTML_ImageUpdaterRegionDelete(ttml_image_updater_region_t *p_updtregion)
|
|
{
|
|
if (p_updtregion->p_pic)
|
|
picture_Release(p_updtregion->p_pic);
|
|
free(p_updtregion);
|
|
}
|
|
|
|
static ttml_image_updater_region_t *TTML_ImageUpdaterRegionNew(picture_t *p_pic)
|
|
{
|
|
ttml_image_updater_region_t *p_region = calloc(1, sizeof(*p_region));
|
|
if(p_region)
|
|
p_region->p_pic = p_pic;
|
|
return p_region;
|
|
}
|
|
|
|
/*
|
|
* UPDATER
|
|
*/
|
|
|
|
typedef struct
|
|
{
|
|
ttml_image_updater_region_t *p_regions;
|
|
ttml_image_updater_region_t **pp_append;
|
|
|
|
} ttml_image_updater_sys_t;
|
|
|
|
static void TTML_ImageSpuAppendRegion(ttml_image_updater_sys_t *p_sys,
|
|
ttml_image_updater_region_t *p_new)
|
|
{
|
|
*p_sys->pp_append = p_new;
|
|
p_sys->pp_append = &p_new->p_next;
|
|
}
|
|
|
|
static int TTML_ImageSpuValidate(subpicture_t *p_spu,
|
|
bool b_src_changed, const video_format_t *p_fmt_src,
|
|
bool b_dst_changed, const video_format_t *p_fmt_dst,
|
|
vlc_tick_t ts)
|
|
{
|
|
VLC_UNUSED(p_spu);
|
|
VLC_UNUSED(b_src_changed); VLC_UNUSED(p_fmt_src);
|
|
VLC_UNUSED(p_fmt_dst);
|
|
VLC_UNUSED(ts);
|
|
return b_dst_changed ? VLC_EGENERIC: VLC_SUCCESS;
|
|
}
|
|
|
|
static void TTML_ImageSpuUpdate(subpicture_t *p_spu,
|
|
const video_format_t *p_fmt_src,
|
|
const video_format_t *p_fmt_dst,
|
|
vlc_tick_t i_ts)
|
|
{
|
|
VLC_UNUSED(p_fmt_src);
|
|
VLC_UNUSED(i_ts);
|
|
ttml_image_updater_sys_t *p_sys = p_spu->updater.p_sys;
|
|
|
|
/* !WARN: SMPTE-TT image profile requires no scaling, and even it
|
|
would, it does not store the necessary original pic size */
|
|
|
|
for(ttml_image_updater_region_t *p_updtregion = p_sys->p_regions;
|
|
p_updtregion; p_updtregion = p_updtregion->p_next)
|
|
{
|
|
subpicture_region_t *r = subpicture_region_ForPicture(&p_updtregion->p_pic->format, p_updtregion->p_pic);
|
|
if (unlikely(r == NULL))
|
|
return;
|
|
|
|
r->i_align = SUBPICTURE_ALIGN_LEFT|SUBPICTURE_ALIGN_TOP;
|
|
|
|
if( p_updtregion->i_flags & ORIGIN_X_IS_RATIO )
|
|
r->i_x = p_updtregion->origin.x * p_fmt_dst->i_visible_width;
|
|
else
|
|
r->i_x = p_updtregion->origin.x;
|
|
|
|
if( p_updtregion->i_flags & ORIGIN_Y_IS_RATIO )
|
|
r->i_y = p_updtregion->origin.y * p_fmt_dst->i_visible_height;
|
|
else
|
|
r->i_y = p_updtregion->origin.y;
|
|
|
|
vlc_spu_regions_push(&p_spu->regions, r);
|
|
}
|
|
}
|
|
|
|
static void TTML_ImageSpuDestroy(subpicture_t *p_spu)
|
|
{
|
|
ttml_image_updater_sys_t *p_sys = p_spu->updater.p_sys;
|
|
while(p_sys->p_regions)
|
|
{
|
|
ttml_image_updater_region_t *p_next = p_sys->p_regions->p_next;
|
|
TTML_ImageUpdaterRegionDelete(p_sys->p_regions);
|
|
p_sys->p_regions = p_next;
|
|
}
|
|
free(p_sys);
|
|
}
|
|
|
|
static inline subpicture_t *decoder_NewTTML_ImageSpu(decoder_t *p_dec)
|
|
{
|
|
ttml_image_updater_sys_t *p_sys = calloc(1, sizeof(*p_sys));
|
|
if(!p_sys)
|
|
return NULL;
|
|
subpicture_updater_t updater = {
|
|
.pf_validate = TTML_ImageSpuValidate,
|
|
.pf_update = TTML_ImageSpuUpdate,
|
|
.pf_destroy = TTML_ImageSpuDestroy,
|
|
.p_sys = p_sys,
|
|
};
|
|
p_sys->p_regions = NULL;
|
|
p_sys->pp_append = &p_sys->p_regions;
|
|
subpicture_t *p_spu = decoder_NewSubpicture(p_dec, &updater);
|
|
if (!p_spu)
|
|
free(p_sys);
|
|
return p_spu;
|
|
}
|
|
|