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