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