1 /* 2 * Copyright (C) 2010 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 "sf2" 19 #include <inttypes.h> 20 #include <utils/Log.h> 21 22 #include <signal.h> 23 24 #include <binder/ProcessState.h> 25 26 #include <media/IMediaHTTPService.h> 27 28 #include <media/stagefright/foundation/hexdump.h> 29 #include <media/stagefright/foundation/ABuffer.h> 30 #include <media/stagefright/foundation/ADebug.h> 31 #include <media/stagefright/foundation/ALooper.h> 32 #include <media/stagefright/foundation/AMessage.h> 33 34 #include <media/stagefright/ACodec.h> 35 #include <media/stagefright/DataSource.h> 36 #include <media/stagefright/MediaBuffer.h> 37 #include <media/stagefright/MediaDefs.h> 38 #include <media/stagefright/MediaExtractor.h> 39 #include <media/stagefright/MediaSource.h> 40 #include <media/stagefright/MetaData.h> 41 #include <media/stagefright/NativeWindowWrapper.h> 42 #include <media/stagefright/Utils.h> 43 44 #include <gui/SurfaceComposerClient.h> 45 46 #include "include/ESDS.h" 47 48 using namespace android; 49 50 volatile static bool ctrlc = false; 51 52 static sighandler_t oldhandler = NULL; 53 54 static void mysighandler(int signum) { 55 if (signum == SIGINT) { 56 ctrlc = true; 57 return; 58 } 59 oldhandler(signum); 60 } 61 62 struct Controller : public AHandler { 63 Controller(const char *uri, bool decodeAudio, 64 const sp<Surface> &surface, bool renderToSurface) 65 : mURI(uri), 66 mDecodeAudio(decodeAudio), 67 mSurface(surface), 68 mRenderToSurface(renderToSurface), 69 mCodec(new ACodec), 70 mIsVorbis(false) { 71 CHECK(!mDecodeAudio || mSurface == NULL); 72 } 73 74 void startAsync() { 75 (new AMessage(kWhatStart, id()))->post(); 76 } 77 78 protected: 79 virtual ~Controller() { 80 } 81 82 virtual void printStatistics() { 83 int64_t delayUs = ALooper::GetNowUs() - mStartTimeUs; 84 85 if (mDecodeAudio) { 86 printf("%" PRId64 " bytes received. %.2f KB/sec\n", 87 mTotalBytesReceived, 88 mTotalBytesReceived * 1E6 / 1024 / delayUs); 89 } else { 90 printf("%d frames decoded, %.2f fps. %" PRId64 " bytes " 91 "received. %.2f KB/sec\n", 92 mNumOutputBuffersReceived, 93 mNumOutputBuffersReceived * 1E6 / delayUs, 94 mTotalBytesReceived, 95 mTotalBytesReceived * 1E6 / 1024 / delayUs); 96 } 97 } 98 99 virtual void onMessageReceived(const sp<AMessage> &msg) { 100 if (ctrlc) { 101 printf("\n"); 102 printStatistics(); 103 (new AMessage(kWhatStop, id()))->post(); 104 ctrlc = false; 105 } 106 switch (msg->what()) { 107 case kWhatStart: 108 { 109 #if 1 110 mDecodeLooper = looper(); 111 #else 112 mDecodeLooper = new ALooper; 113 mDecodeLooper->setName("sf2 decode looper"); 114 mDecodeLooper->start(); 115 #endif 116 117 sp<DataSource> dataSource = 118 DataSource::CreateFromURI( 119 NULL /* httpService */, mURI.c_str()); 120 121 sp<MediaExtractor> extractor = 122 MediaExtractor::Create(dataSource); 123 124 for (size_t i = 0; i < extractor->countTracks(); ++i) { 125 sp<MetaData> meta = extractor->getTrackMetaData(i); 126 127 const char *mime; 128 CHECK(meta->findCString(kKeyMIMEType, &mime)); 129 130 if (!strncasecmp(mDecodeAudio ? "audio/" : "video/", 131 mime, 6)) { 132 mSource = extractor->getTrack(i); 133 134 if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) { 135 mIsVorbis = true; 136 } else { 137 mIsVorbis = false; 138 } 139 break; 140 } 141 } 142 if (mSource == NULL) { 143 printf("no %s track found\n", mDecodeAudio ? "audio" : "video"); 144 exit (1); 145 } 146 147 CHECK_EQ(mSource->start(), (status_t)OK); 148 149 mDecodeLooper->registerHandler(mCodec); 150 151 mCodec->setNotificationMessage( 152 new AMessage(kWhatCodecNotify, id())); 153 154 sp<AMessage> format = makeFormat(mSource->getFormat()); 155 156 if (mSurface != NULL) { 157 format->setObject( 158 "native-window", new NativeWindowWrapper(mSurface)); 159 } 160 161 mCodec->initiateSetup(format); 162 163 mCSDIndex = 0; 164 mStartTimeUs = ALooper::GetNowUs(); 165 mNumOutputBuffersReceived = 0; 166 mTotalBytesReceived = 0; 167 mLeftOverBuffer = NULL; 168 mFinalResult = OK; 169 mSeekState = SEEK_NONE; 170 171 // (new AMessage(kWhatSeek, id()))->post(5000000ll); 172 break; 173 } 174 175 case kWhatSeek: 176 { 177 printf("+"); 178 fflush(stdout); 179 180 CHECK(mSeekState == SEEK_NONE 181 || mSeekState == SEEK_FLUSH_COMPLETED); 182 183 if (mLeftOverBuffer != NULL) { 184 mLeftOverBuffer->release(); 185 mLeftOverBuffer = NULL; 186 } 187 188 mSeekState = SEEK_FLUSHING; 189 mSeekTimeUs = 30000000ll; 190 191 mCodec->signalFlush(); 192 break; 193 } 194 195 case kWhatStop: 196 { 197 if (mLeftOverBuffer != NULL) { 198 mLeftOverBuffer->release(); 199 mLeftOverBuffer = NULL; 200 } 201 202 CHECK_EQ(mSource->stop(), (status_t)OK); 203 mSource.clear(); 204 205 mCodec->initiateShutdown(); 206 break; 207 } 208 209 case kWhatCodecNotify: 210 { 211 int32_t what; 212 CHECK(msg->findInt32("what", &what)); 213 214 if (what == CodecBase::kWhatFillThisBuffer) { 215 onFillThisBuffer(msg); 216 } else if (what == CodecBase::kWhatDrainThisBuffer) { 217 if ((mNumOutputBuffersReceived++ % 16) == 0) { 218 printf("."); 219 fflush(stdout); 220 } 221 222 onDrainThisBuffer(msg); 223 } else if (what == CodecBase::kWhatEOS 224 || what == CodecBase::kWhatError) { 225 printf((what == CodecBase::kWhatEOS) ? "$\n" : "E\n"); 226 227 printStatistics(); 228 (new AMessage(kWhatStop, id()))->post(); 229 } else if (what == CodecBase::kWhatFlushCompleted) { 230 mSeekState = SEEK_FLUSH_COMPLETED; 231 mCodec->signalResume(); 232 233 (new AMessage(kWhatSeek, id()))->post(5000000ll); 234 } else if (what == CodecBase::kWhatOutputFormatChanged) { 235 } else if (what == CodecBase::kWhatShutdownCompleted) { 236 mDecodeLooper->unregisterHandler(mCodec->id()); 237 238 if (mDecodeLooper != looper()) { 239 mDecodeLooper->stop(); 240 } 241 242 looper()->stop(); 243 } 244 break; 245 } 246 247 default: 248 TRESPASS(); 249 break; 250 } 251 } 252 253 private: 254 enum { 255 kWhatStart = 'strt', 256 kWhatStop = 'stop', 257 kWhatCodecNotify = 'noti', 258 kWhatSeek = 'seek', 259 }; 260 261 sp<ALooper> mDecodeLooper; 262 263 AString mURI; 264 bool mDecodeAudio; 265 sp<Surface> mSurface; 266 bool mRenderToSurface; 267 sp<ACodec> mCodec; 268 sp<MediaSource> mSource; 269 bool mIsVorbis; 270 271 Vector<sp<ABuffer> > mCSD; 272 size_t mCSDIndex; 273 274 MediaBuffer *mLeftOverBuffer; 275 status_t mFinalResult; 276 277 int64_t mStartTimeUs; 278 int32_t mNumOutputBuffersReceived; 279 int64_t mTotalBytesReceived; 280 281 enum SeekState { 282 SEEK_NONE, 283 SEEK_FLUSHING, 284 SEEK_FLUSH_COMPLETED, 285 }; 286 SeekState mSeekState; 287 int64_t mSeekTimeUs; 288 289 sp<AMessage> makeFormat(const sp<MetaData> &meta) { 290 CHECK(mCSD.isEmpty()); 291 292 const char *mime; 293 CHECK(meta->findCString(kKeyMIMEType, &mime)); 294 295 sp<AMessage> msg = new AMessage; 296 msg->setString("mime", mime); 297 298 if (!strncasecmp("video/", mime, 6)) { 299 int32_t width, height; 300 CHECK(meta->findInt32(kKeyWidth, &width)); 301 CHECK(meta->findInt32(kKeyHeight, &height)); 302 303 msg->setInt32("width", width); 304 msg->setInt32("height", height); 305 } else { 306 CHECK(!strncasecmp("audio/", mime, 6)); 307 308 int32_t numChannels, sampleRate; 309 CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 310 CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 311 312 msg->setInt32("channel-count", numChannels); 313 msg->setInt32("sample-rate", sampleRate); 314 315 int32_t isADTS; 316 if (meta->findInt32(kKeyIsADTS, &isADTS) && isADTS != 0) { 317 msg->setInt32("is-adts", true); 318 } 319 } 320 321 uint32_t type; 322 const void *data; 323 size_t size; 324 if (meta->findData(kKeyAVCC, &type, &data, &size)) { 325 // Parse the AVCDecoderConfigurationRecord 326 327 const uint8_t *ptr = (const uint8_t *)data; 328 329 CHECK(size >= 7); 330 CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 331 uint8_t profile = ptr[1]; 332 uint8_t level = ptr[3]; 333 334 // There is decodable content out there that fails the following 335 // assertion, let's be lenient for now... 336 // CHECK((ptr[4] >> 2) == 0x3f); // reserved 337 338 size_t lengthSize = 1 + (ptr[4] & 3); 339 340 // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 341 // violates it... 342 // CHECK((ptr[5] >> 5) == 7); // reserved 343 344 size_t numSeqParameterSets = ptr[5] & 31; 345 346 ptr += 6; 347 size -= 6; 348 349 sp<ABuffer> buffer = new ABuffer(1024); 350 buffer->setRange(0, 0); 351 352 for (size_t i = 0; i < numSeqParameterSets; ++i) { 353 CHECK(size >= 2); 354 size_t length = U16_AT(ptr); 355 356 ptr += 2; 357 size -= 2; 358 359 CHECK(size >= length); 360 361 memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 362 memcpy(buffer->data() + buffer->size() + 4, ptr, length); 363 buffer->setRange(0, buffer->size() + 4 + length); 364 365 ptr += length; 366 size -= length; 367 } 368 369 buffer->meta()->setInt32("csd", true); 370 mCSD.push(buffer); 371 372 buffer = new ABuffer(1024); 373 buffer->setRange(0, 0); 374 375 CHECK(size >= 1); 376 size_t numPictureParameterSets = *ptr; 377 ++ptr; 378 --size; 379 380 for (size_t i = 0; i < numPictureParameterSets; ++i) { 381 CHECK(size >= 2); 382 size_t length = U16_AT(ptr); 383 384 ptr += 2; 385 size -= 2; 386 387 CHECK(size >= length); 388 389 memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 390 memcpy(buffer->data() + buffer->size() + 4, ptr, length); 391 buffer->setRange(0, buffer->size() + 4 + length); 392 393 ptr += length; 394 size -= length; 395 } 396 397 buffer->meta()->setInt32("csd", true); 398 mCSD.push(buffer); 399 400 msg->setBuffer("csd", buffer); 401 } else if (meta->findData(kKeyESDS, &type, &data, &size)) { 402 ESDS esds((const char *)data, size); 403 CHECK_EQ(esds.InitCheck(), (status_t)OK); 404 405 const void *codec_specific_data; 406 size_t codec_specific_data_size; 407 esds.getCodecSpecificInfo( 408 &codec_specific_data, &codec_specific_data_size); 409 410 sp<ABuffer> buffer = new ABuffer(codec_specific_data_size); 411 412 memcpy(buffer->data(), codec_specific_data, 413 codec_specific_data_size); 414 415 buffer->meta()->setInt32("csd", true); 416 mCSD.push(buffer); 417 } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 418 sp<ABuffer> buffer = new ABuffer(size); 419 memcpy(buffer->data(), data, size); 420 421 buffer->meta()->setInt32("csd", true); 422 mCSD.push(buffer); 423 424 CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size)); 425 426 buffer = new ABuffer(size); 427 memcpy(buffer->data(), data, size); 428 429 buffer->meta()->setInt32("csd", true); 430 mCSD.push(buffer); 431 } 432 433 int32_t maxInputSize; 434 if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 435 msg->setInt32("max-input-size", maxInputSize); 436 } 437 438 return msg; 439 } 440 441 void onFillThisBuffer(const sp<AMessage> &msg) { 442 sp<AMessage> reply; 443 CHECK(msg->findMessage("reply", &reply)); 444 445 if (mSource == NULL || mSeekState == SEEK_FLUSHING) { 446 reply->setInt32("err", ERROR_END_OF_STREAM); 447 reply->post(); 448 return; 449 } 450 451 sp<ABuffer> outBuffer; 452 CHECK(msg->findBuffer("buffer", &outBuffer)); 453 454 if (mCSDIndex < mCSD.size()) { 455 outBuffer = mCSD.editItemAt(mCSDIndex++); 456 outBuffer->meta()->setInt64("timeUs", 0); 457 } else { 458 size_t sizeLeft = outBuffer->capacity(); 459 outBuffer->setRange(0, 0); 460 461 int32_t n = 0; 462 463 for (;;) { 464 MediaBuffer *inBuffer; 465 466 if (mLeftOverBuffer != NULL) { 467 inBuffer = mLeftOverBuffer; 468 mLeftOverBuffer = NULL; 469 } else if (mFinalResult != OK) { 470 break; 471 } else { 472 MediaSource::ReadOptions options; 473 if (mSeekState == SEEK_FLUSH_COMPLETED) { 474 options.setSeekTo(mSeekTimeUs); 475 mSeekState = SEEK_NONE; 476 } 477 status_t err = mSource->read(&inBuffer, &options); 478 479 if (err != OK) { 480 mFinalResult = err; 481 break; 482 } 483 } 484 485 size_t sizeNeeded = inBuffer->range_length(); 486 if (mIsVorbis) { 487 // Vorbis data is suffixed with the number of 488 // valid samples on the page. 489 sizeNeeded += sizeof(int32_t); 490 } 491 492 if (sizeNeeded > sizeLeft) { 493 if (outBuffer->size() == 0) { 494 ALOGE("Unable to fit even a single input buffer of size %d.", 495 sizeNeeded); 496 } 497 CHECK_GT(outBuffer->size(), 0u); 498 499 mLeftOverBuffer = inBuffer; 500 break; 501 } 502 503 ++n; 504 505 if (outBuffer->size() == 0) { 506 int64_t timeUs; 507 CHECK(inBuffer->meta_data()->findInt64(kKeyTime, &timeUs)); 508 509 outBuffer->meta()->setInt64("timeUs", timeUs); 510 } 511 512 memcpy(outBuffer->data() + outBuffer->size(), 513 (const uint8_t *)inBuffer->data() 514 + inBuffer->range_offset(), 515 inBuffer->range_length()); 516 517 if (mIsVorbis) { 518 int32_t numPageSamples; 519 if (!inBuffer->meta_data()->findInt32( 520 kKeyValidSamples, &numPageSamples)) { 521 numPageSamples = -1; 522 } 523 524 memcpy(outBuffer->data() 525 + outBuffer->size() + inBuffer->range_length(), 526 &numPageSamples, sizeof(numPageSamples)); 527 } 528 529 outBuffer->setRange( 530 0, outBuffer->size() + sizeNeeded); 531 532 sizeLeft -= sizeNeeded; 533 534 inBuffer->release(); 535 inBuffer = NULL; 536 537 break; // Don't coalesce 538 } 539 540 ALOGV("coalesced %d input buffers", n); 541 542 if (outBuffer->size() == 0) { 543 CHECK_NE(mFinalResult, (status_t)OK); 544 545 reply->setInt32("err", mFinalResult); 546 reply->post(); 547 return; 548 } 549 } 550 551 reply->setBuffer("buffer", outBuffer); 552 reply->post(); 553 } 554 555 void onDrainThisBuffer(const sp<AMessage> &msg) { 556 sp<ABuffer> buffer; 557 CHECK(msg->findBuffer("buffer", &buffer)); 558 559 mTotalBytesReceived += buffer->size(); 560 561 sp<AMessage> reply; 562 CHECK(msg->findMessage("reply", &reply)); 563 564 if (mRenderToSurface) { 565 reply->setInt32("render", 1); 566 } 567 568 reply->post(); 569 } 570 571 DISALLOW_EVIL_CONSTRUCTORS(Controller); 572 }; 573 574 static void usage(const char *me) { 575 fprintf(stderr, "usage: %s\n", me); 576 fprintf(stderr, " -h(elp)\n"); 577 fprintf(stderr, " -a(udio)\n"); 578 579 fprintf(stderr, 580 " -S(urface) Allocate output buffers on a surface.\n" 581 " -R(ender) Render surface-allocated buffers.\n"); 582 } 583 584 int main(int argc, char **argv) { 585 android::ProcessState::self()->startThreadPool(); 586 587 bool decodeAudio = false; 588 bool useSurface = false; 589 bool renderToSurface = false; 590 591 int res; 592 while ((res = getopt(argc, argv, "haSR")) >= 0) { 593 switch (res) { 594 case 'a': 595 decodeAudio = true; 596 break; 597 598 case 'S': 599 useSurface = true; 600 break; 601 602 case 'R': 603 renderToSurface = true; 604 break; 605 606 case '?': 607 case 'h': 608 default: 609 { 610 usage(argv[0]); 611 return 1; 612 } 613 } 614 } 615 616 argc -= optind; 617 argv += optind; 618 619 if (argc != 1) { 620 usage(argv[-optind]); 621 return 1; 622 } 623 624 DataSource::RegisterDefaultSniffers(); 625 626 sp<ALooper> looper = new ALooper; 627 looper->setName("sf2"); 628 629 sp<SurfaceComposerClient> composerClient; 630 sp<SurfaceControl> control; 631 sp<Surface> surface; 632 633 if (!decodeAudio && useSurface) { 634 composerClient = new SurfaceComposerClient; 635 CHECK_EQ(composerClient->initCheck(), (status_t)OK); 636 637 control = composerClient->createSurface( 638 String8("A Surface"), 639 1280, 640 800, 641 PIXEL_FORMAT_RGB_565, 642 0); 643 644 CHECK(control != NULL); 645 CHECK(control->isValid()); 646 647 SurfaceComposerClient::openGlobalTransaction(); 648 CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK); 649 CHECK_EQ(control->show(), (status_t)OK); 650 SurfaceComposerClient::closeGlobalTransaction(); 651 652 surface = control->getSurface(); 653 CHECK(surface != NULL); 654 655 CHECK_EQ((status_t)OK, 656 native_window_api_connect( 657 surface.get(), NATIVE_WINDOW_API_MEDIA)); 658 } 659 660 sp<Controller> controller = 661 new Controller(argv[0], decodeAudio, surface, renderToSurface); 662 663 looper->registerHandler(controller); 664 665 signal(SIGINT, mysighandler); 666 667 controller->startAsync(); 668 669 CHECK_EQ(looper->start(true /* runOnCallingThread */), (status_t)OK); 670 671 looper->unregisterHandler(controller->id()); 672 673 if (!decodeAudio && useSurface) { 674 CHECK_EQ((status_t)OK, 675 native_window_api_disconnect( 676 surface.get(), NATIVE_WINDOW_API_MEDIA)); 677 678 composerClient->dispose(); 679 } 680 681 return 0; 682 } 683 684