]> git.sesse.net Git - vlc/blob - modules/packetizer/copy.c
Don't include config.h from the headers - refs #297.
[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/vlc.h>
34 #include <vlc_codec.h>
35 #include <vlc_block.h>
36
37 /*****************************************************************************
38  * Module descriptor
39  *****************************************************************************/
40 static int  Open ( vlc_object_t * );
41 static void Close( vlc_object_t * );
42
43 vlc_module_begin();
44     set_category( CAT_SOUT );
45     set_subcategory( SUBCAT_SOUT_PACKETIZER );
46     set_description( _("Copy packetizer") );
47     set_capability( "packetizer", 1 );
48     set_callbacks( Open, Close );
49 vlc_module_end();
50
51 /*****************************************************************************
52  * Local prototypes
53  *****************************************************************************/
54 struct decoder_sys_t
55 {
56     block_t *p_block;
57 };
58
59 static block_t *Packetize   ( decoder_t *, block_t ** );
60 static block_t *PacketizeSub( decoder_t *, block_t ** );
61
62 /*****************************************************************************
63  * Open: probe the packetizer and return score
64  *****************************************************************************
65  * Tries to launch a decoder and return score so that the interface is able
66  * to choose.
67  *****************************************************************************/
68 static int Open( vlc_object_t *p_this )
69 {
70     decoder_t     *p_dec = (decoder_t*)p_this;
71     decoder_sys_t *p_sys;
72
73     if( p_dec->fmt_in.i_cat != AUDIO_ES &&
74         p_dec->fmt_in.i_cat != VIDEO_ES &&
75         p_dec->fmt_in.i_cat != SPU_ES )
76     {
77         msg_Err( p_dec, "invalid ES type" );
78         return VLC_EGENERIC;
79     }
80
81     if( p_dec->fmt_in.i_cat == SPU_ES )
82         p_dec->pf_packetize = PacketizeSub;
83     else
84         p_dec->pf_packetize = Packetize;
85
86     /* Create the output format */
87     es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
88
89     /* Fix the value of the fourcc */
90     switch( p_dec->fmt_in.i_codec )
91     {
92         /* video */
93         case VLC_FOURCC( 'm', '4', 's', '2'):
94         case VLC_FOURCC( 'M', '4', 'S', '2'):
95         case VLC_FOURCC( 'm', 'p', '4', 's'):
96         case VLC_FOURCC( 'M', 'P', '4', 'S'):
97         case VLC_FOURCC( 'D', 'I', 'V', 'X'):
98         case VLC_FOURCC( 'd', 'i', 'v', 'x'):
99         case VLC_FOURCC( 'X', 'V', 'I', 'D'):
100         case VLC_FOURCC( 'X', 'v', 'i', 'D'):
101         case VLC_FOURCC( 'x', 'v', 'i', 'd'):
102         case VLC_FOURCC( 'D', 'X', '5', '0'):
103         case VLC_FOURCC( 0x04, 0,   0,   0):
104         case VLC_FOURCC( '3', 'I', 'V', '2'):
105             p_dec->fmt_out.i_codec = VLC_FOURCC( 'm', 'p', '4', 'v');
106             break;
107
108         case VLC_FOURCC( 'm', 'p', 'g', '1' ):
109         case VLC_FOURCC( 'm', 'p', 'g', '2' ):
110         case VLC_FOURCC( 'm', 'p', '1', 'v' ):
111         case VLC_FOURCC( 'm', 'p', '2', 'v' ):
112             p_dec->fmt_out.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'v' );
113             break;
114
115         case VLC_FOURCC( 'd', 'i', 'v', '1' ):
116         case VLC_FOURCC( 'M', 'P', 'G', '4' ):
117         case VLC_FOURCC( 'm', 'p', 'g', '4' ):
118             p_dec->fmt_out.i_codec = VLC_FOURCC( 'D', 'I', 'V', '1' );
119             break;
120
121         case VLC_FOURCC( 'd', 'i', 'v', '2' ):
122         case VLC_FOURCC( 'M', 'P', '4', '2' ):
123         case VLC_FOURCC( 'm', 'p', '4', '2' ):
124             p_dec->fmt_out.i_codec = VLC_FOURCC( 'D', 'I', 'V', '2' );
125             break;
126
127         case VLC_FOURCC( 'd', 'i', 'v', '3' ):
128         case VLC_FOURCC( 'd', 'i', 'v', '4' ):
129         case VLC_FOURCC( 'D', 'I', 'V', '4' ):
130         case VLC_FOURCC( 'd', 'i', 'v', '5' ):
131         case VLC_FOURCC( 'D', 'I', 'V', '5' ):
132         case VLC_FOURCC( 'd', 'i', 'v', '6' ):
133         case VLC_FOURCC( 'D', 'I', 'V', '6' ):
134         case VLC_FOURCC( 'M', 'P', '4', '3' ):
135         case VLC_FOURCC( 'm', 'p', '4', '3' ):
136         case VLC_FOURCC( 'm', 'p', 'g', '3' ):
137         case VLC_FOURCC( 'M', 'P', 'G', '3' ):
138         case VLC_FOURCC( 'A', 'P', '4', '1' ):
139             p_dec->fmt_out.i_codec = VLC_FOURCC( 'D', 'I', 'V', '3' );
140             break;
141
142         case VLC_FOURCC( 'h', '2', '6', '3' ):
143         case VLC_FOURCC( 'U', '2', '6', '3' ):
144         case VLC_FOURCC( 'u', '2', '6', '3' ):
145             p_dec->fmt_out.i_codec = VLC_FOURCC( 'H', '2', '6', '3' );
146             break;
147
148         case VLC_FOURCC( 'i', '2', '6', '3' ):
149             p_dec->fmt_out.i_codec = VLC_FOURCC( 'I', '2', '6', '3' );
150             break;
151
152         case VLC_FOURCC( 'm', 'j', 'p', 'g' ):
153         case VLC_FOURCC( 'm', 'j', 'p', 'a' ):
154         case VLC_FOURCC( 'j', 'p', 'e', 'g' ):
155         case VLC_FOURCC( 'J', 'P', 'E', 'G' ):
156         case VLC_FOURCC( 'J', 'F', 'I', 'F' ):
157             p_dec->fmt_out.i_codec = VLC_FOURCC( 'M', 'J', 'P', 'G' );
158             break;
159
160         case VLC_FOURCC( 'd', 'v', 's', 'd' ):
161         case VLC_FOURCC( 'D', 'V', 'S', 'D' ):
162         case VLC_FOURCC( 'd', 'v', 'h', 'd' ):
163             p_dec->fmt_out.i_codec = VLC_FOURCC( 'd', 'v', 's', 'l' );
164             break;
165
166         /* audio */
167         case VLC_FOURCC( 'a', 'r', 'a', 'w' ):
168             switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
169             {
170                 case 1:
171                     p_dec->fmt_out.i_codec = VLC_FOURCC('u','8',' ',' ');
172                     break;
173                 case 2:
174                     p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
175                     break;
176                 case 3:
177                     p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
178                     break;
179                 case 4:
180                     p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
181                     break;
182                 default:
183                     msg_Err( p_dec, "unknown raw audio sample size" );
184                     return VLC_EGENERIC;
185             }
186             break;
187
188         case VLC_FOURCC( 't', 'w', 'o', 's' ):
189             switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
190             {
191                 case 1:
192                     p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
193                     break;
194                 case 2:
195                     p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','b');
196                     break;
197                 case 3:
198                     p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','b');
199                     break;
200                 case 4:
201                     p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','b');
202                     break;
203                 default:
204                     msg_Err( p_dec, "unknown raw audio sample size" );
205                     return VLC_EGENERIC;
206             }
207             break;
208
209         case VLC_FOURCC( 's', 'o', 'w', 't' ):
210             switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
211             {
212                 case 1:
213                     p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
214                     break;
215                 case 2:
216                     p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
217                     break;
218                 case 3:
219                     p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
220                     break;
221                 case 4:
222                     p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
223                     break;
224                 default:
225                     msg_Err( p_dec, "unknown raw audio sample size" );
226                     return VLC_EGENERIC;
227             }
228             break;
229     }
230
231     p_dec->p_sys = p_sys = malloc( sizeof( block_t ) );
232     p_sys->p_block    = NULL;
233
234     return VLC_SUCCESS;
235 }
236
237 /*****************************************************************************
238  * Close:
239  *****************************************************************************/
240 static void Close( vlc_object_t *p_this )
241 {
242     decoder_t     *p_dec = (decoder_t*)p_this;
243
244     if( p_dec->p_sys->p_block )
245     {
246         block_ChainRelease( p_dec->p_sys->p_block );
247     }
248
249     es_format_Clean( &p_dec->fmt_out );
250     free( p_dec->p_sys );
251 }
252
253 /*****************************************************************************
254  * Packetize: packetize an unit (here copy a complete block )
255  *****************************************************************************/
256 static block_t *Packetize ( decoder_t *p_dec, block_t **pp_block )
257 {
258     block_t *p_block;
259     block_t *p_ret = p_dec->p_sys->p_block;
260
261     if( pp_block == NULL || *pp_block == NULL )
262         return NULL;
263     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
264     {
265         block_Release( *pp_block );
266         return NULL;
267     }
268
269     p_block = *pp_block;
270     *pp_block = NULL;
271
272     if( p_block->i_dts <= 0 )
273     {
274         p_block->i_dts = p_block->i_pts;
275     }
276
277     if( p_block->i_dts <= 0 )
278     {
279         msg_Dbg( p_dec, "need dts > 0" );
280         block_Release( p_block );
281         return NULL;
282     }
283
284     if( p_ret != NULL && p_block->i_pts > p_ret->i_pts )
285     {
286         p_ret->i_length = p_block->i_pts - p_ret->i_pts;
287     }
288     p_dec->p_sys->p_block = p_block;
289
290     return p_ret;
291 }
292
293 /*****************************************************************************
294  * PacketizeSub: packetize an unit (here copy a complete block )
295  *****************************************************************************/
296 static block_t *PacketizeSub( decoder_t *p_dec, block_t **pp_block )
297 {
298     block_t *p_block;
299
300     if( pp_block == NULL || *pp_block == NULL )
301         return NULL;
302     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
303     {
304         block_Release( *pp_block );
305         return NULL;
306     }
307
308     p_block = *pp_block;
309     *pp_block = NULL;
310
311     if( p_block->i_dts <= 0 )
312     {
313         p_block->i_dts = p_block->i_pts;
314     }
315
316     if( p_block->i_dts <= 0 )
317     {
318         msg_Dbg( p_dec, "need dts > 0" );
319         block_Release( p_block );
320         return NULL;
321     }
322
323     return p_block;
324 }