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