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 "Converter" 19#include <utils/Log.h> 20 21#include "Converter.h" 22 23#include "MediaPuller.h" 24#include "include/avc_utils.h" 25 26#include <cutils/properties.h> 27#include <gui/Surface.h> 28#include <media/ICrypto.h> 29#include <media/stagefright/foundation/ABuffer.h> 30#include <media/stagefright/foundation/ADebug.h> 31#include <media/stagefright/foundation/AMessage.h> 32#include <media/stagefright/MediaBuffer.h> 33#include <media/stagefright/MediaCodec.h> 34#include <media/stagefright/MediaDefs.h> 35#include <media/stagefright/MediaErrors.h> 36 37#include <arpa/inet.h> 38 39#include <OMX_Video.h> 40 41namespace android { 42 43Converter::Converter( 44 const sp<AMessage> ¬ify, 45 const sp<ALooper> &codecLooper, 46 const sp<AMessage> &outputFormat, 47 uint32_t flags) 48 : mNotify(notify), 49 mCodecLooper(codecLooper), 50 mOutputFormat(outputFormat), 51 mFlags(flags), 52 mIsVideo(false), 53 mIsH264(false), 54 mIsPCMAudio(false), 55 mNeedToManuallyPrependSPSPPS(false), 56 mDoMoreWorkPending(false) 57#if ENABLE_SILENCE_DETECTION 58 ,mFirstSilentFrameUs(-1ll) 59 ,mInSilentMode(false) 60#endif 61 ,mPrevVideoBitrate(-1) 62 ,mNumFramesToDrop(0) 63 ,mEncodingSuspended(false) 64 { 65 AString mime; 66 CHECK(mOutputFormat->findString("mime", &mime)); 67 68 if (!strncasecmp("video/", mime.c_str(), 6)) { 69 mIsVideo = true; 70 71 mIsH264 = !strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC); 72 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime.c_str())) { 73 mIsPCMAudio = true; 74 } 75} 76 77static void ReleaseMediaBufferReference(const sp<ABuffer> &accessUnit) { 78 void *mbuf; 79 if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf) 80 && mbuf != NULL) { 81 ALOGV("releasing mbuf %p", mbuf); 82 83 accessUnit->meta()->setPointer("mediaBuffer", NULL); 84 85 static_cast<MediaBuffer *>(mbuf)->release(); 86 mbuf = NULL; 87 } 88} 89 90void Converter::releaseEncoder() { 91 if (mEncoder == NULL) { 92 return; 93 } 94 95 mEncoder->release(); 96 mEncoder.clear(); 97 98 while (!mInputBufferQueue.empty()) { 99 sp<ABuffer> accessUnit = *mInputBufferQueue.begin(); 100 mInputBufferQueue.erase(mInputBufferQueue.begin()); 101 102 ReleaseMediaBufferReference(accessUnit); 103 } 104 105 for (size_t i = 0; i < mEncoderInputBuffers.size(); ++i) { 106 sp<ABuffer> accessUnit = mEncoderInputBuffers.itemAt(i); 107 ReleaseMediaBufferReference(accessUnit); 108 } 109 110 mEncoderInputBuffers.clear(); 111 mEncoderOutputBuffers.clear(); 112} 113 114Converter::~Converter() { 115 CHECK(mEncoder == NULL); 116} 117 118void Converter::shutdownAsync() { 119 ALOGV("shutdown"); 120 (new AMessage(kWhatShutdown, id()))->post(); 121} 122 123status_t Converter::init() { 124 status_t err = initEncoder(); 125 126 if (err != OK) { 127 releaseEncoder(); 128 } 129 130 return err; 131} 132 133sp<IGraphicBufferProducer> Converter::getGraphicBufferProducer() { 134 CHECK(mFlags & FLAG_USE_SURFACE_INPUT); 135 return mGraphicBufferProducer; 136} 137 138size_t Converter::getInputBufferCount() const { 139 return mEncoderInputBuffers.size(); 140} 141 142sp<AMessage> Converter::getOutputFormat() const { 143 return mOutputFormat; 144} 145 146bool Converter::needToManuallyPrependSPSPPS() const { 147 return mNeedToManuallyPrependSPSPPS; 148} 149 150// static 151int32_t Converter::GetInt32Property( 152 const char *propName, int32_t defaultValue) { 153 char val[PROPERTY_VALUE_MAX]; 154 if (property_get(propName, val, NULL)) { 155 char *end; 156 unsigned long x = strtoul(val, &end, 10); 157 158 if (*end == '\0' && end > val && x > 0) { 159 return x; 160 } 161 } 162 163 return defaultValue; 164} 165 166status_t Converter::initEncoder() { 167 AString outputMIME; 168 CHECK(mOutputFormat->findString("mime", &outputMIME)); 169 170 bool isAudio = !strncasecmp(outputMIME.c_str(), "audio/", 6); 171 172 if (!mIsPCMAudio) { 173 mEncoder = MediaCodec::CreateByType( 174 mCodecLooper, outputMIME.c_str(), true /* encoder */); 175 176 if (mEncoder == NULL) { 177 return ERROR_UNSUPPORTED; 178 } 179 } 180 181 if (mIsPCMAudio) { 182 return OK; 183 } 184 185 int32_t audioBitrate = GetInt32Property("media.wfd.audio-bitrate", 128000); 186 int32_t videoBitrate = GetInt32Property("media.wfd.video-bitrate", 5000000); 187 mPrevVideoBitrate = videoBitrate; 188 189 ALOGI("using audio bitrate of %d bps, video bitrate of %d bps", 190 audioBitrate, videoBitrate); 191 192 if (isAudio) { 193 mOutputFormat->setInt32("bitrate", audioBitrate); 194 } else { 195 mOutputFormat->setInt32("bitrate", videoBitrate); 196 mOutputFormat->setInt32("bitrate-mode", OMX_Video_ControlRateConstant); 197 mOutputFormat->setInt32("frame-rate", 30); 198 mOutputFormat->setInt32("i-frame-interval", 15); // Iframes every 15 secs 199 200 // Configure encoder to use intra macroblock refresh mode 201 mOutputFormat->setInt32("intra-refresh-mode", OMX_VIDEO_IntraRefreshCyclic); 202 203 int width, height, mbs; 204 if (!mOutputFormat->findInt32("width", &width) 205 || !mOutputFormat->findInt32("height", &height)) { 206 return ERROR_UNSUPPORTED; 207 } 208 209 // Update macroblocks in a cyclic fashion with 10% of all MBs within 210 // frame gets updated at one time. It takes about 10 frames to 211 // completely update a whole video frame. If the frame rate is 30, 212 // it takes about 333 ms in the best case (if next frame is not an IDR) 213 // to recover from a lost/corrupted packet. 214 mbs = (((width + 15) / 16) * ((height + 15) / 16) * 10) / 100; 215 mOutputFormat->setInt32("intra-refresh-CIR-mbs", mbs); 216 } 217 218 ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str()); 219 220 mNeedToManuallyPrependSPSPPS = false; 221 222 status_t err = NO_INIT; 223 224 if (!isAudio) { 225 sp<AMessage> tmp = mOutputFormat->dup(); 226 tmp->setInt32("prepend-sps-pps-to-idr-frames", 1); 227 228 err = mEncoder->configure( 229 tmp, 230 NULL /* nativeWindow */, 231 NULL /* crypto */, 232 MediaCodec::CONFIGURE_FLAG_ENCODE); 233 234 if (err == OK) { 235 // Encoder supported prepending SPS/PPS, we don't need to emulate 236 // it. 237 mOutputFormat = tmp; 238 } else { 239 mNeedToManuallyPrependSPSPPS = true; 240 241 ALOGI("We going to manually prepend SPS and PPS to IDR frames."); 242 } 243 } 244 245 if (err != OK) { 246 // We'll get here for audio or if we failed to configure the encoder 247 // to automatically prepend SPS/PPS in the case of video. 248 249 err = mEncoder->configure( 250 mOutputFormat, 251 NULL /* nativeWindow */, 252 NULL /* crypto */, 253 MediaCodec::CONFIGURE_FLAG_ENCODE); 254 } 255 256 if (err != OK) { 257 return err; 258 } 259 260 if (mFlags & FLAG_USE_SURFACE_INPUT) { 261 CHECK(mIsVideo); 262 263 err = mEncoder->createInputSurface(&mGraphicBufferProducer); 264 265 if (err != OK) { 266 return err; 267 } 268 } 269 270 err = mEncoder->start(); 271 272 if (err != OK) { 273 return err; 274 } 275 276 err = mEncoder->getInputBuffers(&mEncoderInputBuffers); 277 278 if (err != OK) { 279 return err; 280 } 281 282 err = mEncoder->getOutputBuffers(&mEncoderOutputBuffers); 283 284 if (err != OK) { 285 return err; 286 } 287 288 if (mFlags & FLAG_USE_SURFACE_INPUT) { 289 scheduleDoMoreWork(); 290 } 291 292 return OK; 293} 294 295void Converter::notifyError(status_t err) { 296 sp<AMessage> notify = mNotify->dup(); 297 notify->setInt32("what", kWhatError); 298 notify->setInt32("err", err); 299 notify->post(); 300} 301 302// static 303bool Converter::IsSilence(const sp<ABuffer> &accessUnit) { 304 const uint8_t *ptr = accessUnit->data(); 305 const uint8_t *end = ptr + accessUnit->size(); 306 while (ptr < end) { 307 if (*ptr != 0) { 308 return false; 309 } 310 ++ptr; 311 } 312 313 return true; 314} 315 316void Converter::onMessageReceived(const sp<AMessage> &msg) { 317 switch (msg->what()) { 318 case kWhatMediaPullerNotify: 319 { 320 int32_t what; 321 CHECK(msg->findInt32("what", &what)); 322 323 if (!mIsPCMAudio && mEncoder == NULL) { 324 ALOGV("got msg '%s' after encoder shutdown.", 325 msg->debugString().c_str()); 326 327 if (what == MediaPuller::kWhatAccessUnit) { 328 sp<ABuffer> accessUnit; 329 CHECK(msg->findBuffer("accessUnit", &accessUnit)); 330 331 ReleaseMediaBufferReference(accessUnit); 332 } 333 break; 334 } 335 336 if (what == MediaPuller::kWhatEOS) { 337 mInputBufferQueue.push_back(NULL); 338 339 feedEncoderInputBuffers(); 340 341 scheduleDoMoreWork(); 342 } else { 343 CHECK_EQ(what, MediaPuller::kWhatAccessUnit); 344 345 sp<ABuffer> accessUnit; 346 CHECK(msg->findBuffer("accessUnit", &accessUnit)); 347 348 if (mNumFramesToDrop > 0 || mEncodingSuspended) { 349 if (mNumFramesToDrop > 0) { 350 --mNumFramesToDrop; 351 ALOGI("dropping frame."); 352 } 353 354 ReleaseMediaBufferReference(accessUnit); 355 break; 356 } 357 358#if 0 359 void *mbuf; 360 if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf) 361 && mbuf != NULL) { 362 ALOGI("queueing mbuf %p", mbuf); 363 } 364#endif 365 366#if ENABLE_SILENCE_DETECTION 367 if (!mIsVideo) { 368 if (IsSilence(accessUnit)) { 369 if (mInSilentMode) { 370 break; 371 } 372 373 int64_t nowUs = ALooper::GetNowUs(); 374 375 if (mFirstSilentFrameUs < 0ll) { 376 mFirstSilentFrameUs = nowUs; 377 } else if (nowUs >= mFirstSilentFrameUs + 10000000ll) { 378 mInSilentMode = true; 379 ALOGI("audio in silent mode now."); 380 break; 381 } 382 } else { 383 if (mInSilentMode) { 384 ALOGI("audio no longer in silent mode."); 385 } 386 mInSilentMode = false; 387 mFirstSilentFrameUs = -1ll; 388 } 389 } 390#endif 391 392 mInputBufferQueue.push_back(accessUnit); 393 394 feedEncoderInputBuffers(); 395 396 scheduleDoMoreWork(); 397 } 398 break; 399 } 400 401 case kWhatEncoderActivity: 402 { 403#if 0 404 int64_t whenUs; 405 if (msg->findInt64("whenUs", &whenUs)) { 406 int64_t nowUs = ALooper::GetNowUs(); 407 ALOGI("[%s] kWhatEncoderActivity after %lld us", 408 mIsVideo ? "video" : "audio", nowUs - whenUs); 409 } 410#endif 411 412 mDoMoreWorkPending = false; 413 414 if (mEncoder == NULL) { 415 break; 416 } 417 418 status_t err = doMoreWork(); 419 420 if (err != OK) { 421 notifyError(err); 422 } else { 423 scheduleDoMoreWork(); 424 } 425 break; 426 } 427 428 case kWhatRequestIDRFrame: 429 { 430 if (mEncoder == NULL) { 431 break; 432 } 433 434 if (mIsVideo) { 435 ALOGV("requesting IDR frame"); 436 mEncoder->requestIDRFrame(); 437 } 438 break; 439 } 440 441 case kWhatShutdown: 442 { 443 ALOGI("shutting down %s encoder", mIsVideo ? "video" : "audio"); 444 445 releaseEncoder(); 446 447 AString mime; 448 CHECK(mOutputFormat->findString("mime", &mime)); 449 ALOGI("encoder (%s) shut down.", mime.c_str()); 450 451 sp<AMessage> notify = mNotify->dup(); 452 notify->setInt32("what", kWhatShutdownCompleted); 453 notify->post(); 454 break; 455 } 456 457 case kWhatDropAFrame: 458 { 459 ++mNumFramesToDrop; 460 break; 461 } 462 463 case kWhatReleaseOutputBuffer: 464 { 465 if (mEncoder != NULL) { 466 size_t bufferIndex; 467 CHECK(msg->findInt32("bufferIndex", (int32_t*)&bufferIndex)); 468 CHECK(bufferIndex < mEncoderOutputBuffers.size()); 469 mEncoder->releaseOutputBuffer(bufferIndex); 470 } 471 break; 472 } 473 474 case kWhatSuspendEncoding: 475 { 476 int32_t suspend; 477 CHECK(msg->findInt32("suspend", &suspend)); 478 479 mEncodingSuspended = suspend; 480 481 if (mFlags & FLAG_USE_SURFACE_INPUT) { 482 sp<AMessage> params = new AMessage; 483 params->setInt32("drop-input-frames",suspend); 484 mEncoder->setParameters(params); 485 } 486 break; 487 } 488 489 default: 490 TRESPASS(); 491 } 492} 493 494void Converter::scheduleDoMoreWork() { 495 if (mIsPCMAudio) { 496 // There's no encoder involved in this case. 497 return; 498 } 499 500 if (mDoMoreWorkPending) { 501 return; 502 } 503 504 mDoMoreWorkPending = true; 505 506#if 1 507 if (mEncoderActivityNotify == NULL) { 508 mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, id()); 509 } 510 mEncoder->requestActivityNotification(mEncoderActivityNotify->dup()); 511#else 512 sp<AMessage> notify = new AMessage(kWhatEncoderActivity, id()); 513 notify->setInt64("whenUs", ALooper::GetNowUs()); 514 mEncoder->requestActivityNotification(notify); 515#endif 516} 517 518status_t Converter::feedRawAudioInputBuffers() { 519 // Split incoming PCM audio into buffers of 6 AUs of 80 audio frames each 520 // and add a 4 byte header according to the wifi display specs. 521 522 while (!mInputBufferQueue.empty()) { 523 sp<ABuffer> buffer = *mInputBufferQueue.begin(); 524 mInputBufferQueue.erase(mInputBufferQueue.begin()); 525 526 int16_t *ptr = (int16_t *)buffer->data(); 527 int16_t *stop = (int16_t *)(buffer->data() + buffer->size()); 528 while (ptr < stop) { 529 *ptr = htons(*ptr); 530 ++ptr; 531 } 532 533 static const size_t kFrameSize = 2 * sizeof(int16_t); // stereo 534 static const size_t kFramesPerAU = 80; 535 static const size_t kNumAUsPerPESPacket = 6; 536 537 if (mPartialAudioAU != NULL) { 538 size_t bytesMissingForFullAU = 539 kNumAUsPerPESPacket * kFramesPerAU * kFrameSize 540 - mPartialAudioAU->size() + 4; 541 542 size_t copy = buffer->size(); 543 if(copy > bytesMissingForFullAU) { 544 copy = bytesMissingForFullAU; 545 } 546 547 memcpy(mPartialAudioAU->data() + mPartialAudioAU->size(), 548 buffer->data(), 549 copy); 550 551 mPartialAudioAU->setRange(0, mPartialAudioAU->size() + copy); 552 553 buffer->setRange(buffer->offset() + copy, buffer->size() - copy); 554 555 int64_t timeUs; 556 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 557 558 int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0); 559 timeUs += copyUs; 560 buffer->meta()->setInt64("timeUs", timeUs); 561 562 if (bytesMissingForFullAU == copy) { 563 sp<AMessage> notify = mNotify->dup(); 564 notify->setInt32("what", kWhatAccessUnit); 565 notify->setBuffer("accessUnit", mPartialAudioAU); 566 notify->post(); 567 568 mPartialAudioAU.clear(); 569 } 570 } 571 572 while (buffer->size() > 0) { 573 sp<ABuffer> partialAudioAU = 574 new ABuffer( 575 4 576 + kNumAUsPerPESPacket * kFrameSize * kFramesPerAU); 577 578 uint8_t *ptr = partialAudioAU->data(); 579 ptr[0] = 0xa0; // 10100000b 580 ptr[1] = kNumAUsPerPESPacket; 581 ptr[2] = 0; // reserved, audio _emphasis_flag = 0 582 583 static const unsigned kQuantizationWordLength = 0; // 16-bit 584 static const unsigned kAudioSamplingFrequency = 2; // 48Khz 585 static const unsigned kNumberOfAudioChannels = 1; // stereo 586 587 ptr[3] = (kQuantizationWordLength << 6) 588 | (kAudioSamplingFrequency << 3) 589 | kNumberOfAudioChannels; 590 591 size_t copy = buffer->size(); 592 if (copy > partialAudioAU->size() - 4) { 593 copy = partialAudioAU->size() - 4; 594 } 595 596 memcpy(&ptr[4], buffer->data(), copy); 597 598 partialAudioAU->setRange(0, 4 + copy); 599 buffer->setRange(buffer->offset() + copy, buffer->size() - copy); 600 601 int64_t timeUs; 602 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 603 604 partialAudioAU->meta()->setInt64("timeUs", timeUs); 605 606 int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0); 607 timeUs += copyUs; 608 buffer->meta()->setInt64("timeUs", timeUs); 609 610 if (copy == partialAudioAU->capacity() - 4) { 611 sp<AMessage> notify = mNotify->dup(); 612 notify->setInt32("what", kWhatAccessUnit); 613 notify->setBuffer("accessUnit", partialAudioAU); 614 notify->post(); 615 616 partialAudioAU.clear(); 617 continue; 618 } 619 620 mPartialAudioAU = partialAudioAU; 621 } 622 } 623 624 return OK; 625} 626 627status_t Converter::feedEncoderInputBuffers() { 628 if (mIsPCMAudio) { 629 return feedRawAudioInputBuffers(); 630 } 631 632 while (!mInputBufferQueue.empty() 633 && !mAvailEncoderInputIndices.empty()) { 634 sp<ABuffer> buffer = *mInputBufferQueue.begin(); 635 mInputBufferQueue.erase(mInputBufferQueue.begin()); 636 637 size_t bufferIndex = *mAvailEncoderInputIndices.begin(); 638 mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin()); 639 640 int64_t timeUs = 0ll; 641 uint32_t flags = 0; 642 643 if (buffer != NULL) { 644 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 645 646 memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(), 647 buffer->data(), 648 buffer->size()); 649 650 void *mediaBuffer; 651 if (buffer->meta()->findPointer("mediaBuffer", &mediaBuffer) 652 && mediaBuffer != NULL) { 653 mEncoderInputBuffers.itemAt(bufferIndex)->meta() 654 ->setPointer("mediaBuffer", mediaBuffer); 655 656 buffer->meta()->setPointer("mediaBuffer", NULL); 657 } 658 } else { 659 flags = MediaCodec::BUFFER_FLAG_EOS; 660 } 661 662 status_t err = mEncoder->queueInputBuffer( 663 bufferIndex, 0, (buffer == NULL) ? 0 : buffer->size(), 664 timeUs, flags); 665 666 if (err != OK) { 667 return err; 668 } 669 } 670 671 return OK; 672} 673 674sp<ABuffer> Converter::prependCSD(const sp<ABuffer> &accessUnit) const { 675 CHECK(mCSD0 != NULL); 676 677 sp<ABuffer> dup = new ABuffer(accessUnit->size() + mCSD0->size()); 678 memcpy(dup->data(), mCSD0->data(), mCSD0->size()); 679 memcpy(dup->data() + mCSD0->size(), accessUnit->data(), accessUnit->size()); 680 681 int64_t timeUs; 682 CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 683 684 dup->meta()->setInt64("timeUs", timeUs); 685 686 return dup; 687} 688 689status_t Converter::doMoreWork() { 690 status_t err; 691 692 if (!(mFlags & FLAG_USE_SURFACE_INPUT)) { 693 for (;;) { 694 size_t bufferIndex; 695 err = mEncoder->dequeueInputBuffer(&bufferIndex); 696 697 if (err != OK) { 698 break; 699 } 700 701 mAvailEncoderInputIndices.push_back(bufferIndex); 702 } 703 704 feedEncoderInputBuffers(); 705 } 706 707 for (;;) { 708 size_t bufferIndex; 709 size_t offset; 710 size_t size; 711 int64_t timeUs; 712 uint32_t flags; 713 native_handle_t* handle = NULL; 714 err = mEncoder->dequeueOutputBuffer( 715 &bufferIndex, &offset, &size, &timeUs, &flags); 716 717 if (err != OK) { 718 if (err == INFO_FORMAT_CHANGED) { 719 continue; 720 } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) { 721 mEncoder->getOutputBuffers(&mEncoderOutputBuffers); 722 continue; 723 } 724 725 if (err == -EAGAIN) { 726 err = OK; 727 } 728 break; 729 } 730 731 if (flags & MediaCodec::BUFFER_FLAG_EOS) { 732 sp<AMessage> notify = mNotify->dup(); 733 notify->setInt32("what", kWhatEOS); 734 notify->post(); 735 } else { 736#if 0 737 if (mIsVideo) { 738 int32_t videoBitrate = GetInt32Property( 739 "media.wfd.video-bitrate", 5000000); 740 741 setVideoBitrate(videoBitrate); 742 } 743#endif 744 745 sp<ABuffer> buffer; 746 sp<ABuffer> outbuf = mEncoderOutputBuffers.itemAt(bufferIndex); 747 748 if (outbuf->meta()->findPointer("handle", (void**)&handle) && 749 handle != NULL) { 750 int32_t rangeLength, rangeOffset; 751 CHECK(outbuf->meta()->findInt32("rangeOffset", &rangeOffset)); 752 CHECK(outbuf->meta()->findInt32("rangeLength", &rangeLength)); 753 outbuf->meta()->setPointer("handle", NULL); 754 755 // MediaSender will post the following message when HDCP 756 // is done, to release the output buffer back to encoder. 757 sp<AMessage> notify(new AMessage( 758 kWhatReleaseOutputBuffer, id())); 759 notify->setInt32("bufferIndex", bufferIndex); 760 761 buffer = new ABuffer( 762 rangeLength > (int32_t)size ? rangeLength : size); 763 buffer->meta()->setPointer("handle", handle); 764 buffer->meta()->setInt32("rangeOffset", rangeOffset); 765 buffer->meta()->setInt32("rangeLength", rangeLength); 766 buffer->meta()->setMessage("notify", notify); 767 } else { 768 buffer = new ABuffer(size); 769 } 770 771 buffer->meta()->setInt64("timeUs", timeUs); 772 773 ALOGV("[%s] time %lld us (%.2f secs)", 774 mIsVideo ? "video" : "audio", timeUs, timeUs / 1E6); 775 776 memcpy(buffer->data(), outbuf->base() + offset, size); 777 778 if (flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) { 779 if (!handle) { 780 if (mIsH264) { 781 mCSD0 = buffer; 782 } 783 mOutputFormat->setBuffer("csd-0", buffer); 784 } 785 } else { 786 if (mNeedToManuallyPrependSPSPPS 787 && mIsH264 788 && (mFlags & FLAG_PREPEND_CSD_IF_NECESSARY) 789 && IsIDR(buffer)) { 790 buffer = prependCSD(buffer); 791 } 792 793 sp<AMessage> notify = mNotify->dup(); 794 notify->setInt32("what", kWhatAccessUnit); 795 notify->setBuffer("accessUnit", buffer); 796 notify->post(); 797 } 798 } 799 800 if (!handle) { 801 mEncoder->releaseOutputBuffer(bufferIndex); 802 } 803 804 if (flags & MediaCodec::BUFFER_FLAG_EOS) { 805 break; 806 } 807 } 808 809 return err; 810} 811 812void Converter::requestIDRFrame() { 813 (new AMessage(kWhatRequestIDRFrame, id()))->post(); 814} 815 816void Converter::dropAFrame() { 817 // Unsupported in surface input mode. 818 CHECK(!(mFlags & FLAG_USE_SURFACE_INPUT)); 819 820 (new AMessage(kWhatDropAFrame, id()))->post(); 821} 822 823void Converter::suspendEncoding(bool suspend) { 824 sp<AMessage> msg = new AMessage(kWhatSuspendEncoding, id()); 825 msg->setInt32("suspend", suspend); 826 msg->post(); 827} 828 829int32_t Converter::getVideoBitrate() const { 830 return mPrevVideoBitrate; 831} 832 833void Converter::setVideoBitrate(int32_t bitRate) { 834 if (mIsVideo && mEncoder != NULL && bitRate != mPrevVideoBitrate) { 835 sp<AMessage> params = new AMessage; 836 params->setInt32("video-bitrate", bitRate); 837 838 mEncoder->setParameters(params); 839 840 mPrevVideoBitrate = bitRate; 841 } 842} 843 844} // namespace android 845