• 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 #include "pv_avifile_header.h"
19 
PVAviFileHeader(PVFile * aFp,uint32 aHdrSize)20 PVAviFileHeader::PVAviFileHeader(PVFile *aFp, uint32 aHdrSize)
21 {
22     iHeaderTotalSize = aHdrSize;
23     uint32 bytesRead = 0;
24     uint32 chunkType = 0;
25     uint32 oldChkType = 0;
26     iError = PV_AVI_FILE_PARSER_SUCCESS;
27 
28     for (uint32 ii = 0; ii < iStreamList.size(); ii++)
29     {
30         iStreamList.pop_back();
31     }
32 
33     uint32 streamListSz = 0;
34 
35     while (bytesRead < iHeaderTotalSize)
36     {
37         oldChkType = chunkType;
38         if ((iError = PVAviFileParserUtils::ReadNextChunkType(aFp, chunkType)) != PV_AVI_FILE_PARSER_SUCCESS)
39         {
40             if ((PV_AVI_FILE_PARSER_UNSUPPORTED_CHUNK == iError))
41             {
42                 PVAVIFILE_LOGINFO((0, "PVAviFileHeader::PVAviFileHeader: Unsupported chunk"));
43 
44                 uint32 chksz = 0;
45                 if (oldChkType != LIST)
46                 {
47                     //get the size of unsupported chunk and skip it.
48                     if (PVAviFileParserUtils::read32(aFp, chksz, true) != PV_AVI_FILE_PARSER_SUCCESS)
49                     {
50                         PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Read Error"));
51                         iError = PV_AVI_FILE_PARSER_READ_ERROR;
52                         break;
53                     }
54 
55                     aFp->Seek(chksz, Oscl_File::SEEKCUR);
56                     bytesRead += chksz + CHUNK_SIZE + CHUNK_SIZE; //data + chunk size + chunk type
57                 }
58                 else
59                 {
60                     //skip the entire list if not supported
61                     aFp->Seek((streamListSz - CHUNK_SIZE), Oscl_File::SEEKCUR); //subtract list name read above
62                     bytesRead += streamListSz;
63                 }
64 
65                 PVAVIFILE_LOGINFO((0, "PVAviFileHeader::PVAviFileHeader: Unsupported chunk skipped"));
66                 iError = PV_AVI_FILE_PARSER_SUCCESS;
67                 continue;
68             }
69             else
70             {
71                 break;
72             }
73         }
74 
75         bytesRead += CHUNK_SIZE;
76 
77         if (bytesRead > iHeaderTotalSize)
78         {
79             PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Size & Byte Count mismatch"));
80             iError =  PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
81             break;
82         }
83 
84         if (AVIH == chunkType)
85         {
86             uint32 aviStrSize = 0;
87             if (PVAviFileParserUtils::read32(aFp, aviStrSize, true) != PV_AVI_FILE_PARSER_SUCCESS)
88             {
89                 PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Read Error"));
90                 iError = PV_AVI_FILE_PARSER_READ_ERROR;
91                 break;
92             }
93 
94             bytesRead += CHUNK_SIZE;
95 
96             if (bytesRead > iHeaderTotalSize)
97             {
98                 PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Size & Byte Count mismatch"));
99                 iError =  PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
100                 break;
101             }
102 
103             if ((aviStrSize <= 0) || (aviStrSize > iHeaderTotalSize))
104             {
105                 PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: AVIH size greater than file header size"));
106                 iError =  PV_AVI_FILE_PARSER_WRONG_SIZE;
107                 break;
108             }
109 
110             if ((iError = ParseMainHeader(aFp)) != PV_AVI_FILE_PARSER_SUCCESS)
111             {
112                 PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: Error encountered while parsing File Header"));
113                 break;
114             }
115 
116             bytesRead += aviStrSize;
117             if (bytesRead > iHeaderTotalSize)
118             {
119                 PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Size & Byte Count mismatch"));
120                 iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
121                 break;
122             }
123         }
124         else if (LIST == chunkType)
125         {
126             if (PVAviFileParserUtils::read32(aFp, streamListSz, true) != PV_AVI_FILE_PARSER_SUCCESS)
127             {
128                 PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Read Error"));
129                 iError =  PV_AVI_FILE_PARSER_READ_ERROR;
130                 break;
131             }
132 
133             bytesRead += CHUNK_SIZE;
134 
135             if (bytesRead > iHeaderTotalSize)
136             {
137                 PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Size & Byte Count mismatch"));
138                 iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
139                 break;
140             }
141 
142             if ((streamListSz <= 0) || (streamListSz > iHeaderTotalSize))
143             {
144                 PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: stream list soze greater tha file header size"));
145                 iError = PV_AVI_FILE_PARSER_WRONG_SIZE;
146                 break;
147             }
148 
149         }
150         else if (STRL == chunkType)
151         {
152             PVAVIFILE_LOGINFO((0, "PVAviFileHeader::PVAviFileHeader: Found stream list"));
153 
154             PVAviFileStreamlist* strlst = OSCL_NEW(PVAviFileStreamlist, (aFp, (streamListSz - CHUNK_SIZE))); //subtract 4 bytes of List type from list size
155             if (strlst != NULL)
156             {
157                 if ((iError = strlst->GetStatus()) != PV_AVI_FILE_PARSER_SUCCESS)
158                 {
159                     OSCL_DELETE(strlst);
160                     strlst = NULL;
161                     break;
162                 }
163             }
164 
165             iStreamList.push_back(*strlst);
166             bytesRead += streamListSz - CHUNK_SIZE;
167             if (bytesRead > iHeaderTotalSize)
168             {
169                 PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Size & Byte Count mismatch"));
170                 iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
171                 break;
172             }
173 
174             OSCL_DELETE(strlst);
175         }
176         else if (JUNK == chunkType)
177         {
178             PVAVIFILE_LOGINFO((0, "PVAviFileParser::ParseFile: Skip Junk data"));
179 
180             uint32 junkSize = 0;
181             if (PVAviFileParserUtils::read32(aFp, junkSize, true) != PV_AVI_FILE_PARSER_SUCCESS)
182             {
183                 PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Read Error"));
184                 iError =  PV_AVI_FILE_PARSER_READ_ERROR;
185                 break;
186             }
187 
188             bytesRead += CHUNK_SIZE;
189             if (bytesRead > iHeaderTotalSize)
190             {
191                 PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Size & Byte Count mismatch"));
192                 iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
193                 break;
194             }
195 
196             if ((junkSize <= 0) || (junkSize > iHeaderTotalSize))
197             {
198                 PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: Junk data size more than file header size"));
199                 iError = PV_AVI_FILE_PARSER_WRONG_SIZE;
200                 break;
201             }
202 
203             aFp->Seek(junkSize, Oscl_File::SEEKCUR);
204             bytesRead += junkSize;
205             if (bytesRead > iHeaderTotalSize)
206             {
207                 PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Size & Byte Count mismatch"));
208                 iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
209                 break;
210             }
211 
212         }
213         else
214         {
215             PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: Chunk not supported in file main header"));
216             iError = PV_AVI_FILE_PARSER_WRONG_CHUNK;
217             break;
218         }
219 
220     }
221 
222     if ((PV_AVI_FILE_PARSER_SUCCESS == iError) && (iStreamList.size() != iMainHeader.iStreams))
223     {
224         PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: "));
225         iError = PV_AVI_FILE_PARSER_ERROR_NUM_STREAM;
226     }
227 
228 
229 }
230 
231 PV_AVI_FILE_PARSER_ERROR_TYPE
ParseMainHeader(PVFile * aFp)232 PVAviFileHeader::ParseMainHeader(PVFile *aFp)
233 {
234     //Read avi main header
235 
236     if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iMainHeader.iMicroSecPerFrame, true)))
237     {
238         return PV_AVI_FILE_PARSER_READ_ERROR;
239     }
240 
241     if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iMainHeader.iMaxBytesPerSec, true)))
242     {
243         return PV_AVI_FILE_PARSER_READ_ERROR;
244     }
245 
246     if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iMainHeader.iPadding, true)))
247     {
248         return PV_AVI_FILE_PARSER_READ_ERROR;
249     }
250 
251     if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iMainHeader.iFlags)))
252     {
253         return PV_AVI_FILE_PARSER_READ_ERROR;
254     }
255 
256     if (iMainHeader.iFlags != 0)
257     {
258         if (iMainHeader.iFlags & AVIF_COPYRIGHTED)
259             iMainHeader.iIsAVIFileCopyrighted = true;
260 
261         if (iMainHeader.iFlags & AVIF_HASINDEX)
262             iMainHeader.iAVIFileHasIndxTbl = true;
263 
264         if (iMainHeader.iFlags & AVIF_ISINTERLEAVED)
265             iMainHeader.iISAVIFileInterleaved = true;
266 
267         if (iMainHeader.iFlags & AVIF_MUSTUSEINDEX)
268             iMainHeader.iAVIFileMustUseIndex = true;
269 
270         if (iMainHeader.iFlags & AVIF_WASCAPTUREFILE)
271             iMainHeader.iAVIFileWasCaptureFile = true;
272     }
273     else
274     {
275         iMainHeader.iIsAVIFileCopyrighted = false;
276         iMainHeader.iAVIFileHasIndxTbl = false;
277         iMainHeader.iISAVIFileInterleaved = false;
278         iMainHeader.iAVIFileMustUseIndex = false;
279         iMainHeader.iAVIFileWasCaptureFile = false;
280     }
281 
282 
283     if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iMainHeader.iTotalFrames, true)))
284     {
285         return PV_AVI_FILE_PARSER_READ_ERROR;
286 
287     }
288 
289     if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iMainHeader.iInitialFrames, true)))
290     {
291         return PV_AVI_FILE_PARSER_READ_ERROR;
292 
293     }
294 
295     if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iMainHeader.iStreams, true)))
296     {
297         return PV_AVI_FILE_PARSER_READ_ERROR;
298 
299     }
300 
301     if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iMainHeader.iSuggestedBufferSize, true)))
302     {
303         return PV_AVI_FILE_PARSER_READ_ERROR;
304 
305     }
306 
307     if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iMainHeader.iWidth, true)))
308     {
309         return PV_AVI_FILE_PARSER_READ_ERROR;
310 
311     }
312 
313     if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iMainHeader.iHeight, true)))
314     {
315         return PV_AVI_FILE_PARSER_READ_ERROR;
316 
317     }
318 
319     for (uint32 ii = 0; ii < RES_BYTES_SZ; ii++)
320     {
321         if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(aFp, iMainHeader.iReserved[ii], true))
322         {
323             return PV_AVI_FILE_PARSER_READ_ERROR;
324         }
325     }
326     return PV_AVI_FILE_PARSER_SUCCESS;
327 }
328 
329 
GetAudioFormat(uint32 aStreamNo)330 uint32 PVAviFileHeader::GetAudioFormat(uint32 aStreamNo)
331 {
332     uint32 strnum = GetNumStreams();
333     uint32 retType = WAVE_FORMAT_UNKNOWN;
334     uint32 ii = 0;
335 
336     for (ii = 0; ii < strnum; ii++)
337     {
338         if ((iStreamList[ii].GetStreamType() == PV_2_AUDIO) && (aStreamNo == ii))
339         {
340             retType = iStreamList[ii].GetAudioFormat();
341         }
342     }
343 
344     return retType;
345 }
346 
347 
GetNumAudioChannels(uint32 aStreamNo)348 uint32 PVAviFileHeader::GetNumAudioChannels(uint32 aStreamNo)
349 {
350     uint32 strnum = GetNumStreams();
351     uint32 retType = 0;
352     uint32 ii = 0;
353 
354     for (ii = 0; ii < strnum; ii++)
355     {
356         if ((iStreamList[ii].GetStreamType() == PV_2_AUDIO) && (ii == aStreamNo))
357         {
358             retType = iStreamList[ii].GetNumAudioChannels();
359         }
360     }
361     return retType;
362 
363 }
364 
365