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