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