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-4 audio demuxer" ) );
00043 set_capability( "demux2", 110 );
00044 set_callbacks( Open, Close );
00045 add_shortcut( "m4a" );
00046 add_shortcut( "mp4a" );
00047 add_shortcut( "aac" );
00048 vlc_module_end();
00049
00050
00051
00052
00053 struct demux_sys_t
00054 {
00055 vlc_bool_t b_start;
00056 es_out_id_t *p_es;
00057
00058 decoder_t *p_packetizer;
00059 };
00060
00061 static int Demux( demux_t * );
00062 static int Control( demux_t *, int, va_list );
00063
00064 #define M4A_PACKET_SIZE 4096
00065
00066
00067
00068
00069 static int Open( vlc_object_t * p_this )
00070 {
00071 demux_t *p_demux = (demux_t*)p_this;
00072 demux_sys_t *p_sys;
00073 uint8_t *p_peek;
00074 int b_forced = VLC_FALSE;
00075
00076 if( p_demux->psz_path )
00077 {
00078 int i_len = strlen( p_demux->psz_path );
00079
00080 if( i_len > 4 && !strcasecmp( &p_demux->psz_path[i_len - 4], ".aac" ) )
00081 {
00082 b_forced = VLC_TRUE;
00083 }
00084 }
00085
00086 if( !p_demux->b_force && !b_forced )
00087 {
00088 return VLC_EGENERIC;
00089 }
00090
00091
00092 if( stream_Peek( p_demux->s, &p_peek, 10 ) < 10 )
00093 {
00094 msg_Err( p_demux, "cannot peek" );
00095 return VLC_EGENERIC;
00096 }
00097 if( !strncmp( (char *)p_peek, "ADIF", 4 ) )
00098 {
00099 msg_Err( p_demux, "ADIF file. Not yet supported. (Please report)" );
00100 return VLC_EGENERIC;
00101 }
00102
00103 p_demux->pf_demux = Demux;
00104 p_demux->pf_control= Control;
00105 p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
00106 p_sys->p_es = NULL;
00107 p_sys->b_start = VLC_TRUE;
00108
00109
00110
00111
00112 p_sys->p_packetizer = vlc_object_create( p_demux, VLC_OBJECT_PACKETIZER );
00113 p_sys->p_packetizer->pf_decode_audio = NULL;
00114 p_sys->p_packetizer->pf_decode_video = NULL;
00115 p_sys->p_packetizer->pf_decode_sub = NULL;
00116 p_sys->p_packetizer->pf_packetize = NULL;
00117 es_format_Init( &p_sys->p_packetizer->fmt_in, AUDIO_ES,
00118 VLC_FOURCC( 'm', 'p', '4', 'a' ) );
00119 es_format_Init( &p_sys->p_packetizer->fmt_out, UNKNOWN_ES, 0 );
00120 p_sys->p_packetizer->p_module =
00121 module_Need( p_sys->p_packetizer, "packetizer", NULL, 0 );
00122
00123 if( p_sys->p_packetizer->p_module == NULL)
00124 {
00125 vlc_object_destroy( p_sys->p_packetizer );
00126 msg_Err( p_demux, "cannot find mp4a packetizer" );
00127 free( p_sys );
00128 return VLC_EGENERIC;
00129 }
00130
00131 return VLC_SUCCESS;
00132 }
00133
00134
00135
00136
00137 static void Close( vlc_object_t * p_this )
00138 {
00139 demux_t *p_demux = (demux_t*)p_this;
00140 demux_sys_t *p_sys = p_demux->p_sys;
00141
00142 module_Unneed( p_sys->p_packetizer, p_sys->p_packetizer->p_module );
00143 vlc_object_destroy( p_sys->p_packetizer );
00144
00145 free( p_sys );
00146 }
00147
00148
00149
00150
00151
00152
00153 static int Demux( demux_t *p_demux)
00154 {
00155 demux_sys_t *p_sys = p_demux->p_sys;
00156 block_t *p_block_in, *p_block_out;
00157
00158 if( ( p_block_in = stream_Block( p_demux->s, M4A_PACKET_SIZE ) ) == NULL )
00159 {
00160 return 0;
00161 }
00162
00163 p_block_in->i_pts = p_block_in->i_dts = p_sys->b_start ? 1 : 0;
00164 p_sys->b_start = VLC_FALSE;
00165
00166 while( (p_block_out = p_sys->p_packetizer->pf_packetize(
00167 p_sys->p_packetizer, &p_block_in )) )
00168 {
00169 while( p_block_out )
00170 {
00171 block_t *p_next = p_block_out->p_next;
00172
00173 if( p_sys->p_es == NULL )
00174 {
00175 p_sys->p_packetizer->fmt_out.b_packetized = VLC_TRUE;
00176 p_sys->p_es = es_out_Add( p_demux->out,
00177 &p_sys->p_packetizer->fmt_out);
00178 }
00179
00180 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
00181
00182 p_block_out->p_next = NULL;
00183 es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
00184
00185 p_block_out = p_next;
00186 }
00187 }
00188 return 1;
00189 }
00190
00191
00192
00193
00194 static int Control( demux_t *p_demux, int i_query, va_list args )
00195 {
00196 if( i_query == DEMUX_SET_TIME ) return VLC_EGENERIC;
00197 else return demux2_vaControlHelper( p_demux->s, 0, -1,
00198 0, 1, i_query, args );
00199 }