NuPlayerDecoderBase.cpp revision 7137ec7e005a5a6e3c0edb91cfacf16a31f4bf6a
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()
32    : mRequestInputBuffersPending(false) {
33    // Every decoder has its own looper because MediaCodec operations
34    // are blocking, but NuPlayer needs asynchronous operations.
35    mDecoderLooper = new ALooper;
36    mDecoderLooper->setName("NPDecoder");
37    mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
38}
39
40NuPlayer::DecoderBase::~DecoderBase() {
41    mDecoderLooper->unregisterHandler(id());
42    mDecoderLooper->stop();
43}
44
45static
46status_t PostAndAwaitResponse(
47        const sp<AMessage> &msg, sp<AMessage> *response) {
48    status_t err = msg->postAndAwaitResponse(response);
49
50    if (err != OK) {
51        return err;
52    }
53
54    if (!(*response)->findInt32("err", &err)) {
55        err = OK;
56    }
57
58    return err;
59}
60
61void NuPlayer::DecoderBase::configure(const sp<AMessage> &format) {
62    sp<AMessage> msg = new AMessage(kWhatConfigure, id());
63    msg->setMessage("format", format);
64    msg->post();
65}
66
67void NuPlayer::DecoderBase::init() {
68    mDecoderLooper->registerHandler(this);
69}
70
71void NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
72    sp<AMessage> msg = new AMessage(kWhatSetRenderer, id());
73    msg->setObject("renderer", renderer);
74    msg->post();
75}
76
77status_t NuPlayer::DecoderBase::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
78    sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, id());
79    msg->setPointer("buffers", buffers);
80
81    sp<AMessage> response;
82    return PostAndAwaitResponse(msg, &response);
83}
84
85void NuPlayer::DecoderBase::signalFlush() {
86    (new AMessage(kWhatFlush, id()))->post();
87}
88
89void NuPlayer::DecoderBase::signalResume() {
90    (new AMessage(kWhatResume, id()))->post();
91}
92
93void NuPlayer::DecoderBase::initiateShutdown() {
94    (new AMessage(kWhatShutdown, id()))->post();
95}
96
97void NuPlayer::DecoderBase::onRequestInputBuffers() {
98    if (mRequestInputBuffersPending) {
99        return;
100    }
101
102    doRequestBuffers();
103}
104
105void NuPlayer::DecoderBase::scheduleRequestBuffers() {
106    if (mRequestInputBuffersPending) {
107        return;
108    }
109    mRequestInputBuffersPending = true;
110    sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, id());
111    msg->post(10 * 1000ll);
112}
113
114void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
115
116    switch (msg->what()) {
117        case kWhatConfigure:
118        {
119            sp<AMessage> format;
120            CHECK(msg->findMessage("format", &format));
121            onConfigure(format);
122            break;
123        }
124
125        case kWhatSetRenderer:
126        {
127            sp<RefBase> obj;
128            CHECK(msg->findObject("renderer", &obj));
129            onSetRenderer(static_cast<Renderer *>(obj.get()));
130            break;
131        }
132
133        case kWhatGetInputBuffers:
134        {
135            uint32_t replyID;
136            CHECK(msg->senderAwaitsResponse(&replyID));
137
138            Vector<sp<ABuffer> > *dstBuffers;
139            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
140
141            onGetInputBuffers(dstBuffers);
142
143            (new AMessage)->postReply(replyID);
144            break;
145        }
146
147        case kWhatRequestInputBuffers:
148        {
149            mRequestInputBuffersPending = false;
150            onRequestInputBuffers();
151            break;
152        }
153
154        case kWhatFlush:
155        {
156            onFlush(true);
157            break;
158        }
159
160        case kWhatResume:
161        {
162            onResume();
163            break;
164        }
165
166        case kWhatShutdown:
167        {
168            onShutdown(true);
169            break;
170        }
171
172        default:
173            TRESPASS();
174            break;
175    }
176}
177
178}  // namespace android
179
180