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