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"
33namespace android {
34
35VideoEditorAudioPlayer::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
70VideoEditorAudioPlayer::~VideoEditorAudioPlayer() {
71
72    ALOGV("Destructor");
73    if (mStarted) {
74        reset();
75    }
76    if (mAudioProcess != NULL) {
77        delete mAudioProcess;
78        mAudioProcess = NULL;
79    }
80}
81
82void 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
101void 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
152status_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
186status_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
204bool VideoEditorAudioPlayer::isSeeking() {
205    Mutex::Autolock lock(mLock);
206    ALOGV("isSeeking: mSeeking=%d", mSeeking);
207    return mSeeking;
208}
209
210bool 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
219int64_t VideoEditorAudioPlayer::getRealTimeUs() {
220    Mutex::Autolock autoLock(mLock);
221    return getRealTimeUs_l();
222}
223
224int64_t VideoEditorAudioPlayer::getRealTimeUs_l() {
225    return -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
226}
227
228int64_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
248bool 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
259void 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
287sp<MediaSource> VideoEditorAudioPlayer::getSource() {
288    Mutex::Autolock autoLock(mLock);
289    return mSource;
290}
291
292void VideoEditorAudioPlayer::setObserver(PreviewPlayer *observer) {
293    ALOGV("setObserver");
294    //CHECK(!mStarted);
295    mObserver = observer;
296}
297
298bool VideoEditorAudioPlayer::isStarted() {
299    return mStarted;
300}
301
302// static
303void VideoEditorAudioPlayer::AudioCallback(int event, void *user, void *info) {
304    static_cast<VideoEditorAudioPlayer *>(user)->AudioCallback(event, info);
305}
306
307
308void 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
319status_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
566void 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
577size_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
591size_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
868void VideoEditorAudioPlayer::setAudioMixSettings(
869                            M4xVSS_AudioMixingSettings* pAudioMixSettings) {
870    mAudioMixSettings = pAudioMixSettings;
871}
872
873void VideoEditorAudioPlayer::setAudioMixPCMFileHandle(
874                            M4OSA_Context pBGAudioPCMFileHandle){
875    mBGAudioPCMFileHandle = pBGAudioPCMFileHandle;
876}
877
878void 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
888void 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