]> git.sesse.net Git - vlc/blob - modules/packetizer/copy.c
Merge branch 1.0-bugfix
[vlc] / modules / packetizer / copy.c
1 /*****************************************************************************
2  * copy.c
3  *****************************************************************************
4  * Copyright (C) 2001, 2002, 2006 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Eric Petit <titer@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_codec.h>
36 #include <vlc_block.h>
37
38 /*****************************************************************************
39  * Module descriptor
40  *****************************************************************************/
41 static int  Open ( vlc_object_t * );
42 static void Close( vlc_object_t * );
43
44 vlc_module_begin ()
45     set_category( CAT_SOUT )
46     set_subcategory( SUBCAT_SOUT_PACKETIZER )
47     set_description( N_("Copy packetizer") )
48     set_capability( "packetizer", 1 )
49     set_callbacks( Open, Close )
50 vlc_module_end ()
51
52 /*****************************************************************************
53  * Local prototypes
54  *****************************************************************************/
55 struct decoder_sys_t
56 {
57     block_t *p_block;
58 };
59
60 static block_t *Packetize   ( decoder_t *, block_t ** );
61 static block_t *PacketizeSub( decoder_t *, block_t ** );
62
63 /*****************************************************************************
64  * Open: probe the packetizer and return score
65  *****************************************************************************
66  * Tries to launch a decoder and return score so that the interface is able
67  * to choose.
68  *****************************************************************************/
69 static int Open( vlc_object_t *p_this )
70 {
71     decoder_t     *p_dec = (decoder_t*)p_this;
72     decoder_sys_t *p_sys;
73
74     if( p_dec->fmt_in.i_cat != AUDIO_ES &&
75         p_dec->fmt_in.i_cat != VIDEO_ES &&
76         p_dec->fmt_in.i_cat != SPU_ES )
77     {
78         msg_Err( p_dec, "invalid ES type" );
79         return VLC_EGENERIC;
80     }
81
82     if( p_dec->fmt_in.i_cat == SPU_ES )
83         p_dec->pf_packetize = PacketizeSub;
84     else
85         p_dec->pf_packetize = Packetize;
86
87     /* Create the output format */
88     es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
89
90     /* Fix the value of the fourcc */
91     switch( p_dec->fmt_in.i_codec )
92     {
93         case VLC_FOURCC( 'a', 'r', 'a', 'w' ):
94             switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
95             {
96                 case 1:
97                     p_dec->fmt_out.i_codec = VLC_CODEC_U8;
98                     break;
99                 case 2:
100                     p_dec->fmt_out.i_codec = VLC_CODEC_S16L;
101                     break;
102                 case 3:
103                     p_dec->fmt_out.i_codec = VLC_CODEC_S24L;
104                     break;
105                 case 4:
106                     p_dec->fmt_out.i_codec = VLC_CODEC_S32L;
107                     break;
108                 default:
109                     msg_Err( p_dec, "unknown raw audio sample size" );
110                     return VLC_EGENERIC;
111             }
112             break;
113
114         case VLC_FOURCC( 't', 'w', 'o', 's' ):
115             switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
116             {
117                 case 1:
118                     p_dec->fmt_out.i_codec = VLC_CODEC_S8;
119                     break;
120                 case 2:
121                     p_dec->fmt_out.i_codec = VLC_CODEC_S16B;
122                     break;
123                 case 3:
124                     p_dec->fmt_out.i_codec = VLC_CODEC_S24B;
125                     break;
126                 case 4:
127                     p_dec->fmt_out.i_codec = VLC_CODEC_S32B;
128                     break;
129                 default:
130                     msg_Err( p_dec, "unknown raw audio sample size" );
131                     return VLC_EGENERIC;
132             }
133             break;
134
135         case VLC_FOURCC( 's', 'o', 'w', 't' ):
136             switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
137             {
138                 case 1:
139                     p_dec->fmt_out.i_codec = VLC_CODEC_S8;
140                     break;
141                 case 2:
142                     p_dec->fmt_out.i_codec = VLC_CODEC_S16L;
143                     break;
144                 case 3:
145                     p_dec->fmt_out.i_codec = VLC_CODEC_S24L;
146                     break;
147                 case 4:
148                     p_dec->fmt_out.i_codec = VLC_CODEC_S32L;
149                     break;
150                 default:
151                     msg_Err( p_dec, "unknown raw audio sample size" );
152                     return VLC_EGENERIC;
153             }
154             break;
155     }
156
157     p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) );
158     p_sys->p_block    = NULL;
159
160     return VLC_SUCCESS;
161 }
162
163 /*****************************************************************************
164  * Close:
165  *****************************************************************************/
166 static void Close( vlc_object_t *p_this )
167 {
168     decoder_t     *p_dec = (decoder_t*)p_this;
169
170     if( p_dec->p_sys->p_block )
171     {
172         block_ChainRelease( p_dec->p_sys->p_block );
173     }
174
175     es_format_Clean( &p_dec->fmt_out );
176     free( p_dec->p_sys );
177 }
178
179 /*****************************************************************************
180  * Packetize: packetize an unit (here copy a complete block )
181  *****************************************************************************/
182 static block_t *Packetize ( decoder_t *p_dec, block_t **pp_block )
183 {
184     block_t *p_block;
185     block_t *p_ret = p_dec->p_sys->p_block;
186
187     if( pp_block == NULL || *pp_block == NULL )
188         return NULL;
189     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
190     {
191         block_Release( *pp_block );
192         return NULL;
193     }
194
195     p_block = *pp_block;
196     *pp_block = NULL;
197
198     if( p_block->i_dts <= 0 )
199     {
200         p_block->i_dts = p_block->i_pts;
201     }
202
203     if( p_block->i_dts <= 0 )
204     {
205         msg_Dbg( p_dec, "need dts > 0" );
206         block_Release( p_block );
207         return NULL;
208     }
209
210     if( p_ret != NULL && p_block->i_pts > p_ret->i_pts )
211     {
212         p_ret->i_length = p_block->i_pts - p_ret->i_pts;
213     }
214     p_dec->p_sys->p_block = p_block;
215
216     return p_ret;
217 }
218
219 /*****************************************************************************
220  * PacketizeSub: packetize an unit (here copy a complete block )
221  *****************************************************************************/
222 static block_t *PacketizeSub( decoder_t *p_dec, block_t **pp_block )
223 {
224     block_t *p_block;
225
226     if( pp_block == NULL || *pp_block == NULL )
227         return NULL;
228     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
229     {
230         block_Release( *pp_block );
231         return NULL;
232     }
233
234     p_block = *pp_block;
235     *pp_block = NULL;
236
237     if( p_block->i_dts <= 0 )
238     {
239         p_block->i_dts = p_block->i_pts;
240     }
241
242     if( p_block->i_dts <= 0 )
243     {
244         msg_Dbg( p_dec, "need dts > 0" );
245         block_Release( p_block );
246         return NULL;
247     }
248
249     return p_block;
250 }