00001 /***************************************************************************** 00002 * vlc_block.h: Data blocks management functions 00003 ***************************************************************************** 00004 * Copyright (C) 2003 the VideoLAN team 00005 * $Id$ 00006 * 00007 * Authors: Laurent Aimar <fenrir@via.ecp.fr> 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 00022 *****************************************************************************/ 00023 00024 #ifndef VLC_BLOCK_H 00025 #define VLC_BLOCK_H 1 00026 00027 /**************************************************************************** 00028 * block: 00029 **************************************************************************** 00030 * - block_sys_t is opaque and thus block_t->p_sys is PRIVATE 00031 * - i_flags may not always be set (ie could be 0, even for a key frame 00032 * it depends where you receive the buffer (before/after a packetizer 00033 * and the demux/packetizer implementations. 00034 * - i_dts/i_pts could be 0, it means no pts 00035 * - i_length: length in microseond of the packet, can be null except in the 00036 * sout where it is mandatory. 00037 * - i_rate 0 or a valid input rate, look at vlc_input.h 00038 * 00039 * - i_buffer number of valid data pointed by p_buffer 00040 * you can freely decrease it but never increase it yourself 00041 * (use block_Realloc) 00042 * - p_buffer: pointer over datas. You should never overwrite it, you can 00043 * only incremment it to skip datas, in others cases use block_Realloc 00044 * (don't duplicate yourself in a bigger buffer, block_Realloc is 00045 * optimised for prehader/postdatas increase) 00046 ****************************************************************************/ 00047 typedef struct block_sys_t block_sys_t; 00048 00049 /** The content doesn't follow the last block, or is probably broken */ 00050 #define BLOCK_FLAG_DISCONTINUITY 0x0001 00051 /** Intra frame */ 00052 #define BLOCK_FLAG_TYPE_I 0x0002 00053 /** Inter frame with backward reference only */ 00054 #define BLOCK_FLAG_TYPE_P 0x0004 00055 /** Inter frame with backward and forward reference */ 00056 #define BLOCK_FLAG_TYPE_B 0x0008 00057 /** For inter frame when you don't know the real type */ 00058 #define BLOCK_FLAG_TYPE_PB 0x0010 00059 /** Warn that this block is a header one */ 00060 #define BLOCK_FLAG_HEADER 0x0020 00061 /** This is the last block of the frame */ 00062 #define BLOCK_FLAG_END_OF_FRAME 0x0040 00063 /** This is not a key frame for bitrate shaping */ 00064 #define BLOCK_FLAG_NO_KEYFRAME 0x0080 00065 /** This block contains a clock reference */ 00066 #define BLOCK_FLAG_CLOCK 0x0200 00067 /** This block is scrambled */ 00068 #define BLOCK_FLAG_SCRAMBLED 0x0400 00069 /** This block has to be decoded but not be displayed */ 00070 #define BLOCK_FLAG_PREROLL 0x0800 00071 /** This block is corrupted and/or there is data loss */ 00072 #define BLOCK_FLAG_CORRUPTED 0x1000 00073 00074 #define BLOCK_FLAG_PRIVATE_MASK 0xffff0000 00075 #define BLOCK_FLAG_PRIVATE_SHIFT 16 00076 00077 typedef void (*block_free_t) (block_t *); 00078 00079 struct block_t 00080 { 00081 block_t *p_next; 00082 block_t *p_prev; 00083 00084 uint32_t i_flags; 00085 00086 mtime_t i_pts; 00087 mtime_t i_dts; 00088 mtime_t i_length; 00089 00090 int i_samples; /* Used for audio */ 00091 int i_rate; 00092 00093 size_t i_buffer; 00094 uint8_t *p_buffer; 00095 00096 /* Rudimentary support for overloading block (de)allocation. */ 00097 block_free_t pf_release; 00098 }; 00099 00100 /**************************************************************************** 00101 * Blocks functions: 00102 **************************************************************************** 00103 * - block_Alloc : create a new block with the requested size ( >= 0 ), return 00104 * NULL for failure. 00105 * - block_Release : release a block allocated with block_Alloc. 00106 * - block_Realloc : realloc a block, 00107 * i_pre: how many bytes to insert before body if > 0, else how many 00108 * bytes of body to skip (the latter can be done without using 00109 * block_Realloc i_buffer -= -i_pre, p_buffer += -i_pre as i_pre < 0) 00110 * i_body (>= 0): the final size of the body (decreasing it can directly 00111 * be done with i_buffer = i_body). 00112 * with preheader and or body (increase 00113 * and decrease are supported). Use it as it is optimised. 00114 * - block_Duplicate : create a copy of a block. 00115 ****************************************************************************/ 00116 VLC_EXPORT( void, block_Init, ( block_t *, void *, size_t ) ); 00117 VLC_EXPORT( block_t *, block_Alloc, ( size_t ) ); 00118 VLC_EXPORT( block_t *, block_Realloc, ( block_t *, ssize_t i_pre, size_t i_body ) ); 00119 00120 #define block_New( dummy, size ) block_Alloc(size) 00121 00122 static inline block_t *block_Duplicate( block_t *p_block ) 00123 { 00124 block_t *p_dup = block_Alloc( p_block->i_buffer ); 00125 if( p_dup == NULL ) 00126 return NULL; 00127 00128 p_dup->i_dts = p_block->i_dts; 00129 p_dup->i_pts = p_block->i_pts; 00130 p_dup->i_flags = p_block->i_flags; 00131 p_dup->i_length = p_block->i_length; 00132 p_dup->i_rate = p_block->i_rate; 00133 p_dup->i_samples = p_block->i_samples; 00134 memcpy( p_dup->p_buffer, p_block->p_buffer, p_block->i_buffer ); 00135 00136 return p_dup; 00137 } 00138 00139 static inline void block_Release( block_t *p_block ) 00140 { 00141 p_block->pf_release( p_block ); 00142 } 00143 00144 VLC_EXPORT( block_t *, block_mmap_Alloc, (void *addr, size_t length) ); 00145 VLC_EXPORT( block_t *, block_File, (int fd) ); 00146 00147 /**************************************************************************** 00148 * Chains of blocks functions helper 00149 **************************************************************************** 00150 * - block_ChainAppend : append a block to the last block of a chain. Try to 00151 * avoid using with a lot of data as it's really slow, prefer 00152 * block_ChainLastAppend 00153 * - block_ChainLastAppend : use a pointer over a pointer to the next blocks, 00154 * and update it. 00155 * - block_ChainRelease : release a chain of block 00156 * - block_ChainExtract : extract data from a chain, return real bytes counts 00157 * - block_ChainGather : gather a chain, free it and return one block. 00158 ****************************************************************************/ 00159 static inline void block_ChainAppend( block_t **pp_list, block_t *p_block ) 00160 { 00161 if( *pp_list == NULL ) 00162 { 00163 *pp_list = p_block; 00164 } 00165 else 00166 { 00167 block_t *p = *pp_list; 00168 00169 while( p->p_next ) p = p->p_next; 00170 p->p_next = p_block; 00171 } 00172 } 00173 00174 static inline void block_ChainLastAppend( block_t ***ppp_last, block_t *p_block ) 00175 { 00176 block_t *p_last = p_block; 00177 00178 **ppp_last = p_block; 00179 00180 while( p_last->p_next ) p_last = p_last->p_next; 00181 *ppp_last = &p_last->p_next; 00182 } 00183 00184 static inline void block_ChainRelease( block_t *p_block ) 00185 { 00186 while( p_block ) 00187 { 00188 block_t *p_next = p_block->p_next; 00189 block_Release( p_block ); 00190 p_block = p_next; 00191 } 00192 } 00193 00194 static size_t block_ChainExtract( block_t *p_list, void *p_data, size_t i_max ) 00195 { 00196 size_t i_total = 0; 00197 uint8_t *p = (uint8_t*)p_data; 00198 00199 while( p_list && i_max ) 00200 { 00201 size_t i_copy = __MIN( i_max, p_list->i_buffer ); 00202 memcpy( p, p_list->p_buffer, i_copy ); 00203 i_max -= i_copy; 00204 i_total += i_copy; 00205 p += i_copy; 00206 00207 p_list = p_list->p_next; 00208 } 00209 return i_total; 00210 } 00211 00212 static inline block_t *block_ChainGather( block_t *p_list ) 00213 { 00214 size_t i_total = 0; 00215 mtime_t i_length = 0; 00216 block_t *b, *g; 00217 00218 if( p_list->p_next == NULL ) 00219 return p_list; /* Already gathered */ 00220 00221 for( b = p_list; b != NULL; b = b->p_next ) 00222 { 00223 i_total += b->i_buffer; 00224 i_length += b->i_length; 00225 } 00226 00227 g = block_Alloc( i_total ); 00228 block_ChainExtract( p_list, g->p_buffer, g->i_buffer ); 00229 00230 g->i_flags = p_list->i_flags; 00231 g->i_pts = p_list->i_pts; 00232 g->i_dts = p_list->i_dts; 00233 g->i_length = i_length; 00234 00235 /* free p_list */ 00236 block_ChainRelease( p_list ); 00237 return g; 00238 } 00239 00240 /**************************************************************************** 00241 * Fifos of blocks. 00242 **************************************************************************** 00243 * - block_FifoNew : create and init a new fifo 00244 * - block_FifoRelease : destroy a fifo and free all blocks in it. 00245 * - block_FifoEmpty : free all blocks in a fifo 00246 * - block_FifoPut : put a block 00247 * - block_FifoGet : get a packet from the fifo (and wait if it is empty) 00248 * - block_FifoShow : show the first packet of the fifo (and wait if 00249 * needed), be carefull, you can use it ONLY if you are sure to be the 00250 * only one getting data from the fifo. 00251 * - block_FifoCount : how many packets are waiting in the fifo 00252 * - block_FifoSize : how many cumulated bytes are waiting in the fifo 00253 * - block_FifoWake : wake ups a thread with block_FifoGet() = NULL 00254 * (this is used to wakeup a thread when there is no data to queue) 00255 ****************************************************************************/ 00256 00257 VLC_EXPORT( block_fifo_t *, block_FifoNew, ( void ) ); 00258 VLC_EXPORT( void, block_FifoRelease, ( block_fifo_t * ) ); 00259 VLC_EXPORT( void, block_FifoEmpty, ( block_fifo_t * ) ); 00260 VLC_EXPORT( size_t, block_FifoPut, ( block_fifo_t *, block_t * ) ); 00261 VLC_EXPORT( void, block_FifoWake, ( block_fifo_t * ) ); 00262 VLC_EXPORT( block_t *, block_FifoGet, ( block_fifo_t * ) ); 00263 VLC_EXPORT( block_t *, block_FifoShow, ( block_fifo_t * ) ); 00264 VLC_EXPORT( size_t, block_FifoSize, ( const block_fifo_t *p_fifo ) ); 00265 VLC_EXPORT( size_t, block_FifoCount, ( const block_fifo_t *p_fifo ) ); 00266 00267 #endif /* VLC_BLOCK_H */
1.5.1