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