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