NuPlayer.cpp revision 6d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aab
1ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi/* 2ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * Copyright (C) 2010 The Android Open Source Project 3ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * 4ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License"); 5ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * you may not use this file except in compliance with the License. 6ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * You may obtain a copy of the License at 7ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * 8ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * http://www.apache.org/licenses/LICENSE-2.0 9ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * 10ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * Unless required by applicable law or agreed to in writing, software 11ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS, 12ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * See the License for the specific language governing permissions and 14ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * limitations under the License. 15ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi */ 16ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 17ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi//#define LOG_NDEBUG 0 18ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#define LOG_TAG "NuPlayer" 19ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <utils/Log.h> 20ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 21ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "NuPlayer.h" 22ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 23ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "HTTPLiveSource.h" 24ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "NuPlayerDecoder.h" 25ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "NuPlayerDriver.h" 26ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "NuPlayerRenderer.h" 27ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "NuPlayerSource.h" 28ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "RTSPSource.h" 29ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "StreamingSource.h" 30ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "GenericSource.h" 31ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 32ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "ATSParser.h" 33ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 34ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "SoftwareRenderer.h" 35ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 36ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/foundation/hexdump.h> 37ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/foundation/ABuffer.h> 38ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/foundation/ADebug.h> 39ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/foundation/AMessage.h> 40ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/ACodec.h> 41ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/MediaDefs.h> 42ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/MediaErrors.h> 43ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/MetaData.h> 44ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <gui/IGraphicBufferProducer.h> 45ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 46ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "avc_utils.h" 47ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 48ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include "ESDS.h" 49ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi#include <media/stagefright/Utils.h> 50ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 51ecbab3662d4474bbb45477939aaa167eb883212bJorim Jagginamespace android { 52ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 53ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggistruct NuPlayer::Action : public RefBase { 54ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi Action() {} 55ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 56ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi virtual void execute(NuPlayer *player) = 0; 57ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 58ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiprivate: 59ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi DISALLOW_EVIL_CONSTRUCTORS(Action); 60ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi}; 61ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 62ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggistruct NuPlayer::SeekAction : public Action { 63ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi SeekAction(int64_t seekTimeUs) 64ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi : mSeekTimeUs(seekTimeUs) { 65ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 66ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 67ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi virtual void execute(NuPlayer *player) { 68ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi player->performSeek(mSeekTimeUs); 69ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 70ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 71ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiprivate: 72ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi int64_t mSeekTimeUs; 73ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 74ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi DISALLOW_EVIL_CONSTRUCTORS(SeekAction); 75ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi}; 76ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 77ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggistruct NuPlayer::SetSurfaceAction : public Action { 78ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper) 79ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi : mWrapper(wrapper) { 80ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 81ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 82ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi virtual void execute(NuPlayer *player) { 83ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi player->performSetSurface(mWrapper); 84ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 85ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 86ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiprivate: 87ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi sp<NativeWindowWrapper> mWrapper; 88ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 89ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction); 90ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi}; 91ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 92ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggistruct NuPlayer::ShutdownDecoderAction : public Action { 93ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi ShutdownDecoderAction(bool audio, bool video) 94ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi : mAudio(audio), 95ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mVideo(video) { 96ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 97ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 98ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi virtual void execute(NuPlayer *player) { 99ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi player->performDecoderShutdown(mAudio, mVideo); 100ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 101ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 102ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiprivate: 103ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi bool mAudio; 104ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi bool mVideo; 105ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 106ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi DISALLOW_EVIL_CONSTRUCTORS(ShutdownDecoderAction); 107ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi}; 108ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 109ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggistruct NuPlayer::PostMessageAction : public Action { 110ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi PostMessageAction(const sp<AMessage> &msg) 111ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi : mMessage(msg) { 112ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 113ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 114ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi virtual void execute(NuPlayer *) { 115ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mMessage->post(); 116ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 117ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 118ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiprivate: 119ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi sp<AMessage> mMessage; 120ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 121ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction); 122ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi}; 123ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 124ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi// Use this if there's no state necessary to save in order to execute 125ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi// the action. 126ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggistruct NuPlayer::SimpleAction : public Action { 127ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi typedef void (NuPlayer::*ActionFunc)(); 128ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 129ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi SimpleAction(ActionFunc func) 130ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi : mFunc(func) { 131ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 132ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 133ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi virtual void execute(NuPlayer *player) { 134ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi (player->*mFunc)(); 135ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 136ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 137ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiprivate: 138ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi ActionFunc mFunc; 139ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 140ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi DISALLOW_EVIL_CONSTRUCTORS(SimpleAction); 141ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi}; 142ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 143ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi//////////////////////////////////////////////////////////////////////////////// 144ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 145ecbab3662d4474bbb45477939aaa167eb883212bJorim JaggiNuPlayer::NuPlayer() 146ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi : mUIDValid(false), 147ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mSourceFlags(0), 148ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mVideoIsAVC(false), 149ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mNeedsSwRenderer(false), 150ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mAudioEOS(false), 151ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mVideoEOS(false), 152ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mScanSourcesPending(false), 153ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mScanSourcesGeneration(0), 154ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mPollDurationGeneration(0), 155ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mTimeDiscontinuityPending(false), 156ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mFlushingAudio(NONE), 157ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mFlushingVideo(NONE), 158ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mSkipRenderingAudioUntilMediaTimeUs(-1ll), 159 mSkipRenderingVideoUntilMediaTimeUs(-1ll), 160 mVideoLateByUs(0ll), 161 mNumFramesTotal(0ll), 162 mNumFramesDropped(0ll), 163 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW), 164 mStarted(false) { 165} 166 167NuPlayer::~NuPlayer() { 168} 169 170void NuPlayer::setUID(uid_t uid) { 171 mUIDValid = true; 172 mUID = uid; 173} 174 175void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) { 176 mDriver = driver; 177} 178 179void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) { 180 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); 181 182 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id()); 183 184 msg->setObject("source", new StreamingSource(notify, source)); 185 msg->post(); 186} 187 188static bool IsHTTPLiveURL(const char *url) { 189 if (!strncasecmp("http://", url, 7) 190 || !strncasecmp("https://", url, 8) 191 || !strncasecmp("file://", url, 7)) { 192 size_t len = strlen(url); 193 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) { 194 return true; 195 } 196 197 if (strstr(url,"m3u8")) { 198 return true; 199 } 200 } 201 202 return false; 203} 204 205void NuPlayer::setDataSourceAsync( 206 const sp<IMediaHTTPService> &httpService, 207 const char *url, 208 const KeyedVector<String8, String8> *headers) { 209 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); 210 size_t len = strlen(url); 211 212 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id()); 213 214 sp<Source> source; 215 if (IsHTTPLiveURL(url)) { 216 source = new HTTPLiveSource(notify, httpService, url, headers); 217 } else if (!strncasecmp(url, "rtsp://", 7)) { 218 source = new RTSPSource( 219 notify, httpService, url, headers, mUIDValid, mUID); 220 } else if ((!strncasecmp(url, "http://", 7) 221 || !strncasecmp(url, "https://", 8)) 222 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) 223 || strstr(url, ".sdp?"))) { 224 source = new RTSPSource( 225 notify, httpService, url, headers, mUIDValid, mUID, true); 226 } else { 227 source = new GenericSource(notify, httpService, url, headers); 228 } 229 230 msg->setObject("source", source); 231 msg->post(); 232} 233 234void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) { 235 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); 236 237 sp<AMessage> notify = new AMessage(kWhatSourceNotify, id()); 238 239 sp<Source> source = new GenericSource(notify, fd, offset, length); 240 msg->setObject("source", source); 241 msg->post(); 242} 243 244void NuPlayer::prepareAsync() { 245 (new AMessage(kWhatPrepare, id()))->post(); 246} 247 248void NuPlayer::setVideoSurfaceTextureAsync( 249 const sp<IGraphicBufferProducer> &bufferProducer) { 250 sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id()); 251 252 if (bufferProducer == NULL) { 253 msg->setObject("native-window", NULL); 254 } else { 255 msg->setObject( 256 "native-window", 257 new NativeWindowWrapper( 258 new Surface(bufferProducer))); 259 } 260 261 msg->post(); 262} 263 264void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) { 265 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id()); 266 msg->setObject("sink", sink); 267 msg->post(); 268} 269 270void NuPlayer::start() { 271 (new AMessage(kWhatStart, id()))->post(); 272} 273 274void NuPlayer::pause() { 275 (new AMessage(kWhatPause, id()))->post(); 276} 277 278void NuPlayer::resume() { 279 (new AMessage(kWhatResume, id()))->post(); 280} 281 282void NuPlayer::resetAsync() { 283 (new AMessage(kWhatReset, id()))->post(); 284} 285 286void NuPlayer::seekToAsync(int64_t seekTimeUs) { 287 sp<AMessage> msg = new AMessage(kWhatSeek, id()); 288 msg->setInt64("seekTimeUs", seekTimeUs); 289 msg->post(); 290} 291 292// static 293bool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) { 294 switch (state) { 295 case FLUSHING_DECODER: 296 if (needShutdown != NULL) { 297 *needShutdown = false; 298 } 299 return true; 300 301 case FLUSHING_DECODER_SHUTDOWN: 302 if (needShutdown != NULL) { 303 *needShutdown = true; 304 } 305 return true; 306 307 default: 308 return false; 309 } 310} 311 312void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { 313 switch (msg->what()) { 314 case kWhatSetDataSource: 315 { 316 ALOGV("kWhatSetDataSource"); 317 318 CHECK(mSource == NULL); 319 320 sp<RefBase> obj; 321 CHECK(msg->findObject("source", &obj)); 322 323 mSource = static_cast<Source *>(obj.get()); 324 325 looper()->registerHandler(mSource); 326 327 CHECK(mDriver != NULL); 328 sp<NuPlayerDriver> driver = mDriver.promote(); 329 if (driver != NULL) { 330 driver->notifySetDataSourceCompleted(OK); 331 } 332 break; 333 } 334 335 case kWhatPrepare: 336 { 337 mSource->prepareAsync(); 338 break; 339 } 340 341 case kWhatGetTrackInfo: 342 { 343 uint32_t replyID; 344 CHECK(msg->senderAwaitsResponse(&replyID)); 345 346 status_t err = INVALID_OPERATION; 347 if (mSource != NULL) { 348 Parcel* reply; 349 CHECK(msg->findPointer("reply", (void**)&reply)); 350 err = mSource->getTrackInfo(reply); 351 } 352 353 sp<AMessage> response = new AMessage; 354 response->setInt32("err", err); 355 356 response->postReply(replyID); 357 break; 358 } 359 360 case kWhatSelectTrack: 361 { 362 uint32_t replyID; 363 CHECK(msg->senderAwaitsResponse(&replyID)); 364 365 status_t err = INVALID_OPERATION; 366 if (mSource != NULL) { 367 size_t trackIndex; 368 int32_t select; 369 CHECK(msg->findSize("trackIndex", &trackIndex)); 370 CHECK(msg->findInt32("select", &select)); 371 err = mSource->selectTrack(trackIndex, select); 372 } 373 374 sp<AMessage> response = new AMessage; 375 response->setInt32("err", err); 376 377 response->postReply(replyID); 378 break; 379 } 380 381 case kWhatPollDuration: 382 { 383 int32_t generation; 384 CHECK(msg->findInt32("generation", &generation)); 385 386 if (generation != mPollDurationGeneration) { 387 // stale 388 break; 389 } 390 391 int64_t durationUs; 392 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) { 393 sp<NuPlayerDriver> driver = mDriver.promote(); 394 if (driver != NULL) { 395 driver->notifyDuration(durationUs); 396 } 397 } 398 399 msg->post(1000000ll); // poll again in a second. 400 break; 401 } 402 403 case kWhatSetVideoNativeWindow: 404 { 405 ALOGV("kWhatSetVideoNativeWindow"); 406 407 mDeferredActions.push_back( 408 new ShutdownDecoderAction( 409 false /* audio */, true /* video */)); 410 411 sp<RefBase> obj; 412 CHECK(msg->findObject("native-window", &obj)); 413 414 mDeferredActions.push_back( 415 new SetSurfaceAction( 416 static_cast<NativeWindowWrapper *>(obj.get()))); 417 418 if (obj != NULL) { 419 // If there is a new surface texture, instantiate decoders 420 // again if possible. 421 mDeferredActions.push_back( 422 new SimpleAction(&NuPlayer::performScanSources)); 423 } 424 425 processDeferredActions(); 426 break; 427 } 428 429 case kWhatSetAudioSink: 430 { 431 ALOGV("kWhatSetAudioSink"); 432 433 sp<RefBase> obj; 434 CHECK(msg->findObject("sink", &obj)); 435 436 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get()); 437 break; 438 } 439 440 case kWhatStart: 441 { 442 ALOGV("kWhatStart"); 443 444 mVideoIsAVC = false; 445 mNeedsSwRenderer = false; 446 mAudioEOS = false; 447 mVideoEOS = false; 448 mSkipRenderingAudioUntilMediaTimeUs = -1; 449 mSkipRenderingVideoUntilMediaTimeUs = -1; 450 mVideoLateByUs = 0; 451 mNumFramesTotal = 0; 452 mNumFramesDropped = 0; 453 mStarted = true; 454 455 mSource->start(); 456 457 uint32_t flags = 0; 458 459 if (mSource->isRealTime()) { 460 flags |= Renderer::FLAG_REAL_TIME; 461 } 462 463 mRenderer = new Renderer( 464 mAudioSink, 465 new AMessage(kWhatRendererNotify, id()), 466 flags); 467 468 looper()->registerHandler(mRenderer); 469 470 postScanSources(); 471 break; 472 } 473 474 case kWhatScanSources: 475 { 476 int32_t generation; 477 CHECK(msg->findInt32("generation", &generation)); 478 if (generation != mScanSourcesGeneration) { 479 // Drop obsolete msg. 480 break; 481 } 482 483 mScanSourcesPending = false; 484 485 ALOGV("scanning sources haveAudio=%d, haveVideo=%d", 486 mAudioDecoder != NULL, mVideoDecoder != NULL); 487 488 bool mHadAnySourcesBefore = 489 (mAudioDecoder != NULL) || (mVideoDecoder != NULL); 490 491 if (mNativeWindow != NULL) { 492 instantiateDecoder(false, &mVideoDecoder); 493 } 494 495 if (mAudioSink != NULL) { 496 instantiateDecoder(true, &mAudioDecoder); 497 } 498 499 if (!mHadAnySourcesBefore 500 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { 501 // This is the first time we've found anything playable. 502 503 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) { 504 schedulePollDuration(); 505 } 506 } 507 508 status_t err; 509 if ((err = mSource->feedMoreTSData()) != OK) { 510 if (mAudioDecoder == NULL && mVideoDecoder == NULL) { 511 // We're not currently decoding anything (no audio or 512 // video tracks found) and we just ran out of input data. 513 514 if (err == ERROR_END_OF_STREAM) { 515 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); 516 } else { 517 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); 518 } 519 } 520 break; 521 } 522 523 if ((mAudioDecoder == NULL && mAudioSink != NULL) 524 || (mVideoDecoder == NULL && mNativeWindow != NULL)) { 525 msg->post(100000ll); 526 mScanSourcesPending = true; 527 } 528 break; 529 } 530 531 case kWhatVideoNotify: 532 case kWhatAudioNotify: 533 { 534 bool audio = msg->what() == kWhatAudioNotify; 535 536 sp<AMessage> codecRequest; 537 CHECK(msg->findMessage("codec-request", &codecRequest)); 538 539 int32_t what; 540 CHECK(codecRequest->findInt32("what", &what)); 541 542 if (what == ACodec::kWhatFillThisBuffer) { 543 status_t err = feedDecoderInputData( 544 audio, codecRequest); 545 546 if (err == -EWOULDBLOCK) { 547 if (mSource->feedMoreTSData() == OK) { 548 msg->post(10000ll); 549 } 550 } 551 } else if (what == ACodec::kWhatEOS) { 552 int32_t err; 553 CHECK(codecRequest->findInt32("err", &err)); 554 555 if (err == ERROR_END_OF_STREAM) { 556 ALOGV("got %s decoder EOS", audio ? "audio" : "video"); 557 } else { 558 ALOGV("got %s decoder EOS w/ error %d", 559 audio ? "audio" : "video", 560 err); 561 } 562 563 mRenderer->queueEOS(audio, err); 564 } else if (what == ACodec::kWhatFlushCompleted) { 565 bool needShutdown; 566 567 if (audio) { 568 CHECK(IsFlushingState(mFlushingAudio, &needShutdown)); 569 mFlushingAudio = FLUSHED; 570 } else { 571 CHECK(IsFlushingState(mFlushingVideo, &needShutdown)); 572 mFlushingVideo = FLUSHED; 573 574 mVideoLateByUs = 0; 575 } 576 577 ALOGV("decoder %s flush completed", audio ? "audio" : "video"); 578 579 if (needShutdown) { 580 ALOGV("initiating %s decoder shutdown", 581 audio ? "audio" : "video"); 582 583 (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown(); 584 585 if (audio) { 586 mFlushingAudio = SHUTTING_DOWN_DECODER; 587 } else { 588 mFlushingVideo = SHUTTING_DOWN_DECODER; 589 } 590 } 591 592 finishFlushIfPossible(); 593 } else if (what == ACodec::kWhatOutputFormatChanged) { 594 if (audio) { 595 int32_t numChannels; 596 CHECK(codecRequest->findInt32( 597 "channel-count", &numChannels)); 598 599 int32_t sampleRate; 600 CHECK(codecRequest->findInt32("sample-rate", &sampleRate)); 601 602 ALOGV("Audio output format changed to %d Hz, %d channels", 603 sampleRate, numChannels); 604 605 mAudioSink->close(); 606 607 audio_output_flags_t flags; 608 int64_t durationUs; 609 // FIXME: we should handle the case where the video decoder 610 // is created after we receive the format change indication. 611 // Current code will just make that we select deep buffer 612 // with video which should not be a problem as it should 613 // not prevent from keeping A/V sync. 614 if (mVideoDecoder == NULL && 615 mSource->getDuration(&durationUs) == OK && 616 durationUs 617 > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) { 618 flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 619 } else { 620 flags = AUDIO_OUTPUT_FLAG_NONE; 621 } 622 623 int32_t channelMask; 624 if (!codecRequest->findInt32("channel-mask", &channelMask)) { 625 channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER; 626 } 627 628 CHECK_EQ(mAudioSink->open( 629 sampleRate, 630 numChannels, 631 (audio_channel_mask_t)channelMask, 632 AUDIO_FORMAT_PCM_16_BIT, 633 8 /* bufferCount */, 634 NULL, 635 NULL, 636 flags), 637 (status_t)OK); 638 mAudioSink->start(); 639 640 mRenderer->signalAudioSinkChanged(); 641 } else { 642 // video 643 644 int32_t width, height; 645 CHECK(codecRequest->findInt32("width", &width)); 646 CHECK(codecRequest->findInt32("height", &height)); 647 648 int32_t cropLeft, cropTop, cropRight, cropBottom; 649 CHECK(codecRequest->findRect( 650 "crop", 651 &cropLeft, &cropTop, &cropRight, &cropBottom)); 652 653 int32_t displayWidth = cropRight - cropLeft + 1; 654 int32_t displayHeight = cropBottom - cropTop + 1; 655 656 ALOGV("Video output format changed to %d x %d " 657 "(crop: %d x %d @ (%d, %d))", 658 width, height, 659 displayWidth, 660 displayHeight, 661 cropLeft, cropTop); 662 663 sp<AMessage> videoInputFormat = 664 mSource->getFormat(false /* audio */); 665 666 // Take into account sample aspect ratio if necessary: 667 int32_t sarWidth, sarHeight; 668 if (videoInputFormat->findInt32("sar-width", &sarWidth) 669 && videoInputFormat->findInt32( 670 "sar-height", &sarHeight)) { 671 ALOGV("Sample aspect ratio %d : %d", 672 sarWidth, sarHeight); 673 674 displayWidth = (displayWidth * sarWidth) / sarHeight; 675 676 ALOGV("display dimensions %d x %d", 677 displayWidth, displayHeight); 678 } 679 680 notifyListener( 681 MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight); 682 683 if (mNeedsSwRenderer && mNativeWindow != NULL) { 684 int32_t colorFormat; 685 CHECK(codecRequest->findInt32("color-format", &colorFormat)); 686 687 sp<MetaData> meta = new MetaData; 688 meta->setInt32(kKeyWidth, width); 689 meta->setInt32(kKeyHeight, height); 690 meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom); 691 meta->setInt32(kKeyColorFormat, colorFormat); 692 693 mRenderer->setSoftRenderer( 694 new SoftwareRenderer(mNativeWindow->getNativeWindow(), meta)); 695 } 696 } 697 } else if (what == ACodec::kWhatShutdownCompleted) { 698 ALOGV("%s shutdown completed", audio ? "audio" : "video"); 699 if (audio) { 700 mAudioDecoder.clear(); 701 702 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER); 703 mFlushingAudio = SHUT_DOWN; 704 } else { 705 mVideoDecoder.clear(); 706 707 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER); 708 mFlushingVideo = SHUT_DOWN; 709 } 710 711 finishFlushIfPossible(); 712 } else if (what == ACodec::kWhatError) { 713 ALOGE("Received error from %s decoder, aborting playback.", 714 audio ? "audio" : "video"); 715 716 mRenderer->queueEOS(audio, UNKNOWN_ERROR); 717 } else if (what == ACodec::kWhatDrainThisBuffer) { 718 renderBuffer(audio, codecRequest); 719 } else if (what == ACodec::kWhatComponentAllocated) { 720 if (!audio) { 721 AString name; 722 CHECK(codecRequest->findString("componentName", &name)); 723 mNeedsSwRenderer = name.startsWith("OMX.google."); 724 } 725 } else if (what != ACodec::kWhatComponentConfigured 726 && what != ACodec::kWhatBuffersAllocated) { 727 ALOGV("Unhandled codec notification %d '%c%c%c%c'.", 728 what, 729 what >> 24, 730 (what >> 16) & 0xff, 731 (what >> 8) & 0xff, 732 what & 0xff); 733 } 734 735 break; 736 } 737 738 case kWhatRendererNotify: 739 { 740 int32_t what; 741 CHECK(msg->findInt32("what", &what)); 742 743 if (what == Renderer::kWhatEOS) { 744 int32_t audio; 745 CHECK(msg->findInt32("audio", &audio)); 746 747 int32_t finalResult; 748 CHECK(msg->findInt32("finalResult", &finalResult)); 749 750 if (audio) { 751 mAudioEOS = true; 752 } else { 753 mVideoEOS = true; 754 } 755 756 if (finalResult == ERROR_END_OF_STREAM) { 757 ALOGV("reached %s EOS", audio ? "audio" : "video"); 758 } else { 759 ALOGE("%s track encountered an error (%d)", 760 audio ? "audio" : "video", finalResult); 761 762 notifyListener( 763 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult); 764 } 765 766 if ((mAudioEOS || mAudioDecoder == NULL) 767 && (mVideoEOS || mVideoDecoder == NULL)) { 768 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); 769 } 770 } else if (what == Renderer::kWhatPosition) { 771 int64_t positionUs; 772 CHECK(msg->findInt64("positionUs", &positionUs)); 773 774 CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs)); 775 776 if (mDriver != NULL) { 777 sp<NuPlayerDriver> driver = mDriver.promote(); 778 if (driver != NULL) { 779 driver->notifyPosition(positionUs); 780 781 driver->notifyFrameStats( 782 mNumFramesTotal, mNumFramesDropped); 783 } 784 } 785 } else if (what == Renderer::kWhatFlushComplete) { 786 int32_t audio; 787 CHECK(msg->findInt32("audio", &audio)); 788 789 ALOGV("renderer %s flush completed.", audio ? "audio" : "video"); 790 } else if (what == Renderer::kWhatVideoRenderingStart) { 791 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0); 792 } else if (what == Renderer::kWhatMediaRenderingStart) { 793 ALOGV("media rendering started"); 794 notifyListener(MEDIA_STARTED, 0, 0); 795 } 796 break; 797 } 798 799 case kWhatMoreDataQueued: 800 { 801 break; 802 } 803 804 case kWhatReset: 805 { 806 ALOGV("kWhatReset"); 807 808 mDeferredActions.push_back( 809 new ShutdownDecoderAction( 810 true /* audio */, true /* video */)); 811 812 mDeferredActions.push_back( 813 new SimpleAction(&NuPlayer::performReset)); 814 815 processDeferredActions(); 816 break; 817 } 818 819 case kWhatSeek: 820 { 821 int64_t seekTimeUs; 822 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs)); 823 824 ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs); 825 826 mDeferredActions.push_back( 827 new SimpleAction(&NuPlayer::performDecoderFlush)); 828 829 mDeferredActions.push_back(new SeekAction(seekTimeUs)); 830 831 processDeferredActions(); 832 break; 833 } 834 835 case kWhatPause: 836 { 837 CHECK(mRenderer != NULL); 838 mSource->pause(); 839 mRenderer->pause(); 840 break; 841 } 842 843 case kWhatResume: 844 { 845 CHECK(mRenderer != NULL); 846 mSource->resume(); 847 mRenderer->resume(); 848 break; 849 } 850 851 case kWhatSourceNotify: 852 { 853 onSourceNotify(msg); 854 break; 855 } 856 857 default: 858 TRESPASS(); 859 break; 860 } 861} 862 863void NuPlayer::finishFlushIfPossible() { 864 if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) { 865 return; 866 } 867 868 if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) { 869 return; 870 } 871 872 ALOGV("both audio and video are flushed now."); 873 874 if (mTimeDiscontinuityPending) { 875 mRenderer->signalTimeDiscontinuity(); 876 mTimeDiscontinuityPending = false; 877 } 878 879 if (mAudioDecoder != NULL) { 880 mAudioDecoder->signalResume(); 881 } 882 883 if (mVideoDecoder != NULL) { 884 mVideoDecoder->signalResume(); 885 } 886 887 mFlushingAudio = NONE; 888 mFlushingVideo = NONE; 889 890 processDeferredActions(); 891} 892 893void NuPlayer::postScanSources() { 894 if (mScanSourcesPending) { 895 return; 896 } 897 898 sp<AMessage> msg = new AMessage(kWhatScanSources, id()); 899 msg->setInt32("generation", mScanSourcesGeneration); 900 msg->post(); 901 902 mScanSourcesPending = true; 903} 904 905status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) { 906 if (*decoder != NULL) { 907 return OK; 908 } 909 910 sp<AMessage> format = mSource->getFormat(audio); 911 912 if (format == NULL) { 913 return -EWOULDBLOCK; 914 } 915 916 if (!audio) { 917 AString mime; 918 CHECK(format->findString("mime", &mime)); 919 mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str()); 920 } 921 922 sp<AMessage> notify = 923 new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify, 924 id()); 925 926 *decoder = audio ? new Decoder(notify) : 927 new Decoder(notify, mNativeWindow); 928 looper()->registerHandler(*decoder); 929 930 (*decoder)->configure(format); 931 932 return OK; 933} 934 935status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { 936 sp<AMessage> reply; 937 CHECK(msg->findMessage("reply", &reply)); 938 939 if ((audio && IsFlushingState(mFlushingAudio)) 940 || (!audio && IsFlushingState(mFlushingVideo))) { 941 reply->setInt32("err", INFO_DISCONTINUITY); 942 reply->post(); 943 return OK; 944 } 945 946 sp<ABuffer> accessUnit; 947 948 bool dropAccessUnit; 949 do { 950 status_t err = mSource->dequeueAccessUnit(audio, &accessUnit); 951 952 if (err == -EWOULDBLOCK) { 953 return err; 954 } else if (err != OK) { 955 if (err == INFO_DISCONTINUITY) { 956 int32_t type; 957 CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); 958 959 bool formatChange = 960 (audio && 961 (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT)) 962 || (!audio && 963 (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT)); 964 965 bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; 966 967 ALOGI("%s discontinuity (formatChange=%d, time=%d)", 968 audio ? "audio" : "video", formatChange, timeChange); 969 970 if (audio) { 971 mSkipRenderingAudioUntilMediaTimeUs = -1; 972 } else { 973 mSkipRenderingVideoUntilMediaTimeUs = -1; 974 } 975 976 if (timeChange) { 977 sp<AMessage> extra; 978 if (accessUnit->meta()->findMessage("extra", &extra) 979 && extra != NULL) { 980 int64_t resumeAtMediaTimeUs; 981 if (extra->findInt64( 982 "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) { 983 ALOGI("suppressing rendering of %s until %lld us", 984 audio ? "audio" : "video", resumeAtMediaTimeUs); 985 986 if (audio) { 987 mSkipRenderingAudioUntilMediaTimeUs = 988 resumeAtMediaTimeUs; 989 } else { 990 mSkipRenderingVideoUntilMediaTimeUs = 991 resumeAtMediaTimeUs; 992 } 993 } 994 } 995 } 996 997 mTimeDiscontinuityPending = 998 mTimeDiscontinuityPending || timeChange; 999 1000 if (formatChange || timeChange) { 1001 if (mFlushingAudio == NONE && mFlushingVideo == NONE) { 1002 // And we'll resume scanning sources once we're done 1003 // flushing. 1004 mDeferredActions.push_front( 1005 new SimpleAction( 1006 &NuPlayer::performScanSources)); 1007 } 1008 1009 sp<AMessage> newFormat = mSource->getFormat(audio); 1010 sp<Decoder> &decoder = audio ? mAudioDecoder : mVideoDecoder; 1011 if (formatChange && !decoder->supportsSeamlessFormatChange(newFormat)) { 1012 flushDecoder(audio, /* needShutdown = */ true); 1013 } else { 1014 flushDecoder(audio, /* needShutdown = */ false); 1015 err = OK; 1016 } 1017 } else { 1018 // This stream is unaffected by the discontinuity 1019 1020 if (audio) { 1021 mFlushingAudio = FLUSHED; 1022 } else { 1023 mFlushingVideo = FLUSHED; 1024 } 1025 1026 finishFlushIfPossible(); 1027 1028 return -EWOULDBLOCK; 1029 } 1030 } 1031 1032 reply->setInt32("err", err); 1033 reply->post(); 1034 return OK; 1035 } 1036 1037 if (!audio) { 1038 ++mNumFramesTotal; 1039 } 1040 1041 dropAccessUnit = false; 1042 if (!audio 1043 && mVideoLateByUs > 100000ll 1044 && mVideoIsAVC 1045 && !IsAVCReferenceFrame(accessUnit)) { 1046 dropAccessUnit = true; 1047 ++mNumFramesDropped; 1048 } 1049 } while (dropAccessUnit); 1050 1051 // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video"); 1052 1053#if 0 1054 int64_t mediaTimeUs; 1055 CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); 1056 ALOGV("feeding %s input buffer at media time %.2f secs", 1057 audio ? "audio" : "video", 1058 mediaTimeUs / 1E6); 1059#endif 1060 1061 reply->setBuffer("buffer", accessUnit); 1062 reply->post(); 1063 1064 return OK; 1065} 1066 1067void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) { 1068 // ALOGV("renderBuffer %s", audio ? "audio" : "video"); 1069 1070 sp<AMessage> reply; 1071 CHECK(msg->findMessage("reply", &reply)); 1072 1073 if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) { 1074 // We're currently attempting to flush the decoder, in order 1075 // to complete this, the decoder wants all its buffers back, 1076 // so we don't want any output buffers it sent us (from before 1077 // we initiated the flush) to be stuck in the renderer's queue. 1078 1079 ALOGV("we're still flushing the %s decoder, sending its output buffer" 1080 " right back.", audio ? "audio" : "video"); 1081 1082 reply->post(); 1083 return; 1084 } 1085 1086 sp<ABuffer> buffer; 1087 CHECK(msg->findBuffer("buffer", &buffer)); 1088 1089 int64_t &skipUntilMediaTimeUs = 1090 audio 1091 ? mSkipRenderingAudioUntilMediaTimeUs 1092 : mSkipRenderingVideoUntilMediaTimeUs; 1093 1094 if (skipUntilMediaTimeUs >= 0) { 1095 int64_t mediaTimeUs; 1096 CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs)); 1097 1098 if (mediaTimeUs < skipUntilMediaTimeUs) { 1099 ALOGV("dropping %s buffer at time %lld as requested.", 1100 audio ? "audio" : "video", 1101 mediaTimeUs); 1102 1103 reply->post(); 1104 return; 1105 } 1106 1107 skipUntilMediaTimeUs = -1; 1108 } 1109 1110 mRenderer->queueBuffer(audio, buffer, reply); 1111} 1112 1113void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) { 1114 if (mDriver == NULL) { 1115 return; 1116 } 1117 1118 sp<NuPlayerDriver> driver = mDriver.promote(); 1119 1120 if (driver == NULL) { 1121 return; 1122 } 1123 1124 driver->notifyListener(msg, ext1, ext2, in); 1125} 1126 1127void NuPlayer::flushDecoder(bool audio, bool needShutdown) { 1128 ALOGV("[%s] flushDecoder needShutdown=%d", 1129 audio ? "audio" : "video", needShutdown); 1130 1131 if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) { 1132 ALOGI("flushDecoder %s without decoder present", 1133 audio ? "audio" : "video"); 1134 } 1135 1136 // Make sure we don't continue to scan sources until we finish flushing. 1137 ++mScanSourcesGeneration; 1138 mScanSourcesPending = false; 1139 1140 (audio ? mAudioDecoder : mVideoDecoder)->signalFlush(); 1141 mRenderer->flush(audio); 1142 1143 FlushStatus newStatus = 1144 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER; 1145 1146 if (audio) { 1147 CHECK(mFlushingAudio == NONE 1148 || mFlushingAudio == AWAITING_DISCONTINUITY); 1149 1150 mFlushingAudio = newStatus; 1151 1152 if (mFlushingVideo == NONE) { 1153 mFlushingVideo = (mVideoDecoder != NULL) 1154 ? AWAITING_DISCONTINUITY 1155 : FLUSHED; 1156 } 1157 } else { 1158 CHECK(mFlushingVideo == NONE 1159 || mFlushingVideo == AWAITING_DISCONTINUITY); 1160 1161 mFlushingVideo = newStatus; 1162 1163 if (mFlushingAudio == NONE) { 1164 mFlushingAudio = (mAudioDecoder != NULL) 1165 ? AWAITING_DISCONTINUITY 1166 : FLUSHED; 1167 } 1168 } 1169} 1170 1171sp<AMessage> NuPlayer::Source::getFormat(bool audio) { 1172 sp<MetaData> meta = getFormatMeta(audio); 1173 1174 if (meta == NULL) { 1175 return NULL; 1176 } 1177 1178 sp<AMessage> msg = new AMessage; 1179 1180 if(convertMetaDataToMessage(meta, &msg) == OK) { 1181 return msg; 1182 } 1183 return NULL; 1184} 1185 1186status_t NuPlayer::setVideoScalingMode(int32_t mode) { 1187 mVideoScalingMode = mode; 1188 if (mNativeWindow != NULL) { 1189 status_t ret = native_window_set_scaling_mode( 1190 mNativeWindow->getNativeWindow().get(), mVideoScalingMode); 1191 if (ret != OK) { 1192 ALOGE("Failed to set scaling mode (%d): %s", 1193 -ret, strerror(-ret)); 1194 return ret; 1195 } 1196 } 1197 return OK; 1198} 1199 1200status_t NuPlayer::getTrackInfo(Parcel* reply) const { 1201 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, id()); 1202 msg->setPointer("reply", reply); 1203 1204 sp<AMessage> response; 1205 status_t err = msg->postAndAwaitResponse(&response); 1206 return err; 1207} 1208 1209status_t NuPlayer::selectTrack(size_t trackIndex, bool select) { 1210 sp<AMessage> msg = new AMessage(kWhatSelectTrack, id()); 1211 msg->setSize("trackIndex", trackIndex); 1212 msg->setInt32("select", select); 1213 1214 sp<AMessage> response; 1215 status_t err = msg->postAndAwaitResponse(&response); 1216 1217 return err; 1218} 1219 1220void NuPlayer::schedulePollDuration() { 1221 sp<AMessage> msg = new AMessage(kWhatPollDuration, id()); 1222 msg->setInt32("generation", mPollDurationGeneration); 1223 msg->post(); 1224} 1225 1226void NuPlayer::cancelPollDuration() { 1227 ++mPollDurationGeneration; 1228} 1229 1230void NuPlayer::processDeferredActions() { 1231 while (!mDeferredActions.empty()) { 1232 // We won't execute any deferred actions until we're no longer in 1233 // an intermediate state, i.e. one more more decoders are currently 1234 // flushing or shutting down. 1235 1236 if (mRenderer != NULL) { 1237 // There's an edge case where the renderer owns all output 1238 // buffers and is paused, therefore the decoder will not read 1239 // more input data and will never encounter the matching 1240 // discontinuity. To avoid this, we resume the renderer. 1241 1242 if (mFlushingAudio == AWAITING_DISCONTINUITY 1243 || mFlushingVideo == AWAITING_DISCONTINUITY) { 1244 mRenderer->resume(); 1245 } 1246 } 1247 1248 if (mFlushingAudio != NONE || mFlushingVideo != NONE) { 1249 // We're currently flushing, postpone the reset until that's 1250 // completed. 1251 1252 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d", 1253 mFlushingAudio, mFlushingVideo); 1254 1255 break; 1256 } 1257 1258 sp<Action> action = *mDeferredActions.begin(); 1259 mDeferredActions.erase(mDeferredActions.begin()); 1260 1261 action->execute(this); 1262 } 1263} 1264 1265void NuPlayer::performSeek(int64_t seekTimeUs) { 1266 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)", 1267 seekTimeUs, 1268 seekTimeUs / 1E6); 1269 1270 mSource->seekTo(seekTimeUs); 1271 1272 if (mDriver != NULL) { 1273 sp<NuPlayerDriver> driver = mDriver.promote(); 1274 if (driver != NULL) { 1275 driver->notifyPosition(seekTimeUs); 1276 driver->notifySeekComplete(); 1277 } 1278 } 1279 1280 // everything's flushed, continue playback. 1281} 1282 1283void NuPlayer::performDecoderFlush() { 1284 ALOGV("performDecoderFlush"); 1285 1286 if (mAudioDecoder == NULL && mVideoDecoder == NULL) { 1287 return; 1288 } 1289 1290 mTimeDiscontinuityPending = true; 1291 1292 if (mAudioDecoder != NULL) { 1293 flushDecoder(true /* audio */, false /* needShutdown */); 1294 } 1295 1296 if (mVideoDecoder != NULL) { 1297 flushDecoder(false /* audio */, false /* needShutdown */); 1298 } 1299} 1300 1301void NuPlayer::performDecoderShutdown(bool audio, bool video) { 1302 ALOGV("performDecoderShutdown audio=%d, video=%d", audio, video); 1303 1304 if ((!audio || mAudioDecoder == NULL) 1305 && (!video || mVideoDecoder == NULL)) { 1306 return; 1307 } 1308 1309 mTimeDiscontinuityPending = true; 1310 1311 if (mFlushingAudio == NONE && (!audio || mAudioDecoder == NULL)) { 1312 mFlushingAudio = FLUSHED; 1313 } 1314 1315 if (mFlushingVideo == NONE && (!video || mVideoDecoder == NULL)) { 1316 mFlushingVideo = FLUSHED; 1317 } 1318 1319 if (audio && mAudioDecoder != NULL) { 1320 flushDecoder(true /* audio */, true /* needShutdown */); 1321 } 1322 1323 if (video && mVideoDecoder != NULL) { 1324 flushDecoder(false /* audio */, true /* needShutdown */); 1325 } 1326} 1327 1328void NuPlayer::performReset() { 1329 ALOGV("performReset"); 1330 1331 CHECK(mAudioDecoder == NULL); 1332 CHECK(mVideoDecoder == NULL); 1333 1334 cancelPollDuration(); 1335 1336 ++mScanSourcesGeneration; 1337 mScanSourcesPending = false; 1338 1339 mRenderer.clear(); 1340 1341 if (mSource != NULL) { 1342 mSource->stop(); 1343 1344 looper()->unregisterHandler(mSource->id()); 1345 1346 mSource.clear(); 1347 } 1348 1349 if (mDriver != NULL) { 1350 sp<NuPlayerDriver> driver = mDriver.promote(); 1351 if (driver != NULL) { 1352 driver->notifyResetComplete(); 1353 } 1354 } 1355 1356 mStarted = false; 1357} 1358 1359void NuPlayer::performScanSources() { 1360 ALOGV("performScanSources"); 1361 1362 if (!mStarted) { 1363 return; 1364 } 1365 1366 if (mAudioDecoder == NULL || mVideoDecoder == NULL) { 1367 postScanSources(); 1368 } 1369} 1370 1371void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) { 1372 ALOGV("performSetSurface"); 1373 1374 mNativeWindow = wrapper; 1375 1376 // XXX - ignore error from setVideoScalingMode for now 1377 setVideoScalingMode(mVideoScalingMode); 1378 1379 if (mDriver != NULL) { 1380 sp<NuPlayerDriver> driver = mDriver.promote(); 1381 if (driver != NULL) { 1382 driver->notifySetSurfaceComplete(); 1383 } 1384 } 1385} 1386 1387void NuPlayer::onSourceNotify(const sp<AMessage> &msg) { 1388 int32_t what; 1389 CHECK(msg->findInt32("what", &what)); 1390 1391 switch (what) { 1392 case Source::kWhatPrepared: 1393 { 1394 if (mSource == NULL) { 1395 // This is a stale notification from a source that was 1396 // asynchronously preparing when the client called reset(). 1397 // We handled the reset, the source is gone. 1398 break; 1399 } 1400 1401 int32_t err; 1402 CHECK(msg->findInt32("err", &err)); 1403 1404 sp<NuPlayerDriver> driver = mDriver.promote(); 1405 if (driver != NULL) { 1406 driver->notifyPrepareCompleted(err); 1407 } 1408 1409 int64_t durationUs; 1410 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) { 1411 sp<NuPlayerDriver> driver = mDriver.promote(); 1412 if (driver != NULL) { 1413 driver->notifyDuration(durationUs); 1414 } 1415 } 1416 break; 1417 } 1418 1419 case Source::kWhatFlagsChanged: 1420 { 1421 uint32_t flags; 1422 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 1423 1424 sp<NuPlayerDriver> driver = mDriver.promote(); 1425 if (driver != NULL) { 1426 driver->notifyFlagsChanged(flags); 1427 } 1428 1429 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION) 1430 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) { 1431 cancelPollDuration(); 1432 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION) 1433 && (flags & Source::FLAG_DYNAMIC_DURATION) 1434 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { 1435 schedulePollDuration(); 1436 } 1437 1438 mSourceFlags = flags; 1439 break; 1440 } 1441 1442 case Source::kWhatVideoSizeChanged: 1443 { 1444 int32_t width, height; 1445 CHECK(msg->findInt32("width", &width)); 1446 CHECK(msg->findInt32("height", &height)); 1447 1448 notifyListener(MEDIA_SET_VIDEO_SIZE, width, height); 1449 break; 1450 } 1451 1452 case Source::kWhatBufferingStart: 1453 { 1454 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0); 1455 break; 1456 } 1457 1458 case Source::kWhatBufferingEnd: 1459 { 1460 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0); 1461 break; 1462 } 1463 1464 case Source::kWhatSubtitleData: 1465 { 1466 sp<ABuffer> buffer; 1467 CHECK(msg->findBuffer("buffer", &buffer)); 1468 1469 int32_t trackIndex; 1470 int64_t timeUs, durationUs; 1471 CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex)); 1472 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 1473 CHECK(buffer->meta()->findInt64("durationUs", &durationUs)); 1474 1475 Parcel in; 1476 in.writeInt32(trackIndex); 1477 in.writeInt64(timeUs); 1478 in.writeInt64(durationUs); 1479 in.writeInt32(buffer->size()); 1480 in.writeInt32(buffer->size()); 1481 in.write(buffer->data(), buffer->size()); 1482 1483 notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in); 1484 break; 1485 } 1486 1487 case Source::kWhatQueueDecoderShutdown: 1488 { 1489 int32_t audio, video; 1490 CHECK(msg->findInt32("audio", &audio)); 1491 CHECK(msg->findInt32("video", &video)); 1492 1493 sp<AMessage> reply; 1494 CHECK(msg->findMessage("reply", &reply)); 1495 1496 queueDecoderShutdown(audio, video, reply); 1497 break; 1498 } 1499 1500 default: 1501 TRESPASS(); 1502 } 1503} 1504 1505//////////////////////////////////////////////////////////////////////////////// 1506 1507void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) { 1508 sp<AMessage> notify = dupNotify(); 1509 notify->setInt32("what", kWhatFlagsChanged); 1510 notify->setInt32("flags", flags); 1511 notify->post(); 1512} 1513 1514void NuPlayer::Source::notifyVideoSizeChanged(int32_t width, int32_t height) { 1515 sp<AMessage> notify = dupNotify(); 1516 notify->setInt32("what", kWhatVideoSizeChanged); 1517 notify->setInt32("width", width); 1518 notify->setInt32("height", height); 1519 notify->post(); 1520} 1521 1522void NuPlayer::Source::notifyPrepared(status_t err) { 1523 sp<AMessage> notify = dupNotify(); 1524 notify->setInt32("what", kWhatPrepared); 1525 notify->setInt32("err", err); 1526 notify->post(); 1527} 1528 1529void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) { 1530 TRESPASS(); 1531} 1532 1533void NuPlayer::queueDecoderShutdown( 1534 bool audio, bool video, const sp<AMessage> &reply) { 1535 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video); 1536 1537 mDeferredActions.push_back( 1538 new ShutdownDecoderAction(audio, video)); 1539 1540 mDeferredActions.push_back( 1541 new SimpleAction(&NuPlayer::performScanSources)); 1542 1543 mDeferredActions.push_back(new PostMessageAction(reply)); 1544 1545 processDeferredActions(); 1546} 1547 1548} // namespace android 1549