NuPlayer.cpp revision 2f6d8c555f235181ef954757aea9f2badbcdfa3c
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "NuPlayer" 19 20#include <inttypes.h> 21 22#include <utils/Log.h> 23 24#include "NuPlayer.h" 25 26#include "HTTPLiveSource.h" 27#include "NuPlayerCCDecoder.h" 28#include "NuPlayerDecoder.h" 29#include "NuPlayerDecoderBase.h" 30#include "NuPlayerDecoderPassThrough.h" 31#include "NuPlayerDriver.h" 32#include "NuPlayerRenderer.h" 33#include "NuPlayerSource.h" 34#include "RTSPSource.h" 35#include "StreamingSource.h" 36#include "GenericSource.h" 37#include "TextDescriptions.h" 38 39#include "ATSParser.h" 40 41#include <cutils/properties.h> 42 43#include <media/AudioResamplerPublic.h> 44#include <media/AVSyncSettings.h> 45#include <media/MediaCodecBuffer.h> 46 47#include <media/stagefright/foundation/hexdump.h> 48#include <media/stagefright/foundation/ABuffer.h> 49#include <media/stagefright/foundation/ADebug.h> 50#include <media/stagefright/foundation/AMessage.h> 51#include <media/stagefright/MediaBuffer.h> 52#include <media/stagefright/MediaDefs.h> 53#include <media/stagefright/MediaErrors.h> 54#include <media/stagefright/MetaData.h> 55 56#include <gui/IGraphicBufferProducer.h> 57#include <gui/Surface.h> 58 59#include "avc_utils.h" 60 61#include "ESDS.h" 62#include <media/stagefright/Utils.h> 63 64namespace android { 65 66struct NuPlayer::Action : public RefBase { 67 Action() {} 68 69 virtual void execute(NuPlayer *player) = 0; 70 71private: 72 DISALLOW_EVIL_CONSTRUCTORS(Action); 73}; 74 75struct NuPlayer::SeekAction : public Action { 76 explicit SeekAction(int64_t seekTimeUs, MediaPlayerSeekMode mode) 77 : mSeekTimeUs(seekTimeUs), 78 mMode(mode) { 79 } 80 81 virtual void execute(NuPlayer *player) { 82 player->performSeek(mSeekTimeUs, mMode); 83 } 84 85private: 86 int64_t mSeekTimeUs; 87 MediaPlayerSeekMode mMode; 88 89 DISALLOW_EVIL_CONSTRUCTORS(SeekAction); 90}; 91 92struct NuPlayer::ResumeDecoderAction : public Action { 93 explicit ResumeDecoderAction(bool needNotify) 94 : mNeedNotify(needNotify) { 95 } 96 97 virtual void execute(NuPlayer *player) { 98 player->performResumeDecoders(mNeedNotify); 99 } 100 101private: 102 bool mNeedNotify; 103 104 DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction); 105}; 106 107struct NuPlayer::SetSurfaceAction : public Action { 108 explicit SetSurfaceAction(const sp<Surface> &surface) 109 : mSurface(surface) { 110 } 111 112 virtual void execute(NuPlayer *player) { 113 player->performSetSurface(mSurface); 114 } 115 116private: 117 sp<Surface> mSurface; 118 119 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction); 120}; 121 122struct NuPlayer::FlushDecoderAction : public Action { 123 FlushDecoderAction(FlushCommand audio, FlushCommand video) 124 : mAudio(audio), 125 mVideo(video) { 126 } 127 128 virtual void execute(NuPlayer *player) { 129 player->performDecoderFlush(mAudio, mVideo); 130 } 131 132private: 133 FlushCommand mAudio; 134 FlushCommand mVideo; 135 136 DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction); 137}; 138 139struct NuPlayer::PostMessageAction : public Action { 140 explicit PostMessageAction(const sp<AMessage> &msg) 141 : mMessage(msg) { 142 } 143 144 virtual void execute(NuPlayer *) { 145 mMessage->post(); 146 } 147 148private: 149 sp<AMessage> mMessage; 150 151 DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction); 152}; 153 154// Use this if there's no state necessary to save in order to execute 155// the action. 156struct NuPlayer::SimpleAction : public Action { 157 typedef void (NuPlayer::*ActionFunc)(); 158 159 explicit SimpleAction(ActionFunc func) 160 : mFunc(func) { 161 } 162 163 virtual void execute(NuPlayer *player) { 164 (player->*mFunc)(); 165 } 166 167private: 168 ActionFunc mFunc; 169 170 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction); 171}; 172 173//////////////////////////////////////////////////////////////////////////////// 174 175NuPlayer::NuPlayer(pid_t pid) 176 : mUIDValid(false), 177 mPID(pid), 178 mSourceFlags(0), 179 mOffloadAudio(false), 180 mAudioDecoderGeneration(0), 181 mVideoDecoderGeneration(0), 182 mRendererGeneration(0), 183 mPreviousSeekTimeUs(0), 184 mAudioEOS(false), 185 mVideoEOS(false), 186 mScanSourcesPending(false), 187 mScanSourcesGeneration(0), 188 mPollDurationGeneration(0), 189 mTimedTextGeneration(0), 190 mFlushingAudio(NONE), 191 mFlushingVideo(NONE), 192 mResumePending(false), 193 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW), 194 mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT), 195 mVideoFpsHint(-1.f), 196 mStarted(false), 197 mPrepared(false), 198 mResetting(false), 199 mSourceStarted(false), 200 mAudioDecoderError(false), 201 mVideoDecoderError(false), 202 mPaused(false), 203 mPausedByClient(true), 204 mPausedForBuffering(false), 205 mIsDrmProtected(false) { 206 clearFlushComplete(); 207} 208 209NuPlayer::~NuPlayer() { 210} 211 212void NuPlayer::setUID(uid_t uid) { 213 mUIDValid = true; 214 mUID = uid; 215} 216 217void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) { 218 mDriver = driver; 219} 220 221void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) { 222 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this); 223 224 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this); 225 226 msg->setObject("source", new StreamingSource(notify, source)); 227 msg->post(); 228} 229 230static bool IsHTTPLiveURL(const char *url) { 231 if (!strncasecmp("http://", url, 7) 232 || !strncasecmp("https://", url, 8) 233 || !strncasecmp("file://", url, 7)) { 234 size_t len = strlen(url); 235 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) { 236 return true; 237 } 238 239 if (strstr(url,"m3u8")) { 240 return true; 241 } 242 } 243 244 return false; 245} 246 247void NuPlayer::setDataSourceAsync( 248 const sp<IMediaHTTPService> &httpService, 249 const char *url, 250 const KeyedVector<String8, String8> *headers) { 251 252 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this); 253 size_t len = strlen(url); 254 255 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this); 256 257 sp<Source> source; 258 if (IsHTTPLiveURL(url)) { 259 source = new HTTPLiveSource(notify, httpService, url, headers); 260 ALOGV("setDataSourceAsync HTTPLiveSource %s", url); 261 } else if (!strncasecmp(url, "rtsp://", 7)) { 262 source = new RTSPSource( 263 notify, httpService, url, headers, mUIDValid, mUID); 264 ALOGV("setDataSourceAsync RTSPSource %s", url); 265 } else if ((!strncasecmp(url, "http://", 7) 266 || !strncasecmp(url, "https://", 8)) 267 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) 268 || strstr(url, ".sdp?"))) { 269 source = new RTSPSource( 270 notify, httpService, url, headers, mUIDValid, mUID, true); 271 ALOGV("setDataSourceAsync RTSPSource http/https/.sdp %s", url); 272 } else { 273 ALOGV("setDataSourceAsync GenericSource %s", url); 274 275 sp<GenericSource> genericSource = 276 new GenericSource(notify, mUIDValid, mUID); 277 278 status_t err = genericSource->setDataSource(httpService, url, headers); 279 280 if (err == OK) { 281 source = genericSource; 282 } else { 283 ALOGE("Failed to set data source!"); 284 } 285 } 286 msg->setObject("source", source); 287 msg->post(); 288} 289 290void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) { 291 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this); 292 293 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this); 294 295 sp<GenericSource> source = 296 new GenericSource(notify, mUIDValid, mUID); 297 298 ALOGV("setDataSourceAsync fd %d/%lld/%lld source: %p", 299 fd, (long long)offset, (long long)length, source.get()); 300 301 status_t err = source->setDataSource(fd, offset, length); 302 303 if (err != OK) { 304 ALOGE("Failed to set data source!"); 305 source = NULL; 306 } 307 308 msg->setObject("source", source); 309 msg->post(); 310} 311 312void NuPlayer::setDataSourceAsync(const sp<DataSource> &dataSource) { 313 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this); 314 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this); 315 316 sp<GenericSource> source = new GenericSource(notify, mUIDValid, mUID); 317 status_t err = source->setDataSource(dataSource); 318 319 if (err != OK) { 320 ALOGE("Failed to set data source!"); 321 source = NULL; 322 } 323 324 msg->setObject("source", source); 325 msg->post(); 326} 327 328status_t NuPlayer::getDefaultBufferingSettings( 329 BufferingSettings *buffering /* nonnull */) { 330 sp<AMessage> msg = new AMessage(kWhatGetDefaultBufferingSettings, this); 331 sp<AMessage> response; 332 status_t err = msg->postAndAwaitResponse(&response); 333 if (err == OK && response != NULL) { 334 CHECK(response->findInt32("err", &err)); 335 if (err == OK) { 336 readFromAMessage(response, buffering); 337 } 338 } 339 return err; 340} 341 342status_t NuPlayer::setBufferingSettings(const BufferingSettings& buffering) { 343 sp<AMessage> msg = new AMessage(kWhatSetBufferingSettings, this); 344 writeToAMessage(msg, buffering); 345 sp<AMessage> response; 346 status_t err = msg->postAndAwaitResponse(&response); 347 if (err == OK && response != NULL) { 348 CHECK(response->findInt32("err", &err)); 349 } 350 return err; 351} 352 353void NuPlayer::prepareAsync() { 354 ALOGV("prepareAsync"); 355 356 (new AMessage(kWhatPrepare, this))->post(); 357} 358 359void NuPlayer::setVideoSurfaceTextureAsync( 360 const sp<IGraphicBufferProducer> &bufferProducer) { 361 sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this); 362 363 if (bufferProducer == NULL) { 364 msg->setObject("surface", NULL); 365 } else { 366 msg->setObject("surface", new Surface(bufferProducer, true /* controlledByApp */)); 367 } 368 369 msg->post(); 370} 371 372void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) { 373 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this); 374 msg->setObject("sink", sink); 375 msg->post(); 376} 377 378void NuPlayer::start() { 379 (new AMessage(kWhatStart, this))->post(); 380} 381 382status_t NuPlayer::setPlaybackSettings(const AudioPlaybackRate &rate) { 383 // do some cursory validation of the settings here. audio modes are 384 // only validated when set on the audiosink. 385 if ((rate.mSpeed != 0.f && rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN) 386 || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX 387 || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN 388 || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) { 389 return BAD_VALUE; 390 } 391 sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this); 392 writeToAMessage(msg, rate); 393 sp<AMessage> response; 394 status_t err = msg->postAndAwaitResponse(&response); 395 if (err == OK && response != NULL) { 396 CHECK(response->findInt32("err", &err)); 397 } 398 return err; 399} 400 401status_t NuPlayer::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) { 402 sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this); 403 sp<AMessage> response; 404 status_t err = msg->postAndAwaitResponse(&response); 405 if (err == OK && response != NULL) { 406 CHECK(response->findInt32("err", &err)); 407 if (err == OK) { 408 readFromAMessage(response, rate); 409 } 410 } 411 return err; 412} 413 414status_t NuPlayer::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) { 415 sp<AMessage> msg = new AMessage(kWhatConfigSync, this); 416 writeToAMessage(msg, sync, videoFpsHint); 417 sp<AMessage> response; 418 status_t err = msg->postAndAwaitResponse(&response); 419 if (err == OK && response != NULL) { 420 CHECK(response->findInt32("err", &err)); 421 } 422 return err; 423} 424 425status_t NuPlayer::getSyncSettings( 426 AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) { 427 sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this); 428 sp<AMessage> response; 429 status_t err = msg->postAndAwaitResponse(&response); 430 if (err == OK && response != NULL) { 431 CHECK(response->findInt32("err", &err)); 432 if (err == OK) { 433 readFromAMessage(response, sync, videoFps); 434 } 435 } 436 return err; 437} 438 439void NuPlayer::pause() { 440 (new AMessage(kWhatPause, this))->post(); 441} 442 443void NuPlayer::resetAsync() { 444 sp<Source> source; 445 { 446 Mutex::Autolock autoLock(mSourceLock); 447 source = mSource; 448 } 449 450 if (source != NULL) { 451 // During a reset, the data source might be unresponsive already, we need to 452 // disconnect explicitly so that reads exit promptly. 453 // We can't queue the disconnect request to the looper, as it might be 454 // queued behind a stuck read and never gets processed. 455 // Doing a disconnect outside the looper to allows the pending reads to exit 456 // (either successfully or with error). 457 source->disconnect(); 458 } 459 460 (new AMessage(kWhatReset, this))->post(); 461} 462 463void NuPlayer::seekToAsync(int64_t seekTimeUs, MediaPlayerSeekMode mode, bool needNotify) { 464 sp<AMessage> msg = new AMessage(kWhatSeek, this); 465 msg->setInt64("seekTimeUs", seekTimeUs); 466 msg->setInt32("mode", mode); 467 msg->setInt32("needNotify", needNotify); 468 msg->post(); 469} 470 471 472void NuPlayer::writeTrackInfo( 473 Parcel* reply, const sp<AMessage>& format) const { 474 if (format == NULL) { 475 ALOGE("NULL format"); 476 return; 477 } 478 int32_t trackType; 479 if (!format->findInt32("type", &trackType)) { 480 ALOGE("no track type"); 481 return; 482 } 483 484 AString mime; 485 if (!format->findString("mime", &mime)) { 486 // Java MediaPlayer only uses mimetype for subtitle and timedtext tracks. 487 // If we can't find the mimetype here it means that we wouldn't be needing 488 // the mimetype on the Java end. We still write a placeholder mime to keep the 489 // (de)serialization logic simple. 490 if (trackType == MEDIA_TRACK_TYPE_AUDIO) { 491 mime = "audio/"; 492 } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) { 493 mime = "video/"; 494 } else { 495 ALOGE("unknown track type: %d", trackType); 496 return; 497 } 498 } 499 500 AString lang; 501 if (!format->findString("language", &lang)) { 502 ALOGE("no language"); 503 return; 504 } 505 506 reply->writeInt32(2); // write something non-zero 507 reply->writeInt32(trackType); 508 reply->writeString16(String16(mime.c_str())); 509 reply->writeString16(String16(lang.c_str())); 510 511 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) { 512 int32_t isAuto, isDefault, isForced; 513 CHECK(format->findInt32("auto", &isAuto)); 514 CHECK(format->findInt32("default", &isDefault)); 515 CHECK(format->findInt32("forced", &isForced)); 516 517 reply->writeInt32(isAuto); 518 reply->writeInt32(isDefault); 519 reply->writeInt32(isForced); 520 } 521} 522 523void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { 524 switch (msg->what()) { 525 case kWhatSetDataSource: 526 { 527 ALOGV("kWhatSetDataSource"); 528 529 CHECK(mSource == NULL); 530 531 status_t err = OK; 532 sp<RefBase> obj; 533 CHECK(msg->findObject("source", &obj)); 534 if (obj != NULL) { 535 Mutex::Autolock autoLock(mSourceLock); 536 mSource = static_cast<Source *>(obj.get()); 537 } else { 538 err = UNKNOWN_ERROR; 539 } 540 541 CHECK(mDriver != NULL); 542 sp<NuPlayerDriver> driver = mDriver.promote(); 543 if (driver != NULL) { 544 driver->notifySetDataSourceCompleted(err); 545 } 546 break; 547 } 548 549 case kWhatGetDefaultBufferingSettings: 550 { 551 sp<AReplyToken> replyID; 552 CHECK(msg->senderAwaitsResponse(&replyID)); 553 554 ALOGV("kWhatGetDefaultBufferingSettings"); 555 BufferingSettings buffering; 556 status_t err = OK; 557 if (mSource != NULL) { 558 err = mSource->getDefaultBufferingSettings(&buffering); 559 } else { 560 err = INVALID_OPERATION; 561 } 562 sp<AMessage> response = new AMessage; 563 if (err == OK) { 564 writeToAMessage(response, buffering); 565 } 566 response->setInt32("err", err); 567 response->postReply(replyID); 568 break; 569 } 570 571 case kWhatSetBufferingSettings: 572 { 573 sp<AReplyToken> replyID; 574 CHECK(msg->senderAwaitsResponse(&replyID)); 575 576 ALOGV("kWhatSetBufferingSettings"); 577 BufferingSettings buffering; 578 readFromAMessage(msg, &buffering); 579 status_t err = OK; 580 if (mSource != NULL) { 581 err = mSource->setBufferingSettings(buffering); 582 } else { 583 err = INVALID_OPERATION; 584 } 585 sp<AMessage> response = new AMessage; 586 response->setInt32("err", err); 587 response->postReply(replyID); 588 break; 589 } 590 591 case kWhatPrepare: 592 { 593 ALOGV("onMessageReceived kWhatPrepare"); 594 595 mSource->prepareAsync(); 596 break; 597 } 598 599 case kWhatGetTrackInfo: 600 { 601 sp<AReplyToken> replyID; 602 CHECK(msg->senderAwaitsResponse(&replyID)); 603 604 Parcel* reply; 605 CHECK(msg->findPointer("reply", (void**)&reply)); 606 607 size_t inbandTracks = 0; 608 if (mSource != NULL) { 609 inbandTracks = mSource->getTrackCount(); 610 } 611 612 size_t ccTracks = 0; 613 if (mCCDecoder != NULL) { 614 ccTracks = mCCDecoder->getTrackCount(); 615 } 616 617 // total track count 618 reply->writeInt32(inbandTracks + ccTracks); 619 620 // write inband tracks 621 for (size_t i = 0; i < inbandTracks; ++i) { 622 writeTrackInfo(reply, mSource->getTrackInfo(i)); 623 } 624 625 // write CC track 626 for (size_t i = 0; i < ccTracks; ++i) { 627 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i)); 628 } 629 630 sp<AMessage> response = new AMessage; 631 response->postReply(replyID); 632 break; 633 } 634 635 case kWhatGetSelectedTrack: 636 { 637 status_t err = INVALID_OPERATION; 638 if (mSource != NULL) { 639 err = OK; 640 641 int32_t type32; 642 CHECK(msg->findInt32("type", (int32_t*)&type32)); 643 media_track_type type = (media_track_type)type32; 644 ssize_t selectedTrack = mSource->getSelectedTrack(type); 645 646 Parcel* reply; 647 CHECK(msg->findPointer("reply", (void**)&reply)); 648 reply->writeInt32(selectedTrack); 649 } 650 651 sp<AMessage> response = new AMessage; 652 response->setInt32("err", err); 653 654 sp<AReplyToken> replyID; 655 CHECK(msg->senderAwaitsResponse(&replyID)); 656 response->postReply(replyID); 657 break; 658 } 659 660 case kWhatSelectTrack: 661 { 662 sp<AReplyToken> replyID; 663 CHECK(msg->senderAwaitsResponse(&replyID)); 664 665 size_t trackIndex; 666 int32_t select; 667 int64_t timeUs; 668 CHECK(msg->findSize("trackIndex", &trackIndex)); 669 CHECK(msg->findInt32("select", &select)); 670 CHECK(msg->findInt64("timeUs", &timeUs)); 671 672 status_t err = INVALID_OPERATION; 673 674 size_t inbandTracks = 0; 675 if (mSource != NULL) { 676 inbandTracks = mSource->getTrackCount(); 677 } 678 size_t ccTracks = 0; 679 if (mCCDecoder != NULL) { 680 ccTracks = mCCDecoder->getTrackCount(); 681 } 682 683 if (trackIndex < inbandTracks) { 684 err = mSource->selectTrack(trackIndex, select, timeUs); 685 686 if (!select && err == OK) { 687 int32_t type; 688 sp<AMessage> info = mSource->getTrackInfo(trackIndex); 689 if (info != NULL 690 && info->findInt32("type", &type) 691 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) { 692 ++mTimedTextGeneration; 693 } 694 } 695 } else { 696 trackIndex -= inbandTracks; 697 698 if (trackIndex < ccTracks) { 699 err = mCCDecoder->selectTrack(trackIndex, select); 700 } 701 } 702 703 sp<AMessage> response = new AMessage; 704 response->setInt32("err", err); 705 706 response->postReply(replyID); 707 break; 708 } 709 710 case kWhatPollDuration: 711 { 712 int32_t generation; 713 CHECK(msg->findInt32("generation", &generation)); 714 715 if (generation != mPollDurationGeneration) { 716 // stale 717 break; 718 } 719 720 int64_t durationUs; 721 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) { 722 sp<NuPlayerDriver> driver = mDriver.promote(); 723 if (driver != NULL) { 724 driver->notifyDuration(durationUs); 725 } 726 } 727 728 msg->post(1000000ll); // poll again in a second. 729 break; 730 } 731 732 case kWhatSetVideoSurface: 733 { 734 735 sp<RefBase> obj; 736 CHECK(msg->findObject("surface", &obj)); 737 sp<Surface> surface = static_cast<Surface *>(obj.get()); 738 739 ALOGD("onSetVideoSurface(%p, %s video decoder)", 740 surface.get(), 741 (mSource != NULL && mStarted && mSource->getFormat(false /* audio */) != NULL 742 && mVideoDecoder != NULL) ? "have" : "no"); 743 744 // Need to check mStarted before calling mSource->getFormat because NuPlayer might 745 // be in preparing state and it could take long time. 746 // When mStarted is true, mSource must have been set. 747 if (mSource == NULL || !mStarted || mSource->getFormat(false /* audio */) == NULL 748 // NOTE: mVideoDecoder's mSurface is always non-null 749 || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(surface) == OK)) { 750 performSetSurface(surface); 751 break; 752 } 753 754 mDeferredActions.push_back( 755 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */, 756 FLUSH_CMD_SHUTDOWN /* video */)); 757 758 mDeferredActions.push_back(new SetSurfaceAction(surface)); 759 760 if (obj != NULL || mAudioDecoder != NULL) { 761 if (mStarted) { 762 // Issue a seek to refresh the video screen only if started otherwise 763 // the extractor may not yet be started and will assert. 764 // If the video decoder is not set (perhaps audio only in this case) 765 // do not perform a seek as it is not needed. 766 int64_t currentPositionUs = 0; 767 if (getCurrentPosition(¤tPositionUs) == OK) { 768 mDeferredActions.push_back( 769 new SeekAction(currentPositionUs, 770 MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */)); 771 } 772 } 773 774 // If there is a new surface texture, instantiate decoders 775 // again if possible. 776 mDeferredActions.push_back( 777 new SimpleAction(&NuPlayer::performScanSources)); 778 } 779 780 // After a flush without shutdown, decoder is paused. 781 // Don't resume it until source seek is done, otherwise it could 782 // start pulling stale data too soon. 783 mDeferredActions.push_back( 784 new ResumeDecoderAction(false /* needNotify */)); 785 786 processDeferredActions(); 787 break; 788 } 789 790 case kWhatSetAudioSink: 791 { 792 ALOGV("kWhatSetAudioSink"); 793 794 sp<RefBase> obj; 795 CHECK(msg->findObject("sink", &obj)); 796 797 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get()); 798 break; 799 } 800 801 case kWhatStart: 802 { 803 ALOGV("kWhatStart"); 804 if (mStarted) { 805 // do not resume yet if the source is still buffering 806 if (!mPausedForBuffering) { 807 onResume(); 808 } 809 } else { 810 onStart(); 811 } 812 mPausedByClient = false; 813 break; 814 } 815 816 case kWhatConfigPlayback: 817 { 818 sp<AReplyToken> replyID; 819 CHECK(msg->senderAwaitsResponse(&replyID)); 820 AudioPlaybackRate rate /* sanitized */; 821 readFromAMessage(msg, &rate); 822 status_t err = OK; 823 if (mRenderer != NULL) { 824 // AudioSink allows only 1.f and 0.f for offload mode. 825 // For other speed, switch to non-offload mode. 826 if (mOffloadAudio && ((rate.mSpeed != 0.f && rate.mSpeed != 1.f) 827 || rate.mPitch != 1.f)) { 828 int64_t currentPositionUs; 829 if (getCurrentPosition(¤tPositionUs) != OK) { 830 currentPositionUs = mPreviousSeekTimeUs; 831 } 832 833 // Set mPlaybackSettings so that the new audio decoder can 834 // be created correctly. 835 mPlaybackSettings = rate; 836 if (!mPaused) { 837 mRenderer->pause(); 838 } 839 restartAudio( 840 currentPositionUs, true /* forceNonOffload */, 841 true /* needsToCreateAudioDecoder */); 842 if (!mPaused) { 843 mRenderer->resume(); 844 } 845 } 846 847 err = mRenderer->setPlaybackSettings(rate); 848 } 849 if (err == OK) { 850 if (rate.mSpeed == 0.f) { 851 onPause(); 852 mPausedByClient = true; 853 // save all other settings (using non-paused speed) 854 // so we can restore them on start 855 AudioPlaybackRate newRate = rate; 856 newRate.mSpeed = mPlaybackSettings.mSpeed; 857 mPlaybackSettings = newRate; 858 } else { /* rate.mSpeed != 0.f */ 859 mPlaybackSettings = rate; 860 if (mStarted) { 861 // do not resume yet if the source is still buffering 862 if (!mPausedForBuffering) { 863 onResume(); 864 } 865 } else if (mPrepared) { 866 onStart(); 867 } 868 869 mPausedByClient = false; 870 } 871 } 872 873 if (mVideoDecoder != NULL) { 874 sp<AMessage> params = new AMessage(); 875 params->setFloat("playback-speed", mPlaybackSettings.mSpeed); 876 mVideoDecoder->setParameters(params); 877 } 878 879 sp<AMessage> response = new AMessage; 880 response->setInt32("err", err); 881 response->postReply(replyID); 882 break; 883 } 884 885 case kWhatGetPlaybackSettings: 886 { 887 sp<AReplyToken> replyID; 888 CHECK(msg->senderAwaitsResponse(&replyID)); 889 AudioPlaybackRate rate = mPlaybackSettings; 890 status_t err = OK; 891 if (mRenderer != NULL) { 892 err = mRenderer->getPlaybackSettings(&rate); 893 } 894 if (err == OK) { 895 // get playback settings used by renderer, as it may be 896 // slightly off due to audiosink not taking small changes. 897 mPlaybackSettings = rate; 898 if (mPaused) { 899 rate.mSpeed = 0.f; 900 } 901 } 902 sp<AMessage> response = new AMessage; 903 if (err == OK) { 904 writeToAMessage(response, rate); 905 } 906 response->setInt32("err", err); 907 response->postReply(replyID); 908 break; 909 } 910 911 case kWhatConfigSync: 912 { 913 sp<AReplyToken> replyID; 914 CHECK(msg->senderAwaitsResponse(&replyID)); 915 916 ALOGV("kWhatConfigSync"); 917 AVSyncSettings sync; 918 float videoFpsHint; 919 readFromAMessage(msg, &sync, &videoFpsHint); 920 status_t err = OK; 921 if (mRenderer != NULL) { 922 err = mRenderer->setSyncSettings(sync, videoFpsHint); 923 } 924 if (err == OK) { 925 mSyncSettings = sync; 926 mVideoFpsHint = videoFpsHint; 927 } 928 sp<AMessage> response = new AMessage; 929 response->setInt32("err", err); 930 response->postReply(replyID); 931 break; 932 } 933 934 case kWhatGetSyncSettings: 935 { 936 sp<AReplyToken> replyID; 937 CHECK(msg->senderAwaitsResponse(&replyID)); 938 AVSyncSettings sync = mSyncSettings; 939 float videoFps = mVideoFpsHint; 940 status_t err = OK; 941 if (mRenderer != NULL) { 942 err = mRenderer->getSyncSettings(&sync, &videoFps); 943 if (err == OK) { 944 mSyncSettings = sync; 945 mVideoFpsHint = videoFps; 946 } 947 } 948 sp<AMessage> response = new AMessage; 949 if (err == OK) { 950 writeToAMessage(response, sync, videoFps); 951 } 952 response->setInt32("err", err); 953 response->postReply(replyID); 954 break; 955 } 956 957 case kWhatScanSources: 958 { 959 int32_t generation; 960 CHECK(msg->findInt32("generation", &generation)); 961 if (generation != mScanSourcesGeneration) { 962 // Drop obsolete msg. 963 break; 964 } 965 966 mScanSourcesPending = false; 967 968 ALOGV("scanning sources haveAudio=%d, haveVideo=%d", 969 mAudioDecoder != NULL, mVideoDecoder != NULL); 970 971 bool mHadAnySourcesBefore = 972 (mAudioDecoder != NULL) || (mVideoDecoder != NULL); 973 bool rescan = false; 974 975 // initialize video before audio because successful initialization of 976 // video may change deep buffer mode of audio. 977 if (mSurface != NULL) { 978 if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) { 979 rescan = true; 980 } 981 } 982 983 // Don't try to re-open audio sink if there's an existing decoder. 984 if (mAudioSink != NULL && mAudioDecoder == NULL) { 985 if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) { 986 rescan = true; 987 } 988 } 989 990 if (!mHadAnySourcesBefore 991 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { 992 // This is the first time we've found anything playable. 993 994 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) { 995 schedulePollDuration(); 996 } 997 } 998 999 status_t err; 1000 if ((err = mSource->feedMoreTSData()) != OK) { 1001 if (mAudioDecoder == NULL && mVideoDecoder == NULL) { 1002 // We're not currently decoding anything (no audio or 1003 // video tracks found) and we just ran out of input data. 1004 1005 if (err == ERROR_END_OF_STREAM) { 1006 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); 1007 } else { 1008 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); 1009 } 1010 } 1011 break; 1012 } 1013 1014 if (rescan) { 1015 msg->post(100000ll); 1016 mScanSourcesPending = true; 1017 } 1018 break; 1019 } 1020 1021 case kWhatVideoNotify: 1022 case kWhatAudioNotify: 1023 { 1024 bool audio = msg->what() == kWhatAudioNotify; 1025 1026 int32_t currentDecoderGeneration = 1027 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration); 1028 int32_t requesterGeneration = currentDecoderGeneration - 1; 1029 CHECK(msg->findInt32("generation", &requesterGeneration)); 1030 1031 if (requesterGeneration != currentDecoderGeneration) { 1032 ALOGV("got message from old %s decoder, generation(%d:%d)", 1033 audio ? "audio" : "video", requesterGeneration, 1034 currentDecoderGeneration); 1035 sp<AMessage> reply; 1036 if (!(msg->findMessage("reply", &reply))) { 1037 return; 1038 } 1039 1040 reply->setInt32("err", INFO_DISCONTINUITY); 1041 reply->post(); 1042 return; 1043 } 1044 1045 int32_t what; 1046 CHECK(msg->findInt32("what", &what)); 1047 1048 if (what == DecoderBase::kWhatInputDiscontinuity) { 1049 int32_t formatChange; 1050 CHECK(msg->findInt32("formatChange", &formatChange)); 1051 1052 ALOGV("%s discontinuity: formatChange %d", 1053 audio ? "audio" : "video", formatChange); 1054 1055 if (formatChange) { 1056 mDeferredActions.push_back( 1057 new FlushDecoderAction( 1058 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE, 1059 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN)); 1060 } 1061 1062 mDeferredActions.push_back( 1063 new SimpleAction( 1064 &NuPlayer::performScanSources)); 1065 1066 processDeferredActions(); 1067 } else if (what == DecoderBase::kWhatEOS) { 1068 int32_t err; 1069 CHECK(msg->findInt32("err", &err)); 1070 1071 if (err == ERROR_END_OF_STREAM) { 1072 ALOGV("got %s decoder EOS", audio ? "audio" : "video"); 1073 } else { 1074 ALOGV("got %s decoder EOS w/ error %d", 1075 audio ? "audio" : "video", 1076 err); 1077 } 1078 1079 mRenderer->queueEOS(audio, err); 1080 } else if (what == DecoderBase::kWhatFlushCompleted) { 1081 ALOGV("decoder %s flush completed", audio ? "audio" : "video"); 1082 1083 handleFlushComplete(audio, true /* isDecoder */); 1084 finishFlushIfPossible(); 1085 } else if (what == DecoderBase::kWhatVideoSizeChanged) { 1086 sp<AMessage> format; 1087 CHECK(msg->findMessage("format", &format)); 1088 1089 sp<AMessage> inputFormat = 1090 mSource->getFormat(false /* audio */); 1091 1092 setVideoScalingMode(mVideoScalingMode); 1093 updateVideoSize(inputFormat, format); 1094 } else if (what == DecoderBase::kWhatShutdownCompleted) { 1095 ALOGV("%s shutdown completed", audio ? "audio" : "video"); 1096 if (audio) { 1097 mAudioDecoder.clear(); 1098 mAudioDecoderError = false; 1099 ++mAudioDecoderGeneration; 1100 1101 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER); 1102 mFlushingAudio = SHUT_DOWN; 1103 } else { 1104 mVideoDecoder.clear(); 1105 mVideoDecoderError = false; 1106 ++mVideoDecoderGeneration; 1107 1108 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER); 1109 mFlushingVideo = SHUT_DOWN; 1110 } 1111 1112 finishFlushIfPossible(); 1113 } else if (what == DecoderBase::kWhatResumeCompleted) { 1114 finishResume(); 1115 } else if (what == DecoderBase::kWhatError) { 1116 status_t err; 1117 if (!msg->findInt32("err", &err) || err == OK) { 1118 err = UNKNOWN_ERROR; 1119 } 1120 1121 // Decoder errors can be due to Source (e.g. from streaming), 1122 // or from decoding corrupted bitstreams, or from other decoder 1123 // MediaCodec operations (e.g. from an ongoing reset or seek). 1124 // They may also be due to openAudioSink failure at 1125 // decoder start or after a format change. 1126 // 1127 // We try to gracefully shut down the affected decoder if possible, 1128 // rather than trying to force the shutdown with something 1129 // similar to performReset(). This method can lead to a hang 1130 // if MediaCodec functions block after an error, but they should 1131 // typically return INVALID_OPERATION instead of blocking. 1132 1133 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo; 1134 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down", 1135 err, audio ? "audio" : "video", *flushing); 1136 1137 switch (*flushing) { 1138 case NONE: 1139 mDeferredActions.push_back( 1140 new FlushDecoderAction( 1141 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE, 1142 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN)); 1143 processDeferredActions(); 1144 break; 1145 case FLUSHING_DECODER: 1146 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush. 1147 break; // Wait for flush to complete. 1148 case FLUSHING_DECODER_SHUTDOWN: 1149 break; // Wait for flush to complete. 1150 case SHUTTING_DOWN_DECODER: 1151 break; // Wait for shutdown to complete. 1152 case FLUSHED: 1153 getDecoder(audio)->initiateShutdown(); // In the middle of a seek. 1154 *flushing = SHUTTING_DOWN_DECODER; // Shut down. 1155 break; 1156 case SHUT_DOWN: 1157 finishFlushIfPossible(); // Should not occur. 1158 break; // Finish anyways. 1159 } 1160 if (mSource != nullptr) { 1161 if (audio) { 1162 if (mVideoDecoderError || mSource->getFormat(false /* audio */) == NULL 1163 || mSurface == NULL) { 1164 // When both audio and video have error, or this stream has only audio 1165 // which has error, notify client of error. 1166 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); 1167 } else { 1168 // Only audio track has error. Video track could be still good to play. 1169 notifyListener(MEDIA_INFO, MEDIA_INFO_PLAY_AUDIO_ERROR, err); 1170 } 1171 mAudioDecoderError = true; 1172 } else { 1173 if (mAudioDecoderError || mSource->getFormat(true /* audio */) == NULL 1174 || mAudioSink == NULL) { 1175 // When both audio and video have error, or this stream has only video 1176 // which has error, notify client of error. 1177 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); 1178 } else { 1179 // Only video track has error. Audio track could be still good to play. 1180 notifyListener(MEDIA_INFO, MEDIA_INFO_PLAY_VIDEO_ERROR, err); 1181 } 1182 mVideoDecoderError = true; 1183 } 1184 } 1185 } else { 1186 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.", 1187 what, 1188 what >> 24, 1189 (what >> 16) & 0xff, 1190 (what >> 8) & 0xff, 1191 what & 0xff); 1192 } 1193 1194 break; 1195 } 1196 1197 case kWhatRendererNotify: 1198 { 1199 int32_t requesterGeneration = mRendererGeneration - 1; 1200 CHECK(msg->findInt32("generation", &requesterGeneration)); 1201 if (requesterGeneration != mRendererGeneration) { 1202 ALOGV("got message from old renderer, generation(%d:%d)", 1203 requesterGeneration, mRendererGeneration); 1204 return; 1205 } 1206 1207 int32_t what; 1208 CHECK(msg->findInt32("what", &what)); 1209 1210 if (what == Renderer::kWhatEOS) { 1211 int32_t audio; 1212 CHECK(msg->findInt32("audio", &audio)); 1213 1214 int32_t finalResult; 1215 CHECK(msg->findInt32("finalResult", &finalResult)); 1216 1217 if (audio) { 1218 mAudioEOS = true; 1219 } else { 1220 mVideoEOS = true; 1221 } 1222 1223 if (finalResult == ERROR_END_OF_STREAM) { 1224 ALOGV("reached %s EOS", audio ? "audio" : "video"); 1225 } else { 1226 ALOGE("%s track encountered an error (%d)", 1227 audio ? "audio" : "video", finalResult); 1228 1229 notifyListener( 1230 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult); 1231 } 1232 1233 if ((mAudioEOS || mAudioDecoder == NULL) 1234 && (mVideoEOS || mVideoDecoder == NULL)) { 1235 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); 1236 } 1237 } else if (what == Renderer::kWhatFlushComplete) { 1238 int32_t audio; 1239 CHECK(msg->findInt32("audio", &audio)); 1240 1241 if (audio) { 1242 mAudioEOS = false; 1243 } else { 1244 mVideoEOS = false; 1245 } 1246 1247 ALOGV("renderer %s flush completed.", audio ? "audio" : "video"); 1248 if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED 1249 || mFlushingAudio == SHUT_DOWN)) { 1250 // Flush has been handled by tear down. 1251 break; 1252 } 1253 handleFlushComplete(audio, false /* isDecoder */); 1254 finishFlushIfPossible(); 1255 } else if (what == Renderer::kWhatVideoRenderingStart) { 1256 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0); 1257 } else if (what == Renderer::kWhatMediaRenderingStart) { 1258 ALOGV("media rendering started"); 1259 notifyListener(MEDIA_STARTED, 0, 0); 1260 } else if (what == Renderer::kWhatAudioTearDown) { 1261 int32_t reason; 1262 CHECK(msg->findInt32("reason", &reason)); 1263 ALOGV("Tear down audio with reason %d.", reason); 1264 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) { 1265 // TimeoutWhenPaused is only for offload mode. 1266 ALOGW("Receive a stale message for teardown."); 1267 break; 1268 } 1269 int64_t positionUs; 1270 if (!msg->findInt64("positionUs", &positionUs)) { 1271 positionUs = mPreviousSeekTimeUs; 1272 } 1273 1274 restartAudio( 1275 positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */, 1276 reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */); 1277 } 1278 break; 1279 } 1280 1281 case kWhatMoreDataQueued: 1282 { 1283 break; 1284 } 1285 1286 case kWhatReset: 1287 { 1288 ALOGV("kWhatReset"); 1289 1290 mResetting = true; 1291 1292 mDeferredActions.push_back( 1293 new FlushDecoderAction( 1294 FLUSH_CMD_SHUTDOWN /* audio */, 1295 FLUSH_CMD_SHUTDOWN /* video */)); 1296 1297 mDeferredActions.push_back( 1298 new SimpleAction(&NuPlayer::performReset)); 1299 1300 processDeferredActions(); 1301 break; 1302 } 1303 1304 case kWhatSeek: 1305 { 1306 int64_t seekTimeUs; 1307 int32_t mode; 1308 int32_t needNotify; 1309 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs)); 1310 CHECK(msg->findInt32("mode", &mode)); 1311 CHECK(msg->findInt32("needNotify", &needNotify)); 1312 1313 ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d", 1314 (long long)seekTimeUs, mode, needNotify); 1315 1316 if (!mStarted) { 1317 // Seek before the player is started. In order to preview video, 1318 // need to start the player and pause it. This branch is called 1319 // only once if needed. After the player is started, any seek 1320 // operation will go through normal path. 1321 // Audio-only cases are handled separately. 1322 onStart(seekTimeUs, (MediaPlayerSeekMode)mode); 1323 if (mStarted) { 1324 onPause(); 1325 mPausedByClient = true; 1326 } 1327 if (needNotify) { 1328 notifyDriverSeekComplete(); 1329 } 1330 break; 1331 } 1332 1333 mDeferredActions.push_back( 1334 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */, 1335 FLUSH_CMD_FLUSH /* video */)); 1336 1337 mDeferredActions.push_back( 1338 new SeekAction(seekTimeUs, (MediaPlayerSeekMode)mode)); 1339 1340 // After a flush without shutdown, decoder is paused. 1341 // Don't resume it until source seek is done, otherwise it could 1342 // start pulling stale data too soon. 1343 mDeferredActions.push_back( 1344 new ResumeDecoderAction(needNotify)); 1345 1346 processDeferredActions(); 1347 break; 1348 } 1349 1350 case kWhatPause: 1351 { 1352 onPause(); 1353 mPausedByClient = true; 1354 break; 1355 } 1356 1357 case kWhatSourceNotify: 1358 { 1359 onSourceNotify(msg); 1360 break; 1361 } 1362 1363 case kWhatClosedCaptionNotify: 1364 { 1365 onClosedCaptionNotify(msg); 1366 break; 1367 } 1368 1369 case kWhatPrepareDrm: 1370 { 1371 status_t status = onPrepareDrm(msg); 1372 1373 sp<AMessage> response = new AMessage; 1374 response->setInt32("status", status); 1375 sp<AReplyToken> replyID; 1376 CHECK(msg->senderAwaitsResponse(&replyID)); 1377 response->postReply(replyID); 1378 break; 1379 } 1380 1381 case kWhatReleaseDrm: 1382 { 1383 status_t status = onReleaseDrm(); 1384 1385 sp<AMessage> response = new AMessage; 1386 response->setInt32("status", status); 1387 sp<AReplyToken> replyID; 1388 CHECK(msg->senderAwaitsResponse(&replyID)); 1389 response->postReply(replyID); 1390 break; 1391 } 1392 1393 default: 1394 TRESPASS(); 1395 break; 1396 } 1397} 1398 1399void NuPlayer::onResume() { 1400 if (!mPaused || mResetting) { 1401 ALOGD_IF(mResetting, "resetting, onResume discarded"); 1402 return; 1403 } 1404 mPaused = false; 1405 if (mSource != NULL) { 1406 mSource->resume(); 1407 } else { 1408 ALOGW("resume called when source is gone or not set"); 1409 } 1410 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if 1411 // needed. 1412 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) { 1413 instantiateDecoder(true /* audio */, &mAudioDecoder); 1414 } 1415 if (mRenderer != NULL) { 1416 mRenderer->resume(); 1417 } else { 1418 ALOGW("resume called when renderer is gone or not set"); 1419 } 1420 1421 mLastStartedPlayingTimeNs = systemTime(); 1422} 1423 1424status_t NuPlayer::onInstantiateSecureDecoders() { 1425 status_t err; 1426 if (!(mSourceFlags & Source::FLAG_SECURE)) { 1427 return BAD_TYPE; 1428 } 1429 1430 if (mRenderer != NULL) { 1431 ALOGE("renderer should not be set when instantiating secure decoders"); 1432 return UNKNOWN_ERROR; 1433 } 1434 1435 // TRICKY: We rely on mRenderer being null, so that decoder does not start requesting 1436 // data on instantiation. 1437 if (mSurface != NULL) { 1438 err = instantiateDecoder(false, &mVideoDecoder); 1439 if (err != OK) { 1440 return err; 1441 } 1442 } 1443 1444 if (mAudioSink != NULL) { 1445 err = instantiateDecoder(true, &mAudioDecoder); 1446 if (err != OK) { 1447 return err; 1448 } 1449 } 1450 return OK; 1451} 1452 1453void NuPlayer::onStart(int64_t startPositionUs, MediaPlayerSeekMode mode) { 1454 ALOGV("onStart: mCrypto: %p (%d)", mCrypto.get(), 1455 (mCrypto != NULL ? mCrypto->getStrongCount() : 0)); 1456 1457 if (!mSourceStarted) { 1458 mSourceStarted = true; 1459 mSource->start(); 1460 } 1461 if (startPositionUs > 0) { 1462 performSeek(startPositionUs, mode); 1463 if (mSource->getFormat(false /* audio */) == NULL) { 1464 return; 1465 } 1466 } 1467 1468 mOffloadAudio = false; 1469 mAudioEOS = false; 1470 mVideoEOS = false; 1471 mStarted = true; 1472 mPaused = false; 1473 1474 uint32_t flags = 0; 1475 1476 if (mSource->isRealTime()) { 1477 flags |= Renderer::FLAG_REAL_TIME; 1478 } 1479 1480 bool hasAudio = (mSource->getFormat(true /* audio */) != NULL); 1481 bool hasVideo = (mSource->getFormat(false /* audio */) != NULL); 1482 if (!hasAudio && !hasVideo) { 1483 ALOGE("no metadata for either audio or video source"); 1484 mSource->stop(); 1485 mSourceStarted = false; 1486 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_MALFORMED); 1487 return; 1488 } 1489 ALOGV_IF(!hasAudio, "no metadata for audio source"); // video only stream 1490 1491 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */); 1492 1493 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC; 1494 if (mAudioSink != NULL) { 1495 streamType = mAudioSink->getAudioStreamType(); 1496 } 1497 1498 mOffloadAudio = 1499 canOffloadStream(audioMeta, hasVideo, mSource->isStreaming(), streamType) 1500 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f); 1501 1502 // Modular DRM: Disabling audio offload if the source is protected 1503 if (mOffloadAudio && mIsDrmProtected) { 1504 mOffloadAudio = false; 1505 ALOGV("onStart: Disabling mOffloadAudio now that the source is protected."); 1506 } 1507 1508 if (mOffloadAudio) { 1509 flags |= Renderer::FLAG_OFFLOAD_AUDIO; 1510 } 1511 1512 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this); 1513 ++mRendererGeneration; 1514 notify->setInt32("generation", mRendererGeneration); 1515 mRenderer = new Renderer(mAudioSink, notify, flags); 1516 mRendererLooper = new ALooper; 1517 mRendererLooper->setName("NuPlayerRenderer"); 1518 mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 1519 mRendererLooper->registerHandler(mRenderer); 1520 1521 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings); 1522 if (err != OK) { 1523 mSource->stop(); 1524 mSourceStarted = false; 1525 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); 1526 return; 1527 } 1528 1529 float rate = getFrameRate(); 1530 if (rate > 0) { 1531 mRenderer->setVideoFrameRate(rate); 1532 } 1533 1534 if (mVideoDecoder != NULL) { 1535 mVideoDecoder->setRenderer(mRenderer); 1536 } 1537 if (mAudioDecoder != NULL) { 1538 mAudioDecoder->setRenderer(mRenderer); 1539 } 1540 1541 mLastStartedPlayingTimeNs = systemTime(); 1542 1543 postScanSources(); 1544} 1545 1546void NuPlayer::onPause() { 1547 if (mPaused) { 1548 return; 1549 } 1550 mPaused = true; 1551 if (mSource != NULL) { 1552 mSource->pause(); 1553 } else { 1554 ALOGW("pause called when source is gone or not set"); 1555 } 1556 if (mRenderer != NULL) { 1557 mRenderer->pause(); 1558 } else { 1559 ALOGW("pause called when renderer is gone or not set"); 1560 } 1561 1562 sp<NuPlayerDriver> driver = mDriver.promote(); 1563 if (driver != NULL) { 1564 int64_t now = systemTime(); 1565 int64_t played = now - mLastStartedPlayingTimeNs; 1566 1567 driver->notifyMorePlayingTimeUs((played+500)/1000); 1568 } 1569} 1570 1571bool NuPlayer::audioDecoderStillNeeded() { 1572 // Audio decoder is no longer needed if it's in shut/shutting down status. 1573 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER)); 1574} 1575 1576void NuPlayer::handleFlushComplete(bool audio, bool isDecoder) { 1577 // We wait for both the decoder flush and the renderer flush to complete 1578 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state. 1579 1580 mFlushComplete[audio][isDecoder] = true; 1581 if (!mFlushComplete[audio][!isDecoder]) { 1582 return; 1583 } 1584 1585 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo; 1586 switch (*state) { 1587 case FLUSHING_DECODER: 1588 { 1589 *state = FLUSHED; 1590 break; 1591 } 1592 1593 case FLUSHING_DECODER_SHUTDOWN: 1594 { 1595 *state = SHUTTING_DOWN_DECODER; 1596 1597 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video"); 1598 getDecoder(audio)->initiateShutdown(); 1599 break; 1600 } 1601 1602 default: 1603 // decoder flush completes only occur in a flushing state. 1604 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state); 1605 break; 1606 } 1607} 1608 1609void NuPlayer::finishFlushIfPossible() { 1610 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED 1611 && mFlushingAudio != SHUT_DOWN) { 1612 return; 1613 } 1614 1615 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED 1616 && mFlushingVideo != SHUT_DOWN) { 1617 return; 1618 } 1619 1620 ALOGV("both audio and video are flushed now."); 1621 1622 mFlushingAudio = NONE; 1623 mFlushingVideo = NONE; 1624 1625 clearFlushComplete(); 1626 1627 processDeferredActions(); 1628} 1629 1630void NuPlayer::postScanSources() { 1631 if (mScanSourcesPending) { 1632 return; 1633 } 1634 1635 sp<AMessage> msg = new AMessage(kWhatScanSources, this); 1636 msg->setInt32("generation", mScanSourcesGeneration); 1637 msg->post(); 1638 1639 mScanSourcesPending = true; 1640} 1641 1642void NuPlayer::tryOpenAudioSinkForOffload( 1643 const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) { 1644 // Note: This is called early in NuPlayer to determine whether offloading 1645 // is possible; otherwise the decoders call the renderer openAudioSink directly. 1646 1647 status_t err = mRenderer->openAudioSink( 1648 format, true /* offloadOnly */, hasVideo, 1649 AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mSource->isStreaming()); 1650 if (err != OK) { 1651 // Any failure we turn off mOffloadAudio. 1652 mOffloadAudio = false; 1653 } else if (mOffloadAudio) { 1654 sendMetaDataToHal(mAudioSink, audioMeta); 1655 } 1656} 1657 1658void NuPlayer::closeAudioSink() { 1659 mRenderer->closeAudioSink(); 1660} 1661 1662void NuPlayer::restartAudio( 1663 int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) { 1664 if (mAudioDecoder != NULL) { 1665 mAudioDecoder->pause(); 1666 mAudioDecoder.clear(); 1667 mAudioDecoderError = false; 1668 ++mAudioDecoderGeneration; 1669 } 1670 if (mFlushingAudio == FLUSHING_DECODER) { 1671 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true; 1672 mFlushingAudio = FLUSHED; 1673 finishFlushIfPossible(); 1674 } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN 1675 || mFlushingAudio == SHUTTING_DOWN_DECODER) { 1676 mFlushComplete[1 /* audio */][1 /* isDecoder */] = true; 1677 mFlushingAudio = SHUT_DOWN; 1678 finishFlushIfPossible(); 1679 needsToCreateAudioDecoder = false; 1680 } 1681 if (mRenderer == NULL) { 1682 return; 1683 } 1684 closeAudioSink(); 1685 mRenderer->flush(true /* audio */, false /* notifyComplete */); 1686 if (mVideoDecoder != NULL) { 1687 mRenderer->flush(false /* audio */, false /* notifyComplete */); 1688 } 1689 1690 performSeek(currentPositionUs, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */); 1691 1692 if (forceNonOffload) { 1693 mRenderer->signalDisableOffloadAudio(); 1694 mOffloadAudio = false; 1695 } 1696 if (needsToCreateAudioDecoder) { 1697 instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload); 1698 } 1699} 1700 1701void NuPlayer::determineAudioModeChange(const sp<AMessage> &audioFormat) { 1702 if (mSource == NULL || mAudioSink == NULL) { 1703 return; 1704 } 1705 1706 if (mRenderer == NULL) { 1707 ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety."); 1708 mOffloadAudio = false; 1709 return; 1710 } 1711 1712 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */); 1713 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */); 1714 audio_stream_type_t streamType = mAudioSink->getAudioStreamType(); 1715 const bool hasVideo = (videoFormat != NULL); 1716 bool canOffload = canOffloadStream( 1717 audioMeta, hasVideo, mSource->isStreaming(), streamType) 1718 && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f); 1719 1720 // Modular DRM: Disabling audio offload if the source is protected 1721 if (canOffload && mIsDrmProtected) { 1722 canOffload = false; 1723 ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected."); 1724 } 1725 1726 if (canOffload) { 1727 if (!mOffloadAudio) { 1728 mRenderer->signalEnableOffloadAudio(); 1729 } 1730 // open audio sink early under offload mode. 1731 tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo); 1732 } else { 1733 if (mOffloadAudio) { 1734 mRenderer->signalDisableOffloadAudio(); 1735 mOffloadAudio = false; 1736 } 1737 } 1738} 1739 1740status_t NuPlayer::instantiateDecoder( 1741 bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) { 1742 // The audio decoder could be cleared by tear down. If still in shut down 1743 // process, no need to create a new audio decoder. 1744 if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) { 1745 return OK; 1746 } 1747 1748 sp<AMessage> format = mSource->getFormat(audio); 1749 1750 if (format == NULL) { 1751 return UNKNOWN_ERROR; 1752 } else { 1753 status_t err; 1754 if (format->findInt32("err", &err) && err) { 1755 return err; 1756 } 1757 } 1758 1759 format->setInt32("priority", 0 /* realtime */); 1760 1761 if (!audio) { 1762 AString mime; 1763 CHECK(format->findString("mime", &mime)); 1764 1765 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this); 1766 if (mCCDecoder == NULL) { 1767 mCCDecoder = new CCDecoder(ccNotify); 1768 } 1769 1770 if (mSourceFlags & Source::FLAG_SECURE) { 1771 format->setInt32("secure", true); 1772 } 1773 1774 if (mSourceFlags & Source::FLAG_PROTECTED) { 1775 format->setInt32("protected", true); 1776 } 1777 1778 float rate = getFrameRate(); 1779 if (rate > 0) { 1780 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed); 1781 } 1782 } 1783 1784 if (audio) { 1785 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this); 1786 ++mAudioDecoderGeneration; 1787 notify->setInt32("generation", mAudioDecoderGeneration); 1788 1789 if (checkAudioModeChange) { 1790 determineAudioModeChange(format); 1791 } 1792 if (mOffloadAudio) { 1793 mSource->setOffloadAudio(true /* offload */); 1794 1795 const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL); 1796 format->setInt32("has-video", hasVideo); 1797 *decoder = new DecoderPassThrough(notify, mSource, mRenderer); 1798 ALOGV("instantiateDecoder audio DecoderPassThrough hasVideo: %d", hasVideo); 1799 } else { 1800 mSource->setOffloadAudio(false /* offload */); 1801 1802 *decoder = new Decoder(notify, mSource, mPID, mUID, mRenderer); 1803 ALOGV("instantiateDecoder audio Decoder"); 1804 } 1805 mAudioDecoderError = false; 1806 } else { 1807 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this); 1808 ++mVideoDecoderGeneration; 1809 notify->setInt32("generation", mVideoDecoderGeneration); 1810 1811 *decoder = new Decoder( 1812 notify, mSource, mPID, mUID, mRenderer, mSurface, mCCDecoder); 1813 mVideoDecoderError = false; 1814 1815 // enable FRC if high-quality AV sync is requested, even if not 1816 // directly queuing to display, as this will even improve textureview 1817 // playback. 1818 { 1819 if (property_get_bool("persist.sys.media.avsync", false)) { 1820 format->setInt32("auto-frc", 1); 1821 } 1822 } 1823 } 1824 (*decoder)->init(); 1825 1826 // Modular DRM 1827 if (mIsDrmProtected) { 1828 format->setPointer("crypto", mCrypto.get()); 1829 ALOGV("instantiateDecoder: mCrypto: %p (%d) isSecure: %d", mCrypto.get(), 1830 (mCrypto != NULL ? mCrypto->getStrongCount() : 0), 1831 (mSourceFlags & Source::FLAG_SECURE) != 0); 1832 } 1833 1834 (*decoder)->configure(format); 1835 1836 if (!audio) { 1837 sp<AMessage> params = new AMessage(); 1838 float rate = getFrameRate(); 1839 if (rate > 0) { 1840 params->setFloat("frame-rate-total", rate); 1841 } 1842 1843 sp<MetaData> fileMeta = getFileMeta(); 1844 if (fileMeta != NULL) { 1845 int32_t videoTemporalLayerCount; 1846 if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount) 1847 && videoTemporalLayerCount > 0) { 1848 params->setInt32("temporal-layer-count", videoTemporalLayerCount); 1849 } 1850 } 1851 1852 if (params->countEntries() > 0) { 1853 (*decoder)->setParameters(params); 1854 } 1855 } 1856 return OK; 1857} 1858 1859void NuPlayer::updateVideoSize( 1860 const sp<AMessage> &inputFormat, 1861 const sp<AMessage> &outputFormat) { 1862 if (inputFormat == NULL) { 1863 ALOGW("Unknown video size, reporting 0x0!"); 1864 notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0); 1865 return; 1866 } 1867 int32_t err = OK; 1868 inputFormat->findInt32("err", &err); 1869 if (err == -EWOULDBLOCK) { 1870 ALOGW("Video meta is not available yet!"); 1871 return; 1872 } 1873 if (err != OK) { 1874 ALOGW("Something is wrong with video meta!"); 1875 return; 1876 } 1877 1878 int32_t displayWidth, displayHeight; 1879 if (outputFormat != NULL) { 1880 int32_t width, height; 1881 CHECK(outputFormat->findInt32("width", &width)); 1882 CHECK(outputFormat->findInt32("height", &height)); 1883 1884 int32_t cropLeft, cropTop, cropRight, cropBottom; 1885 CHECK(outputFormat->findRect( 1886 "crop", 1887 &cropLeft, &cropTop, &cropRight, &cropBottom)); 1888 1889 displayWidth = cropRight - cropLeft + 1; 1890 displayHeight = cropBottom - cropTop + 1; 1891 1892 ALOGV("Video output format changed to %d x %d " 1893 "(crop: %d x %d @ (%d, %d))", 1894 width, height, 1895 displayWidth, 1896 displayHeight, 1897 cropLeft, cropTop); 1898 } else { 1899 CHECK(inputFormat->findInt32("width", &displayWidth)); 1900 CHECK(inputFormat->findInt32("height", &displayHeight)); 1901 1902 ALOGV("Video input format %d x %d", displayWidth, displayHeight); 1903 } 1904 1905 // Take into account sample aspect ratio if necessary: 1906 int32_t sarWidth, sarHeight; 1907 if (inputFormat->findInt32("sar-width", &sarWidth) 1908 && inputFormat->findInt32("sar-height", &sarHeight) 1909 && sarWidth > 0 && sarHeight > 0) { 1910 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight); 1911 1912 displayWidth = (displayWidth * sarWidth) / sarHeight; 1913 1914 ALOGV("display dimensions %d x %d", displayWidth, displayHeight); 1915 } else { 1916 int32_t width, height; 1917 if (inputFormat->findInt32("display-width", &width) 1918 && inputFormat->findInt32("display-height", &height) 1919 && width > 0 && height > 0 1920 && displayWidth > 0 && displayHeight > 0) { 1921 if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) { 1922 displayHeight = (int32_t)(displayWidth * (int64_t)height / width); 1923 } else { 1924 displayWidth = (int32_t)(displayHeight * (int64_t)width / height); 1925 } 1926 ALOGV("Video display width and height are overridden to %d x %d", 1927 displayWidth, displayHeight); 1928 } 1929 } 1930 1931 int32_t rotationDegrees; 1932 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) { 1933 rotationDegrees = 0; 1934 } 1935 1936 if (rotationDegrees == 90 || rotationDegrees == 270) { 1937 int32_t tmp = displayWidth; 1938 displayWidth = displayHeight; 1939 displayHeight = tmp; 1940 } 1941 1942 notifyListener( 1943 MEDIA_SET_VIDEO_SIZE, 1944 displayWidth, 1945 displayHeight); 1946} 1947 1948void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) { 1949 if (mDriver == NULL) { 1950 return; 1951 } 1952 1953 sp<NuPlayerDriver> driver = mDriver.promote(); 1954 1955 if (driver == NULL) { 1956 return; 1957 } 1958 1959 driver->notifyListener(msg, ext1, ext2, in); 1960} 1961 1962void NuPlayer::flushDecoder(bool audio, bool needShutdown) { 1963 ALOGV("[%s] flushDecoder needShutdown=%d", 1964 audio ? "audio" : "video", needShutdown); 1965 1966 const sp<DecoderBase> &decoder = getDecoder(audio); 1967 if (decoder == NULL) { 1968 ALOGI("flushDecoder %s without decoder present", 1969 audio ? "audio" : "video"); 1970 return; 1971 } 1972 1973 // Make sure we don't continue to scan sources until we finish flushing. 1974 ++mScanSourcesGeneration; 1975 if (mScanSourcesPending) { 1976 if (!needShutdown) { 1977 mDeferredActions.push_back( 1978 new SimpleAction(&NuPlayer::performScanSources)); 1979 } 1980 mScanSourcesPending = false; 1981 } 1982 1983 decoder->signalFlush(); 1984 1985 FlushStatus newStatus = 1986 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER; 1987 1988 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL); 1989 mFlushComplete[audio][true /* isDecoder */] = false; 1990 if (audio) { 1991 ALOGE_IF(mFlushingAudio != NONE, 1992 "audio flushDecoder() is called in state %d", mFlushingAudio); 1993 mFlushingAudio = newStatus; 1994 } else { 1995 ALOGE_IF(mFlushingVideo != NONE, 1996 "video flushDecoder() is called in state %d", mFlushingVideo); 1997 mFlushingVideo = newStatus; 1998 } 1999} 2000 2001void NuPlayer::queueDecoderShutdown( 2002 bool audio, bool video, const sp<AMessage> &reply) { 2003 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video); 2004 2005 mDeferredActions.push_back( 2006 new FlushDecoderAction( 2007 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE, 2008 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE)); 2009 2010 mDeferredActions.push_back( 2011 new SimpleAction(&NuPlayer::performScanSources)); 2012 2013 mDeferredActions.push_back(new PostMessageAction(reply)); 2014 2015 processDeferredActions(); 2016} 2017 2018status_t NuPlayer::setVideoScalingMode(int32_t mode) { 2019 mVideoScalingMode = mode; 2020 if (mSurface != NULL) { 2021 status_t ret = native_window_set_scaling_mode(mSurface.get(), mVideoScalingMode); 2022 if (ret != OK) { 2023 ALOGE("Failed to set scaling mode (%d): %s", 2024 -ret, strerror(-ret)); 2025 return ret; 2026 } 2027 } 2028 return OK; 2029} 2030 2031status_t NuPlayer::getTrackInfo(Parcel* reply) const { 2032 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this); 2033 msg->setPointer("reply", reply); 2034 2035 sp<AMessage> response; 2036 status_t err = msg->postAndAwaitResponse(&response); 2037 return err; 2038} 2039 2040status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const { 2041 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this); 2042 msg->setPointer("reply", reply); 2043 msg->setInt32("type", type); 2044 2045 sp<AMessage> response; 2046 status_t err = msg->postAndAwaitResponse(&response); 2047 if (err == OK && response != NULL) { 2048 CHECK(response->findInt32("err", &err)); 2049 } 2050 return err; 2051} 2052 2053status_t NuPlayer::selectTrack(size_t trackIndex, bool select, int64_t timeUs) { 2054 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this); 2055 msg->setSize("trackIndex", trackIndex); 2056 msg->setInt32("select", select); 2057 msg->setInt64("timeUs", timeUs); 2058 2059 sp<AMessage> response; 2060 status_t err = msg->postAndAwaitResponse(&response); 2061 2062 if (err != OK) { 2063 return err; 2064 } 2065 2066 if (!response->findInt32("err", &err)) { 2067 err = OK; 2068 } 2069 2070 return err; 2071} 2072 2073status_t NuPlayer::getCurrentPosition(int64_t *mediaUs) { 2074 sp<Renderer> renderer = mRenderer; 2075 if (renderer == NULL) { 2076 return NO_INIT; 2077 } 2078 2079 return renderer->getCurrentPosition(mediaUs); 2080} 2081 2082void NuPlayer::getStats(Vector<sp<AMessage> > *mTrackStats) { 2083 CHECK(mTrackStats != NULL); 2084 2085 mTrackStats->clear(); 2086 if (mVideoDecoder != NULL) { 2087 mTrackStats->push_back(mVideoDecoder->getStats()); 2088 } 2089 if (mAudioDecoder != NULL) { 2090 mTrackStats->push_back(mAudioDecoder->getStats()); 2091 } 2092} 2093 2094sp<MetaData> NuPlayer::getFileMeta() { 2095 return mSource->getFileFormatMeta(); 2096} 2097 2098float NuPlayer::getFrameRate() { 2099 sp<MetaData> meta = mSource->getFormatMeta(false /* audio */); 2100 if (meta == NULL) { 2101 return 0; 2102 } 2103 int32_t rate; 2104 if (!meta->findInt32(kKeyFrameRate, &rate)) { 2105 // fall back to try file meta 2106 sp<MetaData> fileMeta = getFileMeta(); 2107 if (fileMeta == NULL) { 2108 ALOGW("source has video meta but not file meta"); 2109 return -1; 2110 } 2111 int32_t fileMetaRate; 2112 if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) { 2113 return -1; 2114 } 2115 return fileMetaRate; 2116 } 2117 return rate; 2118} 2119 2120void NuPlayer::schedulePollDuration() { 2121 sp<AMessage> msg = new AMessage(kWhatPollDuration, this); 2122 msg->setInt32("generation", mPollDurationGeneration); 2123 msg->post(); 2124} 2125 2126void NuPlayer::cancelPollDuration() { 2127 ++mPollDurationGeneration; 2128} 2129 2130void NuPlayer::processDeferredActions() { 2131 while (!mDeferredActions.empty()) { 2132 // We won't execute any deferred actions until we're no longer in 2133 // an intermediate state, i.e. one more more decoders are currently 2134 // flushing or shutting down. 2135 2136 if (mFlushingAudio != NONE || mFlushingVideo != NONE) { 2137 // We're currently flushing, postpone the reset until that's 2138 // completed. 2139 2140 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d", 2141 mFlushingAudio, mFlushingVideo); 2142 2143 break; 2144 } 2145 2146 sp<Action> action = *mDeferredActions.begin(); 2147 mDeferredActions.erase(mDeferredActions.begin()); 2148 2149 action->execute(this); 2150 } 2151} 2152 2153void NuPlayer::performSeek(int64_t seekTimeUs, MediaPlayerSeekMode mode) { 2154 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d", 2155 (long long)seekTimeUs, seekTimeUs / 1E6, mode); 2156 2157 if (mSource == NULL) { 2158 // This happens when reset occurs right before the loop mode 2159 // asynchronously seeks to the start of the stream. 2160 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL, 2161 "mSource is NULL and decoders not NULL audio(%p) video(%p)", 2162 mAudioDecoder.get(), mVideoDecoder.get()); 2163 return; 2164 } 2165 mPreviousSeekTimeUs = seekTimeUs; 2166 mSource->seekTo(seekTimeUs, mode); 2167 ++mTimedTextGeneration; 2168 2169 // everything's flushed, continue playback. 2170} 2171 2172void NuPlayer::performDecoderFlush(FlushCommand audio, FlushCommand video) { 2173 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video); 2174 2175 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL) 2176 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) { 2177 return; 2178 } 2179 2180 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) { 2181 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN)); 2182 } 2183 2184 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) { 2185 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN)); 2186 } 2187} 2188 2189void NuPlayer::performReset() { 2190 ALOGV("performReset"); 2191 2192 CHECK(mAudioDecoder == NULL); 2193 CHECK(mVideoDecoder == NULL); 2194 2195 cancelPollDuration(); 2196 2197 ++mScanSourcesGeneration; 2198 mScanSourcesPending = false; 2199 2200 if (mRendererLooper != NULL) { 2201 if (mRenderer != NULL) { 2202 mRendererLooper->unregisterHandler(mRenderer->id()); 2203 } 2204 mRendererLooper->stop(); 2205 mRendererLooper.clear(); 2206 } 2207 mRenderer.clear(); 2208 ++mRendererGeneration; 2209 2210 if (mSource != NULL) { 2211 mSource->stop(); 2212 2213 Mutex::Autolock autoLock(mSourceLock); 2214 mSource.clear(); 2215 } 2216 2217 if (mDriver != NULL) { 2218 sp<NuPlayerDriver> driver = mDriver.promote(); 2219 if (driver != NULL) { 2220 driver->notifyResetComplete(); 2221 } 2222 } 2223 2224 mStarted = false; 2225 mPrepared = false; 2226 mResetting = false; 2227 mSourceStarted = false; 2228 2229 // Modular DRM 2230 if (mCrypto != NULL) { 2231 // decoders will be flushed before this so their mCrypto would go away on their own 2232 // TODO change to ALOGV 2233 ALOGD("performReset mCrypto: %p (%d)", mCrypto.get(), 2234 (mCrypto != NULL ? mCrypto->getStrongCount() : 0)); 2235 mCrypto.clear(); 2236 } 2237 mIsDrmProtected = false; 2238} 2239 2240void NuPlayer::performScanSources() { 2241 ALOGV("performScanSources"); 2242 2243 if (!mStarted) { 2244 return; 2245 } 2246 2247 if (mAudioDecoder == NULL || mVideoDecoder == NULL) { 2248 postScanSources(); 2249 } 2250} 2251 2252void NuPlayer::performSetSurface(const sp<Surface> &surface) { 2253 ALOGV("performSetSurface"); 2254 2255 mSurface = surface; 2256 2257 // XXX - ignore error from setVideoScalingMode for now 2258 setVideoScalingMode(mVideoScalingMode); 2259 2260 if (mDriver != NULL) { 2261 sp<NuPlayerDriver> driver = mDriver.promote(); 2262 if (driver != NULL) { 2263 driver->notifySetSurfaceComplete(); 2264 } 2265 } 2266} 2267 2268void NuPlayer::performResumeDecoders(bool needNotify) { 2269 if (needNotify) { 2270 mResumePending = true; 2271 if (mVideoDecoder == NULL) { 2272 // if audio-only, we can notify seek complete now, 2273 // as the resume operation will be relatively fast. 2274 finishResume(); 2275 } 2276 } 2277 2278 if (mVideoDecoder != NULL) { 2279 // When there is continuous seek, MediaPlayer will cache the seek 2280 // position, and send down new seek request when previous seek is 2281 // complete. Let's wait for at least one video output frame before 2282 // notifying seek complete, so that the video thumbnail gets updated 2283 // when seekbar is dragged. 2284 mVideoDecoder->signalResume(needNotify); 2285 } 2286 2287 if (mAudioDecoder != NULL) { 2288 mAudioDecoder->signalResume(false /* needNotify */); 2289 } 2290} 2291 2292void NuPlayer::finishResume() { 2293 if (mResumePending) { 2294 mResumePending = false; 2295 notifyDriverSeekComplete(); 2296 } 2297} 2298 2299void NuPlayer::notifyDriverSeekComplete() { 2300 if (mDriver != NULL) { 2301 sp<NuPlayerDriver> driver = mDriver.promote(); 2302 if (driver != NULL) { 2303 driver->notifySeekComplete(); 2304 } 2305 } 2306} 2307 2308void NuPlayer::onSourceNotify(const sp<AMessage> &msg) { 2309 int32_t what; 2310 CHECK(msg->findInt32("what", &what)); 2311 2312 switch (what) { 2313 case Source::kWhatInstantiateSecureDecoders: 2314 { 2315 if (mSource == NULL) { 2316 // This is a stale notification from a source that was 2317 // asynchronously preparing when the client called reset(). 2318 // We handled the reset, the source is gone. 2319 break; 2320 } 2321 2322 sp<AMessage> reply; 2323 CHECK(msg->findMessage("reply", &reply)); 2324 status_t err = onInstantiateSecureDecoders(); 2325 reply->setInt32("err", err); 2326 reply->post(); 2327 break; 2328 } 2329 2330 case Source::kWhatPrepared: 2331 { 2332 ALOGV("NuPlayer::onSourceNotify Source::kWhatPrepared source: %p", mSource.get()); 2333 if (mSource == NULL) { 2334 // This is a stale notification from a source that was 2335 // asynchronously preparing when the client called reset(). 2336 // We handled the reset, the source is gone. 2337 break; 2338 } 2339 2340 int32_t err; 2341 CHECK(msg->findInt32("err", &err)); 2342 2343 if (err != OK) { 2344 // shut down potential secure codecs in case client never calls reset 2345 mDeferredActions.push_back( 2346 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */, 2347 FLUSH_CMD_SHUTDOWN /* video */)); 2348 processDeferredActions(); 2349 } else { 2350 mPrepared = true; 2351 } 2352 2353 sp<NuPlayerDriver> driver = mDriver.promote(); 2354 if (driver != NULL) { 2355 // notify duration first, so that it's definitely set when 2356 // the app received the "prepare complete" callback. 2357 int64_t durationUs; 2358 if (mSource->getDuration(&durationUs) == OK) { 2359 driver->notifyDuration(durationUs); 2360 } 2361 driver->notifyPrepareCompleted(err); 2362 } 2363 2364 break; 2365 } 2366 2367 // Modular DRM 2368 case Source::kWhatDrmInfo: 2369 { 2370 Parcel parcel; 2371 sp<ABuffer> drmInfo; 2372 CHECK(msg->findBuffer("drmInfo", &drmInfo)); 2373 parcel.setData(drmInfo->data(), drmInfo->size()); 2374 2375 ALOGV("onSourceNotify() kWhatDrmInfo MEDIA_DRM_INFO drmInfo: %p parcel size: %zu", 2376 drmInfo.get(), parcel.dataSize()); 2377 2378 notifyListener(MEDIA_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &parcel); 2379 2380 break; 2381 } 2382 2383 case Source::kWhatFlagsChanged: 2384 { 2385 uint32_t flags; 2386 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 2387 2388 sp<NuPlayerDriver> driver = mDriver.promote(); 2389 if (driver != NULL) { 2390 2391 ALOGV("onSourceNotify() kWhatFlagsChanged FLAG_CAN_PAUSE: %d " 2392 "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d " 2393 "FLAG_CAN_SEEK: %d FLAG_DYNAMIC_DURATION: %d \n" 2394 "\t\t\t\t FLAG_SECURE: %d FLAG_PROTECTED: %d", 2395 (flags & Source::FLAG_CAN_PAUSE) != 0, 2396 (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0, 2397 (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0, 2398 (flags & Source::FLAG_CAN_SEEK) != 0, 2399 (flags & Source::FLAG_DYNAMIC_DURATION) != 0, 2400 (flags & Source::FLAG_SECURE) != 0, 2401 (flags & Source::FLAG_PROTECTED) != 0); 2402 2403 if ((flags & NuPlayer::Source::FLAG_CAN_SEEK) == 0) { 2404 driver->notifyListener( 2405 MEDIA_INFO, MEDIA_INFO_NOT_SEEKABLE, 0); 2406 } 2407 driver->notifyFlagsChanged(flags); 2408 } 2409 2410 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION) 2411 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) { 2412 cancelPollDuration(); 2413 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION) 2414 && (flags & Source::FLAG_DYNAMIC_DURATION) 2415 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { 2416 schedulePollDuration(); 2417 } 2418 2419 mSourceFlags = flags; 2420 break; 2421 } 2422 2423 case Source::kWhatVideoSizeChanged: 2424 { 2425 sp<AMessage> format; 2426 CHECK(msg->findMessage("format", &format)); 2427 2428 updateVideoSize(format); 2429 break; 2430 } 2431 2432 case Source::kWhatBufferingUpdate: 2433 { 2434 int32_t percentage; 2435 CHECK(msg->findInt32("percentage", &percentage)); 2436 2437 notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0); 2438 break; 2439 } 2440 2441 case Source::kWhatPauseOnBufferingStart: 2442 { 2443 // ignore if not playing 2444 if (mStarted) { 2445 ALOGI("buffer low, pausing..."); 2446 2447 mPausedForBuffering = true; 2448 onPause(); 2449 } 2450 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0); 2451 break; 2452 } 2453 2454 case Source::kWhatResumeOnBufferingEnd: 2455 { 2456 // ignore if not playing 2457 if (mStarted) { 2458 ALOGI("buffer ready, resuming..."); 2459 2460 mPausedForBuffering = false; 2461 2462 // do not resume yet if client didn't unpause 2463 if (!mPausedByClient) { 2464 onResume(); 2465 } 2466 } 2467 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0); 2468 break; 2469 } 2470 2471 case Source::kWhatCacheStats: 2472 { 2473 int32_t kbps; 2474 CHECK(msg->findInt32("bandwidth", &kbps)); 2475 2476 notifyListener(MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps); 2477 break; 2478 } 2479 2480 case Source::kWhatSubtitleData: 2481 { 2482 sp<ABuffer> buffer; 2483 CHECK(msg->findBuffer("buffer", &buffer)); 2484 2485 sendSubtitleData(buffer, 0 /* baseIndex */); 2486 break; 2487 } 2488 2489 case Source::kWhatTimedMetaData: 2490 { 2491 sp<ABuffer> buffer; 2492 if (!msg->findBuffer("buffer", &buffer)) { 2493 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0); 2494 } else { 2495 sendTimedMetaData(buffer); 2496 } 2497 break; 2498 } 2499 2500 case Source::kWhatTimedTextData: 2501 { 2502 int32_t generation; 2503 if (msg->findInt32("generation", &generation) 2504 && generation != mTimedTextGeneration) { 2505 break; 2506 } 2507 2508 sp<ABuffer> buffer; 2509 CHECK(msg->findBuffer("buffer", &buffer)); 2510 2511 sp<NuPlayerDriver> driver = mDriver.promote(); 2512 if (driver == NULL) { 2513 break; 2514 } 2515 2516 int posMs; 2517 int64_t timeUs, posUs; 2518 driver->getCurrentPosition(&posMs); 2519 posUs = (int64_t) posMs * 1000ll; 2520 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 2521 2522 if (posUs < timeUs) { 2523 if (!msg->findInt32("generation", &generation)) { 2524 msg->setInt32("generation", mTimedTextGeneration); 2525 } 2526 msg->post(timeUs - posUs); 2527 } else { 2528 sendTimedTextData(buffer); 2529 } 2530 break; 2531 } 2532 2533 case Source::kWhatQueueDecoderShutdown: 2534 { 2535 int32_t audio, video; 2536 CHECK(msg->findInt32("audio", &audio)); 2537 CHECK(msg->findInt32("video", &video)); 2538 2539 sp<AMessage> reply; 2540 CHECK(msg->findMessage("reply", &reply)); 2541 2542 queueDecoderShutdown(audio, video, reply); 2543 break; 2544 } 2545 2546 case Source::kWhatDrmNoLicense: 2547 { 2548 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE); 2549 break; 2550 } 2551 2552 default: 2553 TRESPASS(); 2554 } 2555} 2556 2557void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) { 2558 int32_t what; 2559 CHECK(msg->findInt32("what", &what)); 2560 2561 switch (what) { 2562 case NuPlayer::CCDecoder::kWhatClosedCaptionData: 2563 { 2564 sp<ABuffer> buffer; 2565 CHECK(msg->findBuffer("buffer", &buffer)); 2566 2567 size_t inbandTracks = 0; 2568 if (mSource != NULL) { 2569 inbandTracks = mSource->getTrackCount(); 2570 } 2571 2572 sendSubtitleData(buffer, inbandTracks); 2573 break; 2574 } 2575 2576 case NuPlayer::CCDecoder::kWhatTrackAdded: 2577 { 2578 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0); 2579 2580 break; 2581 } 2582 2583 default: 2584 TRESPASS(); 2585 } 2586 2587 2588} 2589 2590void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) { 2591 int32_t trackIndex; 2592 int64_t timeUs, durationUs; 2593 CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex)); 2594 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 2595 CHECK(buffer->meta()->findInt64("durationUs", &durationUs)); 2596 2597 Parcel in; 2598 in.writeInt32(trackIndex + baseIndex); 2599 in.writeInt64(timeUs); 2600 in.writeInt64(durationUs); 2601 in.writeInt32(buffer->size()); 2602 in.writeInt32(buffer->size()); 2603 in.write(buffer->data(), buffer->size()); 2604 2605 notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in); 2606} 2607 2608void NuPlayer::sendTimedMetaData(const sp<ABuffer> &buffer) { 2609 int64_t timeUs; 2610 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 2611 2612 Parcel in; 2613 in.writeInt64(timeUs); 2614 in.writeInt32(buffer->size()); 2615 in.writeInt32(buffer->size()); 2616 in.write(buffer->data(), buffer->size()); 2617 2618 notifyListener(MEDIA_META_DATA, 0, 0, &in); 2619} 2620 2621void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) { 2622 const void *data; 2623 size_t size = 0; 2624 int64_t timeUs; 2625 int32_t flag = TextDescriptions::IN_BAND_TEXT_3GPP; 2626 2627 AString mime; 2628 CHECK(buffer->meta()->findString("mime", &mime)); 2629 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0); 2630 2631 data = buffer->data(); 2632 size = buffer->size(); 2633 2634 Parcel parcel; 2635 if (size > 0) { 2636 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 2637 int32_t global = 0; 2638 if (buffer->meta()->findInt32("global", &global) && global) { 2639 flag |= TextDescriptions::GLOBAL_DESCRIPTIONS; 2640 } else { 2641 flag |= TextDescriptions::LOCAL_DESCRIPTIONS; 2642 } 2643 TextDescriptions::getParcelOfDescriptions( 2644 (const uint8_t *)data, size, flag, timeUs / 1000, &parcel); 2645 } 2646 2647 if ((parcel.dataSize() > 0)) { 2648 notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel); 2649 } else { // send an empty timed text 2650 notifyListener(MEDIA_TIMED_TEXT, 0, 0); 2651 } 2652} 2653 2654// Modular DRM begin 2655status_t NuPlayer::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId) 2656{ 2657 ALOGV("prepareDrm "); 2658 2659 // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto 2660 sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this); 2661 // synchronous call so just passing the address but with local copies of "const" args 2662 uint8_t UUID[16]; 2663 memcpy(UUID, uuid, sizeof(UUID)); 2664 Vector<uint8_t> sessionId = drmSessionId; 2665 msg->setPointer("uuid", (void*)UUID); 2666 msg->setPointer("drmSessionId", (void*)&sessionId); 2667 2668 sp<AMessage> response; 2669 status_t status = msg->postAndAwaitResponse(&response); 2670 2671 if (status == OK && response != NULL) { 2672 CHECK(response->findInt32("status", &status)); 2673 ALOGV("prepareDrm ret: %d ", status); 2674 } else { 2675 ALOGE("prepareDrm err: %d", status); 2676 } 2677 2678 return status; 2679} 2680 2681status_t NuPlayer::releaseDrm() 2682{ 2683 ALOGV("releaseDrm "); 2684 2685 sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this); 2686 2687 sp<AMessage> response; 2688 status_t status = msg->postAndAwaitResponse(&response); 2689 2690 if (status == OK && response != NULL) { 2691 CHECK(response->findInt32("status", &status)); 2692 ALOGV("releaseDrm ret: %d ", status); 2693 } else { 2694 ALOGE("releaseDrm err: %d", status); 2695 } 2696 2697 return status; 2698} 2699 2700status_t NuPlayer::onPrepareDrm(const sp<AMessage> &msg) 2701{ 2702 // TODO change to ALOGV 2703 ALOGD("onPrepareDrm "); 2704 2705 status_t status = INVALID_OPERATION; 2706 if (mSource == NULL) { 2707 ALOGE("onPrepareDrm: No source. onPrepareDrm failed with %d.", status); 2708 return status; 2709 } 2710 2711 uint8_t *uuid; 2712 Vector<uint8_t> *drmSessionId; 2713 CHECK(msg->findPointer("uuid", (void**)&uuid)); 2714 CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId)); 2715 2716 status = OK; 2717 sp<ICrypto> crypto = NULL; 2718 2719 status = mSource->prepareDrm(uuid, *drmSessionId, &crypto); 2720 if (crypto == NULL) { 2721 ALOGE("onPrepareDrm: mSource->prepareDrm failed. status: %d", status); 2722 return status; 2723 } 2724 ALOGV("onPrepareDrm: mSource->prepareDrm succeeded"); 2725 2726 if (mCrypto != NULL) { 2727 ALOGE("onPrepareDrm: Unexpected. Already having mCrypto: %p (%d)", 2728 mCrypto.get(), mCrypto->getStrongCount()); 2729 mCrypto.clear(); 2730 } 2731 2732 mCrypto = crypto; 2733 mIsDrmProtected = true; 2734 // TODO change to ALOGV 2735 ALOGD("onPrepareDrm: mCrypto: %p (%d)", mCrypto.get(), 2736 (mCrypto != NULL ? mCrypto->getStrongCount() : 0)); 2737 2738 return status; 2739} 2740 2741status_t NuPlayer::onReleaseDrm() 2742{ 2743 // TODO change to ALOGV 2744 ALOGD("onReleaseDrm "); 2745 2746 if (!mIsDrmProtected) { 2747 ALOGW("onReleaseDrm: Unexpected. mIsDrmProtected is already false."); 2748 } 2749 2750 mIsDrmProtected = false; 2751 2752 status_t status; 2753 if (mCrypto != NULL) { 2754 status=OK; 2755 // first making sure the codecs have released their crypto reference 2756 const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/); 2757 if (videoDecoder != NULL) { 2758 status = videoDecoder->releaseCrypto(); 2759 ALOGV("onReleaseDrm: video decoder ret: %d", status); 2760 } 2761 2762 const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/); 2763 if (audioDecoder != NULL) { 2764 status_t status_audio = audioDecoder->releaseCrypto(); 2765 if (status == OK) { // otherwise, returning the first error 2766 status = status_audio; 2767 } 2768 ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio); 2769 } 2770 2771 // TODO change to ALOGV 2772 ALOGD("onReleaseDrm: mCrypto: %p (%d)", mCrypto.get(), 2773 (mCrypto != NULL ? mCrypto->getStrongCount() : 0)); 2774 mCrypto.clear(); 2775 } else { // mCrypto == NULL 2776 ALOGE("onReleaseDrm: Unexpected. There is no crypto."); 2777 status = INVALID_OPERATION; 2778 } 2779 2780 return status; 2781} 2782// Modular DRM end 2783//////////////////////////////////////////////////////////////////////////////// 2784 2785sp<AMessage> NuPlayer::Source::getFormat(bool audio) { 2786 sp<MetaData> meta = getFormatMeta(audio); 2787 2788 if (meta == NULL) { 2789 return NULL; 2790 } 2791 2792 sp<AMessage> msg = new AMessage; 2793 2794 if(convertMetaDataToMessage(meta, &msg) == OK) { 2795 return msg; 2796 } 2797 return NULL; 2798} 2799 2800void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) { 2801 sp<AMessage> notify = dupNotify(); 2802 notify->setInt32("what", kWhatFlagsChanged); 2803 notify->setInt32("flags", flags); 2804 notify->post(); 2805} 2806 2807void NuPlayer::Source::notifyVideoSizeChanged(const sp<AMessage> &format) { 2808 sp<AMessage> notify = dupNotify(); 2809 notify->setInt32("what", kWhatVideoSizeChanged); 2810 notify->setMessage("format", format); 2811 notify->post(); 2812} 2813 2814void NuPlayer::Source::notifyPrepared(status_t err) { 2815 ALOGV("Source::notifyPrepared %d", err); 2816 sp<AMessage> notify = dupNotify(); 2817 notify->setInt32("what", kWhatPrepared); 2818 notify->setInt32("err", err); 2819 notify->post(); 2820} 2821 2822void NuPlayer::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer) 2823{ 2824 ALOGV("Source::notifyDrmInfo"); 2825 2826 sp<AMessage> notify = dupNotify(); 2827 notify->setInt32("what", kWhatDrmInfo); 2828 notify->setBuffer("drmInfo", drmInfoBuffer); 2829 2830 notify->post(); 2831} 2832 2833void NuPlayer::Source::notifyInstantiateSecureDecoders(const sp<AMessage> &reply) { 2834 sp<AMessage> notify = dupNotify(); 2835 notify->setInt32("what", kWhatInstantiateSecureDecoders); 2836 notify->setMessage("reply", reply); 2837 notify->post(); 2838} 2839 2840void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) { 2841 TRESPASS(); 2842} 2843 2844} // namespace android 2845