NuPlayer.cpp revision 94ce218596a88cc6d37098cce4e17e68f7405603
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#include <utils/Log.h> 20 21#include "NuPlayer.h" 22 23#include "HTTPLiveSource.h" 24#include "NuPlayerCCDecoder.h" 25#include "NuPlayerDecoder.h" 26#include "NuPlayerDecoderBase.h" 27#include "NuPlayerDecoderPassThrough.h" 28#include "NuPlayerDriver.h" 29#include "NuPlayerRenderer.h" 30#include "NuPlayerSource.h" 31#include "RTSPSource.h" 32#include "StreamingSource.h" 33#include "GenericSource.h" 34#include "TextDescriptions.h" 35 36#include "ATSParser.h" 37 38#include <cutils/properties.h> 39 40#include <media/AudioResamplerPublic.h> 41#include <media/AVSyncSettings.h> 42 43#include <media/stagefright/foundation/hexdump.h> 44#include <media/stagefright/foundation/ABuffer.h> 45#include <media/stagefright/foundation/ADebug.h> 46#include <media/stagefright/foundation/AMessage.h> 47#include <media/stagefright/MediaBuffer.h> 48#include <media/stagefright/MediaDefs.h> 49#include <media/stagefright/MediaErrors.h> 50#include <media/stagefright/MetaData.h> 51#include <gui/IGraphicBufferProducer.h> 52 53#include "avc_utils.h" 54 55#include "ESDS.h" 56#include <media/stagefright/Utils.h> 57 58namespace android { 59 60struct NuPlayer::Action : public RefBase { 61 Action() {} 62 63 virtual void execute(NuPlayer *player) = 0; 64 65private: 66 DISALLOW_EVIL_CONSTRUCTORS(Action); 67}; 68 69struct NuPlayer::SeekAction : public Action { 70 SeekAction(int64_t seekTimeUs, bool needNotify) 71 : mSeekTimeUs(seekTimeUs), 72 mNeedNotify(needNotify) { 73 } 74 75 virtual void execute(NuPlayer *player) { 76 player->performSeek(mSeekTimeUs, mNeedNotify); 77 } 78 79private: 80 int64_t mSeekTimeUs; 81 bool mNeedNotify; 82 83 DISALLOW_EVIL_CONSTRUCTORS(SeekAction); 84}; 85 86struct NuPlayer::ResumeDecoderAction : public Action { 87 ResumeDecoderAction(bool needNotify) 88 : mNeedNotify(needNotify) { 89 } 90 91 virtual void execute(NuPlayer *player) { 92 player->performResumeDecoders(mNeedNotify); 93 } 94 95private: 96 bool mNeedNotify; 97 98 DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction); 99}; 100 101struct NuPlayer::SetSurfaceAction : public Action { 102 SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper) 103 : mWrapper(wrapper) { 104 } 105 106 virtual void execute(NuPlayer *player) { 107 player->performSetSurface(mWrapper); 108 } 109 110private: 111 sp<NativeWindowWrapper> mWrapper; 112 113 DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction); 114}; 115 116struct NuPlayer::FlushDecoderAction : public Action { 117 FlushDecoderAction(FlushCommand audio, FlushCommand video) 118 : mAudio(audio), 119 mVideo(video) { 120 } 121 122 virtual void execute(NuPlayer *player) { 123 player->performDecoderFlush(mAudio, mVideo); 124 } 125 126private: 127 FlushCommand mAudio; 128 FlushCommand mVideo; 129 130 DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction); 131}; 132 133struct NuPlayer::PostMessageAction : public Action { 134 PostMessageAction(const sp<AMessage> &msg) 135 : mMessage(msg) { 136 } 137 138 virtual void execute(NuPlayer *) { 139 mMessage->post(); 140 } 141 142private: 143 sp<AMessage> mMessage; 144 145 DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction); 146}; 147 148// Use this if there's no state necessary to save in order to execute 149// the action. 150struct NuPlayer::SimpleAction : public Action { 151 typedef void (NuPlayer::*ActionFunc)(); 152 153 SimpleAction(ActionFunc func) 154 : mFunc(func) { 155 } 156 157 virtual void execute(NuPlayer *player) { 158 (player->*mFunc)(); 159 } 160 161private: 162 ActionFunc mFunc; 163 164 DISALLOW_EVIL_CONSTRUCTORS(SimpleAction); 165}; 166 167//////////////////////////////////////////////////////////////////////////////// 168 169NuPlayer::NuPlayer() 170 : mUIDValid(false), 171 mSourceFlags(0), 172 mOffloadAudio(false), 173 mAudioDecoderGeneration(0), 174 mVideoDecoderGeneration(0), 175 mRendererGeneration(0), 176 mAudioEOS(false), 177 mVideoEOS(false), 178 mScanSourcesPending(false), 179 mScanSourcesGeneration(0), 180 mPollDurationGeneration(0), 181 mTimedTextGeneration(0), 182 mFlushingAudio(NONE), 183 mFlushingVideo(NONE), 184 mResumePending(false), 185 mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW), 186 mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT), 187 mVideoFpsHint(-1.f), 188 mStarted(false), 189 mPaused(false), 190 mPausedByClient(false) { 191 clearFlushComplete(); 192} 193 194NuPlayer::~NuPlayer() { 195} 196 197void NuPlayer::setUID(uid_t uid) { 198 mUIDValid = true; 199 mUID = uid; 200} 201 202void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) { 203 mDriver = driver; 204} 205 206void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) { 207 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this); 208 209 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this); 210 211 msg->setObject("source", new StreamingSource(notify, source)); 212 msg->post(); 213} 214 215static bool IsHTTPLiveURL(const char *url) { 216 if (!strncasecmp("http://", url, 7) 217 || !strncasecmp("https://", url, 8) 218 || !strncasecmp("file://", url, 7)) { 219 size_t len = strlen(url); 220 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) { 221 return true; 222 } 223 224 if (strstr(url,"m3u8")) { 225 return true; 226 } 227 } 228 229 return false; 230} 231 232void NuPlayer::setDataSourceAsync( 233 const sp<IMediaHTTPService> &httpService, 234 const char *url, 235 const KeyedVector<String8, String8> *headers) { 236 237 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this); 238 size_t len = strlen(url); 239 240 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this); 241 242 sp<Source> source; 243 if (IsHTTPLiveURL(url)) { 244 source = new HTTPLiveSource(notify, httpService, url, headers); 245 } else if (!strncasecmp(url, "rtsp://", 7)) { 246 source = new RTSPSource( 247 notify, httpService, url, headers, mUIDValid, mUID); 248 } else if ((!strncasecmp(url, "http://", 7) 249 || !strncasecmp(url, "https://", 8)) 250 && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) 251 || strstr(url, ".sdp?"))) { 252 source = new RTSPSource( 253 notify, httpService, url, headers, mUIDValid, mUID, true); 254 } else { 255 sp<GenericSource> genericSource = 256 new GenericSource(notify, mUIDValid, mUID); 257 // Don't set FLAG_SECURE on mSourceFlags here for widevine. 258 // The correct flags will be updated in Source::kWhatFlagsChanged 259 // handler when GenericSource is prepared. 260 261 status_t err = genericSource->setDataSource(httpService, url, headers); 262 263 if (err == OK) { 264 source = genericSource; 265 } else { 266 ALOGE("Failed to set data source!"); 267 } 268 } 269 msg->setObject("source", source); 270 msg->post(); 271} 272 273void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) { 274 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this); 275 276 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this); 277 278 sp<GenericSource> source = 279 new GenericSource(notify, mUIDValid, mUID); 280 281 status_t err = source->setDataSource(fd, offset, length); 282 283 if (err != OK) { 284 ALOGE("Failed to set data source!"); 285 source = NULL; 286 } 287 288 msg->setObject("source", source); 289 msg->post(); 290} 291 292void NuPlayer::setDataSourceAsync(const sp<DataSource> &dataSource) { 293 sp<AMessage> msg = new AMessage(kWhatSetDataSource, this); 294 sp<AMessage> notify = new AMessage(kWhatSourceNotify, this); 295 296 sp<GenericSource> source = new GenericSource(notify, mUIDValid, mUID); 297 status_t err = source->setDataSource(dataSource); 298 299 if (err != OK) { 300 ALOGE("Failed to set data source!"); 301 source = NULL; 302 } 303 304 msg->setObject("source", source); 305 msg->post(); 306} 307 308void NuPlayer::prepareAsync() { 309 (new AMessage(kWhatPrepare, this))->post(); 310} 311 312void NuPlayer::setVideoSurfaceTextureAsync( 313 const sp<IGraphicBufferProducer> &bufferProducer) { 314 sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, this); 315 316 if (bufferProducer == NULL) { 317 msg->setObject("native-window", NULL); 318 } else { 319 msg->setObject( 320 "native-window", 321 new NativeWindowWrapper( 322 new Surface(bufferProducer, true /* controlledByApp */))); 323 } 324 325 msg->post(); 326} 327 328void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) { 329 sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this); 330 msg->setObject("sink", sink); 331 msg->post(); 332} 333 334void NuPlayer::start() { 335 (new AMessage(kWhatStart, this))->post(); 336} 337 338status_t NuPlayer::setPlaybackSettings(const AudioPlaybackRate &rate) { 339 // do some cursory validation of the settings here. audio modes are 340 // only validated when set on the audiosink. 341 if ((rate.mSpeed != 0.f && rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN) 342 || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX 343 || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN 344 || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) { 345 return BAD_VALUE; 346 } 347 sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this); 348 writeToAMessage(msg, rate); 349 sp<AMessage> response; 350 status_t err = msg->postAndAwaitResponse(&response); 351 if (err == OK && response != NULL) { 352 CHECK(response->findInt32("err", &err)); 353 } 354 return err; 355} 356 357status_t NuPlayer::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) { 358 sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this); 359 sp<AMessage> response; 360 status_t err = msg->postAndAwaitResponse(&response); 361 if (err == OK && response != NULL) { 362 CHECK(response->findInt32("err", &err)); 363 if (err == OK) { 364 readFromAMessage(response, rate); 365 } 366 } 367 return err; 368} 369 370status_t NuPlayer::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) { 371 sp<AMessage> msg = new AMessage(kWhatConfigSync, this); 372 writeToAMessage(msg, sync, videoFpsHint); 373 sp<AMessage> response; 374 status_t err = msg->postAndAwaitResponse(&response); 375 if (err == OK && response != NULL) { 376 CHECK(response->findInt32("err", &err)); 377 } 378 return err; 379} 380 381status_t NuPlayer::getSyncSettings( 382 AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) { 383 sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this); 384 sp<AMessage> response; 385 status_t err = msg->postAndAwaitResponse(&response); 386 if (err == OK && response != NULL) { 387 CHECK(response->findInt32("err", &err)); 388 if (err == OK) { 389 readFromAMessage(response, sync, videoFps); 390 } 391 } 392 return err; 393} 394 395void NuPlayer::pause() { 396 (new AMessage(kWhatPause, this))->post(); 397} 398 399void NuPlayer::resetAsync() { 400 if (mSource != NULL) { 401 // During a reset, the data source might be unresponsive already, we need to 402 // disconnect explicitly so that reads exit promptly. 403 // We can't queue the disconnect request to the looper, as it might be 404 // queued behind a stuck read and never gets processed. 405 // Doing a disconnect outside the looper to allows the pending reads to exit 406 // (either successfully or with error). 407 mSource->disconnect(); 408 } 409 410 (new AMessage(kWhatReset, this))->post(); 411} 412 413void NuPlayer::seekToAsync(int64_t seekTimeUs, bool needNotify) { 414 sp<AMessage> msg = new AMessage(kWhatSeek, this); 415 msg->setInt64("seekTimeUs", seekTimeUs); 416 msg->setInt32("needNotify", needNotify); 417 msg->post(); 418} 419 420 421void NuPlayer::writeTrackInfo( 422 Parcel* reply, const sp<AMessage> format) const { 423 int32_t trackType; 424 CHECK(format->findInt32("type", &trackType)); 425 426 AString mime; 427 CHECK(format->findString("mime", &mime)); 428 429 AString lang; 430 CHECK(format->findString("language", &lang)); 431 432 reply->writeInt32(2); // write something non-zero 433 reply->writeInt32(trackType); 434 reply->writeString16(String16(mime.c_str())); 435 reply->writeString16(String16(lang.c_str())); 436 437 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) { 438 int32_t isAuto, isDefault, isForced; 439 CHECK(format->findInt32("auto", &isAuto)); 440 CHECK(format->findInt32("default", &isDefault)); 441 CHECK(format->findInt32("forced", &isForced)); 442 443 reply->writeInt32(isAuto); 444 reply->writeInt32(isDefault); 445 reply->writeInt32(isForced); 446 } 447} 448 449void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { 450 switch (msg->what()) { 451 case kWhatSetDataSource: 452 { 453 ALOGV("kWhatSetDataSource"); 454 455 CHECK(mSource == NULL); 456 457 status_t err = OK; 458 sp<RefBase> obj; 459 CHECK(msg->findObject("source", &obj)); 460 if (obj != NULL) { 461 mSource = static_cast<Source *>(obj.get()); 462 } else { 463 err = UNKNOWN_ERROR; 464 } 465 466 CHECK(mDriver != NULL); 467 sp<NuPlayerDriver> driver = mDriver.promote(); 468 if (driver != NULL) { 469 driver->notifySetDataSourceCompleted(err); 470 } 471 break; 472 } 473 474 case kWhatPrepare: 475 { 476 mSource->prepareAsync(); 477 break; 478 } 479 480 case kWhatGetTrackInfo: 481 { 482 sp<AReplyToken> replyID; 483 CHECK(msg->senderAwaitsResponse(&replyID)); 484 485 Parcel* reply; 486 CHECK(msg->findPointer("reply", (void**)&reply)); 487 488 size_t inbandTracks = 0; 489 if (mSource != NULL) { 490 inbandTracks = mSource->getTrackCount(); 491 } 492 493 size_t ccTracks = 0; 494 if (mCCDecoder != NULL) { 495 ccTracks = mCCDecoder->getTrackCount(); 496 } 497 498 // total track count 499 reply->writeInt32(inbandTracks + ccTracks); 500 501 // write inband tracks 502 for (size_t i = 0; i < inbandTracks; ++i) { 503 writeTrackInfo(reply, mSource->getTrackInfo(i)); 504 } 505 506 // write CC track 507 for (size_t i = 0; i < ccTracks; ++i) { 508 writeTrackInfo(reply, mCCDecoder->getTrackInfo(i)); 509 } 510 511 sp<AMessage> response = new AMessage; 512 response->postReply(replyID); 513 break; 514 } 515 516 case kWhatGetSelectedTrack: 517 { 518 status_t err = INVALID_OPERATION; 519 if (mSource != NULL) { 520 err = OK; 521 522 int32_t type32; 523 CHECK(msg->findInt32("type", (int32_t*)&type32)); 524 media_track_type type = (media_track_type)type32; 525 ssize_t selectedTrack = mSource->getSelectedTrack(type); 526 527 Parcel* reply; 528 CHECK(msg->findPointer("reply", (void**)&reply)); 529 reply->writeInt32(selectedTrack); 530 } 531 532 sp<AMessage> response = new AMessage; 533 response->setInt32("err", err); 534 535 sp<AReplyToken> replyID; 536 CHECK(msg->senderAwaitsResponse(&replyID)); 537 response->postReply(replyID); 538 break; 539 } 540 541 case kWhatSelectTrack: 542 { 543 sp<AReplyToken> replyID; 544 CHECK(msg->senderAwaitsResponse(&replyID)); 545 546 size_t trackIndex; 547 int32_t select; 548 int64_t timeUs; 549 CHECK(msg->findSize("trackIndex", &trackIndex)); 550 CHECK(msg->findInt32("select", &select)); 551 CHECK(msg->findInt64("timeUs", &timeUs)); 552 553 status_t err = INVALID_OPERATION; 554 555 size_t inbandTracks = 0; 556 if (mSource != NULL) { 557 inbandTracks = mSource->getTrackCount(); 558 } 559 size_t ccTracks = 0; 560 if (mCCDecoder != NULL) { 561 ccTracks = mCCDecoder->getTrackCount(); 562 } 563 564 if (trackIndex < inbandTracks) { 565 err = mSource->selectTrack(trackIndex, select, timeUs); 566 567 if (!select && err == OK) { 568 int32_t type; 569 sp<AMessage> info = mSource->getTrackInfo(trackIndex); 570 if (info != NULL 571 && info->findInt32("type", &type) 572 && type == MEDIA_TRACK_TYPE_TIMEDTEXT) { 573 ++mTimedTextGeneration; 574 } 575 } 576 } else { 577 trackIndex -= inbandTracks; 578 579 if (trackIndex < ccTracks) { 580 err = mCCDecoder->selectTrack(trackIndex, select); 581 } 582 } 583 584 sp<AMessage> response = new AMessage; 585 response->setInt32("err", err); 586 587 response->postReply(replyID); 588 break; 589 } 590 591 case kWhatPollDuration: 592 { 593 int32_t generation; 594 CHECK(msg->findInt32("generation", &generation)); 595 596 if (generation != mPollDurationGeneration) { 597 // stale 598 break; 599 } 600 601 int64_t durationUs; 602 if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) { 603 sp<NuPlayerDriver> driver = mDriver.promote(); 604 if (driver != NULL) { 605 driver->notifyDuration(durationUs); 606 } 607 } 608 609 msg->post(1000000ll); // poll again in a second. 610 break; 611 } 612 613 case kWhatSetVideoNativeWindow: 614 { 615 ALOGV("kWhatSetVideoNativeWindow"); 616 617 sp<RefBase> obj; 618 CHECK(msg->findObject("native-window", &obj)); 619 620 if (mSource == NULL || mSource->getFormat(false /* audio */) == NULL) { 621 performSetSurface(static_cast<NativeWindowWrapper *>(obj.get())); 622 break; 623 } 624 625 mDeferredActions.push_back( 626 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */, 627 FLUSH_CMD_SHUTDOWN /* video */)); 628 629 mDeferredActions.push_back( 630 new SetSurfaceAction( 631 static_cast<NativeWindowWrapper *>(obj.get()))); 632 633 if (obj != NULL) { 634 if (mStarted) { 635 // Issue a seek to refresh the video screen only if started otherwise 636 // the extractor may not yet be started and will assert. 637 // If the video decoder is not set (perhaps audio only in this case) 638 // do not perform a seek as it is not needed. 639 int64_t currentPositionUs = 0; 640 if (getCurrentPosition(¤tPositionUs) == OK) { 641 mDeferredActions.push_back( 642 new SeekAction(currentPositionUs, false /* needNotify */)); 643 } 644 } 645 646 // If there is a new surface texture, instantiate decoders 647 // again if possible. 648 mDeferredActions.push_back( 649 new SimpleAction(&NuPlayer::performScanSources)); 650 } 651 652 // After a flush without shutdown, decoder is paused. 653 // Don't resume it until source seek is done, otherwise it could 654 // start pulling stale data too soon. 655 mDeferredActions.push_back( 656 new ResumeDecoderAction(false /* needNotify */)); 657 658 processDeferredActions(); 659 break; 660 } 661 662 case kWhatSetAudioSink: 663 { 664 ALOGV("kWhatSetAudioSink"); 665 666 sp<RefBase> obj; 667 CHECK(msg->findObject("sink", &obj)); 668 669 mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get()); 670 break; 671 } 672 673 case kWhatStart: 674 { 675 ALOGV("kWhatStart"); 676 if (mStarted) { 677 onResume(); 678 } else { 679 onStart(); 680 } 681 mPausedByClient = false; 682 break; 683 } 684 685 case kWhatConfigPlayback: 686 { 687 sp<AReplyToken> replyID; 688 CHECK(msg->senderAwaitsResponse(&replyID)); 689 AudioPlaybackRate rate /* sanitized */; 690 readFromAMessage(msg, &rate); 691 status_t err = OK; 692 if (mRenderer != NULL) { 693 err = mRenderer->setPlaybackSettings(rate); 694 } 695 if (err == OK) { 696 if (rate.mSpeed == 0.f) { 697 onPause(); 698 // save all other settings (using non-paused speed) 699 // so we can restore them on start 700 AudioPlaybackRate newRate = rate; 701 newRate.mSpeed = mPlaybackSettings.mSpeed; 702 mPlaybackSettings = newRate; 703 } else { /* rate.mSpeed != 0.f */ 704 onResume(); 705 mPlaybackSettings = rate; 706 } 707 } 708 709 if (mVideoDecoder != NULL) { 710 sp<MetaData> meta = getFileMeta(); 711 int32_t rate; 712 if (meta != NULL && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) { 713 sp<AMessage> params = new AMessage(); 714 params->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed); 715 mVideoDecoder->setParameters(params); 716 } 717 } 718 719 sp<AMessage> response = new AMessage; 720 response->setInt32("err", err); 721 response->postReply(replyID); 722 break; 723 } 724 725 case kWhatGetPlaybackSettings: 726 { 727 sp<AReplyToken> replyID; 728 CHECK(msg->senderAwaitsResponse(&replyID)); 729 AudioPlaybackRate rate = mPlaybackSettings; 730 status_t err = OK; 731 if (mRenderer != NULL) { 732 err = mRenderer->getPlaybackSettings(&rate); 733 } 734 if (err == OK) { 735 // get playback settings used by renderer, as it may be 736 // slightly off due to audiosink not taking small changes. 737 mPlaybackSettings = rate; 738 if (mPaused) { 739 rate.mSpeed = 0.f; 740 } 741 } 742 sp<AMessage> response = new AMessage; 743 if (err == OK) { 744 writeToAMessage(response, rate); 745 } 746 response->setInt32("err", err); 747 response->postReply(replyID); 748 break; 749 } 750 751 case kWhatConfigSync: 752 { 753 sp<AReplyToken> replyID; 754 CHECK(msg->senderAwaitsResponse(&replyID)); 755 756 ALOGV("kWhatConfigSync"); 757 AVSyncSettings sync; 758 float videoFpsHint; 759 readFromAMessage(msg, &sync, &videoFpsHint); 760 status_t err = OK; 761 if (mRenderer != NULL) { 762 err = mRenderer->setSyncSettings(sync, videoFpsHint); 763 } 764 if (err == OK) { 765 mSyncSettings = sync; 766 mVideoFpsHint = videoFpsHint; 767 } 768 sp<AMessage> response = new AMessage; 769 response->setInt32("err", err); 770 response->postReply(replyID); 771 break; 772 } 773 774 case kWhatGetSyncSettings: 775 { 776 sp<AReplyToken> replyID; 777 CHECK(msg->senderAwaitsResponse(&replyID)); 778 AVSyncSettings sync = mSyncSettings; 779 float videoFps = mVideoFpsHint; 780 status_t err = OK; 781 if (mRenderer != NULL) { 782 err = mRenderer->getSyncSettings(&sync, &videoFps); 783 if (err == OK) { 784 mSyncSettings = sync; 785 mVideoFpsHint = videoFps; 786 } 787 } 788 sp<AMessage> response = new AMessage; 789 if (err == OK) { 790 writeToAMessage(response, sync, videoFps); 791 } 792 response->setInt32("err", err); 793 response->postReply(replyID); 794 break; 795 } 796 797 case kWhatScanSources: 798 { 799 int32_t generation; 800 CHECK(msg->findInt32("generation", &generation)); 801 if (generation != mScanSourcesGeneration) { 802 // Drop obsolete msg. 803 break; 804 } 805 806 mScanSourcesPending = false; 807 808 ALOGV("scanning sources haveAudio=%d, haveVideo=%d", 809 mAudioDecoder != NULL, mVideoDecoder != NULL); 810 811 bool mHadAnySourcesBefore = 812 (mAudioDecoder != NULL) || (mVideoDecoder != NULL); 813 814 // initialize video before audio because successful initialization of 815 // video may change deep buffer mode of audio. 816 if (mNativeWindow != NULL) { 817 instantiateDecoder(false, &mVideoDecoder); 818 } 819 820 // Don't try to re-open audio sink if there's an existing decoder. 821 if (mAudioSink != NULL && mAudioDecoder == NULL) { 822 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */); 823 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */); 824 audio_stream_type_t streamType = mAudioSink->getAudioStreamType(); 825 const bool hasVideo = (videoFormat != NULL); 826 const bool canOffload = canOffloadStream( 827 audioMeta, hasVideo, true /* is_streaming */, streamType); 828 if (canOffload) { 829 if (!mOffloadAudio) { 830 mRenderer->signalEnableOffloadAudio(); 831 } 832 // open audio sink early under offload mode. 833 sp<AMessage> format = mSource->getFormat(true /*audio*/); 834 tryOpenAudioSinkForOffload(format, hasVideo); 835 } 836 instantiateDecoder(true, &mAudioDecoder); 837 } 838 839 if (!mHadAnySourcesBefore 840 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { 841 // This is the first time we've found anything playable. 842 843 if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) { 844 schedulePollDuration(); 845 } 846 } 847 848 status_t err; 849 if ((err = mSource->feedMoreTSData()) != OK) { 850 if (mAudioDecoder == NULL && mVideoDecoder == NULL) { 851 // We're not currently decoding anything (no audio or 852 // video tracks found) and we just ran out of input data. 853 854 if (err == ERROR_END_OF_STREAM) { 855 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); 856 } else { 857 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); 858 } 859 } 860 break; 861 } 862 863 if ((mAudioDecoder == NULL && mAudioSink != NULL) 864 || (mVideoDecoder == NULL && mNativeWindow != NULL)) { 865 msg->post(100000ll); 866 mScanSourcesPending = true; 867 } 868 break; 869 } 870 871 case kWhatVideoNotify: 872 case kWhatAudioNotify: 873 { 874 bool audio = msg->what() == kWhatAudioNotify; 875 876 int32_t currentDecoderGeneration = 877 (audio? mAudioDecoderGeneration : mVideoDecoderGeneration); 878 int32_t requesterGeneration = currentDecoderGeneration - 1; 879 CHECK(msg->findInt32("generation", &requesterGeneration)); 880 881 if (requesterGeneration != currentDecoderGeneration) { 882 ALOGV("got message from old %s decoder, generation(%d:%d)", 883 audio ? "audio" : "video", requesterGeneration, 884 currentDecoderGeneration); 885 sp<AMessage> reply; 886 if (!(msg->findMessage("reply", &reply))) { 887 return; 888 } 889 890 reply->setInt32("err", INFO_DISCONTINUITY); 891 reply->post(); 892 return; 893 } 894 895 int32_t what; 896 CHECK(msg->findInt32("what", &what)); 897 898 if (what == DecoderBase::kWhatInputDiscontinuity) { 899 int32_t formatChange; 900 CHECK(msg->findInt32("formatChange", &formatChange)); 901 902 ALOGV("%s discontinuity: formatChange %d", 903 audio ? "audio" : "video", formatChange); 904 905 if (formatChange) { 906 mDeferredActions.push_back( 907 new FlushDecoderAction( 908 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE, 909 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN)); 910 } 911 912 mDeferredActions.push_back( 913 new SimpleAction( 914 &NuPlayer::performScanSources)); 915 916 processDeferredActions(); 917 } else if (what == DecoderBase::kWhatEOS) { 918 int32_t err; 919 CHECK(msg->findInt32("err", &err)); 920 921 if (err == ERROR_END_OF_STREAM) { 922 ALOGV("got %s decoder EOS", audio ? "audio" : "video"); 923 } else { 924 ALOGV("got %s decoder EOS w/ error %d", 925 audio ? "audio" : "video", 926 err); 927 } 928 929 mRenderer->queueEOS(audio, err); 930 } else if (what == DecoderBase::kWhatFlushCompleted) { 931 ALOGV("decoder %s flush completed", audio ? "audio" : "video"); 932 933 handleFlushComplete(audio, true /* isDecoder */); 934 finishFlushIfPossible(); 935 } else if (what == DecoderBase::kWhatVideoSizeChanged) { 936 sp<AMessage> format; 937 CHECK(msg->findMessage("format", &format)); 938 939 sp<AMessage> inputFormat = 940 mSource->getFormat(false /* audio */); 941 942 updateVideoSize(inputFormat, format); 943 } else if (what == DecoderBase::kWhatShutdownCompleted) { 944 ALOGV("%s shutdown completed", audio ? "audio" : "video"); 945 if (audio) { 946 mAudioDecoder.clear(); 947 ++mAudioDecoderGeneration; 948 949 CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER); 950 mFlushingAudio = SHUT_DOWN; 951 } else { 952 mVideoDecoder.clear(); 953 ++mVideoDecoderGeneration; 954 955 CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER); 956 mFlushingVideo = SHUT_DOWN; 957 } 958 959 finishFlushIfPossible(); 960 } else if (what == DecoderBase::kWhatResumeCompleted) { 961 finishResume(); 962 } else if (what == DecoderBase::kWhatError) { 963 status_t err; 964 if (!msg->findInt32("err", &err) || err == OK) { 965 err = UNKNOWN_ERROR; 966 } 967 968 // Decoder errors can be due to Source (e.g. from streaming), 969 // or from decoding corrupted bitstreams, or from other decoder 970 // MediaCodec operations (e.g. from an ongoing reset or seek). 971 // They may also be due to openAudioSink failure at 972 // decoder start or after a format change. 973 // 974 // We try to gracefully shut down the affected decoder if possible, 975 // rather than trying to force the shutdown with something 976 // similar to performReset(). This method can lead to a hang 977 // if MediaCodec functions block after an error, but they should 978 // typically return INVALID_OPERATION instead of blocking. 979 980 FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo; 981 ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down", 982 err, audio ? "audio" : "video", *flushing); 983 984 switch (*flushing) { 985 case NONE: 986 mDeferredActions.push_back( 987 new FlushDecoderAction( 988 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE, 989 audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN)); 990 processDeferredActions(); 991 break; 992 case FLUSHING_DECODER: 993 *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush. 994 break; // Wait for flush to complete. 995 case FLUSHING_DECODER_SHUTDOWN: 996 break; // Wait for flush to complete. 997 case SHUTTING_DOWN_DECODER: 998 break; // Wait for shutdown to complete. 999 case FLUSHED: 1000 // Widevine source reads must stop before releasing the video decoder. 1001 if (!audio && mSource != NULL && mSourceFlags & Source::FLAG_SECURE) { 1002 mSource->stop(); 1003 } 1004 getDecoder(audio)->initiateShutdown(); // In the middle of a seek. 1005 *flushing = SHUTTING_DOWN_DECODER; // Shut down. 1006 break; 1007 case SHUT_DOWN: 1008 finishFlushIfPossible(); // Should not occur. 1009 break; // Finish anyways. 1010 } 1011 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); 1012 } else { 1013 ALOGV("Unhandled decoder notification %d '%c%c%c%c'.", 1014 what, 1015 what >> 24, 1016 (what >> 16) & 0xff, 1017 (what >> 8) & 0xff, 1018 what & 0xff); 1019 } 1020 1021 break; 1022 } 1023 1024 case kWhatRendererNotify: 1025 { 1026 int32_t requesterGeneration = mRendererGeneration - 1; 1027 CHECK(msg->findInt32("generation", &requesterGeneration)); 1028 if (requesterGeneration != mRendererGeneration) { 1029 ALOGV("got message from old renderer, generation(%d:%d)", 1030 requesterGeneration, mRendererGeneration); 1031 return; 1032 } 1033 1034 int32_t what; 1035 CHECK(msg->findInt32("what", &what)); 1036 1037 if (what == Renderer::kWhatEOS) { 1038 int32_t audio; 1039 CHECK(msg->findInt32("audio", &audio)); 1040 1041 int32_t finalResult; 1042 CHECK(msg->findInt32("finalResult", &finalResult)); 1043 1044 if (audio) { 1045 mAudioEOS = true; 1046 } else { 1047 mVideoEOS = true; 1048 } 1049 1050 if (finalResult == ERROR_END_OF_STREAM) { 1051 ALOGV("reached %s EOS", audio ? "audio" : "video"); 1052 } else { 1053 ALOGE("%s track encountered an error (%d)", 1054 audio ? "audio" : "video", finalResult); 1055 1056 notifyListener( 1057 MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult); 1058 } 1059 1060 if ((mAudioEOS || mAudioDecoder == NULL) 1061 && (mVideoEOS || mVideoDecoder == NULL)) { 1062 notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0); 1063 } 1064 } else if (what == Renderer::kWhatFlushComplete) { 1065 int32_t audio; 1066 CHECK(msg->findInt32("audio", &audio)); 1067 1068 ALOGV("renderer %s flush completed.", audio ? "audio" : "video"); 1069 handleFlushComplete(audio, false /* isDecoder */); 1070 finishFlushIfPossible(); 1071 } else if (what == Renderer::kWhatVideoRenderingStart) { 1072 notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0); 1073 } else if (what == Renderer::kWhatMediaRenderingStart) { 1074 ALOGV("media rendering started"); 1075 notifyListener(MEDIA_STARTED, 0, 0); 1076 } else if (what == Renderer::kWhatAudioOffloadTearDown) { 1077 ALOGV("Tear down audio offload, fall back to s/w path if due to error."); 1078 int64_t positionUs; 1079 CHECK(msg->findInt64("positionUs", &positionUs)); 1080 int32_t reason; 1081 CHECK(msg->findInt32("reason", &reason)); 1082 closeAudioSink(); 1083 mAudioDecoder.clear(); 1084 ++mAudioDecoderGeneration; 1085 mRenderer->flush( 1086 true /* audio */, false /* notifyComplete */); 1087 if (mVideoDecoder != NULL) { 1088 mRenderer->flush( 1089 false /* audio */, false /* notifyComplete */); 1090 } 1091 1092 performSeek(positionUs, false /* needNotify */); 1093 if (reason == Renderer::kDueToError) { 1094 mRenderer->signalDisableOffloadAudio(); 1095 mOffloadAudio = false; 1096 instantiateDecoder(true /* audio */, &mAudioDecoder); 1097 } 1098 } 1099 break; 1100 } 1101 1102 case kWhatMoreDataQueued: 1103 { 1104 break; 1105 } 1106 1107 case kWhatReset: 1108 { 1109 ALOGV("kWhatReset"); 1110 1111 mDeferredActions.push_back( 1112 new FlushDecoderAction( 1113 FLUSH_CMD_SHUTDOWN /* audio */, 1114 FLUSH_CMD_SHUTDOWN /* video */)); 1115 1116 mDeferredActions.push_back( 1117 new SimpleAction(&NuPlayer::performReset)); 1118 1119 processDeferredActions(); 1120 break; 1121 } 1122 1123 case kWhatSeek: 1124 { 1125 int64_t seekTimeUs; 1126 int32_t needNotify; 1127 CHECK(msg->findInt64("seekTimeUs", &seekTimeUs)); 1128 CHECK(msg->findInt32("needNotify", &needNotify)); 1129 1130 ALOGV("kWhatSeek seekTimeUs=%lld us, needNotify=%d", 1131 (long long)seekTimeUs, needNotify); 1132 1133 mDeferredActions.push_back( 1134 new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */, 1135 FLUSH_CMD_FLUSH /* video */)); 1136 1137 mDeferredActions.push_back( 1138 new SeekAction(seekTimeUs, needNotify)); 1139 1140 // After a flush without shutdown, decoder is paused. 1141 // Don't resume it until source seek is done, otherwise it could 1142 // start pulling stale data too soon. 1143 mDeferredActions.push_back( 1144 new ResumeDecoderAction(needNotify)); 1145 1146 processDeferredActions(); 1147 break; 1148 } 1149 1150 case kWhatPause: 1151 { 1152 onPause(); 1153 mPausedByClient = true; 1154 break; 1155 } 1156 1157 case kWhatSourceNotify: 1158 { 1159 onSourceNotify(msg); 1160 break; 1161 } 1162 1163 case kWhatClosedCaptionNotify: 1164 { 1165 onClosedCaptionNotify(msg); 1166 break; 1167 } 1168 1169 default: 1170 TRESPASS(); 1171 break; 1172 } 1173} 1174 1175void NuPlayer::onResume() { 1176 if (!mPaused) { 1177 return; 1178 } 1179 mPaused = false; 1180 if (mSource != NULL) { 1181 mSource->resume(); 1182 } else { 1183 ALOGW("resume called when source is gone or not set"); 1184 } 1185 // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if 1186 // needed. 1187 if (audioDecoderStillNeeded() && mAudioDecoder == NULL) { 1188 instantiateDecoder(true /* audio */, &mAudioDecoder); 1189 } 1190 if (mRenderer != NULL) { 1191 mRenderer->resume(); 1192 } else { 1193 ALOGW("resume called when renderer is gone or not set"); 1194 } 1195} 1196 1197status_t NuPlayer::onInstantiateSecureDecoders() { 1198 status_t err; 1199 if (!(mSourceFlags & Source::FLAG_SECURE)) { 1200 return BAD_TYPE; 1201 } 1202 1203 if (mRenderer != NULL) { 1204 ALOGE("renderer should not be set when instantiating secure decoders"); 1205 return UNKNOWN_ERROR; 1206 } 1207 1208 // TRICKY: We rely on mRenderer being null, so that decoder does not start requesting 1209 // data on instantiation. 1210 if (mNativeWindow != NULL) { 1211 err = instantiateDecoder(false, &mVideoDecoder); 1212 if (err != OK) { 1213 return err; 1214 } 1215 } 1216 1217 if (mAudioSink != NULL) { 1218 err = instantiateDecoder(true, &mAudioDecoder); 1219 if (err != OK) { 1220 return err; 1221 } 1222 } 1223 return OK; 1224} 1225 1226void NuPlayer::onStart() { 1227 mOffloadAudio = false; 1228 mAudioEOS = false; 1229 mVideoEOS = false; 1230 mStarted = true; 1231 1232 mSource->start(); 1233 1234 uint32_t flags = 0; 1235 1236 if (mSource->isRealTime()) { 1237 flags |= Renderer::FLAG_REAL_TIME; 1238 } 1239 1240 sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */); 1241 audio_stream_type_t streamType = AUDIO_STREAM_MUSIC; 1242 if (mAudioSink != NULL) { 1243 streamType = mAudioSink->getAudioStreamType(); 1244 } 1245 1246 sp<AMessage> videoFormat = mSource->getFormat(false /* audio */); 1247 1248 mOffloadAudio = 1249 canOffloadStream(audioMeta, (videoFormat != NULL), 1250 true /* is_streaming */, streamType); 1251 if (mOffloadAudio) { 1252 flags |= Renderer::FLAG_OFFLOAD_AUDIO; 1253 } 1254 1255 sp<AMessage> notify = new AMessage(kWhatRendererNotify, this); 1256 ++mRendererGeneration; 1257 notify->setInt32("generation", mRendererGeneration); 1258 mRenderer = new Renderer(mAudioSink, notify, flags); 1259 mRendererLooper = new ALooper; 1260 mRendererLooper->setName("NuPlayerRenderer"); 1261 mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 1262 mRendererLooper->registerHandler(mRenderer); 1263 1264 status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings); 1265 if (err != OK) { 1266 mSource->stop(); 1267 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err); 1268 return; 1269 } 1270 1271 sp<MetaData> meta = getFileMeta(); 1272 int32_t rate; 1273 if (meta != NULL 1274 && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) { 1275 mRenderer->setVideoFrameRate(rate); 1276 } 1277 1278 if (mVideoDecoder != NULL) { 1279 mVideoDecoder->setRenderer(mRenderer); 1280 } 1281 if (mAudioDecoder != NULL) { 1282 mAudioDecoder->setRenderer(mRenderer); 1283 } 1284 1285 postScanSources(); 1286} 1287 1288void NuPlayer::onPause() { 1289 if (mPaused) { 1290 return; 1291 } 1292 mPaused = true; 1293 if (mSource != NULL) { 1294 mSource->pause(); 1295 } else { 1296 ALOGW("pause called when source is gone or not set"); 1297 } 1298 if (mRenderer != NULL) { 1299 mRenderer->pause(); 1300 } else { 1301 ALOGW("pause called when renderer is gone or not set"); 1302 } 1303} 1304 1305bool NuPlayer::audioDecoderStillNeeded() { 1306 // Audio decoder is no longer needed if it's in shut/shutting down status. 1307 return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER)); 1308} 1309 1310void NuPlayer::handleFlushComplete(bool audio, bool isDecoder) { 1311 // We wait for both the decoder flush and the renderer flush to complete 1312 // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state. 1313 1314 mFlushComplete[audio][isDecoder] = true; 1315 if (!mFlushComplete[audio][!isDecoder]) { 1316 return; 1317 } 1318 1319 FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo; 1320 switch (*state) { 1321 case FLUSHING_DECODER: 1322 { 1323 *state = FLUSHED; 1324 break; 1325 } 1326 1327 case FLUSHING_DECODER_SHUTDOWN: 1328 { 1329 *state = SHUTTING_DOWN_DECODER; 1330 1331 ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video"); 1332 if (!audio) { 1333 // Widevine source reads must stop before releasing the video decoder. 1334 if (mSource != NULL && mSourceFlags & Source::FLAG_SECURE) { 1335 mSource->stop(); 1336 } 1337 } 1338 getDecoder(audio)->initiateShutdown(); 1339 break; 1340 } 1341 1342 default: 1343 // decoder flush completes only occur in a flushing state. 1344 LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state); 1345 break; 1346 } 1347} 1348 1349void NuPlayer::finishFlushIfPossible() { 1350 if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED 1351 && mFlushingAudio != SHUT_DOWN) { 1352 return; 1353 } 1354 1355 if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED 1356 && mFlushingVideo != SHUT_DOWN) { 1357 return; 1358 } 1359 1360 ALOGV("both audio and video are flushed now."); 1361 1362 mFlushingAudio = NONE; 1363 mFlushingVideo = NONE; 1364 1365 clearFlushComplete(); 1366 1367 processDeferredActions(); 1368} 1369 1370void NuPlayer::postScanSources() { 1371 if (mScanSourcesPending) { 1372 return; 1373 } 1374 1375 sp<AMessage> msg = new AMessage(kWhatScanSources, this); 1376 msg->setInt32("generation", mScanSourcesGeneration); 1377 msg->post(); 1378 1379 mScanSourcesPending = true; 1380} 1381 1382void NuPlayer::tryOpenAudioSinkForOffload(const sp<AMessage> &format, bool hasVideo) { 1383 // Note: This is called early in NuPlayer to determine whether offloading 1384 // is possible; otherwise the decoders call the renderer openAudioSink directly. 1385 1386 status_t err = mRenderer->openAudioSink( 1387 format, true /* offloadOnly */, hasVideo, AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio); 1388 if (err != OK) { 1389 // Any failure we turn off mOffloadAudio. 1390 mOffloadAudio = false; 1391 } else if (mOffloadAudio) { 1392 sp<MetaData> audioMeta = 1393 mSource->getFormatMeta(true /* audio */); 1394 sendMetaDataToHal(mAudioSink, audioMeta); 1395 } 1396} 1397 1398void NuPlayer::closeAudioSink() { 1399 mRenderer->closeAudioSink(); 1400} 1401 1402status_t NuPlayer::instantiateDecoder(bool audio, sp<DecoderBase> *decoder) { 1403 if (*decoder != NULL) { 1404 return OK; 1405 } 1406 1407 sp<AMessage> format = mSource->getFormat(audio); 1408 1409 if (format == NULL) { 1410 return -EWOULDBLOCK; 1411 } 1412 1413 format->setInt32("priority", 0 /* realtime */); 1414 1415 if (!audio) { 1416 AString mime; 1417 CHECK(format->findString("mime", &mime)); 1418 1419 sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this); 1420 if (mCCDecoder == NULL) { 1421 mCCDecoder = new CCDecoder(ccNotify); 1422 } 1423 1424 if (mSourceFlags & Source::FLAG_SECURE) { 1425 format->setInt32("secure", true); 1426 } 1427 1428 if (mSourceFlags & Source::FLAG_PROTECTED) { 1429 format->setInt32("protected", true); 1430 } 1431 1432 sp<MetaData> meta = getFileMeta(); 1433 int32_t rate; 1434 if (meta != NULL && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) { 1435 format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed); 1436 } 1437 } 1438 1439 if (audio) { 1440 sp<AMessage> notify = new AMessage(kWhatAudioNotify, this); 1441 ++mAudioDecoderGeneration; 1442 notify->setInt32("generation", mAudioDecoderGeneration); 1443 1444 if (mOffloadAudio) { 1445 const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL); 1446 format->setInt32("has-video", hasVideo); 1447 *decoder = new DecoderPassThrough(notify, mSource, mRenderer); 1448 } else { 1449 *decoder = new Decoder(notify, mSource, mRenderer); 1450 } 1451 } else { 1452 sp<AMessage> notify = new AMessage(kWhatVideoNotify, this); 1453 ++mVideoDecoderGeneration; 1454 notify->setInt32("generation", mVideoDecoderGeneration); 1455 1456 *decoder = new Decoder( 1457 notify, mSource, mRenderer, mNativeWindow, mCCDecoder); 1458 1459 // enable FRC if high-quality AV sync is requested, even if not 1460 // queuing to native window, as this will even improve textureview 1461 // playback. 1462 { 1463 char value[PROPERTY_VALUE_MAX]; 1464 if (property_get("persist.sys.media.avsync", value, NULL) && 1465 (!strcmp("1", value) || !strcasecmp("true", value))) { 1466 format->setInt32("auto-frc", 1); 1467 } 1468 } 1469 } 1470 (*decoder)->init(); 1471 (*decoder)->configure(format); 1472 1473 // allocate buffers to decrypt widevine source buffers 1474 if (!audio && (mSourceFlags & Source::FLAG_SECURE)) { 1475 Vector<sp<ABuffer> > inputBufs; 1476 CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK); 1477 1478 Vector<MediaBuffer *> mediaBufs; 1479 for (size_t i = 0; i < inputBufs.size(); i++) { 1480 const sp<ABuffer> &buffer = inputBufs[i]; 1481 MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size()); 1482 mediaBufs.push(mbuf); 1483 } 1484 1485 status_t err = mSource->setBuffers(audio, mediaBufs); 1486 if (err != OK) { 1487 for (size_t i = 0; i < mediaBufs.size(); ++i) { 1488 mediaBufs[i]->release(); 1489 } 1490 mediaBufs.clear(); 1491 ALOGE("Secure source didn't support secure mediaBufs."); 1492 return err; 1493 } 1494 } 1495 return OK; 1496} 1497 1498void NuPlayer::updateVideoSize( 1499 const sp<AMessage> &inputFormat, 1500 const sp<AMessage> &outputFormat) { 1501 if (inputFormat == NULL) { 1502 ALOGW("Unknown video size, reporting 0x0!"); 1503 notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0); 1504 return; 1505 } 1506 1507 int32_t displayWidth, displayHeight; 1508 if (outputFormat != NULL) { 1509 int32_t width, height; 1510 CHECK(outputFormat->findInt32("width", &width)); 1511 CHECK(outputFormat->findInt32("height", &height)); 1512 1513 int32_t cropLeft, cropTop, cropRight, cropBottom; 1514 CHECK(outputFormat->findRect( 1515 "crop", 1516 &cropLeft, &cropTop, &cropRight, &cropBottom)); 1517 1518 displayWidth = cropRight - cropLeft + 1; 1519 displayHeight = cropBottom - cropTop + 1; 1520 1521 ALOGV("Video output format changed to %d x %d " 1522 "(crop: %d x %d @ (%d, %d))", 1523 width, height, 1524 displayWidth, 1525 displayHeight, 1526 cropLeft, cropTop); 1527 } else { 1528 CHECK(inputFormat->findInt32("width", &displayWidth)); 1529 CHECK(inputFormat->findInt32("height", &displayHeight)); 1530 1531 ALOGV("Video input format %d x %d", displayWidth, displayHeight); 1532 } 1533 1534 // Take into account sample aspect ratio if necessary: 1535 int32_t sarWidth, sarHeight; 1536 if (inputFormat->findInt32("sar-width", &sarWidth) 1537 && inputFormat->findInt32("sar-height", &sarHeight)) { 1538 ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight); 1539 1540 displayWidth = (displayWidth * sarWidth) / sarHeight; 1541 1542 ALOGV("display dimensions %d x %d", displayWidth, displayHeight); 1543 } 1544 1545 int32_t rotationDegrees; 1546 if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) { 1547 rotationDegrees = 0; 1548 } 1549 1550 if (rotationDegrees == 90 || rotationDegrees == 270) { 1551 int32_t tmp = displayWidth; 1552 displayWidth = displayHeight; 1553 displayHeight = tmp; 1554 } 1555 1556 notifyListener( 1557 MEDIA_SET_VIDEO_SIZE, 1558 displayWidth, 1559 displayHeight); 1560} 1561 1562void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) { 1563 if (mDriver == NULL) { 1564 return; 1565 } 1566 1567 sp<NuPlayerDriver> driver = mDriver.promote(); 1568 1569 if (driver == NULL) { 1570 return; 1571 } 1572 1573 driver->notifyListener(msg, ext1, ext2, in); 1574} 1575 1576void NuPlayer::flushDecoder(bool audio, bool needShutdown) { 1577 ALOGV("[%s] flushDecoder needShutdown=%d", 1578 audio ? "audio" : "video", needShutdown); 1579 1580 const sp<DecoderBase> &decoder = getDecoder(audio); 1581 if (decoder == NULL) { 1582 ALOGI("flushDecoder %s without decoder present", 1583 audio ? "audio" : "video"); 1584 return; 1585 } 1586 1587 // Make sure we don't continue to scan sources until we finish flushing. 1588 ++mScanSourcesGeneration; 1589 if (mScanSourcesPending) { 1590 mDeferredActions.push_back( 1591 new SimpleAction(&NuPlayer::performScanSources)); 1592 mScanSourcesPending = false; 1593 } 1594 1595 decoder->signalFlush(); 1596 1597 FlushStatus newStatus = 1598 needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER; 1599 1600 mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL); 1601 mFlushComplete[audio][true /* isDecoder */] = false; 1602 if (audio) { 1603 ALOGE_IF(mFlushingAudio != NONE, 1604 "audio flushDecoder() is called in state %d", mFlushingAudio); 1605 mFlushingAudio = newStatus; 1606 } else { 1607 ALOGE_IF(mFlushingVideo != NONE, 1608 "video flushDecoder() is called in state %d", mFlushingVideo); 1609 mFlushingVideo = newStatus; 1610 } 1611} 1612 1613void NuPlayer::queueDecoderShutdown( 1614 bool audio, bool video, const sp<AMessage> &reply) { 1615 ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video); 1616 1617 mDeferredActions.push_back( 1618 new FlushDecoderAction( 1619 audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE, 1620 video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE)); 1621 1622 mDeferredActions.push_back( 1623 new SimpleAction(&NuPlayer::performScanSources)); 1624 1625 mDeferredActions.push_back(new PostMessageAction(reply)); 1626 1627 processDeferredActions(); 1628} 1629 1630status_t NuPlayer::setVideoScalingMode(int32_t mode) { 1631 mVideoScalingMode = mode; 1632 if (mNativeWindow != NULL) { 1633 status_t ret = native_window_set_scaling_mode( 1634 mNativeWindow->getNativeWindow().get(), mVideoScalingMode); 1635 if (ret != OK) { 1636 ALOGE("Failed to set scaling mode (%d): %s", 1637 -ret, strerror(-ret)); 1638 return ret; 1639 } 1640 } 1641 return OK; 1642} 1643 1644status_t NuPlayer::getTrackInfo(Parcel* reply) const { 1645 sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this); 1646 msg->setPointer("reply", reply); 1647 1648 sp<AMessage> response; 1649 status_t err = msg->postAndAwaitResponse(&response); 1650 return err; 1651} 1652 1653status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const { 1654 sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this); 1655 msg->setPointer("reply", reply); 1656 msg->setInt32("type", type); 1657 1658 sp<AMessage> response; 1659 status_t err = msg->postAndAwaitResponse(&response); 1660 if (err == OK && response != NULL) { 1661 CHECK(response->findInt32("err", &err)); 1662 } 1663 return err; 1664} 1665 1666status_t NuPlayer::selectTrack(size_t trackIndex, bool select, int64_t timeUs) { 1667 sp<AMessage> msg = new AMessage(kWhatSelectTrack, this); 1668 msg->setSize("trackIndex", trackIndex); 1669 msg->setInt32("select", select); 1670 msg->setInt64("timeUs", timeUs); 1671 1672 sp<AMessage> response; 1673 status_t err = msg->postAndAwaitResponse(&response); 1674 1675 if (err != OK) { 1676 return err; 1677 } 1678 1679 if (!response->findInt32("err", &err)) { 1680 err = OK; 1681 } 1682 1683 return err; 1684} 1685 1686status_t NuPlayer::getCurrentPosition(int64_t *mediaUs) { 1687 sp<Renderer> renderer = mRenderer; 1688 if (renderer == NULL) { 1689 return NO_INIT; 1690 } 1691 1692 return renderer->getCurrentPosition(mediaUs); 1693} 1694 1695void NuPlayer::getStats(int64_t *numFramesTotal, int64_t *numFramesDropped) { 1696 sp<DecoderBase> decoder = getDecoder(false /* audio */); 1697 if (decoder != NULL) { 1698 decoder->getStats(numFramesTotal, numFramesDropped); 1699 } else { 1700 *numFramesTotal = 0; 1701 *numFramesDropped = 0; 1702 } 1703} 1704 1705sp<MetaData> NuPlayer::getFileMeta() { 1706 return mSource->getFileFormatMeta(); 1707} 1708 1709void NuPlayer::schedulePollDuration() { 1710 sp<AMessage> msg = new AMessage(kWhatPollDuration, this); 1711 msg->setInt32("generation", mPollDurationGeneration); 1712 msg->post(); 1713} 1714 1715void NuPlayer::cancelPollDuration() { 1716 ++mPollDurationGeneration; 1717} 1718 1719void NuPlayer::processDeferredActions() { 1720 while (!mDeferredActions.empty()) { 1721 // We won't execute any deferred actions until we're no longer in 1722 // an intermediate state, i.e. one more more decoders are currently 1723 // flushing or shutting down. 1724 1725 if (mFlushingAudio != NONE || mFlushingVideo != NONE) { 1726 // We're currently flushing, postpone the reset until that's 1727 // completed. 1728 1729 ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d", 1730 mFlushingAudio, mFlushingVideo); 1731 1732 break; 1733 } 1734 1735 sp<Action> action = *mDeferredActions.begin(); 1736 mDeferredActions.erase(mDeferredActions.begin()); 1737 1738 action->execute(this); 1739 } 1740} 1741 1742void NuPlayer::performSeek(int64_t seekTimeUs, bool needNotify) { 1743 ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), needNotify(%d)", 1744 (long long)seekTimeUs, 1745 seekTimeUs / 1E6, 1746 needNotify); 1747 1748 if (mSource == NULL) { 1749 // This happens when reset occurs right before the loop mode 1750 // asynchronously seeks to the start of the stream. 1751 LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL, 1752 "mSource is NULL and decoders not NULL audio(%p) video(%p)", 1753 mAudioDecoder.get(), mVideoDecoder.get()); 1754 return; 1755 } 1756 mSource->seekTo(seekTimeUs); 1757 ++mTimedTextGeneration; 1758 1759 // everything's flushed, continue playback. 1760} 1761 1762void NuPlayer::performDecoderFlush(FlushCommand audio, FlushCommand video) { 1763 ALOGV("performDecoderFlush audio=%d, video=%d", audio, video); 1764 1765 if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL) 1766 && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) { 1767 return; 1768 } 1769 1770 if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) { 1771 flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN)); 1772 } 1773 1774 if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) { 1775 flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN)); 1776 } 1777} 1778 1779void NuPlayer::performReset() { 1780 ALOGV("performReset"); 1781 1782 CHECK(mAudioDecoder == NULL); 1783 CHECK(mVideoDecoder == NULL); 1784 1785 cancelPollDuration(); 1786 1787 ++mScanSourcesGeneration; 1788 mScanSourcesPending = false; 1789 1790 if (mRendererLooper != NULL) { 1791 if (mRenderer != NULL) { 1792 mRendererLooper->unregisterHandler(mRenderer->id()); 1793 } 1794 mRendererLooper->stop(); 1795 mRendererLooper.clear(); 1796 } 1797 mRenderer.clear(); 1798 ++mRendererGeneration; 1799 1800 if (mSource != NULL) { 1801 mSource->stop(); 1802 1803 mSource.clear(); 1804 } 1805 1806 if (mDriver != NULL) { 1807 sp<NuPlayerDriver> driver = mDriver.promote(); 1808 if (driver != NULL) { 1809 driver->notifyResetComplete(); 1810 } 1811 } 1812 1813 mStarted = false; 1814} 1815 1816void NuPlayer::performScanSources() { 1817 ALOGV("performScanSources"); 1818 1819 if (!mStarted) { 1820 return; 1821 } 1822 1823 if (mAudioDecoder == NULL || mVideoDecoder == NULL) { 1824 postScanSources(); 1825 } 1826} 1827 1828void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) { 1829 ALOGV("performSetSurface"); 1830 1831 mNativeWindow = wrapper; 1832 1833 // XXX - ignore error from setVideoScalingMode for now 1834 setVideoScalingMode(mVideoScalingMode); 1835 1836 if (mDriver != NULL) { 1837 sp<NuPlayerDriver> driver = mDriver.promote(); 1838 if (driver != NULL) { 1839 driver->notifySetSurfaceComplete(); 1840 } 1841 } 1842} 1843 1844void NuPlayer::performResumeDecoders(bool needNotify) { 1845 if (needNotify) { 1846 mResumePending = true; 1847 if (mVideoDecoder == NULL) { 1848 // if audio-only, we can notify seek complete now, 1849 // as the resume operation will be relatively fast. 1850 finishResume(); 1851 } 1852 } 1853 1854 if (mVideoDecoder != NULL) { 1855 // When there is continuous seek, MediaPlayer will cache the seek 1856 // position, and send down new seek request when previous seek is 1857 // complete. Let's wait for at least one video output frame before 1858 // notifying seek complete, so that the video thumbnail gets updated 1859 // when seekbar is dragged. 1860 mVideoDecoder->signalResume(needNotify); 1861 } 1862 1863 if (mAudioDecoder != NULL) { 1864 mAudioDecoder->signalResume(false /* needNotify */); 1865 } 1866} 1867 1868void NuPlayer::finishResume() { 1869 if (mResumePending) { 1870 mResumePending = false; 1871 if (mDriver != NULL) { 1872 sp<NuPlayerDriver> driver = mDriver.promote(); 1873 if (driver != NULL) { 1874 driver->notifySeekComplete(); 1875 } 1876 } 1877 } 1878} 1879 1880void NuPlayer::onSourceNotify(const sp<AMessage> &msg) { 1881 int32_t what; 1882 CHECK(msg->findInt32("what", &what)); 1883 1884 switch (what) { 1885 case Source::kWhatInstantiateSecureDecoders: 1886 { 1887 if (mSource == NULL) { 1888 // This is a stale notification from a source that was 1889 // asynchronously preparing when the client called reset(). 1890 // We handled the reset, the source is gone. 1891 break; 1892 } 1893 1894 sp<AMessage> reply; 1895 CHECK(msg->findMessage("reply", &reply)); 1896 status_t err = onInstantiateSecureDecoders(); 1897 reply->setInt32("err", err); 1898 reply->post(); 1899 break; 1900 } 1901 1902 case Source::kWhatPrepared: 1903 { 1904 if (mSource == NULL) { 1905 // This is a stale notification from a source that was 1906 // asynchronously preparing when the client called reset(). 1907 // We handled the reset, the source is gone. 1908 break; 1909 } 1910 1911 int32_t err; 1912 CHECK(msg->findInt32("err", &err)); 1913 1914 if (err != OK) { 1915 // shut down potential secure codecs in case client never calls reset 1916 mDeferredActions.push_back( 1917 new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */, 1918 FLUSH_CMD_SHUTDOWN /* video */)); 1919 processDeferredActions(); 1920 } 1921 1922 sp<NuPlayerDriver> driver = mDriver.promote(); 1923 if (driver != NULL) { 1924 // notify duration first, so that it's definitely set when 1925 // the app received the "prepare complete" callback. 1926 int64_t durationUs; 1927 if (mSource->getDuration(&durationUs) == OK) { 1928 driver->notifyDuration(durationUs); 1929 } 1930 driver->notifyPrepareCompleted(err); 1931 } 1932 1933 break; 1934 } 1935 1936 case Source::kWhatFlagsChanged: 1937 { 1938 uint32_t flags; 1939 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 1940 1941 sp<NuPlayerDriver> driver = mDriver.promote(); 1942 if (driver != NULL) { 1943 if ((flags & NuPlayer::Source::FLAG_CAN_SEEK) == 0) { 1944 driver->notifyListener( 1945 MEDIA_INFO, MEDIA_INFO_NOT_SEEKABLE, 0); 1946 } 1947 driver->notifyFlagsChanged(flags); 1948 } 1949 1950 if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION) 1951 && (!(flags & Source::FLAG_DYNAMIC_DURATION))) { 1952 cancelPollDuration(); 1953 } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION) 1954 && (flags & Source::FLAG_DYNAMIC_DURATION) 1955 && (mAudioDecoder != NULL || mVideoDecoder != NULL)) { 1956 schedulePollDuration(); 1957 } 1958 1959 mSourceFlags = flags; 1960 break; 1961 } 1962 1963 case Source::kWhatVideoSizeChanged: 1964 { 1965 sp<AMessage> format; 1966 CHECK(msg->findMessage("format", &format)); 1967 1968 updateVideoSize(format); 1969 break; 1970 } 1971 1972 case Source::kWhatBufferingUpdate: 1973 { 1974 int32_t percentage; 1975 CHECK(msg->findInt32("percentage", &percentage)); 1976 1977 notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0); 1978 break; 1979 } 1980 1981 case Source::kWhatPauseOnBufferingStart: 1982 { 1983 // ignore if not playing 1984 if (mStarted && !mPausedByClient) { 1985 ALOGI("buffer low, pausing..."); 1986 1987 onPause(); 1988 } 1989 // fall-thru 1990 } 1991 1992 case Source::kWhatBufferingStart: 1993 { 1994 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0); 1995 break; 1996 } 1997 1998 case Source::kWhatResumeOnBufferingEnd: 1999 { 2000 // ignore if not playing 2001 if (mStarted && !mPausedByClient) { 2002 ALOGI("buffer ready, resuming..."); 2003 2004 onResume(); 2005 } 2006 // fall-thru 2007 } 2008 2009 case Source::kWhatBufferingEnd: 2010 { 2011 notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0); 2012 break; 2013 } 2014 2015 case Source::kWhatCacheStats: 2016 { 2017 int32_t kbps; 2018 CHECK(msg->findInt32("bandwidth", &kbps)); 2019 2020 notifyListener(MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps); 2021 break; 2022 } 2023 2024 case Source::kWhatSubtitleData: 2025 { 2026 sp<ABuffer> buffer; 2027 CHECK(msg->findBuffer("buffer", &buffer)); 2028 2029 sendSubtitleData(buffer, 0 /* baseIndex */); 2030 break; 2031 } 2032 2033 case Source::kWhatTimedMetaData: 2034 { 2035 sp<ABuffer> buffer; 2036 if (!msg->findBuffer("buffer", &buffer)) { 2037 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0); 2038 } else { 2039 sendTimedMetaData(buffer); 2040 } 2041 break; 2042 } 2043 2044 case Source::kWhatTimedTextData: 2045 { 2046 int32_t generation; 2047 if (msg->findInt32("generation", &generation) 2048 && generation != mTimedTextGeneration) { 2049 break; 2050 } 2051 2052 sp<ABuffer> buffer; 2053 CHECK(msg->findBuffer("buffer", &buffer)); 2054 2055 sp<NuPlayerDriver> driver = mDriver.promote(); 2056 if (driver == NULL) { 2057 break; 2058 } 2059 2060 int posMs; 2061 int64_t timeUs, posUs; 2062 driver->getCurrentPosition(&posMs); 2063 posUs = posMs * 1000; 2064 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 2065 2066 if (posUs < timeUs) { 2067 if (!msg->findInt32("generation", &generation)) { 2068 msg->setInt32("generation", mTimedTextGeneration); 2069 } 2070 msg->post(timeUs - posUs); 2071 } else { 2072 sendTimedTextData(buffer); 2073 } 2074 break; 2075 } 2076 2077 case Source::kWhatQueueDecoderShutdown: 2078 { 2079 int32_t audio, video; 2080 CHECK(msg->findInt32("audio", &audio)); 2081 CHECK(msg->findInt32("video", &video)); 2082 2083 sp<AMessage> reply; 2084 CHECK(msg->findMessage("reply", &reply)); 2085 2086 queueDecoderShutdown(audio, video, reply); 2087 break; 2088 } 2089 2090 case Source::kWhatDrmNoLicense: 2091 { 2092 notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE); 2093 break; 2094 } 2095 2096 default: 2097 TRESPASS(); 2098 } 2099} 2100 2101void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) { 2102 int32_t what; 2103 CHECK(msg->findInt32("what", &what)); 2104 2105 switch (what) { 2106 case NuPlayer::CCDecoder::kWhatClosedCaptionData: 2107 { 2108 sp<ABuffer> buffer; 2109 CHECK(msg->findBuffer("buffer", &buffer)); 2110 2111 size_t inbandTracks = 0; 2112 if (mSource != NULL) { 2113 inbandTracks = mSource->getTrackCount(); 2114 } 2115 2116 sendSubtitleData(buffer, inbandTracks); 2117 break; 2118 } 2119 2120 case NuPlayer::CCDecoder::kWhatTrackAdded: 2121 { 2122 notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0); 2123 2124 break; 2125 } 2126 2127 default: 2128 TRESPASS(); 2129 } 2130 2131 2132} 2133 2134void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) { 2135 int32_t trackIndex; 2136 int64_t timeUs, durationUs; 2137 CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex)); 2138 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 2139 CHECK(buffer->meta()->findInt64("durationUs", &durationUs)); 2140 2141 Parcel in; 2142 in.writeInt32(trackIndex + baseIndex); 2143 in.writeInt64(timeUs); 2144 in.writeInt64(durationUs); 2145 in.writeInt32(buffer->size()); 2146 in.writeInt32(buffer->size()); 2147 in.write(buffer->data(), buffer->size()); 2148 2149 notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in); 2150} 2151 2152void NuPlayer::sendTimedMetaData(const sp<ABuffer> &buffer) { 2153 int64_t timeUs; 2154 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 2155 2156 Parcel in; 2157 in.writeInt64(timeUs); 2158 in.writeInt32(buffer->size()); 2159 in.writeInt32(buffer->size()); 2160 in.write(buffer->data(), buffer->size()); 2161 2162 notifyListener(MEDIA_META_DATA, 0, 0, &in); 2163} 2164 2165void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) { 2166 const void *data; 2167 size_t size = 0; 2168 int64_t timeUs; 2169 int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS; 2170 2171 AString mime; 2172 CHECK(buffer->meta()->findString("mime", &mime)); 2173 CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0); 2174 2175 data = buffer->data(); 2176 size = buffer->size(); 2177 2178 Parcel parcel; 2179 if (size > 0) { 2180 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 2181 flag |= TextDescriptions::IN_BAND_TEXT_3GPP; 2182 TextDescriptions::getParcelOfDescriptions( 2183 (const uint8_t *)data, size, flag, timeUs / 1000, &parcel); 2184 } 2185 2186 if ((parcel.dataSize() > 0)) { 2187 notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel); 2188 } else { // send an empty timed text 2189 notifyListener(MEDIA_TIMED_TEXT, 0, 0); 2190 } 2191} 2192//////////////////////////////////////////////////////////////////////////////// 2193 2194sp<AMessage> NuPlayer::Source::getFormat(bool audio) { 2195 sp<MetaData> meta = getFormatMeta(audio); 2196 2197 if (meta == NULL) { 2198 return NULL; 2199 } 2200 2201 sp<AMessage> msg = new AMessage; 2202 2203 if(convertMetaDataToMessage(meta, &msg) == OK) { 2204 return msg; 2205 } 2206 return NULL; 2207} 2208 2209void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) { 2210 sp<AMessage> notify = dupNotify(); 2211 notify->setInt32("what", kWhatFlagsChanged); 2212 notify->setInt32("flags", flags); 2213 notify->post(); 2214} 2215 2216void NuPlayer::Source::notifyVideoSizeChanged(const sp<AMessage> &format) { 2217 sp<AMessage> notify = dupNotify(); 2218 notify->setInt32("what", kWhatVideoSizeChanged); 2219 notify->setMessage("format", format); 2220 notify->post(); 2221} 2222 2223void NuPlayer::Source::notifyPrepared(status_t err) { 2224 sp<AMessage> notify = dupNotify(); 2225 notify->setInt32("what", kWhatPrepared); 2226 notify->setInt32("err", err); 2227 notify->post(); 2228} 2229 2230void NuPlayer::Source::notifyInstantiateSecureDecoders(const sp<AMessage> &reply) { 2231 sp<AMessage> notify = dupNotify(); 2232 notify->setInt32("what", kWhatInstantiateSecureDecoders); 2233 notify->setMessage("reply", reply); 2234 notify->post(); 2235} 2236 2237void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) { 2238 TRESPASS(); 2239} 2240 2241} // namespace android 2242