Home | History | Annotate | Download | only in nuplayer
      1 /*
      2  * Copyright (C) 2010 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 "NuPlayerDecoderBase"
     19 #include <utils/Log.h>
     20 #include <inttypes.h>
     21 
     22 #include "NuPlayerDecoderBase.h"
     23 
     24 #include "NuPlayerRenderer.h"
     25 
     26 #include <media/MediaCodecBuffer.h>
     27 #include <media/stagefright/foundation/ADebug.h>
     28 #include <media/stagefright/foundation/AMessage.h>
     29 
     30 namespace android {
     31 
     32 NuPlayer::DecoderBase::DecoderBase(const sp<AMessage> &notify)
     33     :  mNotify(notify),
     34        mBufferGeneration(0),
     35        mPaused(false),
     36        mStats(new AMessage),
     37        mRequestInputBuffersPending(false) {
     38     // Every decoder has its own looper because MediaCodec operations
     39     // are blocking, but NuPlayer needs asynchronous operations.
     40     mDecoderLooper = new ALooper;
     41     mDecoderLooper->setName("NPDecoder");
     42     mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
     43 }
     44 
     45 NuPlayer::DecoderBase::~DecoderBase() {
     46     stopLooper();
     47 }
     48 
     49 static
     50 status_t PostAndAwaitResponse(
     51         const sp<AMessage> &msg, sp<AMessage> *response) {
     52     status_t err = msg->postAndAwaitResponse(response);
     53 
     54     if (err != OK) {
     55         return err;
     56     }
     57 
     58     if (!(*response)->findInt32("err", &err)) {
     59         err = OK;
     60     }
     61 
     62     return err;
     63 }
     64 
     65 void NuPlayer::DecoderBase::configure(const sp<AMessage> &format) {
     66     sp<AMessage> msg = new AMessage(kWhatConfigure, this);
     67     msg->setMessage("format", format);
     68     msg->post();
     69 }
     70 
     71 void NuPlayer::DecoderBase::init() {
     72     mDecoderLooper->registerHandler(this);
     73 }
     74 
     75 void NuPlayer::DecoderBase::stopLooper() {
     76     mDecoderLooper->unregisterHandler(id());
     77     mDecoderLooper->stop();
     78 }
     79 
     80 void NuPlayer::DecoderBase::setParameters(const sp<AMessage> &params) {
     81     sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
     82     msg->setMessage("params", params);
     83     msg->post();
     84 }
     85 
     86 void NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
     87     sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
     88     msg->setObject("renderer", renderer);
     89     msg->post();
     90 }
     91 
     92 void NuPlayer::DecoderBase::pause() {
     93     sp<AMessage> msg = new AMessage(kWhatPause, this);
     94 
     95     sp<AMessage> response;
     96     PostAndAwaitResponse(msg, &response);
     97 }
     98 
     99 void NuPlayer::DecoderBase::signalFlush() {
    100     (new AMessage(kWhatFlush, this))->post();
    101 }
    102 
    103 void NuPlayer::DecoderBase::signalResume(bool notifyComplete) {
    104     sp<AMessage> msg = new AMessage(kWhatResume, this);
    105     msg->setInt32("notifyComplete", notifyComplete);
    106     msg->post();
    107 }
    108 
    109 void NuPlayer::DecoderBase::initiateShutdown() {
    110     (new AMessage(kWhatShutdown, this))->post();
    111 }
    112 
    113 void NuPlayer::DecoderBase::onRequestInputBuffers() {
    114     if (mRequestInputBuffersPending) {
    115         return;
    116     }
    117 
    118     // doRequestBuffers() return true if we should request more data
    119     if (doRequestBuffers()) {
    120         mRequestInputBuffersPending = true;
    121 
    122         sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
    123         msg->post(10 * 1000ll);
    124     }
    125 }
    126 
    127 void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
    128 
    129     switch (msg->what()) {
    130         case kWhatConfigure:
    131         {
    132             sp<AMessage> format;
    133             CHECK(msg->findMessage("format", &format));
    134             onConfigure(format);
    135             break;
    136         }
    137 
    138         case kWhatSetParameters:
    139         {
    140             sp<AMessage> params;
    141             CHECK(msg->findMessage("params", &params));
    142             onSetParameters(params);
    143             break;
    144         }
    145 
    146         case kWhatSetRenderer:
    147         {
    148             sp<RefBase> obj;
    149             CHECK(msg->findObject("renderer", &obj));
    150             onSetRenderer(static_cast<Renderer *>(obj.get()));
    151             break;
    152         }
    153 
    154         case kWhatPause:
    155         {
    156             sp<AReplyToken> replyID;
    157             CHECK(msg->senderAwaitsResponse(&replyID));
    158 
    159             mPaused = true;
    160 
    161             (new AMessage)->postReply(replyID);
    162             break;
    163         }
    164 
    165         case kWhatRequestInputBuffers:
    166         {
    167             mRequestInputBuffersPending = false;
    168             onRequestInputBuffers();
    169             break;
    170         }
    171 
    172         case kWhatFlush:
    173         {
    174             onFlush();
    175             break;
    176         }
    177 
    178         case kWhatResume:
    179         {
    180             int32_t notifyComplete;
    181             CHECK(msg->findInt32("notifyComplete", &notifyComplete));
    182 
    183             onResume(notifyComplete);
    184             break;
    185         }
    186 
    187         case kWhatShutdown:
    188         {
    189             onShutdown(true);
    190             break;
    191         }
    192 
    193         default:
    194             TRESPASS();
    195             break;
    196     }
    197 }
    198 
    199 void NuPlayer::DecoderBase::handleError(int32_t err)
    200 {
    201     // We cannot immediately release the codec due to buffers still outstanding
    202     // in the renderer.  We signal to the player the error so it can shutdown/release the
    203     // decoder after flushing and increment the generation to discard unnecessary messages.
    204 
    205     ++mBufferGeneration;
    206 
    207     sp<AMessage> notify = mNotify->dup();
    208     notify->setInt32("what", kWhatError);
    209     notify->setInt32("err", err);
    210     notify->post();
    211 }
    212 
    213 }  // namespace android
    214 
    215