blob: 6941f777cdee448c583326f03ab8b04df142dedc [file] [log] [blame]
Chong Zhang7137ec72014-11-12 16:41:05 -08001/*
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