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