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