NuPlayerDecoderBase.cpp revision 8db8813d39e3c8b5fbd580dfc3062830744afd63
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 29namespace android { 30 31NuPlayer::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 42NuPlayer::DecoderBase::~DecoderBase() { 43 mDecoderLooper->unregisterHandler(id()); 44 mDecoderLooper->stop(); 45} 46 47static 48status_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 63void NuPlayer::DecoderBase::configure(const sp<AMessage> &format) { 64 sp<AMessage> msg = new AMessage(kWhatConfigure, this); 65 msg->setMessage("format", format); 66 msg->post(); 67} 68 69void NuPlayer::DecoderBase::init() { 70 mDecoderLooper->registerHandler(this); 71} 72 73void NuPlayer::DecoderBase::setParameters(const sp<AMessage> ¶ms) { 74 sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 75 msg->setMessage("params", params); 76 msg->post(); 77} 78 79void NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) { 80 sp<AMessage> msg = new AMessage(kWhatSetRenderer, this); 81 msg->setObject("renderer", renderer); 82 msg->post(); 83} 84 85status_t NuPlayer::DecoderBase::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { 86 sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, this); 87 msg->setPointer("buffers", buffers); 88 89 sp<AMessage> response; 90 return PostAndAwaitResponse(msg, &response); 91} 92 93void NuPlayer::DecoderBase::signalFlush() { 94 (new AMessage(kWhatFlush, this))->post(); 95} 96 97void NuPlayer::DecoderBase::signalResume(bool notifyComplete) { 98 sp<AMessage> msg = new AMessage(kWhatResume, this); 99 msg->setInt32("notifyComplete", notifyComplete); 100 msg->post(); 101} 102 103void NuPlayer::DecoderBase::initiateShutdown() { 104 (new AMessage(kWhatShutdown, this))->post(); 105} 106 107void NuPlayer::DecoderBase::onRequestInputBuffers() { 108 if (mRequestInputBuffersPending) { 109 return; 110 } 111 112 // doRequestBuffers() return true if we should request more data 113 if (doRequestBuffers()) { 114 mRequestInputBuffersPending = true; 115 116 sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this); 117 msg->post(10 * 1000ll); 118 } 119} 120 121void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) { 122 123 switch (msg->what()) { 124 case kWhatConfigure: 125 { 126 sp<AMessage> format; 127 CHECK(msg->findMessage("format", &format)); 128 onConfigure(format); 129 break; 130 } 131 132 case kWhatSetParameters: 133 { 134 sp<AMessage> params; 135 CHECK(msg->findMessage("params", ¶ms)); 136 onSetParameters(params); 137 break; 138 } 139 140 case kWhatSetRenderer: 141 { 142 sp<RefBase> obj; 143 CHECK(msg->findObject("renderer", &obj)); 144 onSetRenderer(static_cast<Renderer *>(obj.get())); 145 break; 146 } 147 148 case kWhatGetInputBuffers: 149 { 150 sp<AReplyToken> replyID; 151 CHECK(msg->senderAwaitsResponse(&replyID)); 152 153 Vector<sp<ABuffer> > *dstBuffers; 154 CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); 155 156 onGetInputBuffers(dstBuffers); 157 158 (new AMessage)->postReply(replyID); 159 break; 160 } 161 162 case kWhatRequestInputBuffers: 163 { 164 mRequestInputBuffersPending = false; 165 onRequestInputBuffers(); 166 break; 167 } 168 169 case kWhatFlush: 170 { 171 onFlush(); 172 break; 173 } 174 175 case kWhatResume: 176 { 177 int32_t notifyComplete; 178 CHECK(msg->findInt32("notifyComplete", ¬ifyComplete)); 179 180 onResume(notifyComplete); 181 break; 182 } 183 184 case kWhatShutdown: 185 { 186 onShutdown(true); 187 break; 188 } 189 190 default: 191 TRESPASS(); 192 break; 193 } 194} 195 196void NuPlayer::DecoderBase::handleError(int32_t err) 197{ 198 // We cannot immediately release the codec due to buffers still outstanding 199 // in the renderer. We signal to the player the error so it can shutdown/release the 200 // decoder after flushing and increment the generation to discard unnecessary messages. 201 202 ++mBufferGeneration; 203 204 sp<AMessage> notify = mNotify->dup(); 205 notify->setInt32("what", kWhatError); 206 notify->setInt32("err", err); 207 notify->post(); 208} 209 210} // namespace android 211 212