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/MediaCodecBuffer.h>
27 #include <media/stagefright/foundation/ADebug.h>
28 #include <media/stagefright/foundation/AMessage.h>
29 
30 namespace android {
31 
DecoderBase(const sp<AMessage> & notify)32 NuPlayer::DecoderBase::DecoderBase(const sp<AMessage> &notify)
33     :  mNotify(notify),
34        mBufferGeneration(0),
35        mPaused(false),
36        mStats(new AMessage),
37        mRequestInputBuffersPending(false) {
38     // Every decoder has its own looper because MediaCodec operations
39     // are blocking, but NuPlayer needs asynchronous operations.
40     mDecoderLooper = new ALooper;
41     mDecoderLooper->setName("NPDecoder");
42     mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
43 }
44 
~DecoderBase()45 NuPlayer::DecoderBase::~DecoderBase() {
46     stopLooper();
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 
stopLooper()75 void NuPlayer::DecoderBase::stopLooper() {
76     mDecoderLooper->unregisterHandler(id());
77     mDecoderLooper->stop();
78 }
79 
setParameters(const sp<AMessage> & params)80 void NuPlayer::DecoderBase::setParameters(const sp<AMessage> &params) {
81     sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
82     msg->setMessage("params", params);
83     msg->post();
84 }
85 
setRenderer(const sp<Renderer> & renderer)86 void NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
87     sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
88     msg->setObject("renderer", renderer);
89     msg->post();
90 }
91 
pause()92 void NuPlayer::DecoderBase::pause() {
93     sp<AMessage> msg = new AMessage(kWhatPause, this);
94 
95     sp<AMessage> response;
96     PostAndAwaitResponse(msg, &response);
97 }
98 
signalFlush()99 void NuPlayer::DecoderBase::signalFlush() {
100     (new AMessage(kWhatFlush, this))->post();
101 }
102 
signalResume(bool notifyComplete)103 void NuPlayer::DecoderBase::signalResume(bool notifyComplete) {
104     sp<AMessage> msg = new AMessage(kWhatResume, this);
105     msg->setInt32("notifyComplete", notifyComplete);
106     msg->post();
107 }
108 
initiateShutdown()109 void NuPlayer::DecoderBase::initiateShutdown() {
110     (new AMessage(kWhatShutdown, this))->post();
111 }
112 
onRequestInputBuffers()113 void NuPlayer::DecoderBase::onRequestInputBuffers() {
114     if (mRequestInputBuffersPending) {
115         return;
116     }
117 
118     // doRequestBuffers() return true if we should request more data
119     if (doRequestBuffers()) {
120         mRequestInputBuffersPending = true;
121 
122         sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
123         msg->post(10 * 1000LL);
124     }
125 }
126 
onMessageReceived(const sp<AMessage> & msg)127 void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
128 
129     switch (msg->what()) {
130         case kWhatConfigure:
131         {
132             sp<AMessage> format;
133             CHECK(msg->findMessage("format", &format));
134             onConfigure(format);
135             break;
136         }
137 
138         case kWhatSetParameters:
139         {
140             sp<AMessage> params;
141             CHECK(msg->findMessage("params", &params));
142             onSetParameters(params);
143             break;
144         }
145 
146         case kWhatSetRenderer:
147         {
148             sp<RefBase> obj;
149             CHECK(msg->findObject("renderer", &obj));
150             onSetRenderer(static_cast<Renderer *>(obj.get()));
151             break;
152         }
153 
154         case kWhatPause:
155         {
156             sp<AReplyToken> replyID;
157             CHECK(msg->senderAwaitsResponse(&replyID));
158 
159             mPaused = true;
160 
161             (new AMessage)->postReply(replyID);
162             break;
163         }
164 
165         case kWhatRequestInputBuffers:
166         {
167             mRequestInputBuffersPending = false;
168             onRequestInputBuffers();
169             break;
170         }
171 
172         case kWhatFlush:
173         {
174             onFlush();
175             break;
176         }
177 
178         case kWhatResume:
179         {
180             int32_t notifyComplete;
181             CHECK(msg->findInt32("notifyComplete", &notifyComplete));
182 
183             onResume(notifyComplete);
184             break;
185         }
186 
187         case kWhatShutdown:
188         {
189             onShutdown(true);
190             break;
191         }
192 
193         default:
194             TRESPASS();
195             break;
196     }
197 }
198 
handleError(int32_t err)199 void NuPlayer::DecoderBase::handleError(int32_t err)
200 {
201     // We cannot immediately release the codec due to buffers still outstanding
202     // in the renderer.  We signal to the player the error so it can shutdown/release the
203     // decoder after flushing and increment the generation to discard unnecessary messages.
204 
205     ++mBufferGeneration;
206 
207     sp<AMessage> notify = mNotify->dup();
208     notify->setInt32("what", kWhatError);
209     notify->setInt32("err", err);
210     notify->post();
211 }
212 
213 }  // namespace android
214 
215