1761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman/* 2761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * Copyright (C) 2011 The Android Open Source Project 3761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * 4761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * Licensed under the Apache License, Version 2.0 (the "License"); 5761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * you may not use this file except in compliance with the License. 6761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * You may obtain a copy of the License at 7761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * 8761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * http://www.apache.org/licenses/LICENSE-2.0 9761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * 10761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * Unless required by applicable law or agreed to in writing, software 11761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * distributed under the License is distributed on an "AS IS" BASIS, 12761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * See the License for the specific language governing permissions and 14761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * limitations under the License. 15761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman */ 16761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 17761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#define LOG_TAG "LibAAH_RTP" 18761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman//#define LOG_NDEBUG 0 19761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <utils/Log.h> 20761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 21761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <poll.h> 22761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <pthread.h> 23761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 24761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <common_time/cc_helper.h> 25761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <media/AudioSystem.h> 26761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <media/AudioTrack.h> 27761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <media/stagefright/foundation/ADebug.h> 28761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <media/stagefright/MetaData.h> 29761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <media/stagefright/OMXClient.h> 30761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <media/stagefright/OMXCodec.h> 31761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <media/stagefright/Utils.h> 32761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <utils/Timers.h> 33761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <utils/threads.h> 34761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 35761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include "aah_decoder_pump.h" 36761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 37761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmannamespace android { 38761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 39761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanstatic const long long kLongDecodeErrorThreshold = 1000000ll; 40761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanstatic const uint32_t kMaxLongErrorsBeforeFatal = 3; 41761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanstatic const uint32_t kMaxErrorsBeforeFatal = 60; 42761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 43761defc341c5ce9019a42919c441f035f665ec0dJohn GrossmanAAH_DecoderPump::AAH_DecoderPump(OMXClient& omx) 44761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman : omx_(omx) 45761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman , thread_status_(OK) 46761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman , renderer_(NULL) 47761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman , last_queued_pts_valid_(false) 48761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman , last_queued_pts_(0) 49761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman , last_ts_transform_valid_(false) 50761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman , last_volume_(0xFF) { 51761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman thread_ = new ThreadWrapper(this); 52761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 53761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 54761defc341c5ce9019a42919c441f035f665ec0dJohn GrossmanAAH_DecoderPump::~AAH_DecoderPump() { 55761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman shutdown(); 56761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 57761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 58761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanstatus_t AAH_DecoderPump::initCheck() { 59761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (thread_ == NULL) { 60761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGE("Failed to allocate thread"); 61761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return NO_MEMORY; 62761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 63761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 64761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return OK; 65761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 66761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 67761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanstatus_t AAH_DecoderPump::queueForDecode(MediaBuffer* buf) { 68761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (NULL == buf) { 69761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return BAD_VALUE; 70761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 71761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 72761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (OK != thread_status_) { 73761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return thread_status_; 74761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 75761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 76761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman { // Explicit scope for AutoMutex pattern. 77761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman AutoMutex lock(&thread_lock_); 78761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman in_queue_.push_back(buf); 79761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 80761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 81761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman thread_cond_.signal(); 82761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 83761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return OK; 84761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 85761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 86761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanvoid AAH_DecoderPump::queueToRenderer(MediaBuffer* decoded_sample) { 87761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman Mutex::Autolock lock(&render_lock_); 88761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman sp<MetaData> meta; 89761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman int64_t ts; 90761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman status_t res; 91761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 92761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Fetch the metadata and make sure the sample has a timestamp. We 93761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // cannot render samples which are missing PTSs. 94761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman meta = decoded_sample->meta_data(); 95761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if ((meta == NULL) || (!meta->findInt64(kKeyTime, &ts))) { 96761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGV("Decoded sample missing timestamp, cannot render."); 97761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(false); 98761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } else { 99761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // If we currently are not holding on to a renderer, go ahead and 100761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // make one now. 101761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (NULL == renderer_) { 102761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman renderer_ = new TimedAudioTrack(); 103761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (NULL != renderer_) { 104761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman int frameCount; 105761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman AudioTrack::getMinFrameCount(&frameCount, 106761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman AUDIO_STREAM_DEFAULT, 107761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static_cast<int>(format_sample_rate_)); 108ab334fd351ae5a0e18903da123d63e565b536874Glenn Kasten audio_channel_mask_t ch_format = 109ab334fd351ae5a0e18903da123d63e565b536874Glenn Kasten audio_channel_out_mask_from_count(format_channels_); 110761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 111761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman res = renderer_->set(AUDIO_STREAM_DEFAULT, 112761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman format_sample_rate_, 113761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman AUDIO_FORMAT_PCM_16_BIT, 114761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ch_format, 115761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman frameCount); 116761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (res != OK) { 117761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGE("Failed to setup audio renderer. (res = %d)", res); 118761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman delete renderer_; 119761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman renderer_ = NULL; 120761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } else { 121761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(last_ts_transform_valid_); 122761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 123761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman res = renderer_->setMediaTimeTransform( 124761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman last_ts_transform_, TimedAudioTrack::COMMON_TIME); 125761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (res != NO_ERROR) { 126761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGE("Failed to set media time transform on AudioTrack" 127761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman " (res = %d)", res); 128761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman delete renderer_; 129761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman renderer_ = NULL; 130761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } else { 131761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman float volume = static_cast<float>(last_volume_) 132761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman / 255.0f; 133761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (renderer_->setVolume(volume, volume) != OK) { 134761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGW("%s: setVolume failed", __FUNCTION__); 135761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 136761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 137761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman renderer_->start(); 138761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 139761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 140761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } else { 141761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGE("Failed to allocate AudioTrack to use as a renderer."); 142761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 143761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 144761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 145761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (NULL != renderer_) { 146761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint8_t* decoded_data = 147761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman reinterpret_cast<uint8_t*>(decoded_sample->data()); 148761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint32_t decoded_amt = decoded_sample->range_length(); 149761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman decoded_data += decoded_sample->range_offset(); 150761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 151761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman sp<IMemory> pcm_payload; 152761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman res = renderer_->allocateTimedBuffer(decoded_amt, &pcm_payload); 153761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (res != OK) { 154761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGE("Failed to allocate %d byte audio track buffer." 155761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman " (res = %d)", decoded_amt, res); 156761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } else { 157761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman memcpy(pcm_payload->pointer(), decoded_data, decoded_amt); 158761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 159761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman res = renderer_->queueTimedBuffer(pcm_payload, ts); 160761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (res != OK) { 1614b77dc28097288cb062fce6bf5de0fb3394877a9John Grossman ALOGE("Failed to queue %d byte audio track buffer with" 1624b77dc28097288cb062fce6bf5de0fb3394877a9John Grossman " media PTS %lld. (res = %d)", decoded_amt, ts, res); 163761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } else { 164761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman last_queued_pts_valid_ = true; 165761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman last_queued_pts_ = ts; 166761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 167761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 168761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 169761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } else { 170761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGE("No renderer, dropping audio payload."); 171761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 172761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 173761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 174761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 175761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanvoid AAH_DecoderPump::stopAndCleanupRenderer() { 176761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (NULL == renderer_) { 177761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return; 178761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 179761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 180761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman renderer_->stop(); 181761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman delete renderer_; 182761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman renderer_ = NULL; 183761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 184761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 185761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanvoid AAH_DecoderPump::setRenderTSTransform(const LinearTransform& trans) { 186761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman Mutex::Autolock lock(&render_lock_); 187761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 188761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (last_ts_transform_valid_ && !memcmp(&trans, 189761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman &last_ts_transform_, 190761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman sizeof(trans))) { 191761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return; 192761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 193761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 194761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman last_ts_transform_ = trans; 195761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman last_ts_transform_valid_ = true; 196761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 197761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (NULL != renderer_) { 198761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman status_t res = renderer_->setMediaTimeTransform( 199761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman last_ts_transform_, TimedAudioTrack::COMMON_TIME); 200761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (res != NO_ERROR) { 201761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGE("Failed to set media time transform on AudioTrack" 202761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman " (res = %d)", res); 203761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 204761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 205761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 206761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 207761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanvoid AAH_DecoderPump::setRenderVolume(uint8_t volume) { 208761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman Mutex::Autolock lock(&render_lock_); 209761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 210761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (volume == last_volume_) { 211761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return; 212761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 213761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 214761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman last_volume_ = volume; 215761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (renderer_ != NULL) { 216761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman float volume = static_cast<float>(last_volume_) / 255.0f; 217761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (renderer_->setVolume(volume, volume) != OK) { 218761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGW("%s: setVolume failed", __FUNCTION__); 219761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 220761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 221761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 222761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 223761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// isAboutToUnderflow is something of a hack used to figure out when it might be 224761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// time to give up on trying to fill in a gap in the RTP sequence and simply 225761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// move on with a discontinuity. If we had perfect knowledge of when we were 226761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// going to underflow, it would not be a hack, but unfortunately we do not. 227761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// Right now, we just take the PTS of the last sample queued, and check to see 228761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// if its presentation time is within kAboutToUnderflowThreshold from now. If 229761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// it is, then we say that we are about to underflow. This decision is based on 230761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// two (possibly invalid) assumptions. 231761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// 232761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// 1) The transmitter is leading the clock by more than 233761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// kAboutToUnderflowThreshold. 234761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// 2) The delta between the PTS of the last sample queued and the next sample 235761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// is less than the transmitter's clock lead amount. 236761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// 237761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// Right now, the default transmitter lead time is 1 second, which is a pretty 238761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// large number and greater than the 50mSec that kAboutToUnderflowThreshold is 239761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// currently set to. This should satisfy assumption #1 for now, but changes to 240761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// the transmitter clock lead time could effect this. 241761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// 242761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// For non-sparse streams with a homogeneous sample rate (the vast majority of 243761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// streams in the world), the delta between any two adjacent PTSs will always be 244761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// the homogeneous sample period. It is very uncommon to see a sample period 245761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// greater than the 1 second clock lead we are currently using, and you 246761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// certainly will not see it in an MP3 file which should satisfy assumption #2. 247761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// Sparse audio streams (where no audio is transmitted for long periods of 248761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// silence) and extremely low framerate video stream (like an MPEG-2 slideshow 249761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// or the video stream for a pay TV audio channel) are examples of streams which 250761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman// might violate assumption #2. 251761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanbool AAH_DecoderPump::isAboutToUnderflow(int64_t threshold) { 252761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman Mutex::Autolock lock(&render_lock_); 253761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 254761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // If we have never queued anything to the decoder, we really don't know if 255761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // we are going to underflow or not. 256761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (!last_queued_pts_valid_ || !last_ts_transform_valid_) { 257761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return false; 258761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 259761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 260761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Don't have access to Common Time? If so, then things are Very Bad 261761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // elsewhere in the system; it pretty much does not matter what we do here. 262761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Since we cannot really tell if we are about to underflow or not, its 263761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // probably best to assume that we are not and proceed accordingly. 264761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman int64_t tt_now; 265761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (OK != cc_helper_.getCommonTime(&tt_now)) { 266761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return false; 267761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 268761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 269761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Transform from media time to common time. 270761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman int64_t last_queued_pts_tt; 271761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (!last_ts_transform_.doForwardTransform(last_queued_pts_, 272761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman &last_queued_pts_tt)) { 273761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return false; 274761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 275761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 276761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Check to see if we are underflowing. 277761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return ((tt_now + threshold - last_queued_pts_tt) > 0); 278761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 279761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 280761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanvoid* AAH_DecoderPump::workThread() { 281761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // No need to lock when accessing decoder_ from the thread. The 282761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // implementation of init and shutdown ensure that other threads never touch 283761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // decoder_ while the work thread is running. 284761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(decoder_ != NULL); 285761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(format_ != NULL); 286761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 287761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Start the decoder and note its result code. If something goes horribly 288761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // wrong, callers of queueForDecode and getOutput will be able to detect 289761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // that the thread encountered a fatal error and shut down by examining 290761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // thread_status_. 291761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman thread_status_ = decoder_->start(format_.get()); 292761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (OK != thread_status_) { 2934b77dc28097288cb062fce6bf5de0fb3394877a9John Grossman ALOGE("AAH_DecoderPump's work thread failed to start decoder" 2944b77dc28097288cb062fce6bf5de0fb3394877a9John Grossman " (res = %d)", thread_status_); 295761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return NULL; 296761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 297761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 298761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman DurationTimer decode_timer; 299761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint32_t consecutive_long_errors = 0; 300761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint32_t consecutive_errors = 0; 301761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 302761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman while (!thread_->exitPending()) { 303761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman status_t res; 304761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman MediaBuffer* bufOut = NULL; 305761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 306761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman decode_timer.start(); 307761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman res = decoder_->read(&bufOut); 308761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman decode_timer.stop(); 309761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 310761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (res == INFO_FORMAT_CHANGED) { 311761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Format has changed. Destroy our current renderer so that a new 312761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // one can be created during queueToRenderer with the proper format. 313761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // 314761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // TODO : In order to transition seamlessly, we should change this 315761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // to put the old renderer in a queue to play out completely before 316761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // we destroy it. We can still create a new renderer, the timed 317761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // nature of the renderer should ensure a seamless splice. 318761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman stopAndCleanupRenderer(); 319761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman res = OK; 320761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 321761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 322761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Try to be a little nuanced in our handling of actual decode errors. 323761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Errors could happen because of minor stream corruption or because of 324761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // transient resource limitations. In these cases, we would rather drop 325761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // a little bit of output and ride out the unpleasantness then throw up 326761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // our hands and abort everything. 327761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // 328761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // OTOH - When things are really bad (like we have a non-transient 329761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // resource or bookkeeping issue, or the stream being fed to us is just 330761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // complete and total garbage) we really want to terminate playback and 331761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // raise an error condition all the way up to the application level so 332761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // they can deal with it. 333761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // 334761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Unfortunately, the error codes returned by the decoder can be a 335761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // little non-specific. For example, if an OMXCodec times out 336761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // attempting to obtain an output buffer, the error we get back is a 337761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // generic -1. Try to distinguish between this resource timeout error 338761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // and ES corruption error by timing how long the decode operation 339761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // takes. Maintain accounting for both errors and "long errors". If we 340761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // get more than a certain number consecutive errors of either type, 341761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // consider it fatal and shutdown (which will cause the error to 342761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // propagate all of the way up to the application level). The threshold 343761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // for "long errors" is deliberately much lower than that of normal 344761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // decode errors, both because of how long they take to happen and 345761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // because they generally indicate resource limitation errors which are 346761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // unlikely to go away in pathologically bad cases (in contrast to 347761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // stream corruption errors which might happen 20 times in a row and 348761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // then be suddenly OK again) 349761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (res != OK) { 350761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman consecutive_errors++; 351761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (decode_timer.durationUsecs() >= kLongDecodeErrorThreshold) 352761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman consecutive_long_errors++; 353761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 354761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(NULL == bufOut); 355761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 356761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGW("%s: Failed to decode data (res = %d)", 357761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman __PRETTY_FUNCTION__, res); 358761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 359761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if ((consecutive_errors >= kMaxErrorsBeforeFatal) || 360761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman (consecutive_long_errors >= kMaxLongErrorsBeforeFatal)) { 361761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGE("%s: Maximum decode error threshold has been reached." 362761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman " There have been %d consecutive decode errors, and %d" 363761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman " consecutive decode operations which resulted in errors" 364761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman " and took more than %lld uSec to process. The last" 365761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman " decode operation took %lld uSec.", 366761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman __PRETTY_FUNCTION__, 367761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman consecutive_errors, consecutive_long_errors, 368761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman kLongDecodeErrorThreshold, decode_timer.durationUsecs()); 369761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman thread_status_ = res; 370761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman break; 371761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 372761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 373761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman continue; 374761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 375761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 376761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (NULL == bufOut) { 377761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGW("%s: Successful decode, but no buffer produced", 378761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman __PRETTY_FUNCTION__); 379761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman continue; 380761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 381761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 382761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Successful decode (with actual output produced). Clear the error 383761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // counters. 384761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman consecutive_errors = 0; 385761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman consecutive_long_errors = 0; 386761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 387761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman queueToRenderer(bufOut); 388761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman bufOut->release(); 389761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 390761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 391761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman decoder_->stop(); 392761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman stopAndCleanupRenderer(); 393761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 394761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return NULL; 395761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 396761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 397761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanstatus_t AAH_DecoderPump::init(const sp<MetaData>& params) { 398761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman Mutex::Autolock lock(&init_lock_); 399761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 400761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (decoder_ != NULL) { 401761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // already inited 402761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return OK; 403761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 404761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 405761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (params == NULL) { 406761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return BAD_VALUE; 407761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 408761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 409761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (!params->findInt32(kKeyChannelCount, &format_channels_)) { 410761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return BAD_VALUE; 411761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 412761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 413761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (!params->findInt32(kKeySampleRate, &format_sample_rate_)) { 414761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return BAD_VALUE; 415761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 416761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 417761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(OK == thread_status_); 418761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(decoder_ == NULL); 419761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 420761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman status_t ret_val = UNKNOWN_ERROR; 421761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 422761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Cache the format and attempt to create the decoder. 423761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman format_ = params; 424761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman decoder_ = OMXCodec::Create( 425761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman omx_.interface(), // IOMX Handle 426761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman format_, // Metadata for substream (indicates codec) 427761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman false, // Make a decoder, not an encoder 428761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman sp<MediaSource>(this)); // We will be the source for this codec. 429761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 430761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (decoder_ == NULL) { 431761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGE("Failed to allocate decoder in %s", __PRETTY_FUNCTION__); 432761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman goto bailout; 433761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 434761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 435761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Fire up the pump thread. It will take care of starting and stopping the 436761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // decoder. 437761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ret_val = thread_->run("aah_decode_pump", ANDROID_PRIORITY_AUDIO); 438761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (OK != ret_val) { 439761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGE("Failed to start work thread in %s (res = %d)", 440761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman __PRETTY_FUNCTION__, ret_val); 441761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman goto bailout; 442761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 443761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 444761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanbailout: 445761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (OK != ret_val) { 446761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman decoder_ = NULL; 447761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman format_ = NULL; 448761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 449761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 450761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return OK; 451761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 452761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 453761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanstatus_t AAH_DecoderPump::shutdown() { 454761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman Mutex::Autolock lock(&init_lock_); 455761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return shutdown_l(); 456761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 457761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 458761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanstatus_t AAH_DecoderPump::shutdown_l() { 459761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman thread_->requestExit(); 460761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman thread_cond_.signal(); 461761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman thread_->requestExitAndWait(); 462761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 463761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman for (MBQueue::iterator iter = in_queue_.begin(); 464761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman iter != in_queue_.end(); 465761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ++iter) { 466761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman (*iter)->release(); 467761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 468761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman in_queue_.clear(); 469761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 470761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman last_queued_pts_valid_ = false; 471761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman last_ts_transform_valid_ = false; 472761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman last_volume_ = 0xFF; 473761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman thread_status_ = OK; 474761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 475761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman decoder_ = NULL; 476761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman format_ = NULL; 477761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 478761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return OK; 479761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 480761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 481761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanstatus_t AAH_DecoderPump::read(MediaBuffer **buffer, 482761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman const ReadOptions *options) { 483761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (!buffer) { 484761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return BAD_VALUE; 485761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 486761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 487761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman *buffer = NULL; 488761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 489761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // While its not time to shut down, and we have no data to process, wait. 490761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman AutoMutex lock(&thread_lock_); 491761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman while (!thread_->exitPending() && in_queue_.empty()) 492761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman thread_cond_.wait(thread_lock_); 493761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 494761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // At this point, if its not time to shutdown then we must have something to 495761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // process. Go ahead and pop the front of the queue for processing. 496761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (!thread_->exitPending()) { 497761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(!in_queue_.empty()); 498761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 499761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman *buffer = *(in_queue_.begin()); 500761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman in_queue_.erase(in_queue_.begin()); 501761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 502761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 503761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // If we managed to get a buffer, then everything must be OK. If not, then 504761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // we must be shutting down. 505761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return (NULL == *buffer) ? INVALID_OPERATION : OK; 506761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 507761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 508761defc341c5ce9019a42919c441f035f665ec0dJohn GrossmanAAH_DecoderPump::ThreadWrapper::ThreadWrapper(AAH_DecoderPump* owner) 509761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman : Thread(false /* canCallJava*/ ) 510761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman , owner_(owner) { 511761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 512761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 513761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanbool AAH_DecoderPump::ThreadWrapper::threadLoop() { 514761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(NULL != owner_); 515761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman owner_->workThread(); 516761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return false; 517761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 518761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 519761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} // namespace android 520