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
00028 #include <stdlib.h>
00029 #include <ctype.h>
00030 #include <vlc/vlc.h>
00031 #include <vlc/input.h>
00032 #include <vlc_playlist.h>
00033
00034 #define MAX_LINE 16024
00035
00036
00037
00038
00039 static int DemuxOpen ( vlc_object_t * );
00040 static void DemuxClose ( vlc_object_t * );
00041
00042 vlc_module_begin();
00043 set_description( _("Windows Media NSC metademux") );
00044 set_category( CAT_INPUT );
00045 set_subcategory( SUBCAT_INPUT_DEMUX );
00046 set_capability( "demux2", 2 );
00047 set_callbacks( DemuxOpen, DemuxClose );
00048 vlc_module_end();
00049
00050 static int Demux ( demux_t *p_demux );
00051 static int Control( demux_t *p_demux, int i_query, va_list args );
00052
00053 static const unsigned char inverse[ 128 ] =
00054 {
00055 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00056 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00057 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00058 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00059 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF,
00060 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
00061 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C,
00062 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00063 0xFF, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E,
00064 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
00065 0x3B, 0x3C, 0x3D, 0x3E, 0xFF, 0x3F, 0xFF, 0xFF
00066 };
00067
00068 static int load_byte( unsigned char encoding_type,
00069 unsigned char *output, char **input,
00070 unsigned char *j, unsigned char *k )
00071 {
00072 *output = 0;
00073
00074 if( encoding_type == 1 )
00075 {
00076 if( isxdigit( **input ) == 0 )
00077 return -1;
00078
00079 if( isdigit( **input ) == 0 )
00080 *output = (toupper( **input ) - 7) * 16;
00081 else
00082 *output = **input * 16;
00083
00084 (*input)++;
00085
00086 if( isxdigit( **input ) == 0 )
00087 return -1;
00088
00089 if( isdigit( **input ) == 0 )
00090 *output |= toupper( **input ) - 0x37;
00091 else
00092 *output |= **input - 0x30;
00093
00094 (*input)++;
00095 }
00096 else if( encoding_type == 2 )
00097 {
00098 unsigned char **uinput = (unsigned char **)input;
00099
00100 if( **uinput > 127 || inverse[ **uinput ] == 0xFF )
00101 return -1;
00102
00103 if( *k == 0 )
00104 {
00105 if( (*uinput)[ 1 ] > 127 || inverse[ (*uinput)[ 1 ] ] == 0xFF )
00106 return -1;
00107
00108 *output = (inverse[ (*uinput)[ 0 ] ] * 4) |
00109 (inverse[ (*uinput)[ 1 ] ] / 16);
00110
00111 *j = inverse[ (*uinput)[ 1 ] ] * 16;
00112 *k = 4;
00113
00114 (*uinput) += 2;
00115 }
00116 else if( *k == 2 )
00117 {
00118 *output = *j | inverse[ **uinput ];
00119
00120 *j = 0;
00121 *k = 0;
00122
00123 (*uinput)++;
00124 }
00125 else if( *k == 4 )
00126 {
00127 *output = (inverse[ **uinput ] / 4) | *j;
00128
00129 *j = inverse[ **uinput ] * 64;
00130 *k = 2;
00131
00132 (*uinput)++;
00133 }
00134 }
00135
00136 return 0;
00137 }
00138
00139 char *nscdec( vlc_object_t *p_demux, char* p_encoded )
00140 {
00141 unsigned int i;
00142 unsigned char tmp;
00143 unsigned char j, k;
00144 unsigned int length;
00145 unsigned char encoding_type;
00146
00147 vlc_iconv_t conv;
00148 size_t buf16_size;
00149 unsigned char *buf16;
00150 char *p_buf16;
00151 size_t buf8_size;
00152 char *buf8;
00153 char *p_buf8;
00154
00155 char *p_input = p_encoded;
00156
00157 if( strlen( p_input ) < 15 )
00158 {
00159 msg_Err( p_demux, "input string less than 15 characters" );
00160 return NULL;
00161 }
00162
00163 if( load_byte( 1, &encoding_type, &p_input, NULL, NULL ) )
00164 {
00165 msg_Err( p_demux, "unable to get NSC encoding type" );
00166 return NULL;
00167 }
00168
00169 if( encoding_type != 1 && encoding_type != 2 )
00170 {
00171 msg_Err( p_demux, "encoding type %d is not supported",
00172 encoding_type );
00173 return NULL;
00174 }
00175
00176 j = k = 0;
00177
00178 if( load_byte( encoding_type, &tmp, &p_input, &j, &k ) )
00179 {
00180 msg_Err( p_demux, "load_byte failed" );
00181 return NULL;
00182 }
00183
00184 for( i = 0; i < 4; i++ )
00185 {
00186 if( load_byte( encoding_type, &tmp, &p_input, &j, &k ) )
00187 {
00188 msg_Err( p_demux, "load_byte failed" );
00189 return NULL;
00190 }
00191 }
00192
00193 length = 0;
00194 for( i = 4; i; i-- )
00195 {
00196 if( load_byte( encoding_type, &tmp, &p_input, &j, &k ) )
00197 {
00198 msg_Err( p_demux, "load_byte failed" );
00199 return NULL;
00200 }
00201 length |= tmp << ((i - 1) * 8);
00202 }
00203
00204 if( length == 0 )
00205 {
00206 msg_Err( p_demux, "Length is 0" );
00207 return NULL;
00208 }
00209
00210 buf16_size = length;
00211 buf16 = (unsigned char *)malloc( buf16_size );
00212 if( buf16 == NULL )
00213 {
00214 msg_Err( p_demux, "Out of memory" );
00215 return NULL;
00216 }
00217
00218 for( i = 0; i < length; i++ )
00219 {
00220 if( load_byte( encoding_type, &buf16[ i ], &p_input, &j, &k ) )
00221 {
00222 msg_Err( p_demux, "load_byte failed" );
00223 free( (void *)buf16 );
00224 return NULL;
00225 }
00226 }
00227
00228 buf8_size = length;
00229 buf8 = (char *)malloc( buf8_size + 1 );
00230 if( buf8 == NULL )
00231 {
00232 msg_Err( p_demux, "Out of memory" );
00233 free( (void *)buf16 );
00234 return NULL;
00235 }
00236
00237 conv = vlc_iconv_open( "UTF-8", "UTF-16LE" );
00238 if( conv == (vlc_iconv_t)-1 )
00239 {
00240 msg_Err( p_demux, "iconv_open failed" );
00241 free( (void *)buf16 );
00242 free( (void *)buf8 );
00243 return NULL;
00244 }
00245
00246 p_buf8 = &buf8[ 0 ];
00247 p_buf16 = (char *)&buf16[ 0 ];
00248
00249 if( vlc_iconv( conv, &p_buf16, &buf16_size, &p_buf8, &buf8_size ) < 0 )
00250 {
00251 msg_Err( p_demux, "iconv failed" );
00252 return NULL;
00253 }
00254 else
00255 {
00256 buf8[ length - buf8_size ] = '\0';
00257 }
00258
00259 vlc_iconv_close( conv );
00260
00261 free( (void *)buf16 );
00262 return buf8;
00263 }
00264
00265 static int DemuxOpen( vlc_object_t * p_this )
00266 {
00267 demux_t *p_demux = (demux_t *)p_this;
00268 byte_t *p_peek;
00269 int i_size;
00270
00271
00272 i_size = stream_Peek( p_demux->s, &p_peek, MAX_LINE );
00273 i_size -= sizeof("NSC Format Version=") - 1;
00274
00275 if ( i_size > 0 )
00276 {
00277 while ( i_size && strncasecmp( p_peek, "NSC Format Version=",
00278 (int) sizeof("NSC Format Version=") - 1 ) )
00279 {
00280 p_peek++;
00281 i_size--;
00282 }
00283 if ( !strncasecmp( p_peek, "NSC Format Version=",
00284 (int) sizeof("NSC Format Version=") -1 ) )
00285 {
00286 p_demux->pf_demux = Demux;
00287 p_demux->pf_control = Control;
00288 return VLC_SUCCESS;
00289 }
00290 }
00291 return VLC_EGENERIC;
00292 }
00293
00294
00295
00296
00297
00298 static void DemuxClose( vlc_object_t *p_this )
00299 {
00300 return;
00301 }
00302
00303 static int ParseLine ( demux_t *p_demux, char *psz_line )
00304 {
00305 char *psz_bol;
00306 char *psz_value;
00307
00308 psz_bol = psz_line;
00309
00310 while( *psz_bol == ' ' || *psz_bol == '\t' ||
00311 *psz_bol == '\n' || *psz_bol == '\r' )
00312 {
00313 psz_bol++;
00314 }
00315 psz_value = strchr( psz_bol, '=' );
00316 if( psz_value == NULL )
00317 {
00318 return 0;
00319 }
00320 *psz_value = '\0';
00321 psz_value++;
00322
00323 if( !strncasecmp( psz_value, "0x", 2 ) )
00324 {
00325 int i_value;
00326 sscanf( psz_value, "%x", &i_value );
00327 msg_Dbg( p_demux, "%s = %d", psz_bol, i_value );
00328 }
00329 else if( !strncasecmp( psz_bol, "Format", 6 ) )
00330 {
00331 msg_Dbg( p_demux, "%s = asf header", psz_bol );
00332 }
00333 else
00334 {
00335
00336 char *psz_out;
00337 psz_out = nscdec( (vlc_object_t *)p_demux, psz_value );
00338 if( psz_out )
00339 {
00340 msg_Dbg( p_demux, "%s = %s", psz_bol, psz_out );
00341 if( psz_out) free( psz_out );
00342 }
00343 }
00344 return VLC_SUCCESS;
00345 }
00346
00347
00348
00349
00350
00351
00352 static int Demux ( demux_t *p_demux )
00353 {
00354 char *psz_line;
00355
00356 while( ( psz_line = stream_ReadLine( p_demux->s ) ) )
00357 {
00358 ParseLine( p_demux, psz_line );
00359 if( psz_line ) free( psz_line );
00360 }
00361 return VLC_SUCCESS;
00362 }
00363
00364 static int Control( demux_t *p_demux, int i_query, va_list args )
00365 {
00366 return VLC_EGENERIC;
00367 }