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 "NuPlayerDecoder"
     19 #include <utils/Log.h>
     20 
     21 #include "NuPlayerDecoder.h"
     22 
     23 #include <media/stagefright/foundation/ABuffer.h>
     24 #include <media/stagefright/foundation/ADebug.h>
     25 #include <media/stagefright/foundation/AMessage.h>
     26 #include <media/stagefright/ACodec.h>
     27 #include <media/stagefright/MediaDefs.h>
     28 
     29 namespace android {
     30 
     31 NuPlayer::Decoder::Decoder(
     32         const sp<AMessage> &notify,
     33         const sp<NativeWindowWrapper> &nativeWindow)
     34     : mNotify(notify),
     35       mNativeWindow(nativeWindow) {
     36 }
     37 
     38 NuPlayer::Decoder::~Decoder() {
     39 }
     40 
     41 void NuPlayer::Decoder::configure(const sp<AMessage> &format) {
     42     CHECK(mCodec == NULL);
     43 
     44     AString mime;
     45     CHECK(format->findString("mime", &mime));
     46 
     47     sp<AMessage> notifyMsg =
     48         new AMessage(kWhatCodecNotify, id());
     49 
     50     mCSDIndex = 0;
     51     for (size_t i = 0;; ++i) {
     52         sp<ABuffer> csd;
     53         if (!format->findBuffer(StringPrintf("csd-%d", i).c_str(), &csd)) {
     54             break;
     55         }
     56 
     57         mCSD.push(csd);
     58     }
     59 
     60     if (mNativeWindow != NULL) {
     61         format->setObject("native-window", mNativeWindow);
     62     }
     63 
     64     // Current video decoders do not return from OMX_FillThisBuffer
     65     // quickly, violating the OpenMAX specs, until that is remedied
     66     // we need to invest in an extra looper to free the main event
     67     // queue.
     68     bool needDedicatedLooper = !strncasecmp(mime.c_str(), "video/", 6);
     69 
     70     mCodec = new ACodec;
     71 
     72     if (needDedicatedLooper && mCodecLooper == NULL) {
     73         mCodecLooper = new ALooper;
     74         mCodecLooper->setName("NuPlayerDecoder");
     75         mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
     76     }
     77 
     78     (needDedicatedLooper ? mCodecLooper : looper())->registerHandler(mCodec);
     79 
     80     mCodec->setNotificationMessage(notifyMsg);
     81     mCodec->initiateSetup(format);
     82 }
     83 
     84 void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
     85     switch (msg->what()) {
     86         case kWhatCodecNotify:
     87         {
     88             int32_t what;
     89             CHECK(msg->findInt32("what", &what));
     90 
     91             if (what == ACodec::kWhatFillThisBuffer) {
     92                 onFillThisBuffer(msg);
     93             } else {
     94                 sp<AMessage> notify = mNotify->dup();
     95                 notify->setMessage("codec-request", msg);
     96                 notify->post();
     97             }
     98             break;
     99         }
    100 
    101         default:
    102             TRESPASS();
    103             break;
    104     }
    105 }
    106 
    107 void NuPlayer::Decoder::onFillThisBuffer(const sp<AMessage> &msg) {
    108     sp<AMessage> reply;
    109     CHECK(msg->findMessage("reply", &reply));
    110 
    111 #if 0
    112     sp<ABuffer> outBuffer;
    113     CHECK(msg->findBuffer("buffer", &outBuffer));
    114 #else
    115     sp<ABuffer> outBuffer;
    116 #endif
    117 
    118     if (mCSDIndex < mCSD.size()) {
    119         outBuffer = mCSD.editItemAt(mCSDIndex++);
    120         outBuffer->meta()->setInt64("timeUs", 0);
    121 
    122         reply->setBuffer("buffer", outBuffer);
    123         reply->post();
    124         return;
    125     }
    126 
    127     sp<AMessage> notify = mNotify->dup();
    128     notify->setMessage("codec-request", msg);
    129     notify->post();
    130 }
    131 
    132 void NuPlayer::Decoder::signalFlush() {
    133     if (mCodec != NULL) {
    134         mCodec->signalFlush();
    135     }
    136 }
    137 
    138 void NuPlayer::Decoder::signalResume() {
    139     if (mCodec != NULL) {
    140         mCodec->signalResume();
    141     }
    142 }
    143 
    144 void NuPlayer::Decoder::initiateShutdown() {
    145     if (mCodec != NULL) {
    146         mCodec->initiateShutdown();
    147     }
    148 }
    149 
    150 }  // namespace android
    151 
    152