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