1 /*****************************************************************************
2 * osd.c: transcoding stream output module (osd)
3 *****************************************************************************
4 * Copyright (C) 2003-2009 VLC authors and VideoLAN
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 it
13 * under the terms of the GNU Lesser General Public License as published by
14 * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this program; if not, write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
31 #include "transcode.h"
34 #include <vlc_modules.h>
39 int transcode_osd_new( sout_stream_t
*p_stream
, sout_stream_id_sys_t
*id
)
41 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
43 id
->p_decoder
->fmt_in
.i_cat
= SPU_ES
;
44 id
->p_encoder
->fmt_out
.psz_language
= strdup( "osd" );
46 if( p_sys
->i_osdcodec
!= 0 || p_sys
->psz_osdenc
)
48 msg_Dbg( p_stream
, "creating osdmenu transcoding from fcc=`%4.4s' "
49 "to fcc=`%4.4s'", (char*)&id
->p_encoder
->fmt_out
.i_codec
,
50 (char*)&p_sys
->i_osdcodec
);
52 /* Complete destination format */
53 id
->p_encoder
->fmt_out
.i_codec
= p_sys
->i_osdcodec
;
56 es_format_Init( &id
->p_encoder
->fmt_in
, id
->p_decoder
->fmt_in
.i_cat
,
58 id
->p_encoder
->fmt_in
.psz_language
= strdup( "osd" );
60 id
->p_encoder
->p_cfg
= p_sys
->p_osd_cfg
;
62 id
->p_encoder
->p_module
=
63 module_need( id
->p_encoder
, "encoder", p_sys
->psz_osdenc
, true );
65 if( !id
->p_encoder
->p_module
)
67 msg_Err( p_stream
, "cannot find spu encoder (%s)", p_sys
->psz_osdenc
);
71 /* open output stream */
72 id
->id
= sout_StreamIdAdd( p_stream
->p_next
, &id
->p_encoder
->fmt_out
);
73 id
->b_transcode
= true;
75 if( !id
->id
) goto error
;
79 msg_Dbg( p_stream
, "not transcoding a stream (fcc=`%4.4s')",
80 (char*)&id
->p_decoder
->fmt_out
.i_codec
);
81 id
->id
= sout_StreamIdAdd( p_stream
->p_next
, &id
->p_decoder
->fmt_out
);
82 id
->b_transcode
= false;
84 if( !id
->id
) goto error
;
88 p_sys
->p_spu
= spu_Create( p_stream
);
93 msg_Err( p_stream
, "starting osd encoding thread failed" );
94 if( id
->p_encoder
->p_module
)
95 module_unneed( id
->p_encoder
, id
->p_encoder
->p_module
);
100 void transcode_osd_close( sout_stream_t
*p_stream
, sout_stream_id_sys_t
*id
)
102 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
107 if( id
->p_encoder
->p_module
)
108 module_unneed( id
->p_encoder
, id
->p_encoder
->p_module
);
110 p_sys
->b_osd
= false;
113 int transcode_osd_process( sout_stream_t
*p_stream
, sout_stream_id_sys_t
*id
,
114 block_t
*in
, block_t
**out
)
116 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
117 subpicture_t
*p_subpic
= NULL
;
119 /* Check if we have a subpicture to send */
120 if( p_sys
->p_spu
&& in
->i_dts
> VLC_TS_INVALID
)
123 video_format_Init( &fmt
, 0 );
124 video_format_Setup( &fmt
, 0, 720, 576, 720, 576, 1, 1 );
125 p_subpic
= spu_Render( p_sys
->p_spu
, NULL
, &fmt
, &fmt
, in
->i_dts
, in
->i_dts
, false );
129 msg_Warn( p_stream
, "spu channel not initialized, doing it now" );
131 p_sys
->p_spu
= spu_Create( p_stream
);
136 block_t
*p_block
= NULL
;
138 if( p_sys
->b_master_sync
&& p_sys
->i_master_drift
)
140 p_subpic
->i_start
-= p_sys
->i_master_drift
;
141 if( p_subpic
->i_stop
) p_subpic
->i_stop
-= p_sys
->i_master_drift
;
144 p_block
= id
->p_encoder
->pf_encode_sub( id
->p_encoder
, p_subpic
);
145 subpicture_Delete( p_subpic
);
148 p_block
->i_dts
= p_block
->i_pts
= in
->i_dts
;
149 block_ChainAppend( out
, p_block
);
156 bool transcode_osd_add( sout_stream_t
*p_stream
, es_format_t
*p_fmt
,
157 sout_stream_id_sys_t
*id
)
159 sout_stream_sys_t
*p_sys
= p_stream
->p_sys
;
161 msg_Dbg( p_stream
, "creating osd transcoding from fcc=`%4.4s' "
162 "to fcc=`%4.4s'", (char*)&p_fmt
->i_codec
,
163 (char*)&p_sys
->i_scodec
);
165 id
->b_transcode
= true;
167 /* Create a fake OSD menu elementary stream */
168 if( transcode_osd_new( p_stream
, id
) )
170 msg_Err( p_stream
, "cannot create osd chain" );