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