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#define IMPLEMENT_InterleaveBuffer
19
20#include "interleavebuffer.h"
21
22typedef Oscl_Vector<uint32, OsclMemAllocator> uint32VecType;
23typedef Oscl_Vector<uint8, OsclMemAllocator> uint8VecType;
24typedef Oscl_Vector<int32, OsclMemAllocator> int32VecType;
25
26PVA_FF_InterLeaveBuffer::PVA_FF_InterLeaveBuffer(uint32 mediaType,
27        uint32 codecType,
28        uint32 trackId)
29{
30    _trackId = trackId;
31    _mediaType = mediaType;
32    _codecType = codecType;
33    _lastChunkEndTime           =   0;
34    _maxInterLeaveBufferSize    =   0;
35    _currInterLeaveBufferSize   =   0;
36    _lastInterLeaveBufferTS     =   0;
37    _lastSampleTS               =   0;
38
39
40    // initialise interleaved buffers for audio or video track( max size)
41    if ((uint32) mediaType == MEDIA_TYPE_AUDIO)
42    {
43        if (codecType == CODEC_TYPE_AMR_AUDIO)
44        {
45            _interLeaveBuffer =
46                (uint8 *)(oscl_malloc(sizeof(uint8) * AMR_INTERLEAVE_BUFFER_SIZE));
47
48            _maxInterLeaveBufferSize = AMR_INTERLEAVE_BUFFER_SIZE;
49        }
50        else if (codecType == CODEC_TYPE_AAC_AUDIO)
51        {
52            _interLeaveBuffer =
53                (uint8 *)(oscl_malloc(sizeof(uint8) * AAC_INTERLEAVE_BUFFER_SIZE));
54
55            _maxInterLeaveBufferSize = AAC_INTERLEAVE_BUFFER_SIZE;
56        }
57        else if (codecType == CODEC_TYPE_AMR_WB_AUDIO)
58        {
59            _interLeaveBuffer =
60                (uint8 *)(oscl_malloc(sizeof(uint8) * AMR_WB_INTERLEAVE_BUFFER_SIZE));
61
62            _maxInterLeaveBufferSize = AMR_WB_INTERLEAVE_BUFFER_SIZE;
63        }
64    }
65
66    if ((uint32) mediaType == MEDIA_TYPE_VISUAL)
67    {
68        _interLeaveBuffer = (uint8 *)(oscl_malloc(sizeof(uint8) * VIDEO_INTERLEAVE_BUFFER_SIZE));
69
70        _maxInterLeaveBufferSize = VIDEO_INTERLEAVE_BUFFER_SIZE;
71    }
72
73    if ((uint32) _mediaType == MEDIA_TYPE_TEXT)
74    {
75        _interLeaveBuffer = (uint8 *)(oscl_malloc(sizeof(uint8) * TEXT_INTERLEAVE_BUFFER_SIZE));
76
77        _maxInterLeaveBufferSize = TEXT_INTERLEAVE_BUFFER_SIZE;
78    }
79
80    // initialise vectors to store sample parameters present in interleaved buffers
81    PV_MP4_FF_NEW(fp->auditCB, uint32VecType, (), _pTimeStampVec);
82    PV_MP4_FF_NEW(fp->auditCB, uint32VecType, (), _pSampleSizeVec);
83    PV_MP4_FF_NEW(fp->auditCB, uint8VecType, (), _pSampleFlagsVec);
84    PV_MP4_FF_NEW(fp->auditCB, int32VecType, (), _pIndexVec);
85
86}
87
88PVA_FF_InterLeaveBuffer::~PVA_FF_InterLeaveBuffer()
89{
90    // free interleave buffer and sample parameter vectors
91    if (_interLeaveBuffer != NULL)
92        oscl_free(_interLeaveBuffer);
93    if (_pTimeStampVec != NULL)
94        PV_MP4_FF_TEMPLATED_DELETE(NULL, uint32VecType, Oscl_Vector, _pTimeStampVec);
95    if (_pSampleSizeVec)
96        PV_MP4_FF_TEMPLATED_DELETE(NULL, uint32VecType, Oscl_Vector, _pSampleSizeVec);
97    if (_pSampleFlagsVec)
98        PV_MP4_FF_TEMPLATED_DELETE(NULL, uint8VecType, Oscl_Vector, _pSampleFlagsVec);
99    if (_pIndexVec)
100        PV_MP4_FF_TEMPLATED_DELETE(NULL, int32VecType, Oscl_Vector, _pIndexVec);
101}
102
103// given sample is added to interleave buffer and
104// sample parameters stored in parameter vectors
105bool
106PVA_FF_InterLeaveBuffer::addSampleToInterLeaveBuffer(
107    Oscl_Vector < OsclMemoryFragment,
108    OsclMemAllocator > & fragmentList,
109    uint32 size, uint32 ts, uint8 flags, int32 index)
110{
111    // temporary variables
112    uint32 bytesWritten = 0;
113    uint32 length = 0;
114    uint32 ii = 0;
115    OsclBinIStreamBigEndian stream;
116
117    if (_interLeaveBuffer != NULL)
118    {
119        uint8* currPtr = _interLeaveBuffer + _currInterLeaveBufferSize;
120
121        if (checkInterLeaveBufferSpace(size))
122        {
123            if (_mediaType == MEDIA_TYPE_VISUAL && _codecType == CODEC_TYPE_AVC_VIDEO)
124            {
125                for (ii = 0; ii < fragmentList.size(); ii++)
126                {
127                    // read NAL length in Big Endian format
128                    stream.Attach((OsclAny*) &(fragmentList[ii].len), 4);
129                    stream >> length;
130
131                    // compose nal length in two bytes
132                    oscl_memcpy((OsclAny*)(currPtr + bytesWritten), ((uint8*)&length), 4);
133
134                    // write NAL uint
135                    oscl_memcpy((OsclAny*)(currPtr + bytesWritten + 4), (OsclAny*)fragmentList[ii].ptr, fragmentList[ii].len);
136                    bytesWritten += (fragmentList[ii].len + 4);
137                }
138            }
139            else
140            {
141                for (ii = 0; ii < fragmentList.size(); ii++)
142                {
143                    oscl_memcpy(currPtr + bytesWritten, fragmentList[ii].ptr, fragmentList[ii].len);
144                    bytesWritten += fragmentList[ii].len;
145                }
146            }
147
148            _currInterLeaveBufferSize += size;
149            _lastInterLeaveBufferTS = ts;
150
151            //Store meta data params
152            _pTimeStampVec->push_back(ts);
153            _pSampleSizeVec->push_back(size);
154            _pSampleFlagsVec->push_back(flags);
155            _pIndexVec->push_back(index);
156
157            return true;
158        }
159    }
160
161    return false;
162}
163
164
165// returns false if interleave buffer does not have free space = size
166bool
167PVA_FF_InterLeaveBuffer::checkInterLeaveBufferSpace(uint32 size)
168{
169    if ((_currInterLeaveBufferSize + size) > _maxInterLeaveBufferSize)
170    {
171        return false;
172    }
173    return true;
174}
175
176Oscl_Vector<uint32, OsclMemAllocator>*
177PVA_FF_InterLeaveBuffer::getTimeStampVec()
178{
179    return _pTimeStampVec;
180}
181
182Oscl_Vector<uint32, OsclMemAllocator>*
183PVA_FF_InterLeaveBuffer::getSampleSizeVec()
184{
185    return _pSampleSizeVec;
186
187}
188
189Oscl_Vector<uint8, OsclMemAllocator>*
190PVA_FF_InterLeaveBuffer::getFlagsVec()
191{
192    return _pSampleFlagsVec;
193}
194
195Oscl_Vector<int32, OsclMemAllocator>*
196PVA_FF_InterLeaveBuffer::getTextIndexVec()
197{
198    return _pIndexVec;
199}
200
201
202// reset interleave buffer, reset parameter vectors
203uint8*
204PVA_FF_InterLeaveBuffer::resetInterLeaveBuffer(uint32 &chunkSize)
205{
206    chunkSize = _currInterLeaveBufferSize;
207    // reset params
208    _currInterLeaveBufferSize = 0;
209    _lastInterLeaveBufferTS   = 0;
210
211    //Delete and recreate the vectors
212
213    PV_MP4_FF_TEMPLATED_DELETE(NULL, uint32VecType, Oscl_Vector, _pTimeStampVec);
214    PV_MP4_FF_TEMPLATED_DELETE(NULL, uint32VecType, Oscl_Vector, _pSampleSizeVec);
215    PV_MP4_FF_TEMPLATED_DELETE(NULL, uint8VecType, Oscl_Vector, _pSampleFlagsVec);
216    PV_MP4_FF_TEMPLATED_DELETE(NULL, int32VecType, Oscl_Vector, _pIndexVec);
217
218    PV_MP4_FF_NEW(fp->auditCB, uint32VecType, (), _pTimeStampVec);
219    PV_MP4_FF_NEW(fp->auditCB, uint32VecType, (), _pSampleSizeVec);
220    PV_MP4_FF_NEW(fp->auditCB, uint8VecType, (), _pSampleFlagsVec);
221    PV_MP4_FF_NEW(fp->auditCB, int32VecType, (), _pIndexVec);
222
223    return (_interLeaveBuffer);
224}
225
226
227// return size of interleave buffer
228uint32
229PVA_FF_InterLeaveBuffer::getCurrentInterLeaveBufferSize()
230{
231    return (_currInterLeaveBufferSize);
232}
233
234
235uint32
236PVA_FF_InterLeaveBuffer::getTrackID()
237{
238    return _trackId;
239}
240
241
242
243// retuen last trun end time value
244uint32
245PVA_FF_InterLeaveBuffer::getLastChunkEndTime()
246{
247    return _lastChunkEndTime;
248}
249
250uint32
251PVA_FF_InterLeaveBuffer::getLastSampleTS()
252{
253    return _lastSampleTS;
254}
255
256// set last trun end time value
257void
258PVA_FF_InterLeaveBuffer::setLastChunkEndTime()
259{
260    _lastChunkEndTime = _lastInterLeaveBufferTS;
261}
262
263
264// set last trun end time value = given time
265void
266PVA_FF_InterLeaveBuffer::setLastChunkEndTime(uint32 time)
267{
268    _lastChunkEndTime = time;
269    if (_pTimeStampVec->size() > 0)
270    {
271        _lastSampleTS  = _pTimeStampVec->back();
272    }
273    else
274    {
275        _lastSampleTS = 0;
276    }
277
278
279}
280
281
282uint32
283PVA_FF_InterLeaveBuffer::getFirstTSEntry()
284{
285    if (_pTimeStampVec->size() > 0)
286    {
287        return (*_pTimeStampVec)[0];
288    }
289    return 0;
290}
291