1/*
2 * Copyright (C) 2010 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 "NuPlayerDecoderBase"
19#include <utils/Log.h>
20#include <inttypes.h>
21
22#include "NuPlayerDecoderBase.h"
23
24#include "NuPlayerRenderer.h"
25
26#include <media/stagefright/foundation/ADebug.h>
27#include <media/stagefright/foundation/AMessage.h>
28
29namespace android {
30
31NuPlayer::DecoderBase::DecoderBase(const sp<AMessage> &notify)
32    :  mNotify(notify),
33       mBufferGeneration(0),
34       mPaused(false),
35       mStats(new AMessage),
36       mRequestInputBuffersPending(false) {
37    // Every decoder has its own looper because MediaCodec operations
38    // are blocking, but NuPlayer needs asynchronous operations.
39    mDecoderLooper = new ALooper;
40    mDecoderLooper->setName("NPDecoder");
41    mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
42}
43
44NuPlayer::DecoderBase::~DecoderBase() {
45    mDecoderLooper->unregisterHandler(id());
46    mDecoderLooper->stop();
47}
48
49static
50status_t PostAndAwaitResponse(
51        const sp<AMessage> &msg, sp<AMessage> *response) {
52    status_t err = msg->postAndAwaitResponse(response);
53
54    if (err != OK) {
55        return err;
56    }
57
58    if (!(*response)->findInt32("err", &err)) {
59        err = OK;
60    }
61
62    return err;
63}
64
65void NuPlayer::DecoderBase::configure(const sp<AMessage> &format) {
66    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
67    msg->setMessage("format", format);
68    msg->post();
69}
70
71void NuPlayer::DecoderBase::init() {
72    mDecoderLooper->registerHandler(this);
73}
74
75void NuPlayer::DecoderBase::setParameters(const sp<AMessage> &params) {
76    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
77    msg->setMessage("params", params);
78    msg->post();
79}
80
81void NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
82    sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
83    msg->setObject("renderer", renderer);
84    msg->post();
85}
86
87void NuPlayer::DecoderBase::pause() {
88    sp<AMessage> msg = new AMessage(kWhatPause, this);
89
90    sp<AMessage> response;
91    PostAndAwaitResponse(msg, &response);
92}
93
94status_t NuPlayer::DecoderBase::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
95    sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, this);
96    msg->setPointer("buffers", buffers);
97
98    sp<AMessage> response;
99    return PostAndAwaitResponse(msg, &response);
100}
101
102void NuPlayer::DecoderBase::signalFlush() {
103    (new AMessage(kWhatFlush, this))->post();
104}
105
106void NuPlayer::DecoderBase::signalResume(bool notifyComplete) {
107    sp<AMessage> msg = new AMessage(kWhatResume, this);
108    msg->setInt32("notifyComplete", notifyComplete);
109    msg->post();
110}
111
112void NuPlayer::DecoderBase::initiateShutdown() {
113    (new AMessage(kWhatShutdown, this))->post();
114}
115
116void NuPlayer::DecoderBase::onRequestInputBuffers() {
117    if (mRequestInputBuffersPending) {
118        return;
119    }
120
121    // doRequestBuffers() return true if we should request more data
122    if (doRequestBuffers()) {
123        mRequestInputBuffersPending = true;
124
125        sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
126        msg->post(10 * 1000ll);
127    }
128}
129
130void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
131
132    switch (msg->what()) {
133        case kWhatConfigure:
134        {
135            sp<AMessage> format;
136            CHECK(msg->findMessage("format", &format));
137            onConfigure(format);
138            break;
139        }
140
141        case kWhatSetParameters:
142        {
143            sp<AMessage> params;
144            CHECK(msg->findMessage("params", &params));
145            onSetParameters(params);
146            break;
147        }
148
149        case kWhatSetRenderer:
150        {
151            sp<RefBase> obj;
152            CHECK(msg->findObject("renderer", &obj));
153            onSetRenderer(static_cast<Renderer *>(obj.get()));
154            break;
155        }
156
157        case kWhatPause:
158        {
159            sp<AReplyToken> replyID;
160            CHECK(msg->senderAwaitsResponse(&replyID));
161
162            mPaused = true;
163
164            (new AMessage)->postReply(replyID);
165            break;
166        }
167
168        case kWhatGetInputBuffers:
169        {
170            sp<AReplyToken> replyID;
171            CHECK(msg->senderAwaitsResponse(&replyID));
172
173            Vector<sp<ABuffer> > *dstBuffers;
174            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
175
176            onGetInputBuffers(dstBuffers);
177
178            (new AMessage)->postReply(replyID);
179            break;
180        }
181
182        case kWhatRequestInputBuffers:
183        {
184            mRequestInputBuffersPending = false;
185            onRequestInputBuffers();
186            break;
187        }
188
189        case kWhatFlush:
190        {
191            onFlush();
192            break;
193        }
194
195        case kWhatResume:
196        {
197            int32_t notifyComplete;
198            CHECK(msg->findInt32("notifyComplete", &notifyComplete));
199
200            onResume(notifyComplete);
201            break;
202        }
203
204        case kWhatShutdown:
205        {
206            onShutdown(true);
207            break;
208        }
209
210        default:
211            TRESPASS();
212            break;
213    }
214}
215
216void NuPlayer::DecoderBase::handleError(int32_t err)
217{
218    // We cannot immediately release the codec due to buffers still outstanding
219    // in the renderer.  We signal to the player the error so it can shutdown/release the
220    // decoder after flushing and increment the generation to discard unnecessary messages.
221
222    ++mBufferGeneration;
223
224    sp<AMessage> notify = mNotify->dup();
225    notify->setInt32("what", kWhatError);
226    notify->setInt32("err", err);
227    notify->post();
228}
229
230}  // namespace android
231
232