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> ¬ify) 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> ¶ms) { 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", ¶ms)); 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", ¬ifyComplete)); 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