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