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