00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _VLC_BLOCK_HELPER_H
00025 #define _VLC_BLOCK_HELPER_H 1
00026
00027 typedef struct block_bytestream_t
00028 {
00029 block_t *p_chain;
00030 block_t *p_block;
00031 int i_offset;
00032
00033 } block_bytestream_t;
00034
00035 #define block_BytestreamInit( a ) __block_BytestreamInit( VLC_OBJECT(a) )
00036
00037
00038
00039
00040 static inline block_bytestream_t __block_BytestreamInit( vlc_object_t *p_obj )
00041 {
00042 block_bytestream_t bytestream;
00043
00044 bytestream.i_offset = 0;
00045 bytestream.p_chain = bytestream.p_block = NULL;
00046
00047 return bytestream;
00048 }
00049
00050 static inline void block_BytestreamRelease( block_bytestream_t *p_bytestream )
00051 {
00052 while( p_bytestream->p_chain )
00053 {
00054 block_t *p_next;
00055 p_next = p_bytestream->p_chain->p_next;
00056 p_bytestream->p_chain->pf_release( p_bytestream->p_chain );
00057 p_bytestream->p_chain = p_next;
00058 }
00059 p_bytestream->i_offset = 0;
00060 p_bytestream->p_chain = p_bytestream->p_block = NULL;
00061 }
00062
00063 static inline void block_BytestreamFlush( block_bytestream_t *p_bytestream )
00064 {
00065 while( p_bytestream->p_chain != p_bytestream->p_block )
00066 {
00067 block_t *p_next;
00068 p_next = p_bytestream->p_chain->p_next;
00069 p_bytestream->p_chain->pf_release( p_bytestream->p_chain );
00070 p_bytestream->p_chain = p_next;
00071 }
00072 while( p_bytestream->p_block &&
00073 (p_bytestream->p_block->i_buffer - p_bytestream->i_offset) == 0 )
00074 {
00075 block_t *p_next;
00076 p_next = p_bytestream->p_chain->p_next;
00077 p_bytestream->p_chain->pf_release( p_bytestream->p_chain );
00078 p_bytestream->p_chain = p_bytestream->p_block = p_next;
00079 p_bytestream->i_offset = 0;
00080 }
00081 }
00082
00083 static inline void block_BytestreamPush( block_bytestream_t *p_bytestream,
00084 block_t *p_block )
00085 {
00086 block_ChainAppend( &p_bytestream->p_chain, p_block );
00087 if( !p_bytestream->p_block ) p_bytestream->p_block = p_block;
00088 }
00089
00090 static inline block_t *block_BytestreamPop( block_bytestream_t *p_bytestream )
00091 {
00092 block_t *p_block;
00093
00094 block_BytestreamFlush( p_bytestream );
00095
00096 p_block = p_bytestream->p_block;
00097 if( p_block == NULL )
00098 {
00099 return NULL;
00100 }
00101 else if( !p_block->p_next )
00102 {
00103 p_block->p_buffer += p_bytestream->i_offset;
00104 p_block->i_buffer -= p_bytestream->i_offset;
00105 p_bytestream->i_offset = 0;
00106 p_bytestream->p_chain = p_bytestream->p_block = NULL;
00107 return p_block;
00108 }
00109
00110 while( p_block->p_next && p_block->p_next->p_next )
00111 p_block = p_block->p_next;
00112
00113 {
00114 block_t *p_block_old = p_block;
00115 p_block = p_block->p_next;
00116 p_block_old->p_next = NULL;
00117 }
00118
00119 return p_block;
00120 }
00121
00122 static inline int block_SkipByte( block_bytestream_t *p_bytestream )
00123 {
00124
00125 if( p_bytestream->p_block->i_buffer - p_bytestream->i_offset )
00126 {
00127 p_bytestream->i_offset++;
00128 return VLC_SUCCESS;
00129 }
00130 else
00131 {
00132 block_t *p_block;
00133
00134
00135 for( p_block = p_bytestream->p_block->p_next;
00136 p_block != NULL; p_block = p_block->p_next )
00137 {
00138 if( p_block->i_buffer )
00139 {
00140 p_bytestream->i_offset = 1;
00141 p_bytestream->p_block = p_block;
00142 return VLC_SUCCESS;
00143 }
00144 }
00145 }
00146
00147
00148 return VLC_EGENERIC;
00149 }
00150
00151 static inline int block_PeekByte( block_bytestream_t *p_bytestream,
00152 uint8_t *p_data )
00153 {
00154
00155 if( p_bytestream->p_block->i_buffer - p_bytestream->i_offset )
00156 {
00157 *p_data = p_bytestream->p_block->p_buffer[p_bytestream->i_offset];
00158 return VLC_SUCCESS;
00159 }
00160 else
00161 {
00162 block_t *p_block;
00163
00164
00165 for( p_block = p_bytestream->p_block->p_next;
00166 p_block != NULL; p_block = p_block->p_next )
00167 {
00168 if( p_block->i_buffer )
00169 {
00170 *p_data = p_block->p_buffer[0];
00171 return VLC_SUCCESS;
00172 }
00173 }
00174 }
00175
00176
00177 return VLC_EGENERIC;
00178 }
00179
00180 static inline int block_GetByte( block_bytestream_t *p_bytestream,
00181 uint8_t *p_data )
00182 {
00183
00184 if( p_bytestream->p_block->i_buffer - p_bytestream->i_offset )
00185 {
00186 *p_data = p_bytestream->p_block->p_buffer[p_bytestream->i_offset];
00187 p_bytestream->i_offset++;
00188 return VLC_SUCCESS;
00189 }
00190 else
00191 {
00192 block_t *p_block;
00193
00194
00195 for( p_block = p_bytestream->p_block->p_next;
00196 p_block != NULL; p_block = p_block->p_next )
00197 {
00198 if( p_block->i_buffer )
00199 {
00200 *p_data = p_block->p_buffer[0];
00201 p_bytestream->i_offset = 1;
00202 p_bytestream->p_block = p_block;
00203 return VLC_SUCCESS;
00204 }
00205 }
00206 }
00207
00208
00209 return VLC_EGENERIC;
00210 }
00211
00212 static inline int block_WaitBytes( block_bytestream_t *p_bytestream,
00213 int i_data )
00214 {
00215 block_t *p_block;
00216 int i_offset, i_copy, i_size;
00217
00218
00219 i_offset = p_bytestream->i_offset;
00220 i_size = i_data;
00221 i_copy = 0;
00222 for( p_block = p_bytestream->p_block;
00223 p_block != NULL; p_block = p_block->p_next )
00224 {
00225 i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
00226 i_size -= i_copy;
00227 i_offset = 0;
00228
00229 if( !i_size ) break;
00230 }
00231
00232 if( i_size )
00233 {
00234
00235 return VLC_EGENERIC;
00236 }
00237 return VLC_SUCCESS;
00238 }
00239
00240 static inline int block_SkipBytes( block_bytestream_t *p_bytestream,
00241 int i_data )
00242 {
00243 block_t *p_block;
00244 int i_offset, i_copy;
00245
00246
00247 i_offset = p_bytestream->i_offset;
00248 i_copy = 0;
00249 for( p_block = p_bytestream->p_block;
00250 p_block != NULL; p_block = p_block->p_next )
00251 {
00252 i_copy = __MIN( i_data, p_block->i_buffer - i_offset );
00253 i_data -= i_copy;
00254
00255 if( !i_data ) break;
00256
00257 i_offset = 0;
00258 }
00259
00260 if( i_data )
00261 {
00262
00263 return VLC_EGENERIC;
00264 }
00265
00266 p_bytestream->p_block = p_block;
00267 p_bytestream->i_offset = i_offset + i_copy;
00268 return VLC_SUCCESS;
00269 }
00270
00271 static inline int block_PeekBytes( block_bytestream_t *p_bytestream,
00272 uint8_t *p_data, int i_data )
00273 {
00274 block_t *p_block;
00275 int i_offset, i_copy, i_size;
00276
00277
00278 i_offset = p_bytestream->i_offset;
00279 i_size = i_data;
00280 i_copy = 0;
00281 for( p_block = p_bytestream->p_block;
00282 p_block != NULL; p_block = p_block->p_next )
00283 {
00284 i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
00285 i_size -= i_copy;
00286 i_offset = 0;
00287
00288 if( !i_size ) break;
00289 }
00290
00291 if( i_size )
00292 {
00293
00294 return VLC_EGENERIC;
00295 }
00296
00297
00298 i_offset = p_bytestream->i_offset;
00299 i_size = i_data;
00300 i_copy = 0;
00301 for( p_block = p_bytestream->p_block;
00302 p_block != NULL; p_block = p_block->p_next )
00303 {
00304 i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
00305 i_size -= i_copy;
00306
00307 if( i_copy )
00308 {
00309 memcpy( p_data, p_block->p_buffer + i_offset, i_copy );
00310 p_data += i_copy;
00311 }
00312
00313 i_offset = 0;
00314
00315 if( !i_size ) break;
00316 }
00317
00318 return VLC_SUCCESS;
00319 }
00320
00321 static inline int block_GetBytes( block_bytestream_t *p_bytestream,
00322 uint8_t *p_data, int i_data )
00323 {
00324 block_t *p_block;
00325 int i_offset, i_copy, i_size;
00326
00327
00328 i_offset = p_bytestream->i_offset;
00329 i_size = i_data;
00330 i_copy = 0;
00331 for( p_block = p_bytestream->p_block;
00332 p_block != NULL; p_block = p_block->p_next )
00333 {
00334 i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
00335 i_size -= i_copy;
00336 i_offset = 0;
00337
00338 if( !i_size ) break;
00339 }
00340
00341 if( i_size )
00342 {
00343
00344 return VLC_EGENERIC;
00345 }
00346
00347
00348 i_offset = p_bytestream->i_offset;
00349 i_size = i_data;
00350 i_copy = 0;
00351 for( p_block = p_bytestream->p_block;
00352 p_block != NULL; p_block = p_block->p_next )
00353 {
00354 i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
00355 i_size -= i_copy;
00356
00357 if( i_copy )
00358 {
00359 memcpy( p_data, p_block->p_buffer + i_offset, i_copy );
00360 p_data += i_copy;
00361 }
00362
00363 if( !i_size ) break;
00364
00365 i_offset = 0;
00366 }
00367
00368
00369 p_bytestream->p_block = p_block;
00370 p_bytestream->i_offset = i_offset + i_copy;
00371
00372 return VLC_SUCCESS;
00373 }
00374
00375 static inline int block_PeekOffsetBytes( block_bytestream_t *p_bytestream,
00376 int i_peek_offset, uint8_t *p_data, int i_data )
00377 {
00378 block_t *p_block;
00379 int i_offset, i_copy, i_size;
00380
00381
00382 i_offset = p_bytestream->i_offset;
00383 i_size = i_data + i_peek_offset;
00384 i_copy = 0;
00385 for( p_block = p_bytestream->p_block;
00386 p_block != NULL; p_block = p_block->p_next )
00387 {
00388 i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
00389 i_size -= i_copy;
00390 i_offset = 0;
00391
00392 if( !i_size ) break;
00393 }
00394
00395 if( i_size )
00396 {
00397
00398 return VLC_EGENERIC;
00399 }
00400
00401
00402 i_offset = p_bytestream->i_offset;
00403 i_size = i_peek_offset;
00404 i_copy = 0;
00405 for( p_block = p_bytestream->p_block;
00406 p_block != NULL; p_block = p_block->p_next )
00407 {
00408 i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
00409 i_size -= i_copy;
00410
00411 if( !i_size ) break;
00412
00413 i_offset = 0;
00414 }
00415
00416
00417 i_offset += i_copy;
00418 i_size = i_data;
00419 i_copy = 0;
00420 for( ; p_block != NULL; p_block = p_block->p_next )
00421 {
00422 i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
00423 i_size -= i_copy;
00424
00425 if( i_copy )
00426 {
00427 memcpy( p_data, p_block->p_buffer + i_offset, i_copy );
00428 p_data += i_copy;
00429 }
00430
00431 i_offset = 0;
00432
00433 if( !i_size ) break;
00434 }
00435
00436 return VLC_SUCCESS;
00437 }
00438
00439 static inline int block_FindStartcodeFromOffset(
00440 block_bytestream_t *p_bytestream, int *pi_offset,
00441 uint8_t *p_startcode, int i_startcode_length )
00442 {
00443 block_t *p_block, *p_block_backup = 0;
00444 int i_size, i_offset, i_offset_backup = 0;
00445 int i_caller_offset_backup = 0, i_match;
00446
00447
00448 i_size = *pi_offset + p_bytestream->i_offset;
00449 for( p_block = p_bytestream->p_block;
00450 p_block != NULL; p_block = p_block->p_next )
00451 {
00452 i_size -= p_block->i_buffer;
00453 if( i_size < 0 ) break;
00454 }
00455
00456 if( i_size >= 0 )
00457 {
00458
00459 return VLC_EGENERIC;
00460 }
00461
00462
00463
00464
00465 i_size = p_block->i_buffer + i_size;
00466 *pi_offset -= i_size;
00467 i_match = 0;
00468 for( ; p_block != NULL; p_block = p_block->p_next )
00469 {
00470 for( i_offset = i_size; i_offset < p_block->i_buffer; i_offset++ )
00471 {
00472 if( p_block->p_buffer[i_offset] == p_startcode[i_match] )
00473 {
00474 if( !i_match )
00475 {
00476 p_block_backup = p_block;
00477 i_offset_backup = i_offset;
00478 i_caller_offset_backup = *pi_offset;
00479 }
00480
00481 if( i_match + 1 == i_startcode_length )
00482 {
00483
00484 *pi_offset += i_offset - i_match;
00485 return VLC_SUCCESS;
00486 }
00487
00488 i_match++;
00489 }
00490 else if ( i_match )
00491 {
00492
00493 p_block = p_block_backup;
00494 i_offset = i_offset_backup;
00495 *pi_offset = i_caller_offset_backup;
00496 i_match = 0;
00497 }
00498
00499 }
00500 i_size = 0;
00501 *pi_offset += i_offset;
00502 }
00503
00504 *pi_offset -= i_match;
00505 return VLC_EGENERIC;
00506 }
00507
00508 #endif