• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
29 namespace android {
30 
DecoderBase(const sp<AMessage> & notify)31 NuPlayer::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 
~DecoderBase()44 NuPlayer::DecoderBase::~DecoderBase() {
45     mDecoderLooper->unregisterHandler(id());
46     mDecoderLooper->stop();
47 }
48 
49 static
PostAndAwaitResponse(const sp<AMessage> & msg,sp<AMessage> * response)50 status_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 
configure(const sp<AMessage> & format)65 void 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 
init()71 void NuPlayer::DecoderBase::init() {
72     mDecoderLooper->registerHandler(this);
73 }
74 
setParameters(const sp<AMessage> & params)75 void 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 
setRenderer(const sp<Renderer> & renderer)81 void 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 
pause()87 void NuPlayer::DecoderBase::pause() {
88     sp<AMessage> msg = new AMessage(kWhatPause, this);
89 
90     sp<AMessage> response;
91     PostAndAwaitResponse(msg, &response);
92 }
93 
getInputBuffers(Vector<sp<ABuffer>> * buffers) const94 status_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 
signalFlush()102 void NuPlayer::DecoderBase::signalFlush() {
103     (new AMessage(kWhatFlush, this))->post();
104 }
105 
signalResume(bool notifyComplete)106 void NuPlayer::DecoderBase::signalResume(bool notifyComplete) {
107     sp<AMessage> msg = new AMessage(kWhatResume, this);
108     msg->setInt32("notifyComplete", notifyComplete);
109     msg->post();
110 }
111 
initiateShutdown()112 void NuPlayer::DecoderBase::initiateShutdown() {
113     (new AMessage(kWhatShutdown, this))->post();
114 }
115 
onRequestInputBuffers()116 void 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 
onMessageReceived(const sp<AMessage> & msg)130 void 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 
handleError(int32_t err)216 void 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