1 /* 2 * Copyright (C) 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 "SimplePlayer" 19 #include <utils/Log.h> 20 21 #include "SimplePlayer.h" 22 23 #include <gui/Surface.h> 24 #include <media/AudioTrack.h> 25 #include <media/ICrypto.h> 26 #include <media/IMediaHTTPService.h> 27 #include <media/stagefright/foundation/ABuffer.h> 28 #include <media/stagefright/foundation/ADebug.h> 29 #include <media/stagefright/foundation/AMessage.h> 30 #include <media/stagefright/MediaCodec.h> 31 #include <media/stagefright/MediaErrors.h> 32 #include <media/stagefright/NativeWindowWrapper.h> 33 #include <media/stagefright/NuMediaExtractor.h> 34 35 namespace android { 36 37 SimplePlayer::SimplePlayer() 38 : mState(UNINITIALIZED), 39 mDoMoreStuffGeneration(0), 40 mStartTimeRealUs(-1ll) { 41 } 42 43 SimplePlayer::~SimplePlayer() { 44 } 45 46 // static 47 status_t PostAndAwaitResponse( 48 const sp<AMessage> &msg, sp<AMessage> *response) { 49 status_t err = msg->postAndAwaitResponse(response); 50 51 if (err != OK) { 52 return err; 53 } 54 55 if (!(*response)->findInt32("err", &err)) { 56 err = OK; 57 } 58 59 return err; 60 } 61 status_t SimplePlayer::setDataSource(const char *path) { 62 sp<AMessage> msg = new AMessage(kWhatSetDataSource, id()); 63 msg->setString("path", path); 64 sp<AMessage> response; 65 return PostAndAwaitResponse(msg, &response); 66 } 67 68 status_t SimplePlayer::setSurface(const sp<IGraphicBufferProducer> &bufferProducer) { 69 sp<AMessage> msg = new AMessage(kWhatSetSurface, id()); 70 71 sp<Surface> surface; 72 if (bufferProducer != NULL) { 73 surface = new Surface(bufferProducer); 74 } 75 76 msg->setObject( 77 "native-window", new NativeWindowWrapper(surface)); 78 79 sp<AMessage> response; 80 return PostAndAwaitResponse(msg, &response); 81 } 82 83 status_t SimplePlayer::prepare() { 84 sp<AMessage> msg = new AMessage(kWhatPrepare, id()); 85 sp<AMessage> response; 86 return PostAndAwaitResponse(msg, &response); 87 } 88 89 status_t SimplePlayer::start() { 90 sp<AMessage> msg = new AMessage(kWhatStart, id()); 91 sp<AMessage> response; 92 return PostAndAwaitResponse(msg, &response); 93 } 94 95 status_t SimplePlayer::stop() { 96 sp<AMessage> msg = new AMessage(kWhatStop, id()); 97 sp<AMessage> response; 98 return PostAndAwaitResponse(msg, &response); 99 } 100 101 status_t SimplePlayer::reset() { 102 sp<AMessage> msg = new AMessage(kWhatReset, id()); 103 sp<AMessage> response; 104 return PostAndAwaitResponse(msg, &response); 105 } 106 107 void SimplePlayer::onMessageReceived(const sp<AMessage> &msg) { 108 switch (msg->what()) { 109 case kWhatSetDataSource: 110 { 111 status_t err; 112 if (mState != UNINITIALIZED) { 113 err = INVALID_OPERATION; 114 } else { 115 CHECK(msg->findString("path", &mPath)); 116 mState = UNPREPARED; 117 } 118 119 uint32_t replyID; 120 CHECK(msg->senderAwaitsResponse(&replyID)); 121 122 sp<AMessage> response = new AMessage; 123 response->setInt32("err", err); 124 response->postReply(replyID); 125 break; 126 } 127 128 case kWhatSetSurface: 129 { 130 status_t err; 131 if (mState != UNPREPARED) { 132 err = INVALID_OPERATION; 133 } else { 134 sp<RefBase> obj; 135 CHECK(msg->findObject("native-window", &obj)); 136 137 mNativeWindow = static_cast<NativeWindowWrapper *>(obj.get()); 138 139 err = OK; 140 } 141 142 uint32_t replyID; 143 CHECK(msg->senderAwaitsResponse(&replyID)); 144 145 sp<AMessage> response = new AMessage; 146 response->setInt32("err", err); 147 response->postReply(replyID); 148 break; 149 } 150 151 case kWhatPrepare: 152 { 153 status_t err; 154 if (mState != UNPREPARED) { 155 err = INVALID_OPERATION; 156 } else { 157 err = onPrepare(); 158 159 if (err == OK) { 160 mState = STOPPED; 161 } 162 } 163 164 uint32_t replyID; 165 CHECK(msg->senderAwaitsResponse(&replyID)); 166 167 sp<AMessage> response = new AMessage; 168 response->setInt32("err", err); 169 response->postReply(replyID); 170 break; 171 } 172 173 case kWhatStart: 174 { 175 status_t err = OK; 176 177 if (mState == UNPREPARED) { 178 err = onPrepare(); 179 180 if (err == OK) { 181 mState = STOPPED; 182 } 183 } 184 185 if (err == OK) { 186 if (mState != STOPPED) { 187 err = INVALID_OPERATION; 188 } else { 189 err = onStart(); 190 191 if (err == OK) { 192 mState = STARTED; 193 } 194 } 195 } 196 197 uint32_t replyID; 198 CHECK(msg->senderAwaitsResponse(&replyID)); 199 200 sp<AMessage> response = new AMessage; 201 response->setInt32("err", err); 202 response->postReply(replyID); 203 break; 204 } 205 206 case kWhatStop: 207 { 208 status_t err; 209 210 if (mState != STARTED) { 211 err = INVALID_OPERATION; 212 } else { 213 err = onStop(); 214 215 if (err == OK) { 216 mState = STOPPED; 217 } 218 } 219 220 uint32_t replyID; 221 CHECK(msg->senderAwaitsResponse(&replyID)); 222 223 sp<AMessage> response = new AMessage; 224 response->setInt32("err", err); 225 response->postReply(replyID); 226 break; 227 } 228 229 case kWhatReset: 230 { 231 status_t err = OK; 232 233 if (mState == STARTED) { 234 CHECK_EQ(onStop(), (status_t)OK); 235 mState = STOPPED; 236 } 237 238 if (mState == STOPPED) { 239 err = onReset(); 240 mState = UNINITIALIZED; 241 } 242 243 uint32_t replyID; 244 CHECK(msg->senderAwaitsResponse(&replyID)); 245 246 sp<AMessage> response = new AMessage; 247 response->setInt32("err", err); 248 response->postReply(replyID); 249 break; 250 } 251 252 case kWhatDoMoreStuff: 253 { 254 int32_t generation; 255 CHECK(msg->findInt32("generation", &generation)); 256 257 if (generation != mDoMoreStuffGeneration) { 258 break; 259 } 260 261 status_t err = onDoMoreStuff(); 262 263 if (err == OK) { 264 msg->post(10000ll); 265 } 266 break; 267 } 268 269 default: 270 TRESPASS(); 271 } 272 } 273 274 status_t SimplePlayer::onPrepare() { 275 CHECK_EQ(mState, UNPREPARED); 276 277 mExtractor = new NuMediaExtractor; 278 279 status_t err = mExtractor->setDataSource( 280 NULL /* httpService */, mPath.c_str()); 281 282 if (err != OK) { 283 mExtractor.clear(); 284 return err; 285 } 286 287 if (mCodecLooper == NULL) { 288 mCodecLooper = new ALooper; 289 mCodecLooper->start(); 290 } 291 292 bool haveAudio = false; 293 bool haveVideo = false; 294 for (size_t i = 0; i < mExtractor->countTracks(); ++i) { 295 sp<AMessage> format; 296 status_t err = mExtractor->getTrackFormat(i, &format); 297 CHECK_EQ(err, (status_t)OK); 298 299 AString mime; 300 CHECK(format->findString("mime", &mime)); 301 302 bool isVideo = !strncasecmp(mime.c_str(), "video/", 6); 303 304 if (!haveAudio && !strncasecmp(mime.c_str(), "audio/", 6)) { 305 haveAudio = true; 306 } else if (!haveVideo && isVideo) { 307 haveVideo = true; 308 } else { 309 continue; 310 } 311 312 err = mExtractor->selectTrack(i); 313 CHECK_EQ(err, (status_t)OK); 314 315 CodecState *state = 316 &mStateByTrackIndex.editValueAt( 317 mStateByTrackIndex.add(i, CodecState())); 318 319 state->mNumFramesWritten = 0; 320 state->mCodec = MediaCodec::CreateByType( 321 mCodecLooper, mime.c_str(), false /* encoder */); 322 323 CHECK(state->mCodec != NULL); 324 325 err = state->mCodec->configure( 326 format, 327 isVideo ? mNativeWindow->getSurfaceTextureClient() : NULL, 328 NULL /* crypto */, 329 0 /* flags */); 330 331 CHECK_EQ(err, (status_t)OK); 332 333 size_t j = 0; 334 sp<ABuffer> buffer; 335 while (format->findBuffer(StringPrintf("csd-%d", j).c_str(), &buffer)) { 336 state->mCSD.push_back(buffer); 337 338 ++j; 339 } 340 } 341 342 for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) { 343 CodecState *state = &mStateByTrackIndex.editValueAt(i); 344 345 status_t err = state->mCodec->start(); 346 CHECK_EQ(err, (status_t)OK); 347 348 err = state->mCodec->getInputBuffers(&state->mBuffers[0]); 349 CHECK_EQ(err, (status_t)OK); 350 351 err = state->mCodec->getOutputBuffers(&state->mBuffers[1]); 352 CHECK_EQ(err, (status_t)OK); 353 354 for (size_t j = 0; j < state->mCSD.size(); ++j) { 355 const sp<ABuffer> &srcBuffer = state->mCSD.itemAt(j); 356 357 size_t index; 358 err = state->mCodec->dequeueInputBuffer(&index, -1ll); 359 CHECK_EQ(err, (status_t)OK); 360 361 const sp<ABuffer> &dstBuffer = state->mBuffers[0].itemAt(index); 362 363 CHECK_LE(srcBuffer->size(), dstBuffer->capacity()); 364 dstBuffer->setRange(0, srcBuffer->size()); 365 memcpy(dstBuffer->data(), srcBuffer->data(), srcBuffer->size()); 366 367 err = state->mCodec->queueInputBuffer( 368 index, 369 0, 370 dstBuffer->size(), 371 0ll, 372 MediaCodec::BUFFER_FLAG_CODECCONFIG); 373 CHECK_EQ(err, (status_t)OK); 374 } 375 } 376 377 return OK; 378 } 379 380 status_t SimplePlayer::onStart() { 381 CHECK_EQ(mState, STOPPED); 382 383 mStartTimeRealUs = -1ll; 384 385 sp<AMessage> msg = new AMessage(kWhatDoMoreStuff, id()); 386 msg->setInt32("generation", ++mDoMoreStuffGeneration); 387 msg->post(); 388 389 return OK; 390 } 391 392 status_t SimplePlayer::onStop() { 393 CHECK_EQ(mState, STARTED); 394 395 ++mDoMoreStuffGeneration; 396 397 return OK; 398 } 399 400 status_t SimplePlayer::onReset() { 401 CHECK_EQ(mState, STOPPED); 402 403 for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) { 404 CodecState *state = &mStateByTrackIndex.editValueAt(i); 405 406 CHECK_EQ(state->mCodec->release(), (status_t)OK); 407 } 408 409 mStartTimeRealUs = -1ll; 410 411 mStateByTrackIndex.clear(); 412 mCodecLooper.clear(); 413 mExtractor.clear(); 414 mNativeWindow.clear(); 415 mPath.clear(); 416 417 return OK; 418 } 419 420 status_t SimplePlayer::onDoMoreStuff() { 421 ALOGV("onDoMoreStuff"); 422 for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) { 423 CodecState *state = &mStateByTrackIndex.editValueAt(i); 424 425 status_t err; 426 do { 427 size_t index; 428 err = state->mCodec->dequeueInputBuffer(&index); 429 430 if (err == OK) { 431 ALOGV("dequeued input buffer on track %d", 432 mStateByTrackIndex.keyAt(i)); 433 434 state->mAvailInputBufferIndices.push_back(index); 435 } else { 436 ALOGV("dequeueInputBuffer on track %d returned %d", 437 mStateByTrackIndex.keyAt(i), err); 438 } 439 } while (err == OK); 440 441 do { 442 BufferInfo info; 443 err = state->mCodec->dequeueOutputBuffer( 444 &info.mIndex, 445 &info.mOffset, 446 &info.mSize, 447 &info.mPresentationTimeUs, 448 &info.mFlags); 449 450 if (err == OK) { 451 ALOGV("dequeued output buffer on track %d", 452 mStateByTrackIndex.keyAt(i)); 453 454 state->mAvailOutputBufferInfos.push_back(info); 455 } else if (err == INFO_FORMAT_CHANGED) { 456 err = onOutputFormatChanged(mStateByTrackIndex.keyAt(i), state); 457 CHECK_EQ(err, (status_t)OK); 458 } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) { 459 err = state->mCodec->getOutputBuffers(&state->mBuffers[1]); 460 CHECK_EQ(err, (status_t)OK); 461 } else { 462 ALOGV("dequeueOutputBuffer on track %d returned %d", 463 mStateByTrackIndex.keyAt(i), err); 464 } 465 } while (err == OK 466 || err == INFO_FORMAT_CHANGED 467 || err == INFO_OUTPUT_BUFFERS_CHANGED); 468 } 469 470 for (;;) { 471 size_t trackIndex; 472 status_t err = mExtractor->getSampleTrackIndex(&trackIndex); 473 474 if (err != OK) { 475 ALOGI("encountered input EOS."); 476 break; 477 } else { 478 CodecState *state = &mStateByTrackIndex.editValueFor(trackIndex); 479 480 if (state->mAvailInputBufferIndices.empty()) { 481 break; 482 } 483 484 size_t index = *state->mAvailInputBufferIndices.begin(); 485 state->mAvailInputBufferIndices.erase( 486 state->mAvailInputBufferIndices.begin()); 487 488 const sp<ABuffer> &dstBuffer = 489 state->mBuffers[0].itemAt(index); 490 491 err = mExtractor->readSampleData(dstBuffer); 492 CHECK_EQ(err, (status_t)OK); 493 494 int64_t timeUs; 495 CHECK_EQ(mExtractor->getSampleTime(&timeUs), (status_t)OK); 496 497 err = state->mCodec->queueInputBuffer( 498 index, 499 dstBuffer->offset(), 500 dstBuffer->size(), 501 timeUs, 502 0); 503 CHECK_EQ(err, (status_t)OK); 504 505 ALOGV("enqueued input data on track %d", trackIndex); 506 507 err = mExtractor->advance(); 508 CHECK_EQ(err, (status_t)OK); 509 } 510 } 511 512 int64_t nowUs = ALooper::GetNowUs(); 513 514 if (mStartTimeRealUs < 0ll) { 515 mStartTimeRealUs = nowUs + 1000000ll; 516 } 517 518 for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) { 519 CodecState *state = &mStateByTrackIndex.editValueAt(i); 520 521 while (!state->mAvailOutputBufferInfos.empty()) { 522 BufferInfo *info = &*state->mAvailOutputBufferInfos.begin(); 523 524 int64_t whenRealUs = info->mPresentationTimeUs + mStartTimeRealUs; 525 int64_t lateByUs = nowUs - whenRealUs; 526 527 if (lateByUs > -10000ll) { 528 bool release = true; 529 530 if (lateByUs > 30000ll) { 531 ALOGI("track %d buffer late by %lld us, dropping.", 532 mStateByTrackIndex.keyAt(i), lateByUs); 533 state->mCodec->releaseOutputBuffer(info->mIndex); 534 } else { 535 if (state->mAudioTrack != NULL) { 536 const sp<ABuffer> &srcBuffer = 537 state->mBuffers[1].itemAt(info->mIndex); 538 539 renderAudio(state, info, srcBuffer); 540 541 if (info->mSize > 0) { 542 release = false; 543 } 544 } 545 546 if (release) { 547 state->mCodec->renderOutputBufferAndRelease( 548 info->mIndex); 549 } 550 } 551 552 if (release) { 553 state->mAvailOutputBufferInfos.erase( 554 state->mAvailOutputBufferInfos.begin()); 555 556 info = NULL; 557 } else { 558 break; 559 } 560 } else { 561 ALOGV("track %d buffer early by %lld us.", 562 mStateByTrackIndex.keyAt(i), -lateByUs); 563 break; 564 } 565 } 566 } 567 568 return OK; 569 } 570 571 status_t SimplePlayer::onOutputFormatChanged( 572 size_t trackIndex, CodecState *state) { 573 sp<AMessage> format; 574 status_t err = state->mCodec->getOutputFormat(&format); 575 576 if (err != OK) { 577 return err; 578 } 579 580 AString mime; 581 CHECK(format->findString("mime", &mime)); 582 583 if (!strncasecmp(mime.c_str(), "audio/", 6)) { 584 int32_t channelCount; 585 int32_t sampleRate; 586 CHECK(format->findInt32("channel-count", &channelCount)); 587 CHECK(format->findInt32("sample-rate", &sampleRate)); 588 589 state->mAudioTrack = new AudioTrack( 590 AUDIO_STREAM_MUSIC, 591 sampleRate, 592 AUDIO_FORMAT_PCM_16_BIT, 593 audio_channel_out_mask_from_count(channelCount), 594 0); 595 596 state->mNumFramesWritten = 0; 597 } 598 599 return OK; 600 } 601 602 void SimplePlayer::renderAudio( 603 CodecState *state, BufferInfo *info, const sp<ABuffer> &buffer) { 604 CHECK(state->mAudioTrack != NULL); 605 606 if (state->mAudioTrack->stopped()) { 607 state->mAudioTrack->start(); 608 } 609 610 uint32_t numFramesPlayed; 611 CHECK_EQ(state->mAudioTrack->getPosition(&numFramesPlayed), (status_t)OK); 612 613 uint32_t numFramesAvailableToWrite = 614 state->mAudioTrack->frameCount() 615 - (state->mNumFramesWritten - numFramesPlayed); 616 617 size_t numBytesAvailableToWrite = 618 numFramesAvailableToWrite * state->mAudioTrack->frameSize(); 619 620 size_t copy = info->mSize; 621 if (copy > numBytesAvailableToWrite) { 622 copy = numBytesAvailableToWrite; 623 } 624 625 if (copy == 0) { 626 return; 627 } 628 629 int64_t startTimeUs = ALooper::GetNowUs(); 630 631 ssize_t nbytes = state->mAudioTrack->write( 632 buffer->base() + info->mOffset, copy); 633 634 CHECK_EQ(nbytes, (ssize_t)copy); 635 636 int64_t delayUs = ALooper::GetNowUs() - startTimeUs; 637 638 uint32_t numFramesWritten = nbytes / state->mAudioTrack->frameSize(); 639 640 if (delayUs > 2000ll) { 641 ALOGW("AudioTrack::write took %lld us, numFramesAvailableToWrite=%u, " 642 "numFramesWritten=%u", 643 delayUs, numFramesAvailableToWrite, numFramesWritten); 644 } 645 646 info->mOffset += nbytes; 647 info->mSize -= nbytes; 648 649 state->mNumFramesWritten += numFramesWritten; 650 } 651 652 } // namespace android 653