1/*
2 * Copyright (C) 2011 The Android Open Source Project
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 express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/**
18******************************************************************************
19 * @file    M4MP4W_Utils.c
20 * @brief   Utilities and private functions for the MP4 writer
21******************************************************************************
22*/
23
24#include "NXPSW_CompilerSwitches.h"
25
26#ifndef _M4MP4W_USE_CST_MEMORY_WRITER
27
28#include "M4MP4W_Utils.h"
29#include "M4OSA_Error.h"
30#include "M4MP4W_Types.h"
31
32#define ERR_CHECK(exp, err) if (!(exp)) { return err; }
33
34/*******************************************************************************/
35M4OSA_ERR M4MP4W_putByte(M4OSA_UChar c, M4OSA_FileWriterPointer* fileFunction,
36                         M4OSA_Context context)
37/*******************************************************************************/
38{
39    M4OSA_ERR err = fileFunction->writeData(context, (M4OSA_MemAddr8)&c, 1);
40    return err;
41}
42
43/*******************************************************************************/
44M4OSA_ERR M4MP4W_putBE16(M4OSA_UInt32 val, M4OSA_FileWriterPointer* fileFunction,
45                         M4OSA_Context context)
46/*******************************************************************************/
47{
48    M4OSA_ERR err;
49    err = M4MP4W_putByte((M4OSA_UChar)(val >> 8), fileFunction, context);
50    ERR_CHECK(err == M4NO_ERROR, err);
51    err = M4MP4W_putByte((M4OSA_UChar)val, fileFunction, context);
52    return err;
53}
54
55/*******************************************************************************/
56M4OSA_ERR M4MP4W_putBE24(M4OSA_UInt32 val, M4OSA_FileWriterPointer* fileFunction,
57                         M4OSA_Context context)
58/*******************************************************************************/
59{
60    M4OSA_ERR err;
61    err = M4MP4W_putByte((M4OSA_UChar)(val >> 16), fileFunction, context);
62    ERR_CHECK(err == M4NO_ERROR, err);
63    err = M4MP4W_putByte((M4OSA_UChar)(val >> 8), fileFunction, context);
64    ERR_CHECK(err == M4NO_ERROR, err);
65    err = M4MP4W_putByte((M4OSA_UChar)val, fileFunction, context);
66    return err;
67}
68
69/*******************************************************************************/
70M4OSA_ERR M4MP4W_putBE32(M4OSA_UInt32 val, M4OSA_FileWriterPointer* fileFunction,
71                         M4OSA_Context context)
72/*******************************************************************************/
73{
74    M4OSA_ERR err;
75    err = M4MP4W_putByte((M4OSA_UChar)(val >> 24), fileFunction, context);
76    ERR_CHECK(err == M4NO_ERROR, err);
77    err = M4MP4W_putByte((M4OSA_UChar)(val >> 16), fileFunction, context);
78    ERR_CHECK(err == M4NO_ERROR, err);
79    err = M4MP4W_putByte((M4OSA_UChar)(val >> 8), fileFunction, context);
80    ERR_CHECK(err == M4NO_ERROR, err);
81    err = M4MP4W_putByte((M4OSA_UChar)val, fileFunction, context);
82    return err;
83}
84
85/*******************************************************************************/
86M4OSA_ERR M4MP4W_putBlock(const M4OSA_UChar* Block, M4OSA_UInt32 size,
87                           M4OSA_FileWriterPointer* fileFunction, M4OSA_Context context)
88/*******************************************************************************/
89{
90    M4OSA_ERR err = fileFunction->writeData(context, (M4OSA_MemAddr8)Block, size);
91    return err;
92}
93
94/*******************************************************************************/
95void M4MP4W_convertInt32BE(M4OSA_UInt32* valPtr)
96/*******************************************************************************/
97{
98    M4OSA_UChar a, b;
99    M4OSA_UChar* c = (M4OSA_UChar*)valPtr;
100    a       = *(c);
101    b       = *(c+1);
102    *(c)   = *(c+3);
103    *(c+1) = *(c+2);
104    *(c+2) = b;
105    *(c+3) = a;
106}
107
108/*******************************************************************************/
109void M4MP4W_table32ToBE(M4OSA_UInt32* tab, M4OSA_UInt32 nb)
110/*******************************************************************************/
111{
112    M4OSA_UInt32 i;
113    for (i=0; i<nb; i++)
114        M4MP4W_convertInt32BE(&(tab)[i]);
115}
116
117/*******************************************************************************/
118void* M4MP4W_realloc(M4OSA_MemAddr32 ptr, M4OSA_UInt32 oldSize, M4OSA_UInt32 newSize)
119/*******************************************************************************/
120{
121    M4OSA_MemAddr32 ptr2 = (M4OSA_MemAddr32)M4OSA_32bitAlignedMalloc(newSize, M4MP4_WRITER,
122                                                          (M4OSA_Char *)"realloc");
123    if (M4OSA_NULL != ptr2)
124    {
125        memcpy((void *)ptr2, (void *)ptr, oldSize);
126    }
127    free(ptr);
128    return ptr2;
129}
130
131/*******************************************************************************/
132M4OSA_ERR M4MP4W_freeContext(M4OSA_Context context)
133/*******************************************************************************/
134{
135#ifdef _M4MP4W_MOOV_FIRST
136    M4OSA_UInt32 i;
137#endif /*_M4MP4W_MOOV_FIRST*/
138    M4MP4W_Mp4FileData* mMp4FileDataPtr = (M4MP4W_Mp4FileData*)context;
139    ERR_CHECK(context != M4OSA_NULL, M4ERR_PARAMETER);
140
141    /*freeContext is now called after closeWrite*/
142    ERR_CHECK( mMp4FileDataPtr->state == M4MP4W_closed, M4ERR_STATE);
143    mMp4FileDataPtr->state = M4MP4W_closed;
144
145    if (mMp4FileDataPtr->audioTrackPtr != M4OSA_NULL)
146    {
147        /*delete also other chunks if any*/
148        /*for (i=0; i<=mMp4FileDataPtr->audioTrackPtr->currentChunk; i++)*/
149
150#ifdef _M4MP4W_MOOV_FIRST
151        for (i=0; i<=mMp4FileDataPtr->audioTrackPtr->LastAllocatedChunk; i++)
152        {
153            free(mMp4FileDataPtr->audioTrackPtr->Chunk[i]);
154        }
155#else
156        if ((M4OSA_NULL != mMp4FileDataPtr->audioTrackPtr->Chunk) &&
157             (M4OSA_NULL != mMp4FileDataPtr->audioTrackPtr->Chunk[0]))
158        {
159            free(mMp4FileDataPtr->audioTrackPtr->Chunk[0]);
160        }
161        if (M4OSA_NULL != mMp4FileDataPtr->audioTrackPtr->chunkOffsetTable)
162        {
163            free(mMp4FileDataPtr->audioTrackPtr->chunkOffsetTable);
164        }
165#endif /*_M4MP4W_MOOV_FIRST*/
166
167        /*now dynamic*/
168        if (M4OSA_NULL != mMp4FileDataPtr->audioTrackPtr->Chunk)
169        {
170            free(mMp4FileDataPtr->audioTrackPtr->Chunk);
171        }
172        if (M4OSA_NULL != mMp4FileDataPtr->audioTrackPtr->chunkSizeTable)
173        {
174            free(mMp4FileDataPtr->audioTrackPtr->chunkSizeTable);
175        }
176        if (M4OSA_NULL != mMp4FileDataPtr->audioTrackPtr->chunkSampleNbTable)
177        {
178            free(mMp4FileDataPtr->audioTrackPtr->chunkSampleNbTable);
179        }
180        if (M4OSA_NULL != mMp4FileDataPtr->audioTrackPtr->chunkTimeMsTable)
181        {
182            free(mMp4FileDataPtr->audioTrackPtr->chunkTimeMsTable);
183        }
184
185        if (mMp4FileDataPtr->audioTrackPtr->TABLE_STTS != M4OSA_NULL)
186        {
187            free(mMp4FileDataPtr->audioTrackPtr->TABLE_STTS);
188        }
189
190        if (mMp4FileDataPtr->audioTrackPtr->TABLE_STSZ != M4OSA_NULL)
191        {
192            free(mMp4FileDataPtr->audioTrackPtr->TABLE_STSZ);
193        }
194
195        if (mMp4FileDataPtr->audioTrackPtr->DSI != M4OSA_NULL)
196        {
197            free(mMp4FileDataPtr->audioTrackPtr->DSI);
198            mMp4FileDataPtr->audioTrackPtr->DSI = M4OSA_NULL;
199        }
200
201        free(mMp4FileDataPtr->audioTrackPtr);
202        mMp4FileDataPtr->audioTrackPtr = M4OSA_NULL;
203    }
204    if (mMp4FileDataPtr->videoTrackPtr != M4OSA_NULL)
205    {
206        /*delete also other chunks if any*/
207        /*for (i=0; i<=mMp4FileDataPtr->videoTrackPtr->currentChunk; i++)*/
208
209#ifdef _M4MP4W_MOOV_FIRST
210        for (i=0; i<=mMp4FileDataPtr->videoTrackPtr->LastAllocatedChunk; i++)
211        {
212            free(mMp4FileDataPtr->videoTrackPtr->Chunk[i]);
213        }
214#else
215        if ((M4OSA_NULL != mMp4FileDataPtr->videoTrackPtr->Chunk) &&
216             (M4OSA_NULL != mMp4FileDataPtr->videoTrackPtr->Chunk[0]))
217        {
218            free(mMp4FileDataPtr->videoTrackPtr->Chunk[0]);
219        }
220        if (M4OSA_NULL != mMp4FileDataPtr->videoTrackPtr->chunkOffsetTable)
221        {
222            free(mMp4FileDataPtr->videoTrackPtr->chunkOffsetTable);
223        }
224#endif /*_M4MP4W_MOOV_FIRST*/
225
226        /*now dynamic*/
227        if (M4OSA_NULL != mMp4FileDataPtr->videoTrackPtr->Chunk)
228        {
229            free(mMp4FileDataPtr->videoTrackPtr->Chunk);
230        }
231        if (M4OSA_NULL != mMp4FileDataPtr->videoTrackPtr->chunkSizeTable)
232        {
233            free(mMp4FileDataPtr->videoTrackPtr->chunkSizeTable);
234        }
235        if (M4OSA_NULL != mMp4FileDataPtr->videoTrackPtr->chunkSampleNbTable)
236        {
237            free(mMp4FileDataPtr->videoTrackPtr->chunkSampleNbTable);
238        }
239        if (M4OSA_NULL != mMp4FileDataPtr->videoTrackPtr->chunkTimeMsTable)
240        {
241            free(mMp4FileDataPtr->videoTrackPtr->chunkTimeMsTable);
242        }
243
244        if (mMp4FileDataPtr->videoTrackPtr->DSI != M4OSA_NULL)
245        {
246            free(mMp4FileDataPtr->videoTrackPtr->DSI);
247            mMp4FileDataPtr->videoTrackPtr->DSI = M4OSA_NULL;
248        }
249
250        /*now dynamic*/
251        if (M4OSA_NULL != mMp4FileDataPtr->videoTrackPtr->TABLE_STTS)
252        {
253            free(mMp4FileDataPtr->videoTrackPtr->TABLE_STTS);
254        }
255        if (M4OSA_NULL != mMp4FileDataPtr->videoTrackPtr->TABLE_STSZ)
256        {
257            free(mMp4FileDataPtr->videoTrackPtr->TABLE_STSZ);
258        }
259        if (M4OSA_NULL != mMp4FileDataPtr->videoTrackPtr->TABLE_STSS)
260        {
261            free(mMp4FileDataPtr->videoTrackPtr->TABLE_STSS);
262        }
263
264        free(mMp4FileDataPtr->videoTrackPtr);
265        mMp4FileDataPtr->videoTrackPtr = M4OSA_NULL;
266    }
267
268    if (mMp4FileDataPtr->embeddedString != M4OSA_NULL)
269    {
270        free(mMp4FileDataPtr->embeddedString);
271        mMp4FileDataPtr->embeddedString = M4OSA_NULL;
272    }
273
274    free(mMp4FileDataPtr);
275
276    return M4NO_ERROR;
277}
278
279#ifdef _M4MP4W_OPTIMIZE_FOR_PHONE
280/*******************************************************************************/
281M4OSA_Void M4MP4W_put32_Hi(M4OSA_UInt32* tab, M4OSA_UInt16 Hi)
282/*******************************************************************************/
283{
284    *tab &= 0xFFFF;
285    *tab |= Hi<<16;
286}
287
288/*******************************************************************************/
289M4OSA_Void M4MP4W_put32_Lo(M4OSA_UInt32* tab, M4OSA_UInt16 Lo)
290/*******************************************************************************/
291{
292    *tab &= 0xFFFF0000;
293    *tab |= Lo;
294}
295
296/*******************************************************************************/
297M4OSA_UInt16 M4MP4W_get32_Hi(M4OSA_UInt32* tab)
298/*******************************************************************************/
299{
300    return (*tab >> 16) & 0xFFFF;
301}
302
303/*******************************************************************************/
304M4OSA_UInt16 M4MP4W_get32_Lo(M4OSA_UInt32* tab)
305/*******************************************************************************/
306{
307    return *tab & 0xFFFF;
308}
309#endif
310
311#endif /* _M4MP4W_USE_CST_MEMORY_WRITER */
312
313