00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdlib.h>
00024
00025 #include <vlc/vlc.h>
00026
00027 #include "asf.h"
00028 #include "buffer.h"
00029
00030
00031 static int CmpGuid( const guid_t *p_guid1, const guid_t *p_guid2 )
00032 {
00033 return( ( p_guid1->v1 == p_guid2->v1 &&
00034 p_guid1->v2 == p_guid2->v2 &&
00035 p_guid1->v3 == p_guid2->v3 &&
00036 p_guid1->v4[0] == p_guid2->v4[0] &&
00037 p_guid1->v4[1] == p_guid2->v4[1] &&
00038 p_guid1->v4[2] == p_guid2->v4[2] &&
00039 p_guid1->v4[3] == p_guid2->v4[3] &&
00040 p_guid1->v4[4] == p_guid2->v4[4] &&
00041 p_guid1->v4[5] == p_guid2->v4[5] &&
00042 p_guid1->v4[6] == p_guid2->v4[6] &&
00043 p_guid1->v4[7] == p_guid2->v4[7] ) ? 1 : 0 );
00044 }
00045
00046 void E_( GenerateGuid )( guid_t *p_guid )
00047 {
00048 int i;
00049
00050 srand( mdate() & 0xffffffff );
00051
00052
00053 p_guid->v1 = 0xbabac001;
00054 p_guid->v2 = ( (uint64_t)rand() << 16 ) / RAND_MAX;
00055 p_guid->v3 = ( (uint64_t)rand() << 16 ) / RAND_MAX;
00056 for( i = 0; i < 8; i++ )
00057 {
00058 p_guid->v4[i] = ( (uint64_t)rand() * 256 ) / RAND_MAX;
00059 }
00060 }
00061
00062 void E_( asf_HeaderParse )( asf_header_t *hdr,
00063 uint8_t *p_header, int i_header )
00064 {
00065 var_buffer_t buffer;
00066 guid_t guid;
00067 uint64_t i_size;
00068 int i;
00069
00070 hdr->i_file_size = 0;
00071 hdr->i_data_packets_count = 0;
00072 hdr->i_min_data_packet_size = 0;
00073 for( i = 0; i < 128; i++ )
00074 {
00075 hdr->stream[i].i_cat = ASF_STREAM_UNKNOWN;
00076 hdr->stream[i].i_selected = 0;
00077 hdr->stream[i].i_bitrate = -1;
00078 }
00079
00080
00081 var_buffer_initread( &buffer, p_header, i_header );
00082
00083 var_buffer_getguid( &buffer, &guid );
00084
00085 if( !CmpGuid( &guid, &asf_object_header_guid ) )
00086 {
00087
00088
00089 }
00090 var_buffer_getmemory( &buffer, NULL, 30 - 16 );
00091
00092 for( ;; )
00093 {
00094
00095
00096 var_buffer_getguid( &buffer, &guid );
00097 i_size = var_buffer_get64( &buffer );
00098
00099
00100
00101
00102
00103
00104
00105 if( CmpGuid( &guid, &asf_object_file_properties_guid ) )
00106 {
00107 var_buffer_getmemory( &buffer, NULL, 16 );
00108 hdr->i_file_size = var_buffer_get64( &buffer );
00109 var_buffer_getmemory( &buffer, NULL, 8 );
00110 hdr->i_data_packets_count = var_buffer_get64( &buffer );
00111 var_buffer_getmemory( &buffer, NULL, 8+8+8+4);
00112 hdr->i_min_data_packet_size = var_buffer_get32( &buffer );
00113
00114 var_buffer_getmemory( &buffer, NULL, i_size - 24 - 16 - 8 - 8 - 8 - 8-8-8-4 - 4);
00115 }
00116 else if( CmpGuid( &guid, &asf_object_header_extension_guid ) )
00117 {
00118
00119 var_buffer_getmemory( &buffer, NULL, 46 - 24 );
00120 }
00121 else if( CmpGuid( &guid, &asf_object_extended_stream_properties_guid ) )
00122 {
00123
00124 int16_t i_count1, i_count2;
00125 int i_subsize;
00126 int i;
00127
00128
00129
00130 var_buffer_getmemory( &buffer, NULL, 84 - 24 );
00131
00132 i_count1 = var_buffer_get16( &buffer );
00133 i_count2 = var_buffer_get16( &buffer );
00134
00135 i_subsize = 88;
00136 for( i = 0; i < i_count1; i++ )
00137 {
00138 int i_len;
00139
00140 var_buffer_get16( &buffer );
00141 i_len = var_buffer_get16( &buffer );
00142 var_buffer_getmemory( &buffer, NULL, i_len );
00143
00144 i_subsize = 4 + i_len;
00145 }
00146
00147 for( i = 0; i < i_count2; i++ )
00148 {
00149 int i_len;
00150 var_buffer_getmemory( &buffer, NULL, 16 + 2 );
00151 i_len = var_buffer_get32( &buffer );
00152 var_buffer_getmemory( &buffer, NULL, i_len );
00153
00154 i_subsize += 16 + 6 + i_len;
00155 }
00156
00157
00158
00159
00160 if( i_size - i_subsize <= 24 )
00161 {
00162 var_buffer_getmemory( &buffer, NULL, i_size - i_subsize );
00163 }
00164
00165
00166 }
00167 else if( CmpGuid( &guid, &asf_object_stream_properties_guid ) )
00168 {
00169 int i_stream_id;
00170 guid_t stream_type;
00171
00172
00173
00174 var_buffer_getguid( &buffer, &stream_type );
00175 var_buffer_getmemory( &buffer, NULL, 32 );
00176 i_stream_id = var_buffer_get8( &buffer ) & 0x7f;
00177
00178
00179 var_buffer_getmemory( &buffer, NULL, i_size - 24 - 32 - 16 - 1);
00180
00181 if( CmpGuid( &stream_type, &asf_object_stream_type_video ) )
00182 {
00183
00184 hdr->stream[i_stream_id].i_cat = ASF_STREAM_VIDEO;
00185 }
00186 else if( CmpGuid( &stream_type, &asf_object_stream_type_audio ) )
00187 {
00188
00189 hdr->stream[i_stream_id].i_cat = ASF_STREAM_AUDIO;
00190 }
00191 else
00192 {
00193 hdr->stream[i_stream_id].i_cat = ASF_STREAM_UNKNOWN;
00194 }
00195 }
00196 else if ( CmpGuid( &guid, &asf_object_bitrate_properties_guid ) )
00197 {
00198 int i_count;
00199 uint8_t i_stream_id;
00200
00201
00202
00203 i_count = var_buffer_get16( &buffer );
00204 i_size -= 2;
00205 while( i_count > 0 )
00206 {
00207 i_stream_id = var_buffer_get16( &buffer )&0x7f;
00208 hdr->stream[i_stream_id].i_bitrate = var_buffer_get32( &buffer );
00209 i_count--;
00210 i_size -= 6;
00211 }
00212
00213 var_buffer_getmemory( &buffer, NULL, i_size - 24 );
00214 }
00215 else
00216 {
00217
00218
00219
00220 var_buffer_getmemory( &buffer, NULL, i_size - 24 );
00221 }
00222
00223 if( var_buffer_readempty( &buffer ) )
00224 return;
00225 }
00226 }
00227
00228 void E_( asf_StreamSelect ) ( asf_header_t *hdr,
00229 int i_bitrate_max,
00230 vlc_bool_t b_all, vlc_bool_t b_audio, vlc_bool_t b_video )
00231 {
00232
00233 int i;
00234 int i_audio, i_video;
00235 int i_bitrate_total;
00236 #if 0
00237 char *psz_stream;
00238 #endif
00239
00240 i_audio = 0;
00241 i_video = 0;
00242 i_bitrate_total = 0;
00243 if( b_all )
00244 {
00245
00246 for( i = 1; i < 128; i++ )
00247 {
00248 if( hdr->stream[i].i_cat != ASF_STREAM_UNKNOWN )
00249 {
00250 hdr->stream[i].i_selected = 1;
00251 }
00252 }
00253 return;
00254 }
00255 else
00256 {
00257 for( i = 0; i < 128; i++ )
00258 {
00259 hdr->stream[i].i_selected = 0;
00260 }
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 for( i = 1; i < 128; i++ )
00277 {
00278 if( hdr->stream[i].i_cat == ASF_STREAM_UNKNOWN )
00279 {
00280 continue;
00281 }
00282 else if( hdr->stream[i].i_cat == ASF_STREAM_AUDIO && b_audio &&
00283 ( i_audio <= 0 ||
00284 ( ( ( hdr->stream[i].i_bitrate > hdr->stream[i_audio].i_bitrate &&
00285 ( i_bitrate_total + hdr->stream[i].i_bitrate - hdr->stream[i_audio].i_bitrate
00286 < i_bitrate_max || !i_bitrate_max) ) ||
00287 ( hdr->stream[i].i_bitrate < hdr->stream[i_audio].i_bitrate &&
00288 i_bitrate_max != 0 && i_bitrate_total > i_bitrate_max )
00289 ) ) ) )
00290 {
00291
00292 if( i_audio > 0 )
00293 {
00294 hdr->stream[i_audio].i_selected = 0;
00295 if( hdr->stream[i_audio].i_bitrate> 0 )
00296 {
00297 i_bitrate_total -= hdr->stream[i_audio].i_bitrate;
00298 }
00299 }
00300
00301 hdr->stream[i].i_selected = 1;
00302 if( hdr->stream[i].i_bitrate> 0 )
00303 {
00304 i_bitrate_total += hdr->stream[i].i_bitrate;
00305 }
00306 i_audio = i;
00307 }
00308 else if( hdr->stream[i].i_cat == ASF_STREAM_VIDEO && b_video &&
00309 ( i_video <= 0 ||
00310 (
00311 ( ( hdr->stream[i].i_bitrate > hdr->stream[i_video].i_bitrate &&
00312 ( i_bitrate_total + hdr->stream[i].i_bitrate - hdr->stream[i_video].i_bitrate
00313 < i_bitrate_max || !i_bitrate_max) ) ||
00314 ( hdr->stream[i].i_bitrate < hdr->stream[i_video].i_bitrate &&
00315 i_bitrate_max != 0 && i_bitrate_total > i_bitrate_max )
00316 ) ) ) )
00317 {
00318
00319
00320 if( i_video > 0 )
00321 {
00322 hdr->stream[i_video].i_selected = 0;
00323 if( hdr->stream[i_video].i_bitrate> 0 )
00324 {
00325 i_bitrate_total -= hdr->stream[i_video].i_bitrate;
00326 }
00327 }
00328
00329 hdr->stream[i].i_selected = 1;
00330 if( hdr->stream[i].i_bitrate> 0 )
00331 {
00332 i_bitrate_total += hdr->stream[i].i_bitrate;
00333 }
00334 i_video = i;
00335 }
00336
00337 }
00338 }
00339