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