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