• 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                 (numChannels == 2)
538                     ? AUDIO_CHANNEL_OUT_STEREO
539                     : AUDIO_CHANNEL_OUT_MONO,
540                 0, AUDIO_OUTPUT_FLAG_NONE, &AudioCallback, this, 0);
541 
542         if ((err = mAudioTrack->initCheck()) != OK) {
543             delete mAudioTrack;
544             mAudioTrack = NULL;
545 
546             if (mFirstBuffer != NULL) {
547                 mFirstBuffer->release();
548                 mFirstBuffer = NULL;
549             }
550 
551             if (!sourceAlreadyStarted) {
552                 mSource->stop();
553             }
554 
555             return err;
556         }
557 
558         mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
559         mFrameSize = mAudioTrack->frameSize();
560 
561         mAudioTrack->start();
562     }
563 
564     mStarted = true;
565 
566     return OK;
567 }
568 
569 
reset()570 void VideoEditorAudioPlayer::reset() {
571 
572     ALOGV("reset");
573     clear();
574 
575     // Capture the current seek point
576     mBGAudioPCMFileSeekPoint = 0;
577     mBGAudioStoryBoardSkimTimeStamp =0;
578     mBGAudioStoryBoardCurrentMediaBeginCutTS=0;
579 }
580 
AudioSinkCallback(MediaPlayerBase::AudioSink * audioSink,void * buffer,size_t size,void * cookie)581 size_t VideoEditorAudioPlayer::AudioSinkCallback(
582         MediaPlayerBase::AudioSink *audioSink,
583         void *buffer, size_t size, void *cookie) {
584     VideoEditorAudioPlayer *me = (VideoEditorAudioPlayer *)cookie;
585 
586     return me->fillBuffer(buffer, size);
587 }
588 
589 
fillBuffer(void * data,size_t size)590 size_t VideoEditorAudioPlayer::fillBuffer(void *data, size_t size) {
591 
592     if (mReachedEOS) {
593         return 0;
594     }
595 
596     size_t size_done = 0;
597     size_t size_remaining = size;
598 
599     M4OSA_ERR err = M4NO_ERROR;
600     M4AM_Buffer16 bgFrame = {NULL, 0};
601     M4AM_Buffer16 mixFrame = {NULL, 0};
602     M4AM_Buffer16 ptFrame = {NULL, 0};
603     int64_t currentSteamTS = 0;
604     int64_t startTimeForBT = 0;
605     M4OSA_Float fPTVolLevel =
606      ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal)/100;
607     M4OSA_Int16     *pPTMdata=NULL;
608     M4OSA_UInt32     uiPCMsize = 0;
609 
610     bool postSeekComplete = false;
611     bool postEOS = false;
612 
613     while ((size_remaining > 0)&&(err==M4NO_ERROR)) {
614         MediaSource::ReadOptions options;
615 
616         {
617             Mutex::Autolock autoLock(mLock);
618             if (mSeeking) {
619                 if (mIsFirstBuffer) {
620                     if (mFirstBuffer != NULL) {
621                         mFirstBuffer->release();
622                         mFirstBuffer = NULL;
623                     }
624                     mIsFirstBuffer = false;
625                 }
626 
627                 options.setSeekTo(mSeekTimeUs);
628 
629                 if (mInputBuffer != NULL) {
630                     mInputBuffer->release();
631                     mInputBuffer = NULL;
632                 }
633 
634                 mSeeking = false;
635 
636                 if (mObserver) {
637                     postSeekComplete = true;
638                 }
639             }
640         }
641 
642         if (mInputBuffer == NULL) {
643             status_t status = OK;
644 
645             if (mIsFirstBuffer) {
646                 mInputBuffer = mFirstBuffer;
647                 mFirstBuffer = NULL;
648                 status = mFirstBufferResult;
649 
650                 mIsFirstBuffer = false;
651             } else {
652 
653                 {
654                     Mutex::Autolock autoLock(mLock);
655                     status = mSource->read(&mInputBuffer, &options);
656                 }
657                 // Data is Primary Track, mix with background track
658                 // after reading same size from Background track PCM file
659                 if (status == OK)
660                 {
661                     // Mix only when skim point is after startTime of BT
662                     if (((mBGAudioStoryBoardSkimTimeStamp* 1000) +
663                           (mPositionTimeMediaUs - mSeekTimeUs)) >=
664                           (int64_t)(mAudioMixSettings->uiAddCts * 1000)) {
665 
666                         ALOGV("VideoEditorAudioPlayer::INSIDE MIXING");
667                         ALOGV("Checking %lld <= %lld",
668                             mBGAudioPCMFileSeekPoint-mBGAudioPCMFileOriginalSeekPoint,
669                             mBGAudioPCMFileTrimmedLength);
670 
671 
672                         M4OSA_Void* ptr;
673                         ptr = (M4OSA_Void*)((unsigned int)mInputBuffer->data() +
674                         mInputBuffer->range_offset());
675 
676                         M4OSA_UInt32 len = mInputBuffer->range_length();
677                         M4OSA_Context fp = M4OSA_NULL;
678 
679                         uiPCMsize = (mInputBuffer->range_length())/2;
680                         pPTMdata = (M4OSA_Int16*) ((uint8_t*) mInputBuffer->data()
681                                 + mInputBuffer->range_offset());
682 
683                         ALOGV("mix with background malloc to do len %d", len);
684 
685                         bgFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_32bitAlignedMalloc( len, 1,
686                                                        (M4OSA_Char*)"bgFrame");
687                         bgFrame.m_bufferSize = len;
688 
689                         mixFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_32bitAlignedMalloc(len, 1,
690                                                     (M4OSA_Char*)"mixFrame");
691                         mixFrame.m_bufferSize = len;
692 
693                         ALOGV("mix with bgm with size %lld", mBGAudioPCMFileLength);
694 
695                         CHECK(mInputBuffer->meta_data()->findInt64(kKeyTime,
696                                          &mPositionTimeMediaUs));
697 
698                         if (mBGAudioPCMFileSeekPoint -
699                              mBGAudioPCMFileOriginalSeekPoint <=
700                               (mBGAudioPCMFileTrimmedLength - len)) {
701 
702                             ALOGV("Checking mBGAudioPCMFileHandle %d",
703                                 (unsigned int)mBGAudioPCMFileHandle);
704 
705                             if (mBGAudioPCMFileHandle != M4OSA_NULL) {
706                                 ALOGV("fillBuffer seeking file to %lld",
707                                     mBGAudioPCMFileSeekPoint);
708 
709                             // TODO : 32bits required for OSAL
710                                 M4OSA_UInt32 tmp32 =
711                                     (M4OSA_UInt32)mBGAudioPCMFileSeekPoint;
712                                 err = M4OSA_fileReadSeek(mBGAudioPCMFileHandle,
713                                                 M4OSA_kFileSeekBeginning,
714                                                 (M4OSA_FilePosition*)&tmp32);
715 
716                                 mBGAudioPCMFileSeekPoint = tmp32;
717 
718                                 if (err != M4NO_ERROR){
719                                     ALOGE("M4OSA_fileReadSeek err %d",(int)err);
720                                 }
721 
722                                 err = M4OSA_fileReadData(mBGAudioPCMFileHandle,
723                                        (M4OSA_Int8*)bgFrame.m_dataAddress,
724                                        (M4OSA_UInt32*)&len);
725                                 if (err == M4WAR_NO_DATA_YET ) {
726 
727                                     ALOGV("fillBuffer End of file reached");
728                                     err = M4NO_ERROR;
729 
730                                     // We reached the end of file
731                                     // move to begin cut time equal value
732                                     if (mAudioMixSettings->bLoop) {
733                                         mBGAudioPCMFileSeekPoint =
734                                          (((int64_t)(mAudioMixSettings->beginCutMs) *
735                                           mAudioMixSettings->uiSamplingFrequency) *
736                                           mAudioMixSettings->uiNbChannels *
737                                            sizeof(M4OSA_UInt16)) / 1000;
738                                         ALOGV("fillBuffer Looping \
739                                             to mBGAudioPCMFileSeekPoint %lld",
740                                             mBGAudioPCMFileSeekPoint);
741                                     }
742                                     else {
743                                             // No mixing;
744                                             // take care of volume of primary track
745                                         if (fPTVolLevel < 1.0) {
746                                             setPrimaryTrackVolume(pPTMdata,
747                                              uiPCMsize, fPTVolLevel);
748                                         }
749                                     }
750                                 } else if (err != M4NO_ERROR ) {
751                                      ALOGV("fileReadData for audio err %d", err);
752                                 } else {
753                                     mBGAudioPCMFileSeekPoint += len;
754                                     ALOGV("fillBuffer mBGAudioPCMFileSeekPoint \
755                                          %lld", mBGAudioPCMFileSeekPoint);
756 
757                                     // Assign the ptr data to primary track
758                                     ptFrame.m_dataAddress = (M4OSA_UInt16*)ptr;
759                                     ptFrame.m_bufferSize = len;
760 
761                                     // Call to mix and duck
762                                     mAudioProcess->mixAndDuck(
763                                          &ptFrame, &bgFrame, &mixFrame);
764 
765                                         // Overwrite the decoded buffer
766                                     memcpy((void *)ptr,
767                                          (void *)mixFrame.m_dataAddress, len);
768                                 }
769                             }
770                         } else if (mAudioMixSettings->bLoop){
771                             // Move to begin cut time equal value
772                             mBGAudioPCMFileSeekPoint =
773                                 mBGAudioPCMFileOriginalSeekPoint;
774                         } else {
775                             // No mixing;
776                             // take care of volume level of primary track
777                             if(fPTVolLevel < 1.0) {
778                                 setPrimaryTrackVolume(
779                                       pPTMdata, uiPCMsize, fPTVolLevel);
780                             }
781                         }
782                         if (bgFrame.m_dataAddress) {
783                             free(bgFrame.m_dataAddress);
784                         }
785                         if (mixFrame.m_dataAddress) {
786                             free(mixFrame.m_dataAddress);
787                         }
788                     } else {
789                         // No mixing;
790                         // take care of volume level of primary track
791                         if(fPTVolLevel < 1.0) {
792                             setPrimaryTrackVolume(pPTMdata, uiPCMsize,
793                                                  fPTVolLevel);
794                         }
795                     }
796                 }
797             }
798 
799             CHECK((status == OK && mInputBuffer != NULL)
800                    || (status != OK && mInputBuffer == NULL));
801 
802             Mutex::Autolock autoLock(mLock);
803 
804             if (status != OK) {
805                 ALOGV("fillBuffer: mSource->read returned err %d", status);
806                 if (mObserver && !mReachedEOS) {
807                     postEOS = true;
808                 }
809 
810                 mReachedEOS = true;
811                 mFinalStatus = status;
812                 break;
813             }
814 
815             CHECK(mInputBuffer->meta_data()->findInt64(
816                         kKeyTime, &mPositionTimeMediaUs));
817 
818             mPositionTimeRealUs =
819                 ((mNumFramesPlayed + size_done / mFrameSize) * 1000000)
820                     / mSampleRate;
821 
822             ALOGV("buffer->size() = %d, "
823                      "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f",
824                  mInputBuffer->range_length(),
825                  mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6);
826         }
827 
828         if (mInputBuffer->range_length() == 0) {
829             mInputBuffer->release();
830             mInputBuffer = NULL;
831 
832             continue;
833         }
834 
835         size_t copy = size_remaining;
836         if (copy > mInputBuffer->range_length()) {
837             copy = mInputBuffer->range_length();
838         }
839 
840         memcpy((char *)data + size_done,
841            (const char *)mInputBuffer->data() + mInputBuffer->range_offset(),
842                copy);
843 
844         mInputBuffer->set_range(mInputBuffer->range_offset() + copy,
845                             mInputBuffer->range_length() - copy);
846 
847         size_done += copy;
848         size_remaining -= copy;
849     }
850 
851     {
852         Mutex::Autolock autoLock(mLock);
853         mNumFramesPlayed += size_done / mFrameSize;
854     }
855 
856     if (postEOS) {
857         mObserver->postAudioEOS();
858     }
859 
860     if (postSeekComplete) {
861         mObserver->postAudioSeekComplete();
862     }
863 
864     return size_done;
865 }
866 
setAudioMixSettings(M4xVSS_AudioMixingSettings * pAudioMixSettings)867 void VideoEditorAudioPlayer::setAudioMixSettings(
868                             M4xVSS_AudioMixingSettings* pAudioMixSettings) {
869     mAudioMixSettings = pAudioMixSettings;
870 }
871 
setAudioMixPCMFileHandle(M4OSA_Context pBGAudioPCMFileHandle)872 void VideoEditorAudioPlayer::setAudioMixPCMFileHandle(
873                             M4OSA_Context pBGAudioPCMFileHandle){
874     mBGAudioPCMFileHandle = pBGAudioPCMFileHandle;
875 }
876 
setAudioMixStoryBoardSkimTimeStamp(M4OSA_UInt32 pBGAudioStoryBoardSkimTimeStamp,M4OSA_UInt32 pBGAudioCurrentMediaBeginCutTS,M4OSA_UInt32 pBGAudioCurrentMediaVolumeVal)877 void VideoEditorAudioPlayer::setAudioMixStoryBoardSkimTimeStamp(
878                             M4OSA_UInt32 pBGAudioStoryBoardSkimTimeStamp,
879                             M4OSA_UInt32 pBGAudioCurrentMediaBeginCutTS,
880                             M4OSA_UInt32 pBGAudioCurrentMediaVolumeVal) {
881 
882     mBGAudioStoryBoardSkimTimeStamp = pBGAudioStoryBoardSkimTimeStamp;
883     mBGAudioStoryBoardCurrentMediaBeginCutTS = pBGAudioCurrentMediaBeginCutTS;
884     mBGAudioStoryBoardCurrentMediaVolumeVal = pBGAudioCurrentMediaVolumeVal;
885 }
886 
setPrimaryTrackVolume(M4OSA_Int16 * data,M4OSA_UInt32 size,M4OSA_Float volLevel)887 void VideoEditorAudioPlayer::setPrimaryTrackVolume(
888     M4OSA_Int16 *data, M4OSA_UInt32 size, M4OSA_Float volLevel) {
889 
890     while(size-- > 0) {
891         *data = (M4OSA_Int16)((*data)*volLevel);
892         data++;
893     }
894 }
895 
896 }
897