Used vlc_fourcc_GetCodecAudio when applicable.
[vlc.git] / 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 for audio */
91     if( p_dec->fmt_in.i_cat == AUDIO_ES )
92     {
93         p_dec->fmt_out.i_codec = vlc_fourcc_GetCodecAudio( p_dec->fmt_in.i_codec,
94                                                            p_dec->fmt_in.audio.i_bitspersample );
95         if( !p_dec->fmt_out.i_codec )
96         {
97             msg_Err( p_dec, "unknown raw audio sample size" );
98             return VLC_EGENERIC;
99         }
100     }
101
102     p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) );
103     p_sys->p_block    = NULL;
104
105     return VLC_SUCCESS;
106 }
107
108 /*****************************************************************************
109  * Close:
110  *****************************************************************************/
111 static void Close( vlc_object_t *p_this )
112 {
113     decoder_t     *p_dec = (decoder_t*)p_this;
114
115     if( p_dec->p_sys->p_block )
116     {
117         block_ChainRelease( p_dec->p_sys->p_block );
118     }
119
120     es_format_Clean( &p_dec->fmt_out );
121     free( p_dec->p_sys );
122 }
123
124 /*****************************************************************************
125  * Packetize: packetize an unit (here copy a complete block )
126  *****************************************************************************/
127 static block_t *Packetize ( decoder_t *p_dec, block_t **pp_block )
128 {
129     block_t *p_block;
130     block_t *p_ret = p_dec->p_sys->p_block;
131
132     if( pp_block == NULL || *pp_block == NULL )
133         return NULL;
134     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
135     {
136         block_Release( *pp_block );
137         return NULL;
138     }
139
140     p_block = *pp_block;
141     *pp_block = NULL;
142
143     if( p_block->i_dts <= 0 )
144     {
145         p_block->i_dts = p_block->i_pts;
146     }
147
148     if( p_block->i_dts <= 0 )
149     {
150         msg_Dbg( p_dec, "need dts > 0" );
151         block_Release( p_block );
152         return NULL;
153     }
154
155     if( p_ret != NULL && p_block->i_pts > p_ret->i_pts )
156     {
157         p_ret->i_length = p_block->i_pts - p_ret->i_pts;
158     }
159     p_dec->p_sys->p_block = p_block;
160
161     return p_ret;
162 }
163
164 /*****************************************************************************
165  * PacketizeSub: packetize an unit (here copy a complete block )
166  *****************************************************************************/
167 static block_t *PacketizeSub( decoder_t *p_dec, block_t **pp_block )
168 {
169     block_t *p_block;
170
171     if( pp_block == NULL || *pp_block == NULL )
172         return NULL;
173     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
174     {
175         block_Release( *pp_block );
176         return NULL;
177     }
178
179     p_block = *pp_block;
180     *pp_block = NULL;
181
182     if( p_block->i_dts <= 0 )
183     {
184         p_block->i_dts = p_block->i_pts;
185     }
186
187     if( p_block->i_dts <= 0 )
188     {
189         msg_Dbg( p_dec, "need dts > 0" );
190         block_Release( p_block );
191         return NULL;
192     }
193
194     return p_block;
195 }