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