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