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