GenericSource.cpp revision f8bd851cc652501239a8e3759b21890dfa2afdea
1afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber/* 2afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * Copyright (C) 2012 The Android Open Source Project 3afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * 4afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * you may not use this file except in compliance with the License. 6afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * You may obtain a copy of the License at 7afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * 8afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * 10afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * Unless required by applicable law or agreed to in writing, software 11afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * See the License for the specific language governing permissions and 14afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * limitations under the License. 15afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber */ 16afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 177e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang//#define LOG_NDEBUG 0 187e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang#define LOG_TAG "GenericSource" 197e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang 20afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include "GenericSource.h" 21afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 22afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include "AnotherPacketSource.h" 23afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 24a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang#include <media/IMediaHTTPService.h> 25afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 26afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/foundation/ADebug.h> 27afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/foundation/AMessage.h> 28afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/DataSource.h> 29afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/FileSource.h> 30afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/MediaBuffer.h> 31afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/MediaDefs.h> 32afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/MediaExtractor.h> 33afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/MediaSource.h> 34afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/MetaData.h> 3517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih#include <media/stagefright/Utils.h> 36802768790c131f8237364906fd13981a6bb91193Ronghua Wu#include "../../libstagefright/include/DRMExtractor.h" 37d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang#include "../../libstagefright/include/NuCachedSource2.h" 38cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar#include "../../libstagefright/include/WVMExtractor.h" 39360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih#include "../../libstagefright/include/HTTPBase.h" 40afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 41afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubernamespace android { 42afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 43efbb61950db36a5eb789be83f077246172507c67Chong Zhangstatic int64_t kLowWaterMarkUs = 2000000ll; // 2secs 44efbb61950db36a5eb789be83f077246172507c67Chong Zhangstatic int64_t kHighWaterMarkUs = 5000000ll; // 5secs 45efbb61950db36a5eb789be83f077246172507c67Chong Zhangstatic const ssize_t kLowWaterMarkBytes = 40000; 46efbb61950db36a5eb789be83f077246172507c67Chong Zhangstatic const ssize_t kHighWaterMarkBytes = 200000; 47efbb61950db36a5eb789be83f077246172507c67Chong Zhang 48afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas HuberNuPlayer::GenericSource::GenericSource( 49b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber const sp<AMessage> ¬ify, 50cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar bool uidValid, 51cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar uid_t uid) 52b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber : Source(notify), 535c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih mAudioTimeUs(0), 545c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih mAudioLastDequeueTimeUs(0), 555c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih mVideoTimeUs(0), 565c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih mVideoLastDequeueTimeUs(0), 573423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih mFetchSubtitleDataGeneration(0), 58e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar mFetchTimedTextDataGeneration(0), 59b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber mDurationUs(0ll), 60cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar mAudioIsVorbis(false), 613de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang mIsWidevine(false), 6242e8153cf7271b572e4a94ade332b68521977f36Chong Zhang mIsSecure(false), 63efbb61950db36a5eb789be83f077246172507c67Chong Zhang mIsStreaming(false), 64cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar mUIDValid(uidValid), 65d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang mUID(uid), 66a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang mFd(-1), 67802768790c131f8237364906fd13981a6bb91193Ronghua Wu mDrmManagerClient(NULL), 682a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang mBitrate(-1ll), 6984f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar mPollBufferingGeneration(0), 70efbb61950db36a5eb789be83f077246172507c67Chong Zhang mPendingReadBufferTypes(0), 71efbb61950db36a5eb789be83f077246172507c67Chong Zhang mBuffering(false), 72c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang mPrepareBuffering(false), 73c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang mPrevBufferPercentage(-1) { 74a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang resetDataSource(); 75afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber DataSource::RegisterDefaultSniffers(); 763de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang} 773de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang 78a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhangvoid NuPlayer::GenericSource::resetDataSource() { 79a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang mHTTPService.clear(); 80360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih mHttpSource.clear(); 81a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang mUri.clear(); 82a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang mUriHeaders.clear(); 83a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang if (mFd >= 0) { 84a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang close(mFd); 85a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang mFd = -1; 86a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang } 87a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang mOffset = 0; 88a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang mLength = 0; 89802768790c131f8237364906fd13981a6bb91193Ronghua Wu setDrmPlaybackStatusIfNeeded(Playback::STOP, 0); 90802768790c131f8237364906fd13981a6bb91193Ronghua Wu mDecryptHandle = NULL; 91802768790c131f8237364906fd13981a6bb91193Ronghua Wu mDrmManagerClient = NULL; 92802768790c131f8237364906fd13981a6bb91193Ronghua Wu mStarted = false; 932abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mStopRead = true; 94a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang} 95a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang 96a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhangstatus_t NuPlayer::GenericSource::setDataSource( 973de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang const sp<IMediaHTTPService> &httpService, 983de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang const char *url, 993de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang const KeyedVector<String8, String8> *headers) { 100a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang resetDataSource(); 101afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 102a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang mHTTPService = httpService; 103a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang mUri = url; 104afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 105a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang if (headers) { 106a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang mUriHeaders = *headers; 1073de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang } 108afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 109a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang // delay data source creation to prepareAsync() to avoid blocking 110a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang // the calling thread in setDataSource for any significant time. 111a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang return OK; 1123de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang} 113afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 114a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhangstatus_t NuPlayer::GenericSource::setDataSource( 1153de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang int fd, int64_t offset, int64_t length) { 116a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang resetDataSource(); 117a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang 118a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang mFd = dup(fd); 119a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang mOffset = offset; 120a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang mLength = length; 121afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 122a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang // delay data source creation to prepareAsync() to avoid blocking 123a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang // the calling thread in setDataSource for any significant time. 124a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang return OK; 125afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber} 126afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 12799f31604136d66ae10e20669fb6b5716f342bde0Chris Watkinsstatus_t NuPlayer::GenericSource::setDataSource(const sp<DataSource>& source) { 12899f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins resetDataSource(); 12999f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins mDataSource = source; 13099f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins return OK; 13199f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins} 13299f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins 133f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissensp<MetaData> NuPlayer::GenericSource::getFileFormatMeta() const { 134f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen return mFileMeta; 135f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen} 136f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen 137d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhangstatus_t NuPlayer::GenericSource::initFromDataSource() { 138cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar sp<MediaExtractor> extractor; 139fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang String8 mimeType; 140fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang float confidence; 141fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang sp<AMessage> dummy; 142fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang bool isWidevineStreaming = false; 143cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar 144d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang CHECK(mDataSource != NULL); 145d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang 146cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar if (mIsWidevine) { 147fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang isWidevineStreaming = SniffWVM( 148fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang mDataSource, &mimeType, &confidence, &dummy); 149fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang if (!isWidevineStreaming || 150fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang strcasecmp( 151cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) { 152cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar ALOGE("unsupported widevine mime: %s", mimeType.string()); 1533de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang return UNKNOWN_ERROR; 154cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar } 155fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang } else if (mIsStreaming) { 156c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang if (!mDataSource->sniff(&mimeType, &confidence, &dummy)) { 157c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang return UNKNOWN_ERROR; 158fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang } 159fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang isWidevineStreaming = !strcasecmp( 160c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM); 161fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang } 162cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar 163fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang if (isWidevineStreaming) { 164fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang // we don't want cached source for widevine streaming. 165fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang mCachedSource.clear(); 166fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang mDataSource = mHttpSource; 1672a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang mWVMExtractor = new WVMExtractor(mDataSource); 1682a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang mWVMExtractor->setAdaptiveStreamingMode(true); 169cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar if (mUIDValid) { 1702a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang mWVMExtractor->setUID(mUID); 171cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar } 1722a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang extractor = mWVMExtractor; 173cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar } else { 174d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang extractor = MediaExtractor::Create(mDataSource, 175c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang mimeType.isEmpty() ? NULL : mimeType.string()); 176cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar } 177afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1783de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang if (extractor == NULL) { 1793de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang return UNKNOWN_ERROR; 1803de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang } 181afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 182802768790c131f8237364906fd13981a6bb91193Ronghua Wu if (extractor->getDrmFlag()) { 183802768790c131f8237364906fd13981a6bb91193Ronghua Wu checkDrmStatus(mDataSource); 184802768790c131f8237364906fd13981a6bb91193Ronghua Wu } 185802768790c131f8237364906fd13981a6bb91193Ronghua Wu 186f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen mFileMeta = extractor->getMetaData(); 187f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen if (mFileMeta != NULL) { 188c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen int64_t duration; 189f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen if (mFileMeta->findInt64(kKeyDuration, &duration)) { 190c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen mDurationUs = duration; 191c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 19242e8153cf7271b572e4a94ade332b68521977f36Chong Zhang 19342e8153cf7271b572e4a94ade332b68521977f36Chong Zhang if (!mIsWidevine) { 19442e8153cf7271b572e4a94ade332b68521977f36Chong Zhang // Check mime to see if we actually have a widevine source. 19542e8153cf7271b572e4a94ade332b68521977f36Chong Zhang // If the data source is not URL-type (eg. file source), we 19642e8153cf7271b572e4a94ade332b68521977f36Chong Zhang // won't be able to tell until now. 19742e8153cf7271b572e4a94ade332b68521977f36Chong Zhang const char *fileMime; 19842e8153cf7271b572e4a94ade332b68521977f36Chong Zhang if (mFileMeta->findCString(kKeyMIMEType, &fileMime) 19942e8153cf7271b572e4a94ade332b68521977f36Chong Zhang && !strncasecmp(fileMime, "video/wvm", 9)) { 20042e8153cf7271b572e4a94ade332b68521977f36Chong Zhang mIsWidevine = true; 20142e8153cf7271b572e4a94ade332b68521977f36Chong Zhang } 20242e8153cf7271b572e4a94ade332b68521977f36Chong Zhang } 203c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen } 204c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen 2052a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang int32_t totalBitrate = 0; 2062a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang 207705d3290102875409e334e2a80e64221714aa37cMarco Nelissen size_t numtracks = extractor->countTracks(); 208705d3290102875409e334e2a80e64221714aa37cMarco Nelissen if (numtracks == 0) { 209705d3290102875409e334e2a80e64221714aa37cMarco Nelissen return UNKNOWN_ERROR; 210705d3290102875409e334e2a80e64221714aa37cMarco Nelissen } 211705d3290102875409e334e2a80e64221714aa37cMarco Nelissen 212705d3290102875409e334e2a80e64221714aa37cMarco Nelissen for (size_t i = 0; i < numtracks; ++i) { 213afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang sp<MediaSource> track = extractor->getTrack(i); 214afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang 215afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber sp<MetaData> meta = extractor->getTrackMetaData(i); 216afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 217afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber const char *mime; 218afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 219afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 220afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang // Do the string compare immediately with "mime", 221afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang // we can't assume "mime" would stay valid after another 222afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang // extractor operation, some extractors might modify meta 223afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang // during getTrack() and make it invalid. 224afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (!strncasecmp(mime, "audio/", 6)) { 225afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (mAudioTrack.mSource == NULL) { 226dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih mAudioTrack.mIndex = i; 227dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih mAudioTrack.mSource = track; 228af52c1a1ccab588ae4ed94521f202ed9474eccecRobert Shih mAudioTrack.mPackets = 229af52c1a1ccab588ae4ed94521f202ed9474eccecRobert Shih new AnotherPacketSource(mAudioTrack.mSource->getFormat()); 230afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 231afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) { 232afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber mAudioIsVorbis = true; 233afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } else { 234afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber mAudioIsVorbis = false; 235afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 236afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 237afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } else if (!strncasecmp(mime, "video/", 6)) { 238afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (mVideoTrack.mSource == NULL) { 239dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih mVideoTrack.mIndex = i; 240dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih mVideoTrack.mSource = track; 241af52c1a1ccab588ae4ed94521f202ed9474eccecRobert Shih mVideoTrack.mPackets = 242af52c1a1ccab588ae4ed94521f202ed9474eccecRobert Shih new AnotherPacketSource(mVideoTrack.mSource->getFormat()); 2437e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang 2447e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang // check if the source requires secure buffers 2457e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang int32_t secure; 246a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang if (meta->findInt32(kKeyRequiresSecureBuffers, &secure) 247a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang && secure) { 24842e8153cf7271b572e4a94ade332b68521977f36Chong Zhang mIsSecure = true; 2493de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang if (mUIDValid) { 2503de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang extractor->setUID(mUID); 2513de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang } 2527e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang } 253afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 254afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 255afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 256afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (track != NULL) { 257dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih mSources.push(track); 258afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber int64_t durationUs; 259afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (meta->findInt64(kKeyDuration, &durationUs)) { 260afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (durationUs > mDurationUs) { 261afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber mDurationUs = durationUs; 262afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 263afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 2642a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang 2652a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang int32_t bitrate; 2662a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) { 2672a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang totalBitrate += bitrate; 2682a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang } else { 2692a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang totalBitrate = -1; 2702a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang } 271afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 272afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 2733de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang 274fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar mBitrate = totalBitrate; 275fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar 276fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar return OK; 277fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar} 278fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar 279fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnarstatus_t NuPlayer::GenericSource::startSources() { 280efbb61950db36a5eb789be83f077246172507c67Chong Zhang // Start the selected A/V tracks now before we start buffering. 281efbb61950db36a5eb789be83f077246172507c67Chong Zhang // Widevine sources might re-initialize crypto when starting, if we delay 282efbb61950db36a5eb789be83f077246172507c67Chong Zhang // this to start(), all data buffered during prepare would be wasted. 283efbb61950db36a5eb789be83f077246172507c67Chong Zhang // (We don't actually start reading until start().) 284efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (mAudioTrack.mSource != NULL && mAudioTrack.mSource->start() != OK) { 285efbb61950db36a5eb789be83f077246172507c67Chong Zhang ALOGE("failed to start audio track!"); 286efbb61950db36a5eb789be83f077246172507c67Chong Zhang return UNKNOWN_ERROR; 287efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 288efbb61950db36a5eb789be83f077246172507c67Chong Zhang 289efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (mVideoTrack.mSource != NULL && mVideoTrack.mSource->start() != OK) { 290efbb61950db36a5eb789be83f077246172507c67Chong Zhang ALOGE("failed to start video track!"); 291efbb61950db36a5eb789be83f077246172507c67Chong Zhang return UNKNOWN_ERROR; 292efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 293efbb61950db36a5eb789be83f077246172507c67Chong Zhang 2943de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang return OK; 295afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber} 296afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 297802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::checkDrmStatus(const sp<DataSource>& dataSource) { 298802768790c131f8237364906fd13981a6bb91193Ronghua Wu dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient); 299802768790c131f8237364906fd13981a6bb91193Ronghua Wu if (mDecryptHandle != NULL) { 300802768790c131f8237364906fd13981a6bb91193Ronghua Wu CHECK(mDrmManagerClient); 301802768790c131f8237364906fd13981a6bb91193Ronghua Wu if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) { 302802768790c131f8237364906fd13981a6bb91193Ronghua Wu sp<AMessage> msg = dupNotify(); 303802768790c131f8237364906fd13981a6bb91193Ronghua Wu msg->setInt32("what", kWhatDrmNoLicense); 304802768790c131f8237364906fd13981a6bb91193Ronghua Wu msg->post(); 305802768790c131f8237364906fd13981a6bb91193Ronghua Wu } 306802768790c131f8237364906fd13981a6bb91193Ronghua Wu } 307802768790c131f8237364906fd13981a6bb91193Ronghua Wu} 308802768790c131f8237364906fd13981a6bb91193Ronghua Wu 309802768790c131f8237364906fd13981a6bb91193Ronghua Wuint64_t NuPlayer::GenericSource::getLastReadPosition() { 310802768790c131f8237364906fd13981a6bb91193Ronghua Wu if (mAudioTrack.mSource != NULL) { 311802768790c131f8237364906fd13981a6bb91193Ronghua Wu return mAudioTimeUs; 312802768790c131f8237364906fd13981a6bb91193Ronghua Wu } else if (mVideoTrack.mSource != NULL) { 313802768790c131f8237364906fd13981a6bb91193Ronghua Wu return mVideoTimeUs; 314802768790c131f8237364906fd13981a6bb91193Ronghua Wu } else { 315802768790c131f8237364906fd13981a6bb91193Ronghua Wu return 0; 316802768790c131f8237364906fd13981a6bb91193Ronghua Wu } 317802768790c131f8237364906fd13981a6bb91193Ronghua Wu} 318802768790c131f8237364906fd13981a6bb91193Ronghua Wu 319a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhangstatus_t NuPlayer::GenericSource::setBuffers( 320a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang bool audio, Vector<MediaBuffer *> &buffers) { 32142e8153cf7271b572e4a94ade332b68521977f36Chong Zhang if (mIsSecure && !audio) { 322cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar return mVideoTrack.mSource->setBuffers(buffers); 323cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar } 324cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar return INVALID_OPERATION; 325cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar} 326cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar 327afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas HuberNuPlayer::GenericSource::~GenericSource() { 3281228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang if (mLooper != NULL) { 3291228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang mLooper->unregisterHandler(id()); 3301228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang mLooper->stop(); 3311228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang } 332a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang resetDataSource(); 333afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber} 334afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 3359575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::GenericSource::prepareAsync() { 3361228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang if (mLooper == NULL) { 3371228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang mLooper = new ALooper; 3381228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang mLooper->setName("generic"); 3391228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang mLooper->start(); 3401228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang 3411228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang mLooper->registerHandler(this); 3421228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang } 3431228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang 3441d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatPrepareAsync, this); 3451228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang msg->post(); 3461228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang} 3471228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang 3481228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhangvoid NuPlayer::GenericSource::onPrepareAsync() { 349a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang // delayed data source creation 350d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang if (mDataSource == NULL) { 35142e8153cf7271b572e4a94ade332b68521977f36Chong Zhang // set to false first, if the extractor 35242e8153cf7271b572e4a94ade332b68521977f36Chong Zhang // comes back as secure, set it to true then. 35342e8153cf7271b572e4a94ade332b68521977f36Chong Zhang mIsSecure = false; 35442e8153cf7271b572e4a94ade332b68521977f36Chong Zhang 355d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang if (!mUri.empty()) { 356360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih const char* uri = mUri.c_str(); 357c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang String8 contentType; 358360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih mIsWidevine = !strncasecmp(uri, "widevine://", 11); 359360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih 360360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih if (!strncasecmp("http://", uri, 7) 361360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih || !strncasecmp("https://", uri, 8) 362360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih || mIsWidevine) { 363360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih mHttpSource = DataSource::CreateMediaHTTP(mHTTPService); 364360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih if (mHttpSource == NULL) { 365360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih ALOGE("Failed to create http source!"); 366360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih notifyPreparedAndCleanup(UNKNOWN_ERROR); 367360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih return; 368360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih } 369360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih } 370d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang 371d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang mDataSource = DataSource::CreateFromURI( 372c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang mHTTPService, uri, &mUriHeaders, &contentType, 373360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih static_cast<HTTPBase *>(mHttpSource.get())); 374d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang } else { 375d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang mIsWidevine = false; 376d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang 377d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang mDataSource = new FileSource(mFd, mOffset, mLength); 378a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang mFd = -1; 379d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang } 380a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang 381d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang if (mDataSource == NULL) { 382d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang ALOGE("Failed to create data source!"); 383d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang notifyPreparedAndCleanup(UNKNOWN_ERROR); 384d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang return; 385d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang } 38699f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins } 387a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang 38899f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins if (mDataSource->flags() & DataSource::kIsCachingDataSource) { 38999f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get()); 390a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang } 391a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang 39299f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins // For widevine or other cached streaming cases, we need to wait for 39399f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins // enough buffering before reporting prepared. 39499f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins // Note that even when URL doesn't start with widevine://, mIsWidevine 39599f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins // could still be set to true later, if the streaming or file source 39699f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins // is sniffed to be widevine. We don't want to buffer for file source 39799f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins // in that case, so must check the flag now. 39899f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins mIsStreaming = (mIsWidevine || mCachedSource != NULL); 39999f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins 400c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang // init extractor from data source 401c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang status_t err = initFromDataSource(); 402a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang 403a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang if (err != OK) { 404a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang ALOGE("Failed to init from data source!"); 405d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang notifyPreparedAndCleanup(err); 406a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang return; 407a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang } 408a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang 4099575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber if (mVideoTrack.mSource != NULL) { 41017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih sp<MetaData> meta = doGetFormatMeta(false /* audio */); 41117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih sp<AMessage> msg = new AMessage; 41217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih err = convertMetaDataToMessage(meta, &msg); 41317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih if(err != OK) { 41417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih notifyPreparedAndCleanup(err); 41517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih return; 41617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih } 41717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih notifyVideoSizeChanged(msg); 4189575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber } 4199575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber 4209575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber notifyFlagsChanged( 42142e8153cf7271b572e4a94ade332b68521977f36Chong Zhang (mIsSecure ? FLAG_SECURE : 0) 4221713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang | (mDecryptHandle != NULL ? FLAG_PROTECTED : 0) 423cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar | FLAG_CAN_PAUSE 4249575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber | FLAG_CAN_SEEK_BACKWARD 4259575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber | FLAG_CAN_SEEK_FORWARD 4269575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber | FLAG_CAN_SEEK); 4279575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber 428fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar if (mIsSecure) { 429fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar // secure decoders must be instantiated before starting widevine source 430fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar sp<AMessage> reply = new AMessage(kWhatSecureDecodersInstantiated, this); 431fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar notifyInstantiateSecureDecoders(reply); 432fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar } else { 433fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar finishPrepareAsync(); 434fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar } 435fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar} 436fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar 437fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnarvoid NuPlayer::GenericSource::onSecureDecodersInstantiated(status_t err) { 438fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar if (err != OK) { 439fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar ALOGE("Failed to instantiate secure decoders!"); 440fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar notifyPreparedAndCleanup(err); 441fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar return; 442fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar } 443fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar finishPrepareAsync(); 444fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar} 445fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar 446fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnarvoid NuPlayer::GenericSource::finishPrepareAsync() { 447fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar status_t err = startSources(); 448fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar if (err != OK) { 449fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar ALOGE("Failed to init start data source!"); 450fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar notifyPreparedAndCleanup(err); 451fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar return; 452fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar } 453fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar 454efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (mIsStreaming) { 455efbb61950db36a5eb789be83f077246172507c67Chong Zhang mPrepareBuffering = true; 456efbb61950db36a5eb789be83f077246172507c67Chong Zhang 457efbb61950db36a5eb789be83f077246172507c67Chong Zhang ensureCacheIsFetching(); 458efbb61950db36a5eb789be83f077246172507c67Chong Zhang restartPollBuffering(); 459efbb61950db36a5eb789be83f077246172507c67Chong Zhang } else { 460efbb61950db36a5eb789be83f077246172507c67Chong Zhang notifyPrepared(); 461efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 4629575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber} 4639575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber 464d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhangvoid NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) { 465d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang if (err != OK) { 466d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang mDataSource.clear(); 467d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang mCachedSource.clear(); 468360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih mHttpSource.clear(); 469fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar mBitrate = -1; 4702a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang 4712a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang cancelPollBuffering(); 472d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang } 473d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang notifyPrepared(err); 474d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang} 475d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang 476afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubervoid NuPlayer::GenericSource::start() { 477afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber ALOGI("start"); 478afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 4792abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mStopRead = false; 480afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (mAudioTrack.mSource != NULL) { 48117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih postReadBuffer(MEDIA_TRACK_TYPE_AUDIO); 482afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 483afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 484afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (mVideoTrack.mSource != NULL) { 48517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih postReadBuffer(MEDIA_TRACK_TYPE_VIDEO); 486afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 487802768790c131f8237364906fd13981a6bb91193Ronghua Wu 488802768790c131f8237364906fd13981a6bb91193Ronghua Wu setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000); 489802768790c131f8237364906fd13981a6bb91193Ronghua Wu mStarted = true; 490efbb61950db36a5eb789be83f077246172507c67Chong Zhang 4911d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatStart, this))->post(); 492802768790c131f8237364906fd13981a6bb91193Ronghua Wu} 493802768790c131f8237364906fd13981a6bb91193Ronghua Wu 494802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::stop() { 495802768790c131f8237364906fd13981a6bb91193Ronghua Wu // nothing to do, just account for DRM playback status 496802768790c131f8237364906fd13981a6bb91193Ronghua Wu setDrmPlaybackStatusIfNeeded(Playback::STOP, 0); 497802768790c131f8237364906fd13981a6bb91193Ronghua Wu mStarted = false; 49842e8153cf7271b572e4a94ade332b68521977f36Chong Zhang if (mIsWidevine || mIsSecure) { 49942e8153cf7271b572e4a94ade332b68521977f36Chong Zhang // For widevine or secure sources we need to prevent any further reads. 5001d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStopWidevine, this); 5012abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung sp<AMessage> response; 5022abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung (void) msg->postAndAwaitResponse(&response); 5032abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung } 504802768790c131f8237364906fd13981a6bb91193Ronghua Wu} 505802768790c131f8237364906fd13981a6bb91193Ronghua Wu 506802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::pause() { 507802768790c131f8237364906fd13981a6bb91193Ronghua Wu // nothing to do, just account for DRM playback status 508802768790c131f8237364906fd13981a6bb91193Ronghua Wu setDrmPlaybackStatusIfNeeded(Playback::PAUSE, 0); 509802768790c131f8237364906fd13981a6bb91193Ronghua Wu mStarted = false; 510802768790c131f8237364906fd13981a6bb91193Ronghua Wu} 511802768790c131f8237364906fd13981a6bb91193Ronghua Wu 512802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::resume() { 513802768790c131f8237364906fd13981a6bb91193Ronghua Wu // nothing to do, just account for DRM playback status 514802768790c131f8237364906fd13981a6bb91193Ronghua Wu setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000); 515802768790c131f8237364906fd13981a6bb91193Ronghua Wu mStarted = true; 516efbb61950db36a5eb789be83f077246172507c67Chong Zhang 5171d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatResume, this))->post(); 518802768790c131f8237364906fd13981a6bb91193Ronghua Wu} 519802768790c131f8237364906fd13981a6bb91193Ronghua Wu 52048296b792a8d68358de74141fa80bd5bd84d0307Chong Zhangvoid NuPlayer::GenericSource::disconnect() { 52148296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang if (mDataSource != NULL) { 52248296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang // disconnect data source 52348296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang if (mDataSource->flags() & DataSource::kIsCachingDataSource) { 52448296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang static_cast<NuCachedSource2 *>(mDataSource.get())->disconnect(); 52548296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang } 526360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih } else if (mHttpSource != NULL) { 527360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih static_cast<HTTPBase *>(mHttpSource.get())->disconnect(); 52848296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang } 52948296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang} 53048296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang 531802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::setDrmPlaybackStatusIfNeeded(int playbackStatus, int64_t position) { 532802768790c131f8237364906fd13981a6bb91193Ronghua Wu if (mDecryptHandle != NULL) { 533802768790c131f8237364906fd13981a6bb91193Ronghua Wu mDrmManagerClient->setPlaybackStatus(mDecryptHandle, playbackStatus, position); 534802768790c131f8237364906fd13981a6bb91193Ronghua Wu } 53517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih mSubtitleTrack.mPackets = new AnotherPacketSource(NULL); 53617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih mTimedTextTrack.mPackets = new AnotherPacketSource(NULL); 537afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber} 538afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 539afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::feedMoreTSData() { 540afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber return OK; 541afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber} 542afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 5432a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhangvoid NuPlayer::GenericSource::schedulePollBuffering() { 5441d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatPollBuffering, this); 5452a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang msg->setInt32("generation", mPollBufferingGeneration); 5462a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang msg->post(1000000ll); 5472a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang} 5482a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang 5492a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhangvoid NuPlayer::GenericSource::cancelPollBuffering() { 550efbb61950db36a5eb789be83f077246172507c67Chong Zhang mBuffering = false; 5512a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang ++mPollBufferingGeneration; 552c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang mPrevBufferPercentage = -1; 5532a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang} 5542a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang 555efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::GenericSource::restartPollBuffering() { 556efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (mIsStreaming) { 557efbb61950db36a5eb789be83f077246172507c67Chong Zhang cancelPollBuffering(); 558efbb61950db36a5eb789be83f077246172507c67Chong Zhang onPollBuffering(); 559efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 560efbb61950db36a5eb789be83f077246172507c67Chong Zhang} 561efbb61950db36a5eb789be83f077246172507c67Chong Zhang 562c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhangvoid NuPlayer::GenericSource::notifyBufferingUpdate(int32_t percentage) { 563c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang // Buffering percent could go backward as it's estimated from remaining 564c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang // data and last access time. This could cause the buffering position 565c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang // drawn on media control to jitter slightly. Remember previously reported 566c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang // percentage and don't allow it to go backward. 567c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang if (percentage < mPrevBufferPercentage) { 568c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang percentage = mPrevBufferPercentage; 569c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang } else if (percentage > 100) { 570c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang percentage = 100; 571c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang } 572c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang 573c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang mPrevBufferPercentage = percentage; 574c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang 575efbb61950db36a5eb789be83f077246172507c67Chong Zhang ALOGV("notifyBufferingUpdate: buffering %d%%", percentage); 576efbb61950db36a5eb789be83f077246172507c67Chong Zhang 5772a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang sp<AMessage> msg = dupNotify(); 5782a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang msg->setInt32("what", kWhatBufferingUpdate); 5792a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang msg->setInt32("percentage", percentage); 5802a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang msg->post(); 5812a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang} 5822a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang 583efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::GenericSource::startBufferingIfNecessary() { 584efbb61950db36a5eb789be83f077246172507c67Chong Zhang ALOGV("startBufferingIfNecessary: mPrepareBuffering=%d, mBuffering=%d", 585efbb61950db36a5eb789be83f077246172507c67Chong Zhang mPrepareBuffering, mBuffering); 586efbb61950db36a5eb789be83f077246172507c67Chong Zhang 587efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (mPrepareBuffering) { 588efbb61950db36a5eb789be83f077246172507c67Chong Zhang return; 589efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 590efbb61950db36a5eb789be83f077246172507c67Chong Zhang 591efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (!mBuffering) { 592efbb61950db36a5eb789be83f077246172507c67Chong Zhang mBuffering = true; 593efbb61950db36a5eb789be83f077246172507c67Chong Zhang 594efbb61950db36a5eb789be83f077246172507c67Chong Zhang ensureCacheIsFetching(); 595efbb61950db36a5eb789be83f077246172507c67Chong Zhang sendCacheStats(); 596efbb61950db36a5eb789be83f077246172507c67Chong Zhang 597efbb61950db36a5eb789be83f077246172507c67Chong Zhang sp<AMessage> notify = dupNotify(); 598efbb61950db36a5eb789be83f077246172507c67Chong Zhang notify->setInt32("what", kWhatPauseOnBufferingStart); 599efbb61950db36a5eb789be83f077246172507c67Chong Zhang notify->post(); 600efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 601efbb61950db36a5eb789be83f077246172507c67Chong Zhang} 602efbb61950db36a5eb789be83f077246172507c67Chong Zhang 603efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::GenericSource::stopBufferingIfNecessary() { 604efbb61950db36a5eb789be83f077246172507c67Chong Zhang ALOGV("stopBufferingIfNecessary: mPrepareBuffering=%d, mBuffering=%d", 605efbb61950db36a5eb789be83f077246172507c67Chong Zhang mPrepareBuffering, mBuffering); 606efbb61950db36a5eb789be83f077246172507c67Chong Zhang 607efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (mPrepareBuffering) { 608efbb61950db36a5eb789be83f077246172507c67Chong Zhang mPrepareBuffering = false; 609efbb61950db36a5eb789be83f077246172507c67Chong Zhang notifyPrepared(); 610efbb61950db36a5eb789be83f077246172507c67Chong Zhang return; 611efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 612efbb61950db36a5eb789be83f077246172507c67Chong Zhang 613efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (mBuffering) { 614efbb61950db36a5eb789be83f077246172507c67Chong Zhang mBuffering = false; 615efbb61950db36a5eb789be83f077246172507c67Chong Zhang 616efbb61950db36a5eb789be83f077246172507c67Chong Zhang sendCacheStats(); 617efbb61950db36a5eb789be83f077246172507c67Chong Zhang 618efbb61950db36a5eb789be83f077246172507c67Chong Zhang sp<AMessage> notify = dupNotify(); 619efbb61950db36a5eb789be83f077246172507c67Chong Zhang notify->setInt32("what", kWhatResumeOnBufferingEnd); 620efbb61950db36a5eb789be83f077246172507c67Chong Zhang notify->post(); 621efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 622efbb61950db36a5eb789be83f077246172507c67Chong Zhang} 623efbb61950db36a5eb789be83f077246172507c67Chong Zhang 624efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::GenericSource::sendCacheStats() { 625efbb61950db36a5eb789be83f077246172507c67Chong Zhang int32_t kbps = 0; 626efbb61950db36a5eb789be83f077246172507c67Chong Zhang status_t err = UNKNOWN_ERROR; 627efbb61950db36a5eb789be83f077246172507c67Chong Zhang 628fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang if (mWVMExtractor != NULL) { 629efbb61950db36a5eb789be83f077246172507c67Chong Zhang err = mWVMExtractor->getEstimatedBandwidthKbps(&kbps); 630fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang } else if (mCachedSource != NULL) { 631fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang err = mCachedSource->getEstimatedBandwidthKbps(&kbps); 632efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 633efbb61950db36a5eb789be83f077246172507c67Chong Zhang 634efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (err == OK) { 635efbb61950db36a5eb789be83f077246172507c67Chong Zhang sp<AMessage> notify = dupNotify(); 636efbb61950db36a5eb789be83f077246172507c67Chong Zhang notify->setInt32("what", kWhatCacheStats); 637efbb61950db36a5eb789be83f077246172507c67Chong Zhang notify->setInt32("bandwidth", kbps); 638efbb61950db36a5eb789be83f077246172507c67Chong Zhang notify->post(); 639efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 640efbb61950db36a5eb789be83f077246172507c67Chong Zhang} 641efbb61950db36a5eb789be83f077246172507c67Chong Zhang 642efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::GenericSource::ensureCacheIsFetching() { 643efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (mCachedSource != NULL) { 644efbb61950db36a5eb789be83f077246172507c67Chong Zhang mCachedSource->resumeFetchingIfNecessary(); 645efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 646efbb61950db36a5eb789be83f077246172507c67Chong Zhang} 647efbb61950db36a5eb789be83f077246172507c67Chong Zhang 6482a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhangvoid NuPlayer::GenericSource::onPollBuffering() { 6492a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang status_t finalStatus = UNKNOWN_ERROR; 650efbb61950db36a5eb789be83f077246172507c67Chong Zhang int64_t cachedDurationUs = -1ll; 651efbb61950db36a5eb789be83f077246172507c67Chong Zhang ssize_t cachedDataRemaining = -1; 6522a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang 653fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang ALOGW_IF(mWVMExtractor != NULL && mCachedSource != NULL, 654fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang "WVMExtractor and NuCachedSource both present"); 655fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang 656fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang if (mWVMExtractor != NULL) { 657fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang cachedDurationUs = 658fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang mWVMExtractor->getCachedDurationUs(&finalStatus); 659fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang } else if (mCachedSource != NULL) { 660efbb61950db36a5eb789be83f077246172507c67Chong Zhang cachedDataRemaining = 6612a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang mCachedSource->approxDataRemaining(&finalStatus); 6622a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang 6632a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang if (finalStatus == OK) { 6642a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang off64_t size; 6652a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang int64_t bitrate = 0ll; 6662a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang if (mDurationUs > 0 && mCachedSource->getSize(&size) == OK) { 6672a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang bitrate = size * 8000000ll / mDurationUs; 6682a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang } else if (mBitrate > 0) { 6692a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang bitrate = mBitrate; 6702a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang } 6712a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang if (bitrate > 0) { 6722a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang cachedDurationUs = cachedDataRemaining * 8000000ll / bitrate; 6732a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang } 6742a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang } 6752a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang } 6762a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang 677efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (finalStatus != OK) { 678efbb61950db36a5eb789be83f077246172507c67Chong Zhang ALOGV("onPollBuffering: EOS (finalStatus = %d)", finalStatus); 679efbb61950db36a5eb789be83f077246172507c67Chong Zhang 680efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (finalStatus == ERROR_END_OF_STREAM) { 681efbb61950db36a5eb789be83f077246172507c67Chong Zhang notifyBufferingUpdate(100); 682efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 683efbb61950db36a5eb789be83f077246172507c67Chong Zhang 684efbb61950db36a5eb789be83f077246172507c67Chong Zhang stopBufferingIfNecessary(); 6852a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang return; 686efbb61950db36a5eb789be83f077246172507c67Chong Zhang } else if (cachedDurationUs >= 0ll) { 687efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (mDurationUs > 0ll) { 688efbb61950db36a5eb789be83f077246172507c67Chong Zhang int64_t cachedPosUs = getLastReadPosition() + cachedDurationUs; 689efbb61950db36a5eb789be83f077246172507c67Chong Zhang int percentage = 100.0 * cachedPosUs / mDurationUs; 690efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (percentage > 100) { 691efbb61950db36a5eb789be83f077246172507c67Chong Zhang percentage = 100; 692efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 693efbb61950db36a5eb789be83f077246172507c67Chong Zhang 694efbb61950db36a5eb789be83f077246172507c67Chong Zhang notifyBufferingUpdate(percentage); 6952a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang } 6962a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang 697efbb61950db36a5eb789be83f077246172507c67Chong Zhang ALOGV("onPollBuffering: cachedDurationUs %.1f sec", 698efbb61950db36a5eb789be83f077246172507c67Chong Zhang cachedDurationUs / 1000000.0f); 699efbb61950db36a5eb789be83f077246172507c67Chong Zhang 700efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (cachedDurationUs < kLowWaterMarkUs) { 701efbb61950db36a5eb789be83f077246172507c67Chong Zhang startBufferingIfNecessary(); 702efbb61950db36a5eb789be83f077246172507c67Chong Zhang } else if (cachedDurationUs > kHighWaterMarkUs) { 703efbb61950db36a5eb789be83f077246172507c67Chong Zhang stopBufferingIfNecessary(); 704efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 705efbb61950db36a5eb789be83f077246172507c67Chong Zhang } else if (cachedDataRemaining >= 0) { 7066d339f1f764bbd32e3381dae7bfa7c6c575bb493Lajos Molnar ALOGV("onPollBuffering: cachedDataRemaining %zd bytes", 707efbb61950db36a5eb789be83f077246172507c67Chong Zhang cachedDataRemaining); 708efbb61950db36a5eb789be83f077246172507c67Chong Zhang 709efbb61950db36a5eb789be83f077246172507c67Chong Zhang if (cachedDataRemaining < kLowWaterMarkBytes) { 710efbb61950db36a5eb789be83f077246172507c67Chong Zhang startBufferingIfNecessary(); 711efbb61950db36a5eb789be83f077246172507c67Chong Zhang } else if (cachedDataRemaining > kHighWaterMarkBytes) { 712efbb61950db36a5eb789be83f077246172507c67Chong Zhang stopBufferingIfNecessary(); 713efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 7142a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang } 7152a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang 7162a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang schedulePollBuffering(); 7172a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang} 7182a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang 7193423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shihvoid NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) { 7203423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih switch (msg->what()) { 7211228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang case kWhatPrepareAsync: 7221228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang { 7231228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang onPrepareAsync(); 7241228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang break; 7251228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang } 7263423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih case kWhatFetchSubtitleData: 7273423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih { 728e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar fetchTextData(kWhatSendSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE, 729e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg); 730e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar break; 731e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 7323423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 733e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar case kWhatFetchTimedTextData: 734e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar { 735e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar fetchTextData(kWhatSendTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT, 736e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg); 7373423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih break; 7383423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 7393423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 7403423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih case kWhatSendSubtitleData: 7413423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih { 742e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar sendTextData(kWhatSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE, 743e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg); 744e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar break; 745e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 7463423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 747e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar case kWhatSendTimedTextData: 748e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar { 749e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar sendTextData(kWhatTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT, 750e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg); 7513423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih break; 7523423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 7533423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 7543423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih case kWhatChangeAVSource: 7553423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih { 7563423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih int32_t trackIndex; 7573423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih CHECK(msg->findInt32("trackIndex", &trackIndex)); 7583423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih const sp<MediaSource> source = mSources.itemAt(trackIndex); 7593423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 7603423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih Track* track; 7613423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih const char *mime; 7623423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih media_track_type trackType, counterpartType; 7633423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih sp<MetaData> meta = source->getFormat(); 7643423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih meta->findCString(kKeyMIMEType, &mime); 7653423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih if (!strncasecmp(mime, "audio/", 6)) { 7663423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih track = &mAudioTrack; 7673423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih trackType = MEDIA_TRACK_TYPE_AUDIO; 7683423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih counterpartType = MEDIA_TRACK_TYPE_VIDEO;; 7693423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } else { 7703423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih CHECK(!strncasecmp(mime, "video/", 6)); 7713423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih track = &mVideoTrack; 7723423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih trackType = MEDIA_TRACK_TYPE_VIDEO; 7733423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih counterpartType = MEDIA_TRACK_TYPE_AUDIO;; 7743423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 7753423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 7763423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 7773423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih if (track->mSource != NULL) { 7783423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih track->mSource->stop(); 7793423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 7803423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih track->mSource = source; 7813423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih track->mSource->start(); 7823423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih track->mIndex = trackIndex; 7833423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 7843423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih int64_t timeUs, actualTimeUs; 7853423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih const bool formatChange = true; 7865c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih if (trackType == MEDIA_TRACK_TYPE_AUDIO) { 7875c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih timeUs = mAudioLastDequeueTimeUs; 7885c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih } else { 7895c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih timeUs = mVideoLastDequeueTimeUs; 7905c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih } 7913423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih readBuffer(trackType, timeUs, &actualTimeUs, formatChange); 7923423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih readBuffer(counterpartType, -1, NULL, formatChange); 7936d339f1f764bbd32e3381dae7bfa7c6c575bb493Lajos Molnar ALOGV("timeUs %lld actualTimeUs %lld", (long long)timeUs, (long long)actualTimeUs); 7943423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 7953423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih break; 7963423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 797efbb61950db36a5eb789be83f077246172507c67Chong Zhang 798efbb61950db36a5eb789be83f077246172507c67Chong Zhang case kWhatStart: 799efbb61950db36a5eb789be83f077246172507c67Chong Zhang case kWhatResume: 800efbb61950db36a5eb789be83f077246172507c67Chong Zhang { 801efbb61950db36a5eb789be83f077246172507c67Chong Zhang restartPollBuffering(); 802efbb61950db36a5eb789be83f077246172507c67Chong Zhang break; 803efbb61950db36a5eb789be83f077246172507c67Chong Zhang } 804efbb61950db36a5eb789be83f077246172507c67Chong Zhang 8052a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang case kWhatPollBuffering: 8062a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang { 8072a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang int32_t generation; 8082a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang CHECK(msg->findInt32("generation", &generation)); 8092a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang if (generation == mPollBufferingGeneration) { 8102a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang onPollBuffering(); 8112a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang } 8122a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang break; 8132a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang } 81417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 81517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih case kWhatGetFormat: 81617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih { 81717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih onGetFormatMeta(msg); 81817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih break; 81917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih } 82017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 82117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih case kWhatGetSelectedTrack: 82217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih { 82317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih onGetSelectedTrack(msg); 82417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih break; 82517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih } 82617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 82717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih case kWhatSelectTrack: 82817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih { 82917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih onSelectTrack(msg); 83017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih break; 83117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih } 83217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 83317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih case kWhatSeek: 83417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih { 83517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih onSeek(msg); 83617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih break; 83717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih } 83817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 83917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih case kWhatReadBuffer: 84017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih { 84117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih onReadBuffer(msg); 84217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih break; 84317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih } 84417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 845fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar case kWhatSecureDecodersInstantiated: 846fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar { 847fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar int32_t err; 848fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar CHECK(msg->findInt32("err", &err)); 849fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar onSecureDecodersInstantiated(err); 850fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar break; 851fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar } 852fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar 8532abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung case kWhatStopWidevine: 8542abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung { 8552abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung // mStopRead is only used for Widevine to prevent the video source 8562abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung // from being read while the associated video decoder is shutting down. 8572abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mStopRead = true; 8582abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung if (mVideoTrack.mSource != NULL) { 8592abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mVideoTrack.mPackets->clear(); 8602abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung } 8612abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung sp<AMessage> response = new AMessage; 8623f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 8632abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung CHECK(msg->senderAwaitsResponse(&replyID)); 8642abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung response->postReply(replyID); 8652abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung break; 8662abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung } 8673423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih default: 8683423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih Source::onMessageReceived(msg); 8693423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih break; 8703423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 8713423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih} 8723423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 873e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnarvoid NuPlayer::GenericSource::fetchTextData( 874e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar uint32_t sendWhat, 875e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar media_track_type type, 876e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar int32_t curGen, 877e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar sp<AnotherPacketSource> packets, 878e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar sp<AMessage> msg) { 879e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar int32_t msgGeneration; 880e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar CHECK(msg->findInt32("generation", &msgGeneration)); 881e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (msgGeneration != curGen) { 882e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar // stale 883e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar return; 884e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 885e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 886e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar int32_t avail; 887e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (packets->hasBufferAvailable(&avail)) { 888e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar return; 889e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 890e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 891e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar int64_t timeUs; 892e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar CHECK(msg->findInt64("timeUs", &timeUs)); 893e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 894e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar int64_t subTimeUs; 895e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar readBuffer(type, timeUs, &subTimeUs); 896e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 897e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar int64_t delayUs = subTimeUs - timeUs; 898e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (msg->what() == kWhatFetchSubtitleData) { 899e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar const int64_t oneSecUs = 1000000ll; 900e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar delayUs -= oneSecUs; 901e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 9021d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg2 = new AMessage(sendWhat, this); 903e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar msg2->setInt32("generation", msgGeneration); 904e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar msg2->post(delayUs < 0 ? 0 : delayUs); 905e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar} 906e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 907e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnarvoid NuPlayer::GenericSource::sendTextData( 908e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar uint32_t what, 909e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar media_track_type type, 910e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar int32_t curGen, 911e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar sp<AnotherPacketSource> packets, 912e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar sp<AMessage> msg) { 913e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar int32_t msgGeneration; 914e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar CHECK(msg->findInt32("generation", &msgGeneration)); 915e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (msgGeneration != curGen) { 916e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar // stale 917e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar return; 918e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 919e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 920e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar int64_t subTimeUs; 921e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (packets->nextBufferTime(&subTimeUs) != OK) { 922e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar return; 923e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 924e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 925e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar int64_t nextSubTimeUs; 926e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar readBuffer(type, -1, &nextSubTimeUs); 927e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 928e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar sp<ABuffer> buffer; 929e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar status_t dequeueStatus = packets->dequeueAccessUnit(&buffer); 930e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (dequeueStatus == OK) { 931e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar sp<AMessage> notify = dupNotify(); 932e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar notify->setInt32("what", what); 933e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar notify->setBuffer("buffer", buffer); 934e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar notify->post(); 935e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 936e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar const int64_t delayUs = nextSubTimeUs - subTimeUs; 937e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar msg->post(delayUs < 0 ? 0 : delayUs); 938e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 939e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar} 940e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 941840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<MetaData> NuPlayer::GenericSource::getFormatMeta(bool audio) { 9421d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetFormat, this); 94317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih msg->setInt32("audio", audio); 94417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 94517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih sp<AMessage> response; 94617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih void *format; 94717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih status_t err = msg->postAndAwaitResponse(&response); 94817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih if (err == OK && response != NULL) { 94917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih CHECK(response->findPointer("format", &format)); 95017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih return (MetaData *)format; 95117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih } else { 95217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih return NULL; 95317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih } 95417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih} 95517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 95617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onGetFormatMeta(sp<AMessage> msg) const { 95717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih int32_t audio; 95817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih CHECK(msg->findInt32("audio", &audio)); 95917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 96017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih sp<AMessage> response = new AMessage; 96117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih sp<MetaData> format = doGetFormatMeta(audio); 96217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih response->setPointer("format", format.get()); 96317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 9643f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 96517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih CHECK(msg->senderAwaitsResponse(&replyID)); 96617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih response->postReply(replyID); 96717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih} 96817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 96917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihsp<MetaData> NuPlayer::GenericSource::doGetFormatMeta(bool audio) const { 970afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber sp<MediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource; 971afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 972afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (source == NULL) { 973afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber return NULL; 974afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 975afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 976afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber return source->getFormat(); 977afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber} 978afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 979afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::dequeueAccessUnit( 980afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber bool audio, sp<ABuffer> *accessUnit) { 981afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber Track *track = audio ? &mAudioTrack : &mVideoTrack; 982afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 983afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (track->mSource == NULL) { 984afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber return -EWOULDBLOCK; 985afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 986afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 987cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar if (mIsWidevine && !audio) { 988cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar // try to read a buffer as we may not have been able to the last time 98917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih postReadBuffer(MEDIA_TRACK_TYPE_VIDEO); 990cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar } 991cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar 992afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber status_t finalResult; 993afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (!track->mPackets->hasBufferAvailable(&finalResult)) { 99442e8153cf7271b572e4a94ade332b68521977f36Chong Zhang if (finalResult == OK) { 99542e8153cf7271b572e4a94ade332b68521977f36Chong Zhang postReadBuffer( 99642e8153cf7271b572e4a94ade332b68521977f36Chong Zhang audio ? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO); 99742e8153cf7271b572e4a94ade332b68521977f36Chong Zhang return -EWOULDBLOCK; 99842e8153cf7271b572e4a94ade332b68521977f36Chong Zhang } 99942e8153cf7271b572e4a94ade332b68521977f36Chong Zhang return finalResult; 1000afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 1001afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1002afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber status_t result = track->mPackets->dequeueAccessUnit(accessUnit); 1003afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 10043423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih if (!track->mPackets->hasBufferAvailable(&finalResult)) { 100517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO); 1006e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 1007e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 10083423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih if (result != OK) { 1009e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (mSubtitleTrack.mSource != NULL) { 1010e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar mSubtitleTrack.mPackets->clear(); 1011e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar mFetchSubtitleDataGeneration++; 1012e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 1013e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (mTimedTextTrack.mSource != NULL) { 1014e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar mTimedTextTrack.mPackets->clear(); 1015e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar mFetchTimedTextDataGeneration++; 1016e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 10173423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih return result; 10183423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 10193423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 10203423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih int64_t timeUs; 10213423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih status_t eosResult; // ignored 10223423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs)); 10235c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih if (audio) { 10245c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih mAudioLastDequeueTimeUs = timeUs; 10255c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih } else { 10265c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih mVideoLastDequeueTimeUs = timeUs; 10275c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih } 1028e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 1029e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (mSubtitleTrack.mSource != NULL 1030e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) { 10311d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this); 10323423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih msg->setInt64("timeUs", timeUs); 10333423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih msg->setInt32("generation", mFetchSubtitleDataGeneration); 10343423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih msg->post(); 10353423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 1036eb1735e343a93830df259ae8882160bb0d79dcb5Robert Shih 1037e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (mTimedTextTrack.mSource != NULL 1038e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) { 10391d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, this); 1040e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar msg->setInt64("timeUs", timeUs); 1041e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar msg->setInt32("generation", mFetchTimedTextDataGeneration); 1042e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar msg->post(); 1043e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 1044e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 1045afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber return result; 1046afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber} 1047afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1048afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::getDuration(int64_t *durationUs) { 1049afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber *durationUs = mDurationUs; 1050afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber return OK; 1051afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber} 1052afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1053dd235727a1b4e283deeb581559f99c2c8889da07Robert Shihsize_t NuPlayer::GenericSource::getTrackCount() const { 1054dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih return mSources.size(); 1055dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih} 1056dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih 1057dd235727a1b4e283deeb581559f99c2c8889da07Robert Shihsp<AMessage> NuPlayer::GenericSource::getTrackInfo(size_t trackIndex) const { 1058dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih size_t trackCount = mSources.size(); 1059dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih if (trackIndex >= trackCount) { 1060dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih return NULL; 1061dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih } 1062dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih 1063dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih sp<AMessage> format = new AMessage(); 1064dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih sp<MetaData> meta = mSources.itemAt(trackIndex)->getFormat(); 1065dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih 1066dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih const char *mime; 1067dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih CHECK(meta->findCString(kKeyMIMEType, &mime)); 1068dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih 1069dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih int32_t trackType; 1070dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih if (!strncasecmp(mime, "video/", 6)) { 1071dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih trackType = MEDIA_TRACK_TYPE_VIDEO; 1072dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih } else if (!strncasecmp(mime, "audio/", 6)) { 1073dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih trackType = MEDIA_TRACK_TYPE_AUDIO; 1074dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) { 1075dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih trackType = MEDIA_TRACK_TYPE_TIMEDTEXT; 1076dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih } else { 1077dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih trackType = MEDIA_TRACK_TYPE_UNKNOWN; 1078dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih } 1079dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih format->setInt32("type", trackType); 1080dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih 1081dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih const char *lang; 1082dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih if (!meta->findCString(kKeyMediaLanguage, &lang)) { 1083dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih lang = "und"; 1084dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih } 1085dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih format->setString("language", lang); 1086dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih 1087dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) { 1088dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih format->setString("mime", mime); 1089dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih 1090dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih int32_t isAutoselect = 1, isDefault = 0, isForced = 0; 1091dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih meta->findInt32(kKeyTrackIsAutoselect, &isAutoselect); 1092dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih meta->findInt32(kKeyTrackIsDefault, &isDefault); 1093dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih meta->findInt32(kKeyTrackIsForced, &isForced); 1094dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih 1095dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih format->setInt32("auto", !!isAutoselect); 1096dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih format->setInt32("default", !!isDefault); 1097dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih format->setInt32("forced", !!isForced); 1098dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih } 1099dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih 1100dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih return format; 1101dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih} 1102dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih 1103e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnarssize_t NuPlayer::GenericSource::getSelectedTrack(media_track_type type) const { 11041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this); 110517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih msg->setInt32("type", type); 110617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 110717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih sp<AMessage> response; 110817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih int32_t index; 110917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih status_t err = msg->postAndAwaitResponse(&response); 111017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih if (err == OK && response != NULL) { 111117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih CHECK(response->findInt32("index", &index)); 111217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih return index; 111317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih } else { 111417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih return -1; 111517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih } 111617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih} 111717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 111817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onGetSelectedTrack(sp<AMessage> msg) const { 111917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih int32_t tmpType; 112017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih CHECK(msg->findInt32("type", &tmpType)); 112117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih media_track_type type = (media_track_type)tmpType; 112217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 112317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih sp<AMessage> response = new AMessage; 112417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih ssize_t index = doGetSelectedTrack(type); 112517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih response->setInt32("index", index); 112617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 11273f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 112817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih CHECK(msg->senderAwaitsResponse(&replyID)); 112917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih response->postReply(replyID); 113017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih} 113117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 113217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihssize_t NuPlayer::GenericSource::doGetSelectedTrack(media_track_type type) const { 1133e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar const Track *track = NULL; 1134e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar switch (type) { 1135e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar case MEDIA_TRACK_TYPE_VIDEO: 1136e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track = &mVideoTrack; 1137e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar break; 1138e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar case MEDIA_TRACK_TYPE_AUDIO: 1139e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track = &mAudioTrack; 1140e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar break; 1141e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar case MEDIA_TRACK_TYPE_TIMEDTEXT: 1142e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track = &mTimedTextTrack; 1143e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar break; 1144e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar case MEDIA_TRACK_TYPE_SUBTITLE: 1145e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track = &mSubtitleTrack; 1146e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar break; 1147e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar default: 1148e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar break; 1149e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 1150e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 1151e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (track != NULL && track->mSource != NULL) { 1152e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar return track->mIndex; 1153e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 1154e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 1155e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar return -1; 1156e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar} 1157e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 11586ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shihstatus_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select, int64_t timeUs) { 1159e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex); 11601d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSelectTrack, this); 116117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih msg->setInt32("trackIndex", trackIndex); 1162da23ab9b0dfa780175651daf057a02b0aa106dc8Robert Shih msg->setInt32("select", select); 11636ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih msg->setInt64("timeUs", timeUs); 116417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 116517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih sp<AMessage> response; 116617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih status_t err = msg->postAndAwaitResponse(&response); 116717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih if (err == OK && response != NULL) { 116817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih CHECK(response->findInt32("err", &err)); 116917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih } 117017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 117117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih return err; 117217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih} 117317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 117417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onSelectTrack(sp<AMessage> msg) { 117517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih int32_t trackIndex, select; 11766ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih int64_t timeUs; 117717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih CHECK(msg->findInt32("trackIndex", &trackIndex)); 117817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih CHECK(msg->findInt32("select", &select)); 11796ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih CHECK(msg->findInt64("timeUs", &timeUs)); 118017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 118117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih sp<AMessage> response = new AMessage; 11826ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih status_t err = doSelectTrack(trackIndex, select, timeUs); 118317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih response->setInt32("err", err); 118417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 11853f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 118617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih CHECK(msg->senderAwaitsResponse(&replyID)); 118717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih response->postReply(replyID); 118817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih} 118917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 11906ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shihstatus_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select, int64_t timeUs) { 11913423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih if (trackIndex >= mSources.size()) { 11923423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih return BAD_INDEX; 11933423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 11943423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 11953423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih if (!select) { 1196e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar Track* track = NULL; 1197e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (mSubtitleTrack.mSource != NULL && trackIndex == mSubtitleTrack.mIndex) { 1198e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track = &mSubtitleTrack; 1199e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar mFetchSubtitleDataGeneration++; 1200e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } else if (mTimedTextTrack.mSource != NULL && trackIndex == mTimedTextTrack.mIndex) { 1201e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track = &mTimedTextTrack; 1202e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar mFetchTimedTextDataGeneration++; 1203e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 1204e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (track == NULL) { 12053423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih return INVALID_OPERATION; 12063423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 1207e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track->mSource->stop(); 1208e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track->mSource = NULL; 1209e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track->mPackets->clear(); 12103423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih return OK; 12113423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 12123423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 12133423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih const sp<MediaSource> source = mSources.itemAt(trackIndex); 12143423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih sp<MetaData> meta = source->getFormat(); 12153423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih const char *mime; 12163423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih CHECK(meta->findCString(kKeyMIMEType, &mime)); 12173423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih if (!strncasecmp(mime, "text/", 5)) { 1218e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar bool isSubtitle = strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP); 1219e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar Track *track = isSubtitle ? &mSubtitleTrack : &mTimedTextTrack; 1220e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (track->mSource != NULL && track->mIndex == trackIndex) { 12213423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih return OK; 12223423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 1223e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track->mIndex = trackIndex; 1224e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (track->mSource != NULL) { 1225e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track->mSource->stop(); 12263423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 1227e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track->mSource = mSources.itemAt(trackIndex); 1228e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track->mSource->start(); 1229e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (track->mPackets == NULL) { 1230e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track->mPackets = new AnotherPacketSource(track->mSource->getFormat()); 12313423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } else { 1232e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track->mPackets->clear(); 1233e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track->mPackets->setFormat(track->mSource->getFormat()); 12343423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 12353423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 1236e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 1237e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (isSubtitle) { 1238e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar mFetchSubtitleDataGeneration++; 1239e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } else { 1240e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar mFetchTimedTextDataGeneration++; 1241e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 1242e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 12436ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih status_t eosResult; // ignored 12446ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih if (mSubtitleTrack.mSource != NULL 12456ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) { 12461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this); 12476ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih msg->setInt64("timeUs", timeUs); 12486ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih msg->setInt32("generation", mFetchSubtitleDataGeneration); 12496ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih msg->post(); 12506ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih } 12516ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih 12526ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih if (mTimedTextTrack.mSource != NULL 12536ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) { 12541d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, this); 12556ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih msg->setInt64("timeUs", timeUs); 12566ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih msg->setInt32("generation", mFetchTimedTextDataGeneration); 12576ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih msg->post(); 12586ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih } 12596ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih 12603423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih return OK; 12613423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) { 12623423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih bool audio = !strncasecmp(mime, "audio/", 6); 12633423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih Track *track = audio ? &mAudioTrack : &mVideoTrack; 12643423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih if (track->mSource != NULL && track->mIndex == trackIndex) { 12653423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih return OK; 12663423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 12673423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 12681d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatChangeAVSource, this); 12693423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih msg->setInt32("trackIndex", trackIndex); 12703423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih msg->post(); 12713423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih return OK; 12723423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 12733423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 12743423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih return INVALID_OPERATION; 12753423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih} 12763423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 1277afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs) { 12781d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSeek, this); 127917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih msg->setInt64("seekTimeUs", seekTimeUs); 128017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 128117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih sp<AMessage> response; 128217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih status_t err = msg->postAndAwaitResponse(&response); 128317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih if (err == OK && response != NULL) { 128417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih CHECK(response->findInt32("err", &err)); 128517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih } 128617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 128717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih return err; 128817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih} 128917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 129017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onSeek(sp<AMessage> msg) { 129117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih int64_t seekTimeUs; 129217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih CHECK(msg->findInt64("seekTimeUs", &seekTimeUs)); 129317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 129417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih sp<AMessage> response = new AMessage; 129517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih status_t err = doSeek(seekTimeUs); 129617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih response->setInt32("err", err); 129717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 12983f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 129917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih CHECK(msg->senderAwaitsResponse(&replyID)); 130017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih response->postReply(replyID); 130117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih} 130217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 130317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihstatus_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs) { 13042abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung // If the Widevine source is stopped, do not attempt to read any 13052abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung // more buffers. 13062abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung if (mStopRead) { 13072abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung return INVALID_OPERATION; 13082abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung } 1309afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (mVideoTrack.mSource != NULL) { 1310afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber int64_t actualTimeUs; 13113423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, &actualTimeUs); 1312afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1313afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber seekTimeUs = actualTimeUs; 13145c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih mVideoLastDequeueTimeUs = seekTimeUs; 1315afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 1316afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1317afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (mAudioTrack.mSource != NULL) { 13183423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih readBuffer(MEDIA_TRACK_TYPE_AUDIO, seekTimeUs); 13195c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih mAudioLastDequeueTimeUs = seekTimeUs; 1320afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 1321afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1322802768790c131f8237364906fd13981a6bb91193Ronghua Wu setDrmPlaybackStatusIfNeeded(Playback::START, seekTimeUs / 1000); 1323802768790c131f8237364906fd13981a6bb91193Ronghua Wu if (!mStarted) { 1324802768790c131f8237364906fd13981a6bb91193Ronghua Wu setDrmPlaybackStatusIfNeeded(Playback::PAUSE, 0); 1325802768790c131f8237364906fd13981a6bb91193Ronghua Wu } 1326efbb61950db36a5eb789be83f077246172507c67Chong Zhang 1327efbb61950db36a5eb789be83f077246172507c67Chong Zhang // If currently buffering, post kWhatBufferingEnd first, so that 1328efbb61950db36a5eb789be83f077246172507c67Chong Zhang // NuPlayer resumes. Otherwise, if cache hits high watermark 1329efbb61950db36a5eb789be83f077246172507c67Chong Zhang // before new polling happens, no one will resume the playback. 1330efbb61950db36a5eb789be83f077246172507c67Chong Zhang stopBufferingIfNecessary(); 1331efbb61950db36a5eb789be83f077246172507c67Chong Zhang restartPollBuffering(); 1332efbb61950db36a5eb789be83f077246172507c67Chong Zhang 1333afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber return OK; 1334afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber} 1335afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 13363423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shihsp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer( 13373423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih MediaBuffer* mb, 13383423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih media_track_type trackType, 1339474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia int64_t /* seekTimeUs */, 13403423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih int64_t *actualTimeUs) { 13413423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO; 13423423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih size_t outLength = mb->range_length(); 13433423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 13443423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih if (audio && mAudioIsVorbis) { 13453423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih outLength += sizeof(int32_t); 13463423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 13473423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 13483423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih sp<ABuffer> ab; 134942e8153cf7271b572e4a94ade332b68521977f36Chong Zhang if (mIsSecure && !audio) { 13503423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih // data is already provided in the buffer 13513423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih ab = new ABuffer(NULL, mb->range_length()); 13523423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih mb->add_ref(); 135396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia ab->setMediaBufferBase(mb); 13543423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } else { 13553423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih ab = new ABuffer(outLength); 13563423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih memcpy(ab->data(), 13573423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih (const uint8_t *)mb->data() + mb->range_offset(), 13583423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih mb->range_length()); 13593423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 13603423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 13613423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih if (audio && mAudioIsVorbis) { 13623423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih int32_t numPageSamples; 13633423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih if (!mb->meta_data()->findInt32(kKeyValidSamples, &numPageSamples)) { 13643423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih numPageSamples = -1; 13653423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 13663423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 13673423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih uint8_t* abEnd = ab->data() + mb->range_length(); 13683423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih memcpy(abEnd, &numPageSamples, sizeof(numPageSamples)); 13693423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 13703423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 1371e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar sp<AMessage> meta = ab->meta(); 1372e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 13733423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih int64_t timeUs; 13743423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs)); 13753423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih meta->setInt64("timeUs", timeUs); 13763423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 1377474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia#if 0 1378474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia // Temporarily disable pre-roll till we have a full solution to handle 1379474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia // both single seek and continous seek gracefully. 1380474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia if (seekTimeUs > timeUs) { 1381474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia sp<AMessage> extra = new AMessage; 1382474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia extra->setInt64("resume-at-mediaTimeUs", seekTimeUs); 1383474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia meta->setMessage("extra", extra); 1384474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia } 1385474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia#endif 1386474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia 1387e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if (trackType == MEDIA_TRACK_TYPE_TIMEDTEXT) { 1388e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar const char *mime; 1389e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar CHECK(mTimedTextTrack.mSource != NULL 1390e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar && mTimedTextTrack.mSource->getFormat()->findCString(kKeyMIMEType, &mime)); 1391e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar meta->setString("mime", mime); 1392e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar } 1393e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar 13943423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih int64_t durationUs; 13953423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih if (mb->meta_data()->findInt64(kKeyDuration, &durationUs)) { 13963423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih meta->setInt64("durationUs", durationUs); 13973423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 13983423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 13993423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) { 14003423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih meta->setInt32("trackIndex", mSubtitleTrack.mIndex); 14013423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 14023423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 1403f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih uint32_t dataType; // unused 1404f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih const void *seiData; 1405f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih size_t seiLength; 1406f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih if (mb->meta_data()->findData(kKeySEI, &dataType, &seiData, &seiLength)) { 1407f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih sp<ABuffer> sei = ABuffer::CreateAsCopy(seiData, seiLength);; 1408f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih meta->setBuffer("sei", sei); 1409f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih } 1410f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih 14113423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih if (actualTimeUs) { 14123423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih *actualTimeUs = timeUs; 14133423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 14143423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 14153423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih mb->release(); 14163423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih mb = NULL; 14173423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 14183423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih return ab; 14193423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih} 14203423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 142117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::postReadBuffer(media_track_type trackType) { 142284f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar Mutex::Autolock _l(mReadBufferLock); 142384f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar 142484f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar if ((mPendingReadBufferTypes & (1 << trackType)) == 0) { 142584f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar mPendingReadBufferTypes |= (1 << trackType); 14261d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReadBuffer, this); 142784f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar msg->setInt32("trackType", trackType); 142884f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar msg->post(); 142984f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar } 143017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih} 143117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 143217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onReadBuffer(sp<AMessage> msg) { 143317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih int32_t tmpType; 143417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih CHECK(msg->findInt32("trackType", &tmpType)); 143517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih media_track_type trackType = (media_track_type)tmpType; 143642e8153cf7271b572e4a94ade332b68521977f36Chong Zhang readBuffer(trackType); 143784f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar { 143884f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar // only protect the variable change, as readBuffer may 143942e8153cf7271b572e4a94ade332b68521977f36Chong Zhang // take considerable time. 144084f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar Mutex::Autolock _l(mReadBufferLock); 144184f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar mPendingReadBufferTypes &= ~(1 << trackType); 144284f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar } 144317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih} 144417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih 1445afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubervoid NuPlayer::GenericSource::readBuffer( 14463423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih media_track_type trackType, int64_t seekTimeUs, int64_t *actualTimeUs, bool formatChange) { 14472abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung // Do not read data if Widevine source is stopped 14482abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung if (mStopRead) { 14492abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung return; 14502abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung } 14513423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih Track *track; 1452c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk size_t maxBuffers = 1; 14533423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih switch (trackType) { 14543423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih case MEDIA_TRACK_TYPE_VIDEO: 14553423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih track = &mVideoTrack; 1456a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker if (mIsWidevine) { 1457a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker maxBuffers = 2; 1458a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker } 14593423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih break; 14603423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih case MEDIA_TRACK_TYPE_AUDIO: 14613423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih track = &mAudioTrack; 1462a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker if (mIsWidevine) { 1463a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker maxBuffers = 8; 1464a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker } else { 1465a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker maxBuffers = 64; 1466a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker } 14673423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih break; 14683423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih case MEDIA_TRACK_TYPE_SUBTITLE: 14693423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih track = &mSubtitleTrack; 14703423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih break; 1471e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar case MEDIA_TRACK_TYPE_TIMEDTEXT: 1472e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar track = &mTimedTextTrack; 1473e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar break; 14743423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih default: 14753423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih TRESPASS(); 14763423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 14773423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih 14783423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih if (track->mSource == NULL) { 14793423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih return; 14803423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih } 1481afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1482afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (actualTimeUs) { 1483afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber *actualTimeUs = seekTimeUs; 1484afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 1485afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1486afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber MediaSource::ReadOptions options; 1487afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1488afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber bool seeking = false; 1489afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1490afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (seekTimeUs >= 0) { 14913423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih options.setSeekTo(seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC); 1492afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber seeking = true; 1493afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 1494afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 149542e8153cf7271b572e4a94ade332b68521977f36Chong Zhang if (mIsWidevine) { 1496cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar options.setNonBlocking(); 1497cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar } 1498cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar 1499c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk for (size_t numBuffers = 0; numBuffers < maxBuffers; ) { 1500afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber MediaBuffer *mbuf; 1501afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber status_t err = track->mSource->read(&mbuf, &options); 1502afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1503afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber options.clearSeekTo(); 1504afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1505afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (err == OK) { 1506802768790c131f8237364906fd13981a6bb91193Ronghua Wu int64_t timeUs; 1507802768790c131f8237364906fd13981a6bb91193Ronghua Wu CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs)); 1508802768790c131f8237364906fd13981a6bb91193Ronghua Wu if (trackType == MEDIA_TRACK_TYPE_AUDIO) { 1509802768790c131f8237364906fd13981a6bb91193Ronghua Wu mAudioTimeUs = timeUs; 1510802768790c131f8237364906fd13981a6bb91193Ronghua Wu } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) { 1511802768790c131f8237364906fd13981a6bb91193Ronghua Wu mVideoTimeUs = timeUs; 1512802768790c131f8237364906fd13981a6bb91193Ronghua Wu } 1513802768790c131f8237364906fd13981a6bb91193Ronghua Wu 15143423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih // formatChange && seeking: track whose source is changed during selection 15153423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih // formatChange && !seeking: track whose source is not changed during selection 15163423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih // !formatChange: normal seek 1517e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar if ((seeking || formatChange) 1518e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar && (trackType == MEDIA_TRACK_TYPE_AUDIO 1519e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar || trackType == MEDIA_TRACK_TYPE_VIDEO)) { 1520fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia ATSParser::DiscontinuityType type = (formatChange && seeking) 1521fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia ? ATSParser::DISCONTINUITY_FORMATCHANGE 1522fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia : ATSParser::DISCONTINUITY_NONE; 15233423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih track->mPackets->queueDiscontinuity( type, NULL, true /* discard */); 1524afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 1525afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1526474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia sp<ABuffer> buffer = mediaBufferToABuffer( 1527474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia mbuf, trackType, seekTimeUs, actualTimeUs); 1528afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber track->mPackets->queueAccessUnit(buffer); 1529317a49a4c4bf02944d1e01941c6b9f86179044bbMarco Nelissen formatChange = false; 1530317a49a4c4bf02944d1e01941c6b9f86179044bbMarco Nelissen seeking = false; 1531c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk ++numBuffers; 1532cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar } else if (err == WOULD_BLOCK) { 1533cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar break; 1534afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } else if (err == INFO_FORMAT_CHANGED) { 1535afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#if 0 1536afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber track->mPackets->queueDiscontinuity( 1537632740c58119a132ce19f6d498e39c5c3773971aChong Zhang ATSParser::DISCONTINUITY_FORMATCHANGE, 1538632740c58119a132ce19f6d498e39c5c3773971aChong Zhang NULL, 1539632740c58119a132ce19f6d498e39c5c3773971aChong Zhang false /* discard */); 1540afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#endif 1541afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } else { 1542afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber track->mPackets->signalEOS(err); 1543afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber break; 1544afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 1545afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } 1546afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber} 1547afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber 1548afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber} // namespace android 1549