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