📄 subtitle_asa.c
字号:
/***************************************************************************** * subtitle_asa.c: Demux for subtitle text files using the asa engine. ***************************************************************************** * Copyright (C) 1999-2007 the VideoLAN team * $Id$ * * Authors: David Lamparter <equinox at videolan dot org> * * Originated from subtitle.c * * Authors: Laurent Aimar <fenrir@via.ecp.fr> * Derk-Jan Hartman <hartman at videolan dot org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 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 General Public License for more details. * * You should have received a copy of the GNU 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 *****************************************************************************/#include "config.h"#include <vlc_common.h>#include <vlc_plugin.h>#include <vlc_input.h>#include <errno.h>#ifdef HAVE_SYS_TYPES_H# include <sys/types.h>#endif#include <ctype.h>#include <vlc_demux.h>#include <vlc_charset.h>#include "asademux.h"/***************************************************************************** * Module descriptor *****************************************************************************/static int Open ( vlc_object_t *p_this );static void Close( vlc_object_t *p_this );#define SUB_DELAY_LONGTEXT \ N_("Apply a delay to all subtitles (in 1/10s, eg 100 means 10s).")#define SUB_FPS_LONGTEXT \ N_("Override the normal frames per second settings. " \ "This will only affect frame-based subtitle formats without a fixed value.")#define SUB_TYPE_LONGTEXT \ N_("Force the subtiles format. Use \"auto\", the set of supported values varies.")vlc_module_begin(); set_shortname( N_("Subtitles (asa demuxer)")); set_description( N_("Text subtitles parser") ); set_capability( "demux", 50 ); set_category( CAT_INPUT ); set_subcategory( SUBCAT_INPUT_DEMUX ); add_float( "sub-fps", 0.0, NULL, N_("Frames per second"), SUB_FPS_LONGTEXT, true ); add_integer( "sub-delay", 0, NULL, N_("Subtitles delay"), SUB_DELAY_LONGTEXT, true ); add_string( "sub-type", "auto", NULL, N_("Subtitles format"), SUB_TYPE_LONGTEXT, true ); set_callbacks( Open, Close ); add_shortcut( "asademux" );vlc_module_end();/***************************************************************************** * Prototypes: *****************************************************************************/typedef struct{ int64_t i_start; int64_t i_stop; char *psz_text;} subtitle_t;struct demux_sys_t{ int i_type; es_out_id_t *es; int64_t i_next_demux_date; int64_t i_microsecperframe; char *psz_header; int i_subtitle; int i_subtitles; int i_subs_alloc; subtitle_t *subtitle; int64_t i_length;};static int Demux( demux_t * );static int Control( demux_t *, int, va_list );static void Fix( demux_t * );static int ProcessLine( demux_t *, void *, int64_t, int64_t, const char *, size_t );/***************************************************************************** * Module initializer *****************************************************************************/static int Open ( vlc_object_t *p_this ){ demux_t *p_demux = (demux_t*)p_this; demux_sys_t *p_sys; es_format_t fmt; input_thread_t *p_input; float f_fps; char *psz_type; int64_t i_ssize; void *p_data; struct asa_import_detect *p_detect = NULL; if( strcmp( p_demux->psz_demux, "asademux" ) ) { return VLC_EGENERIC; } p_demux->pf_demux = Demux; p_demux->pf_control = Control; p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) ); if( !p_sys ) return VLC_ENOMEM; p_sys->psz_header = NULL; p_sys->i_subtitle = 0; p_sys->i_subtitles = 0; p_sys->i_subs_alloc = 0; p_sys->subtitle = NULL; p_sys->i_microsecperframe = 40000; /* Get the FPS */ p_input = (input_thread_t *)vlc_object_find( p_demux, VLC_OBJECT_INPUT, FIND_PARENT ); if( p_input ) { f_fps = var_GetFloat( p_input, "sub-original-fps" ); if( f_fps >= 1.0 ) p_sys->i_microsecperframe = (int64_t)( (float)1000000 / f_fps ); msg_Dbg( p_demux, "Movie fps: %f", f_fps ); vlc_object_release( p_input ); } /* Check for override of the fps */ f_fps = var_CreateGetFloat( p_demux, "sub-fps" ); if( f_fps >= 1.0 ) { p_sys->i_microsecperframe = (int64_t)( (float)1000000 / f_fps ); msg_Dbg( p_demux, "Override subtitle fps %f", f_fps ); } /* Get or probe the type */ psz_type = var_CreateGetString( p_demux, "sub-type" ); if( *psz_type ) { for( p_detect = asa_det_first; p_detect; p_detect = p_detect->next ) { if( !strcmp( p_detect->name, psz_type ) ) { break; } } if( !p_detect ) { msg_Warn( p_demux, "unknown sub-type \"%s\"", psz_type ); } } free( psz_type ); /* Probe if unknown type */ if( !p_detect ) { int i_size; const uint8_t *p; msg_Dbg( p_demux, "autodetecting subtitle format" ); i_size = stream_Peek( p_demux->s, &p, 4096 ); if( i_size <= 0) { msg_Warn( p_demux, "cannot process subtitles (no data?)" ); return VLC_EGENERIC; } p_detect = asa_imports_detect( p, i_size ); } if( !p_detect ) { msg_Err( p_demux, "failed to recognize subtitle type" ); free( p_sys ); return VLC_EGENERIC; } if( !p_detect->fmt ) { msg_Err( p_demux, "detected %s subtitle format, no asa support", p_detect->name ); free( p_sys ); return VLC_EGENERIC; } msg_Dbg( p_demux, "detected %s subtitle format", p_detect->name ); stream_Control( p_demux->s, STREAM_GET_SIZE, &i_ssize ); p_data = malloc( i_ssize ); if( !p_data ) { free( p_sys ); return VLC_ENOMEM; } if( stream_Read( p_demux->s, &p_data, i_ssize ) != i_ssize ) { msg_Err( p_demux, "subtitle stream read error" ); free( p_data ); free( p_sys ); return VLC_EGENERIC; } asa_import( p_demux, p_data, i_ssize, p_sys->i_microsecperframe, p_detect, ProcessLine, NULL ); free( p_data ); msg_Dbg(p_demux, "loaded %d subtitles", p_sys->i_subtitles ); /* Fix subtitle (order and time) *** */ Fix( p_demux ); p_sys->i_subtitle = 0; p_sys->i_length = 0; if( p_sys->i_subtitles > 0 ) { p_sys->i_length = p_sys->subtitle[p_sys->i_subtitles-1].i_stop; /* +1 to avoid 0 */ if( p_sys->i_length <= 0 ) p_sys->i_length = p_sys->subtitle[p_sys->i_subtitles-1].i_start+1; } /* *** add subtitle ES *** */ if( p_detect->fmt->target == ASAI_TARGET_SSA ) { es_format_Init( &fmt, SPU_ES, VLC_FOURCC( 's','s','a',' ' ) ); } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -