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