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