• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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