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