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.
 
 
 
 
 
 

164 lines
5.2 KiB

/*****************************************************************************
* substtml.c : TTML subtitles decoder
*****************************************************************************
* Copyright (C) 2015 VLC authors and VideoLAN
*
* Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
* Sushma Reddy <sushma.reddy@research.iiit.ac.in>
*
* 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.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_modules.h>
#include <vlc_codec.h>
#include "substext.h"
#define ALIGN_TEXT N_("Subtitle justification")
#define ALIGN_LONGTEXT N_("Set the justification of subtitles")
/*****************************************************************************
* Module descriptor.
*****************************************************************************/
static int OpenDecoder ( vlc_object_t * );
static void CloseDecoder ( vlc_object_t * );
vlc_module_begin ()
set_capability( "decoder", 10 )
set_shortname( N_("TTML decoder"))
set_description( N_("TTML subtitles decoder") )
set_callbacks( OpenDecoder, CloseDecoder )
set_category( CAT_INPUT )
set_subcategory( SUBCAT_INPUT_SCODEC )
add_integer( "ttml-align", 0, ALIGN_TEXT, ALIGN_LONGTEXT, false )
vlc_module_end ();
/*****************************************************************************
* Local prototypes
*****************************************************************************/
struct decoder_sys_t
{
int i_align;
};
static subpicture_t *ParseText( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
subpicture_t *p_spu = NULL;
char *psz_subtitle = NULL;
/* We cannot display a subpicture with no date */
if( p_block->i_pts <= VLC_TS_INVALID )
{
msg_Warn( p_dec, "subtitle without a date" );
return NULL;
}
/* Check validity of packet data */
/* An "empty" line containing only \0 can be used to force
and ephemer picture from the screen */
if( p_block->i_buffer < 1 )
{
msg_Warn( p_dec, "no subtitle data" );
return NULL;
}
psz_subtitle = malloc( p_block->i_buffer );
if ( unlikely( psz_subtitle == NULL ) )
return NULL;
memcpy( psz_subtitle, p_block->p_buffer, p_block->i_buffer );
/* Create the subpicture unit */
p_spu = decoder_NewSubpictureText( p_dec );
if( !p_spu )
{
free( psz_subtitle );
return NULL;
}
p_spu->i_start = p_block->i_pts;
p_spu->i_stop = p_block->i_pts + p_block->i_length;
p_spu->b_ephemer = (p_block->i_length == 0);
p_spu->b_absolute = false;
subpicture_updater_sys_t *p_spu_sys = p_spu->updater.p_sys;
p_spu_sys->align = SUBPICTURE_ALIGN_BOTTOM | p_sys->i_align;
p_spu_sys->text = psz_subtitle;
return p_spu;
}
/****************************************************************************
* DecodeBlock: the whole thing
****************************************************************************/
static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
if( !pp_block || *pp_block == NULL )
return NULL;
block_t* p_block = *pp_block;
subpicture_t *p_spu = ParseText( p_dec, p_block );
block_Release( p_block );
*pp_block = NULL;
return p_spu;
}
/*****************************************************************************
* OpenDecoder: probe the decoder and return score
*****************************************************************************/
static int OpenDecoder( 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_TTML )
{
return VLC_EGENERIC;
}
/* Allocate the memory needed to store the decoder's structure */
p_dec->p_sys = p_sys = calloc( 1, sizeof( *p_sys ) );
if( unlikely( p_sys == NULL ) )
{
return VLC_ENOMEM;
}
p_dec->pf_decode_sub = DecodeBlock;
p_dec->fmt_out.i_cat = SPU_ES;
p_sys->i_align = var_InheritInteger( p_dec, "ttml-align" );
return VLC_SUCCESS;
}
/*****************************************************************************
* CloseDecoder: clean up the decoder
*****************************************************************************/
static void CloseDecoder( vlc_object_t *p_this )
{
/* Cleanup here */
decoder_t *p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
free( p_sys );
}