1
/*****************************************************************************
2
* spu.c: transcoding stream output module (spu)
3
*****************************************************************************
4
* Copyright (C) 2003-2009 the VideoLAN team
5
* $Id: e493b6ff62a05d747cd054fe7d12e18a18e02454 $
7
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
8
* Gildas Bazin <gbazin@videolan.org>
9
* Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
10
* Antoine Cellerier <dionoea at videolan dot org>
12
* This program is free software; you can redistribute it and/or modify
13
* it under the terms of the GNU General Public License as published by
14
* the Free Software Foundation; either version 2 of the License, or
15
* (at your option) any later version.
17
* This program is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
22
* You should have received a copy of the GNU General Public License
23
* along with this program; if not, write to the Free Software
24
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25
*****************************************************************************/
27
/*****************************************************************************
29
*****************************************************************************/
31
#include "transcode.h"
37
static subpicture_t *spu_new_buffer( decoder_t *p_dec )
40
return subpicture_New();
43
static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
46
subpicture_Delete( p_subpic );
48
int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_t *id )
50
sout_stream_sys_t *p_sys = p_stream->p_sys;
56
/* Initialization of decoder structures */
57
id->p_decoder->pf_decode_sub = NULL;
58
id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
59
id->p_decoder->pf_spu_buffer_del = spu_del_buffer;
60
id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
61
/* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
63
id->p_decoder->p_module =
64
module_need( id->p_decoder, "decoder", "$codec", false );
66
if( !id->p_decoder->p_module )
68
msg_Err( p_stream, "cannot find spu decoder" );
72
if( !p_sys->b_soverlay )
75
/* Initialization of encoder format structures */
76
es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat,
77
id->p_decoder->fmt_in.i_codec );
79
id->p_encoder->p_cfg = p_sys->p_spu_cfg;
81
id->p_encoder->p_module =
82
module_need( id->p_encoder, "encoder", p_sys->psz_senc, true );
84
if( !id->p_encoder->p_module )
86
module_unneed( id->p_decoder, id->p_decoder->p_module );
87
msg_Err( p_stream, "cannot find spu encoder (%s)", p_sys->psz_senc );
94
p_sys->p_spu = spu_Create( p_stream );
95
spu_Init( p_sys->p_spu );
101
void transcode_spu_close( sout_stream_id_t *id)
104
if( id->p_decoder->p_module )
105
module_unneed( id->p_decoder, id->p_decoder->p_module );
106
if( id->p_decoder->p_description )
107
vlc_meta_Delete( id->p_decoder->p_description );
110
if( id->p_encoder->p_module )
111
module_unneed( id->p_encoder, id->p_encoder->p_module );
114
int transcode_spu_process( sout_stream_t *p_stream,
115
sout_stream_id_t *id,
116
block_t *in, block_t **out )
118
sout_stream_sys_t *p_sys = p_stream->p_sys;
119
subpicture_t *p_subpic;
122
p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
126
sout_UpdateStatistic( p_stream->p_sout, SOUT_STATISTIC_DECODED_SUBTITLE, 1 );
128
if( p_sys->b_master_sync && p_sys->i_master_drift )
130
p_subpic->i_start -= p_sys->i_master_drift;
131
if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
134
if( p_sys->b_soverlay )
136
spu_DisplaySubpicture( p_sys->p_spu, p_subpic );
142
p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
143
spu_del_buffer( id->p_decoder, p_subpic );
146
block_ChainAppend( out, p_block );
154
bool transcode_spu_add( sout_stream_t *p_stream, es_format_t *p_fmt,
155
sout_stream_id_t *id )
157
sout_stream_sys_t *p_sys = p_stream->p_sys;
159
if( p_sys->i_scodec || p_sys->psz_senc )
161
msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "
162
"to fcc=`%4.4s'", (char*)&p_fmt->i_codec,
163
(char*)&p_sys->i_scodec );
165
/* Complete destination format */
166
id->p_encoder->fmt_out.i_codec = p_sys->i_scodec;
168
/* build decoder -> filter -> encoder */
169
if( transcode_spu_new( p_stream, id ) )
171
msg_Err( p_stream, "cannot create subtitles chain" );
175
/* open output stream */
176
id->id = sout_StreamIdAdd( p_stream->p_next, &id->p_encoder->fmt_out );
177
id->b_transcode = true;
181
transcode_spu_close( id );
187
assert( p_sys->b_soverlay );
188
msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying",
189
(char*)&p_fmt->i_codec );
191
id->b_transcode = true;
193
/* Build decoder -> filter -> overlaying chain */
194
if( transcode_spu_new( p_stream, id ) )
196
msg_Err( p_stream, "cannot create subtitles chain" );