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