Home | History | Annotate | Download | only in include
      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:
     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 
    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:
    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 
    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) {};
    220         virtual ~PVMFTimedTextMediaDataCleanup() {};
    221 
    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:
    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 
    278         virtual ~PVMFTimedTextMediaDataAlloc()
    279         {
    280         };
    281 
    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 
    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:
    379         virtual ~PVMFTimedTextSampleEntryCleanupSA() {};
    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:
    401         PVMFTimedTextSampleEntryCleanupDA(Oscl_DefAlloc& in_gen_alloc) :
    402                 gen_alloc(&in_gen_alloc) {};
    403         virtual ~PVMFTimedTextSampleEntryCleanupDA() {};
    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:
    433         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