1f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/* 2f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Copyright (C) 2010 The Android Open Source Project 3f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 4f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * you may not use this file except in compliance with the License. 6f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * You may obtain a copy of the License at 7f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 8f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 10f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Unless required by applicable law or agreed to in writing, software 11f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * See the License for the specific language governing permissions and 14f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * limitations under the License. 15f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 16f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0 18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "NuPlayer" 19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Log.h> 20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayer.h" 225bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 235bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include "HTTPLiveSource.h" 24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerDecoder.h" 2543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber#include "NuPlayerDriver.h" 26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerRenderer.h" 275bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include "NuPlayerSource.h" 282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber#include "RTSPSource.h" 295bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include "StreamingSource.h" 30afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include "GenericSource.h" 315bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 325bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include "ATSParser.h" 33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 343831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber#include <media/stagefright/foundation/hexdump.h> 35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h> 37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h> 38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h> 393fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber#include <media/stagefright/MediaDefs.h> 40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaErrors.h> 41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MetaData.h> 421173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <gui/ISurfaceTexture.h> 43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 443fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber#include "avc_utils.h" 453fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 46f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android { 47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//////////////////////////////////////////////////////////////////////////////// 49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 50f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::NuPlayer() 519b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber : mUIDValid(false), 523fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mVideoIsAVC(false), 539b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber mAudioEOS(false), 54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoEOS(false), 555bc087c573c70c84c6a39946457590b42d392a33Andreas Huber mScanSourcesPending(false), 561aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mScanSourcesGeneration(0), 576e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber mTimeDiscontinuityPending(false), 58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushingAudio(NONE), 591aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mFlushingVideo(NONE), 601aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mResetInProgress(false), 613fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mResetPostponed(false), 623fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mSkipRenderingAudioUntilMediaTimeUs(-1ll), 633fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mSkipRenderingVideoUntilMediaTimeUs(-1ll), 643fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mVideoLateByUs(0ll), 653fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mNumFramesTotal(0ll), 668b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen mNumFramesDropped(0ll) { 67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 69f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::~NuPlayer() { 70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 729b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Hubervoid NuPlayer::setUID(uid_t uid) { 739b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber mUIDValid = true; 749b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber mUID = uid; 759b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber} 769b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber 7743c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) { 7843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mDriver = driver; 79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 81f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::setDataSource(const sp<IStreamSource> &source) { 82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); 83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 845bc087c573c70c84c6a39946457590b42d392a33Andreas Huber msg->setObject("source", new StreamingSource(source)); 855bc087c573c70c84c6a39946457590b42d392a33Andreas Huber msg->post(); 865bc087c573c70c84c6a39946457590b42d392a33Andreas Huber} 875bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 88afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatic bool IsHTTPLiveURL(const char *url) { 89afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (!strncasecmp("http://", url, 7) 90afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber || !strncasecmp("https://", url, 8)) { 91afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber size_t len = strlen(url); 92afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) { 93afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber return true; 94afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 95afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 96afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (strstr(url,"m3u8")) { 97afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber return true; 98afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 99afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 100afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 101afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber return false; 102afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber} 103afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1045bc087c573c70c84c6a39946457590b42d392a33Andreas Hubervoid NuPlayer::setDataSource( 1055bc087c573c70c84c6a39946457590b42d392a33Andreas Huber const char *url, const KeyedVector<String8, String8> *headers) { 1065bc087c573c70c84c6a39946457590b42d392a33Andreas Huber sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); 107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 108afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber sp<Source> source; 109afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (IsHTTPLiveURL(url)) { 110afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber source = new HTTPLiveSource(url, headers, mUIDValid, mUID); 111afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } else if (!strncasecmp(url, "rtsp://", 7)) { 112afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber source = new RTSPSource(url, headers, mUIDValid, mUID); 1132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } else { 114afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber source = new GenericSource(url, headers, mUIDValid, mUID); 1152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 1162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 117afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber msg->setObject("source", source); 118afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber msg->post(); 119afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber} 120afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 121afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubervoid NuPlayer::setDataSource(int fd, int64_t offset, int64_t length) { 122afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); 123afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 124afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber sp<Source> source = new GenericSource(fd, offset, length); 125afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber msg->setObject("source", source); 126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1291173118eace0e9e347cb007f0da817cee87579edGlenn Kastenvoid NuPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) { 1301173118eace0e9e347cb007f0da817cee87579edGlenn Kasten sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id()); 1311173118eace0e9e347cb007f0da817cee87579edGlenn Kasten sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ? 1321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten new SurfaceTextureClient(surfaceTexture) : NULL); 1331173118eace0e9e347cb007f0da817cee87579edGlenn Kasten msg->setObject("native-window", new NativeWindowWrapper(surfaceTextureClient)); 134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 137f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) { 138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id()); 139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setObject("sink", sink); 140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(); 141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 143f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::start() { 144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (new AMessage(kWhatStart, id()))->post(); 145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 14743c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::pause() { 148b408222bd9479c291874b607acae1425d6154fe7Andreas Huber (new AMessage(kWhatPause, id()))->post(); 14943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber} 15043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 15143c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::resume() { 152b408222bd9479c291874b607acae1425d6154fe7Andreas Huber (new AMessage(kWhatResume, id()))->post(); 15343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber} 15443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 1551aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::resetAsync() { 1561aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber (new AMessage(kWhatReset, id()))->post(); 1571aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber} 1581aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 15943c3e6ce02215ca99d506458f596cb1211639f29Andreas Hubervoid NuPlayer::seekToAsync(int64_t seekTimeUs) { 16043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber sp<AMessage> msg = new AMessage(kWhatSeek, id()); 16143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber msg->setInt64("seekTimeUs", seekTimeUs); 16243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber msg->post(); 16343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber} 16443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 16553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber// static 1661aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberbool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) { 16753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber switch (state) { 16853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber case FLUSHING_DECODER: 1691aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (needShutdown != NULL) { 1701aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber *needShutdown = false; 17153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber } 17253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber return true; 17353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber 1741aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber case FLUSHING_DECODER_SHUTDOWN: 1751aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (needShutdown != NULL) { 1761aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber *needShutdown = true; 17753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber } 17853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber return true; 17953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber 18053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber default: 18153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber return false; 18253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber } 18353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber} 18453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber 185f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::onMessageReceived(const sp<AMessage> &msg) { 186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatSetDataSource: 188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 1893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("kWhatSetDataSource"); 190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mSource == NULL); 192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1935bc087c573c70c84c6a39946457590b42d392a33Andreas Huber sp<RefBase> obj; 1945bc087c573c70c84c6a39946457590b42d392a33Andreas Huber CHECK(msg->findObject("source", &obj)); 195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1965bc087c573c70c84c6a39946457590b42d392a33Andreas Huber mSource = static_cast<Source *>(obj.get()); 197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2001173118eace0e9e347cb007f0da817cee87579edGlenn Kasten case kWhatSetVideoNativeWindow: 201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 2023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("kWhatSetVideoNativeWindow"); 203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<RefBase> obj; 2051173118eace0e9e347cb007f0da817cee87579edGlenn Kasten CHECK(msg->findObject("native-window", &obj)); 206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2071173118eace0e9e347cb007f0da817cee87579edGlenn Kasten mNativeWindow = static_cast<NativeWindowWrapper *>(obj.get()); 208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatSetAudioSink: 212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 2133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("kWhatSetAudioSink"); 214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<RefBase> obj; 216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findObject("sink", &obj)); 217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get()); 219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatStart: 223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 2243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("kWhatStart"); 22543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 2263fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mVideoIsAVC = false; 2271aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mAudioEOS = false; 2281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mVideoEOS = false; 22932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber mSkipRenderingAudioUntilMediaTimeUs = -1; 23032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber mSkipRenderingVideoUntilMediaTimeUs = -1; 2313fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mVideoLateByUs = 0; 2323fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mNumFramesTotal = 0; 2333fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mNumFramesDropped = 0; 2341aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 2355bc087c573c70c84c6a39946457590b42d392a33Andreas Huber mSource->start(); 236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mRenderer = new Renderer( 238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioSink, 239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber new AMessage(kWhatRendererNotify, id())); 240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber looper()->registerHandler(mRenderer); 242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2431aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber postScanSources(); 244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatScanSources: 248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 2491aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber int32_t generation; 2501aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber CHECK(msg->findInt32("generation", &generation)); 2511aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (generation != mScanSourcesGeneration) { 2521aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber // Drop obsolete msg. 2531aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber break; 2541aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 2551aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 2565bc087c573c70c84c6a39946457590b42d392a33Andreas Huber mScanSourcesPending = false; 2575bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 2583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("scanning sources haveAudio=%d, haveVideo=%d", 25943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mAudioDecoder != NULL, mVideoDecoder != NULL); 26043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 2615bc087c573c70c84c6a39946457590b42d392a33Andreas Huber instantiateDecoder(false, &mVideoDecoder); 262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mAudioSink != NULL) { 2645bc087c573c70c84c6a39946457590b42d392a33Andreas Huber instantiateDecoder(true, &mAudioDecoder); 265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 267eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber status_t err; 268eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber if ((err = mSource->feedMoreTSData()) != OK) { 2691aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (mAudioDecoder == NULL && mVideoDecoder == NULL) { 2701aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber // We're not currently decoding anything (no audio or 2711aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber // video tracks found) and we just ran out of input data. 272eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber 273eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber if (err == ERROR_END_OF_STREAM) { 274eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); 275eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber } else { 276eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); 277eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber } 2781aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mAudioDecoder == NULL || mVideoDecoder == NULL) { 283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->post(100000ll); 2845bc087c573c70c84c6a39946457590b42d392a33Andreas Huber mScanSourcesPending = true; 285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatVideoNotify: 290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatAudioNotify: 291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool audio = msg->what() == kWhatAudioNotify; 293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> codecRequest; 295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findMessage("codec-request", &codecRequest)); 296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t what; 298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(codecRequest->findInt32("what", &what)); 299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (what == ACodec::kWhatFillThisBuffer) { 301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = feedDecoderInputData( 302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber audio, codecRequest); 303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3045bc087c573c70c84c6a39946457590b42d392a33Andreas Huber if (err == -EWOULDBLOCK) { 305eac68baf095aeef54865c28b6888924dc6295cbdAndreas Huber if (mSource->feedMoreTSData() == OK) { 3061183a4ab06b9fe01fe39a4b8728bfc71789361fcAndreas Huber msg->post(10000ll); 3075bc087c573c70c84c6a39946457590b42d392a33Andreas Huber } 308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (what == ACodec::kWhatEOS) { 310dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber int32_t err; 311dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber CHECK(codecRequest->findInt32("err", &err)); 312dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber 313dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber if (err == ERROR_END_OF_STREAM) { 3143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("got %s decoder EOS", audio ? "audio" : "video"); 315dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber } else { 3163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("got %s decoder EOS w/ error %d", 317dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber audio ? "audio" : "video", 318dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber err); 319dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber } 320dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber 321dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber mRenderer->queueEOS(audio, err); 322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (what == ACodec::kWhatFlushCompleted) { 3231aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber bool needShutdown; 32453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber 325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 3261aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber CHECK(IsFlushingState(mFlushingAudio, &needShutdown)); 327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushingAudio = FLUSHED; 328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 3291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber CHECK(IsFlushingState(mFlushingVideo, &needShutdown)); 330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFlushingVideo = FLUSHED; 3313fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 3323fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mVideoLateByUs = 0; 333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("decoder %s flush completed", audio ? "audio" : "video"); 336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3371aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (needShutdown) { 3383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("initiating %s decoder shutdown", 33953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber audio ? "audio" : "video"); 340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 34153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown(); 342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 34353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber if (audio) { 34453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber mFlushingAudio = SHUTTING_DOWN_DECODER; 34553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber } else { 34653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber mFlushingVideo = SHUTTING_DOWN_DECODER; 34753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber } 348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 3493831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 3503831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber finishFlushIfPossible(); 3512c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber } else if (what == ACodec::kWhatOutputFormatChanged) { 35231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber if (audio) { 35331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber int32_t numChannels; 35431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CHECK(codecRequest->findInt32("channel-count", &numChannels)); 3552c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber 35631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber int32_t sampleRate; 35731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CHECK(codecRequest->findInt32("sample-rate", &sampleRate)); 3582c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber 3593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Audio output format changed to %d Hz, %d channels", 36031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber sampleRate, numChannels); 3612c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber 36231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber mAudioSink->close(); 3631948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent 3641948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent audio_output_flags_t flags; 3651948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent int64_t durationUs; 3661948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent // FIXME: we should handle the case where the video decoder is created after 3671948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent // we receive the format change indication. Current code will just make that 3681948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent // we select deep buffer with video which should not be a problem as it should 3691948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent // not prevent from keeping A/V sync. 3701948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent if (mVideoDecoder == NULL && 3711948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent mSource->getDuration(&durationUs) == OK && 3721948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) { 3731948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 3741948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent } else { 3751948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent flags = AUDIO_OUTPUT_FLAG_NONE; 3761948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent } 3771948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent 3789806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t channelMask; 3799806555d3930be43e11106281dee354820ac1c88Andreas Huber if (!codecRequest->findInt32("channel-mask", &channelMask)) { 3809806555d3930be43e11106281dee354820ac1c88Andreas Huber channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER; 3819806555d3930be43e11106281dee354820ac1c88Andreas Huber } 3829806555d3930be43e11106281dee354820ac1c88Andreas Huber 383078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber CHECK_EQ(mAudioSink->open( 384078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber sampleRate, 385078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber numChannels, 3869806555d3930be43e11106281dee354820ac1c88Andreas Huber (audio_channel_mask_t)channelMask, 387078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber AUDIO_FORMAT_PCM_16_BIT, 3881948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent 8 /* bufferCount */, 3891948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent NULL, 3901948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent NULL, 3911948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent flags), 392078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber (status_t)OK); 39331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber mAudioSink->start(); 3943831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 39531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber mRenderer->signalAudioSinkChanged(); 39631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } else { 39731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber // video 39831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 39931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber int32_t width, height; 40031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CHECK(codecRequest->findInt32("width", &width)); 40131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CHECK(codecRequest->findInt32("height", &height)); 40231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 40331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber int32_t cropLeft, cropTop, cropRight, cropBottom; 40431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber CHECK(codecRequest->findRect( 40531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber "crop", 40631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber &cropLeft, &cropTop, &cropRight, &cropBottom)); 40731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 4083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Video output format changed to %d x %d " 409cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber "(crop: %d x %d @ (%d, %d))", 41031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber width, height, 411cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber (cropRight - cropLeft + 1), 412cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber (cropBottom - cropTop + 1), 413cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber cropLeft, cropTop); 41431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber 41531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber notifyListener( 41631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber MEDIA_SET_VIDEO_SIZE, 41731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber cropRight - cropLeft + 1, 41831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber cropBottom - cropTop + 1); 41931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber } 4203831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } else if (what == ACodec::kWhatShutdownCompleted) { 4213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("%s shutdown completed", audio ? "audio" : "video"); 4223831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber if (audio) { 4233831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mAudioDecoder.clear(); 4243831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 4253831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER); 4263831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mFlushingAudio = SHUT_DOWN; 4273831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } else { 4283831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mVideoDecoder.clear(); 4293831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 4303831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER); 4313831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mFlushingVideo = SHUT_DOWN; 4323831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 4333831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 4343831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber finishFlushIfPossible(); 435c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber } else if (what == ACodec::kWhatError) { 43629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Received error from %s decoder, aborting playback.", 437c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber audio ? "audio" : "video"); 438c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber 439c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber mRenderer->queueEOS(audio, UNKNOWN_ERROR); 4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (what == ACodec::kWhatDrainThisBuffer) { 441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber renderBuffer(audio, codecRequest); 4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("Unhandled codec notification %d.", what); 444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatRendererNotify: 450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t what; 452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("what", &what)); 453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (what == Renderer::kWhatEOS) { 455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t audio; 456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 458c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber int32_t finalResult; 459c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber CHECK(msg->findInt32("finalResult", &finalResult)); 460c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber 461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (audio) { 462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mAudioEOS = true; 463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mVideoEOS = true; 465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 467c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber if (finalResult == ERROR_END_OF_STREAM) { 4683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("reached %s EOS", audio ? "audio" : "video"); 469c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber } else { 47029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("%s track encountered an error (%d)", 471c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber audio ? "audio" : "video", finalResult); 472c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber 473c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber notifyListener( 474c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult); 475c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber } 476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if ((mAudioEOS || mAudioDecoder == NULL) 478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber && (mVideoEOS || mVideoDecoder == NULL)) { 479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); 480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 48143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } else if (what == Renderer::kWhatPosition) { 48243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber int64_t positionUs; 48343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber CHECK(msg->findInt64("positionUs", &positionUs)); 48443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 4853fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs)); 4863fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 48743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber if (mDriver != NULL) { 48843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber sp<NuPlayerDriver> driver = mDriver.promote(); 48943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber if (driver != NULL) { 49043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber driver->notifyPosition(positionUs); 4913fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 4923fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber driver->notifyFrameStats( 4933fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mNumFramesTotal, mNumFramesDropped); 49443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 49543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 4963fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } else if (what == Renderer::kWhatFlushComplete) { 497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(what, (int32_t)Renderer::kWhatFlushComplete); 498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t audio; 500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("audio", &audio)); 501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("renderer %s flush completed.", audio ? "audio" : "video"); 503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatMoreDataQueued: 508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5121aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber case kWhatReset: 5131aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber { 5143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("kWhatReset"); 5151aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 516b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber if (mRenderer != NULL) { 517b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber // There's an edge case where the renderer owns all output 518b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber // buffers and is paused, therefore the decoder will not read 519b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber // more input data and will never encounter the matching 520b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber // discontinuity. To avoid this, we resume the renderer. 521b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber 522b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber if (mFlushingAudio == AWAITING_DISCONTINUITY 523b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber || mFlushingVideo == AWAITING_DISCONTINUITY) { 524b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber mRenderer->resume(); 525b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber } 526b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber } 527b58ce9f5e8d0696f9571a94ba5fc05f4500f663fAndreas Huber 5281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (mFlushingAudio != NONE || mFlushingVideo != NONE) { 5291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber // We're currently flushing, postpone the reset until that's 5301aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber // completed. 5311aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 532ea9d51bd710e6739077a3700f27a1c37767a2f6dAndreas Huber ALOGV("postponing reset mFlushingAudio=%d, mFlushingVideo=%d", 533ea9d51bd710e6739077a3700f27a1c37767a2f6dAndreas Huber mFlushingAudio, mFlushingVideo); 5341aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 5351aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mResetPostponed = true; 5361aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber break; 5371aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 5381aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 5391aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (mAudioDecoder == NULL && mVideoDecoder == NULL) { 5401aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber finishReset(); 5411aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber break; 5421aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 5431aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 5446e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber mTimeDiscontinuityPending = true; 5456e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber 5461aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (mAudioDecoder != NULL) { 5471aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber flushDecoder(true /* audio */, true /* needShutdown */); 5481aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 5491aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 5501aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (mVideoDecoder != NULL) { 5511aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber flushDecoder(false /* audio */, true /* needShutdown */); 5521aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 5531aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 5541aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mResetInProgress = true; 5551aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber break; 5561aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 5571aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 55843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber case kWhatSeek: 55943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber { 56043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber int64_t seekTimeUs; 56143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber CHECK(msg->findInt64("seekTimeUs", &seekTimeUs)); 56243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 5633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("kWhatSeek seekTimeUs=%lld us (%.2f secs)", 56443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber seekTimeUs, seekTimeUs / 1E6); 56543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 56643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mSource->seekTo(seekTimeUs); 56743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 56843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber if (mDriver != NULL) { 56943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber sp<NuPlayerDriver> driver = mDriver.promote(); 57043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber if (driver != NULL) { 57143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber driver->notifySeekComplete(); 57243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 57343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 57443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 57543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber break; 57643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 57743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 578b408222bd9479c291874b607acae1425d6154fe7Andreas Huber case kWhatPause: 579b408222bd9479c291874b607acae1425d6154fe7Andreas Huber { 580b408222bd9479c291874b607acae1425d6154fe7Andreas Huber CHECK(mRenderer != NULL); 581b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mRenderer->pause(); 582b408222bd9479c291874b607acae1425d6154fe7Andreas Huber break; 583b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 584b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 585b408222bd9479c291874b607acae1425d6154fe7Andreas Huber case kWhatResume: 586b408222bd9479c291874b607acae1425d6154fe7Andreas Huber { 587b408222bd9479c291874b607acae1425d6154fe7Andreas Huber CHECK(mRenderer != NULL); 588b408222bd9479c291874b607acae1425d6154fe7Andreas Huber mRenderer->resume(); 589b408222bd9479c291874b607acae1425d6154fe7Andreas Huber break; 590b408222bd9479c291874b607acae1425d6154fe7Andreas Huber } 591b408222bd9479c291874b607acae1425d6154fe7Andreas Huber 592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber TRESPASS(); 594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5983831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::finishFlushIfPossible() { 5993831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) { 6003831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber return; 6013831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 6023831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 6033831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) { 6043831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber return; 6053831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 6063831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 6073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("both audio and video are flushed now."); 6083831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 6096e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if (mTimeDiscontinuityPending) { 6106e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber mRenderer->signalTimeDiscontinuity(); 6116e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber mTimeDiscontinuityPending = false; 6126e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } 6133831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 61422fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber if (mAudioDecoder != NULL) { 6153831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mAudioDecoder->signalResume(); 6163831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 6173831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 61822fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber if (mVideoDecoder != NULL) { 6193831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mVideoDecoder->signalResume(); 6203831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 6213831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 6223831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mFlushingAudio = NONE; 6233831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mFlushingVideo = NONE; 624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6251aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (mResetInProgress) { 6263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("reset completed"); 6271aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 6281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mResetInProgress = false; 6291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber finishReset(); 6301aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } else if (mResetPostponed) { 6311aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber (new AMessage(kWhatReset, id()))->post(); 6321aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mResetPostponed = false; 63322fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber } else if (mAudioDecoder == NULL || mVideoDecoder == NULL) { 6341aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber postScanSources(); 6351aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 6361aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber} 6371aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 6381aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::finishReset() { 6391aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber CHECK(mAudioDecoder == NULL); 6401aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber CHECK(mVideoDecoder == NULL); 6411aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 6422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber ++mScanSourcesGeneration; 6432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mScanSourcesPending = false; 6442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 6451aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mRenderer.clear(); 6462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 6472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (mSource != NULL) { 6482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mSource->stop(); 6492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mSource.clear(); 6502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 6511aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 65243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber if (mDriver != NULL) { 65343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber sp<NuPlayerDriver> driver = mDriver.promote(); 65443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber if (driver != NULL) { 65543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber driver->notifyResetComplete(); 65643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 65743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 6581aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber} 6591aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 6601aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::postScanSources() { 6611aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (mScanSourcesPending) { 6621aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber return; 663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6641aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 6651aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber sp<AMessage> msg = new AMessage(kWhatScanSources, id()); 6661aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber msg->setInt32("generation", mScanSourcesGeneration); 6671aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber msg->post(); 6681aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 6691aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mScanSourcesPending = true; 670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6725bc087c573c70c84c6a39946457590b42d392a33Andreas Huberstatus_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { 673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (*decoder != NULL) { 674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6775bc087c573c70c84c6a39946457590b42d392a33Andreas Huber sp<MetaData> meta = mSource->getFormat(audio); 678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6795bc087c573c70c84c6a39946457590b42d392a33Andreas Huber if (meta == NULL) { 680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return -EWOULDBLOCK; 681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6833fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber if (!audio) { 6843fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber const char *mime; 6853fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 6863fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime); 6873fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } 6883fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = 690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify, 691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber id()); 692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6931173118eace0e9e347cb007f0da817cee87579edGlenn Kasten *decoder = audio ? new Decoder(notify) : 6941173118eace0e9e347cb007f0da817cee87579edGlenn Kasten new Decoder(notify, mNativeWindow); 695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber looper()->registerHandler(*decoder); 696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6975bc087c573c70c84c6a39946457590b42d392a33Andreas Huber (*decoder)->configure(meta); 698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 69943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber int64_t durationUs; 70043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) { 70143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber sp<NuPlayerDriver> driver = mDriver.promote(); 70243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber if (driver != NULL) { 70343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber driver->notifyDuration(durationUs); 70443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 70543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 70643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 710f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { 711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> reply; 712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findMessage("reply", &reply)); 713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 71453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber if ((audio && IsFlushingState(mFlushingAudio)) 71553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber || (!audio && IsFlushingState(mFlushingVideo))) { 716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->setInt32("err", INFO_DISCONTINUITY); 717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->post(); 718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ABuffer> accessUnit; 722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7233fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber bool dropAccessUnit; 7243fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber do { 7253fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber status_t err = mSource->dequeueAccessUnit(audio, &accessUnit); 7265bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 7273fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber if (err == -EWOULDBLOCK) { 7283fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber return err; 7293fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } else if (err != OK) { 7303fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber if (err == INFO_DISCONTINUITY) { 7313fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber int32_t type; 7323fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); 73353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber 7343fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber bool formatChange = 7356e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber (audio && 7366e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT)) 7376e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber || (!audio && 7386e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT)); 73953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber 7406e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; 7416e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber 742df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("%s discontinuity (formatChange=%d, time=%d)", 7436e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber audio ? "audio" : "video", formatChange, timeChange); 74432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 7453fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber if (audio) { 7463fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mSkipRenderingAudioUntilMediaTimeUs = -1; 7473fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } else { 7483fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber mSkipRenderingVideoUntilMediaTimeUs = -1; 7493fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } 75032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 7516e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if (timeChange) { 7526e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber sp<AMessage> extra; 7536e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if (accessUnit->meta()->findMessage("extra", &extra) 7546e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber && extra != NULL) { 7556e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber int64_t resumeAtMediaTimeUs; 7566e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if (extra->findInt64( 7576e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) { 758df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("suppressing rendering of %s until %lld us", 7596e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber audio ? "audio" : "video", resumeAtMediaTimeUs); 7606e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber 7616e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if (audio) { 7626e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber mSkipRenderingAudioUntilMediaTimeUs = 7636e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber resumeAtMediaTimeUs; 7646e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } else { 7656e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber mSkipRenderingVideoUntilMediaTimeUs = 7666e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber resumeAtMediaTimeUs; 7676e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } 7683fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } 76932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber } 77032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber } 7713fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 7726e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber mTimeDiscontinuityPending = 7736e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber mTimeDiscontinuityPending || timeChange; 7746e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber 7756e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if (formatChange || timeChange) { 7766e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber flushDecoder(audio, formatChange); 7776e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } else { 7786e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber // This stream is unaffected by the discontinuity 7796e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber 7806e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if (audio) { 7816e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber mFlushingAudio = FLUSHED; 7826e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } else { 7836e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber mFlushingVideo = FLUSHED; 7846e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } 7856e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber 7866e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber finishFlushIfPossible(); 7876e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber 7886e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber return -EWOULDBLOCK; 7896e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } 79032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber } 79132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 7923fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber reply->setInt32("err", err); 7933fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber reply->post(); 7943fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber return OK; 795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7973fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber if (!audio) { 7983fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber ++mNumFramesTotal; 7993fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } 8003fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 8013fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber dropAccessUnit = false; 8023fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber if (!audio 8033fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber && mVideoLateByUs > 100000ll 8043fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber && mVideoIsAVC 8053fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber && !IsAVCReferenceFrame(accessUnit)) { 8063fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber dropAccessUnit = true; 8073fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber ++mNumFramesDropped; 8083fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } 8093fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } while (dropAccessUnit); 810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 8113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video"); 812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0 814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mediaTimeUs; 815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); 8163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("feeding %s input buffer at media time %.2f secs", 817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber audio ? "audio" : "video", 818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mediaTimeUs / 1E6); 819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif 820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 8212d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber reply->setBuffer("buffer", accessUnit); 822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->post(); 823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return OK; 825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 827f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) { 8283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block // ALOGV("renderBuffer %s", audio ? "audio" : "video"); 829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> reply; 831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findMessage("reply", &reply)); 832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 83318ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) { 83418ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber // We're currently attempting to flush the decoder, in order 83518ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber // to complete this, the decoder wants all its buffers back, 83618ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber // so we don't want any output buffers it sent us (from before 83718ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber // we initiated the flush) to be stuck in the renderer's queue. 83818ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber 8393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("we're still flushing the %s decoder, sending its output buffer" 84018ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber " right back.", audio ? "audio" : "video"); 84118ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber 84218ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber reply->post(); 84318ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber return; 84418ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber } 84518ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber 8462d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber sp<ABuffer> buffer; 8472d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber CHECK(msg->findBuffer("buffer", &buffer)); 848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 84932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber int64_t &skipUntilMediaTimeUs = 85032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber audio 85132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber ? mSkipRenderingAudioUntilMediaTimeUs 85232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber : mSkipRenderingVideoUntilMediaTimeUs; 85332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 85432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber if (skipUntilMediaTimeUs >= 0) { 85532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber int64_t mediaTimeUs; 85632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs)); 85732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 85832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber if (mediaTimeUs < skipUntilMediaTimeUs) { 8593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("dropping %s buffer at time %lld as requested.", 86032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber audio ? "audio" : "video", 86132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber mediaTimeUs); 86232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 86332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber reply->post(); 86432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber return; 86532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber } 86632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 86732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber skipUntilMediaTimeUs = -1; 86832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber } 86932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mRenderer->queueBuffer(audio, buffer, reply); 871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 873f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::notifyListener(int msg, int ext1, int ext2) { 87443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber if (mDriver == NULL) { 875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 87843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber sp<NuPlayerDriver> driver = mDriver.promote(); 879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 88043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber if (driver == NULL) { 881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 884a4af2143ecbd630e946647c1b5f90fda8f61ebb3Andreas Huber driver->notifyListener(msg, ext1, ext2); 885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 8871aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid NuPlayer::flushDecoder(bool audio, bool needShutdown) { 8886e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) { 889df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("flushDecoder %s without decoder present", 8906e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber audio ? "audio" : "video"); 8916e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } 8926e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber 8931aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber // Make sure we don't continue to scan sources until we finish flushing. 8941aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber ++mScanSourcesGeneration; 89543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber mScanSourcesPending = false; 8961aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 8971aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber (audio ? mAudioDecoder : mVideoDecoder)->signalFlush(); 8981aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mRenderer->flush(audio); 8991aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 9001aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber FlushStatus newStatus = 9011aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER; 9021aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 9031aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (audio) { 9041aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber CHECK(mFlushingAudio == NONE 9051aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber || mFlushingAudio == AWAITING_DISCONTINUITY); 9061aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 9071aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mFlushingAudio = newStatus; 9081aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 9091aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (mFlushingVideo == NONE) { 9101aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mFlushingVideo = (mVideoDecoder != NULL) 9111aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber ? AWAITING_DISCONTINUITY 9121aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber : FLUSHED; 9131aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 9141aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } else { 9151aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber CHECK(mFlushingVideo == NONE 9161aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber || mFlushingVideo == AWAITING_DISCONTINUITY); 9171aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 9181aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mFlushingVideo = newStatus; 9191aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 9201aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber if (mFlushingAudio == NONE) { 9211aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber mFlushingAudio = (mAudioDecoder != NULL) 9221aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber ? AWAITING_DISCONTINUITY 9231aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber : FLUSHED; 9241aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 9251aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 9261aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber} 9271aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber 928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} // namespace android 929