NuPlayerDecoderBase.cpp revision f8d717772f6d185cb07720cd5091df9b7d612e0b
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(bool notifyComplete) {
90    sp<AMessage> msg = new AMessage(kWhatResume, id());
91    msg->setInt32("notifyComplete", notifyComplete);
92    msg->post();
93}
94
95void NuPlayer::DecoderBase::initiateShutdown() {
96    (new AMessage(kWhatShutdown, id()))->post();
97}
98
99void NuPlayer::DecoderBase::onRequestInputBuffers() {
100    if (mRequestInputBuffersPending) {
101        return;
102    }
103
104    doRequestBuffers();
105}
106
107void NuPlayer::DecoderBase::scheduleRequestBuffers() {
108    if (mRequestInputBuffersPending) {
109        return;
110    }
111    mRequestInputBuffersPending = true;
112    sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, id());
113    msg->post(10 * 1000ll);
114}
115
116void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
117
118    switch (msg->what()) {
119        case kWhatConfigure:
120        {
121            sp<AMessage> format;
122            CHECK(msg->findMessage("format", &format));
123            onConfigure(format);
124            break;
125        }
126
127        case kWhatSetRenderer:
128        {
129            sp<RefBase> obj;
130            CHECK(msg->findObject("renderer", &obj));
131            onSetRenderer(static_cast<Renderer *>(obj.get()));
132            break;
133        }
134
135        case kWhatGetInputBuffers:
136        {
137            uint32_t replyID;
138            CHECK(msg->senderAwaitsResponse(&replyID));
139
140            Vector<sp<ABuffer> > *dstBuffers;
141            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
142
143            onGetInputBuffers(dstBuffers);
144
145            (new AMessage)->postReply(replyID);
146            break;
147        }
148
149        case kWhatRequestInputBuffers:
150        {
151            mRequestInputBuffersPending = false;
152            onRequestInputBuffers();
153            break;
154        }
155
156        case kWhatFlush:
157        {
158            onFlush(true);
159            break;
160        }
161
162        case kWhatResume:
163        {
164            int32_t notifyComplete;
165            CHECK(msg->findInt32("notifyComplete", &notifyComplete));
166
167            onResume(notifyComplete);
168            break;
169        }
170
171        case kWhatShutdown:
172        {
173            onShutdown(true);
174            break;
175        }
176
177        default:
178            TRESPASS();
179            break;
180    }
181}
182
183}  // namespace android
184
185