NuPlayerDecoderPassThrough.cpp revision de01afbbc55ac9c5c23ec66154603f34217aed2c
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "NuPlayerDecoderPassThrough"
19#include <utils/Log.h>
20#include <inttypes.h>
21
22#include "NuPlayerDecoderPassThrough.h"
23
24#include <media/ICrypto.h>
25#include <media/stagefright/foundation/ABuffer.h>
26#include <media/stagefright/foundation/ADebug.h>
27#include <media/stagefright/foundation/AMessage.h>
28#include <media/stagefright/MediaDefs.h>
29#include <media/stagefright/MediaErrors.h>
30
31namespace android {
32
33static const int kMaxPendingBuffers = 10;
34static const int kMaxCachedBytes = 200000;
35
36NuPlayer::DecoderPassThrough::DecoderPassThrough(
37        const sp<AMessage> &notify)
38    : Decoder(notify),
39      mNotify(notify),
40      mBufferGeneration(0),
41      mReachedEOS(true),
42      mPendingBuffers(0),
43      mCachedBytes(0),
44      mComponentName("pass through decoder") {
45    mDecoderLooper = new ALooper;
46    mDecoderLooper->setName("NuPlayerDecoderPassThrough");
47    mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
48}
49
50NuPlayer::DecoderPassThrough::~DecoderPassThrough() {
51}
52
53void NuPlayer::DecoderPassThrough::configure(const sp<AMessage> &format) {
54    sp<AMessage> msg = new AMessage(kWhatConfigure, id());
55    msg->setMessage("format", format);
56    msg->post();
57}
58
59void NuPlayer::DecoderPassThrough::init() {
60    mDecoderLooper->registerHandler(this);
61}
62
63void NuPlayer::DecoderPassThrough::signalFlush() {
64    (new AMessage(kWhatFlush, id()))->post();
65}
66
67void NuPlayer::DecoderPassThrough::signalResume() {
68    (new AMessage(kWhatResume, id()))->post();
69}
70
71void NuPlayer::DecoderPassThrough::initiateShutdown() {
72    (new AMessage(kWhatShutdown, id()))->post();
73}
74
75bool NuPlayer::DecoderPassThrough::supportsSeamlessFormatChange(
76        const sp<AMessage> & /* targetFormat */) const {
77    return true;
78}
79
80void NuPlayer::DecoderPassThrough::onConfigure(const sp<AMessage> &format) {
81    ALOGV("[%s] onConfigure", mComponentName.c_str());
82    mPendingBuffers = 0;
83    mCachedBytes = 0;
84    mReachedEOS = false;
85    ++mBufferGeneration;
86
87    requestABuffer();
88
89    sp<AMessage> notify = mNotify->dup();
90    notify->setInt32("what", kWhatOutputFormatChanged);
91    notify->setMessage("format", format);
92    notify->post();
93}
94
95bool NuPlayer::DecoderPassThrough::isStaleReply(const sp<AMessage> &msg) {
96    int32_t generation;
97    CHECK(msg->findInt32("generation", &generation));
98    return generation != mBufferGeneration;
99}
100
101void NuPlayer::DecoderPassThrough::requestABuffer() {
102    if (mCachedBytes >= kMaxCachedBytes || mReachedEOS) {
103        ALOGV("[%s] mReachedEOS=%d, max pending buffers(%d:%d)",
104                mComponentName.c_str(), (mReachedEOS ? 1 : 0),
105                mPendingBuffers, kMaxPendingBuffers);
106        return;
107    }
108
109    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id());
110    reply->setInt32("generation", mBufferGeneration);
111
112    sp<AMessage> notify = mNotify->dup();
113    notify->setInt32("what", kWhatFillThisBuffer);
114    notify->setMessage("reply", reply);
115    notify->post();
116    mPendingBuffers++;
117
118    sp<AMessage> message = new AMessage(kWhatRequestABuffer, id());
119    message->setInt32("generation", mBufferGeneration);
120    message->post();
121    return;
122}
123
124void android::NuPlayer::DecoderPassThrough::onInputBufferFilled(
125        const sp<AMessage> &msg) {
126    if (mReachedEOS) {
127        return;
128    }
129
130    sp<ABuffer> buffer;
131    msg->findBuffer("buffer", &buffer);
132    if (buffer == NULL) {
133        mReachedEOS = true;
134
135        sp<AMessage> notify = mNotify->dup();
136        notify->setInt32("what", kWhatEOS);
137        notify->setInt32("err", ERROR_END_OF_STREAM);
138        notify->post();
139        return;
140    }
141
142    mCachedBytes += buffer->size();
143
144    sp<AMessage> reply = new AMessage(kWhatBufferConsumed, id());
145    reply->setInt32("generation", mBufferGeneration);
146    reply->setInt32("size", buffer->size());
147
148    sp<AMessage> notify = mNotify->dup();
149    notify->setInt32("what", kWhatDrainThisBuffer);
150    notify->setBuffer("buffer", buffer);
151    notify->setMessage("reply", reply);
152    notify->post();
153}
154
155void NuPlayer::DecoderPassThrough::onBufferConsumed(int32_t size) {
156    mPendingBuffers--;
157    mCachedBytes -= size;
158    sp<AMessage> message = new AMessage(kWhatRequestABuffer, id());
159    message->setInt32("generation", mBufferGeneration);
160    message->post();
161}
162
163void NuPlayer::DecoderPassThrough::onFlush() {
164    ++mBufferGeneration;
165
166    sp<AMessage> notify = mNotify->dup();
167    notify->setInt32("what", kWhatFlushCompleted);
168    notify->post();
169    mPendingBuffers = 0;
170    mCachedBytes = 0;
171    mReachedEOS = false;
172}
173
174void NuPlayer::DecoderPassThrough::onShutdown() {
175    ++mBufferGeneration;
176
177    sp<AMessage> notify = mNotify->dup();
178    notify->setInt32("what", kWhatShutdownCompleted);
179    notify->post();
180    mReachedEOS = true;
181}
182
183void NuPlayer::DecoderPassThrough::onMessageReceived(const sp<AMessage> &msg) {
184    ALOGV("[%s] onMessage: %s", mComponentName.c_str(),
185            msg->debugString().c_str());
186
187    switch (msg->what()) {
188        case kWhatConfigure:
189        {
190            sp<AMessage> format;
191            CHECK(msg->findMessage("format", &format));
192            onConfigure(format);
193            break;
194        }
195
196        case kWhatRequestABuffer:
197        {
198            if (!isStaleReply(msg)) {
199                requestABuffer();
200            }
201
202            break;
203        }
204
205        case kWhatInputBufferFilled:
206        {
207            if (!isStaleReply(msg)) {
208                onInputBufferFilled(msg);
209            }
210            break;
211        }
212
213        case kWhatBufferConsumed:
214        {
215            if (!isStaleReply(msg)) {
216                int32_t size;
217                CHECK(msg->findInt32("size", &size));
218                onBufferConsumed(size);
219            }
220            break;
221        }
222
223        case kWhatFlush:
224        {
225            onFlush();
226            break;
227        }
228
229        case kWhatResume:
230        {
231            requestABuffer();
232            break;
233        }
234
235        case kWhatShutdown:
236        {
237            onShutdown();
238            break;
239        }
240
241        default:
242            TRESPASS();
243            break;
244    }
245}
246
247}  // namespace android
248