• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
VideoEditorAudioPlayer(const sp<MediaPlayerBase::AudioSink> & audioSink,PreviewPlayer * observer)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 
~VideoEditorAudioPlayer()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 
pause(bool playPendingSamples)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 
clear()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 
resume()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 
seekTo(int64_t time_us)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 
isSeeking()205 bool VideoEditorAudioPlayer::isSeeking() {
206     Mutex::Autolock lock(mLock);
207     ALOGV("isSeeking: mSeeking=%d", mSeeking);
208     return mSeeking;
209 }
210 
reachedEOS(status_t * finalStatus)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 
getRealTimeUs()220 int64_t VideoEditorAudioPlayer::getRealTimeUs() {
221     Mutex::Autolock autoLock(mLock);
222     return getRealTimeUs_l();
223 }
224 
getRealTimeUs_l()225 int64_t VideoEditorAudioPlayer::getRealTimeUs_l() {
226     return -mLatencyUs + (mNumFramesPlayed * 1000000) / mSampleRate;
227 }
228 
getMediaTimeUs()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 
getMediaTimeMapping(int64_t * realtime_us,int64_t * mediatime_us)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 
setSource(const sp<MediaSource> & source)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 
getSource()288 sp<MediaSource> VideoEditorAudioPlayer::getSource() {
289     Mutex::Autolock autoLock(mLock);
290     return mSource;
291 }
292 
setObserver(PreviewPlayer * observer)293 void VideoEditorAudioPlayer::setObserver(PreviewPlayer *observer) {
294     ALOGV("setObserver");
295     //CHECK(!mStarted);
296     mObserver = observer;
297 }
298 
isStarted()299 bool VideoEditorAudioPlayer::isStarted() {
300     return mStarted;
301 }
302 
303 // static
AudioCallback(int event,void * user,void * info)304 void VideoEditorAudioPlayer::AudioCallback(int event, void *user, void *info) {
305     static_cast<VideoEditorAudioPlayer *>(user)->AudioCallback(event, info);
306 }
307 
308 
AudioCallback(int event,void * info)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 
start(bool sourceAlreadyStarted)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 
reset()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 
AudioSinkCallback(MediaPlayerBase::AudioSink * audioSink,void * buffer,size_t size,void * cookie)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 
fillBuffer(void * data,size_t size)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 
setAudioMixSettings(M4xVSS_AudioMixingSettings * pAudioMixSettings)865 void VideoEditorAudioPlayer::setAudioMixSettings(
866                             M4xVSS_AudioMixingSettings* pAudioMixSettings) {
867     mAudioMixSettings = pAudioMixSettings;
868 }
869 
setAudioMixPCMFileHandle(M4OSA_Context pBGAudioPCMFileHandle)870 void VideoEditorAudioPlayer::setAudioMixPCMFileHandle(
871                             M4OSA_Context pBGAudioPCMFileHandle){
872     mBGAudioPCMFileHandle = pBGAudioPCMFileHandle;
873 }
874 
setAudioMixStoryBoardSkimTimeStamp(M4OSA_UInt32 pBGAudioStoryBoardSkimTimeStamp,M4OSA_UInt32 pBGAudioCurrentMediaBeginCutTS,M4OSA_UInt32 pBGAudioCurrentMediaVolumeVal)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 
setPrimaryTrackVolume(M4OSA_Int16 * data,M4OSA_UInt32 size,M4OSA_Float volLevel)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