1 /*****************************************************************************
2 * input_ps.c: PS demux and packet management
3 *****************************************************************************
4 * Copyright (C) 1998, 1999, 2000 VideoLAN
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.
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.
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 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
29 #include <netinet/in.h>
40 #include "stream_control.h"
41 #include "input_ext-intf.h"
42 #include "input_ext-dec.h"
47 #include "mpeg_system.h"
51 /*****************************************************************************
53 *****************************************************************************/
54 static int PSProbe ( struct input_thread_s * );
55 static void PSRead ( struct input_thread_s *,
56 data_packet_t * p_packets[INPUT_READ_ONCE] );
57 static void PSInit ( struct input_thread_s * );
58 static void PSEnd ( struct input_thread_s * );
59 static struct data_packet_s * NewPacket ( void *, size_t );
60 static void DeletePacket( void *, struct data_packet_s * );
61 static void DeletePES ( void *, struct pes_packet_s * );
64 * Data reading functions
67 /*****************************************************************************
68 * PSProbe: verifies that the stream is a PS stream
69 *****************************************************************************/
70 static int PSProbe( input_thread_t * p_input )
72 /* verify that the first three bytes are 0x000001, or unscramble and
77 /*****************************************************************************
78 * PSInit: initializes PS structures
79 *****************************************************************************/
80 static void PSInit( input_thread_t * p_input )
82 thread_ps_data_t * p_method;
83 stream_ps_data_t * p_demux;
86 (thread_ps_data_t *)malloc( sizeof(thread_ps_data_t) )) == NULL )
88 intf_ErrMsg( "Out of memory" );
93 p_input->p_method_data = (void *)p_method;
95 /* Re-open the socket as a buffered FILE stream */
96 if( (p_method->stream = fdopen( p_input->i_handle, "r" )) == NULL )
98 intf_ErrMsg( "Cannot open file (%s)", strerror(errno) );
102 fseek( p_method->stream, 0, SEEK_SET );
104 /* Pre-parse the stream to gather stream_descriptor_t. */
107 p_input->stream.pp_programs =
108 (pgrm_descriptor_t **)malloc( sizeof(pgrm_descriptor_t *) );
109 p_input->stream.pp_programs[0] =
110 (pgrm_descriptor_t *)malloc( sizeof(pgrm_descriptor_t) );
111 p_input->stream.pp_programs[0]->i_synchro_state = SYNCHRO_START;
112 p_input->stream.pp_programs[0]->delta_cr = 0;
113 p_input->stream.pp_programs[0]->last_cr = 0;
114 p_input->stream.pp_programs[0]->c_average_count = 0;
116 p_demux = (stream_ps_data_t *)malloc( sizeof( stream_ps_data_t) );
117 p_input->stream.p_demux_data = (void *)p_demux;
118 p_demux->b_is_PSM_complete = 0;
121 /*****************************************************************************
122 * PSEnd: frees unused data
123 *****************************************************************************/
124 static void PSEnd( input_thread_t * p_input )
126 free( p_input->stream.p_demux_data );
127 free( p_input->p_method_data );
130 /*****************************************************************************
131 * PSRead: reads a data packet
132 *****************************************************************************/
133 /* FIXME: read INPUT_READ_ONCE packet at once */
134 static void PSRead( input_thread_t * p_input,
135 data_packet_t * p_packets[INPUT_READ_ONCE] )
138 data_packet_t * p_data;
140 thread_ps_data_t * p_method;
142 p_method = (thread_ps_data_t *)p_input->p_method_data;
144 while( fread( p_header, 6, 1, p_method->stream ) != 1 )
147 if( (i_error = ferror( p_method->stream )) )
149 intf_ErrMsg( "Read 1 failed (%s)", strerror(i_error) );
150 p_input->b_error = 1;
154 if( feof( p_method->stream ) )
156 intf_ErrMsg( "EOF reached" );
157 p_input->b_error = 1;
162 if( (U32_AT(p_header) & 0xFFFFFF00) != 0x100L )
164 u32 i_buffer = U32_AT(p_header);
165 intf_ErrMsg( "Garbage at input (%x)\n", i_buffer );
166 while( (i_buffer & 0xFFFFFF00) != 0x100L )
169 i_buffer |= getc( p_method->stream );
170 if( feof(p_method->stream) || ferror(p_method->stream) )
172 p_input->b_error = 1;
176 *(u32 *)p_header = i_buffer;
177 fread( p_header + 4, 2, 1, p_method->stream );
180 if( U32_AT(p_header) != 0x1BA )
182 i_packet_size = U16_AT(&p_header[4]);
189 if( (p_data = NewPacket( p_input, i_packet_size + 6 )) == NULL )
191 p_input->b_error = 1;
192 intf_ErrMsg( "Out of memory" );
196 memcpy( p_data->p_buffer, p_header, 6 );
198 /* FIXME: catch EINTR ! */
199 while( fread( p_data->p_buffer + 6, i_packet_size,
200 1, p_method->stream ) != 1 )
203 if( (i_error = ferror( p_method->stream)) )
205 intf_ErrMsg( "Read 1 failed (%s)", strerror(i_error) );
206 p_input->b_error = 1;
210 if( feof( p_method->stream ) )
212 intf_ErrMsg( "EOF reached" );
213 p_input->b_error = 1;
218 if( U32_AT(p_header) == 0x1BA )
222 /* FIXME: catch EINTR ! */
223 if( (p_data->p_buffer[13] & 0x3) != 0 )
225 fread( p_garbage, p_garbage[0] & 0x3, 1,
230 memset( p_packets, 0, sizeof(p_packets) );
231 p_packets[0] = p_data;
236 * Packet management utilities
239 /*****************************************************************************
240 * NewPacket: allocates a data packet
241 *****************************************************************************/
242 static struct data_packet_s * NewPacket( void * p_garbage,
245 data_packet_t * p_data;
247 if( (p_data = (data_packet_t *)malloc( sizeof(data_packet_t) )) == NULL )
249 intf_DbgMsg( "Out of memory" );
253 if( (p_data->p_buffer = (byte_t *)malloc( i_size )) == NULL )
255 intf_DbgMsg( "Out of memory" );
260 p_data->p_payload_start = p_data->p_buffer;
261 p_data->p_payload_end = p_data->p_buffer + i_size;
266 /*****************************************************************************
267 * DeletePacket: deletes a data packet
268 *****************************************************************************/
269 static void DeletePacket( void * p_garbage,
270 data_packet_t * p_data )
273 ASSERT(p_data->p_buffer);
274 free( p_data->p_buffer );
278 /*****************************************************************************
279 * DeletePES: deletes a PES packet and associated data packets
280 *****************************************************************************/
281 static void DeletePES( void * p_garbage, pes_packet_t * p_pes )
283 data_packet_t * p_data;
284 data_packet_t * p_next;
286 p_data = p_pes->p_first;
288 while( p_data != NULL )
290 p_next = p_data->p_next;
291 free( p_data->p_buffer );
299 /*****************************************************************************
300 * PSKludge: fakes a PS plugin (FIXME)
301 *****************************************************************************/
302 input_capabilities_t * PSKludge( void )
304 input_capabilities_t * p_plugin;
306 p_plugin = (input_capabilities_t *)malloc( sizeof(input_capabilities_t) );
307 p_plugin->pf_init = PSInit;
308 p_plugin->pf_read = PSRead;
309 p_plugin->pf_demux = input_DemuxPS; /* FIXME: use i_p_config_t ! */
310 p_plugin->pf_new_packet = NewPacket;
311 p_plugin->pf_delete_packet = DeletePacket;
312 p_plugin->pf_delete_pes = DeletePES;
313 p_plugin->pf_rewind = NULL;
314 p_plugin->pf_seek = NULL;