00001
00002
00003
00004
00005
00006
00007
00018 #ifndef OSCL_MEDIA_DATA_H
00019 #define OSCL_MEDIA_DATA_H
00020
00021 #ifndef OSCL_BASE_H_INCLUDED
00022 #include "oscl_base.h"
00023 #endif
00024
00025 #ifndef OSCL_MEM_BASIC_FUNCTIONS_H_INCLUDED
00026 #include "oscl_mem_basic_functions.h"
00027 #endif
00028
00029 #ifndef OSCL_MEDIA_STATUS_H_INCLUDED
00030 #include "oscl_media_status.h"
00031 #endif
00032
00033 typedef void (*BufferFreeFuncPtr)(void *);
00034
00035 typedef uint32 MediaTimestamp;
00036
00037 template <class T> class MemAllocator
00038 {
00039 public:
00040 typedef T* pointer;
00041
00042 virtual pointer allocate(void * hint = 0, const int num_reserved_frags = 1) = 0;
00043 virtual void deallocate(pointer p) = 0;
00044 virtual ~MemAllocator() {}
00045 };
00046
00047 class BufferState;
00048
00049 class BufferMgr
00050 {
00051 public:
00052 virtual void BufferReleased(void* ptr, BufferState* state = NULL) = 0;
00053 virtual ~BufferMgr() {}
00054 };
00055
00056
00057 class BufferState
00058 {
00059 public:
00060 BufferState(BufferFreeFuncPtr the_free_function, void *bufptr = 0) :
00061 refcount(0), ptr(bufptr), free_function(the_free_function), buf_mgr(0) {};
00062
00063 BufferState(BufferMgr* the_buf_mgr = 0, void *bufptr = 0) :
00064 refcount(0), ptr(bufptr), free_function(0), buf_mgr(the_buf_mgr) {};
00065
00066 void increment_refcnt()
00067 {
00068 ++refcount;
00069 };
00070 void decrement_refcnt()
00071 {
00072 if (!(--refcount))
00073 {
00074 if (buf_mgr) buf_mgr->BufferReleased(ptr, this);
00075 else if (free_function)
00076 {
00077 free_function(ptr);
00078 ptr = 0;
00079 }
00080 }
00081 };
00082
00083 void bind(void *in_ptr, BufferFreeFuncPtr in_free_function)
00084 {
00085 refcount = 0;
00086 ptr = in_ptr, free_function = in_free_function;
00087
00088 };
00089 void bind(void *in_ptr, BufferMgr* in_buf_mgr)
00090 {
00091 refcount = 0;
00092 ptr = in_ptr, buf_mgr = in_buf_mgr;
00093 };
00094
00095 void *get_ptr()
00096 {
00097 return ptr;
00098 };
00099 int32 get_refcount()
00100 {
00101 return refcount;
00102 };
00103
00104 BufferFreeFuncPtr get_free_function()
00105 {
00106 return free_function;
00107 };
00108 BufferMgr* get_buf_mgr()
00109 {
00110 return buf_mgr;
00111 };
00112
00113 void reset()
00114 {
00115 refcount = 0;
00116 ptr = 0;
00117 };
00118
00119 private:
00120 int32 refcount;
00121 void *ptr;
00122 BufferFreeFuncPtr free_function;
00123 BufferMgr* buf_mgr;
00124 };
00125
00126
00127
00128
00129
00130 class BufferFragment : public OsclMemoryFragment {};
00131
00132
00133 template <class ChainClass, uint32 max_frags> class BufFragGroup
00134 {
00135 public:
00136
00137
00138 BufFragGroup(): next(0), num_fragments(0), length(0)
00139 {
00140 oscl_memset(fragments, 0, sizeof(fragments));
00141 oscl_memset(buffer_states, 0, sizeof(buffer_states));
00142 };
00143
00144 virtual ~BufFragGroup() {}
00145
00146 int32 GetMaxFrags() const
00147 {
00148 return max_frags;
00149 };
00150 int32 GetNumFrags() const
00151 {
00152 return num_fragments;
00153 };
00154 uint32 GetLength() const
00155 {
00156 return length;
00157 };
00158
00159 BufferFragment * GetFragment(const int32 idx);
00160
00161 BufferState * GetBufferState(const int32 idx);
00162
00163 void AppendNext(ChainClass* next_ptr)
00164 {
00165 next = next_ptr;
00166 };
00167 ChainClass* GetNext() const
00168 {
00169 return next;
00170 };
00171
00172
00173
00174
00175 protected:
00176
00177
00178
00179
00180
00181
00182 virtual void Clear()
00183 {
00184 for (uint ii = 0 ; ii < num_fragments; ++ii)
00185 {
00186 if (buffer_states[ii])
00187 {
00188 buffer_states[ii]->decrement_refcnt();
00189 }
00190 }
00191 num_fragments = length = 0;
00192 oscl_memset(buffer_states, 0, sizeof(buffer_states));
00193 oscl_memset(fragments, 0, sizeof(fragments));
00194 };
00195
00196 BufFragStatusClass::status_t AddFragment(const BufferFragment& frag, BufferState* in_buffer_state,
00197 int32 location_offset = max_frags)
00198 {
00199 if (num_fragments > max_frags)
00200 {
00201 return BufFragStatusClass::TOO_MANY_FRAGS;
00202 }
00203 if (frag.ptr == NULL)
00204 {
00205 return BufFragStatusClass::EMPTY_FRAGMENT;
00206 }
00207
00208 if (location_offset >= 0 && location_offset < (int32) num_fragments)
00209 {
00210 if (fragments[location_offset].ptr)
00211 {
00212
00213 oscl_memmove(fragments + location_offset + 1, fragments + location_offset,
00214 (num_fragments - location_offset)*sizeof(BufferFragment));
00215 oscl_memmove(buffer_states + location_offset + 1, buffer_states + location_offset,
00216 (num_fragments - location_offset)*sizeof(BufferState*));
00217 ++num_fragments;
00218
00219
00220
00221 }
00222 fragments[location_offset] = frag;
00223 buffer_states[location_offset] = in_buffer_state;
00224 if (in_buffer_state) in_buffer_state->increment_refcnt();
00225 length += frag.len;
00226 return BufFragStatusClass::BFG_SUCCESS;
00227 }
00228
00229
00230 fragments[num_fragments] = frag;
00231 buffer_states[num_fragments++] = in_buffer_state;
00232 length += frag.len;
00233 if (in_buffer_state) in_buffer_state->increment_refcnt();
00234 return BufFragStatusClass::BFG_SUCCESS;
00235 };
00236
00237 BufferFragment fragments[max_frags];
00238 BufferState* buffer_states[max_frags];
00239 ChainClass* next;
00240 uint32 num_fragments;
00241 uint32 length;
00242 };
00243
00244 template <class ChainClass, uint32 max_frags> inline BufferFragment * BufFragGroup<ChainClass, max_frags> :: GetFragment(const int32 idx)
00245 {
00246 if (idx < (int)num_fragments && idx >= 0)
00247 {
00248 return & fragments[idx];
00249 }
00250 else
00251 {
00252 return NULL;
00253 }
00254 }
00255
00256 template <class ChainClass, uint32 max_frags> inline BufferState * BufFragGroup<ChainClass, max_frags> :: GetBufferState(const int32 idx)
00257 {
00258 if (idx < (int)num_fragments && idx >= 0)
00259 {
00260 return buffer_states[idx];
00261 }
00262 else
00263 {
00264 return NULL;
00265 }
00266 }
00267
00268
00269 template <class ChainClass, uint32 max_frags, uint32 local_bufsize> class MediaData :
00270 public BufFragGroup<ChainClass, max_frags>
00271 {
00272
00273 public:
00274 MediaData(): timestamp(0), available_localbuf(local_bufsize), num_reserved_fragments(0) {};
00275
00276 virtual ~MediaData() {}
00277
00278 uint32 GetLocalBufsize() const
00279 {
00280 return local_bufsize;
00281 };
00282 MediaTimestamp GetTimestamp() const
00283 {
00284 return timestamp;
00285 };
00286 void SetTimestamp(MediaTimestamp in_timestamp)
00287 {
00288 timestamp = in_timestamp;
00289 };
00290 uint32 GetAvailableBufferSize() const
00291 {
00292 return available_localbuf;
00293 };
00294
00295
00296
00297
00298
00299
00300 MediaStatusClass::status_t GetLocalFragment(BufferFragment& fragment)
00301 {
00302 if (fragment.len > available_localbuf)
00303 {
00304 fragment.ptr = NULL;
00305 fragment.len = available_localbuf;
00306 return MediaStatusClass::NOT_ENOUGH_SPACE;
00307 }
00308
00309 fragment.ptr = localbuf + (local_bufsize - available_localbuf);
00310 available_localbuf -= fragment.len;
00311 return MediaStatusClass::BFG_SUCCESS;
00312 };
00313
00314 virtual void Clear()
00315 {
00316 for (uint ii = 0 ; ii < this->num_fragments; ++ii)
00317 {
00318 if (this->buffer_states[ii])
00319 {
00320 this->buffer_states[ii]->decrement_refcnt();
00321 }
00322 }
00323 this->num_fragments = 0;
00324 this->length = 0;
00325 oscl_memset(this->buffer_states, 0, sizeof(this->buffer_states));
00326 oscl_memset(this->fragments, 0, sizeof(this->fragments));
00327 this->available_localbuf = local_bufsize;
00328 };
00329
00330
00331 bool IsLocalData(const OsclMemoryFragment& frag) const
00332 {
00333 if (frag.ptr == NULL)
00334 return true;
00335 if ((uint8 *)frag.ptr >= localbuf)
00336 {
00337 if (((uint8 *)frag.ptr) + frag.len < localbuf + local_bufsize)
00338 {
00339 return true;
00340 }
00341 return false;
00342 }
00343 return false;
00344 }
00345
00346 int GetMediaSize() const
00347 {
00348 int num_reserved = 0;
00349 for (int ii = 0; ii < num_reserved_fragments; ii++)
00350 num_reserved += this->fragments[ii].len;
00351
00352 return (this->length - num_reserved);
00353 }
00354
00355 BufferFragment * GetMediaFragment(const uint32 idx)
00356 {
00357 uint32 tmp = idx + this->num_reserved_fragments;
00358 if (tmp > this->num_fragments)
00359 {
00360 return NULL;
00361 }
00362 else
00363 {
00364 return & this->fragments[tmp];
00365 }
00366 }
00367
00368 uint32 GetNumMediaFrags(const uint32 idx) const
00369 {
00370 if (this->num_fragments >= this->num_reserved_fragments)
00371 return this->num_fragments - this->num_reserved_fragments;
00372 else return 0;
00373 }
00374
00375 protected:
00376
00377 MediaStatusClass::status_t AddLocalFragment(const BufferFragment& frag,
00378 int32 location_offset)
00379 {
00380
00381 if (this->num_fragments > max_frags)
00382 {
00383 return MediaStatusClass::TOO_MANY_FRAGS;
00384 }
00385
00386 if (frag.ptr == NULL || frag.len == 0)
00387 {
00388 return MediaStatusClass::EMPTY_FRAGMENT;
00389 }
00390
00391
00392 if (frag.len > available_localbuf)
00393 {
00394 return MediaStatusClass::NOT_ENOUGH_SPACE;
00395 }
00396
00397
00398 BufferFragment local_fragment;
00399 local_fragment.len = frag.len;
00400 local_fragment.ptr = localbuf + (local_bufsize - available_localbuf);
00401 available_localbuf -= frag.len;
00402 this->length += frag.len;
00403
00404 oscl_memcpy(local_fragment.ptr, frag.ptr, frag.len*sizeof(uint8));
00405
00406 if (location_offset >= 0 && location_offset < (int32) this->num_fragments)
00407 {
00408 if (this->fragments[location_offset].ptr)
00409 {
00410
00411 oscl_memmove(this->fragments + location_offset + 1, this->fragments + location_offset,
00412 (this->num_fragments - location_offset)*sizeof(BufferFragment));
00413 oscl_memmove(this->buffer_states + location_offset + 1, this->buffer_states + location_offset,
00414 (this->num_fragments - location_offset)*sizeof(BufferState*));
00415 ++this->num_fragments;
00416
00417
00418
00419 }
00420 this->fragments[location_offset] = local_fragment;
00421 this->buffer_states[location_offset] = NULL;
00422 return MediaStatusClass::BFG_SUCCESS;
00423 }
00424
00425
00426 this->fragments[this->num_fragments] = local_fragment;
00427 this->buffer_states[this->num_fragments++] = NULL;
00428 return MediaStatusClass::BFG_SUCCESS;
00429 };
00430
00431 MediaTimestamp timestamp;
00432 uint8 localbuf[local_bufsize];
00433 uint32 available_localbuf;
00434
00435 int num_reserved_fragments;
00436 };
00437
00438 #endif
00439