]> git.sesse.net Git - vlc/blob - modules/mux/wav.c
* all: compilation fix.
[vlc] / modules / mux / wav.c
1 /*****************************************************************************
2  * wav.c: wav muxer module for vlc
3  *****************************************************************************
4  * Copyright (C) 2004 VideoLAN
5  * $Id$
6  *
7  * Authors: Gildas Bazin <gbazin@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>
28
29 #include <vlc/vlc.h>
30 #include <vlc/sout.h>
31
32 #include "codecs.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_description( _("WAV muxer") );
42     set_capability( "sout mux", 5 );
43     set_callbacks( Open, Close );
44     add_shortcut( "wav" );
45 vlc_module_end();
46
47 /*****************************************************************************
48  * Exported prototypes
49  *****************************************************************************/
50 static int Control  ( sout_mux_t *, int, va_list );
51 static int AddStream( sout_mux_t *, sout_input_t * );
52 static int DelStream( sout_mux_t *, sout_input_t * );
53 static int Mux      ( sout_mux_t * );
54
55 struct sout_mux_sys_t
56 {
57     vlc_bool_t b_used;
58     vlc_bool_t b_header;
59
60     /* Wave header for the output data */
61     WAVEHEADER waveheader;
62 };
63
64 /*****************************************************************************
65  * Open:
66  *****************************************************************************/
67 static int Open( vlc_object_t *p_this )
68 {
69     sout_mux_t *p_mux = (sout_mux_t*)p_this;
70     sout_mux_sys_t  *p_sys;
71
72     p_mux->pf_control  = Control;
73     p_mux->pf_addstream = AddStream;
74     p_mux->pf_delstream = DelStream;
75     p_mux->pf_mux       = Mux;
76
77     p_mux->p_sys = p_sys = malloc( sizeof( sout_mux_sys_t ) );
78     p_sys->b_used       = VLC_FALSE;
79     p_sys->b_header     = VLC_TRUE;
80
81     return VLC_SUCCESS;
82 }
83
84 /*****************************************************************************
85  * Close:
86  *****************************************************************************/
87 static void Close( vlc_object_t * p_this )
88 {
89     sout_mux_t *p_mux = (sout_mux_t*)p_this;
90     sout_mux_sys_t *p_sys = p_mux->p_sys;
91
92     free( p_sys );
93 }
94
95 static int Control( sout_mux_t *p_mux, int i_query, va_list args )
96 {
97     vlc_bool_t *pb_bool;
98     char **ppsz;
99
100    switch( i_query )
101    {
102        case MUX_CAN_ADD_STREAM_WHILE_MUXING:
103            pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
104            *pb_bool = VLC_FALSE;
105            return VLC_SUCCESS;
106
107        case MUX_GET_ADD_STREAM_WAIT:
108            pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
109            *pb_bool = VLC_TRUE;
110            return VLC_SUCCESS;
111
112        case MUX_GET_MIME:
113            ppsz = (char**)va_arg( args, char ** );
114            *ppsz = strdup( "audio/wav" );
115            return VLC_SUCCESS;
116
117         default:
118             return VLC_EGENERIC;
119    }
120 }
121 static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
122 {
123     sout_mux_sys_t *p_sys = p_mux->p_sys;
124     int i_bytes_per_sample;
125
126     if( p_input->p_fmt->i_cat != AUDIO_ES )
127         msg_Dbg( p_mux, "not an audio stream" );
128
129     if( p_sys->b_used )
130     {
131         msg_Dbg( p_mux, "can't add more than 1 stream" );
132         return VLC_EGENERIC;
133     }
134
135     msg_Dbg( p_mux, "adding input %i channels, %iHz",
136              p_input->p_fmt->audio.i_channels,
137              p_input->p_fmt->audio.i_rate );
138
139     //p_input->p_fmt->i_codec;
140
141     /* Build a WAV header for the output data */
142     memset( &p_sys->waveheader, 0, sizeof(WAVEHEADER) );
143     SetWLE( &p_sys->waveheader.Format, 1 ); /*WAVE_FORMAT_PCM*/
144     SetWLE( &p_sys->waveheader.BitsPerSample, 16);
145     p_sys->waveheader.MainChunkID = VLC_FOURCC('R', 'I', 'F', 'F');
146     p_sys->waveheader.Length = 0;                     /* we just don't know */
147     p_sys->waveheader.ChunkTypeID = VLC_FOURCC('W', 'A', 'V', 'E');
148     p_sys->waveheader.SubChunkID = VLC_FOURCC('f', 'm', 't', ' ');
149     SetDWLE( &p_sys->waveheader.SubChunkLength, 16 );
150     SetWLE( &p_sys->waveheader.Modus, p_input->p_fmt->audio.i_channels );
151     SetDWLE( &p_sys->waveheader.SampleFreq, p_input->p_fmt->audio.i_rate );
152     i_bytes_per_sample = p_input->p_fmt->audio.i_channels *
153         16 /*BitsPerSample*/ / 8;
154     SetWLE( &p_sys->waveheader.BytesPerSample, i_bytes_per_sample );
155     SetDWLE( &p_sys->waveheader.BytesPerSec,
156              i_bytes_per_sample * p_input->p_fmt->audio.i_rate );
157     p_sys->waveheader.DataChunkID = VLC_FOURCC('d', 'a', 't', 'a');
158     p_sys->waveheader.DataLength = 0;                 /* we just don't know */
159
160     p_sys->b_used = VLC_TRUE;
161
162     return VLC_SUCCESS;
163 }
164
165 static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
166 {
167     msg_Dbg( p_mux, "removing input" );
168     return VLC_SUCCESS;
169 }
170
171 static int Mux( sout_mux_t *p_mux )
172 {
173     sout_mux_sys_t *p_sys = p_mux->p_sys;
174
175     if( !p_mux->i_nb_inputs ) return VLC_SUCCESS;
176
177     if( p_sys->b_header )
178     {
179         /* Return only the header */
180         block_t *p_block = block_New( p_mux, sizeof( WAVEHEADER ) );
181         memcpy( p_block->p_buffer, &p_sys->waveheader, sizeof(WAVEHEADER) );
182
183         msg_Dbg( p_mux, "writing header data" );
184         sout_AccessOutWrite( p_mux->p_access, p_block );
185     }
186     p_sys->b_header = VLC_FALSE;
187
188     while( p_mux->pp_inputs[0]->p_fifo->i_depth > 0 )
189     {
190         block_t *p_block = block_FifoGet( p_mux->pp_inputs[0]->p_fifo );
191         sout_AccessOutWrite( p_mux->p_access, p_block );
192     }
193
194     return VLC_SUCCESS;
195 }