| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 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 |  | 
| Wei Jia | c6cfd70 | 2014-11-11 16:33:20 -0800 | [diff] [blame] | 24 | #include "NuPlayerRenderer.h" | 
 | 25 | #include "NuPlayerSource.h" | 
 | 26 |  | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 27 | #include <media/ICrypto.h> | 
 | 28 | #include <media/stagefright/foundation/ABuffer.h> | 
 | 29 | #include <media/stagefright/foundation/ADebug.h> | 
 | 30 | #include <media/stagefright/foundation/AMessage.h> | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 31 | #include <media/stagefright/MediaErrors.h> | 
 | 32 |  | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 33 | #include "ATSParser.h" | 
 | 34 |  | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 35 | namespace android { | 
 | 36 |  | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 37 | // TODO optimize buffer size for power consumption | 
 | 38 | // The offload read buffer size is 32 KB but 24 KB uses less power. | 
 | 39 | static const size_t kAggregateBufferSizeBytes = 24 * 1024; | 
| Phil Burk | c5cc2e2 | 2014-09-09 20:08:39 -0700 | [diff] [blame] | 40 | static const size_t kMaxCachedBytes = 200000; | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 41 |  | 
 | 42 | NuPlayer::DecoderPassThrough::DecoderPassThrough( | 
| Wei Jia | c6cfd70 | 2014-11-11 16:33:20 -0800 | [diff] [blame] | 43 |         const sp<AMessage> ¬ify, | 
 | 44 |         const sp<Source> &source, | 
 | 45 |         const sp<Renderer> &renderer) | 
| Andy Hung | 202bce1 | 2014-12-03 11:47:36 -0800 | [diff] [blame^] | 46 |     : DecoderBase(notify), | 
| Wei Jia | c6cfd70 | 2014-11-11 16:33:20 -0800 | [diff] [blame] | 47 |       mSource(source), | 
 | 48 |       mRenderer(renderer), | 
 | 49 |       mSkipRenderingUntilMediaTimeUs(-1ll), | 
| Ronghua Wu | f182891 | 2014-12-01 15:33:36 -0800 | [diff] [blame] | 50 |       mPaused(false), | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 51 |       mReachedEOS(true), | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 52 |       mPendingAudioErr(OK), | 
| Phil Burk | c5cc2e2 | 2014-09-09 20:08:39 -0700 | [diff] [blame] | 53 |       mPendingBuffersToDrain(0), | 
| Chong Zhang | de01afb | 2014-08-13 13:48:10 -0700 | [diff] [blame] | 54 |       mCachedBytes(0), | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 55 |       mComponentName("pass through decoder") { | 
| Wei Jia | c6cfd70 | 2014-11-11 16:33:20 -0800 | [diff] [blame] | 56 |     ALOGW_IF(renderer == NULL, "expect a non-NULL renderer"); | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 57 | } | 
 | 58 |  | 
 | 59 | NuPlayer::DecoderPassThrough::~DecoderPassThrough() { | 
 | 60 | } | 
 | 61 |  | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 62 | void NuPlayer::DecoderPassThrough::getStats( | 
 | 63 |         int64_t *numFramesTotal, int64_t *numFramesDropped) const { | 
 | 64 |     *numFramesTotal = 0; | 
 | 65 |     *numFramesDropped = 0; | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 66 | } | 
 | 67 |  | 
 | 68 | void NuPlayer::DecoderPassThrough::onConfigure(const sp<AMessage> &format) { | 
 | 69 |     ALOGV("[%s] onConfigure", mComponentName.c_str()); | 
| Chong Zhang | de01afb | 2014-08-13 13:48:10 -0700 | [diff] [blame] | 70 |     mCachedBytes = 0; | 
| Phil Burk | c5cc2e2 | 2014-09-09 20:08:39 -0700 | [diff] [blame] | 71 |     mPendingBuffersToDrain = 0; | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 72 |     mReachedEOS = false; | 
 | 73 |     ++mBufferGeneration; | 
 | 74 |  | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 75 |     onRequestInputBuffers(); | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 76 |  | 
| Andy Hung | 202bce1 | 2014-12-03 11:47:36 -0800 | [diff] [blame^] | 77 |     // The audio sink is already opened before the PassThrough decoder is created. | 
 | 78 |     // Opening again might be relevant if decoder is instantiated after shutdown and | 
 | 79 |     // format is different. | 
 | 80 |     status_t err = mRenderer->openAudioSink( | 
 | 81 |             format, true /* offloadOnly */, false /* hasVideo */, | 
 | 82 |             AUDIO_OUTPUT_FLAG_NONE /* flags */, NULL /* isOffloaded */); | 
 | 83 |     if (err != OK) { | 
 | 84 |         handleError(err); | 
| Wei Jia | c6cfd70 | 2014-11-11 16:33:20 -0800 | [diff] [blame] | 85 |     } | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 86 | } | 
 | 87 |  | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 88 | void NuPlayer::DecoderPassThrough::onSetRenderer( | 
 | 89 |         const sp<Renderer> &renderer) { | 
 | 90 |     // renderer can't be changed during offloading | 
 | 91 |     ALOGW_IF(renderer != mRenderer, | 
 | 92 |             "ignoring request to change renderer"); | 
 | 93 | } | 
 | 94 |  | 
 | 95 | void NuPlayer::DecoderPassThrough::onGetInputBuffers( | 
 | 96 |         Vector<sp<ABuffer> > * /* dstBuffers */) { | 
 | 97 |     ALOGE("onGetInputBuffers() called unexpectedly"); | 
 | 98 | } | 
 | 99 |  | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 100 | bool NuPlayer::DecoderPassThrough::isStaleReply(const sp<AMessage> &msg) { | 
 | 101 |     int32_t generation; | 
 | 102 |     CHECK(msg->findInt32("generation", &generation)); | 
 | 103 |     return generation != mBufferGeneration; | 
 | 104 | } | 
 | 105 |  | 
| Ronghua Wu | f182891 | 2014-12-01 15:33:36 -0800 | [diff] [blame] | 106 | bool NuPlayer::DecoderPassThrough::isDoneFetching() const { | 
 | 107 |     ALOGV("[%s] mCachedBytes = %zu, mReachedEOS = %d mPaused = %d", | 
 | 108 |             mComponentName.c_str(), mCachedBytes, mReachedEOS, mPaused); | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 109 |  | 
| Ronghua Wu | f182891 | 2014-12-01 15:33:36 -0800 | [diff] [blame] | 110 |     return mCachedBytes >= kMaxCachedBytes || mReachedEOS || mPaused; | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 111 | } | 
 | 112 |  | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 113 | void NuPlayer::DecoderPassThrough::doRequestBuffers() { | 
 | 114 |     status_t err = OK; | 
| Ronghua Wu | f182891 | 2014-12-01 15:33:36 -0800 | [diff] [blame] | 115 |     while (!isDoneFetching()) { | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 116 |         sp<AMessage> msg = new AMessage(); | 
 | 117 |  | 
 | 118 |         err = fetchInputData(msg); | 
 | 119 |         if (err != OK) { | 
 | 120 |             break; | 
 | 121 |         } | 
 | 122 |  | 
 | 123 |         onInputBufferFetched(msg); | 
 | 124 |     } | 
 | 125 |  | 
 | 126 |     if (err == -EWOULDBLOCK | 
 | 127 |             && mSource->feedMoreTSData() == OK) { | 
 | 128 |         scheduleRequestBuffers(); | 
 | 129 |     } | 
 | 130 | } | 
 | 131 |  | 
 | 132 | status_t NuPlayer::DecoderPassThrough::dequeueAccessUnit(sp<ABuffer> *accessUnit) { | 
 | 133 |     status_t err; | 
 | 134 |  | 
 | 135 |     // Did we save an accessUnit earlier because of a discontinuity? | 
 | 136 |     if (mPendingAudioAccessUnit != NULL) { | 
 | 137 |         *accessUnit = mPendingAudioAccessUnit; | 
 | 138 |         mPendingAudioAccessUnit.clear(); | 
 | 139 |         err = mPendingAudioErr; | 
 | 140 |         ALOGV("feedDecoderInputData() use mPendingAudioAccessUnit"); | 
 | 141 |     } else { | 
 | 142 |         err = mSource->dequeueAccessUnit(true /* audio */, accessUnit); | 
 | 143 |     } | 
 | 144 |  | 
 | 145 |     if (err == INFO_DISCONTINUITY || err == ERROR_END_OF_STREAM) { | 
 | 146 |         if (mAggregateBuffer != NULL) { | 
 | 147 |             // We already have some data so save this for later. | 
 | 148 |             mPendingAudioErr = err; | 
 | 149 |             mPendingAudioAccessUnit = *accessUnit; | 
 | 150 |             (*accessUnit).clear(); | 
 | 151 |             ALOGD("return aggregated buffer and save err(=%d) for later", err); | 
 | 152 |             err = OK; | 
 | 153 |         } | 
 | 154 |     } | 
 | 155 |  | 
 | 156 |     return err; | 
 | 157 | } | 
 | 158 |  | 
 | 159 | sp<ABuffer> NuPlayer::DecoderPassThrough::aggregateBuffer( | 
 | 160 |         const sp<ABuffer> &accessUnit) { | 
 | 161 |     sp<ABuffer> aggregate; | 
 | 162 |  | 
 | 163 |     if (accessUnit == NULL) { | 
 | 164 |         // accessUnit is saved to mPendingAudioAccessUnit | 
 | 165 |         // return current mAggregateBuffer | 
 | 166 |         aggregate = mAggregateBuffer; | 
 | 167 |         mAggregateBuffer.clear(); | 
 | 168 |         return aggregate; | 
 | 169 |     } | 
 | 170 |  | 
 | 171 |     size_t smallSize = accessUnit->size(); | 
 | 172 |     if ((mAggregateBuffer == NULL) | 
 | 173 |             // Don't bother if only room for a few small buffers. | 
 | 174 |             && (smallSize < (kAggregateBufferSizeBytes / 3))) { | 
 | 175 |         // Create a larger buffer for combining smaller buffers from the extractor. | 
 | 176 |         mAggregateBuffer = new ABuffer(kAggregateBufferSizeBytes); | 
 | 177 |         mAggregateBuffer->setRange(0, 0); // start empty | 
 | 178 |     } | 
 | 179 |  | 
 | 180 |     if (mAggregateBuffer != NULL) { | 
 | 181 |         int64_t timeUs; | 
 | 182 |         int64_t dummy; | 
 | 183 |         bool smallTimestampValid = accessUnit->meta()->findInt64("timeUs", &timeUs); | 
 | 184 |         bool bigTimestampValid = mAggregateBuffer->meta()->findInt64("timeUs", &dummy); | 
 | 185 |         // Will the smaller buffer fit? | 
 | 186 |         size_t bigSize = mAggregateBuffer->size(); | 
 | 187 |         size_t roomLeft = mAggregateBuffer->capacity() - bigSize; | 
 | 188 |         // Should we save this small buffer for the next big buffer? | 
 | 189 |         // If the first small buffer did not have a timestamp then save | 
 | 190 |         // any buffer that does have a timestamp until the next big buffer. | 
 | 191 |         if ((smallSize > roomLeft) | 
 | 192 |             || (!bigTimestampValid && (bigSize > 0) && smallTimestampValid)) { | 
 | 193 |             mPendingAudioErr = OK; | 
 | 194 |             mPendingAudioAccessUnit = accessUnit; | 
 | 195 |             aggregate = mAggregateBuffer; | 
 | 196 |             mAggregateBuffer.clear(); | 
 | 197 |         } else { | 
 | 198 |             // Grab time from first small buffer if available. | 
 | 199 |             if ((bigSize == 0) && smallTimestampValid) { | 
 | 200 |                 mAggregateBuffer->meta()->setInt64("timeUs", timeUs); | 
 | 201 |             } | 
 | 202 |             // Append small buffer to the bigger buffer. | 
 | 203 |             memcpy(mAggregateBuffer->base() + bigSize, accessUnit->data(), smallSize); | 
 | 204 |             bigSize += smallSize; | 
 | 205 |             mAggregateBuffer->setRange(0, bigSize); | 
 | 206 |  | 
 | 207 |             ALOGV("feedDecoderInputData() smallSize = %zu, bigSize = %zu, capacity = %zu", | 
 | 208 |                     smallSize, bigSize, mAggregateBuffer->capacity()); | 
 | 209 |         } | 
 | 210 |     } else { | 
 | 211 |         // decided not to aggregate | 
 | 212 |         aggregate = accessUnit; | 
 | 213 |     } | 
 | 214 |  | 
 | 215 |     return aggregate; | 
 | 216 | } | 
 | 217 |  | 
 | 218 | status_t NuPlayer::DecoderPassThrough::fetchInputData(sp<AMessage> &reply) { | 
 | 219 |     sp<ABuffer> accessUnit; | 
 | 220 |  | 
 | 221 |     do { | 
 | 222 |         status_t err = dequeueAccessUnit(&accessUnit); | 
 | 223 |  | 
 | 224 |         if (err == -EWOULDBLOCK) { | 
 | 225 |             return err; | 
 | 226 |         } else if (err != OK) { | 
 | 227 |             if (err == INFO_DISCONTINUITY) { | 
 | 228 |                 int32_t type; | 
 | 229 |                 CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); | 
 | 230 |  | 
 | 231 |                 bool formatChange = | 
 | 232 |                         (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT) != 0; | 
 | 233 |  | 
 | 234 |                 bool timeChange = | 
 | 235 |                         (type & ATSParser::DISCONTINUITY_TIME) != 0; | 
 | 236 |  | 
 | 237 |                 ALOGI("audio discontinuity (formatChange=%d, time=%d)", | 
 | 238 |                         formatChange, timeChange); | 
 | 239 |  | 
 | 240 |                 if (formatChange || timeChange) { | 
 | 241 |                     sp<AMessage> msg = mNotify->dup(); | 
 | 242 |                     msg->setInt32("what", kWhatInputDiscontinuity); | 
 | 243 |                     // will perform seamless format change, | 
 | 244 |                     // only notify NuPlayer to scan sources | 
 | 245 |                     msg->setInt32("formatChange", false); | 
 | 246 |                     msg->post(); | 
 | 247 |                 } | 
 | 248 |  | 
 | 249 |                 if (timeChange) { | 
 | 250 |                     onFlush(false /* notifyComplete */); | 
 | 251 |                     err = OK; | 
 | 252 |                 } else if (formatChange) { | 
 | 253 |                     // do seamless format change | 
 | 254 |                     err = OK; | 
 | 255 |                 } else { | 
 | 256 |                     // This stream is unaffected by the discontinuity | 
 | 257 |                     return -EWOULDBLOCK; | 
 | 258 |                 } | 
 | 259 |             } | 
 | 260 |  | 
 | 261 |             reply->setInt32("err", err); | 
 | 262 |             return OK; | 
 | 263 |         } | 
 | 264 |  | 
 | 265 |         accessUnit = aggregateBuffer(accessUnit); | 
 | 266 |     } while (accessUnit == NULL); | 
 | 267 |  | 
 | 268 | #if 0 | 
 | 269 |     int64_t mediaTimeUs; | 
 | 270 |     CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); | 
 | 271 |     ALOGV("feeding audio input buffer at media time %.2f secs", | 
 | 272 |          mediaTimeUs / 1E6); | 
 | 273 | #endif | 
 | 274 |  | 
 | 275 |     reply->setBuffer("buffer", accessUnit); | 
 | 276 |  | 
 | 277 |     return OK; | 
 | 278 | } | 
 | 279 |  | 
 | 280 | void NuPlayer::DecoderPassThrough::onInputBufferFetched( | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 281 |         const sp<AMessage> &msg) { | 
 | 282 |     if (mReachedEOS) { | 
 | 283 |         return; | 
 | 284 |     } | 
 | 285 |  | 
 | 286 |     sp<ABuffer> buffer; | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 287 |     bool hasBuffer = msg->findBuffer("buffer", &buffer); | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 288 |     if (buffer == NULL) { | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 289 |         int32_t streamErr = ERROR_END_OF_STREAM; | 
 | 290 |         CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); | 
 | 291 |         if (streamErr == OK) { | 
 | 292 |             return; | 
 | 293 |         } | 
 | 294 |  | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 295 |         mReachedEOS = true; | 
| Wei Jia | c6cfd70 | 2014-11-11 16:33:20 -0800 | [diff] [blame] | 296 |         if (mRenderer != NULL) { | 
 | 297 |             mRenderer->queueEOS(true /* audio */, ERROR_END_OF_STREAM); | 
 | 298 |         } | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 299 |         return; | 
 | 300 |     } | 
 | 301 |  | 
| Wei Jia | c6cfd70 | 2014-11-11 16:33:20 -0800 | [diff] [blame] | 302 |     sp<AMessage> extra; | 
 | 303 |     if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) { | 
 | 304 |         int64_t resumeAtMediaTimeUs; | 
 | 305 |         if (extra->findInt64( | 
 | 306 |                     "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) { | 
 | 307 |             ALOGI("[%s] suppressing rendering until %lld us", | 
 | 308 |                     mComponentName.c_str(), (long long)resumeAtMediaTimeUs); | 
 | 309 |             mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs; | 
 | 310 |         } | 
 | 311 |     } | 
 | 312 |  | 
 | 313 |     int32_t bufferSize = buffer->size(); | 
 | 314 |     mCachedBytes += bufferSize; | 
 | 315 |  | 
 | 316 |     if (mSkipRenderingUntilMediaTimeUs >= 0) { | 
 | 317 |         int64_t timeUs = 0; | 
 | 318 |         CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); | 
 | 319 |  | 
 | 320 |         if (timeUs < mSkipRenderingUntilMediaTimeUs) { | 
 | 321 |             ALOGV("[%s] dropping buffer at time %lld as requested.", | 
 | 322 |                      mComponentName.c_str(), (long long)timeUs); | 
 | 323 |  | 
 | 324 |             onBufferConsumed(bufferSize); | 
 | 325 |             return; | 
 | 326 |         } | 
 | 327 |  | 
 | 328 |         mSkipRenderingUntilMediaTimeUs = -1; | 
 | 329 |     } | 
 | 330 |  | 
 | 331 |     if (mRenderer == NULL) { | 
 | 332 |         onBufferConsumed(bufferSize); | 
 | 333 |         return; | 
 | 334 |     } | 
| Chong Zhang | de01afb | 2014-08-13 13:48:10 -0700 | [diff] [blame] | 335 |  | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 336 |     sp<AMessage> reply = new AMessage(kWhatBufferConsumed, id()); | 
 | 337 |     reply->setInt32("generation", mBufferGeneration); | 
| Wei Jia | c6cfd70 | 2014-11-11 16:33:20 -0800 | [diff] [blame] | 338 |     reply->setInt32("size", bufferSize); | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 339 |  | 
| Wei Jia | c6cfd70 | 2014-11-11 16:33:20 -0800 | [diff] [blame] | 340 |     mRenderer->queueBuffer(true /* audio */, buffer, reply); | 
 | 341 |  | 
| Phil Burk | c5cc2e2 | 2014-09-09 20:08:39 -0700 | [diff] [blame] | 342 |     ++mPendingBuffersToDrain; | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 343 |     ALOGV("onInputBufferFilled: #ToDrain = %zu, cachedBytes = %zu", | 
 | 344 |             mPendingBuffersToDrain, mCachedBytes); | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 345 | } | 
 | 346 |  | 
| Chong Zhang | de01afb | 2014-08-13 13:48:10 -0700 | [diff] [blame] | 347 | void NuPlayer::DecoderPassThrough::onBufferConsumed(int32_t size) { | 
| Phil Burk | c5cc2e2 | 2014-09-09 20:08:39 -0700 | [diff] [blame] | 348 |     --mPendingBuffersToDrain; | 
| Chong Zhang | de01afb | 2014-08-13 13:48:10 -0700 | [diff] [blame] | 349 |     mCachedBytes -= size; | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 350 |     ALOGV("onBufferConsumed: #ToDrain = %zu, cachedBytes = %zu", | 
 | 351 |             mPendingBuffersToDrain, mCachedBytes); | 
 | 352 |     onRequestInputBuffers(); | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 353 | } | 
 | 354 |  | 
| Chong Zhang | f8d7177 | 2014-11-26 15:08:34 -0800 | [diff] [blame] | 355 | void NuPlayer::DecoderPassThrough::onResume(bool notifyComplete) { | 
| Ronghua Wu | f182891 | 2014-12-01 15:33:36 -0800 | [diff] [blame] | 356 |     mPaused = false; | 
 | 357 |  | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 358 |     onRequestInputBuffers(); | 
| Chong Zhang | f8d7177 | 2014-11-26 15:08:34 -0800 | [diff] [blame] | 359 |  | 
 | 360 |     if (notifyComplete) { | 
 | 361 |         sp<AMessage> notify = mNotify->dup(); | 
 | 362 |         notify->setInt32("what", kWhatResumeCompleted); | 
 | 363 |         notify->post(); | 
 | 364 |     } | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 365 | } | 
 | 366 |  | 
 | 367 | void NuPlayer::DecoderPassThrough::onFlush(bool notifyComplete) { | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 368 |     ++mBufferGeneration; | 
| Wei Jia | c6cfd70 | 2014-11-11 16:33:20 -0800 | [diff] [blame] | 369 |     mSkipRenderingUntilMediaTimeUs = -1; | 
| Ronghua Wu | f182891 | 2014-12-01 15:33:36 -0800 | [diff] [blame] | 370 |     mPendingAudioAccessUnit.clear(); | 
 | 371 |     mPendingAudioErr = OK; | 
 | 372 |     mAggregateBuffer.clear(); | 
| Wei Jia | c6cfd70 | 2014-11-11 16:33:20 -0800 | [diff] [blame] | 373 |  | 
 | 374 |     if (mRenderer != NULL) { | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 375 |         mRenderer->flush(true /* audio */, notifyComplete); | 
 | 376 |         mRenderer->signalTimeDiscontinuity(); | 
| Wei Jia | c6cfd70 | 2014-11-11 16:33:20 -0800 | [diff] [blame] | 377 |     } | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 378 |  | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 379 |     if (notifyComplete) { | 
| Ronghua Wu | f182891 | 2014-12-01 15:33:36 -0800 | [diff] [blame] | 380 |         mPaused = true; | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 381 |         sp<AMessage> notify = mNotify->dup(); | 
 | 382 |         notify->setInt32("what", kWhatFlushCompleted); | 
 | 383 |         notify->post(); | 
 | 384 |     } | 
 | 385 |  | 
| Phil Burk | c5cc2e2 | 2014-09-09 20:08:39 -0700 | [diff] [blame] | 386 |     mPendingBuffersToDrain = 0; | 
| Chong Zhang | de01afb | 2014-08-13 13:48:10 -0700 | [diff] [blame] | 387 |     mCachedBytes = 0; | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 388 |     mReachedEOS = false; | 
 | 389 | } | 
 | 390 |  | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 391 | void NuPlayer::DecoderPassThrough::onShutdown(bool notifyComplete) { | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 392 |     ++mBufferGeneration; | 
| Wei Jia | c6cfd70 | 2014-11-11 16:33:20 -0800 | [diff] [blame] | 393 |     mSkipRenderingUntilMediaTimeUs = -1; | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 394 |  | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 395 |     if (notifyComplete) { | 
 | 396 |         sp<AMessage> notify = mNotify->dup(); | 
 | 397 |         notify->setInt32("what", kWhatShutdownCompleted); | 
 | 398 |         notify->post(); | 
 | 399 |     } | 
 | 400 |  | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 401 |     mReachedEOS = true; | 
 | 402 | } | 
 | 403 |  | 
 | 404 | void NuPlayer::DecoderPassThrough::onMessageReceived(const sp<AMessage> &msg) { | 
 | 405 |     ALOGV("[%s] onMessage: %s", mComponentName.c_str(), | 
 | 406 |             msg->debugString().c_str()); | 
 | 407 |  | 
 | 408 |     switch (msg->what()) { | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 409 |         case kWhatBufferConsumed: | 
 | 410 |         { | 
 | 411 |             if (!isStaleReply(msg)) { | 
| Chong Zhang | de01afb | 2014-08-13 13:48:10 -0700 | [diff] [blame] | 412 |                 int32_t size; | 
 | 413 |                 CHECK(msg->findInt32("size", &size)); | 
 | 414 |                 onBufferConsumed(size); | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 415 |             } | 
 | 416 |             break; | 
 | 417 |         } | 
 | 418 |  | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 419 |         default: | 
| Chong Zhang | 7137ec7 | 2014-11-12 16:41:05 -0800 | [diff] [blame] | 420 |             DecoderBase::onMessageReceived(msg); | 
| Wei Jia | bc2fb72 | 2014-07-08 16:37:57 -0700 | [diff] [blame] | 421 |             break; | 
 | 422 |     } | 
 | 423 | } | 
 | 424 |  | 
 | 425 | }  // namespace android |