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