VideoEditorAudioPlayer.cpp revision 32ed3f4dad00f8a65f7e6b38402c70d5341c57eb
1/*
2 * Copyright (C) 2011 NXP Software
3 * Copyright (C) 2011 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#define LOG_NDEBUG 1
19#define LOG_TAG "VideoEditorAudioPlayer"
20#include <utils/Log.h>
21
22#include <binder/IPCThreadState.h>
23#include <media/AudioTrack.h>
24#include <VideoEditorAudioPlayer.h>
25#include <media/stagefright/MediaDebug.h>
26#include <media/stagefright/MediaDefs.h>
27#include <media/stagefright/MediaErrors.h>
28#include <media/stagefright/MediaSource.h>
29#include <media/stagefright/MetaData.h>
30
31#include "PreviewPlayer.h"
32namespace android {
33
34VideoEditorAudioPlayer::VideoEditorAudioPlayer(
35        const sp<MediaPlayerBase::AudioSink> &audioSink,
36        AwesomePlayer *observer)
37    : AudioPlayer(audioSink, observer) {
38
39    LOGV("VideoEditorAudioPlayer");
40    mBGAudioPCMFileHandle = NULL;
41    mAudioProcess = NULL;
42    mBGAudioPCMFileLength = 0;
43    mBGAudioPCMFileTrimmedLength = 0;
44    mBGAudioPCMFileDuration = 0;
45    mBGAudioPCMFileSeekPoint = 0;
46    mBGAudioPCMFileOriginalSeekPoint = 0;
47    mBGAudioStoryBoardSkimTimeStamp = 0;
48    mBGAudioStoryBoardCurrentMediaBeginCutTS = 0;
49    mBGAudioStoryBoardCurrentMediaVolumeVal = 0;
50    mSeekTimeUs = 0;
51    mSource = NULL;
52}
53
54VideoEditorAudioPlayer::~VideoEditorAudioPlayer() {
55
56    LOGV("~VideoEditorAudioPlayer");
57    if (mStarted) {
58        reset();
59    }
60    if (mAudioProcess != NULL) {
61        delete mAudioProcess;
62        mAudioProcess = NULL;
63    }
64}
65void VideoEditorAudioPlayer::setSource(const sp<MediaSource> &source) {
66    Mutex::Autolock autoLock(mLock);
67
68    // Before setting source, stop any existing source.
69    // Make sure to release any buffer we hold onto so that the
70    // source is able to stop().
71
72    if (mFirstBuffer != NULL) {
73        mFirstBuffer->release();
74        mFirstBuffer = NULL;
75    }
76
77    if (mInputBuffer != NULL) {
78        LOGV("VideoEditorAudioPlayer releasing input buffer.");
79
80        mInputBuffer->release();
81        mInputBuffer = NULL;
82    }
83
84    if (mSource != NULL) {
85        mSource->stop();
86        mSource.clear();
87    }
88
89    mSource = source;
90    mReachedEOS = false;
91}
92
93sp<MediaSource> VideoEditorAudioPlayer::getSource() {
94    Mutex::Autolock autoLock(mLock);
95    return mSource;
96}
97
98void VideoEditorAudioPlayer::setObserver(AwesomePlayer *observer) {
99    LOGV("setObserver");
100    //CHECK(!mStarted);
101    mObserver = observer;
102}
103
104bool VideoEditorAudioPlayer::isStarted() {
105    return mStarted;
106}
107
108status_t VideoEditorAudioPlayer::start(bool sourceAlreadyStarted) {
109    Mutex::Autolock autoLock(mLock);
110    CHECK(!mStarted);
111    CHECK(mSource != NULL);
112    LOGV("Start");
113    status_t err;
114    M4OSA_ERR result = M4NO_ERROR;
115    M4OSA_UInt32 startTime = 0;
116    M4OSA_UInt32 seekTimeStamp = 0;
117    M4OSA_Bool bStoryBoardTSBeyondBTEndCutTime = M4OSA_FALSE;
118
119    if (!sourceAlreadyStarted) {
120        err = mSource->start();
121        if (err != OK) {
122            return err;
123        }
124    }
125
126    // Create the BG Audio handler
127    mAudioProcess = new VideoEditorBGAudioProcessing();
128    veAudMixSettings audioMixSettings;
129
130    // Pass on the audio ducking parameters
131    audioMixSettings.lvInDucking_threshold =
132        mAudioMixSettings->uiInDucking_threshold;
133    audioMixSettings.lvInDucking_lowVolume =
134        ((M4OSA_Float)mAudioMixSettings->uiInDucking_lowVolume) / 100.0;
135    audioMixSettings.lvInDucking_enable =
136        mAudioMixSettings->bInDucking_enable;
137    audioMixSettings.lvPTVolLevel =
138        ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal) / 100.0;
139    audioMixSettings.lvBTVolLevel =
140        ((M4OSA_Float)mAudioMixSettings->uiAddVolume) / 100.0;
141    audioMixSettings.lvBTChannelCount = mAudioMixSettings->uiBTChannelCount;
142    audioMixSettings.lvPTChannelCount = mAudioMixSettings->uiNbChannels;
143
144    // Call to Audio mix param setting
145    mAudioProcess->veSetAudioProcessingParams(audioMixSettings);
146
147    // Get the BG Audio PCM file details
148    if ( mBGAudioPCMFileHandle ) {
149
150        // TODO : 32bits required for OSAL, to be updated once OSAL is updated
151        M4OSA_UInt32 tmp32 = 0;
152        result = M4OSA_fileReadGetOption(mBGAudioPCMFileHandle,
153                                        M4OSA_kFileReadGetFileSize,
154                                        (M4OSA_Void**)&tmp32);
155        mBGAudioPCMFileLength = tmp32;
156        mBGAudioPCMFileTrimmedLength = mBGAudioPCMFileLength;
157
158
159        LOGV("VideoEditorAudioPlayer::start M4OSA_kFileReadGetFileSize = %lld",
160                            mBGAudioPCMFileLength);
161
162        // Get the duration in time of the audio BT
163        if ( result == M4NO_ERROR ) {
164         LOGV("VEAP: channels = %d freq = %d",
165         mAudioMixSettings->uiNbChannels,  mAudioMixSettings->uiSamplingFrequency);
166
167            // No trim
168            mBGAudioPCMFileDuration = ((
169                    (int64_t)(mBGAudioPCMFileLength/sizeof(M4OSA_UInt16)/
170                    mAudioMixSettings->uiNbChannels))*1000 ) /
171                    mAudioMixSettings->uiSamplingFrequency;
172
173            LOGV("VideoEditorAudioPlayer:: beginCutMs %d , endCutMs %d",
174                    (unsigned int) mAudioMixSettings->beginCutMs,
175                    (unsigned int) mAudioMixSettings->endCutMs);
176
177            // Remove the trim part
178            if ((mAudioMixSettings->beginCutMs == 0) &&
179                (mAudioMixSettings->endCutMs != 0)) {
180                // End time itself the file duration
181                mBGAudioPCMFileDuration = mAudioMixSettings->endCutMs;
182                // Limit the file length also
183                mBGAudioPCMFileTrimmedLength = ((
184                     (int64_t)(mBGAudioPCMFileDuration *
185                     mAudioMixSettings->uiSamplingFrequency) *
186                     mAudioMixSettings->uiNbChannels) *
187                     sizeof(M4OSA_UInt16)) / 1000;
188            }
189            else if ((mAudioMixSettings->beginCutMs != 0) &&
190                     (mAudioMixSettings->endCutMs == mBGAudioPCMFileDuration)) {
191                // End time itself the file duration
192                mBGAudioPCMFileDuration = mBGAudioPCMFileDuration -
193                      mAudioMixSettings->beginCutMs;
194                // Limit the file length also
195                mBGAudioPCMFileTrimmedLength = ((
196                     (int64_t)(mBGAudioPCMFileDuration *
197                     mAudioMixSettings->uiSamplingFrequency) *
198                     mAudioMixSettings->uiNbChannels) *
199                     sizeof(M4OSA_UInt16)) / 1000;
200            }
201            else if ((mAudioMixSettings->beginCutMs != 0) &&
202                    (mAudioMixSettings->endCutMs != 0)) {
203                // End time itself the file duration
204                mBGAudioPCMFileDuration = mAudioMixSettings->endCutMs -
205                    mAudioMixSettings->beginCutMs;
206                // Limit the file length also
207                mBGAudioPCMFileTrimmedLength = ((
208                    (int64_t)(mBGAudioPCMFileDuration *
209                    mAudioMixSettings->uiSamplingFrequency) *
210                    mAudioMixSettings->uiNbChannels) *
211                    sizeof(M4OSA_UInt16)) / 1000; /*make to sec from ms*/
212            }
213
214            LOGV("VideoEditorAudioPlayer: file duration recorded : %lld",
215                    mBGAudioPCMFileDuration);
216        }
217
218        // Last played location to be seeked at for next media item
219        if ( result == M4NO_ERROR ) {
220            LOGV("VideoEditorAudioPlayer::mBGAudioStoryBoardSkimTimeStamp %lld",
221                    mBGAudioStoryBoardSkimTimeStamp);
222            LOGV("VideoEditorAudioPlayer::uiAddCts %d",
223                    mAudioMixSettings->uiAddCts);
224            if (mBGAudioStoryBoardSkimTimeStamp >= mAudioMixSettings->uiAddCts) {
225                startTime = (mBGAudioStoryBoardSkimTimeStamp -
226                 mAudioMixSettings->uiAddCts);
227            }
228            else {
229                // do nothing
230            }
231
232            LOGV("VideoEditorAudioPlayer::startTime %d", startTime);
233            seekTimeStamp = 0;
234            if (startTime) {
235                if (startTime >= mBGAudioPCMFileDuration) {
236                    // The BG track should be looped and started again
237                    if (mAudioMixSettings->bLoop) {
238                        // Add begin cut time to the mod value
239                        seekTimeStamp = ((startTime%mBGAudioPCMFileDuration) +
240                        mAudioMixSettings->beginCutMs);
241                    }else {
242                        // Looping disabled, donot do BT Mix , set to file end
243                        seekTimeStamp = (mBGAudioPCMFileDuration +
244                        mAudioMixSettings->beginCutMs);
245                    }
246                }else {
247                    // BT still present , just seek to story board time
248                    seekTimeStamp = startTime + mAudioMixSettings->beginCutMs;
249                }
250            }
251            else {
252                seekTimeStamp = mAudioMixSettings->beginCutMs;
253            }
254
255            // Convert the seekTimeStamp to file location
256            mBGAudioPCMFileOriginalSeekPoint = (
257                                        (int64_t)(mAudioMixSettings->beginCutMs)
258                                        * mAudioMixSettings->uiSamplingFrequency
259                                        * mAudioMixSettings->uiNbChannels
260                                        * sizeof(M4OSA_UInt16))/ 1000 ; /*make to sec from ms*/
261
262            mBGAudioPCMFileSeekPoint = ((int64_t)(seekTimeStamp)
263                                        * mAudioMixSettings->uiSamplingFrequency
264                                        * mAudioMixSettings->uiNbChannels
265                                        * sizeof(M4OSA_UInt16))/ 1000 ;
266        }
267    }
268
269    // We allow an optional INFO_FORMAT_CHANGED at the very beginning
270    // of playback, if there is one, getFormat below will retrieve the
271    // updated format, if there isn't, we'll stash away the valid buffer
272    // of data to be used on the first audio callback.
273
274    CHECK(mFirstBuffer == NULL);
275
276    mFirstBufferResult = mSource->read(&mFirstBuffer);
277    if (mFirstBufferResult == INFO_FORMAT_CHANGED) {
278        LOGV("INFO_FORMAT_CHANGED!!!");
279
280        CHECK(mFirstBuffer == NULL);
281        mFirstBufferResult = OK;
282        mIsFirstBuffer = false;
283    } else {
284        mIsFirstBuffer = true;
285    }
286
287    sp<MetaData> format = mSource->getFormat();
288    const char *mime;
289    bool success = format->findCString(kKeyMIMEType, &mime);
290    CHECK(success);
291    CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
292
293    success = format->findInt32(kKeySampleRate, &mSampleRate);
294    CHECK(success);
295
296    int32_t numChannels;
297    success = format->findInt32(kKeyChannelCount, &numChannels);
298    CHECK(success);
299
300    if (mAudioSink.get() != NULL) {
301        status_t err = mAudioSink->open(
302                mSampleRate, numChannels, AudioSystem::PCM_16_BIT,
303                DEFAULT_AUDIOSINK_BUFFERCOUNT,
304                &VideoEditorAudioPlayer::AudioSinkCallback, this);
305        if (err != OK) {
306            if (mFirstBuffer != NULL) {
307                mFirstBuffer->release();
308                mFirstBuffer = NULL;
309            }
310
311            if (!sourceAlreadyStarted) {
312                mSource->stop();
313            }
314
315            return err;
316        }
317
318        mLatencyUs = (int64_t)mAudioSink->latency() * 1000;
319        mFrameSize = mAudioSink->frameSize();
320
321        mAudioSink->start();
322    } else {
323        mAudioTrack = new AudioTrack(
324                AudioSystem::MUSIC, mSampleRate, AudioSystem::PCM_16_BIT,
325                (numChannels == 2)
326                    ? AudioSystem::CHANNEL_OUT_STEREO
327                    : AudioSystem::CHANNEL_OUT_MONO,
328                0, 0, &AudioCallback, this, 0);
329
330        if ((err = mAudioTrack->initCheck()) != OK) {
331            delete mAudioTrack;
332            mAudioTrack = NULL;
333
334            if (mFirstBuffer != NULL) {
335                mFirstBuffer->release();
336                mFirstBuffer = NULL;
337            }
338
339            if (!sourceAlreadyStarted) {
340                mSource->stop();
341            }
342
343            return err;
344        }
345
346        mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
347        mFrameSize = mAudioTrack->frameSize();
348
349        mAudioTrack->start();
350    }
351
352    mStarted = true;
353
354    return OK;
355}
356
357void VideoEditorAudioPlayer::resume() {
358
359    veAudMixSettings audioMixSettings;
360
361    // Single audio player is used;
362    // Pass on the audio ducking parameters
363    // which might have changed with new audio source
364    audioMixSettings.lvInDucking_threshold =
365        mAudioMixSettings->uiInDucking_threshold;
366    audioMixSettings.lvInDucking_lowVolume =
367        ((M4OSA_Float)mAudioMixSettings->uiInDucking_lowVolume) / 100.0;
368    audioMixSettings.lvInDucking_enable =
369        mAudioMixSettings->bInDucking_enable;
370    audioMixSettings.lvPTVolLevel =
371        ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal) / 100.0;
372    audioMixSettings.lvBTVolLevel =
373        ((M4OSA_Float)mAudioMixSettings->uiAddVolume) / 100.0;
374    audioMixSettings.lvBTChannelCount = mAudioMixSettings->uiBTChannelCount;
375    audioMixSettings.lvPTChannelCount = mAudioMixSettings->uiNbChannels;
376
377    // Call to Audio mix param setting
378    mAudioProcess->veSetAudioProcessingParams(audioMixSettings);
379
380    //Call the base class
381    AudioPlayer::resume();
382}
383
384void VideoEditorAudioPlayer::reset() {
385
386    LOGV("reset");
387    AudioPlayer::reset();
388
389    // Capture the current seek point
390    mBGAudioPCMFileSeekPoint = 0;
391    mBGAudioStoryBoardSkimTimeStamp =0;
392    mBGAudioStoryBoardCurrentMediaBeginCutTS=0;
393}
394
395size_t VideoEditorAudioPlayer::AudioSinkCallback(
396        MediaPlayerBase::AudioSink *audioSink,
397        void *buffer, size_t size, void *cookie) {
398    VideoEditorAudioPlayer *me = (VideoEditorAudioPlayer *)cookie;
399
400    return me->fillBuffer(buffer, size);
401}
402
403
404size_t VideoEditorAudioPlayer::fillBuffer(void *data, size_t size) {
405
406    if (mReachedEOS) {
407        return 0;
408    }
409
410    size_t size_done = 0;
411    size_t size_remaining = size;
412
413    M4OSA_ERR err = M4NO_ERROR;
414    M4AM_Buffer16 bgFrame = {NULL, 0};
415    M4AM_Buffer16 mixFrame = {NULL, 0};
416    M4AM_Buffer16 ptFrame = {NULL, 0};
417    int64_t currentSteamTS = 0;
418    int64_t startTimeForBT = 0;
419    M4OSA_Float fPTVolLevel =
420     ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal)/100;
421    M4OSA_Int16     *pPTMdata=NULL;
422    M4OSA_UInt32     uiPCMsize = 0;
423
424    bool postSeekComplete = false;
425    bool postEOS = false;
426
427    while ((size_remaining > 0)&&(err==M4NO_ERROR)) {
428        MediaSource::ReadOptions options;
429
430        {
431            Mutex::Autolock autoLock(mLock);
432            if (mSeeking) {
433                if (mIsFirstBuffer) {
434                    if (mFirstBuffer != NULL) {
435                        mFirstBuffer->release();
436                        mFirstBuffer = NULL;
437                    }
438                    mIsFirstBuffer = false;
439                }
440
441                options.setSeekTo(mSeekTimeUs);
442
443                if (mInputBuffer != NULL) {
444                    mInputBuffer->release();
445                    mInputBuffer = NULL;
446                }
447
448                mSeeking = false;
449
450                if (mObserver) {
451                    postSeekComplete = true;
452                }
453            }
454        }
455
456        if (mInputBuffer == NULL) {
457            status_t status = OK;
458
459            if (mIsFirstBuffer) {
460                mInputBuffer = mFirstBuffer;
461                mFirstBuffer = NULL;
462                status = mFirstBufferResult;
463
464                mIsFirstBuffer = false;
465            } else {
466
467                {
468                    Mutex::Autolock autoLock(mLock);
469                    status = mSource->read(&mInputBuffer, &options);
470                }
471                // Data is Primary Track, mix with background track
472                // after reading same size from Background track PCM file
473                if (status == OK)
474                {
475                    // Mix only when skim point is after startTime of BT
476                    if (((mBGAudioStoryBoardSkimTimeStamp* 1000) +
477                          (mPositionTimeMediaUs - mSeekTimeUs)) >=
478                          (int64_t)(mAudioMixSettings->uiAddCts * 1000)) {
479
480                        LOGV("VideoEditorAudioPlayer::INSIDE MIXING");
481                        LOGV("Checking %lld <= %lld",
482                            mBGAudioPCMFileSeekPoint-mBGAudioPCMFileOriginalSeekPoint,
483                            mBGAudioPCMFileTrimmedLength);
484
485
486                        M4OSA_Void* ptr;
487                        ptr = (M4OSA_Void*)((unsigned int)mInputBuffer->data() +
488                        mInputBuffer->range_offset());
489
490                        M4OSA_UInt32 len = mInputBuffer->range_length();
491                        M4OSA_Context fp = M4OSA_NULL;
492
493                        uiPCMsize = (mInputBuffer->range_length())/2;
494                        pPTMdata = (M4OSA_Int16*) ((uint8_t*) mInputBuffer->data()
495                                + mInputBuffer->range_offset());
496
497                        LOGV("mix with background malloc to do len %d", len);
498
499                        bgFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_malloc( len, 1,
500                                                       (M4OSA_Char*)"bgFrame");
501                        if (NULL == bgFrame.m_dataAddress) {
502                            LOGE("mBackgroundAudioSetting Malloc failed");
503                        }
504
505                        bgFrame.m_bufferSize = len;
506
507                        mixFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_malloc(len, 1,
508                                                    (M4OSA_Char*)"mixFrame");
509                        if (NULL == mixFrame.m_dataAddress) {
510                            LOGE("mBackgroundAudioSetting Malloc failed");
511                        }
512
513                        mixFrame.m_bufferSize = len;
514
515                        LOGV("mix with bgm with size %lld", mBGAudioPCMFileLength);
516
517                        CHECK(mInputBuffer->meta_data()->findInt64(kKeyTime,
518                                         &mPositionTimeMediaUs));
519
520                        if (mBGAudioPCMFileSeekPoint -
521                             mBGAudioPCMFileOriginalSeekPoint <=
522                              (mBGAudioPCMFileTrimmedLength - len)) {
523
524                            LOGV("Checking mBGAudioPCMFileHandle %d",
525                                (unsigned int)mBGAudioPCMFileHandle);
526
527                            if (mBGAudioPCMFileHandle != M4OSA_NULL) {
528                                LOGV("fillBuffer seeking file to %lld",
529                                    mBGAudioPCMFileSeekPoint);
530
531                            // TODO : 32bits required for OSAL
532                                M4OSA_UInt32 tmp32 =
533                                    (M4OSA_UInt32)mBGAudioPCMFileSeekPoint;
534                                err = M4OSA_fileReadSeek(mBGAudioPCMFileHandle,
535                                                M4OSA_kFileSeekBeginning,
536                                                (M4OSA_FilePosition*)&tmp32);
537
538                                mBGAudioPCMFileSeekPoint = tmp32;
539
540                                if (err != M4NO_ERROR){
541                                    LOGE("M4OSA_fileReadSeek err %d",(int)err);
542                                }
543
544                                err = M4OSA_fileReadData(mBGAudioPCMFileHandle,
545                                       (M4OSA_Int8*)bgFrame.m_dataAddress,
546                                       (M4OSA_UInt32*)&len);
547                                if (err == M4WAR_NO_DATA_YET ) {
548
549                                    LOGV("fillBuffer End of file reached");
550                                    err = M4NO_ERROR;
551
552                                    // We reached the end of file
553                                    // move to begin cut time equal value
554                                    if (mAudioMixSettings->bLoop) {
555                                        mBGAudioPCMFileSeekPoint =
556                                         (((int64_t)(mAudioMixSettings->beginCutMs) *
557                                          mAudioMixSettings->uiSamplingFrequency) *
558                                          mAudioMixSettings->uiNbChannels *
559                                           sizeof(M4OSA_UInt16)) / 1000;
560                                        LOGV("fillBuffer Looping \
561                                            to mBGAudioPCMFileSeekPoint %lld",
562                                            mBGAudioPCMFileSeekPoint);
563                                    }
564                                    else {
565                                            // No mixing;
566                                            // take care of volume of primary track
567                                        if (fPTVolLevel < 1.0) {
568                                            setPrimaryTrackVolume(pPTMdata,
569                                             uiPCMsize, fPTVolLevel);
570                                        }
571                                    }
572                                } else if (err != M4NO_ERROR ) {
573                                     LOGV("fileReadData for audio err %d", err);
574                                } else {
575                                    mBGAudioPCMFileSeekPoint += len;
576                                    LOGV("fillBuffer mBGAudioPCMFileSeekPoint \
577                                         %lld", mBGAudioPCMFileSeekPoint);
578
579                                    // Assign the ptr data to primary track
580                                    ptFrame.m_dataAddress = (M4OSA_UInt16*)ptr;
581                                    ptFrame.m_bufferSize = len;
582
583                                    // Call to mix and duck
584                                    mAudioProcess->veProcessAudioMixNDuck(
585                                         &ptFrame, &bgFrame, &mixFrame);
586
587                                        // Overwrite the decoded buffer
588                                    memcpy((void *)ptr,
589                                         (void *)mixFrame.m_dataAddress, len);
590                                }
591                            }
592                        } else if (mAudioMixSettings->bLoop){
593                            // Move to begin cut time equal value
594                            mBGAudioPCMFileSeekPoint =
595                                mBGAudioPCMFileOriginalSeekPoint;
596                        } else {
597                            // No mixing;
598                            // take care of volume level of primary track
599                            if(fPTVolLevel < 1.0) {
600                                setPrimaryTrackVolume(
601                                      pPTMdata, uiPCMsize, fPTVolLevel);
602                            }
603                        }
604                        if (bgFrame.m_dataAddress) {
605                            M4OSA_free((M4OSA_MemAddr32)bgFrame.m_dataAddress);
606                        }
607                        if (mixFrame.m_dataAddress) {
608                            M4OSA_free((M4OSA_MemAddr32)mixFrame.m_dataAddress);
609                        }
610                    } else {
611                        // No mixing;
612                        // take care of volume level of primary track
613                        if(fPTVolLevel < 1.0) {
614                            setPrimaryTrackVolume(pPTMdata, uiPCMsize,
615                                                 fPTVolLevel);
616                        }
617                    }
618                }
619            }
620
621            CHECK((status == OK && mInputBuffer != NULL)
622                   || (status != OK && mInputBuffer == NULL));
623
624            Mutex::Autolock autoLock(mLock);
625
626            if (status != OK) {
627                LOGV("fillBuffer: mSource->read returned err %d", status);
628                if (mObserver && !mReachedEOS) {
629                    postEOS = true;
630                }
631
632                mReachedEOS = true;
633                mFinalStatus = status;
634                break;
635            }
636
637            CHECK(mInputBuffer->meta_data()->findInt64(
638                        kKeyTime, &mPositionTimeMediaUs));
639
640            mPositionTimeRealUs =
641                ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
642                    / mSampleRate;
643
644            LOGV("buffer->size() = %d, "
645                     "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
646                 mInputBuffer->range_length(),
647                 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
648        }
649
650        if (mInputBuffer->range_length() == 0) {
651            mInputBuffer->release();
652            mInputBuffer = NULL;
653
654            continue;
655        }
656
657        size_t copy = size_remaining;
658        if (copy > mInputBuffer->range_length()) {
659            copy = mInputBuffer->range_length();
660        }
661
662        memcpy((char *)data + size_done,
663           (const char *)mInputBuffer->data() + mInputBuffer->range_offset(),
664               copy);
665
666        mInputBuffer->set_range(mInputBuffer->range_offset() + copy,
667                            mInputBuffer->range_length() - copy);
668
669        size_done += copy;
670        size_remaining -= copy;
671    }
672
673    {
674        Mutex::Autolock autoLock(mLock);
675        mNumFramesPlayed += size_done / mFrameSize;
676    }
677
678    if (postEOS) {
679        mObserver->postAudioEOS();
680    }
681
682    if (postSeekComplete) {
683        mObserver->postAudioSeekComplete();
684    }
685
686    return size_done;
687}
688
689void VideoEditorAudioPlayer::setAudioMixSettings(
690                            M4xVSS_AudioMixingSettings* pAudioMixSettings) {
691    mAudioMixSettings = pAudioMixSettings;
692}
693
694void VideoEditorAudioPlayer::setAudioMixPCMFileHandle(
695                            M4OSA_Context pBGAudioPCMFileHandle){
696    mBGAudioPCMFileHandle = pBGAudioPCMFileHandle;
697}
698
699void VideoEditorAudioPlayer::setAudioMixStoryBoardSkimTimeStamp(
700                            M4OSA_UInt32 pBGAudioStoryBoardSkimTimeStamp,
701                            M4OSA_UInt32 pBGAudioCurrentMediaBeginCutTS,
702                            M4OSA_UInt32 pBGAudioCurrentMediaVolumeVal) {
703
704    mBGAudioStoryBoardSkimTimeStamp = pBGAudioStoryBoardSkimTimeStamp;
705    mBGAudioStoryBoardCurrentMediaBeginCutTS = pBGAudioCurrentMediaBeginCutTS;
706    mBGAudioStoryBoardCurrentMediaVolumeVal = pBGAudioCurrentMediaVolumeVal;
707}
708
709void VideoEditorAudioPlayer::setPrimaryTrackVolume(
710    M4OSA_Int16 *data, M4OSA_UInt32 size, M4OSA_Float volLevel) {
711
712    while(size-- > 0) {
713        *data = (M4OSA_Int16)((*data)*volLevel);
714        data++;
715    }
716}
717
718}
719