]> git.sesse.net Git - vlc/blob - modules/demux/wav/wav.c
* ALL: i18n updates and fixes.
[vlc] / modules / demux / wav / wav.c
1 /*****************************************************************************
2  * wav.c : wav file input module for vlc
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: wav.c,v 1.13 2003/02/27 13:19:43 gbazin Exp $
6  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21  *****************************************************************************/
22
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26 #include <stdlib.h>                                      /* malloc(), free() */
27 #include <string.h>                                              /* strdup() */
28
29 #include <vlc/vlc.h>
30 #include <vlc/input.h>
31
32 #include <codecs.h>
33 #include "wav.h"
34
35 /*****************************************************************************
36  * Local prototypes
37  *****************************************************************************/
38 static int    WAVInit       ( vlc_object_t * );
39 static void __WAVEnd        ( vlc_object_t * );
40 static int    WAVDemux      ( input_thread_t * );
41 static int    WAVCallDemux  ( input_thread_t * );
42
43 #define WAVEnd(a) __WAVEnd(VLC_OBJECT(a))
44
45 /*****************************************************************************
46  * Module descriptor
47  *****************************************************************************/
48 vlc_module_begin();
49     set_description( _("WAV demuxer") );
50     set_capability( "demux", 142 );
51     set_callbacks( WAVInit, __WAVEnd );
52 vlc_module_end();
53
54 /*****************************************************************************
55  * Declaration of local function
56  *****************************************************************************/
57
58 #define FREE( p ) if( p ) free( p ); (p) = NULL
59
60 #define __EVEN( x ) ( (x)%2 != 0 ) ? ((x)+1) : (x)
61
62 /* Some functions to manipulate memory */
63 static uint16_t GetWLE( uint8_t *p_buff )
64 {
65     return( (p_buff[0]) + ( p_buff[1] <<8 ) );
66 }
67
68 static uint32_t GetDWLE( uint8_t *p_buff )
69 {
70     return( p_buff[0] + ( p_buff[1] <<8 ) +
71             ( p_buff[2] <<16 ) + ( p_buff[3] <<24 ) );
72 }
73
74 static uint32_t CreateDWLE( int a, int b, int c, int d )
75 {
76     return( a + ( b << 8 ) + ( c << 16 ) + ( d << 24 ) );
77 }
78
79
80 static off_t TellAbsolute( input_thread_t *p_input )
81 {
82     off_t i_pos;
83
84     vlc_mutex_lock( &p_input->stream.stream_lock );
85
86     i_pos= p_input->stream.p_selected_area->i_tell;
87
88     vlc_mutex_unlock( &p_input->stream.stream_lock );
89
90     return( i_pos );
91 }
92
93 /* return 1 if success, 0 if fail */
94 static int ReadData( input_thread_t *p_input, uint8_t *p_buff, int i_size )
95 {
96     data_packet_t *p_data;
97
98     int i_count = 0;
99
100     if( !i_size )
101     {
102         return( 0 );
103     }
104
105     do
106     {
107         int i_read;
108
109         i_read = input_SplitBuffer(p_input, &p_data, __MIN( i_size, 1024 ) );
110         if( i_read <= 0 )
111         {
112             return( i_count );
113         }
114         memcpy( p_buff, p_data->p_payload_start, i_read );
115         input_DeletePacket( p_input->p_method_data, p_data );
116
117         p_buff += i_read;
118         i_size -= i_read;
119         i_count += i_read;
120
121     } while( i_size );
122
123     return( i_count );
124 }
125
126 static int SeekAbsolute( input_thread_t *p_input,
127                          off_t i_pos)
128 {
129     int         i_skip;
130 #if 0
131     if( i_pos >= p_input->stream.p_selected_area->i_size )
132     {
133         return( 0 );
134     }
135 #endif
136
137     i_skip    = i_pos - TellAbsolute( p_input );
138     if( i_skip == 0 )
139     {
140         return( VLC_SUCCESS );
141     }
142     if( i_skip < 0 && !p_input->stream.b_seekable )
143     {
144         return( VLC_EGENERIC );
145     }
146     else if( !p_input->stream.b_seekable ||
147              ( i_skip > 0 && i_skip < 1024 && p_input->stream.i_method != INPUT_METHOD_FILE ) )
148     {
149         while( i_skip > 0 )
150         {
151             uint8_t dummy[1024];
152             int     i_read;
153
154             i_read = ReadData( p_input, dummy, __MIN( i_skip, 1024 ) );
155             if( i_read <= 0 )
156             {
157                 return( VLC_EGENERIC );
158             }
159             i_skip -= i_read;
160         }
161         return( VLC_SUCCESS );
162     }
163     else
164     {
165             input_AccessReinit( p_input );
166             p_input->pf_seek( p_input, i_pos );
167             return( VLC_SUCCESS );
168     }
169 }
170
171 static int SkipBytes( input_thread_t *p_input, int i_skip )
172 {
173     return( SeekAbsolute( p_input, TellAbsolute( p_input ) + i_skip ) );
174 }
175
176 static int ReadPES( input_thread_t *p_input,
177                     pes_packet_t **pp_pes,
178                     int i_size )
179 {
180     pes_packet_t *p_pes;
181
182     *pp_pes = NULL;
183
184     if( !(p_pes = input_NewPES( p_input->p_method_data )) )
185     {
186         msg_Err( p_input, "cannot allocate new PES" );
187         return( 0 );
188     }
189
190     while( i_size > 0 )
191     {
192         data_packet_t   *p_data;
193         int i_read;
194
195         if( (i_read = input_SplitBuffer( p_input,
196                                          &p_data,
197                                          __MIN( i_size, 1024 ) ) ) <= 0 )
198         {
199             input_DeletePES( p_input->p_method_data, p_pes );
200             return( 0 );
201         }
202         if( !p_pes->p_first )
203         {
204             p_pes->p_first = p_data;
205             p_pes->i_nb_data = 1;
206             p_pes->i_pes_size = i_read;
207         }
208         else
209         {
210             p_pes->p_last->p_next  = p_data;
211             p_pes->i_nb_data++;
212             p_pes->i_pes_size += i_read;
213         }
214         p_pes->p_last  = p_data;
215         i_size -= i_read;
216     }
217     *pp_pes = p_pes;
218     return( 1 );
219 }
220
221 static int FindTag( input_thread_t *p_input, uint32_t i_tag )
222 {
223     uint32_t   i_id;
224     uint32_t   i_size;
225     uint8_t    *p_peek;
226
227     for( ;; )
228     {
229
230         if( input_Peek( p_input, &p_peek, 8 ) < 8 )
231         {
232             msg_Err( p_input, "cannot peek()" );
233             return( 0 );
234         }
235
236         i_id   = GetDWLE( p_peek );
237         i_size = GetDWLE( p_peek + 4 );
238
239         msg_Dbg( p_input, "FindTag: tag:%4.4s size:%d", (char*)&i_id, i_size );
240         if( i_id == i_tag )
241         {
242             /* Yes, we have found the good tag */
243             return( 1 );
244         }
245         if( !SkipBytes( p_input, __EVEN( i_size ) + 8 ) )
246         {
247             return( 0 );
248         }
249     }
250 }
251
252 static int LoadTag_fmt( input_thread_t *p_input,
253                         demux_sys_t *p_demux )
254 {
255     uint8_t  *p_peek;
256     uint32_t i_size;
257     WAVEFORMATEX *p_wf;
258
259
260     if( input_Peek( p_input, &p_peek , 8 ) < 8 )
261     {
262         return( 0 );
263     }
264
265     p_demux->i_wf = i_size = GetDWLE( p_peek + 4 );
266     SkipBytes( p_input, 8 );
267     if( i_size < 16 )
268     {
269         SkipBytes( p_input, i_size );
270         return( 0 );
271     }
272     p_wf = p_demux->p_wf = malloc( __MAX( i_size, sizeof( WAVEFORMATEX) ) );
273     ReadData( p_input, (uint8_t*)p_wf, __EVEN( i_size ) );
274
275     p_wf->wFormatTag      = GetWLE( (uint8_t*)&p_demux->p_wf->wFormatTag );
276     p_wf->nChannels       = GetWLE( (uint8_t*)&p_demux->p_wf->nChannels );
277     p_wf->nSamplesPerSec  = GetWLE( (uint8_t*)&p_demux->p_wf->nSamplesPerSec );
278     p_wf->nAvgBytesPerSec = GetWLE( (uint8_t*)&p_demux->p_wf->nAvgBytesPerSec );
279     p_wf->nBlockAlign     = GetWLE( (uint8_t*)&p_demux->p_wf->nBlockAlign );
280     p_wf->wBitsPerSample  = GetWLE( (uint8_t*)&p_demux->p_wf->wBitsPerSample );
281     if( i_size >= sizeof( WAVEFORMATEX) )
282     {
283         p_wf->cbSize          = GetWLE( (uint8_t*)&p_demux->p_wf->cbSize );
284     }
285     else
286     {
287         p_wf->cbSize = 0;
288     }
289
290     msg_Dbg( p_input, "loaded \"fmt \" chunk" );
291     return( 1 );
292 }
293
294 static int PCM_GetFrame( input_thread_t *p_input,
295                          WAVEFORMATEX   *p_wf,
296                          pes_packet_t   **pp_pes,
297                          mtime_t        *pi_length )
298 {
299     int i_samples;
300
301     int i_bytes;
302     int i_modulo;
303
304     /* read samples for 50ms of */
305     i_samples = __MAX( p_wf->nSamplesPerSec / 20, 1 );
306
307
308     *pi_length = (mtime_t)1000000 *
309                  (mtime_t)i_samples /
310                  (mtime_t)p_wf->nSamplesPerSec;
311
312     i_bytes = i_samples * p_wf->nChannels * ( (p_wf->wBitsPerSample + 7) / 8 );
313
314     if( p_wf->nBlockAlign > 0 )
315     {
316         if( ( i_modulo = i_bytes % p_wf->nBlockAlign ) != 0 )
317         {
318             i_bytes += p_wf->nBlockAlign - i_modulo;
319         }
320     }
321
322     return( ReadPES( p_input, pp_pes, i_bytes ) );
323 }
324
325 static int MS_ADPCM_GetFrame( input_thread_t *p_input,
326                               WAVEFORMATEX   *p_wf,
327                               pes_packet_t   **pp_pes,
328                               mtime_t        *pi_length )
329 {
330     int i_samples;
331
332     i_samples = 2 + 2 * ( p_wf->nBlockAlign -
333                                 7 * p_wf->nChannels ) / p_wf->nChannels;
334
335     *pi_length = (mtime_t)1000000 *
336                  (mtime_t)i_samples /
337                  (mtime_t)p_wf->nSamplesPerSec;
338
339     return( ReadPES( p_input, pp_pes, p_wf->nBlockAlign ) );
340 }
341
342 static int IMA_ADPCM_GetFrame( input_thread_t *p_input,
343                                WAVEFORMATEX   *p_wf,
344                                pes_packet_t   **pp_pes,
345                                mtime_t        *pi_length )
346 {
347     int i_samples;
348
349     i_samples = 2 * ( p_wf->nBlockAlign -
350                         4 * p_wf->nChannels ) / p_wf->nChannels;
351
352     *pi_length = (mtime_t)1000000 *
353                  (mtime_t)i_samples /
354                  (mtime_t)p_wf->nSamplesPerSec;
355
356     return( ReadPES( p_input, pp_pes, p_wf->nBlockAlign ) );
357 }
358
359 /*****************************************************************************
360  * WAVInit: check file and initializes structures
361  *****************************************************************************/
362 static int WAVInit( vlc_object_t * p_this )
363 {
364     input_thread_t *p_input = (input_thread_t *)p_this;
365     uint8_t  *p_peek;
366     uint32_t i_size;
367
368     demux_sys_t *p_demux;
369
370
371
372     /* Initialize access plug-in structures. */
373     if( p_input->i_mtu == 0 )
374     {
375         /* Improve speed. */
376         p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE ;
377     }
378
379     /* a little test to see if it's a wav file */
380     if( input_Peek( p_input, &p_peek, 12 ) < 12 )
381     {
382         msg_Warn( p_input, "WAV plugin discarded (cannot peek)" );
383         return( -1 );
384     }
385
386     if( ( GetDWLE( p_peek ) != CreateDWLE( 'R', 'I', 'F', 'F' ) )||
387         ( GetDWLE( p_peek + 8 ) != CreateDWLE( 'W', 'A', 'V', 'E' ) ) )
388     {
389         msg_Warn( p_input, "WAV plugin discarded (not a valid file)" );
390         return( -1 );
391     }
392     i_size = GetDWLE( p_peek + 4 );
393     SkipBytes( p_input, 12 );
394
395     if( !FindTag( p_input, CreateDWLE( 'f', 'm', 't' ,' ' ) ) )
396     {
397         msg_Err( p_input, "cannot find \"fmt \" tag" );
398         return( -1 );
399     }
400
401     /* create our structure that will contains all data */
402     if( !( p_input->p_demux_data =
403                 p_demux = malloc( sizeof( demux_sys_t ) ) ) )
404     {
405         msg_Err( p_input, "out of memory" );
406         return( -1 );
407     }
408     memset( p_demux, 0, sizeof( demux_sys_t ) );
409
410     /* Load WAVEFORMATEX header */
411     if( !LoadTag_fmt( p_input, p_demux ) )
412     {
413         msg_Err( p_input, "cannot load \"fmt \" tag" );
414         FREE( p_demux );
415         return( -1 );
416     }
417     msg_Dbg( p_input, "format:0x%4.4x channels:%d %dHz %dKo/s blockalign:%d bits/samples:%d extra size:%d",
418             p_demux->p_wf->wFormatTag,
419             p_demux->p_wf->nChannels,
420             p_demux->p_wf->nSamplesPerSec,
421             p_demux->p_wf->nAvgBytesPerSec / 1024,
422             p_demux->p_wf->nBlockAlign,
423             p_demux->p_wf->wBitsPerSample,
424             p_demux->p_wf->cbSize );
425
426     if( !FindTag( p_input, CreateDWLE( 'd', 'a', 't', 'a' ) ) )
427     {
428         msg_Err( p_input, "cannot find \"data\" tag" );
429         FREE( p_demux->p_wf );
430         FREE( p_demux );
431         return( -1 );
432     }
433     if( input_Peek( p_input, &p_peek, 8 ) < 8 )
434     {
435         msg_Warn( p_input, "WAV plugin discarded (cannot peek)" );
436         FREE( p_demux->p_wf );
437         FREE( p_demux );
438         return( -1 );
439     }
440
441     p_demux->i_data_pos = TellAbsolute( p_input ) + 8;
442     p_demux->i_data_size = GetDWLE( p_peek + 4 );
443     SkipBytes( p_input, 8 );
444
445     /* XXX p_demux->psz_demux shouldn't be NULL ! */
446     switch( p_demux->p_wf->wFormatTag )
447     {
448         case( WAVE_FORMAT_PCM ):
449             msg_Dbg( p_input,"found raw pcm audio format" );
450             p_demux->i_fourcc = VLC_FOURCC( 'a', 'r', 'a', 'w' );
451             p_demux->GetFrame = PCM_GetFrame;
452             p_demux->psz_demux = strdup( "" );
453             break;
454         case( WAVE_FORMAT_MPEG ):
455         case( WAVE_FORMAT_MPEGLAYER3 ):
456             msg_Dbg( p_input, "found mpeg audio format" );
457             p_demux->i_fourcc = VLC_FOURCC( 'm', 'p', 'g', 'a' );
458             p_demux->GetFrame = NULL;
459             p_demux->psz_demux = strdup( "mpegaudio" );
460             break;
461         case( WAVE_FORMAT_A52 ):
462             msg_Dbg( p_input,"found a52 audio format" );
463             p_demux->i_fourcc = VLC_FOURCC( 'a', '5', '2', ' ' );
464             p_demux->GetFrame = NULL;
465             p_demux->psz_demux = strdup( "a52" );
466             break;
467         case( WAVE_FORMAT_ADPCM ):
468             msg_Dbg( p_input, "found ms adpcm audio format" );
469             p_demux->i_fourcc = VLC_FOURCC( 'm', 's', 0x00, 0x02 );
470             p_demux->GetFrame = MS_ADPCM_GetFrame;
471             p_demux->psz_demux = strdup( "" );
472             break;
473         case( WAVE_FORMAT_IMA_ADPCM ):
474             msg_Dbg( p_input, "found ima adpcm audio format" );
475             p_demux->i_fourcc = VLC_FOURCC( 'm', 's', 0x00, 0x11 );
476             p_demux->GetFrame = IMA_ADPCM_GetFrame;
477             p_demux->psz_demux = strdup( "" );
478             break;
479         default:
480             msg_Warn( p_input,"unrecognize audio format(0x%x)",
481                       p_demux->p_wf->wFormatTag );
482             p_demux->i_fourcc =
483                 VLC_FOURCC( 'm', 's',
484                             (p_demux->p_wf->wFormatTag >> 8)&0xff,
485                             (p_demux->p_wf->wFormatTag )&0xff);
486             p_demux->GetFrame = NULL;
487             p_demux->psz_demux = strdup( "" );
488             break;
489     }
490
491     if( p_demux->GetFrame )
492     {
493         msg_Dbg( p_input, "using internal demux" );
494
495         p_input->pf_demux = WAVDemux;
496         p_input->p_demux_data = p_demux;
497
498         /*  create one program */
499         vlc_mutex_lock( &p_input->stream.stream_lock );
500         if( input_InitStream( p_input, 0 ) == -1)
501         {
502             vlc_mutex_unlock( &p_input->stream.stream_lock );
503             msg_Err( p_input, "cannot init stream" );
504             // FIXME
505             return( -1 );
506         }
507         if( input_AddProgram( p_input, 0, 0) == NULL )
508         {
509             vlc_mutex_unlock( &p_input->stream.stream_lock );
510             msg_Err( p_input, "cannot add program" );
511             // FIXME
512             return( -1 );
513         }
514         p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
515         p_input->stream.i_mux_rate = 0 ; /* FIXME */
516
517         p_demux->p_es = input_AddES( p_input,
518                                      p_input->stream.p_selected_program, 1,
519                                      0 );
520         p_demux->p_es->i_stream_id = 1;
521         p_demux->p_es->i_fourcc = p_demux->i_fourcc;
522         p_demux->p_es->i_cat = AUDIO_ES;
523         p_demux->p_es->p_waveformatex = malloc( p_demux->i_wf );
524         memcpy( p_demux->p_es->p_waveformatex, p_demux->p_wf, p_demux->i_wf );
525
526         input_SelectES( p_input, p_demux->p_es );
527
528         p_input->stream.p_selected_program->b_is_ok = 1;
529         vlc_mutex_unlock( &p_input->stream.stream_lock );
530     }
531     else
532     {
533         char *psz_sav;
534         /* call an external demux */
535         msg_Warn( p_input, "unsupported formattag, using external demux" );
536
537         psz_sav = p_input->psz_demux;
538         p_input->psz_demux = p_demux->psz_demux;
539
540         p_demux->p_demux = module_Need( p_input, "demux", NULL );
541
542         p_input->psz_demux = psz_sav;
543
544         if( !p_demux->p_demux )
545         {
546             msg_Err( p_input,
547                      "cannot get external demux for formattag 0x%x",
548                      p_demux->p_wf->wFormatTag );
549             FREE( p_demux->psz_demux );
550             FREE( p_demux->p_wf );
551             FREE( p_demux );
552             return( -1 );
553         }
554         /* save value and switch back */
555         p_demux->pf_demux = p_input->pf_demux;
556         p_demux->p_demux_data = p_input->p_demux_data;
557
558         p_input->pf_demux = WAVCallDemux;
559         p_input->p_demux_data = p_demux;
560
561     }
562
563     return( 0 );
564 }
565
566 /*****************************************************************************
567  * WAVCallDemux: call true demux
568  *****************************************************************************
569  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
570  *****************************************************************************/
571 static int WAVCallDemux( input_thread_t *p_input )
572 {
573     demux_sys_t  *p_demux = p_input->p_demux_data;
574     int i_status;
575     char *psz_sav;
576
577     /* save context */
578     psz_sav = p_input->psz_demux;
579
580     /* switch context */
581     p_input->pf_demux = p_demux->pf_demux;
582     p_input->p_demux_data = p_demux->p_demux_data;
583     p_input->psz_demux = p_demux->psz_demux;
584
585     /* call demux */
586     i_status = p_input->pf_demux( p_input );
587
588     /* save (new?) state */
589     p_demux->pf_demux = p_input->pf_demux;
590     p_demux->p_demux_data = p_input->p_demux_data;
591
592     /* switch back */
593     p_input->psz_demux = psz_sav;
594     p_input->pf_demux = WAVCallDemux;
595     p_input->p_demux_data = p_demux;
596
597     return( i_status );
598 }
599
600 /*****************************************************************************
601  * WAVDemux: read packet and send them to decoders
602  *****************************************************************************
603  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
604  *****************************************************************************/
605 static int WAVDemux( input_thread_t *p_input )
606 {
607     demux_sys_t  *p_demux = p_input->p_demux_data;
608     pes_packet_t *p_pes;
609     mtime_t      i_length;
610
611     if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT )
612     {
613         off_t   i_offset;
614
615         i_offset = TellAbsolute( p_input ) - p_demux->i_data_pos;
616         if( i_offset < 0 )
617         {
618             i_offset = 0;
619         }
620         if( p_demux->p_wf->nBlockAlign != 0 )
621         {
622             i_offset += p_demux->p_wf->nBlockAlign -
623                                 i_offset % p_demux->p_wf->nBlockAlign;
624         }
625         SeekAbsolute( p_input, p_demux->i_data_pos + i_offset );
626     }
627
628     input_ClockManageRef( p_input,
629                           p_input->stream.p_selected_program,
630                           p_demux->i_pcr );
631
632     if( TellAbsolute( p_input )
633          >= (off_t)(p_demux->i_data_pos + p_demux->i_data_size) )
634     {
635         return( 0 ); // EOF
636     }
637
638     if( !p_demux->GetFrame( p_input, p_demux->p_wf, &p_pes, &i_length ) )
639     {
640         msg_Warn( p_input, "failed to get one frame" );
641         return( 0 );
642     }
643
644     p_pes->i_dts =
645         p_pes->i_pts = input_ClockGetTS( p_input,
646                                          p_input->stream.p_selected_program,
647                                          p_demux->i_pcr );
648
649     if( !p_demux->p_es->p_decoder_fifo )
650     {
651         msg_Err( p_input, "no audio decoder" );
652         input_DeletePES( p_input->p_method_data, p_pes );
653         return( -1 );
654     }
655     else
656     {
657         input_DecodePES( p_demux->p_es->p_decoder_fifo, p_pes );
658     }
659
660     p_demux->i_pcr += i_length * 9 / 100;
661     return( 1 );
662 }
663
664 /*****************************************************************************
665  * WAVEnd: frees unused data
666  *****************************************************************************/
667 static void __WAVEnd ( vlc_object_t * p_this )
668 {
669     input_thread_t *  p_input = (input_thread_t *)p_this;
670     demux_sys_t *p_demux = p_input->p_demux_data;
671
672     FREE( p_demux->p_wf );
673     FREE( p_demux->psz_demux );
674
675     if( p_demux->p_demux )
676     {
677         char *psz_sav;
678
679         /* save context */
680         psz_sav = p_input->psz_demux;
681
682         /* switch context */
683         p_input->pf_demux = p_demux->pf_demux;
684         p_input->p_demux_data = p_demux->p_demux_data;
685         p_input->psz_demux = p_demux->psz_demux;
686
687         /* unload module */
688         module_Unneed( p_input, p_demux->p_demux );
689
690         /* switch back */
691         p_input->psz_demux = psz_sav;
692         p_input->p_demux_data = p_demux;
693     }
694
695     FREE( p_input->p_demux_data );
696 }
697