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