]> git.sesse.net Git - vlc/blob - modules/demux/demuxdump.c
* Stringreview !!!
[vlc] / modules / demux / demuxdump.c
1 /*****************************************************************************
2  * demuxdump.c : Pseudo demux module for vlc (dump raw stream)
3  *****************************************************************************
4  * Copyright (C) 2001-2003 VideoLAN
5  * $Id: demuxdump.c,v 1.12 2004/01/25 20:05:28 hartman Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
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>                                      /* malloc(), free() */
28 #include <string.h>                                              /* strdup() */
29 #include <errno.h>
30
31 #include <vlc/vlc.h>
32 #include <vlc/input.h>
33
34 #include <sys/types.h>
35
36 /*****************************************************************************
37  * Local prototypes
38  *****************************************************************************/
39 static int  Activate ( vlc_object_t * );
40 static int  Demux ( input_thread_t * );
41 static void Deactivate ( vlc_object_t * );
42
43 #define DUMP_BLOCKSIZE  16384
44
45 /*****************************************************************************
46  * Module descriptor
47  *****************************************************************************/
48 #define FILE_TEXT N_("Filename of dump")
49 #define FILE_LONGTEXT N_( \
50     "Specify a file name to which the raw stream will be dumped." )
51
52 vlc_module_begin();
53     set_description( _("Filedump demuxer") );
54     set_capability( "demux", 0 );
55     add_file( "demuxdump-file", "stream-demux.dump", NULL, FILE_TEXT, 
56               FILE_LONGTEXT, VLC_FALSE );
57     set_callbacks( Activate, Deactivate );
58     add_shortcut( "dump" );
59 vlc_module_end();
60
61 struct demux_sys_t
62 {
63     char        *psz_name;
64     FILE        *p_file;
65     uint64_t    i_write;
66
67     void        *p_demux_data_sav;
68 };
69
70 /*
71  * Data reading functions
72  */
73
74 /*****************************************************************************
75  * Activate: initializes dump structures
76  *****************************************************************************/
77 static int Activate( vlc_object_t * p_this )
78 {
79     input_thread_t      *p_input = (input_thread_t *)p_this;
80     demux_sys_t         *p_demux;
81     vlc_value_t         val;
82     char                *psz_name;
83
84     /* Set the demux function */
85     p_input->pf_demux = Demux;
86     p_input->pf_demux_control = demux_vaControlDefault;
87
88     /* Initialize access plug-in structures. */
89     if( p_input->i_mtu == 0 )
90     {
91         /* Improve speed. */
92         p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
93     }
94     
95     var_Create( p_input, "demuxdump-file", VLC_VAR_FILE|VLC_VAR_DOINHERIT );
96     var_Get( p_input, "demuxdump-file", &val );
97     psz_name = val.psz_string;
98     if( !psz_name || !*psz_name )
99     {
100         msg_Warn( p_input, "no dump file name given" );
101         return VLC_EGENERIC;
102     }
103
104     p_demux = malloc( sizeof( demux_sys_t ) );
105     memset( p_demux, 0, sizeof( demux_sys_t ) );
106
107     if( !strcmp( psz_name, "-" ) )
108     {
109         msg_Info( p_input,
110                   "dumping raw stream to standard output" );
111         p_demux->p_file = stdout;
112         p_demux->psz_name = psz_name;
113     }
114     else if( !( p_demux->p_file = fopen( psz_name, "wb" ) ) )
115     {
116         msg_Err( p_input,
117                  "cannot create `%s' for writing", 
118                  psz_name );
119         free( p_demux );
120         return VLC_EGENERIC;
121     }
122     else
123     {
124         msg_Info( p_input,
125                   "dumping raw stream to file `%s'", 
126                   psz_name );
127         p_demux->psz_name = psz_name;
128     }
129
130     p_demux->i_write = 0;
131     p_demux->p_demux_data_sav = p_input->p_demux_data;
132
133     if( p_input->stream.p_selected_program != NULL )
134     {
135         /* workaround for dvd access */
136         msg_Warn( p_input, "demux data already initializated (by access?)" );
137     }
138     else
139     {
140
141         if( input_InitStream( p_input, 0 ) == -1 )
142         {
143             if( p_demux->p_file != stdout )
144                 fclose( p_demux->p_file );
145             free( p_demux );
146             return VLC_EGENERIC;
147         }
148         input_AddProgram( p_input, 0, 0 );
149         p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
150
151         vlc_mutex_lock( &p_input->stream.stream_lock );
152         p_input->stream.p_selected_area->i_tell = 0;
153         vlc_mutex_unlock( &p_input->stream.stream_lock );
154     }
155
156     p_input->p_demux_data = p_demux;
157
158     vlc_mutex_lock( &p_input->stream.stream_lock );
159     p_input->stream.p_selected_program->b_is_ok = 1;
160     vlc_mutex_unlock( &p_input->stream.stream_lock );
161     
162     return VLC_SUCCESS;
163 }
164
165 /*****************************************************************************
166  * Deactivate: initializes dump structures
167  *****************************************************************************/
168 static void Deactivate ( vlc_object_t *p_this )
169 {
170     input_thread_t      *p_input = (input_thread_t *)p_this;
171     demux_sys_t         *p_demux = (demux_sys_t*)p_input->p_demux_data;
172
173     msg_Info( p_input,
174               "closing %s ("I64Fd" Kbytes dumped)",
175               p_demux->psz_name,
176               p_demux->i_write / 1024 );
177
178     if( p_demux->p_file )
179     {
180         if( p_demux->p_file != stdout )
181             fclose( p_demux->p_file );
182         p_demux->p_file = NULL;
183     }
184     if( p_demux->psz_name )
185     {
186         free( p_demux->psz_name );
187     }
188     p_input->p_demux_data = p_demux->p_demux_data_sav;
189     free( p_demux );
190 }
191
192 /*****************************************************************************
193  * Demux: reads and demuxes data packets
194  *****************************************************************************
195  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
196  *****************************************************************************/
197 static int Demux( input_thread_t * p_input )
198 {
199     demux_sys_t         *p_demux = (demux_sys_t*)p_input->p_demux_data;
200
201     ssize_t         i_read;
202     data_packet_t * p_data;
203     int             i_write;
204
205     p_input->p_demux_data = p_demux->p_demux_data_sav;
206     i_read = input_SplitBuffer( p_input, &p_data, DUMP_BLOCKSIZE );
207     p_input->p_demux_data = p_demux;
208     
209     if ( i_read <= 0 )
210     {
211         return i_read;
212     }
213
214     i_write = fwrite( p_data->p_payload_start,
215                        1,
216                        i_read,
217                        p_demux->p_file );
218     
219     input_DeletePacket( p_input->p_method_data, p_data );
220
221     if( i_write < 0 )
222     {
223         msg_Err( p_input, 
224                  "failed to write %d bytes",
225                  i_write );
226         return( -1 );
227     }
228     else
229     {
230         msg_Dbg( p_input,
231                  "dumped %d bytes",
232                  i_write );
233         p_demux->i_write += i_write;
234     }
235
236
237     if( (p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT)
238          | (input_ClockManageControl( p_input, 
239                       p_input->stream.p_selected_program,
240                          (mtime_t)0 ) == PAUSE_S) )
241     {
242         msg_Warn( p_input, "synchro reinit" );
243         p_input->stream.p_selected_program->i_synchro_state = SYNCHRO_OK;
244     }
245
246     return( 1 );
247 }