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/stagefright/foundation/ADebug.h>
     27 #include <media/stagefright/foundation/AMessage.h>
     28 
     29 namespace android {
     30 
     31 NuPlayer::DecoderBase::DecoderBase(const sp<AMessage> &notify)
     32     :  mNotify(notify),
     33        mBufferGeneration(0),
     34        mPaused(false),
     35        mStats(new AMessage),
     36        mRequestInputBuffersPending(false) {
     37     // Every decoder has its own looper because MediaCodec operations
     38     // are blocking, but NuPlayer needs asynchronous operations.
     39     mDecoderLooper = new ALooper;
     40     mDecoderLooper->setName("NPDecoder");
     41     mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
     42 }
     43 
     44 NuPlayer::DecoderBase::~DecoderBase() {
     45     mDecoderLooper->unregisterHandler(id());
     46     mDecoderLooper->stop();
     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::setParameters(const sp<AMessage> &params) {
     76     sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
     77     msg->setMessage("params", params);
     78     msg->post();
     79 }
     80 
     81 void NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
     82     sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
     83     msg->setObject("renderer", renderer);
     84     msg->post();
     85 }
     86 
     87 void NuPlayer::DecoderBase::pause() {
     88     sp<AMessage> msg = new AMessage(kWhatPause, this);
     89 
     90     sp<AMessage> response;
     91     PostAndAwaitResponse(msg, &response);
     92 }
     93 
     94 status_t NuPlayer::DecoderBase::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
     95     sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, this);
     96     msg->setPointer("buffers", buffers);
     97 
     98     sp<AMessage> response;
     99     return PostAndAwaitResponse(msg, &response);
    100 }
    101 
    102 void NuPlayer::DecoderBase::signalFlush() {
    103     (new AMessage(kWhatFlush, this))->post();
    104 }
    105 
    106 void NuPlayer::DecoderBase::signalResume(bool notifyComplete) {
    107     sp<AMessage> msg = new AMessage(kWhatResume, this);
    108     msg->setInt32("notifyComplete", notifyComplete);
    109     msg->post();
    110 }
    111 
    112 void NuPlayer::DecoderBase::initiateShutdown() {
    113     (new AMessage(kWhatShutdown, this))->post();
    114 }
    115 
    116 void NuPlayer::DecoderBase::onRequestInputBuffers() {
    117     if (mRequestInputBuffersPending) {
    118         return;
    119     }
    120 
    121     // doRequestBuffers() return true if we should request more data
    122     if (doRequestBuffers()) {
    123         mRequestInputBuffersPending = true;
    124 
    125         sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
    126         msg->post(10 * 1000ll);
    127     }
    128 }
    129 
    130 void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
    131 
    132     switch (msg->what()) {
    133         case kWhatConfigure:
    134         {
    135             sp<AMessage> format;
    136             CHECK(msg->findMessage("format", &format));
    137             onConfigure(format);
    138             break;
    139         }
    140 
    141         case kWhatSetParameters:
    142         {
    143             sp<AMessage> params;
    144             CHECK(msg->findMessage("params", &params));
    145             onSetParameters(params);
    146             break;
    147         }
    148 
    149         case kWhatSetRenderer:
    150         {
    151             sp<RefBase> obj;
    152             CHECK(msg->findObject("renderer", &obj));
    153             onSetRenderer(static_cast<Renderer *>(obj.get()));
    154             break;
    155         }
    156 
    157         case kWhatPause:
    158         {
    159             sp<AReplyToken> replyID;
    160             CHECK(msg->senderAwaitsResponse(&replyID));
    161 
    162             mPaused = true;
    163 
    164             (new AMessage)->postReply(replyID);
    165             break;
    166         }
    167 
    168         case kWhatGetInputBuffers:
    169         {
    170             sp<AReplyToken> replyID;
    171             CHECK(msg->senderAwaitsResponse(&replyID));
    172 
    173             Vector<sp<ABuffer> > *dstBuffers;
    174             CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
    175 
    176             onGetInputBuffers(dstBuffers);
    177 
    178             (new AMessage)->postReply(replyID);
    179             break;
    180         }
    181 
    182         case kWhatRequestInputBuffers:
    183         {
    184             mRequestInputBuffersPending = false;
    185             onRequestInputBuffers();
    186             break;
    187         }
    188 
    189         case kWhatFlush:
    190         {
    191             onFlush();
    192             break;
    193         }
    194 
    195         case kWhatResume:
    196         {
    197             int32_t notifyComplete;
    198             CHECK(msg->findInt32("notifyComplete", &notifyComplete));
    199 
    200             onResume(notifyComplete);
    201             break;
    202         }
    203 
    204         case kWhatShutdown:
    205         {
    206             onShutdown(true);
    207             break;
    208         }
    209 
    210         default:
    211             TRESPASS();
    212             break;
    213     }
    214 }
    215 
    216 void NuPlayer::DecoderBase::handleError(int32_t err)
    217 {
    218     // We cannot immediately release the codec due to buffers still outstanding
    219     // in the renderer.  We signal to the player the error so it can shutdown/release the
    220     // decoder after flushing and increment the generation to discard unnecessary messages.
    221 
    222     ++mBufferGeneration;
    223 
    224     sp<AMessage> notify = mNotify->dup();
    225     notify->setInt32("what", kWhatError);
    226     notify->setInt32("err", err);
    227     notify->post();
    228 }
    229 
    230 }  // namespace android
    231 
    232