00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdlib.h>
00028
00029 #include <vlc/vlc.h>
00030 #include <vlc/input.h>
00031 #include "vlc_codec.h"
00032
00033
00034
00035
00036 static int Open ( vlc_object_t * );
00037 static void Close( vlc_object_t * );
00038
00039 vlc_module_begin();
00040 set_category( CAT_INPUT );
00041 set_subcategory( SUBCAT_INPUT_DEMUX );
00042 set_description( _("MPEG-I/II video demuxer" ) );
00043 set_capability( "demux2", 100 );
00044 set_callbacks( Open, Close );
00045 add_shortcut( "mpgv" );
00046 vlc_module_end();
00047
00048
00049
00050
00051 struct demux_sys_t
00052 {
00053 vlc_bool_t b_start;
00054
00055 es_out_id_t *p_es;
00056
00057 decoder_t *p_packetizer;
00058 };
00059
00060 static int Demux( demux_t * );
00061 static int Control( demux_t *, int, va_list );
00062
00063 #define MPGV_PACKET_SIZE 4096
00064
00065
00066
00067
00068 static int Open( vlc_object_t * p_this )
00069 {
00070 demux_t *p_demux = (demux_t*)p_this;
00071 demux_sys_t *p_sys;
00072 vlc_bool_t b_forced = VLC_FALSE;
00073
00074 uint8_t *p_peek;
00075
00076 es_format_t fmt;
00077
00078 if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 )
00079 {
00080 msg_Err( p_demux, "cannot peek" );
00081 return VLC_EGENERIC;
00082 }
00083
00084 if( !strncmp( p_demux->psz_demux, "mpgv", 4 ) )
00085 {
00086 b_forced = VLC_TRUE;
00087 }
00088
00089 if( p_peek[0] != 0x00 || p_peek[1] != 0x00 || p_peek[2] != 0x01 )
00090 {
00091 if( !b_forced ) return VLC_EGENERIC;
00092
00093 msg_Err( p_demux, "this doesn't look like an MPEG ES stream, continuing" );
00094 }
00095
00096 if( p_peek[3] > 0xb9 )
00097 {
00098 if( !b_forced ) return VLC_EGENERIC;
00099 msg_Err( p_demux, "this seems to be a system stream (PS plug-in ?), but continuing" );
00100 }
00101
00102 p_demux->pf_demux = Demux;
00103 p_demux->pf_control= Control;
00104 p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
00105 p_sys->b_start = VLC_TRUE;
00106 p_sys->p_es = NULL;
00107
00108
00109
00110
00111 p_sys->p_packetizer = vlc_object_create( p_demux, VLC_OBJECT_PACKETIZER );
00112 p_sys->p_packetizer->pf_decode_audio = NULL;
00113 p_sys->p_packetizer->pf_decode_video = NULL;
00114 p_sys->p_packetizer->pf_decode_sub = NULL;
00115 p_sys->p_packetizer->pf_packetize = NULL;
00116 es_format_Init( &p_sys->p_packetizer->fmt_in, VIDEO_ES,
00117 VLC_FOURCC( 'm', 'p', 'g', 'v' ) );
00118 es_format_Init( &p_sys->p_packetizer->fmt_out, UNKNOWN_ES, 0 );
00119 p_sys->p_packetizer->p_module =
00120 module_Need( p_sys->p_packetizer, "packetizer", NULL, 0 );
00121
00122 if( p_sys->p_packetizer->p_module == NULL)
00123 {
00124 vlc_object_destroy( p_sys->p_packetizer );
00125 msg_Err( p_demux, "cannot find mpgv packetizer" );
00126 free( p_sys );
00127 return VLC_EGENERIC;
00128 }
00129
00130
00131
00132
00133 es_format_Init( &fmt, VIDEO_ES, VLC_FOURCC( 'm', 'p', 'g', 'v' ) );
00134 p_sys->p_es = es_out_Add( p_demux->out, &fmt );
00135
00136 return VLC_SUCCESS;
00137 }
00138
00139
00140
00141
00142 static void Close( vlc_object_t * p_this )
00143 {
00144 demux_t *p_demux = (demux_t*)p_this;
00145 demux_sys_t *p_sys = p_demux->p_sys;
00146
00147 module_Unneed( p_sys->p_packetizer, p_sys->p_packetizer->p_module );
00148 vlc_object_destroy( p_sys->p_packetizer );
00149
00150 free( p_sys );
00151 }
00152
00153
00154
00155
00156
00157
00158 static int Demux( demux_t *p_demux )
00159 {
00160 demux_sys_t *p_sys = p_demux->p_sys;
00161 block_t *p_block_in, *p_block_out;
00162
00163 if( ( p_block_in = stream_Block( p_demux->s, MPGV_PACKET_SIZE ) ) == NULL )
00164 {
00165 return 0;
00166 }
00167
00168 if( p_sys->b_start )
00169 {
00170 p_block_in->i_pts =
00171 p_block_in->i_dts = 1;
00172 }
00173 else
00174 {
00175 p_block_in->i_pts =
00176 p_block_in->i_dts = 0;
00177 }
00178
00179 while( (p_block_out = p_sys->p_packetizer->pf_packetize( p_sys->p_packetizer, &p_block_in )) )
00180 {
00181 p_sys->b_start = VLC_FALSE;
00182
00183 while( p_block_out )
00184 {
00185 block_t *p_next = p_block_out->p_next;
00186
00187 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
00188
00189 p_block_out->p_next = NULL;
00190 es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
00191
00192 p_block_out = p_next;
00193 }
00194 }
00195 return 1;
00196 }
00197
00198
00199
00200
00201 static int Control( demux_t *p_demux, int i_query, va_list args )
00202 {
00203
00204
00205 if( i_query == DEMUX_SET_TIME )
00206 return VLC_EGENERIC;
00207 else
00208 return demux2_vaControlHelper( p_demux->s,
00209 0, -1,
00210 0, 1, i_query, args );
00211 }
00212