NuPlayerDecoderPassThrough.cpp revision bc2fb720bbd0acd122bacc67e844e982d068f6f9
1/* 2 * Copyright (C) 2014 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 "NuPlayerDecoderPassThrough" 19#include <utils/Log.h> 20#include <inttypes.h> 21 22#include "NuPlayerDecoderPassThrough.h" 23 24#include <media/ICrypto.h> 25#include <media/stagefright/foundation/ABuffer.h> 26#include <media/stagefright/foundation/ADebug.h> 27#include <media/stagefright/foundation/AMessage.h> 28#include <media/stagefright/MediaDefs.h> 29#include <media/stagefright/MediaErrors.h> 30 31namespace android { 32 33static const int kMaxPendingBuffers = 10; 34 35NuPlayer::DecoderPassThrough::DecoderPassThrough( 36 const sp<AMessage> ¬ify) 37 : Decoder(notify), 38 mNotify(notify), 39 mBufferGeneration(0), 40 mReachedEOS(true), 41 mPendingBuffers(0), 42 mComponentName("pass through decoder") { 43 mDecoderLooper = new ALooper; 44 mDecoderLooper->setName("NuPlayerDecoderPassThrough"); 45 mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 46} 47 48NuPlayer::DecoderPassThrough::~DecoderPassThrough() { 49} 50 51void NuPlayer::DecoderPassThrough::configure(const sp<AMessage> &format) { 52 sp<AMessage> msg = new AMessage(kWhatConfigure, id()); 53 msg->setMessage("format", format); 54 msg->post(); 55} 56 57void NuPlayer::DecoderPassThrough::init() { 58 mDecoderLooper->registerHandler(this); 59} 60 61void NuPlayer::DecoderPassThrough::signalFlush() { 62 (new AMessage(kWhatFlush, id()))->post(); 63} 64 65void NuPlayer::DecoderPassThrough::signalResume() { 66 (new AMessage(kWhatResume, id()))->post(); 67} 68 69void NuPlayer::DecoderPassThrough::initiateShutdown() { 70 (new AMessage(kWhatShutdown, id()))->post(); 71} 72 73bool NuPlayer::DecoderPassThrough::supportsSeamlessFormatChange( 74 const sp<AMessage> & /* targetFormat */) const { 75 return true; 76} 77 78void NuPlayer::DecoderPassThrough::onConfigure(const sp<AMessage> &format) { 79 ALOGV("[%s] onConfigure", mComponentName.c_str()); 80 mPendingBuffers = 0; 81 mReachedEOS = false; 82 ++mBufferGeneration; 83 84 requestABuffer(); 85 86 sp<AMessage> notify = mNotify->dup(); 87 notify->setInt32("what", kWhatOutputFormatChanged); 88 notify->setMessage("format", format); 89 notify->post(); 90} 91 92bool NuPlayer::DecoderPassThrough::isStaleReply(const sp<AMessage> &msg) { 93 int32_t generation; 94 CHECK(msg->findInt32("generation", &generation)); 95 return generation != mBufferGeneration; 96} 97 98void NuPlayer::DecoderPassThrough::requestABuffer() { 99 if (mPendingBuffers >= kMaxPendingBuffers || mReachedEOS) { 100 ALOGV("[%s] mReachedEOS=%d, max pending buffers(%d:%d)", 101 mComponentName.c_str(), (mReachedEOS ? 1 : 0), 102 mPendingBuffers, kMaxPendingBuffers); 103 return; 104 } 105 106 sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id()); 107 reply->setInt32("generation", mBufferGeneration); 108 109 sp<AMessage> notify = mNotify->dup(); 110 notify->setInt32("what", kWhatFillThisBuffer); 111 notify->setMessage("reply", reply); 112 notify->post(); 113 mPendingBuffers++; 114 115 sp<AMessage> message = new AMessage(kWhatRequestABuffer, id()); 116 message->setInt32("generation", mBufferGeneration); 117 message->post(); 118 return; 119} 120 121void android::NuPlayer::DecoderPassThrough::onInputBufferFilled( 122 const sp<AMessage> &msg) { 123 if (mReachedEOS) { 124 return; 125 } 126 127 sp<ABuffer> buffer; 128 msg->findBuffer("buffer", &buffer); 129 if (buffer == NULL) { 130 mReachedEOS = true; 131 132 sp<AMessage> notify = mNotify->dup(); 133 notify->setInt32("what", kWhatEOS); 134 notify->setInt32("err", ERROR_END_OF_STREAM); 135 notify->post(); 136 return; 137 } 138 139 sp<AMessage> reply = new AMessage(kWhatBufferConsumed, id()); 140 reply->setInt32("generation", mBufferGeneration); 141 142 sp<AMessage> notify = mNotify->dup(); 143 notify->setInt32("what", kWhatDrainThisBuffer); 144 notify->setBuffer("buffer", buffer); 145 notify->setMessage("reply", reply); 146 notify->post(); 147} 148 149void NuPlayer::DecoderPassThrough::onBufferConsumed() { 150 mPendingBuffers--; 151 sp<AMessage> message = new AMessage(kWhatRequestABuffer, id()); 152 message->setInt32("generation", mBufferGeneration); 153 message->post(); 154} 155 156void NuPlayer::DecoderPassThrough::onFlush() { 157 ++mBufferGeneration; 158 159 sp<AMessage> notify = mNotify->dup(); 160 notify->setInt32("what", kWhatFlushCompleted); 161 notify->post(); 162 mPendingBuffers = 0; 163 mReachedEOS = false; 164} 165 166void NuPlayer::DecoderPassThrough::onShutdown() { 167 ++mBufferGeneration; 168 169 sp<AMessage> notify = mNotify->dup(); 170 notify->setInt32("what", kWhatShutdownCompleted); 171 notify->post(); 172 mReachedEOS = true; 173} 174 175void NuPlayer::DecoderPassThrough::onMessageReceived(const sp<AMessage> &msg) { 176 ALOGV("[%s] onMessage: %s", mComponentName.c_str(), 177 msg->debugString().c_str()); 178 179 switch (msg->what()) { 180 case kWhatConfigure: 181 { 182 sp<AMessage> format; 183 CHECK(msg->findMessage("format", &format)); 184 onConfigure(format); 185 break; 186 } 187 188 case kWhatRequestABuffer: 189 { 190 if (!isStaleReply(msg)) { 191 requestABuffer(); 192 } 193 194 break; 195 } 196 197 case kWhatInputBufferFilled: 198 { 199 if (!isStaleReply(msg)) { 200 onInputBufferFilled(msg); 201 } 202 break; 203 } 204 205 case kWhatBufferConsumed: 206 { 207 if (!isStaleReply(msg)) { 208 onBufferConsumed(); 209 } 210 break; 211 } 212 213 case kWhatFlush: 214 { 215 onFlush(); 216 break; 217 } 218 219 case kWhatResume: 220 { 221 requestABuffer(); 222 break; 223 } 224 225 case kWhatShutdown: 226 { 227 onShutdown(); 228 break; 229 } 230 231 default: 232 TRESPASS(); 233 break; 234 } 235} 236 237} // namespace android 238