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