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