1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 /** 19 * @file pvmf_timedtext.h 20 * @brief This file defines structures/utilities specific to timed text media 21 * 22 */ 23 24 #ifndef PVMF_TIMEDTEXT_H_INCLUDED 25 #define PVMF_TIMEDTEXT_H_INCLUDED 26 27 #ifndef OSCL_DEFALLOC_H_INCLUDED 28 #include "oscl_defalloc.h" 29 #endif 30 31 #ifndef OSCL_SHARED_PTR_H_INCLUDED 32 #include "oscl_shared_ptr.h" 33 #endif 34 35 #ifndef OSCL_MEM_MEMPOOL_H_INCLUDED 36 #include "oscl_mem_mempool.h" 37 #endif 38 39 #ifndef PVMF_MEDIA_DATA_IMPL_H_INCLUDED 40 #include "pvmf_media_data_impl.h" 41 #endif 42 43 #ifndef PVMF_SIMPLE_MEDIA_BUFFER_H_INCLUDED 44 #include "pvmf_simple_media_buffer.h" 45 #endif 46 47 const PVUid32 PVMFTimedTextFormatSpecificInfo_UID = 0x1; 48 49 #define PVMFTIMEDTEXT_TRANSLATION_MATRIXSIZE 9 50 #define PVMFTIMEDTEXT_RGBA_ARRAYSIZE 4 51 52 /** 53 * Timed text track level parameters that would be transmitted as 54 * format specific info 55 **/ 56 struct PVMFTimedTextFormatSpecificInfo 57 { 58 PVUid32 iUID32; 59 int16 iLayer; 60 int32 iTranslationMatrix[PVMFTIMEDTEXT_TRANSLATION_MATRIXSIZE]; 61 uint32 iWidth; 62 uint32 iHeight; 63 }; 64 65 /** 66 * Timed text font record entry that describes the font used 67 * in the text sample entry 68 **/ 69 struct PVMFTimedTextFontRecord 70 { 71 uint16 iFontID; 72 uint8 iFontNameLength; 73 uint8* iFontName; 74 }; 75 76 #define PVMF_TIMED_TEXT_UTF_16_MARKER_BYTE_1 0xFE 77 #define PVMF_TIMED_TEXT_UTF_16_MARKER_BYTE_2 0xFF 78 79 enum PVMFTimedTextStringFormatType 80 { 81 PVMF_TIMED_TEXT_STRING_FORMAT_UNKNOWN, 82 PVMF_TIMED_TEXT_STRING_FORMAT_UTF8, 83 PVMF_TIMED_TEXT_STRING_FORMAT_UTF16, 84 PVMF_TIMED_TEXT_STRING_FORMAT_UTF16_LE 85 }; 86 87 88 /** 89 * Timed text sample entry that describes the associated 90 * text sample 91 **/ 92 class PVMFTimedTextSampleEntry 93 { 94 public: PVMFTimedTextSampleEntry()95 PVMFTimedTextSampleEntry() 96 { 97 iDisplayFlags = 0; 98 iHorizontalJustification = 0; 99 iVerticalJustification = 0; 100 oscl_memset(iBackgroundRGBA, 0, PVMFTIMEDTEXT_RGBA_ARRAYSIZE); 101 102 iBoxTop = 0; 103 iBoxLeft = 0; 104 iBoxBottom = 0; 105 iBoxRight = 0; 106 107 iStyleStartChar = 0; 108 iStyleEndChar = 0; 109 iStyleFontID = 0; 110 iStyleFontStyleFlags = 0; 111 iStyleFontSize = 0; 112 oscl_memset(iStyleTextColorRGBA, 0, PVMFTIMEDTEXT_RGBA_ARRAYSIZE); 113 114 iFontEntryCount = 0; 115 iFontRecordList = NULL; 116 } 117 ~PVMFTimedTextSampleEntry()118 ~PVMFTimedTextSampleEntry() 119 { 120 if (iFontRecordList) 121 { 122 for (int32 i = 0; i < iFontEntryCount; ++i) 123 { 124 if (iFontRecordList[i].iFontName != NULL) 125 { 126 OSCL_ARRAY_DELETE(iFontRecordList[i].iFontName); 127 iFontRecordList[i].iFontName = NULL; 128 } 129 } 130 131 OSCL_ARRAY_DELETE(iFontRecordList); 132 iFontRecordList = NULL; 133 } 134 } 135 136 // Text sample entry info 137 uint32 iDisplayFlags; 138 int8 iHorizontalJustification; 139 int8 iVerticalJustification; 140 uint8 iBackgroundRGBA[PVMFTIMEDTEXT_RGBA_ARRAYSIZE]; 141 142 // Box record info 143 int16 iBoxTop; 144 int16 iBoxLeft; 145 int16 iBoxBottom; 146 int16 iBoxRight; 147 148 // Style record info 149 uint16 iStyleStartChar; 150 uint16 iStyleEndChar; 151 uint16 iStyleFontID; 152 uint8 iStyleFontStyleFlags; 153 uint8 iStyleFontSize; 154 uint8 iStyleTextColorRGBA[PVMFTIMEDTEXT_RGBA_ARRAYSIZE]; 155 156 // Font table 157 uint16 iFontEntryCount; 158 PVMFTimedTextFontRecord* iFontRecordList; 159 }; 160 161 /** 162 * Container class transported in PVMFMediaData that contains 163 * a shared pointer to the text sample entry object and a pointer 164 * to the text sample data 165 **/ 166 class PVMFTimedTextMediaData 167 { 168 public: PVMFTimedTextMediaData()169 PVMFTimedTextMediaData() 170 { 171 iTextSample = NULL; 172 iFormatType = PVMF_TIMED_TEXT_STRING_FORMAT_UNKNOWN; 173 iTextStringLengthInBytes = 0; 174 iTextSampleLength = 0; 175 iTextSampleCapacity = 0; 176 iTextSampleDuration = 0; 177 } 178 ~PVMFTimedTextMediaData()179 ~PVMFTimedTextMediaData() 180 { 181 iTextSampleEntry.Unbind(); 182 } 183 184 // Shared pointer to a text sample entry object 185 // Use the GetRep() method to check for and retrieve the pointer 186 // to PVMFTimedTextSampleEntry object 187 OsclSharedPtr<PVMFTimedTextSampleEntry> iTextSampleEntry; 188 189 // Text sample data 190 // Pointer to the text sample data 191 uint8* iTextSample; 192 // length in bytes of actual text string 193 uint32 iTextStringLengthInBytes; 194 // Length of the valid text sample data including the text string and the modifiers 195 // in order to calculate the text sample modifier length, do : 196 // modifierLength = (iTextSampleLength - iTextStringLengthInBytes) 197 uint32 iTextSampleLength; 198 // Buffer capacity for iTextSample pointer. Can be equal to or larger than iTextSampleLength 199 uint32 iTextSampleCapacity; 200 // Sample duration in media timescale 201 uint32 iTextSampleDuration; 202 // Sample format 203 PVMFTimedTextStringFormatType iFormatType; 204 // Timestamp for the text sample in NPT (normal playback time) in milliseconds 205 // MIGHT BE DEPRECATED IN THE FUTURE SINCE NOT MAINTAINABLE. 206 PVMFTimestamp iTextSampleTimestampNPT; 207 }; 208 209 /** 210 * The PVMFTimedTextMediaDataCleanup deallocator class 211 * takes care of calling the destructor for PVMFTimedTextMediaData 212 * before freeing the memory 213 */ 214 215 class PVMFTimedTextMediaDataCleanup : public OsclDestructDealloc 216 { 217 public: 218 PVMFTimedTextMediaDataCleanup(PVMFTimedTextMediaData& textmediadata, Oscl_DefAlloc* in_gen_alloc = NULL) : 219 iTextMediaData(&textmediadata), iGenAlloc(in_gen_alloc) {}; ~PVMFTimedTextMediaDataCleanup()220 virtual ~PVMFTimedTextMediaDataCleanup() {}; 221 destruct_and_dealloc(OsclAny * ptr)222 virtual void destruct_and_dealloc(OsclAny* ptr) 223 { 224 // Call the text media data's destructor 225 iTextMediaData->~PVMFTimedTextMediaData(); 226 227 if (!iGenAlloc) 228 { 229 OsclMemAllocator my_alloc; 230 my_alloc.deallocate(ptr); 231 } 232 else 233 { 234 iGenAlloc->deallocate(ptr); 235 } 236 }; 237 238 private: 239 PVMFTimedTextMediaData* iTextMediaData; 240 Oscl_DefAlloc* iGenAlloc; 241 }; 242 243 /** 244 * The PVMFTimedTextMediaDataAlloc allocator class 245 * takes care of allocating the refcounter, PVMFSimpleMediaBuffer container, 246 * PVMFTimedTextMediaData object, and the actual buffer space for the text sample in a single block of memory. 247 */ 248 249 class PVMFTimedTextMediaDataAlloc 250 { 251 public: PVMFTimedTextMediaDataAlloc(OsclMemPoolResizableAllocator * in_gen_alloc)252 PVMFTimedTextMediaDataAlloc(OsclMemPoolResizableAllocator* in_gen_alloc) 253 { 254 if (in_gen_alloc) 255 { 256 gen_alloc = in_gen_alloc; 257 iBufferOverhead = 0; 258 uint32 aligned_refcnt_size = 259 oscl_mem_aligned_size(sizeof(OsclRefCounterDA)); 260 uint32 aligned_cleanup_size = 261 oscl_mem_aligned_size(sizeof(PVMFTimedTextMediaDataCleanup)); 262 uint32 aligned_simplemb_size = 263 oscl_mem_aligned_size(sizeof(PVMFSimpleMediaBuffer)); 264 uint32 aligned_textmediadata_size = 265 oscl_mem_aligned_size(sizeof(PVMFTimedTextMediaData)); 266 iBufferOverhead = aligned_refcnt_size + 267 aligned_cleanup_size + 268 aligned_simplemb_size + 269 aligned_textmediadata_size; 270 271 } 272 else 273 { 274 OSCL_LEAVE(OsclErrArgument); 275 } 276 }; 277 ~PVMFTimedTextMediaDataAlloc()278 virtual ~PVMFTimedTextMediaDataAlloc() 279 { 280 }; 281 allocate(uint32 requested_size)282 OsclSharedPtr<PVMFMediaDataImpl> allocate(uint32 requested_size) 283 { 284 uint32 aligned_refcnt_size = 285 oscl_mem_aligned_size(sizeof(OsclRefCounterDA)); 286 287 uint32 aligned_cleanup_size = 288 oscl_mem_aligned_size(sizeof(PVMFTimedTextMediaDataCleanup)); 289 290 uint32 aligned_simplemb_size = 291 oscl_mem_aligned_size(sizeof(PVMFSimpleMediaBuffer)); 292 293 uint32 aligned_textmediadata_size = 294 oscl_mem_aligned_size(sizeof(PVMFTimedTextMediaData)); 295 296 uint32 aligned_requested_size = 297 oscl_mem_aligned_size(requested_size); 298 299 uint32 totalmem_size = aligned_refcnt_size + 300 aligned_cleanup_size + 301 aligned_simplemb_size + 302 aligned_textmediadata_size + 303 aligned_requested_size; 304 305 // Allocate the memory 306 uint8* mem_ptr = NULL; 307 if (!gen_alloc) 308 { 309 OsclMemAllocator my_alloc; 310 mem_ptr = (uint8*) my_alloc.allocate(totalmem_size); 311 } 312 else 313 { 314 mem_ptr = (uint8*) gen_alloc->allocate(totalmem_size); 315 } 316 317 // Memory map 318 // | RefCtr | Cleanup | PVMFSimpleMediaBuffer | PVMFTimedTextMediaData | Text sample data | 319 320 // Create the text media data 321 PVMFTimedTextMediaData* textmediadata_ptr = OSCL_PLACEMENT_NEW(mem_ptr + aligned_refcnt_size + aligned_cleanup_size + aligned_simplemb_size, PVMFTimedTextMediaData()); 322 textmediadata_ptr->iTextSample = mem_ptr + aligned_refcnt_size + aligned_cleanup_size + aligned_simplemb_size + aligned_textmediadata_size; 323 textmediadata_ptr->iTextSampleLength = 0; 324 textmediadata_ptr->iTextSampleCapacity = aligned_requested_size; 325 326 // Create the cleanup object 327 PVMFTimedTextMediaDataCleanup* cleanup_ptr = OSCL_PLACEMENT_NEW(mem_ptr + aligned_refcnt_size, PVMFTimedTextMediaDataCleanup(*textmediadata_ptr, gen_alloc)); 328 329 // Create the refcount object 330 OsclRefCounter* my_refcnt = OSCL_PLACEMENT_NEW(mem_ptr, OsclRefCounterDA(mem_ptr, cleanup_ptr)); 331 332 // Create the simple media buffer 333 PVMFMediaDataImpl* media_data_ptr = OSCL_PLACEMENT_NEW(mem_ptr + aligned_refcnt_size + aligned_cleanup_size, PVMFSimpleMediaBuffer((OsclAny*)textmediadata_ptr, aligned_textmediadata_size + aligned_requested_size, my_refcnt)); 334 media_data_ptr->setMediaFragFilledLen(0, aligned_textmediadata_size + aligned_requested_size); 335 336 // Return as shared pointer 337 OsclSharedPtr<PVMFMediaDataImpl> shared_media_data(media_data_ptr, my_refcnt); 338 return shared_media_data; 339 } 340 ResizeMemoryFragment(OsclSharedPtr<PVMFMediaDataImpl> & aSharedBuffer)341 void ResizeMemoryFragment(OsclSharedPtr<PVMFMediaDataImpl>& aSharedBuffer) 342 { 343 OsclRefCounterMemFrag memFrag; 344 aSharedBuffer->getMediaFragment(0, memFrag); 345 uint32 currCapacity = memFrag.getCapacity(); 346 uint32 bytesUsed = memFrag.getMemFragSize(); 347 348 //uint32 alignedBytesUsed = bytesUsed; 349 uint32 alignedBytesUsed = oscl_mem_aligned_size(bytesUsed); 350 351 if (alignedBytesUsed < currCapacity) 352 { 353 uint32 bytesToReclaim = (currCapacity - alignedBytesUsed); 354 OsclMemPoolResizableAllocator* dataAllocator = 355 reinterpret_cast<OsclMemPoolResizableAllocator*>(gen_alloc); 356 /* Account for the overhead */ 357 uint8* memFragPtr = (uint8*)(memFrag.getMemFragPtr()); 358 uint8* ptr = (memFragPtr - iBufferOverhead); 359 dataAllocator->trim((OsclAny*)ptr, bytesToReclaim); 360 aSharedBuffer->setCapacity(alignedBytesUsed); 361 } 362 } 363 364 private: 365 uint32 iBufferOverhead; 366 OsclMemPoolResizableAllocator* gen_alloc; 367 }; 368 369 370 /** 371 * The PVMFTimedTextSampleEntryCleanupSA deallocator class 372 * takes care of calling the destructor for PVMFTimedTextSampleEntry 373 * before freeing the memory using a static allocator 374 */ 375 376 class PVMFTimedTextSampleEntryCleanupSA : public OsclDestructDealloc 377 { 378 public: ~PVMFTimedTextSampleEntryCleanupSA()379 virtual ~PVMFTimedTextSampleEntryCleanupSA() {}; destruct_and_dealloc(OsclAny * ptr)380 virtual void destruct_and_dealloc(OsclAny* ptr) 381 { 382 uint8* tmp_ptr = (uint8*) ptr; 383 uint32 aligned_refcnt_size = oscl_mem_aligned_size(sizeof(OsclRefCounterSA<PVMFTimedTextSampleEntryCleanupSA>)); 384 tmp_ptr += aligned_refcnt_size; 385 PVMFTimedTextSampleEntry* tse_ptr = reinterpret_cast<PVMFTimedTextSampleEntry*>(tmp_ptr); 386 tse_ptr->~PVMFTimedTextSampleEntry(); 387 OsclMemAllocator alloc; 388 alloc.deallocate(ptr); 389 } 390 }; 391 392 /** 393 * The PVMFTimedTextSampleEntryCleanupDA deallocator class 394 * takes care of calling the destructor for PVMFTimedTextSampleEntry 395 * before freeing the memory using a passed-in allocator 396 */ 397 398 class PVMFTimedTextSampleEntryCleanupDA : public OsclDestructDealloc 399 { 400 public: PVMFTimedTextSampleEntryCleanupDA(Oscl_DefAlloc & in_gen_alloc)401 PVMFTimedTextSampleEntryCleanupDA(Oscl_DefAlloc& in_gen_alloc) : 402 gen_alloc(&in_gen_alloc) {}; ~PVMFTimedTextSampleEntryCleanupDA()403 virtual ~PVMFTimedTextSampleEntryCleanupDA() {}; destruct_and_dealloc(OsclAny * ptr)404 virtual void destruct_and_dealloc(OsclAny* ptr) 405 { 406 uint8* tmp_ptr = (uint8*) ptr; 407 uint32 aligned_size = oscl_mem_aligned_size(sizeof(OsclRefCounterDA)); 408 // skip the refcounter 409 tmp_ptr += aligned_size; 410 // skip the cleanup 411 aligned_size = oscl_mem_aligned_size(sizeof(PVMFTimedTextSampleEntryCleanupDA)); 412 tmp_ptr += aligned_size; 413 414 PVMFTimedTextSampleEntry* tse_ptr = reinterpret_cast<PVMFTimedTextSampleEntry*>(tmp_ptr); 415 tse_ptr->~PVMFTimedTextSampleEntry(); 416 gen_alloc->deallocate(ptr); 417 } 418 419 private: 420 Oscl_DefAlloc* gen_alloc; 421 }; 422 423 424 /** 425 * The PVMFTimedTextSampleEntryUtil allocator utility class 426 * takes care of creating a shared pointer for PVMFTimedTextSampleEntry including 427 * the refcounter, cleanup object if allocator is passed-in, and the PVMFTimedTextSampleEntry object 428 */ 429 430 class PVMFTimedTextSampleEntryUtil 431 { 432 public: PVMFTimedTextSampleEntryUtil()433 PVMFTimedTextSampleEntryUtil() {}; ~PVMFTimedTextSampleEntryUtil()434 ~PVMFTimedTextSampleEntryUtil() {}; 435 436 static OsclSharedPtr<PVMFTimedTextSampleEntry> CreatePVMFTimedTextSampleEntry(Oscl_DefAlloc* gen_alloc = NULL) 437 { 438 // Allocate enough room 439 uint8* my_ptr = NULL; 440 OsclRefCounter* my_refcnt; 441 uint32 aligned_tse_size = oscl_mem_aligned_size(sizeof(PVMFTimedTextSampleEntry)); 442 443 // Must compute the aligned size for PVMFTimedTextSampleEntry. 444 if (gen_alloc) 445 { 446 // Memory map 447 // | RefCtr | Cleanup | PVMFTimedTextSampleEntry | 448 449 uint32 aligned_refcnt_size = oscl_mem_aligned_size(sizeof(OsclRefCounterDA)); 450 uint32 aligned_cleanup_size = oscl_mem_aligned_size(sizeof(PVMFTimedTextSampleEntryCleanupDA)); 451 my_ptr = (uint8*) gen_alloc->ALLOCATE(aligned_refcnt_size + aligned_cleanup_size + aligned_tse_size); 452 453 PVMFTimedTextSampleEntryCleanupDA* my_cleanup = OSCL_PLACEMENT_NEW(my_ptr + aligned_refcnt_size, PVMFTimedTextSampleEntryCleanupDA(*gen_alloc)); 454 my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterDA(my_ptr, my_cleanup)); 455 my_ptr += aligned_refcnt_size + aligned_cleanup_size; 456 } 457 else 458 { 459 // Memory map 460 // | RefCtr | PVMFTimedTextSampleEntry | 461 462 OsclMemAllocator my_alloc; 463 uint32 aligned_refcnt_size = oscl_mem_aligned_size(sizeof(OsclRefCounterSA<PVMFTimedTextSampleEntryCleanupSA>)); 464 my_ptr = (uint8*) my_alloc.ALLOCATE(aligned_refcnt_size + aligned_tse_size); 465 my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterSA<PVMFTimedTextSampleEntryCleanupSA>(my_ptr)); 466 my_ptr += aligned_refcnt_size; 467 } 468 469 PVMFTimedTextSampleEntry* tse_ptr = OSCL_PLACEMENT_NEW(my_ptr, PVMFTimedTextSampleEntry()); 470 471 OsclSharedPtr<PVMFTimedTextSampleEntry> shared_tse(tse_ptr, my_refcnt); 472 return shared_tse; 473 } 474 }; 475 476 #endif 477 478