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