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