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/SurfaceTextureClient.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 34namespace android { 35 36SimplePlayer::SimplePlayer() 37 : mState(UNINITIALIZED), 38 mDoMoreStuffGeneration(0), 39 mStartTimeRealUs(-1ll) { 40} 41 42SimplePlayer::~SimplePlayer() { 43} 44 45// static 46status_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} 60status_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 67status_t SimplePlayer::setSurface(const sp<ISurfaceTexture> &surfaceTexture) { 68 sp<AMessage> msg = new AMessage(kWhatSetSurface, id()); 69 70 sp<SurfaceTextureClient> surfaceTextureClient; 71 if (surfaceTexture != NULL) { 72 surfaceTextureClient = new SurfaceTextureClient(surfaceTexture); 73 } 74 75 msg->setObject( 76 "native-window", new NativeWindowWrapper(surfaceTextureClient)); 77 78 sp<AMessage> response; 79 return PostAndAwaitResponse(msg, &response); 80} 81 82status_t SimplePlayer::prepare() { 83 sp<AMessage> msg = new AMessage(kWhatPrepare, id()); 84 sp<AMessage> response; 85 return PostAndAwaitResponse(msg, &response); 86} 87 88status_t SimplePlayer::start() { 89 sp<AMessage> msg = new AMessage(kWhatStart, id()); 90 sp<AMessage> response; 91 return PostAndAwaitResponse(msg, &response); 92} 93 94status_t SimplePlayer::stop() { 95 sp<AMessage> msg = new AMessage(kWhatStop, id()); 96 sp<AMessage> response; 97 return PostAndAwaitResponse(msg, &response); 98} 99 100status_t SimplePlayer::reset() { 101 sp<AMessage> msg = new AMessage(kWhatReset, id()); 102 sp<AMessage> response; 103 return PostAndAwaitResponse(msg, &response); 104} 105 106void 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 273status_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 if (!haveAudio && !strncasecmp(mime.c_str(), "audio/", 6)) { 301 haveAudio = true; 302 } else if (!haveVideo && !strncasecmp(mime.c_str(), "video/", 6)) { 303 haveVideo = true; 304 } else { 305 continue; 306 } 307 308 err = mExtractor->selectTrack(i); 309 CHECK_EQ(err, (status_t)OK); 310 311 CodecState *state = 312 &mStateByTrackIndex.editValueAt( 313 mStateByTrackIndex.add(i, CodecState())); 314 315 state->mNumFramesWritten = 0; 316 state->mCodec = MediaCodec::CreateByType( 317 mCodecLooper, mime.c_str(), false /* encoder */); 318 319 CHECK(state->mCodec != NULL); 320 321 err = state->mCodec->configure( 322 format, 323 mNativeWindow->getSurfaceTextureClient(), 324 NULL /* crypto */, 325 0 /* flags */); 326 327 CHECK_EQ(err, (status_t)OK); 328 329 size_t j = 0; 330 sp<ABuffer> buffer; 331 while (format->findBuffer(StringPrintf("csd-%d", j).c_str(), &buffer)) { 332 state->mCSD.push_back(buffer); 333 334 ++j; 335 } 336 } 337 338 for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) { 339 CodecState *state = &mStateByTrackIndex.editValueAt(i); 340 341 status_t err = state->mCodec->start(); 342 CHECK_EQ(err, (status_t)OK); 343 344 err = state->mCodec->getInputBuffers(&state->mBuffers[0]); 345 CHECK_EQ(err, (status_t)OK); 346 347 err = state->mCodec->getOutputBuffers(&state->mBuffers[1]); 348 CHECK_EQ(err, (status_t)OK); 349 350 for (size_t j = 0; j < state->mCSD.size(); ++j) { 351 const sp<ABuffer> &srcBuffer = state->mCSD.itemAt(j); 352 353 size_t index; 354 err = state->mCodec->dequeueInputBuffer(&index, -1ll); 355 CHECK_EQ(err, (status_t)OK); 356 357 const sp<ABuffer> &dstBuffer = state->mBuffers[0].itemAt(index); 358 359 CHECK_LE(srcBuffer->size(), dstBuffer->capacity()); 360 dstBuffer->setRange(0, srcBuffer->size()); 361 memcpy(dstBuffer->data(), srcBuffer->data(), srcBuffer->size()); 362 363 err = state->mCodec->queueInputBuffer( 364 index, 365 0, 366 dstBuffer->size(), 367 0ll, 368 MediaCodec::BUFFER_FLAG_CODECCONFIG); 369 CHECK_EQ(err, (status_t)OK); 370 } 371 } 372 373 return OK; 374} 375 376status_t SimplePlayer::onStart() { 377 CHECK_EQ(mState, STOPPED); 378 379 mStartTimeRealUs = -1ll; 380 381 sp<AMessage> msg = new AMessage(kWhatDoMoreStuff, id()); 382 msg->setInt32("generation", ++mDoMoreStuffGeneration); 383 msg->post(); 384 385 return OK; 386} 387 388status_t SimplePlayer::onStop() { 389 CHECK_EQ(mState, STARTED); 390 391 ++mDoMoreStuffGeneration; 392 393 return OK; 394} 395 396status_t SimplePlayer::onReset() { 397 CHECK_EQ(mState, STOPPED); 398 399 for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) { 400 CodecState *state = &mStateByTrackIndex.editValueAt(i); 401 402 CHECK_EQ(state->mCodec->release(), (status_t)OK); 403 } 404 405 mStartTimeRealUs = -1ll; 406 407 mStateByTrackIndex.clear(); 408 mCodecLooper.clear(); 409 mExtractor.clear(); 410 mNativeWindow.clear(); 411 mPath.clear(); 412 413 return OK; 414} 415 416status_t SimplePlayer::onDoMoreStuff() { 417 ALOGV("onDoMoreStuff"); 418 for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) { 419 CodecState *state = &mStateByTrackIndex.editValueAt(i); 420 421 status_t err; 422 do { 423 size_t index; 424 err = state->mCodec->dequeueInputBuffer(&index); 425 426 if (err == OK) { 427 ALOGV("dequeued input buffer on track %d", 428 mStateByTrackIndex.keyAt(i)); 429 430 state->mAvailInputBufferIndices.push_back(index); 431 } else { 432 ALOGV("dequeueInputBuffer on track %d returned %d", 433 mStateByTrackIndex.keyAt(i), err); 434 } 435 } while (err == OK); 436 437 do { 438 BufferInfo info; 439 err = state->mCodec->dequeueOutputBuffer( 440 &info.mIndex, 441 &info.mOffset, 442 &info.mSize, 443 &info.mPresentationTimeUs, 444 &info.mFlags); 445 446 if (err == OK) { 447 ALOGV("dequeued output buffer on track %d", 448 mStateByTrackIndex.keyAt(i)); 449 450 state->mAvailOutputBufferInfos.push_back(info); 451 } else if (err == INFO_FORMAT_CHANGED) { 452 err = onOutputFormatChanged(mStateByTrackIndex.keyAt(i), state); 453 CHECK_EQ(err, (status_t)OK); 454 } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) { 455 err = state->mCodec->getOutputBuffers(&state->mBuffers[1]); 456 CHECK_EQ(err, (status_t)OK); 457 } else { 458 ALOGV("dequeueOutputBuffer on track %d returned %d", 459 mStateByTrackIndex.keyAt(i), err); 460 } 461 } while (err == OK 462 || err == INFO_FORMAT_CHANGED 463 || err == INFO_OUTPUT_BUFFERS_CHANGED); 464 } 465 466 for (;;) { 467 size_t trackIndex; 468 status_t err = mExtractor->getSampleTrackIndex(&trackIndex); 469 470 if (err != OK) { 471 ALOGI("encountered input EOS."); 472 break; 473 } else { 474 CodecState *state = &mStateByTrackIndex.editValueFor(trackIndex); 475 476 if (state->mAvailInputBufferIndices.empty()) { 477 break; 478 } 479 480 size_t index = *state->mAvailInputBufferIndices.begin(); 481 state->mAvailInputBufferIndices.erase( 482 state->mAvailInputBufferIndices.begin()); 483 484 const sp<ABuffer> &dstBuffer = 485 state->mBuffers[0].itemAt(index); 486 487 err = mExtractor->readSampleData(dstBuffer); 488 CHECK_EQ(err, (status_t)OK); 489 490 int64_t timeUs; 491 CHECK_EQ(mExtractor->getSampleTime(&timeUs), (status_t)OK); 492 493 err = state->mCodec->queueInputBuffer( 494 index, 495 dstBuffer->offset(), 496 dstBuffer->size(), 497 timeUs, 498 0); 499 CHECK_EQ(err, (status_t)OK); 500 501 ALOGV("enqueued input data on track %d", trackIndex); 502 503 err = mExtractor->advance(); 504 CHECK_EQ(err, (status_t)OK); 505 } 506 } 507 508 int64_t nowUs = ALooper::GetNowUs(); 509 510 if (mStartTimeRealUs < 0ll) { 511 mStartTimeRealUs = nowUs + 1000000ll; 512 } 513 514 for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) { 515 CodecState *state = &mStateByTrackIndex.editValueAt(i); 516 517 while (!state->mAvailOutputBufferInfos.empty()) { 518 BufferInfo *info = &*state->mAvailOutputBufferInfos.begin(); 519 520 int64_t whenRealUs = info->mPresentationTimeUs + mStartTimeRealUs; 521 int64_t lateByUs = nowUs - whenRealUs; 522 523 if (lateByUs > -10000ll) { 524 bool release = true; 525 526 if (lateByUs > 30000ll) { 527 ALOGI("track %d buffer late by %lld us, dropping.", 528 mStateByTrackIndex.keyAt(i), lateByUs); 529 state->mCodec->releaseOutputBuffer(info->mIndex); 530 } else { 531 if (state->mAudioTrack != NULL) { 532 const sp<ABuffer> &srcBuffer = 533 state->mBuffers[1].itemAt(info->mIndex); 534 535 renderAudio(state, info, srcBuffer); 536 537 if (info->mSize > 0) { 538 release = false; 539 } 540 } 541 542 if (release) { 543 state->mCodec->renderOutputBufferAndRelease( 544 info->mIndex); 545 } 546 } 547 548 if (release) { 549 state->mAvailOutputBufferInfos.erase( 550 state->mAvailOutputBufferInfos.begin()); 551 552 info = NULL; 553 } else { 554 break; 555 } 556 } else { 557 ALOGV("track %d buffer early by %lld us.", 558 mStateByTrackIndex.keyAt(i), -lateByUs); 559 break; 560 } 561 } 562 } 563 564 return OK; 565} 566 567status_t SimplePlayer::onOutputFormatChanged( 568 size_t trackIndex, CodecState *state) { 569 sp<AMessage> format; 570 status_t err = state->mCodec->getOutputFormat(&format); 571 572 if (err != OK) { 573 return err; 574 } 575 576 AString mime; 577 CHECK(format->findString("mime", &mime)); 578 579 if (!strncasecmp(mime.c_str(), "audio/", 6)) { 580 int32_t channelCount; 581 int32_t sampleRate; 582 CHECK(format->findInt32("channel-count", &channelCount)); 583 CHECK(format->findInt32("sample-rate", &sampleRate)); 584 585 state->mAudioTrack = new AudioTrack( 586 AUDIO_STREAM_MUSIC, 587 sampleRate, 588 AUDIO_FORMAT_PCM_16_BIT, 589 audio_channel_out_mask_from_count(channelCount), 590 0); 591 592 state->mNumFramesWritten = 0; 593 } 594 595 return OK; 596} 597 598void SimplePlayer::renderAudio( 599 CodecState *state, BufferInfo *info, const sp<ABuffer> &buffer) { 600 CHECK(state->mAudioTrack != NULL); 601 602 if (state->mAudioTrack->stopped()) { 603 state->mAudioTrack->start(); 604 } 605 606 uint32_t numFramesPlayed; 607 CHECK_EQ(state->mAudioTrack->getPosition(&numFramesPlayed), (status_t)OK); 608 609 uint32_t numFramesAvailableToWrite = 610 state->mAudioTrack->frameCount() 611 - (state->mNumFramesWritten - numFramesPlayed); 612 613 size_t numBytesAvailableToWrite = 614 numFramesAvailableToWrite * state->mAudioTrack->frameSize(); 615 616 size_t copy = info->mSize; 617 if (copy > numBytesAvailableToWrite) { 618 copy = numBytesAvailableToWrite; 619 } 620 621 if (copy == 0) { 622 return; 623 } 624 625 int64_t startTimeUs = ALooper::GetNowUs(); 626 627 ssize_t nbytes = state->mAudioTrack->write( 628 buffer->base() + info->mOffset, copy); 629 630 CHECK_EQ(nbytes, (ssize_t)copy); 631 632 int64_t delayUs = ALooper::GetNowUs() - startTimeUs; 633 634 uint32_t numFramesWritten = nbytes / state->mAudioTrack->frameSize(); 635 636 if (delayUs > 2000ll) { 637 ALOGW("AudioTrack::write took %lld us, numFramesAvailableToWrite=%u, " 638 "numFramesWritten=%u", 639 delayUs, numFramesAvailableToWrite, numFramesWritten); 640 } 641 642 info->mOffset += nbytes; 643 info->mSize -= nbytes; 644 645 state->mNumFramesWritten += numFramesWritten; 646} 647 648} // namespace android 649