MediaCodec.cpp revision 7bad72237b49ac47e77ffe2a89fd26f3d171324c
1/* 2 * Copyright 2012, 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 "MediaCodec" 19#include <utils/Log.h> 20#include <inttypes.h> 21 22#include <media/stagefright/MediaCodec.h> 23 24#include "include/SoftwareRenderer.h" 25 26#include <gui/Surface.h> 27#include <media/ICrypto.h> 28#include <media/stagefright/foundation/ABuffer.h> 29#include <media/stagefright/foundation/ADebug.h> 30#include <media/stagefright/foundation/AMessage.h> 31#include <media/stagefright/foundation/AString.h> 32#include <media/stagefright/foundation/hexdump.h> 33#include <media/stagefright/ACodec.h> 34#include <media/stagefright/BufferProducerWrapper.h> 35#include <media/stagefright/MediaCodecList.h> 36#include <media/stagefright/MediaDefs.h> 37#include <media/stagefright/MediaErrors.h> 38#include <media/stagefright/MetaData.h> 39#include <media/stagefright/NativeWindowWrapper.h> 40 41#include "include/avc_utils.h" 42 43namespace android { 44 45// static 46sp<MediaCodec> MediaCodec::CreateByType( 47 const sp<ALooper> &looper, const char *mime, bool encoder) { 48 sp<MediaCodec> codec = new MediaCodec(looper); 49 if (codec->init(mime, true /* nameIsType */, encoder) != OK) { 50 return NULL; 51 } 52 53 return codec; 54} 55 56// static 57sp<MediaCodec> MediaCodec::CreateByComponentName( 58 const sp<ALooper> &looper, const char *name) { 59 sp<MediaCodec> codec = new MediaCodec(looper); 60 if (codec->init(name, false /* nameIsType */, false /* encoder */) != OK) { 61 return NULL; 62 } 63 64 return codec; 65} 66 67MediaCodec::MediaCodec(const sp<ALooper> &looper) 68 : mState(UNINITIALIZED), 69 mLooper(looper), 70 mCodec(NULL), 71 mReplyID(0), 72 mFlags(0), 73 mSoftRenderer(NULL), 74 mDequeueInputTimeoutGeneration(0), 75 mDequeueInputReplyID(0), 76 mDequeueOutputTimeoutGeneration(0), 77 mDequeueOutputReplyID(0), 78 mHaveInputSurface(false) { 79} 80 81MediaCodec::~MediaCodec() { 82 CHECK_EQ(mState, UNINITIALIZED); 83} 84 85// static 86status_t MediaCodec::PostAndAwaitResponse( 87 const sp<AMessage> &msg, sp<AMessage> *response) { 88 status_t err = msg->postAndAwaitResponse(response); 89 90 if (err != OK) { 91 return err; 92 } 93 94 if (!(*response)->findInt32("err", &err)) { 95 err = OK; 96 } 97 98 return err; 99} 100 101status_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) { 102 // Current video decoders do not return from OMX_FillThisBuffer 103 // quickly, violating the OpenMAX specs, until that is remedied 104 // we need to invest in an extra looper to free the main event 105 // queue. 106 mCodec = new ACodec; 107 bool needDedicatedLooper = false; 108 if (nameIsType && !strncasecmp(name, "video/", 6)) { 109 needDedicatedLooper = true; 110 } else { 111 AString tmp = name; 112 if (tmp.endsWith(".secure")) { 113 tmp.erase(tmp.size() - 7, 7); 114 } 115 const MediaCodecList *mcl = MediaCodecList::getInstance(); 116 ssize_t codecIdx = mcl->findCodecByName(tmp.c_str()); 117 if (codecIdx >= 0) { 118 Vector<AString> types; 119 if (mcl->getSupportedTypes(codecIdx, &types) == OK) { 120 for (size_t i = 0; i < types.size(); i++) { 121 if (types[i].startsWith("video/")) { 122 needDedicatedLooper = true; 123 break; 124 } 125 } 126 } 127 } 128 } 129 130 if (needDedicatedLooper) { 131 if (mCodecLooper == NULL) { 132 mCodecLooper = new ALooper; 133 mCodecLooper->setName("CodecLooper"); 134 mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 135 } 136 137 mCodecLooper->registerHandler(mCodec); 138 } else { 139 mLooper->registerHandler(mCodec); 140 } 141 142 mLooper->registerHandler(this); 143 144 mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, id())); 145 146 sp<AMessage> msg = new AMessage(kWhatInit, id()); 147 msg->setString("name", name); 148 msg->setInt32("nameIsType", nameIsType); 149 150 if (nameIsType) { 151 msg->setInt32("encoder", encoder); 152 } 153 154 sp<AMessage> response; 155 return PostAndAwaitResponse(msg, &response); 156} 157 158status_t MediaCodec::configure( 159 const sp<AMessage> &format, 160 const sp<Surface> &nativeWindow, 161 const sp<ICrypto> &crypto, 162 uint32_t flags) { 163 sp<AMessage> msg = new AMessage(kWhatConfigure, id()); 164 165 msg->setMessage("format", format); 166 msg->setInt32("flags", flags); 167 168 if (nativeWindow != NULL) { 169 msg->setObject( 170 "native-window", 171 new NativeWindowWrapper(nativeWindow)); 172 } 173 174 if (crypto != NULL) { 175 msg->setPointer("crypto", crypto.get()); 176 } 177 178 sp<AMessage> response; 179 return PostAndAwaitResponse(msg, &response); 180} 181 182status_t MediaCodec::createInputSurface( 183 sp<IGraphicBufferProducer>* bufferProducer) { 184 sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, id()); 185 186 sp<AMessage> response; 187 status_t err = PostAndAwaitResponse(msg, &response); 188 if (err == NO_ERROR) { 189 // unwrap the sp<IGraphicBufferProducer> 190 sp<RefBase> obj; 191 bool found = response->findObject("input-surface", &obj); 192 CHECK(found); 193 sp<BufferProducerWrapper> wrapper( 194 static_cast<BufferProducerWrapper*>(obj.get())); 195 *bufferProducer = wrapper->getBufferProducer(); 196 } else { 197 ALOGW("createInputSurface failed, err=%d", err); 198 } 199 return err; 200} 201 202status_t MediaCodec::start() { 203 sp<AMessage> msg = new AMessage(kWhatStart, id()); 204 205 sp<AMessage> response; 206 return PostAndAwaitResponse(msg, &response); 207} 208 209status_t MediaCodec::stop() { 210 sp<AMessage> msg = new AMessage(kWhatStop, id()); 211 212 sp<AMessage> response; 213 return PostAndAwaitResponse(msg, &response); 214} 215 216status_t MediaCodec::release() { 217 sp<AMessage> msg = new AMessage(kWhatRelease, id()); 218 219 sp<AMessage> response; 220 return PostAndAwaitResponse(msg, &response); 221} 222 223status_t MediaCodec::queueInputBuffer( 224 size_t index, 225 size_t offset, 226 size_t size, 227 int64_t presentationTimeUs, 228 uint32_t flags, 229 AString *errorDetailMsg) { 230 if (errorDetailMsg != NULL) { 231 errorDetailMsg->clear(); 232 } 233 234 sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id()); 235 msg->setSize("index", index); 236 msg->setSize("offset", offset); 237 msg->setSize("size", size); 238 msg->setInt64("timeUs", presentationTimeUs); 239 msg->setInt32("flags", flags); 240 msg->setPointer("errorDetailMsg", errorDetailMsg); 241 242 sp<AMessage> response; 243 return PostAndAwaitResponse(msg, &response); 244} 245 246status_t MediaCodec::queueSecureInputBuffer( 247 size_t index, 248 size_t offset, 249 const CryptoPlugin::SubSample *subSamples, 250 size_t numSubSamples, 251 const uint8_t key[16], 252 const uint8_t iv[16], 253 CryptoPlugin::Mode mode, 254 int64_t presentationTimeUs, 255 uint32_t flags, 256 AString *errorDetailMsg) { 257 if (errorDetailMsg != NULL) { 258 errorDetailMsg->clear(); 259 } 260 261 sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id()); 262 msg->setSize("index", index); 263 msg->setSize("offset", offset); 264 msg->setPointer("subSamples", (void *)subSamples); 265 msg->setSize("numSubSamples", numSubSamples); 266 msg->setPointer("key", (void *)key); 267 msg->setPointer("iv", (void *)iv); 268 msg->setInt32("mode", mode); 269 msg->setInt64("timeUs", presentationTimeUs); 270 msg->setInt32("flags", flags); 271 msg->setPointer("errorDetailMsg", errorDetailMsg); 272 273 sp<AMessage> response; 274 status_t err = PostAndAwaitResponse(msg, &response); 275 276 return err; 277} 278 279status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 280 sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id()); 281 msg->setInt64("timeoutUs", timeoutUs); 282 283 sp<AMessage> response; 284 status_t err; 285 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 286 return err; 287 } 288 289 CHECK(response->findSize("index", index)); 290 291 return OK; 292} 293 294status_t MediaCodec::dequeueOutputBuffer( 295 size_t *index, 296 size_t *offset, 297 size_t *size, 298 int64_t *presentationTimeUs, 299 uint32_t *flags, 300 int64_t timeoutUs) { 301 sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, id()); 302 msg->setInt64("timeoutUs", timeoutUs); 303 304 sp<AMessage> response; 305 status_t err; 306 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 307 return err; 308 } 309 310 CHECK(response->findSize("index", index)); 311 CHECK(response->findSize("offset", offset)); 312 CHECK(response->findSize("size", size)); 313 CHECK(response->findInt64("timeUs", presentationTimeUs)); 314 CHECK(response->findInt32("flags", (int32_t *)flags)); 315 316 return OK; 317} 318 319status_t MediaCodec::renderOutputBufferAndRelease(size_t index) { 320 sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id()); 321 msg->setSize("index", index); 322 msg->setInt32("render", true); 323 324 sp<AMessage> response; 325 return PostAndAwaitResponse(msg, &response); 326} 327 328status_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) { 329 sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id()); 330 msg->setSize("index", index); 331 msg->setInt32("render", true); 332 msg->setInt64("timestampNs", timestampNs); 333 334 sp<AMessage> response; 335 return PostAndAwaitResponse(msg, &response); 336} 337 338status_t MediaCodec::releaseOutputBuffer(size_t index) { 339 sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id()); 340 msg->setSize("index", index); 341 342 sp<AMessage> response; 343 return PostAndAwaitResponse(msg, &response); 344} 345 346status_t MediaCodec::signalEndOfInputStream() { 347 sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, id()); 348 349 sp<AMessage> response; 350 return PostAndAwaitResponse(msg, &response); 351} 352 353status_t MediaCodec::getOutputFormat(sp<AMessage> *format) const { 354 sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id()); 355 356 sp<AMessage> response; 357 status_t err; 358 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 359 return err; 360 } 361 362 CHECK(response->findMessage("format", format)); 363 364 return OK; 365} 366 367status_t MediaCodec::getInputFormat(sp<AMessage> *format) const { 368 sp<AMessage> msg = new AMessage(kWhatGetInputFormat, id()); 369 370 sp<AMessage> response; 371 status_t err; 372 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 373 return err; 374 } 375 376 CHECK(response->findMessage("format", format)); 377 378 return OK; 379} 380 381status_t MediaCodec::getName(AString *name) const { 382 sp<AMessage> msg = new AMessage(kWhatGetName, id()); 383 384 sp<AMessage> response; 385 status_t err; 386 if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 387 return err; 388 } 389 390 CHECK(response->findString("name", name)); 391 392 return OK; 393} 394 395status_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { 396 sp<AMessage> msg = new AMessage(kWhatGetBuffers, id()); 397 msg->setInt32("portIndex", kPortIndexInput); 398 msg->setPointer("buffers", buffers); 399 400 sp<AMessage> response; 401 return PostAndAwaitResponse(msg, &response); 402} 403 404status_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const { 405 sp<AMessage> msg = new AMessage(kWhatGetBuffers, id()); 406 msg->setInt32("portIndex", kPortIndexOutput); 407 msg->setPointer("buffers", buffers); 408 409 sp<AMessage> response; 410 return PostAndAwaitResponse(msg, &response); 411} 412 413status_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) { 414 sp<AMessage> format; 415 return getBufferAndFormat(kPortIndexOutput, index, buffer, &format); 416} 417 418status_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) { 419 sp<ABuffer> buffer; 420 return getBufferAndFormat(kPortIndexOutput, index, &buffer, format); 421} 422 423status_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) { 424 sp<AMessage> format; 425 return getBufferAndFormat(kPortIndexInput, index, buffer, &format); 426} 427 428status_t MediaCodec::getBufferAndFormat( 429 size_t portIndex, size_t index, 430 sp<ABuffer> *buffer, sp<AMessage> *format) { 431 // use mutex instead of a context switch 432 433 buffer->clear(); 434 format->clear(); 435 if (mState != STARTED) { 436 return INVALID_OPERATION; 437 } 438 439 // we do not want mPortBuffers to change during this section 440 // we also don't want mOwnedByClient to change during this 441 Mutex::Autolock al(mBufferLock); 442 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 443 if (index < buffers->size()) { 444 const BufferInfo &info = buffers->itemAt(index); 445 if (info.mOwnedByClient) { 446 *buffer = info.mData; 447 *format = info.mFormat; 448 } 449 } 450 return OK; 451} 452 453status_t MediaCodec::flush() { 454 sp<AMessage> msg = new AMessage(kWhatFlush, id()); 455 456 sp<AMessage> response; 457 return PostAndAwaitResponse(msg, &response); 458} 459 460status_t MediaCodec::requestIDRFrame() { 461 (new AMessage(kWhatRequestIDRFrame, id()))->post(); 462 463 return OK; 464} 465 466void MediaCodec::requestActivityNotification(const sp<AMessage> ¬ify) { 467 sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, id()); 468 msg->setMessage("notify", notify); 469 msg->post(); 470} 471 472//////////////////////////////////////////////////////////////////////////////// 473 474void MediaCodec::cancelPendingDequeueOperations() { 475 if (mFlags & kFlagDequeueInputPending) { 476 sp<AMessage> response = new AMessage; 477 response->setInt32("err", INVALID_OPERATION); 478 response->postReply(mDequeueInputReplyID); 479 480 ++mDequeueInputTimeoutGeneration; 481 mDequeueInputReplyID = 0; 482 mFlags &= ~kFlagDequeueInputPending; 483 } 484 485 if (mFlags & kFlagDequeueOutputPending) { 486 sp<AMessage> response = new AMessage; 487 response->setInt32("err", INVALID_OPERATION); 488 response->postReply(mDequeueOutputReplyID); 489 490 ++mDequeueOutputTimeoutGeneration; 491 mDequeueOutputReplyID = 0; 492 mFlags &= ~kFlagDequeueOutputPending; 493 } 494} 495 496bool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) { 497 if (mState != STARTED 498 || (mFlags & kFlagStickyError) 499 || (newRequest && (mFlags & kFlagDequeueInputPending))) { 500 sp<AMessage> response = new AMessage; 501 response->setInt32("err", INVALID_OPERATION); 502 503 response->postReply(replyID); 504 505 return true; 506 } 507 508 ssize_t index = dequeuePortBuffer(kPortIndexInput); 509 510 if (index < 0) { 511 CHECK_EQ(index, -EAGAIN); 512 return false; 513 } 514 515 sp<AMessage> response = new AMessage; 516 response->setSize("index", index); 517 response->postReply(replyID); 518 519 return true; 520} 521 522bool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) { 523 sp<AMessage> response = new AMessage; 524 525 if (mState != STARTED 526 || (mFlags & kFlagStickyError) 527 || (newRequest && (mFlags & kFlagDequeueOutputPending))) { 528 response->setInt32("err", INVALID_OPERATION); 529 } else if (mFlags & kFlagOutputBuffersChanged) { 530 response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED); 531 mFlags &= ~kFlagOutputBuffersChanged; 532 } else if (mFlags & kFlagOutputFormatChanged) { 533 response->setInt32("err", INFO_FORMAT_CHANGED); 534 mFlags &= ~kFlagOutputFormatChanged; 535 } else { 536 ssize_t index = dequeuePortBuffer(kPortIndexOutput); 537 538 if (index < 0) { 539 CHECK_EQ(index, -EAGAIN); 540 return false; 541 } 542 543 const sp<ABuffer> &buffer = 544 mPortBuffers[kPortIndexOutput].itemAt(index).mData; 545 546 response->setSize("index", index); 547 response->setSize("offset", buffer->offset()); 548 response->setSize("size", buffer->size()); 549 550 int64_t timeUs; 551 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 552 553 response->setInt64("timeUs", timeUs); 554 555 int32_t omxFlags; 556 CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 557 558 uint32_t flags = 0; 559 if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 560 flags |= BUFFER_FLAG_SYNCFRAME; 561 } 562 if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 563 flags |= BUFFER_FLAG_CODECCONFIG; 564 } 565 if (omxFlags & OMX_BUFFERFLAG_EOS) { 566 flags |= BUFFER_FLAG_EOS; 567 } 568 569 response->setInt32("flags", flags); 570 } 571 572 response->postReply(replyID); 573 574 return true; 575} 576 577void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { 578 switch (msg->what()) { 579 case kWhatCodecNotify: 580 { 581 int32_t what; 582 CHECK(msg->findInt32("what", &what)); 583 584 switch (what) { 585 case CodecBase::kWhatError: 586 { 587 int32_t omxError, internalError; 588 CHECK(msg->findInt32("omx-error", &omxError)); 589 CHECK(msg->findInt32("err", &internalError)); 590 591 ALOGE("Codec reported an error. " 592 "(omx error 0x%08x, internalError %d)", 593 omxError, internalError); 594 595 if (omxError == OMX_ErrorResourcesLost 596 && internalError == DEAD_OBJECT) { 597 mFlags |= kFlagSawMediaServerDie; 598 } 599 600 bool sendErrorReponse = true; 601 602 switch (mState) { 603 case INITIALIZING: 604 { 605 setState(UNINITIALIZED); 606 break; 607 } 608 609 case CONFIGURING: 610 { 611 setState(INITIALIZED); 612 break; 613 } 614 615 case STARTING: 616 { 617 setState(CONFIGURED); 618 break; 619 } 620 621 case STOPPING: 622 case RELEASING: 623 { 624 // Ignore the error, assuming we'll still get 625 // the shutdown complete notification. 626 627 sendErrorReponse = false; 628 629 if (mFlags & kFlagSawMediaServerDie) { 630 // MediaServer died, there definitely won't 631 // be a shutdown complete notification after 632 // all. 633 634 // note that we're directly going from 635 // STOPPING->UNINITIALIZED, instead of the 636 // usual STOPPING->INITIALIZED state. 637 setState(UNINITIALIZED); 638 639 (new AMessage)->postReply(mReplyID); 640 } 641 break; 642 } 643 644 case FLUSHING: 645 { 646 setState(STARTED); 647 break; 648 } 649 650 case STARTED: 651 { 652 sendErrorReponse = false; 653 654 mFlags |= kFlagStickyError; 655 postActivityNotificationIfPossible(); 656 657 cancelPendingDequeueOperations(); 658 setState(UNINITIALIZED); 659 break; 660 } 661 662 default: 663 { 664 sendErrorReponse = false; 665 666 mFlags |= kFlagStickyError; 667 postActivityNotificationIfPossible(); 668 setState(UNINITIALIZED); 669 break; 670 } 671 } 672 673 if (sendErrorReponse) { 674 sp<AMessage> response = new AMessage; 675 response->setInt32("err", UNKNOWN_ERROR); 676 677 response->postReply(mReplyID); 678 } 679 break; 680 } 681 682 case CodecBase::kWhatComponentAllocated: 683 { 684 CHECK_EQ(mState, INITIALIZING); 685 setState(INITIALIZED); 686 687 CHECK(msg->findString("componentName", &mComponentName)); 688 689 if (mComponentName.startsWith("OMX.google.")) { 690 mFlags |= kFlagIsSoftwareCodec; 691 } else { 692 mFlags &= ~kFlagIsSoftwareCodec; 693 } 694 695 if (mComponentName.endsWith(".secure")) { 696 mFlags |= kFlagIsSecure; 697 } else { 698 mFlags &= ~kFlagIsSecure; 699 } 700 701 (new AMessage)->postReply(mReplyID); 702 break; 703 } 704 705 case CodecBase::kWhatComponentConfigured: 706 { 707 CHECK_EQ(mState, CONFIGURING); 708 setState(CONFIGURED); 709 710 // reset input surface flag 711 mHaveInputSurface = false; 712 713 CHECK(msg->findMessage("input-format", &mInputFormat)); 714 CHECK(msg->findMessage("output-format", &mOutputFormat)); 715 716 (new AMessage)->postReply(mReplyID); 717 break; 718 } 719 720 case CodecBase::kWhatInputSurfaceCreated: 721 { 722 // response to initiateCreateInputSurface() 723 status_t err = NO_ERROR; 724 sp<AMessage> response = new AMessage(); 725 if (!msg->findInt32("err", &err)) { 726 sp<RefBase> obj; 727 msg->findObject("input-surface", &obj); 728 CHECK(obj != NULL); 729 response->setObject("input-surface", obj); 730 mHaveInputSurface = true; 731 } else { 732 response->setInt32("err", err); 733 } 734 response->postReply(mReplyID); 735 break; 736 } 737 738 case CodecBase::kWhatSignaledInputEOS: 739 { 740 // response to signalEndOfInputStream() 741 sp<AMessage> response = new AMessage(); 742 status_t err; 743 if (msg->findInt32("err", &err)) { 744 response->setInt32("err", err); 745 } 746 response->postReply(mReplyID); 747 break; 748 } 749 750 751 case CodecBase::kWhatBuffersAllocated: 752 { 753 Mutex::Autolock al(mBufferLock); 754 int32_t portIndex; 755 CHECK(msg->findInt32("portIndex", &portIndex)); 756 757 ALOGV("%s buffers allocated", 758 portIndex == kPortIndexInput ? "input" : "output"); 759 760 CHECK(portIndex == kPortIndexInput 761 || portIndex == kPortIndexOutput); 762 763 mPortBuffers[portIndex].clear(); 764 765 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 766 767 sp<RefBase> obj; 768 CHECK(msg->findObject("portDesc", &obj)); 769 770 sp<CodecBase::PortDescription> portDesc = 771 static_cast<CodecBase::PortDescription *>(obj.get()); 772 773 size_t numBuffers = portDesc->countBuffers(); 774 775 for (size_t i = 0; i < numBuffers; ++i) { 776 BufferInfo info; 777 info.mBufferID = portDesc->bufferIDAt(i); 778 info.mOwnedByClient = false; 779 info.mData = portDesc->bufferAt(i); 780 781 if (portIndex == kPortIndexInput && mCrypto != NULL) { 782 info.mEncryptedData = 783 new ABuffer(info.mData->capacity()); 784 } 785 786 buffers->push_back(info); 787 } 788 789 if (portIndex == kPortIndexOutput) { 790 if (mState == STARTING) { 791 // We're always allocating output buffers after 792 // allocating input buffers, so this is a good 793 // indication that now all buffers are allocated. 794 setState(STARTED); 795 (new AMessage)->postReply(mReplyID); 796 } else { 797 mFlags |= kFlagOutputBuffersChanged; 798 postActivityNotificationIfPossible(); 799 } 800 } 801 break; 802 } 803 804 case CodecBase::kWhatOutputFormatChanged: 805 { 806 ALOGV("codec output format changed"); 807 808 if ((mFlags & kFlagIsSoftwareCodec) 809 && mNativeWindow != NULL) { 810 AString mime; 811 CHECK(msg->findString("mime", &mime)); 812 813 if (!strncasecmp("video/", mime.c_str(), 6)) { 814 delete mSoftRenderer; 815 mSoftRenderer = NULL; 816 817 int32_t width, height; 818 CHECK(msg->findInt32("width", &width)); 819 CHECK(msg->findInt32("height", &height)); 820 821 int32_t cropLeft, cropTop, cropRight, cropBottom; 822 CHECK(msg->findRect("crop", 823 &cropLeft, &cropTop, &cropRight, &cropBottom)); 824 825 int32_t colorFormat; 826 CHECK(msg->findInt32( 827 "color-format", &colorFormat)); 828 829 sp<MetaData> meta = new MetaData; 830 meta->setInt32(kKeyWidth, width); 831 meta->setInt32(kKeyHeight, height); 832 meta->setRect(kKeyCropRect, 833 cropLeft, cropTop, cropRight, cropBottom); 834 meta->setInt32(kKeyColorFormat, colorFormat); 835 836 mSoftRenderer = 837 new SoftwareRenderer(mNativeWindow, meta); 838 } 839 } 840 841 mOutputFormat = msg; 842 843 if (mFlags & kFlagIsEncoder) { 844 // Before we announce the format change we should 845 // collect codec specific data and amend the output 846 // format as necessary. 847 mFlags |= kFlagGatherCodecSpecificData; 848 } else { 849 mFlags |= kFlagOutputFormatChanged; 850 postActivityNotificationIfPossible(); 851 } 852 break; 853 } 854 855 case CodecBase::kWhatFillThisBuffer: 856 { 857 /* size_t index = */updateBuffers(kPortIndexInput, msg); 858 859 if (mState == FLUSHING 860 || mState == STOPPING 861 || mState == RELEASING) { 862 returnBuffersToCodecOnPort(kPortIndexInput); 863 break; 864 } 865 866 if (!mCSD.empty()) { 867 ssize_t index = dequeuePortBuffer(kPortIndexInput); 868 CHECK_GE(index, 0); 869 870 // If codec specific data had been specified as 871 // part of the format in the call to configure and 872 // if there's more csd left, we submit it here 873 // clients only get access to input buffers once 874 // this data has been exhausted. 875 876 status_t err = queueCSDInputBuffer(index); 877 878 if (err != OK) { 879 ALOGE("queueCSDInputBuffer failed w/ error %d", 880 err); 881 882 mFlags |= kFlagStickyError; 883 postActivityNotificationIfPossible(); 884 885 cancelPendingDequeueOperations(); 886 } 887 break; 888 } 889 890 if (mFlags & kFlagDequeueInputPending) { 891 CHECK(handleDequeueInputBuffer(mDequeueInputReplyID)); 892 893 ++mDequeueInputTimeoutGeneration; 894 mFlags &= ~kFlagDequeueInputPending; 895 mDequeueInputReplyID = 0; 896 } else { 897 postActivityNotificationIfPossible(); 898 } 899 break; 900 } 901 902 case CodecBase::kWhatDrainThisBuffer: 903 { 904 /* size_t index = */updateBuffers(kPortIndexOutput, msg); 905 906 if (mState == FLUSHING 907 || mState == STOPPING 908 || mState == RELEASING) { 909 returnBuffersToCodecOnPort(kPortIndexOutput); 910 break; 911 } 912 913 sp<ABuffer> buffer; 914 CHECK(msg->findBuffer("buffer", &buffer)); 915 916 int32_t omxFlags; 917 CHECK(msg->findInt32("flags", &omxFlags)); 918 919 buffer->meta()->setInt32("omxFlags", omxFlags); 920 921 if (mFlags & kFlagGatherCodecSpecificData) { 922 // This is the very first output buffer after a 923 // format change was signalled, it'll either contain 924 // the one piece of codec specific data we can expect 925 // or there won't be codec specific data. 926 if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 927 status_t err = 928 amendOutputFormatWithCodecSpecificData(buffer); 929 930 if (err != OK) { 931 ALOGE("Codec spit out malformed codec " 932 "specific data!"); 933 } 934 } 935 936 mFlags &= ~kFlagGatherCodecSpecificData; 937 mFlags |= kFlagOutputFormatChanged; 938 } 939 940 if (mFlags & kFlagDequeueOutputPending) { 941 CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID)); 942 943 ++mDequeueOutputTimeoutGeneration; 944 mFlags &= ~kFlagDequeueOutputPending; 945 mDequeueOutputReplyID = 0; 946 } else { 947 postActivityNotificationIfPossible(); 948 } 949 950 break; 951 } 952 953 case CodecBase::kWhatEOS: 954 { 955 // We already notify the client of this by using the 956 // corresponding flag in "onOutputBufferReady". 957 break; 958 } 959 960 case CodecBase::kWhatShutdownCompleted: 961 { 962 if (mState == STOPPING) { 963 setState(INITIALIZED); 964 } else { 965 CHECK_EQ(mState, RELEASING); 966 setState(UNINITIALIZED); 967 } 968 969 (new AMessage)->postReply(mReplyID); 970 break; 971 } 972 973 case CodecBase::kWhatFlushCompleted: 974 { 975 CHECK_EQ(mState, FLUSHING); 976 setState(STARTED); 977 978 mCodec->signalResume(); 979 980 (new AMessage)->postReply(mReplyID); 981 break; 982 } 983 984 default: 985 TRESPASS(); 986 } 987 break; 988 } 989 990 case kWhatInit: 991 { 992 uint32_t replyID; 993 CHECK(msg->senderAwaitsResponse(&replyID)); 994 995 if (mState != UNINITIALIZED) { 996 sp<AMessage> response = new AMessage; 997 response->setInt32("err", INVALID_OPERATION); 998 999 response->postReply(replyID); 1000 break; 1001 } 1002 1003 mReplyID = replyID; 1004 setState(INITIALIZING); 1005 1006 AString name; 1007 CHECK(msg->findString("name", &name)); 1008 1009 int32_t nameIsType; 1010 int32_t encoder = false; 1011 CHECK(msg->findInt32("nameIsType", &nameIsType)); 1012 if (nameIsType) { 1013 CHECK(msg->findInt32("encoder", &encoder)); 1014 } 1015 1016 sp<AMessage> format = new AMessage; 1017 1018 if (nameIsType) { 1019 format->setString("mime", name.c_str()); 1020 format->setInt32("encoder", encoder); 1021 } else { 1022 format->setString("componentName", name.c_str()); 1023 } 1024 1025 mCodec->initiateAllocateComponent(format); 1026 break; 1027 } 1028 1029 case kWhatConfigure: 1030 { 1031 uint32_t replyID; 1032 CHECK(msg->senderAwaitsResponse(&replyID)); 1033 1034 if (mState != INITIALIZED) { 1035 sp<AMessage> response = new AMessage; 1036 response->setInt32("err", INVALID_OPERATION); 1037 1038 response->postReply(replyID); 1039 break; 1040 } 1041 1042 sp<RefBase> obj; 1043 if (!msg->findObject("native-window", &obj)) { 1044 obj.clear(); 1045 } 1046 1047 sp<AMessage> format; 1048 CHECK(msg->findMessage("format", &format)); 1049 1050 if (obj != NULL) { 1051 format->setObject("native-window", obj); 1052 1053 status_t err = setNativeWindow( 1054 static_cast<NativeWindowWrapper *>(obj.get()) 1055 ->getSurfaceTextureClient()); 1056 1057 if (err != OK) { 1058 sp<AMessage> response = new AMessage; 1059 response->setInt32("err", err); 1060 1061 response->postReply(replyID); 1062 break; 1063 } 1064 } else { 1065 setNativeWindow(NULL); 1066 } 1067 1068 mReplyID = replyID; 1069 setState(CONFIGURING); 1070 1071 void *crypto; 1072 if (!msg->findPointer("crypto", &crypto)) { 1073 crypto = NULL; 1074 } 1075 1076 mCrypto = static_cast<ICrypto *>(crypto); 1077 1078 uint32_t flags; 1079 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 1080 1081 if (flags & CONFIGURE_FLAG_ENCODE) { 1082 format->setInt32("encoder", true); 1083 mFlags |= kFlagIsEncoder; 1084 } 1085 1086 extractCSD(format); 1087 1088 mCodec->initiateConfigureComponent(format); 1089 break; 1090 } 1091 1092 case kWhatCreateInputSurface: 1093 { 1094 uint32_t replyID; 1095 CHECK(msg->senderAwaitsResponse(&replyID)); 1096 1097 // Must be configured, but can't have been started yet. 1098 if (mState != CONFIGURED) { 1099 sp<AMessage> response = new AMessage; 1100 response->setInt32("err", INVALID_OPERATION); 1101 1102 response->postReply(replyID); 1103 break; 1104 } 1105 1106 mReplyID = replyID; 1107 mCodec->initiateCreateInputSurface(); 1108 break; 1109 } 1110 1111 case kWhatStart: 1112 { 1113 uint32_t replyID; 1114 CHECK(msg->senderAwaitsResponse(&replyID)); 1115 1116 if (mState != CONFIGURED) { 1117 sp<AMessage> response = new AMessage; 1118 response->setInt32("err", INVALID_OPERATION); 1119 1120 response->postReply(replyID); 1121 break; 1122 } 1123 1124 mReplyID = replyID; 1125 setState(STARTING); 1126 1127 mCodec->initiateStart(); 1128 break; 1129 } 1130 1131 case kWhatStop: 1132 case kWhatRelease: 1133 { 1134 State targetState = 1135 (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED; 1136 1137 uint32_t replyID; 1138 CHECK(msg->senderAwaitsResponse(&replyID)); 1139 1140 if (mState != INITIALIZED 1141 && mState != CONFIGURED && mState != STARTED) { 1142 // We may be in "UNINITIALIZED" state already without the 1143 // client being aware of this if media server died while 1144 // we were being stopped. The client would assume that 1145 // after stop() returned, it would be safe to call release() 1146 // and it should be in this case, no harm to allow a release() 1147 // if we're already uninitialized. 1148 // Similarly stopping a stopped MediaCodec should be benign. 1149 sp<AMessage> response = new AMessage; 1150 response->setInt32( 1151 "err", 1152 mState == targetState ? OK : INVALID_OPERATION); 1153 1154 response->postReply(replyID); 1155 break; 1156 } 1157 1158 if (mFlags & kFlagSawMediaServerDie) { 1159 // It's dead, Jim. Don't expect initiateShutdown to yield 1160 // any useful results now... 1161 setState(UNINITIALIZED); 1162 (new AMessage)->postReply(replyID); 1163 break; 1164 } 1165 1166 mReplyID = replyID; 1167 setState(msg->what() == kWhatStop ? STOPPING : RELEASING); 1168 1169 mCodec->initiateShutdown( 1170 msg->what() == kWhatStop /* keepComponentAllocated */); 1171 1172 returnBuffersToCodec(); 1173 break; 1174 } 1175 1176 case kWhatDequeueInputBuffer: 1177 { 1178 uint32_t replyID; 1179 CHECK(msg->senderAwaitsResponse(&replyID)); 1180 1181 if (mHaveInputSurface) { 1182 ALOGE("dequeueInputBuffer can't be used with input surface"); 1183 sp<AMessage> response = new AMessage; 1184 response->setInt32("err", INVALID_OPERATION); 1185 response->postReply(replyID); 1186 break; 1187 } 1188 1189 if (handleDequeueInputBuffer(replyID, true /* new request */)) { 1190 break; 1191 } 1192 1193 int64_t timeoutUs; 1194 CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 1195 1196 if (timeoutUs == 0ll) { 1197 sp<AMessage> response = new AMessage; 1198 response->setInt32("err", -EAGAIN); 1199 response->postReply(replyID); 1200 break; 1201 } 1202 1203 mFlags |= kFlagDequeueInputPending; 1204 mDequeueInputReplyID = replyID; 1205 1206 if (timeoutUs > 0ll) { 1207 sp<AMessage> timeoutMsg = 1208 new AMessage(kWhatDequeueInputTimedOut, id()); 1209 timeoutMsg->setInt32( 1210 "generation", ++mDequeueInputTimeoutGeneration); 1211 timeoutMsg->post(timeoutUs); 1212 } 1213 break; 1214 } 1215 1216 case kWhatDequeueInputTimedOut: 1217 { 1218 int32_t generation; 1219 CHECK(msg->findInt32("generation", &generation)); 1220 1221 if (generation != mDequeueInputTimeoutGeneration) { 1222 // Obsolete 1223 break; 1224 } 1225 1226 CHECK(mFlags & kFlagDequeueInputPending); 1227 1228 sp<AMessage> response = new AMessage; 1229 response->setInt32("err", -EAGAIN); 1230 response->postReply(mDequeueInputReplyID); 1231 1232 mFlags &= ~kFlagDequeueInputPending; 1233 mDequeueInputReplyID = 0; 1234 break; 1235 } 1236 1237 case kWhatQueueInputBuffer: 1238 { 1239 uint32_t replyID; 1240 CHECK(msg->senderAwaitsResponse(&replyID)); 1241 1242 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1243 sp<AMessage> response = new AMessage; 1244 response->setInt32("err", INVALID_OPERATION); 1245 1246 response->postReply(replyID); 1247 break; 1248 } 1249 1250 status_t err = onQueueInputBuffer(msg); 1251 1252 sp<AMessage> response = new AMessage; 1253 response->setInt32("err", err); 1254 response->postReply(replyID); 1255 break; 1256 } 1257 1258 case kWhatDequeueOutputBuffer: 1259 { 1260 uint32_t replyID; 1261 CHECK(msg->senderAwaitsResponse(&replyID)); 1262 1263 if (handleDequeueOutputBuffer(replyID, true /* new request */)) { 1264 break; 1265 } 1266 1267 int64_t timeoutUs; 1268 CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 1269 1270 if (timeoutUs == 0ll) { 1271 sp<AMessage> response = new AMessage; 1272 response->setInt32("err", -EAGAIN); 1273 response->postReply(replyID); 1274 break; 1275 } 1276 1277 mFlags |= kFlagDequeueOutputPending; 1278 mDequeueOutputReplyID = replyID; 1279 1280 if (timeoutUs > 0ll) { 1281 sp<AMessage> timeoutMsg = 1282 new AMessage(kWhatDequeueOutputTimedOut, id()); 1283 timeoutMsg->setInt32( 1284 "generation", ++mDequeueOutputTimeoutGeneration); 1285 timeoutMsg->post(timeoutUs); 1286 } 1287 break; 1288 } 1289 1290 case kWhatDequeueOutputTimedOut: 1291 { 1292 int32_t generation; 1293 CHECK(msg->findInt32("generation", &generation)); 1294 1295 if (generation != mDequeueOutputTimeoutGeneration) { 1296 // Obsolete 1297 break; 1298 } 1299 1300 CHECK(mFlags & kFlagDequeueOutputPending); 1301 1302 sp<AMessage> response = new AMessage; 1303 response->setInt32("err", -EAGAIN); 1304 response->postReply(mDequeueOutputReplyID); 1305 1306 mFlags &= ~kFlagDequeueOutputPending; 1307 mDequeueOutputReplyID = 0; 1308 break; 1309 } 1310 1311 case kWhatReleaseOutputBuffer: 1312 { 1313 uint32_t replyID; 1314 CHECK(msg->senderAwaitsResponse(&replyID)); 1315 1316 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1317 sp<AMessage> response = new AMessage; 1318 response->setInt32("err", INVALID_OPERATION); 1319 1320 response->postReply(replyID); 1321 break; 1322 } 1323 1324 status_t err = onReleaseOutputBuffer(msg); 1325 1326 sp<AMessage> response = new AMessage; 1327 response->setInt32("err", err); 1328 response->postReply(replyID); 1329 break; 1330 } 1331 1332 case kWhatSignalEndOfInputStream: 1333 { 1334 uint32_t replyID; 1335 CHECK(msg->senderAwaitsResponse(&replyID)); 1336 1337 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1338 sp<AMessage> response = new AMessage; 1339 response->setInt32("err", INVALID_OPERATION); 1340 1341 response->postReply(replyID); 1342 break; 1343 } 1344 1345 mReplyID = replyID; 1346 mCodec->signalEndOfInputStream(); 1347 break; 1348 } 1349 1350 case kWhatGetBuffers: 1351 { 1352 uint32_t replyID; 1353 CHECK(msg->senderAwaitsResponse(&replyID)); 1354 1355 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1356 sp<AMessage> response = new AMessage; 1357 response->setInt32("err", INVALID_OPERATION); 1358 1359 response->postReply(replyID); 1360 break; 1361 } 1362 1363 int32_t portIndex; 1364 CHECK(msg->findInt32("portIndex", &portIndex)); 1365 1366 Vector<sp<ABuffer> > *dstBuffers; 1367 CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); 1368 1369 dstBuffers->clear(); 1370 const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex]; 1371 1372 for (size_t i = 0; i < srcBuffers.size(); ++i) { 1373 const BufferInfo &info = srcBuffers.itemAt(i); 1374 1375 dstBuffers->push_back( 1376 (portIndex == kPortIndexInput && mCrypto != NULL) 1377 ? info.mEncryptedData : info.mData); 1378 } 1379 1380 (new AMessage)->postReply(replyID); 1381 break; 1382 } 1383 1384 case kWhatFlush: 1385 { 1386 uint32_t replyID; 1387 CHECK(msg->senderAwaitsResponse(&replyID)); 1388 1389 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1390 sp<AMessage> response = new AMessage; 1391 response->setInt32("err", INVALID_OPERATION); 1392 1393 response->postReply(replyID); 1394 break; 1395 } 1396 1397 mReplyID = replyID; 1398 setState(FLUSHING); 1399 1400 mCodec->signalFlush(); 1401 returnBuffersToCodec(); 1402 break; 1403 } 1404 1405 case kWhatGetInputFormat: 1406 case kWhatGetOutputFormat: 1407 { 1408 sp<AMessage> format = 1409 (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat); 1410 1411 uint32_t replyID; 1412 CHECK(msg->senderAwaitsResponse(&replyID)); 1413 1414 if ((mState != CONFIGURED && mState != STARTING && 1415 mState != STARTED && mState != FLUSHING) 1416 || (mFlags & kFlagStickyError) 1417 || format == NULL) { 1418 sp<AMessage> response = new AMessage; 1419 response->setInt32("err", INVALID_OPERATION); 1420 1421 response->postReply(replyID); 1422 break; 1423 } 1424 1425 sp<AMessage> response = new AMessage; 1426 response->setMessage("format", format); 1427 response->postReply(replyID); 1428 break; 1429 } 1430 1431 case kWhatRequestIDRFrame: 1432 { 1433 mCodec->signalRequestIDRFrame(); 1434 break; 1435 } 1436 1437 case kWhatRequestActivityNotification: 1438 { 1439 CHECK(mActivityNotify == NULL); 1440 CHECK(msg->findMessage("notify", &mActivityNotify)); 1441 1442 postActivityNotificationIfPossible(); 1443 break; 1444 } 1445 1446 case kWhatGetName: 1447 { 1448 uint32_t replyID; 1449 CHECK(msg->senderAwaitsResponse(&replyID)); 1450 1451 if (mComponentName.empty()) { 1452 sp<AMessage> response = new AMessage; 1453 response->setInt32("err", INVALID_OPERATION); 1454 1455 response->postReply(replyID); 1456 break; 1457 } 1458 1459 sp<AMessage> response = new AMessage; 1460 response->setString("name", mComponentName.c_str()); 1461 response->postReply(replyID); 1462 break; 1463 } 1464 1465 case kWhatSetParameters: 1466 { 1467 uint32_t replyID; 1468 CHECK(msg->senderAwaitsResponse(&replyID)); 1469 1470 sp<AMessage> params; 1471 CHECK(msg->findMessage("params", ¶ms)); 1472 1473 status_t err = onSetParameters(params); 1474 1475 sp<AMessage> response = new AMessage; 1476 response->setInt32("err", err); 1477 1478 response->postReply(replyID); 1479 break; 1480 } 1481 1482 default: 1483 TRESPASS(); 1484 } 1485} 1486 1487void MediaCodec::extractCSD(const sp<AMessage> &format) { 1488 mCSD.clear(); 1489 1490 size_t i = 0; 1491 for (;;) { 1492 sp<ABuffer> csd; 1493 if (!format->findBuffer(StringPrintf("csd-%u", i).c_str(), &csd)) { 1494 break; 1495 } 1496 1497 mCSD.push_back(csd); 1498 ++i; 1499 } 1500 1501 ALOGV("Found %zu pieces of codec specific data.", mCSD.size()); 1502} 1503 1504status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) { 1505 CHECK(!mCSD.empty()); 1506 1507 const BufferInfo *info = 1508 &mPortBuffers[kPortIndexInput].itemAt(bufferIndex); 1509 1510 sp<ABuffer> csd = *mCSD.begin(); 1511 mCSD.erase(mCSD.begin()); 1512 1513 const sp<ABuffer> &codecInputData = 1514 (mCrypto != NULL) ? info->mEncryptedData : info->mData; 1515 1516 if (csd->size() > codecInputData->capacity()) { 1517 return -EINVAL; 1518 } 1519 1520 memcpy(codecInputData->data(), csd->data(), csd->size()); 1521 1522 AString errorDetailMsg; 1523 1524 sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id()); 1525 msg->setSize("index", bufferIndex); 1526 msg->setSize("offset", 0); 1527 msg->setSize("size", csd->size()); 1528 msg->setInt64("timeUs", 0ll); 1529 msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG); 1530 msg->setPointer("errorDetailMsg", &errorDetailMsg); 1531 1532 return onQueueInputBuffer(msg); 1533} 1534 1535void MediaCodec::setState(State newState) { 1536 if (newState == INITIALIZED || newState == UNINITIALIZED) { 1537 delete mSoftRenderer; 1538 mSoftRenderer = NULL; 1539 1540 mCrypto.clear(); 1541 setNativeWindow(NULL); 1542 1543 mOutputFormat.clear(); 1544 mFlags &= ~kFlagOutputFormatChanged; 1545 mFlags &= ~kFlagOutputBuffersChanged; 1546 mFlags &= ~kFlagStickyError; 1547 mFlags &= ~kFlagIsEncoder; 1548 mFlags &= ~kFlagGatherCodecSpecificData; 1549 1550 mActivityNotify.clear(); 1551 } 1552 1553 if (newState == UNINITIALIZED) { 1554 mComponentName.clear(); 1555 1556 // The component is gone, mediaserver's probably back up already 1557 // but should definitely be back up should we try to instantiate 1558 // another component.. and the cycle continues. 1559 mFlags &= ~kFlagSawMediaServerDie; 1560 } 1561 1562 mState = newState; 1563 1564 cancelPendingDequeueOperations(); 1565} 1566 1567void MediaCodec::returnBuffersToCodec() { 1568 returnBuffersToCodecOnPort(kPortIndexInput); 1569 returnBuffersToCodecOnPort(kPortIndexOutput); 1570} 1571 1572void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) { 1573 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1574 Mutex::Autolock al(mBufferLock); 1575 1576 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1577 1578 for (size_t i = 0; i < buffers->size(); ++i) { 1579 BufferInfo *info = &buffers->editItemAt(i); 1580 1581 if (info->mNotify != NULL) { 1582 sp<AMessage> msg = info->mNotify; 1583 info->mNotify = NULL; 1584 info->mOwnedByClient = false; 1585 1586 if (portIndex == kPortIndexInput) { 1587 /* no error, just returning buffers */ 1588 msg->setInt32("err", OK); 1589 } 1590 msg->post(); 1591 } 1592 } 1593 1594 mAvailPortBuffers[portIndex].clear(); 1595} 1596 1597size_t MediaCodec::updateBuffers( 1598 int32_t portIndex, const sp<AMessage> &msg) { 1599 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1600 1601 uint32_t bufferID; 1602 CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 1603 1604 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1605 1606 for (size_t i = 0; i < buffers->size(); ++i) { 1607 BufferInfo *info = &buffers->editItemAt(i); 1608 1609 if (info->mBufferID == bufferID) { 1610 CHECK(info->mNotify == NULL); 1611 CHECK(msg->findMessage("reply", &info->mNotify)); 1612 1613 mAvailPortBuffers[portIndex].push_back(i); 1614 1615 return i; 1616 } 1617 } 1618 1619 TRESPASS(); 1620 1621 return 0; 1622} 1623 1624status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { 1625 size_t index; 1626 size_t offset; 1627 size_t size; 1628 int64_t timeUs; 1629 uint32_t flags; 1630 CHECK(msg->findSize("index", &index)); 1631 CHECK(msg->findSize("offset", &offset)); 1632 CHECK(msg->findInt64("timeUs", &timeUs)); 1633 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 1634 1635 const CryptoPlugin::SubSample *subSamples; 1636 size_t numSubSamples; 1637 const uint8_t *key; 1638 const uint8_t *iv; 1639 CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted; 1640 1641 // We allow the simpler queueInputBuffer API to be used even in 1642 // secure mode, by fabricating a single unencrypted subSample. 1643 CryptoPlugin::SubSample ss; 1644 1645 if (msg->findSize("size", &size)) { 1646 if (mCrypto != NULL) { 1647 ss.mNumBytesOfClearData = size; 1648 ss.mNumBytesOfEncryptedData = 0; 1649 1650 subSamples = &ss; 1651 numSubSamples = 1; 1652 key = NULL; 1653 iv = NULL; 1654 } 1655 } else { 1656 if (mCrypto == NULL) { 1657 return -EINVAL; 1658 } 1659 1660 CHECK(msg->findPointer("subSamples", (void **)&subSamples)); 1661 CHECK(msg->findSize("numSubSamples", &numSubSamples)); 1662 CHECK(msg->findPointer("key", (void **)&key)); 1663 CHECK(msg->findPointer("iv", (void **)&iv)); 1664 1665 int32_t tmp; 1666 CHECK(msg->findInt32("mode", &tmp)); 1667 1668 mode = (CryptoPlugin::Mode)tmp; 1669 1670 size = 0; 1671 for (size_t i = 0; i < numSubSamples; ++i) { 1672 size += subSamples[i].mNumBytesOfClearData; 1673 size += subSamples[i].mNumBytesOfEncryptedData; 1674 } 1675 } 1676 1677 if (index >= mPortBuffers[kPortIndexInput].size()) { 1678 return -ERANGE; 1679 } 1680 1681 BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index); 1682 1683 if (info->mNotify == NULL || !info->mOwnedByClient) { 1684 return -EACCES; 1685 } 1686 1687 if (offset + size > info->mData->capacity()) { 1688 return -EINVAL; 1689 } 1690 1691 sp<AMessage> reply = info->mNotify; 1692 info->mData->setRange(offset, size); 1693 info->mData->meta()->setInt64("timeUs", timeUs); 1694 1695 if (flags & BUFFER_FLAG_EOS) { 1696 info->mData->meta()->setInt32("eos", true); 1697 } 1698 1699 if (flags & BUFFER_FLAG_CODECCONFIG) { 1700 info->mData->meta()->setInt32("csd", true); 1701 } 1702 1703 if (mCrypto != NULL) { 1704 if (size > info->mEncryptedData->capacity()) { 1705 return -ERANGE; 1706 } 1707 1708 AString *errorDetailMsg; 1709 CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg)); 1710 1711 ssize_t result = mCrypto->decrypt( 1712 (mFlags & kFlagIsSecure) != 0, 1713 key, 1714 iv, 1715 mode, 1716 info->mEncryptedData->base() + offset, 1717 subSamples, 1718 numSubSamples, 1719 info->mData->base(), 1720 errorDetailMsg); 1721 1722 if (result < 0) { 1723 return result; 1724 } 1725 1726 info->mData->setRange(0, result); 1727 } 1728 1729 // synchronization boundary for getBufferAndFormat 1730 { 1731 Mutex::Autolock al(mBufferLock); 1732 info->mOwnedByClient = false; 1733 } 1734 reply->setBuffer("buffer", info->mData); 1735 reply->post(); 1736 1737 info->mNotify = NULL; 1738 1739 return OK; 1740} 1741 1742status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) { 1743 size_t index; 1744 CHECK(msg->findSize("index", &index)); 1745 1746 int32_t render; 1747 if (!msg->findInt32("render", &render)) { 1748 render = 0; 1749 } 1750 1751 if (mState != STARTED) { 1752 return -EINVAL; 1753 } 1754 1755 if (index >= mPortBuffers[kPortIndexOutput].size()) { 1756 return -ERANGE; 1757 } 1758 1759 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 1760 1761 if (info->mNotify == NULL || !info->mOwnedByClient) { 1762 return -EACCES; 1763 } 1764 1765 // synchronization boundary for getBufferAndFormat 1766 { 1767 Mutex::Autolock al(mBufferLock); 1768 info->mOwnedByClient = false; 1769 } 1770 1771 if (render && info->mData != NULL && info->mData->size() != 0) { 1772 info->mNotify->setInt32("render", true); 1773 1774 int64_t timestampNs = 0; 1775 if (msg->findInt64("timestampNs", ×tampNs)) { 1776 info->mNotify->setInt64("timestampNs", timestampNs); 1777 } else { 1778 // TODO: it seems like we should use the timestamp 1779 // in the (media)buffer as it potentially came from 1780 // an input surface, but we did not propagate it prior to 1781 // API 20. Perhaps check for target SDK version. 1782#if 0 1783 if (info->mData->meta()->findInt64("timeUs", ×tampNs)) { 1784 ALOGV("using buffer PTS of %" PRId64, timestampNs); 1785 timestampNs *= 1000; 1786 } 1787#endif 1788 } 1789 1790 if (mSoftRenderer != NULL) { 1791 mSoftRenderer->render( 1792 info->mData->data(), info->mData->size(), timestampNs, NULL); 1793 } 1794 } 1795 1796 info->mNotify->post(); 1797 info->mNotify = NULL; 1798 1799 return OK; 1800} 1801 1802ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) { 1803 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1804 1805 List<size_t> *availBuffers = &mAvailPortBuffers[portIndex]; 1806 1807 if (availBuffers->empty()) { 1808 return -EAGAIN; 1809 } 1810 1811 size_t index = *availBuffers->begin(); 1812 availBuffers->erase(availBuffers->begin()); 1813 1814 BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index); 1815 CHECK(!info->mOwnedByClient); 1816 { 1817 Mutex::Autolock al(mBufferLock); 1818 info->mFormat = portIndex == kPortIndexInput ? mInputFormat : mOutputFormat; 1819 info->mOwnedByClient = true; 1820 } 1821 1822 return index; 1823} 1824 1825status_t MediaCodec::setNativeWindow( 1826 const sp<Surface> &surfaceTextureClient) { 1827 status_t err; 1828 1829 if (mNativeWindow != NULL) { 1830 err = native_window_api_disconnect( 1831 mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA); 1832 1833 if (err != OK) { 1834 ALOGW("native_window_api_disconnect returned an error: %s (%d)", 1835 strerror(-err), err); 1836 } 1837 1838 mNativeWindow.clear(); 1839 } 1840 1841 if (surfaceTextureClient != NULL) { 1842 err = native_window_api_connect( 1843 surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA); 1844 1845 if (err != OK) { 1846 ALOGE("native_window_api_connect returned an error: %s (%d)", 1847 strerror(-err), err); 1848 1849 return err; 1850 } 1851 1852 mNativeWindow = surfaceTextureClient; 1853 } 1854 1855 return OK; 1856} 1857 1858void MediaCodec::postActivityNotificationIfPossible() { 1859 if (mActivityNotify == NULL) { 1860 return; 1861 } 1862 1863 if ((mFlags & (kFlagStickyError 1864 | kFlagOutputBuffersChanged 1865 | kFlagOutputFormatChanged)) 1866 || !mAvailPortBuffers[kPortIndexInput].empty() 1867 || !mAvailPortBuffers[kPortIndexOutput].empty()) { 1868 mActivityNotify->post(); 1869 mActivityNotify.clear(); 1870 } 1871} 1872 1873status_t MediaCodec::setParameters(const sp<AMessage> ¶ms) { 1874 sp<AMessage> msg = new AMessage(kWhatSetParameters, id()); 1875 msg->setMessage("params", params); 1876 1877 sp<AMessage> response; 1878 return PostAndAwaitResponse(msg, &response); 1879} 1880 1881status_t MediaCodec::onSetParameters(const sp<AMessage> ¶ms) { 1882 mCodec->signalSetParameters(params); 1883 1884 return OK; 1885} 1886 1887status_t MediaCodec::amendOutputFormatWithCodecSpecificData( 1888 const sp<ABuffer> &buffer) { 1889 AString mime; 1890 CHECK(mOutputFormat->findString("mime", &mime)); 1891 1892 if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 1893 // Codec specific data should be SPS and PPS in a single buffer, 1894 // each prefixed by a startcode (0x00 0x00 0x00 0x01). 1895 // We separate the two and put them into the output format 1896 // under the keys "csd-0" and "csd-1". 1897 1898 unsigned csdIndex = 0; 1899 1900 const uint8_t *data = buffer->data(); 1901 size_t size = buffer->size(); 1902 1903 const uint8_t *nalStart; 1904 size_t nalSize; 1905 while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 1906 sp<ABuffer> csd = new ABuffer(nalSize + 4); 1907 memcpy(csd->data(), "\x00\x00\x00\x01", 4); 1908 memcpy(csd->data() + 4, nalStart, nalSize); 1909 1910 mOutputFormat->setBuffer( 1911 StringPrintf("csd-%u", csdIndex).c_str(), csd); 1912 1913 ++csdIndex; 1914 } 1915 1916 if (csdIndex != 2) { 1917 return ERROR_MALFORMED; 1918 } 1919 } else { 1920 // For everything else we just stash the codec specific data into 1921 // the output format as a single piece of csd under "csd-0". 1922 mOutputFormat->setBuffer("csd-0", buffer); 1923 } 1924 1925 return OK; 1926} 1927 1928} // namespace android 1929