PageRenderTime 54ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/frameworks/av/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp

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