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