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 #define FPS_TEXT N_("Frames per Second")
00040 #define FPS_LONGTEXT N_("Allows you to set the desired frame rate.")
00041
00042
00043 vlc_module_begin();
00044 set_shortname( "H264");
00045 set_category( CAT_INPUT );
00046 set_subcategory( SUBCAT_INPUT_DEMUX );
00047 set_description( _("H264 video demuxer" ) );
00048 set_capability( "demux2", 0 );
00049 add_float( "h264-fps", 25.0, NULL, FPS_TEXT, FPS_LONGTEXT, VLC_TRUE );
00050 set_callbacks( Open, Close );
00051 add_shortcut( "h264" );
00052 vlc_module_end();
00053
00054
00055
00056
00057 struct demux_sys_t
00058 {
00059 mtime_t i_dts;
00060 es_out_id_t *p_es;
00061
00062 float f_fps;
00063 decoder_t *p_packetizer;
00064 };
00065
00066 static int Demux( demux_t * );
00067 static int Control( demux_t *, int, va_list );
00068
00069 #define H264_PACKET_SIZE 2048
00070
00071
00072
00073
00074 static int Open( vlc_object_t * p_this )
00075 {
00076 demux_t *p_demux = (demux_t*)p_this;
00077 demux_sys_t *p_sys;
00078 vlc_bool_t b_forced = VLC_FALSE;
00079
00080 uint8_t *p_peek;
00081 vlc_value_t val;
00082
00083 if( stream_Peek( p_demux->s, &p_peek, 5 ) < 5 )
00084 {
00085 msg_Err( p_demux, "cannot peek" );
00086 return VLC_EGENERIC;
00087 }
00088
00089 if( !strncmp( p_demux->psz_demux, "h264", 4 ) )
00090 {
00091 b_forced = VLC_TRUE;
00092 }
00093
00094 if( p_peek[0] != 0x00 || p_peek[1] != 0x00 ||
00095 p_peek[2] != 0x00 || p_peek[3] != 0x01 ||
00096 (p_peek[4]&0x1F) != 7 )
00097 {
00098 if( !b_forced )
00099 {
00100 msg_Warn( p_demux, "h264 module discarded (no startcode)" );
00101 return VLC_EGENERIC;
00102 }
00103
00104 msg_Err( p_demux, "this doesn't look like a H264 ES stream, continuing" );
00105 }
00106
00107 p_demux->pf_demux = Demux;
00108 p_demux->pf_control= Control;
00109 p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
00110 p_sys->p_es = NULL;
00111 p_sys->i_dts = 1;
00112 var_Create( p_demux, "h264-fps", VLC_VAR_FLOAT|VLC_VAR_DOINHERIT );
00113 var_Get( p_demux, "h264-fps", &val );
00114 p_sys->f_fps = val.f_float;
00115 if( val.f_float < 0.001 )
00116 {
00117 p_sys->f_fps = 0.001;
00118 }
00119 msg_Dbg( p_demux, "using %.2f fps", p_sys->f_fps );
00120
00121
00122
00123
00124 p_sys->p_packetizer = vlc_object_create( p_demux, VLC_OBJECT_PACKETIZER );
00125 p_sys->p_packetizer->pf_decode_audio = NULL;
00126 p_sys->p_packetizer->pf_decode_video = NULL;
00127 p_sys->p_packetizer->pf_decode_sub = NULL;
00128 p_sys->p_packetizer->pf_packetize = NULL;
00129 es_format_Init( &p_sys->p_packetizer->fmt_in, VIDEO_ES,
00130 VLC_FOURCC( 'h', '2', '6', '4' ) );
00131 es_format_Init( &p_sys->p_packetizer->fmt_out, UNKNOWN_ES, 0 );
00132 p_sys->p_packetizer->p_module =
00133 module_Need( p_sys->p_packetizer, "packetizer", NULL, 0 );
00134
00135 if( p_sys->p_packetizer->p_module == NULL)
00136 {
00137 vlc_object_destroy( p_sys->p_packetizer );
00138 msg_Err( p_demux, "cannot find mp4v packetizer" );
00139 free( p_sys );
00140 return VLC_EGENERIC;
00141 }
00142
00143 return VLC_SUCCESS;
00144 }
00145
00146
00147
00148
00149 static void Close( vlc_object_t * p_this )
00150 {
00151 demux_t *p_demux = (demux_t*)p_this;
00152 demux_sys_t *p_sys = p_demux->p_sys;
00153
00154 module_Unneed( p_sys->p_packetizer, p_sys->p_packetizer->p_module );
00155 vlc_object_destroy( p_sys->p_packetizer );
00156
00157 free( p_sys );
00158 }
00159
00160
00161
00162
00163
00164
00165 static int Demux( demux_t *p_demux)
00166 {
00167 demux_sys_t *p_sys = p_demux->p_sys;
00168 block_t *p_block_in, *p_block_out;
00169
00170 if( ( p_block_in = stream_Block( p_demux->s, H264_PACKET_SIZE ) ) == NULL )
00171 {
00172 return 0;
00173 }
00174
00175
00176 p_block_in->i_dts = 1;
00177 p_block_in->i_pts = 1;
00178
00179 while( (p_block_out = p_sys->p_packetizer->pf_packetize( p_sys->p_packetizer, &p_block_in )) )
00180 {
00181 while( p_block_out )
00182 {
00183 block_t *p_next = p_block_out->p_next;
00184
00185 p_block_out->p_next = NULL;
00186
00187 if( p_sys->p_es == NULL )
00188 {
00189 p_sys->p_packetizer->fmt_out.b_packetized = VLC_TRUE;
00190 p_sys->p_es = es_out_Add( p_demux->out, &p_sys->p_packetizer->fmt_out);
00191 }
00192
00193 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_dts );
00194 p_block_out->i_dts = p_sys->i_dts;
00195 p_block_out->i_pts = p_sys->i_dts;
00196
00197 es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
00198
00199 p_block_out = p_next;
00200
00201 p_sys->i_dts += (int64_t)((double)1000000.0 / p_sys->f_fps);
00202 }
00203 }
00204 return 1;
00205 }
00206
00207
00208
00209
00210 static int Control( demux_t *p_demux, int i_query, va_list args )
00211 {
00212
00213
00214 if( i_query == DEMUX_SET_TIME )
00215 return VLC_EGENERIC;
00216 else
00217 return demux2_vaControlHelper( p_demux->s,
00218 0, -1,
00219 0, 1, i_query, args );
00220 }
00221