1c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia/* 2c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia * Copyright 2015 The Android Open Source Project 3c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia * 4c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia * Licensed under the Apache License, Version 2.0 (the "License"); 5c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia * you may not use this file except in compliance with the License. 6c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia * You may obtain a copy of the License at 7c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia * 8c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia * http://www.apache.org/licenses/LICENSE-2.0 9c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia * 10c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia * Unless required by applicable law or agreed to in writing, software 11c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia * distributed under the License is distributed on an "AS IS" BASIS, 12c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia * See the License for the specific language governing permissions and 14c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia * limitations under the License. 15c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia */ 16c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 17c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia//#define LOG_NDEBUG 0 18c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia#define LOG_TAG "MediaSync" 19c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia#include <inttypes.h> 20c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 21c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia#include <gui/BufferQueue.h> 22c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia#include <gui/IGraphicBufferConsumer.h> 23c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia#include <gui/IGraphicBufferProducer.h> 24c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 25c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia#include <media/AudioTrack.h> 26c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia#include <media/stagefright/MediaClock.h> 27c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia#include <media/stagefright/MediaSync.h> 28a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar#include <media/stagefright/VideoFrameScheduler.h> 29c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia#include <media/stagefright/foundation/ADebug.h> 30c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia#include <media/stagefright/foundation/ALooper.h> 31c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia#include <media/stagefright/foundation/AMessage.h> 32c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 33c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia#include <ui/GraphicBuffer.h> 34c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 35c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia// Maximum late time allowed for a video frame to be rendered. When a video 36c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia// frame arrives later than this number, it will be discarded without rendering. 37c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiastatic const int64_t kMaxAllowedVideoLateTimeUs = 40000ll; 38c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 39c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jianamespace android { 40c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 41c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia// static 42c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiasp<MediaSync> MediaSync::create() { 43c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia sp<MediaSync> sync = new MediaSync(); 44c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia sync->mLooper->registerHandler(sync); 45c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return sync; 46c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 47c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 48c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei JiaMediaSync::MediaSync() 49c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia : mIsAbandoned(false), 50c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mMutex(), 51c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mReleaseCondition(), 52c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mNumOutstandingBuffers(0), 53b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia mUsageFlagsFromOutput(0), 54a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar mMaxAcquiredBufferCount(1), 5508dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar mReturnPendingInputFrame(false), 56c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mNativeSampleRateInHz(0), 57c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mNumFramesWritten(0), 58c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mHasAudio(false), 59c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mNextBufferItemMediaUs(-1), 60c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mPlaybackRate(0.0) { 61c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mMediaClock = new MediaClock; 62c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 633a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // initialize settings 643a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mPlaybackSettings = AUDIO_PLAYBACK_RATE_DEFAULT; 653a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mPlaybackSettings.mSpeed = mPlaybackRate; 663a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 67c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mLooper = new ALooper; 68c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mLooper->setName("MediaSync"); 69c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 70c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 71c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 72c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei JiaMediaSync::~MediaSync() { 73c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (mInput != NULL) { 74c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mInput->consumerDisconnect(); 75c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 76c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (mOutput != NULL) { 77c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mOutput->disconnect(NATIVE_WINDOW_API_MEDIA); 78c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 79c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 80c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (mLooper != NULL) { 81c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mLooper->unregisterHandler(id()); 82c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mLooper->stop(); 83c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 84c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 85c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 86ce8c218ec9db7acd86f9f8929f8bbb668151b53dWei Jiastatus_t MediaSync::setSurface(const sp<IGraphicBufferProducer> &output) { 87c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia Mutex::Autolock lock(mMutex); 88c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 89b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia if (output == mOutput) { 90b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia return NO_ERROR; // same output surface. 91c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 92c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 933a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (output == NULL && mSyncSettings.mSource == AVSYNC_SOURCE_VSYNC) { 94ce8c218ec9db7acd86f9f8929f8bbb668151b53dWei Jia ALOGE("setSurface: output surface is used as sync source and cannot be removed."); 953a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return INVALID_OPERATION; 963a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 973a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 98c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (output != NULL) { 99b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia int newUsage = 0; 100b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia output->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &newUsage); 101b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia 102b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia // Check usage flags only when current output surface has been used to create input surface. 103b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia if (mOutput != NULL && mInput != NULL) { 104b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia int ignoredFlags = (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER 105b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia | GRALLOC_USAGE_EXTERNAL_DISP); 106b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia // New output surface is not allowed to add new usage flag except ignored ones. 107b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia if ((newUsage & ~(mUsageFlagsFromOutput | ignoredFlags)) != 0) { 108b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia ALOGE("setSurface: new output surface has new usage flag not used by current one."); 109b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia return BAD_VALUE; 110b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia } 111b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia } 112b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia 113b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia // Try to connect to new output surface. If failed, current output surface will not 114b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia // be changed. 115c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia IGraphicBufferProducer::QueueBufferOutput queueBufferOutput; 116b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia sp<OutputListener> listener(new OutputListener(this, output)); 117c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia IInterface::asBinder(output)->linkToDeath(listener); 118c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia status_t status = 119c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia output->connect(listener, 120c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia NATIVE_WINDOW_API_MEDIA, 121c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia true /* producerControlledByApp */, 122c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia &queueBufferOutput); 123c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (status != NO_ERROR) { 124ce8c218ec9db7acd86f9f8929f8bbb668151b53dWei Jia ALOGE("setSurface: failed to connect (%d)", status); 125c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return status; 126c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 127a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar 128a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar if (mFrameScheduler == NULL) { 129a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar mFrameScheduler = new VideoFrameScheduler(); 130a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar mFrameScheduler->init(); 131a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar } 132b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia } 133c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 134b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia if (mOutput != NULL) { 135b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia mOutput->disconnect(NATIVE_WINDOW_API_MEDIA); 136b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia while (!mBuffersSentToOutput.isEmpty()) { 137b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia returnBufferToInput_l(mBuffersSentToOutput.valueAt(0), Fence::NO_FENCE); 138b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia mBuffersSentToOutput.removeItemsAt(0); 139b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia } 140c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 141c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 142b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia mOutput = output; 143b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia 144c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return NO_ERROR; 145c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 146c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 147c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia// |audioTrack| is used only for querying information. 148ce8c218ec9db7acd86f9f8929f8bbb668151b53dWei Jiastatus_t MediaSync::setAudioTrack(const sp<AudioTrack> &audioTrack) { 149c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia Mutex::Autolock lock(mMutex); 150c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 151c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // TODO: support audio track change. 152c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (mAudioTrack != NULL) { 153ce8c218ec9db7acd86f9f8929f8bbb668151b53dWei Jia ALOGE("setAudioTrack: audioTrack has already been configured."); 154c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return INVALID_OPERATION; 155c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 156c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 1573a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (audioTrack == NULL && mSyncSettings.mSource == AVSYNC_SOURCE_AUDIO) { 158ce8c218ec9db7acd86f9f8929f8bbb668151b53dWei Jia ALOGE("setAudioTrack: audioTrack is used as sync source and cannot be removed."); 1593a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return INVALID_OPERATION; 1609767a47dcf9bbe090045ab99e0290d73289c704fWei Jia } 1619767a47dcf9bbe090045ab99e0290d73289c704fWei Jia 1623a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (audioTrack != NULL) { 1633a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // check if audio track supports the playback settings 1643a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (mPlaybackSettings.mSpeed != 0.f 1653a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar && audioTrack->setPlaybackRate(mPlaybackSettings) != OK) { 1663a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar ALOGE("playback settings are not supported by the audio track"); 1673a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return INVALID_OPERATION; 1683a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 1693a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar uint32_t nativeSampleRateInHz = audioTrack->getOriginalSampleRate(); 1703a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (nativeSampleRateInHz <= 0) { 171ce8c218ec9db7acd86f9f8929f8bbb668151b53dWei Jia ALOGE("setAudioTrack: native sample rate should be positive."); 1723a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return BAD_VALUE; 1733a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 1743a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mAudioTrack = audioTrack; 1753a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mNativeSampleRateInHz = nativeSampleRateInHz; 1763a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar (void)setPlaybackSettings_l(mPlaybackSettings); 1773a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 1783a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar else { 1793a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mAudioTrack = NULL; 1803a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mNativeSampleRateInHz = 0; 1813a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 182c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 1833a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // potentially resync to new source 1843a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar resync_l(); 1853a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return OK; 186c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 187c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 188c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiastatus_t MediaSync::createInputSurface( 189c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia sp<IGraphicBufferProducer> *outBufferProducer) { 190c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (outBufferProducer == NULL) { 191c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return BAD_VALUE; 192c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 193c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 194c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia Mutex::Autolock lock(mMutex); 195c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 196c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (mOutput == NULL) { 197c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return NO_INIT; 198c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 199c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 200c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (mInput != NULL) { 201c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return INVALID_OPERATION; 202c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 203c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 204c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia sp<IGraphicBufferProducer> bufferProducer; 205c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia sp<IGraphicBufferConsumer> bufferConsumer; 206c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia BufferQueue::createBufferQueue(&bufferProducer, &bufferConsumer); 207c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 208c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia sp<InputListener> listener(new InputListener(this)); 209c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia IInterface::asBinder(bufferConsumer)->linkToDeath(listener); 210c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia status_t status = 211c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia bufferConsumer->consumerConnect(listener, false /* controlledByApp */); 212c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (status == NO_ERROR) { 213c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia bufferConsumer->setConsumerName(String8("MediaSync")); 2149b73fa9a02b7234b43ac2be66a3328ff36d39c2dLajos Molnar // propagate usage bits from output surface 215b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia mUsageFlagsFromOutput = 0; 216b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia mOutput->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &mUsageFlagsFromOutput); 217b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia bufferConsumer->setConsumerUsageBits(mUsageFlagsFromOutput); 218c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia *outBufferProducer = bufferProducer; 219c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mInput = bufferConsumer; 220a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar 221a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar // set undequeued buffer count 222a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar int minUndequeuedBuffers; 223a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar mOutput->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers); 224a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar mMaxAcquiredBufferCount = minUndequeuedBuffers; 225a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar bufferConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBufferCount); 226c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 227c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return status; 228c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 229c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 2303a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid MediaSync::resync_l() { 2313a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AVSyncSource src = mSyncSettings.mSource; 2323a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (src == AVSYNC_SOURCE_DEFAULT) { 2333a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (mAudioTrack != NULL) { 2343a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar src = AVSYNC_SOURCE_AUDIO; 2353a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } else { 2363a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar src = AVSYNC_SOURCE_SYSTEM_CLOCK; 2373a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 238c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 239c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 2403a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // TODO: resync ourselves to the current clock (e.g. on sync source change) 2413a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar updatePlaybackRate_l(mPlaybackRate); 2423a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 243c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 2443a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid MediaSync::updatePlaybackRate_l(float rate) { 245c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (rate > mPlaybackRate) { 246c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mNextBufferItemMediaUs = -1; 247c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 248c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mPlaybackRate = rate; 24908dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar // TODO: update frame scheduler with this info 250c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mMediaClock->setPlaybackRate(rate); 251c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia onDrainVideo_l(); 252c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 253c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 254c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiasp<const MediaClock> MediaSync::getMediaClock() { 255c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return mMediaClock; 256c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 257c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 25899d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jiastatus_t MediaSync::getPlayTimeForPendingAudioFrames(int64_t *outTimeUs) { 25999d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia Mutex::Autolock lock(mMutex); 26099d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia // User should check the playback rate if it doesn't want to receive a 26199d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia // huge number for play time. 26299d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia if (mPlaybackRate == 0.0f) { 26399d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia *outTimeUs = INT64_MAX; 26499d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia return OK; 26599d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia } 26699d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia 26799d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia uint32_t numFramesPlayed = 0; 26899d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia if (mAudioTrack != NULL) { 26999d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia status_t res = mAudioTrack->getPosition(&numFramesPlayed); 27099d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia if (res != OK) { 27199d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia return res; 27299d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia } 27399d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia } 27499d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia 27599d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia int64_t numPendingFrames = mNumFramesWritten - numFramesPlayed; 27699d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia if (numPendingFrames < 0) { 27799d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia numPendingFrames = 0; 27899d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia ALOGW("getPlayTimeForPendingAudioFrames: pending frame count is negative."); 27999d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia } 28099d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia double timeUs = numPendingFrames * 1000000.0 28199d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia / (mNativeSampleRateInHz * (double)mPlaybackRate); 28299d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia if (timeUs > (double)INT64_MAX) { 28399d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia // Overflow. 28499d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia *outTimeUs = INT64_MAX; 28599d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia ALOGW("getPlayTimeForPendingAudioFrames: play time for pending audio frames " 28699d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia "is too high, possibly due to super low playback rate(%f)", mPlaybackRate); 28799d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia } else { 28899d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia *outTimeUs = (int64_t)timeUs; 28999d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia } 29099d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia 29199d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia return OK; 29299d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia} 29399d1f78c9b16b5668e78c353373e0e7f4592cab9Wei Jia 294c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiastatus_t MediaSync::updateQueuedAudioData( 295c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia size_t sizeInBytes, int64_t presentationTimeUs) { 296c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (sizeInBytes == 0) { 297c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return OK; 298c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 299c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 300c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia Mutex::Autolock lock(mMutex); 301c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 302c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (mAudioTrack == NULL) { 303c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia ALOGW("updateQueuedAudioData: audioTrack has NOT been configured."); 304c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return INVALID_OPERATION; 305c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 306c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 307c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia int64_t numFrames = sizeInBytes / mAudioTrack->frameSize(); 308c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia int64_t maxMediaTimeUs = presentationTimeUs 309c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia + getDurationIfPlayedAtNativeSampleRate_l(numFrames); 310c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 311c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia int64_t nowUs = ALooper::GetNowUs(); 31280243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia int64_t nowMediaUs = presentationTimeUs 313c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia - getDurationIfPlayedAtNativeSampleRate_l(mNumFramesWritten) 314c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia + getPlayedOutAudioDurationMedia_l(nowUs); 315c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 31680243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia mNumFramesWritten += numFrames; 31780243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia 318c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia int64_t oldRealTime = -1; 319c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (mNextBufferItemMediaUs != -1) { 320c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia oldRealTime = getRealTime(mNextBufferItemMediaUs, nowUs); 321c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 322c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 323c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mMediaClock->updateAnchor(nowMediaUs, nowUs, maxMediaTimeUs); 324c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mHasAudio = true; 325c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 326c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (oldRealTime != -1) { 327c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia int64_t newRealTime = getRealTime(mNextBufferItemMediaUs, nowUs); 32880243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia if (newRealTime >= oldRealTime) { 32980243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia return OK; 330c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 331c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 332c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 33380243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia mNextBufferItemMediaUs = -1; 33480243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia onDrainVideo_l(); 335c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return OK; 336c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 337c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 338c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiavoid MediaSync::setName(const AString &name) { 339c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia Mutex::Autolock lock(mMutex); 340c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mInput->setConsumerName(String8(name.c_str())); 341c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 342c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 34308dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnarvoid MediaSync::flush() { 34408dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar Mutex::Autolock lock(mMutex); 34508dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar if (mFrameScheduler != NULL) { 34608dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar mFrameScheduler->restart(); 34708dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar } 34808dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar while (!mBufferItems.empty()) { 34908dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar BufferItem *bufferItem = &*mBufferItems.begin(); 35008dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar returnBufferToInput_l(bufferItem->mGraphicBuffer, bufferItem->mFence); 35108dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar mBufferItems.erase(mBufferItems.begin()); 35208dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar } 35308dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar mNextBufferItemMediaUs = -1; 35408dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar mNumFramesWritten = 0; 35508dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar mReturnPendingInputFrame = true; 35608dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar mReleaseCondition.signal(); 35708dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar mMediaClock->clearAnchor(); 35808dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar} 35908dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar 3603a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t MediaSync::setVideoFrameRateHint(float rate) { 361a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar Mutex::Autolock lock(mMutex); 362a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar if (rate < 0.f) { 363a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar return BAD_VALUE; 364a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar } 365a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar if (mFrameScheduler != NULL) { 366a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar mFrameScheduler->init(rate); 367a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar } 368a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar return OK; 3693a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 3703a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 3713a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarfloat MediaSync::getVideoFrameRate() { 372a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar Mutex::Autolock lock(mMutex); 373a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar if (mFrameScheduler != NULL) { 374a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar float fps = mFrameScheduler->getFrameRate(); 375a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar if (fps > 0.f) { 376a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar return fps; 377a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar } 378a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar } 379a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar 380a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar // we don't have or know the frame rate 3813a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return -1.f; 3823a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 3833a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 3843a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t MediaSync::setSyncSettings(const AVSyncSettings &syncSettings) { 3853a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // validate settings 3863a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (syncSettings.mSource >= AVSYNC_SOURCE_MAX 3873a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar || syncSettings.mAudioAdjustMode >= AVSYNC_AUDIO_ADJUST_MODE_MAX 3883a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar || syncSettings.mTolerance < 0.f 3893a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar || syncSettings.mTolerance >= AVSYNC_TOLERANCE_MAX) { 3903a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return BAD_VALUE; 3913a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 3923a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 3933a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar Mutex::Autolock lock(mMutex); 3943a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 3953a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // verify that we have the sync source 3963a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar switch (syncSettings.mSource) { 3973a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar case AVSYNC_SOURCE_AUDIO: 3983a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (mAudioTrack == NULL) { 3993a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar ALOGE("setSyncSettings: audio sync source requires an audio track"); 4003a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return BAD_VALUE; 4013a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 4023a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar break; 4033a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar case AVSYNC_SOURCE_VSYNC: 4043a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (mOutput == NULL) { 4053a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar ALOGE("setSyncSettings: vsync sync source requires an output surface"); 4063a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return BAD_VALUE; 4073a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 4083a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar break; 4093a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar default: 4103a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar break; 4113a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 4123a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 4133a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mSyncSettings = syncSettings; 4143a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar resync_l(); 4153a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return OK; 4163a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 4173a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 4183a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid MediaSync::getSyncSettings(AVSyncSettings *syncSettings) { 4193a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar Mutex::Autolock lock(mMutex); 4203a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar *syncSettings = mSyncSettings; 4213a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 4223a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 4233a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t MediaSync::setPlaybackSettings(const AudioPlaybackRate &rate) { 4243a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar Mutex::Autolock lock(mMutex); 4253a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 4263a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = setPlaybackSettings_l(rate); 4273a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err == OK) { 4283a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // TODO: adjust rate if using VSYNC as source 4293a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar updatePlaybackRate_l(rate.mSpeed); 4303a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 4313a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return err; 4323a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 4333a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 4343a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarstatus_t MediaSync::setPlaybackSettings_l(const AudioPlaybackRate &rate) { 4353a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (rate.mSpeed < 0.f || rate.mPitch < 0.f) { 4363a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // We don't validate other audio settings. 4373a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // They will be validated when/if audiotrack is set. 4383a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return BAD_VALUE; 4393a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 4403a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 4413a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (mAudioTrack != NULL) { 4423a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (rate.mSpeed == 0.f) { 4433a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mAudioTrack->pause(); 4443a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } else { 4453a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar status_t err = mAudioTrack->setPlaybackRate(rate); 4463a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar if (err != OK) { 4473a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return BAD_VALUE; 4483a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 4493a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 4503a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar // ignore errors 4513a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar (void)mAudioTrack->start(); 4523a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 4533a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar } 4543a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar mPlaybackSettings = rate; 4553a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar return OK; 4563a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 4573a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 4583a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid MediaSync::getPlaybackSettings(AudioPlaybackRate *rate) { 4593a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar Mutex::Autolock lock(mMutex); 4603a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar *rate = mPlaybackSettings; 4613a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 4623a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 463c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiaint64_t MediaSync::getRealTime(int64_t mediaTimeUs, int64_t nowUs) { 464c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia int64_t realUs; 465c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (mMediaClock->getRealTimeFor(mediaTimeUs, &realUs) != OK) { 466c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // If failed to get current position, e.g. due to audio clock is 467c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // not ready, then just play out video immediately without delay. 468c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return nowUs; 469c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 470c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return realUs; 471c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 472c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 473c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiaint64_t MediaSync::getDurationIfPlayedAtNativeSampleRate_l(int64_t numFrames) { 474c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return (numFrames * 1000000LL / mNativeSampleRateInHz); 475c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 476c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 477c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiaint64_t MediaSync::getPlayedOutAudioDurationMedia_l(int64_t nowUs) { 478c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia CHECK(mAudioTrack != NULL); 479c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 480c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia uint32_t numFramesPlayed; 481c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia int64_t numFramesPlayedAt; 482c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia AudioTimestamp ts; 483c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia static const int64_t kStaleTimestamp100ms = 100000; 484c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 485c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia status_t res = mAudioTrack->getTimestamp(ts); 486c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (res == OK) { 487c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // case 1: mixing audio tracks. 488c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia numFramesPlayed = ts.mPosition; 489c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia numFramesPlayedAt = 490c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia ts.mTime.tv_sec * 1000000LL + ts.mTime.tv_nsec / 1000; 491c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia const int64_t timestampAge = nowUs - numFramesPlayedAt; 492c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (timestampAge > kStaleTimestamp100ms) { 493c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // This is an audio FIXME. 494c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // getTimestamp returns a timestamp which may come from audio 495c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // mixing threads. After pausing, the MixerThread may go idle, 496c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // thus the mTime estimate may become stale. Assuming that the 497c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // MixerThread runs 20ms, with FastMixer at 5ms, the max latency 498c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // should be about 25ms with an average around 12ms (to be 499c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // verified). For safety we use 100ms. 500c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia ALOGV("getTimestamp: returned stale timestamp nowUs(%lld) " 501c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia "numFramesPlayedAt(%lld)", 502c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia (long long)nowUs, (long long)numFramesPlayedAt); 503c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia numFramesPlayedAt = nowUs - kStaleTimestamp100ms; 504c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 505c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia //ALOGD("getTimestamp: OK %d %lld", 506c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // numFramesPlayed, (long long)numFramesPlayedAt); 507c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } else if (res == WOULD_BLOCK) { 508c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // case 2: transitory state on start of a new track 509c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia numFramesPlayed = 0; 510c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia numFramesPlayedAt = nowUs; 511c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia //ALOGD("getTimestamp: WOULD_BLOCK %d %lld", 512c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // numFramesPlayed, (long long)numFramesPlayedAt); 513c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } else { 514c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // case 3: transitory at new track or audio fast tracks. 515c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia res = mAudioTrack->getPosition(&numFramesPlayed); 516c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia CHECK_EQ(res, (status_t)OK); 517c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia numFramesPlayedAt = nowUs; 518c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia numFramesPlayedAt += 1000LL * mAudioTrack->latency() / 2; /* XXX */ 519a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar //ALOGD("getPosition: %d %lld", numFramesPlayed, (long long)numFramesPlayedAt); 520c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 521c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 522c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia //can't be negative until 12.4 hrs, test. 523c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia //CHECK_EQ(numFramesPlayed & (1 << 31), 0); 524c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia int64_t durationUs = 525c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia getDurationIfPlayedAtNativeSampleRate_l(numFramesPlayed) 526c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia + nowUs - numFramesPlayedAt; 527c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (durationUs < 0) { 528c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // Occurs when numFramesPlayed position is very small and the following: 529c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // (1) In case 1, the time nowUs is computed before getTimestamp() is 530c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // called and numFramesPlayedAt is greater than nowUs by time more 531c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // than numFramesPlayed. 532c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // (2) In case 3, using getPosition and adding mAudioTrack->latency() 533c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // to numFramesPlayedAt, by a time amount greater than 534c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // numFramesPlayed. 535c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // 536c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // Both of these are transitory conditions. 537c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia ALOGV("getPlayedOutAudioDurationMedia_l: negative duration %lld " 538c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia "set to zero", (long long)durationUs); 539c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia durationUs = 0; 540c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 541c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia ALOGV("getPlayedOutAudioDurationMedia_l(%lld) nowUs(%lld) frames(%u) " 542c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia "framesAt(%lld)", 543c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia (long long)durationUs, (long long)nowUs, numFramesPlayed, 544c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia (long long)numFramesPlayedAt); 545c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return durationUs; 546c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 547c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 548c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiavoid MediaSync::onDrainVideo_l() { 549c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (!isPlaying()) { 550c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return; 551c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 552c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 553c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia while (!mBufferItems.empty()) { 55480243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia int64_t nowUs = ALooper::GetNowUs(); 555c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia BufferItem *bufferItem = &*mBufferItems.begin(); 556c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia int64_t itemMediaUs = bufferItem->mTimestamp / 1000; 557c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia int64_t itemRealUs = getRealTime(itemMediaUs, nowUs); 55880243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia 559a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar // adjust video frame PTS based on vsync 560a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar itemRealUs = mFrameScheduler->schedule(itemRealUs * 1000) / 1000; 56182a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar int64_t twoVsyncsUs = 2 * (mFrameScheduler->getVsyncPeriod() / 1000); 562a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar 563a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar // post 2 display refreshes before rendering is due 564a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar if (itemRealUs <= nowUs + twoVsyncsUs) { 565a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar ALOGV("adjusting PTS from %lld to %lld", 566a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar (long long)bufferItem->mTimestamp / 1000, (long long)itemRealUs); 567a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar bufferItem->mTimestamp = itemRealUs * 1000; 568a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar bufferItem->mIsAutoTimestamp = false; 569a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar 570c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (mHasAudio) { 571c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (nowUs - itemRealUs <= kMaxAllowedVideoLateTimeUs) { 57282a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar renderOneBufferItem_l(*bufferItem); 573c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } else { 574c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // too late. 575c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia returnBufferToInput_l( 576c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia bufferItem->mGraphicBuffer, bufferItem->mFence); 577a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar mFrameScheduler->restart(); 578c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 579c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } else { 580c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // always render video buffer in video-only mode. 58182a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar renderOneBufferItem_l(*bufferItem); 582c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 583c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // smooth out videos >= 10fps 584c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mMediaClock->updateAnchor( 585c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia itemMediaUs, nowUs, itemMediaUs + 100000); 586c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 587c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 588c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mBufferItems.erase(mBufferItems.begin()); 58980243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia mNextBufferItemMediaUs = -1; 590c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } else { 591c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (mNextBufferItemMediaUs == -1 59280243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia || mNextBufferItemMediaUs > itemMediaUs) { 593c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia sp<AMessage> msg = new AMessage(kWhatDrainVideo, this); 594a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar msg->post(itemRealUs - nowUs - twoVsyncsUs); 59580243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia mNextBufferItemMediaUs = itemMediaUs; 596c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 597c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia break; 598c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 599c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 600c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 601c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 602c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiavoid MediaSync::onFrameAvailableFromInput() { 603c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia Mutex::Autolock lock(mMutex); 604c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 605a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar const static nsecs_t kAcquireWaitTimeout = 2000000000; // 2 seconds 606a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar 60708dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar mReturnPendingInputFrame = false; 60808dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar 609c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // If there are too many outstanding buffers, wait until a buffer is 610c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // released back to the input in onBufferReleased. 611a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar // NOTE: BufferQueue allows dequeuing maxAcquiredBufferCount + 1 buffers 61208dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar while (mNumOutstandingBuffers > mMaxAcquiredBufferCount 61308dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar && !mIsAbandoned && !mReturnPendingInputFrame) { 614a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar if (mReleaseCondition.waitRelative(mMutex, kAcquireWaitTimeout) != OK) { 61582a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar ALOGI_IF(mPlaybackRate != 0.f, "still waiting to release a buffer before acquire"); 616a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar } 617c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 618c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // If the sync is abandoned while we are waiting, the release 619c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // condition variable will be broadcast, and we should just return 620c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // without attempting to do anything more (since the input queue will 621c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // also be abandoned). 622c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (mIsAbandoned) { 623c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return; 624c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 625c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 626c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 627c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // Acquire and detach the buffer from the input. 628c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia BufferItem bufferItem; 629c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia status_t status = mInput->acquireBuffer(&bufferItem, 0 /* presentWhen */); 630c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (status != NO_ERROR) { 631c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia ALOGE("acquiring buffer from input failed (%d)", status); 632c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return; 633c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 634264bac95912efe121d6a60026612617f04f42966Lajos Molnar ++mNumOutstandingBuffers; 635c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 636c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia ALOGV("acquired buffer %#llx from input", (long long)bufferItem.mGraphicBuffer->getId()); 637c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 638a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos status = mInput->detachBuffer(bufferItem.mSlot); 639c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (status != NO_ERROR) { 640c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia ALOGE("detaching buffer from input failed (%d)", status); 641c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (status == NO_INIT) { 642c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // If the input has been abandoned, move on. 643c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia onAbandoned_l(true /* isInput */); 644c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 645c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return; 646c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 647c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 648bac588208fadec78e3fa205c238089df277d3817Wei Jia if (mBuffersFromInput.indexOfKey(bufferItem.mGraphicBuffer->getId()) >= 0) { 649bac588208fadec78e3fa205c238089df277d3817Wei Jia // Something is wrong since this buffer should be at our hands, bail. 650a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar ALOGE("received buffer multiple times from input"); 651bac588208fadec78e3fa205c238089df277d3817Wei Jia mInput->consumerDisconnect(); 652bac588208fadec78e3fa205c238089df277d3817Wei Jia onAbandoned_l(true /* isInput */); 653bac588208fadec78e3fa205c238089df277d3817Wei Jia return; 654bac588208fadec78e3fa205c238089df277d3817Wei Jia } 655bac588208fadec78e3fa205c238089df277d3817Wei Jia mBuffersFromInput.add(bufferItem.mGraphicBuffer->getId(), bufferItem.mGraphicBuffer); 656bac588208fadec78e3fa205c238089df277d3817Wei Jia 65708dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar // If flush happened while waiting for a buffer to be released, simply return it 65808dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar // TRICKY: do it here after it is detached so that we don't have to cache mGraphicBuffer. 65908dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar if (mReturnPendingInputFrame) { 66008dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar mReturnPendingInputFrame = false; 66108dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar returnBufferToInput_l(bufferItem.mGraphicBuffer, bufferItem.mFence); 66208dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar return; 66308dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar } 66408dc42c46c942ff316a69be1cf74f3c60cf53e7fLajos Molnar 665c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mBufferItems.push_back(bufferItem); 666bac588208fadec78e3fa205c238089df277d3817Wei Jia 66780243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia if (mBufferItems.size() == 1) { 66880243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia onDrainVideo_l(); 66980243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia } 670c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 671c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 67282a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnarvoid MediaSync::renderOneBufferItem_l(const BufferItem &bufferItem) { 673c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia IGraphicBufferProducer::QueueBufferInput queueInput( 674c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia bufferItem.mTimestamp, 675c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia bufferItem.mIsAutoTimestamp, 676c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia bufferItem.mDataSpace, 677c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia bufferItem.mCrop, 678c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia static_cast<int32_t>(bufferItem.mScalingMode), 679c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia bufferItem.mTransform, 680c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia bufferItem.mFence); 681c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 682c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // Attach and queue the buffer to the output. 683c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia int slot; 684264bac95912efe121d6a60026612617f04f42966Lajos Molnar mOutput->setGenerationNumber(bufferItem.mGraphicBuffer->getGenerationNumber()); 685c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia status_t status = mOutput->attachBuffer(&slot, bufferItem.mGraphicBuffer); 686c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia ALOGE_IF(status != NO_ERROR, "attaching buffer to output failed (%d)", status); 687c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (status == NO_ERROR) { 688c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia IGraphicBufferProducer::QueueBufferOutput queueOutput; 689c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia status = mOutput->queueBuffer(slot, queueInput, &queueOutput); 690c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia ALOGE_IF(status != NO_ERROR, "queueing buffer to output failed (%d)", status); 691c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 692c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 693c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (status != NO_ERROR) { 694c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia returnBufferToInput_l(bufferItem.mGraphicBuffer, bufferItem.mFence); 695c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (status == NO_INIT) { 696c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // If the output has been abandoned, move on. 697c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia onAbandoned_l(false /* isInput */); 698c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 699c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia return; 700c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 701c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 702b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia if (mBuffersSentToOutput.indexOfKey(bufferItem.mGraphicBuffer->getId()) >= 0) { 703b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia // Something is wrong since this buffer should be held by output now, bail. 704b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia mInput->consumerDisconnect(); 705b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia onAbandoned_l(true /* isInput */); 706b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia return; 707b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia } 708b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia mBuffersSentToOutput.add(bufferItem.mGraphicBuffer->getId(), bufferItem.mGraphicBuffer); 709b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia 710c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia ALOGV("queued buffer %#llx to output", (long long)bufferItem.mGraphicBuffer->getId()); 711c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 712c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 713b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jiavoid MediaSync::onBufferReleasedByOutput(sp<IGraphicBufferProducer> &output) { 714c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia Mutex::Autolock lock(mMutex); 715c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 716b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia if (output != mOutput) { 717b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia return; // This is not the current output, ignore. 718b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia } 719b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia 720c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia sp<GraphicBuffer> buffer; 721c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia sp<Fence> fence; 72282a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar status_t status = mOutput->detachNextBuffer(&buffer, &fence); 72382a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar ALOGE_IF(status != NO_ERROR, "detaching buffer from output failed (%d)", status); 724c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 72582a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar if (status == NO_INIT) { 72682a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar // If the output has been abandoned, we can't do anything else, 72782a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar // since buffer is invalid. 72882a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar onAbandoned_l(false /* isInput */); 72982a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar return; 73082a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar } 731c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 73282a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar ALOGV("detached buffer %#llx from output", (long long)buffer->getId()); 733c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 73482a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar // If we've been abandoned, we can't return the buffer to the input, so just 73582a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar // move on. 73682a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar if (mIsAbandoned) { 73782a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar return; 73882a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar } 739b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia 74082a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar ssize_t ix = mBuffersSentToOutput.indexOfKey(buffer->getId()); 74182a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar if (ix < 0) { 74282a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar // The buffer is unknown, maybe leftover, ignore. 74382a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar return; 744a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar } 74582a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar mBuffersSentToOutput.removeItemsAt(ix); 74682a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar 74782a633b602a7ffe1efd9886744393f52a093a2f3Lajos Molnar returnBufferToInput_l(buffer, fence); 748c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 749c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 750c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiavoid MediaSync::returnBufferToInput_l( 751c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia const sp<GraphicBuffer> &buffer, const sp<Fence> &fence) { 752bac588208fadec78e3fa205c238089df277d3817Wei Jia ssize_t ix = mBuffersFromInput.indexOfKey(buffer->getId()); 753bac588208fadec78e3fa205c238089df277d3817Wei Jia if (ix < 0) { 754bac588208fadec78e3fa205c238089df277d3817Wei Jia // The buffer is unknown, something is wrong, bail. 755a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnar ALOGE("output returned unknown buffer"); 756bac588208fadec78e3fa205c238089df277d3817Wei Jia mOutput->disconnect(NATIVE_WINDOW_API_MEDIA); 757bac588208fadec78e3fa205c238089df277d3817Wei Jia onAbandoned_l(false /* isInput */); 758bac588208fadec78e3fa205c238089df277d3817Wei Jia return; 759bac588208fadec78e3fa205c238089df277d3817Wei Jia } 760bac588208fadec78e3fa205c238089df277d3817Wei Jia sp<GraphicBuffer> oldBuffer = mBuffersFromInput.valueAt(ix); 761bac588208fadec78e3fa205c238089df277d3817Wei Jia mBuffersFromInput.removeItemsAt(ix); 762bac588208fadec78e3fa205c238089df277d3817Wei Jia 763c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // Attach and release the buffer back to the input. 764c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia int consumerSlot; 765bac588208fadec78e3fa205c238089df277d3817Wei Jia status_t status = mInput->attachBuffer(&consumerSlot, oldBuffer); 766c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia ALOGE_IF(status != NO_ERROR, "attaching buffer to input failed (%d)", status); 767c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (status == NO_ERROR) { 768c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia status = mInput->releaseBuffer(consumerSlot, 0 /* frameNumber */, 769c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence); 770c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia ALOGE_IF(status != NO_ERROR, "releasing buffer to input failed (%d)", status); 771c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 772c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 773c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia // Notify any waiting onFrameAvailable calls. 774c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia --mNumOutstandingBuffers; 775c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mReleaseCondition.signal(); 776264bac95912efe121d6a60026612617f04f42966Lajos Molnar 777264bac95912efe121d6a60026612617f04f42966Lajos Molnar if (status == NO_ERROR) { 778264bac95912efe121d6a60026612617f04f42966Lajos Molnar ALOGV("released buffer %#llx to input", (long long)oldBuffer->getId()); 779264bac95912efe121d6a60026612617f04f42966Lajos Molnar } 780c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 781c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 782c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiavoid MediaSync::onAbandoned_l(bool isInput) { 783c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia ALOGE("the %s has abandoned me", (isInput ? "input" : "output")); 784c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (!mIsAbandoned) { 785c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia if (isInput) { 786c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mOutput->disconnect(NATIVE_WINDOW_API_MEDIA); 787c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } else { 788c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mInput->consumerDisconnect(); 789c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 790c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mIsAbandoned = true; 791c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 792c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mReleaseCondition.broadcast(); 793c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 794c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 795c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiavoid MediaSync::onMessageReceived(const sp<AMessage> &msg) { 796c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia switch (msg->what()) { 797c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia case kWhatDrainVideo: 798c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia { 799c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia Mutex::Autolock lock(mMutex); 80080243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia if (mNextBufferItemMediaUs != -1) { 80180243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia int64_t nowUs = ALooper::GetNowUs(); 80280243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia int64_t itemRealUs = getRealTime(mNextBufferItemMediaUs, nowUs); 80380243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia 80480243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia // The message could arrive earlier than expected due to 80580243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia // various reasons, e.g., media clock has been changed because 80680243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia // of new anchor time or playback rate. In such cases, the 80780243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia // message needs to be re-posted. 80880243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia if (itemRealUs > nowUs) { 80980243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia msg->post(itemRealUs - nowUs); 81080243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia break; 81180243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia } 81280243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia } 81380243639b0aa2c7c941c23c1aaeaa75de38c148cWei Jia 814c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia onDrainVideo_l(); 815c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia break; 816c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 817c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 818c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia default: 819c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia TRESPASS(); 820c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia break; 821c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia } 822c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 823c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 824c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei JiaMediaSync::InputListener::InputListener(const sp<MediaSync> &sync) 825c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia : mSync(sync) {} 826c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 827c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei JiaMediaSync::InputListener::~InputListener() {} 828c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 829c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiavoid MediaSync::InputListener::onFrameAvailable(const BufferItem &/* item */) { 830c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mSync->onFrameAvailableFromInput(); 831c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 832c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 833c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia// We don't care about sideband streams, since we won't relay them. 834c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiavoid MediaSync::InputListener::onSidebandStreamChanged() { 835c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia ALOGE("onSidebandStreamChanged: got sideband stream unexpectedly."); 836c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 837c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 838c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 839c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiavoid MediaSync::InputListener::binderDied(const wp<IBinder> &/* who */) { 840c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia Mutex::Autolock lock(mSync->mMutex); 841c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mSync->onAbandoned_l(true /* isInput */); 842c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 843c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 844b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei JiaMediaSync::OutputListener::OutputListener(const sp<MediaSync> &sync, 845b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia const sp<IGraphicBufferProducer> &output) 846b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia : mSync(sync), 847b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia mOutput(output) {} 848c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 849c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei JiaMediaSync::OutputListener::~OutputListener() {} 850c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 851c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiavoid MediaSync::OutputListener::onBufferReleased() { 852b6ea1292f8adae45d95c6f37d50c96534219b6d2Wei Jia mSync->onBufferReleasedByOutput(mOutput); 853c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 854c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 855c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jiavoid MediaSync::OutputListener::binderDied(const wp<IBinder> &/* who */) { 856c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia Mutex::Autolock lock(mSync->mMutex); 857c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia mSync->onAbandoned_l(false /* isInput */); 858c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} 859c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia 860c8db9712d9abe9b0d74193ea7d7cff428e32e62cWei Jia} // namespace android 861