sl@0
|
1 |
// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
// All rights reserved.
|
sl@0
|
3 |
// This component and the accompanying materials are made available
|
sl@0
|
4 |
// under the terms of "Eclipse Public License v1.0"
|
sl@0
|
5 |
// which accompanies this distribution, and is available
|
sl@0
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
//
|
sl@0
|
8 |
// Initial Contributors:
|
sl@0
|
9 |
// Nokia Corporation - initial contribution.
|
sl@0
|
10 |
//
|
sl@0
|
11 |
// Contributors:
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// Description:
|
sl@0
|
14 |
//
|
sl@0
|
15 |
|
sl@0
|
16 |
// INCLUDE FILES
|
sl@0
|
17 |
#include <e32base.h>
|
sl@0
|
18 |
#include <f32file.h>
|
sl@0
|
19 |
#include <f32file64.h>
|
sl@0
|
20 |
#include <3gplibrary/mp4lib.h>
|
sl@0
|
21 |
#include "mp4atom.h"
|
sl@0
|
22 |
#include "mp4memwrap.h"
|
sl@0
|
23 |
#include "asyncfileparser.h"
|
sl@0
|
24 |
|
sl@0
|
25 |
// MACROS
|
sl@0
|
26 |
// Debug print macro
|
sl@0
|
27 |
#if defined(_DEBUG) && defined(_ASYNCFILEPARSERLOGGING)
|
sl@0
|
28 |
#include <e32svr.h>
|
sl@0
|
29 |
#define PRINT(x)
|
sl@0
|
30 |
#else
|
sl@0
|
31 |
#define PRINT(x)
|
sl@0
|
32 |
#endif
|
sl@0
|
33 |
|
sl@0
|
34 |
// ============================ MEMBER FUNCTIONS ===============================
|
sl@0
|
35 |
|
sl@0
|
36 |
// -----------------------------------------------------------------------------
|
sl@0
|
37 |
// CFileAsyncParser::CFileAsyncParser
|
sl@0
|
38 |
// C++ default constructor can NOT contain any code, that
|
sl@0
|
39 |
// might leave.
|
sl@0
|
40 |
// -----------------------------------------------------------------------------
|
sl@0
|
41 |
//
|
sl@0
|
42 |
CFileAsyncParser::CFileAsyncParser() : CActive( EPriorityHigh ), iDiskBufferPointer(NULL,0)
|
sl@0
|
43 |
{
|
sl@0
|
44 |
|
sl@0
|
45 |
}
|
sl@0
|
46 |
|
sl@0
|
47 |
// -----------------------------------------------------------------------------
|
sl@0
|
48 |
// CFileAsyncParser::ConstructL
|
sl@0
|
49 |
// Symbian 2nd phase constructor can leave.
|
sl@0
|
50 |
// -----------------------------------------------------------------------------
|
sl@0
|
51 |
//
|
sl@0
|
52 |
void CFileAsyncParser::ConstructL( MP4HandleStruct* aHandle, RFile64& aFile )
|
sl@0
|
53 |
{
|
sl@0
|
54 |
PRINT(_L("CFileAsyncParser::ConstructL() IN"));
|
sl@0
|
55 |
iError = KErrNone;
|
sl@0
|
56 |
iInputFile = &aFile;
|
sl@0
|
57 |
iHandle = aHandle;
|
sl@0
|
58 |
iAudioSize = 0;
|
sl@0
|
59 |
iReturnedAudioFrames = 0;
|
sl@0
|
60 |
iAudioTimeStamp = 0;
|
sl@0
|
61 |
iAudioTimeStamp2 = 1; // always fill timestamp2 too (null = dont fill)
|
sl@0
|
62 |
iAllDataInMemory = EFalse;
|
sl@0
|
63 |
|
sl@0
|
64 |
if ( iHandle->readBufferSize == 0)
|
sl@0
|
65 |
{
|
sl@0
|
66 |
iReadBufferSize = READBUFSIZE;
|
sl@0
|
67 |
}
|
sl@0
|
68 |
else
|
sl@0
|
69 |
{
|
sl@0
|
70 |
iReadBufferSize = iHandle->readBufferSize;
|
sl@0
|
71 |
}
|
sl@0
|
72 |
|
sl@0
|
73 |
iDiskBuffer = HBufC8::NewL(iReadBufferSize);
|
sl@0
|
74 |
iCurrentDiskReadPosition = 0;
|
sl@0
|
75 |
iCurrentBufferReadPosition = 0;
|
sl@0
|
76 |
CActiveScheduler::Add(this);
|
sl@0
|
77 |
|
sl@0
|
78 |
PRINT(_L("CFileAsyncParser::ConstructL() OUT"));
|
sl@0
|
79 |
}
|
sl@0
|
80 |
|
sl@0
|
81 |
// -----------------------------------------------------------------------------
|
sl@0
|
82 |
// CFileAsyncParser::NewL
|
sl@0
|
83 |
// Two-phased constructor.
|
sl@0
|
84 |
// -----------------------------------------------------------------------------
|
sl@0
|
85 |
//
|
sl@0
|
86 |
CFileAsyncParser* CFileAsyncParser::NewL( MP4HandleStruct* aHandle, RFile64& aFile )
|
sl@0
|
87 |
{
|
sl@0
|
88 |
CFileAsyncParser* self = new(ELeave) CFileAsyncParser;
|
sl@0
|
89 |
CleanupStack::PushL(self);
|
sl@0
|
90 |
self->ConstructL( aHandle, aFile );
|
sl@0
|
91 |
CleanupStack::Pop(self);
|
sl@0
|
92 |
return self;
|
sl@0
|
93 |
}
|
sl@0
|
94 |
|
sl@0
|
95 |
// -----------------------------------------------------------------------------
|
sl@0
|
96 |
// Destructor
|
sl@0
|
97 |
// -----------------------------------------------------------------------------
|
sl@0
|
98 |
//
|
sl@0
|
99 |
CFileAsyncParser::~CFileAsyncParser()
|
sl@0
|
100 |
{
|
sl@0
|
101 |
PRINT(_L("CFileAsyncParser::~CFileAsyncParser() in"));
|
sl@0
|
102 |
|
sl@0
|
103 |
if ( IsActive() )
|
sl@0
|
104 |
{
|
sl@0
|
105 |
if ( iAsyncReadOngoing )
|
sl@0
|
106 |
{
|
sl@0
|
107 |
Cancel();
|
sl@0
|
108 |
}
|
sl@0
|
109 |
}
|
sl@0
|
110 |
|
sl@0
|
111 |
delete iDiskBuffer;
|
sl@0
|
112 |
PRINT(_L("CFileAsyncParser::~CFileAsyncParser() out"));
|
sl@0
|
113 |
}
|
sl@0
|
114 |
|
sl@0
|
115 |
// -----------------------------------------------------------------------------
|
sl@0
|
116 |
// CFileAsyncParser::ReadAudioFrames( );
|
sl@0
|
117 |
// Writes incoming buffer data to internal buffers for writing to disk.
|
sl@0
|
118 |
// (other items were commented in a header).
|
sl@0
|
119 |
// -----------------------------------------------------------------------------
|
sl@0
|
120 |
//
|
sl@0
|
121 |
TInt CFileAsyncParser::ReadAudioFrames( mp4_u8 *buffer, mp4_i64 aPosition, mp4_u32 aBytesToRead )
|
sl@0
|
122 |
{
|
sl@0
|
123 |
PRINT(_L("CFileAsyncParser::ReadAudioFrames()"));
|
sl@0
|
124 |
iProcessingAudio = ETrue;
|
sl@0
|
125 |
return ReadDataAsync( buffer, aPosition, aBytesToRead );
|
sl@0
|
126 |
}
|
sl@0
|
127 |
|
sl@0
|
128 |
// -----------------------------------------------------------------------------
|
sl@0
|
129 |
// CFileAsyncParser::ReadVideoFrame( );
|
sl@0
|
130 |
// Writes incoming buffer data to internal buffers for writing to disk.
|
sl@0
|
131 |
// (other items were commented in a header).
|
sl@0
|
132 |
// -----------------------------------------------------------------------------
|
sl@0
|
133 |
//
|
sl@0
|
134 |
TInt CFileAsyncParser::ReadVideoFrame( mp4_u8* buffer, mp4_i64 aPosition, mp4_u32 aBytesToRead )
|
sl@0
|
135 |
{
|
sl@0
|
136 |
PRINT(_L("CFileAsyncParser::ReadVideoFrame()"));
|
sl@0
|
137 |
iProcessingAudio = EFalse;
|
sl@0
|
138 |
return ReadDataAsync( buffer, aPosition, aBytesToRead );
|
sl@0
|
139 |
}
|
sl@0
|
140 |
|
sl@0
|
141 |
|
sl@0
|
142 |
// -----------------------------------------------------------------------------
|
sl@0
|
143 |
// CFileAsyncParser::ReadDataAsync( );
|
sl@0
|
144 |
// Reads data from file asynchronously.
|
sl@0
|
145 |
// (other items were commented in a header).
|
sl@0
|
146 |
// -----------------------------------------------------------------------------
|
sl@0
|
147 |
//
|
sl@0
|
148 |
TInt CFileAsyncParser::ReadDataAsync( mp4_u8 *buffer, mp4_i64 aPosition, mp4_u32 aBytesToRead )
|
sl@0
|
149 |
{
|
sl@0
|
150 |
PRINT(_L("CFileAsyncParser::ReadDataAsync() in"));
|
sl@0
|
151 |
iBuffer = buffer;
|
sl@0
|
152 |
if ( iAsyncReadOngoing )
|
sl@0
|
153 |
{
|
sl@0
|
154 |
return -1; // only one async read can be ongoing at one time;
|
sl@0
|
155 |
}
|
sl@0
|
156 |
if (!iDiskBuffer)
|
sl@0
|
157 |
{
|
sl@0
|
158 |
return -1;
|
sl@0
|
159 |
}
|
sl@0
|
160 |
|
sl@0
|
161 |
// Is the new seek point inside the current disk buffer?
|
sl@0
|
162 |
if ( (iCurrentDiskReadPosition > aPosition) &&
|
sl@0
|
163 |
(( iCurrentDiskReadPosition - iDiskBuffer->Length() ) <= aPosition ))
|
sl@0
|
164 |
{
|
sl@0
|
165 |
// Yes
|
sl@0
|
166 |
iCurrentBufferReadPosition = iDiskBuffer->Length() - (iCurrentDiskReadPosition - aPosition);
|
sl@0
|
167 |
}
|
sl@0
|
168 |
else
|
sl@0
|
169 |
{
|
sl@0
|
170 |
// No, set current position and zero diskbuffer
|
sl@0
|
171 |
iCurrentBufferReadPosition = 0;
|
sl@0
|
172 |
iCurrentDiskReadPosition = (mp4_i64)aPosition;
|
sl@0
|
173 |
iDiskBuffer->Des().SetLength(0);
|
sl@0
|
174 |
}
|
sl@0
|
175 |
|
sl@0
|
176 |
iBytesToRead = aBytesToRead;
|
sl@0
|
177 |
iBytesRead = 0;
|
sl@0
|
178 |
TInt available = 0;
|
sl@0
|
179 |
|
sl@0
|
180 |
// How much data is available in diskbuffer.
|
sl@0
|
181 |
available = iDiskBuffer->Length() - iCurrentBufferReadPosition;
|
sl@0
|
182 |
if (available > iBytesToRead)
|
sl@0
|
183 |
{
|
sl@0
|
184 |
available = iBytesToRead;
|
sl@0
|
185 |
}
|
sl@0
|
186 |
|
sl@0
|
187 |
// If any available copy it first to output buffer
|
sl@0
|
188 |
if (available )
|
sl@0
|
189 |
{
|
sl@0
|
190 |
memcpy(iBuffer, iDiskBuffer->Ptr() + iCurrentBufferReadPosition, available);
|
sl@0
|
191 |
iCurrentBufferReadPosition += available;
|
sl@0
|
192 |
iBytesRead += available;
|
sl@0
|
193 |
}
|
sl@0
|
194 |
|
sl@0
|
195 |
// If we got everything from diskbuffer process it right away
|
sl@0
|
196 |
if (iBytesRead == iBytesToRead)
|
sl@0
|
197 |
{
|
sl@0
|
198 |
PRINT(_L("CFileAsyncParser::ReadDataAsync() Data found in memory, no need to read file - return right away"));
|
sl@0
|
199 |
iAllDataInMemory = ETrue;
|
sl@0
|
200 |
SetActive();
|
sl@0
|
201 |
TRequestStatus* tmp = &iStatus;
|
sl@0
|
202 |
User::RequestComplete(tmp, KErrNone);
|
sl@0
|
203 |
PRINT(_L("CFileAsyncParser::ReadDataAsync() out"));
|
sl@0
|
204 |
return MP4_OK;
|
sl@0
|
205 |
}
|
sl@0
|
206 |
else
|
sl@0
|
207 |
{
|
sl@0
|
208 |
// Need to read rest of the requested data from file.
|
sl@0
|
209 |
iAllDataInMemory = EFalse;
|
sl@0
|
210 |
}
|
sl@0
|
211 |
|
sl@0
|
212 |
// Determine used readbuffer size
|
sl@0
|
213 |
if ( iHandle->readBufferSize == 0)
|
sl@0
|
214 |
{
|
sl@0
|
215 |
iReadBufferSize = READBUFSIZE;
|
sl@0
|
216 |
}
|
sl@0
|
217 |
else
|
sl@0
|
218 |
{
|
sl@0
|
219 |
iReadBufferSize = iHandle->readBufferSize;
|
sl@0
|
220 |
}
|
sl@0
|
221 |
|
sl@0
|
222 |
// Increase disk read buffer size if requested frames are larger than current disk buffer.
|
sl@0
|
223 |
if ( (iBytesToRead > iReadBufferSize ) || (iReadBufferSize != iDiskBuffer->Des().MaxLength()) )
|
sl@0
|
224 |
{
|
sl@0
|
225 |
iReadBufferSize = iBytesToRead;
|
sl@0
|
226 |
if (iDiskBuffer)
|
sl@0
|
227 |
{
|
sl@0
|
228 |
delete iDiskBuffer;
|
sl@0
|
229 |
iDiskBuffer = NULL;
|
sl@0
|
230 |
TRAPD(memerror, iDiskBuffer = HBufC8::NewL(iReadBufferSize));
|
sl@0
|
231 |
if (memerror)
|
sl@0
|
232 |
{
|
sl@0
|
233 |
return MP4_OUT_OF_MEMORY;
|
sl@0
|
234 |
}
|
sl@0
|
235 |
else
|
sl@0
|
236 |
{
|
sl@0
|
237 |
iCurrentBufferReadPosition = 0;
|
sl@0
|
238 |
}
|
sl@0
|
239 |
}
|
sl@0
|
240 |
}
|
sl@0
|
241 |
|
sl@0
|
242 |
iAsyncReadOngoing = ETrue;
|
sl@0
|
243 |
iDiskBufferPointer.Set(iDiskBuffer->Des());
|
sl@0
|
244 |
iCurrentDiskReadPosition = aPosition + iBytesRead;
|
sl@0
|
245 |
switch (iHandle->sourceType)
|
sl@0
|
246 |
{
|
sl@0
|
247 |
case MP4_SOURCE_RFILE:
|
sl@0
|
248 |
{
|
sl@0
|
249 |
PRINT(_L("CFileAsyncParser::ReadDataAsync() Data not in memory, reading RFile64"));
|
sl@0
|
250 |
RFile64* rfile = (RFile64*)iHandle->rfile;
|
sl@0
|
251 |
rfile->Read(iCurrentDiskReadPosition, iDiskBufferPointer, iDiskBufferPointer.MaxLength(), iStatus);
|
sl@0
|
252 |
break;
|
sl@0
|
253 |
}
|
sl@0
|
254 |
case MP4_SOURCE_CAF:
|
sl@0
|
255 |
{
|
sl@0
|
256 |
PRINT(_L("CFileAsyncParser::ReadDataAsync() Data not in memory, reading CAF object"));
|
sl@0
|
257 |
iHandle->cafError = iHandle->cfile->Read(iCurrentDiskReadPosition, iDiskBufferPointer, iDiskBufferPointer.MaxLength(), iStatus);
|
sl@0
|
258 |
if ( iHandle->cafError != KErrNone)
|
sl@0
|
259 |
return -2;
|
sl@0
|
260 |
break;
|
sl@0
|
261 |
}
|
sl@0
|
262 |
default:
|
sl@0
|
263 |
return -1;
|
sl@0
|
264 |
}
|
sl@0
|
265 |
|
sl@0
|
266 |
if ( !IsActive() )
|
sl@0
|
267 |
{
|
sl@0
|
268 |
SetActive();
|
sl@0
|
269 |
}
|
sl@0
|
270 |
PRINT(_L("CFileAsyncParser::ReadDataAsync() out"));
|
sl@0
|
271 |
return 0;
|
sl@0
|
272 |
}
|
sl@0
|
273 |
|
sl@0
|
274 |
|
sl@0
|
275 |
|
sl@0
|
276 |
// -----------------------------------------------------------------------------
|
sl@0
|
277 |
// CFileAsyncParser::DoCancel()
|
sl@0
|
278 |
// From CActive Cancels async request.
|
sl@0
|
279 |
// -----------------------------------------------------------------------------
|
sl@0
|
280 |
//
|
sl@0
|
281 |
void CFileAsyncParser::DoCancel()
|
sl@0
|
282 |
{
|
sl@0
|
283 |
PRINT(_L("CFileAsyncParser::DoCancel() in"));
|
sl@0
|
284 |
if (iAsyncReadOngoing)
|
sl@0
|
285 |
{
|
sl@0
|
286 |
if (iHandle->sourceType == MP4_SOURCE_RFILE)
|
sl@0
|
287 |
{
|
sl@0
|
288 |
// cancel read from file
|
sl@0
|
289 |
((RFile64 *)(iHandle->rfile))->ReadCancel();
|
sl@0
|
290 |
}
|
sl@0
|
291 |
else if (iHandle->sourceType == MP4_SOURCE_CAF)
|
sl@0
|
292 |
{
|
sl@0
|
293 |
// cancel read from caf object
|
sl@0
|
294 |
iHandle->cfile->ReadCancel(iStatus);
|
sl@0
|
295 |
}
|
sl@0
|
296 |
iAsyncReadOngoing = EFalse;
|
sl@0
|
297 |
}
|
sl@0
|
298 |
|
sl@0
|
299 |
PRINT(_L("CFileAsyncParser::DoCancel() out"));
|
sl@0
|
300 |
}
|
sl@0
|
301 |
|
sl@0
|
302 |
// -----------------------------------------------------------------------------
|
sl@0
|
303 |
// CFileAsyncParser::ReturnAudioFrames()
|
sl@0
|
304 |
// Return audio frames to observer.
|
sl@0
|
305 |
// -----------------------------------------------------------------------------
|
sl@0
|
306 |
//
|
sl@0
|
307 |
void CFileAsyncParser::ReturnAudioFrames()
|
sl@0
|
308 |
{
|
sl@0
|
309 |
PRINT(_L("CFileAsyncParser::ReturnAudioFrames() in"));
|
sl@0
|
310 |
TInt error = KErrNone;
|
sl@0
|
311 |
|
sl@0
|
312 |
// Update last accessed position in file pointer
|
sl@0
|
313 |
if (iHandle->audioSampleOffset + iHandle->audioSampleSize - 1 > iHandle->lastAccessedPosInFile)
|
sl@0
|
314 |
{
|
sl@0
|
315 |
iHandle->lastAccessedPosInFile = iHandle->audioSampleOffset + iHandle->audioSampleSize - 1;
|
sl@0
|
316 |
}
|
sl@0
|
317 |
|
sl@0
|
318 |
// Fill audio frame size
|
sl@0
|
319 |
iAudioSize = iHandle->audioSampleSize;
|
sl@0
|
320 |
|
sl@0
|
321 |
// Fill audio timestamp information
|
sl@0
|
322 |
iAudioTimeStamp = 0;
|
sl@0
|
323 |
iAudioTimeStamp2 = 1; // fill also timestamp2 (wont be filled if 0)
|
sl@0
|
324 |
error = convertAudioSampleToTime(iHandle, iHandle->moov->trakAudio->mdia, &iAudioTimeStamp, &iAudioTimeStamp2);
|
sl@0
|
325 |
if (error == MP4_OK)
|
sl@0
|
326 |
{
|
sl@0
|
327 |
// Fill iReturnedAudioFrames
|
sl@0
|
328 |
iReturnedAudioFrames = 0;
|
sl@0
|
329 |
error = CalculateAudioFrameCount();
|
sl@0
|
330 |
}
|
sl@0
|
331 |
|
sl@0
|
332 |
// Move forward in audio samples
|
sl@0
|
333 |
if (error == MP4_OK)
|
sl@0
|
334 |
{
|
sl@0
|
335 |
error = advanceAudioSample(iHandle, iHandle->moov->trakAudio);
|
sl@0
|
336 |
if ( error == -1)
|
sl@0
|
337 |
{
|
sl@0
|
338 |
error = MP4_ERROR;
|
sl@0
|
339 |
}
|
sl@0
|
340 |
else if ( error == -2 )
|
sl@0
|
341 |
{
|
sl@0
|
342 |
error = MP4_OK;
|
sl@0
|
343 |
iHandle->audioLast = MP4TRUE;
|
sl@0
|
344 |
}
|
sl@0
|
345 |
}
|
sl@0
|
346 |
|
sl@0
|
347 |
iAsyncReadOngoing = EFalse;
|
sl@0
|
348 |
iHandle->asyncObserver->M3GPMP4LibAudioFramesAvailable(error,
|
sl@0
|
349 |
iAudioSize,
|
sl@0
|
350 |
iAudioTimeStamp,
|
sl@0
|
351 |
iReturnedAudioFrames,
|
sl@0
|
352 |
iAudioTimeStamp2);
|
sl@0
|
353 |
PRINT(_L("CFileAsyncParser::ReturnAudioFrames() out"));
|
sl@0
|
354 |
}
|
sl@0
|
355 |
|
sl@0
|
356 |
// -----------------------------------------------------------------------------
|
sl@0
|
357 |
// CFileAsyncParser::ReturnVideoFrame()
|
sl@0
|
358 |
// Return video frame to observer.
|
sl@0
|
359 |
// -----------------------------------------------------------------------------
|
sl@0
|
360 |
//
|
sl@0
|
361 |
void CFileAsyncParser::ReturnVideoFrame()
|
sl@0
|
362 |
{
|
sl@0
|
363 |
PRINT(_L("CFileAsyncParser::ReturnVideoFrame() in"));
|
sl@0
|
364 |
TInt error = KErrNone;
|
sl@0
|
365 |
|
sl@0
|
366 |
// Update last accessed position in file pointer
|
sl@0
|
367 |
if (iHandle->videoFrameOffset + iHandle->videoFrameSize - 1 > iHandle->lastAccessedPosInFile)
|
sl@0
|
368 |
{
|
sl@0
|
369 |
iHandle->lastAccessedPosInFile = iHandle->videoFrameOffset + iHandle->videoFrameSize - 1;
|
sl@0
|
370 |
}
|
sl@0
|
371 |
|
sl@0
|
372 |
// Fill video frame size
|
sl@0
|
373 |
iVideoSize = iHandle->videoFrameSize;
|
sl@0
|
374 |
|
sl@0
|
375 |
// Fill video timestamp information
|
sl@0
|
376 |
iVideoTimeStamp = 0;
|
sl@0
|
377 |
iVideoTimeStamp2 = 1; // fill also timestamp2 (wont be filled if 0)
|
sl@0
|
378 |
error = convertVideoSampleToTime(iHandle, iHandle->moov->trakVideo->mdia, &iVideoTimeStamp, &iVideoTimeStamp2);
|
sl@0
|
379 |
if (error == MP4_OK)
|
sl@0
|
380 |
{
|
sl@0
|
381 |
// Fill iKeyFrame
|
sl@0
|
382 |
iVideoKeyFrame = 0;
|
sl@0
|
383 |
error = isVideoFrameKeyFrame(iHandle, iHandle->moov->trakVideo, &iVideoKeyFrame);
|
sl@0
|
384 |
}
|
sl@0
|
385 |
|
sl@0
|
386 |
// Move forward in video frames
|
sl@0
|
387 |
if (error == MP4_OK)
|
sl@0
|
388 |
{
|
sl@0
|
389 |
error = advanceVideoFrame(iHandle, iHandle->moov->trakVideo);
|
sl@0
|
390 |
if ( error == -1)
|
sl@0
|
391 |
{
|
sl@0
|
392 |
error = MP4_ERROR;
|
sl@0
|
393 |
}
|
sl@0
|
394 |
else if ( error == -2 )
|
sl@0
|
395 |
{
|
sl@0
|
396 |
error = MP4_OK;
|
sl@0
|
397 |
iHandle->videoLast = MP4TRUE;
|
sl@0
|
398 |
}
|
sl@0
|
399 |
}
|
sl@0
|
400 |
|
sl@0
|
401 |
iAsyncReadOngoing = EFalse;
|
sl@0
|
402 |
iHandle->asyncObserver->M3GPMP4LibVideoFrameAvailable(error,
|
sl@0
|
403 |
iVideoSize,
|
sl@0
|
404 |
iVideoTimeStamp,
|
sl@0
|
405 |
iVideoKeyFrame,
|
sl@0
|
406 |
iVideoTimeStamp2);
|
sl@0
|
407 |
PRINT(_L("CFileAsyncParser::ReturnVideoFrame() out"));
|
sl@0
|
408 |
}
|
sl@0
|
409 |
|
sl@0
|
410 |
// -----------------------------------------------------------------------------
|
sl@0
|
411 |
// CFileAsyncParser::CalculateAudioFrameCount()
|
sl@0
|
412 |
// Return video frame to observer.
|
sl@0
|
413 |
// -----------------------------------------------------------------------------
|
sl@0
|
414 |
//
|
sl@0
|
415 |
TInt CFileAsyncParser::CalculateAudioFrameCount()
|
sl@0
|
416 |
{
|
sl@0
|
417 |
mp4_i32 frameLength = 0;
|
sl@0
|
418 |
mp4_u32 numOfFrames = 0;
|
sl@0
|
419 |
mp4_u8 *framepointer = 0;
|
sl@0
|
420 |
mp4_u32 rawAmrFrameLength[16] = {13,14,16,18,20,21,27,32,6,0,0,0,0,0,0,1};
|
sl@0
|
421 |
trackAtom *trak = iHandle->moov->trakAudio;
|
sl@0
|
422 |
|
sl@0
|
423 |
if (!trak)
|
sl@0
|
424 |
{
|
sl@0
|
425 |
return -1;
|
sl@0
|
426 |
}
|
sl@0
|
427 |
|
sl@0
|
428 |
/* AMR */
|
sl@0
|
429 |
if (trak->mdia->minf)
|
sl@0
|
430 |
if (trak->mdia->minf->stbl)
|
sl@0
|
431 |
if (trak->mdia->minf->stbl->stsd)
|
sl@0
|
432 |
if (iHandle->type & MP4_TYPE_AMR_NB)
|
sl@0
|
433 |
{
|
sl@0
|
434 |
framepointer = iBuffer;
|
sl@0
|
435 |
numOfFrames = 0;
|
sl@0
|
436 |
while ( iBytesRead > 0 )
|
sl@0
|
437 |
{
|
sl@0
|
438 |
frameLength = rawAmrFrameLength[(TInt)(((*framepointer) & 0x78) >> 3)];
|
sl@0
|
439 |
if ( frameLength == 0)
|
sl@0
|
440 |
{
|
sl@0
|
441 |
return -4;
|
sl@0
|
442 |
}
|
sl@0
|
443 |
iBytesRead -= frameLength;
|
sl@0
|
444 |
framepointer += frameLength;
|
sl@0
|
445 |
numOfFrames++;
|
sl@0
|
446 |
}
|
sl@0
|
447 |
iReturnedAudioFrames = numOfFrames;
|
sl@0
|
448 |
}
|
sl@0
|
449 |
else if (iHandle->type & MP4_TYPE_AMR_WB)
|
sl@0
|
450 |
{
|
sl@0
|
451 |
/* Return the number of sample entries listed for this particular sample entry index */
|
sl@0
|
452 |
if (trak->mdia->minf->stbl->stsd->sawb[iHandle->audioSampleEntryIndex - 1])
|
sl@0
|
453 |
if (trak->mdia->minf->stbl->stsd->sawb[iHandle->audioSampleEntryIndex - 1]->damr)
|
sl@0
|
454 |
iReturnedAudioFrames = trak->mdia->minf->stbl->stsd->sawb[iHandle->audioSampleEntryIndex - 1]->damr->framesPerSample;
|
sl@0
|
455 |
}
|
sl@0
|
456 |
else
|
sl@0
|
457 |
{
|
sl@0
|
458 |
}
|
sl@0
|
459 |
|
sl@0
|
460 |
/* MPEG-4 audio */
|
sl@0
|
461 |
if (trak->mdia->minf)
|
sl@0
|
462 |
if (trak->mdia->minf->stbl)
|
sl@0
|
463 |
if (trak->mdia->minf->stbl->stsd)
|
sl@0
|
464 |
if (trak->mdia->minf->stbl->stsd->mp4a[iHandle->audioSampleEntryIndex - 1])
|
sl@0
|
465 |
iReturnedAudioFrames = 1;
|
sl@0
|
466 |
|
sl@0
|
467 |
/* QCELP 13K as QCELPSampleEntry*/
|
sl@0
|
468 |
if (trak->mdia->minf)
|
sl@0
|
469 |
if (trak->mdia->minf->stbl)
|
sl@0
|
470 |
if (trak->mdia->minf->stbl->stsd)
|
sl@0
|
471 |
if ((iHandle->type & MP4_TYPE_QCELP_13K) && (!iHandle->qcelpStoredAsMPEGAudio))
|
sl@0
|
472 |
{
|
sl@0
|
473 |
/* Return the number of sample entries listed for this particular sample entry index */
|
sl@0
|
474 |
if (trak->mdia->minf->stbl->stsd->sqcp[iHandle->audioSampleEntryIndex - 1])
|
sl@0
|
475 |
if (trak->mdia->minf->stbl->stsd->sqcp[iHandle->audioSampleEntryIndex - 1]->dqcp)
|
sl@0
|
476 |
iReturnedAudioFrames = trak->mdia->minf->stbl->stsd->sqcp[iHandle->audioSampleEntryIndex - 1]->dqcp->framesPerSample;
|
sl@0
|
477 |
}
|
sl@0
|
478 |
|
sl@0
|
479 |
/* QCELP 13K as MPEG-4 audio */
|
sl@0
|
480 |
if (trak->mdia->minf)
|
sl@0
|
481 |
if (trak->mdia->minf->stbl)
|
sl@0
|
482 |
if (trak->mdia->minf->stbl->stsd)
|
sl@0
|
483 |
if (trak->mdia->minf->stbl->stsd->mp4a[iHandle->audioSampleEntryIndex - 1])
|
sl@0
|
484 |
iReturnedAudioFrames = 1;
|
sl@0
|
485 |
|
sl@0
|
486 |
return MP4_OK;
|
sl@0
|
487 |
}
|
sl@0
|
488 |
|
sl@0
|
489 |
// -----------------------------------------------------------------------------
|
sl@0
|
490 |
// CFileAsyncParser::RunL()
|
sl@0
|
491 |
// From CActive Called when async request completes.
|
sl@0
|
492 |
// -----------------------------------------------------------------------------
|
sl@0
|
493 |
//
|
sl@0
|
494 |
void CFileAsyncParser::RunL()
|
sl@0
|
495 |
{
|
sl@0
|
496 |
PRINT(_L("CFileAsyncParser::RunL() in"));
|
sl@0
|
497 |
if ( iStatus != KErrNone )
|
sl@0
|
498 |
{
|
sl@0
|
499 |
PRINT((_L("CFileAsyncParser::RunL() error in previous async: %d "), iStatus.Int() ));
|
sl@0
|
500 |
iError = iStatus.Int();
|
sl@0
|
501 |
iHandle->asyncObserver->M3GPMP4LibAudioFramesAvailable(MP4_FILE_ERROR,0,0,0,0);
|
sl@0
|
502 |
return;
|
sl@0
|
503 |
}
|
sl@0
|
504 |
|
sl@0
|
505 |
if (!iAllDataInMemory)
|
sl@0
|
506 |
{
|
sl@0
|
507 |
if ((mp4_u32)iDiskBuffer->Length() == 0) // EOF or error
|
sl@0
|
508 |
{
|
sl@0
|
509 |
iError = MP4_FILE_ERROR; // metadata info doesn't match file -> corrupted clip.
|
sl@0
|
510 |
}
|
sl@0
|
511 |
|
sl@0
|
512 |
memcpy(iBuffer+iBytesRead, iDiskBuffer->Ptr(), iBytesToRead-iBytesRead);
|
sl@0
|
513 |
iCurrentBufferReadPosition += iBytesToRead-iBytesRead;
|
sl@0
|
514 |
iCurrentDiskReadPosition += iDiskBuffer->Length();
|
sl@0
|
515 |
iBytesRead = iBytesToRead;
|
sl@0
|
516 |
|
sl@0
|
517 |
// set handle disk buffer sizes to zero just in case.
|
sl@0
|
518 |
iHandle->diskReadBufPos = 0;
|
sl@0
|
519 |
iHandle->diskReadSize = 0;
|
sl@0
|
520 |
iHandle->diskReadBufStart = 0;
|
sl@0
|
521 |
iHandle->diskReadPos = iCurrentDiskReadPosition;
|
sl@0
|
522 |
}
|
sl@0
|
523 |
|
sl@0
|
524 |
if ( iProcessingAudio )
|
sl@0
|
525 |
{
|
sl@0
|
526 |
ReturnAudioFrames();
|
sl@0
|
527 |
}
|
sl@0
|
528 |
else
|
sl@0
|
529 |
{
|
sl@0
|
530 |
ReturnVideoFrame();
|
sl@0
|
531 |
}
|
sl@0
|
532 |
|
sl@0
|
533 |
PRINT(_L("CFileAsyncParser::RunL() out"));
|
sl@0
|
534 |
}
|
sl@0
|
535 |
|
sl@0
|
536 |
// End of File
|