blob: 143956015730f5d361fb180798cc62abbc129427 [file] [log] [blame]
Ajit Khare73cfaf42013-01-07 23:28:47 -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
Shalaj Jain65506622013-01-29 18:27:08 -080017//#define LOG_NDEBUG 0
Ajit Khare73cfaf42013-01-07 23:28:47 -080018#define LOG_TAG "DashPlayerDecoder"
19#include <utils/Log.h>
20
21#include "DashPlayerDecoder.h"
Shalaj Jain65506622013-01-29 18:27:08 -080022#include "DashCodec.h"
Ajit Khare73cfaf42013-01-07 23:28:47 -080023#include "ESDS.h"
24#include "QCMediaDefs.h"
25#include "QCMetaData.h"
26#include <media/stagefright/foundation/ABuffer.h>
27#include <media/stagefright/foundation/ADebug.h>
28#include <media/stagefright/foundation/AMessage.h>
Ajit Khare73cfaf42013-01-07 23:28:47 -080029#include <media/stagefright/MediaDefs.h>
30#include <media/stagefright/MetaData.h>
31#include <media/stagefright/Utils.h>
32
33namespace android {
34
35DashPlayer::Decoder::Decoder(
36 const sp<AMessage> &notify,
37 const sp<NativeWindowWrapper> &nativeWindow)
38 : mNotify(notify),
39 mNativeWindow(nativeWindow) {
40 mAudioSink = NULL;
41}
42
43DashPlayer::Decoder::~Decoder() {
Naupada Dharmendra Patnaikc1b2eb42013-03-14 14:13:49 +053044 ALooper::handler_id id = 0;
45 if (mCodec != NULL) {
46 id = mCodec->id();
47 }
48 if (id != 0) {
49 if (mCodecLooper != NULL) {
50 mCodecLooper->stop();
51 mCodecLooper->unregisterHandler(id);
52 }
53 looper()->unregisterHandler(id);
54 }
Ajit Khare73cfaf42013-01-07 23:28:47 -080055}
56
57void DashPlayer::Decoder::configure(const sp<MetaData> &meta) {
58 CHECK(mCodec == NULL);
59
60 const char *mime;
61 CHECK(meta->findCString(kKeyMIMEType, &mime));
62
63 ALOGV("@@@@:: Decoder::configure :: mime is --- %s ---",mime);
64
65 sp<AMessage> notifyMsg =
66 new AMessage(kWhatCodecNotify, id());
67
68 sp<AMessage> format = makeFormat(meta);
69
70 if (mNativeWindow != NULL) {
71 format->setObject("native-window", mNativeWindow);
72 }
73
74 // Current video decoders do not return from OMX_FillThisBuffer
75 // quickly, violating the OpenMAX specs, until that is remedied
76 // we need to invest in an extra looper to free the main event
77 // queue.
78 bool isVideo = !strncasecmp(mime, "video/", 6);
79
80 if(!isVideo) {
81 const char *mime;
82 CHECK(meta->findCString(kKeyMIMEType, &mime));
83 }
84
Shalaj Jain65506622013-01-29 18:27:08 -080085 ALOGV("@@@@:: DashCodec created ");
86 mCodec = new DashCodec;
Ajit Khare73cfaf42013-01-07 23:28:47 -080087
88 bool needDedicatedLooper = false;
89
90 if (isVideo){
91 needDedicatedLooper = true;
92 if(mCodecLooper == NULL) {
93 ALOGV("@@@@:: Creating Looper for %s",(isVideo?"Video":"Audio"));
94 mCodecLooper = new ALooper;
95 mCodecLooper->setName("DashPlayerDecoder");
96 mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
97 }
98 }
99
100 (needDedicatedLooper ? mCodecLooper : looper())->registerHandler(mCodec);
101 mCodec->setNotificationMessage(notifyMsg);
102 mCodec->initiateSetup(format);
103
104}
105
106void DashPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
107 switch (msg->what()) {
108 case kWhatCodecNotify:
109 {
110 int32_t what;
111 CHECK(msg->findInt32("what", &what));
112
Shalaj Jain65506622013-01-29 18:27:08 -0800113 if (what == DashCodec::kWhatFillThisBuffer) {
Ajit Khare73cfaf42013-01-07 23:28:47 -0800114 onFillThisBuffer(msg);
115 }else {
116 sp<AMessage> notify = mNotify->dup();
117 notify->setMessage("codec-request", msg);
118 notify->post();
119 }
120 break;
121 }
122
123 default:
124 TRESPASS();
125 break;
126 }
127}
128
129void DashPlayer::Decoder::setSink(const sp<MediaPlayerBase::AudioSink> &sink, sp<Renderer> Renderer) {
130 mAudioSink = sink;
131 mRenderer = Renderer;
132}
133
134
135sp<AMessage> DashPlayer::Decoder::makeFormat(const sp<MetaData> &meta) {
136 CHECK(mCSD.isEmpty());
137
138 sp<AMessage> msg;
139 uint32_t type;
140 const void *data;
141 size_t size;
142
143 CHECK_EQ(convertMetaDataToMessage(meta, &msg), (status_t)OK);
144
145 int32_t value;
146 if (meta->findInt32(kKeySmoothStreaming, &value)) {
147 msg->setInt32("smooth-streaming", value);
148 }
149
150 if (meta->findInt32(kKeyIsDRM, &value)) {
151 msg->setInt32("secure-op", 1);
152 }
153
154 if (meta->findInt32(kKeyRequiresSecureBuffers, &value)) {
155 msg->setInt32("requires-secure-buffers", 1);
156 }
157
158 if (meta->findInt32(kKeyEnableDecodeOrder, &value)) {
159 msg->setInt32("decodeOrderEnable", value);
160 }
161 if (meta->findData(kKeyAacCodecSpecificData, &type, &data, &size)) {
162 if (size > 0 && data != NULL) {
163 sp<ABuffer> buffer = new ABuffer(size);
164 if (buffer != NULL) {
165 memcpy(buffer->data(), data, size);
166 buffer->meta()->setInt32("csd", true);
167 buffer->meta()->setInt64("timeUs", 0);
168 msg->setBuffer("csd-0", buffer);
169 }
170 else {
171 ALOGE("kKeyAacCodecSpecificData ABuffer Allocation failed");
172 }
173 }
174 else {
175 ALOGE("Not a valid data pointer or size == 0");
176 }
177 }
178
179
180 mCSDIndex = 0;
181 for (size_t i = 0;; ++i) {
182 sp<ABuffer> csd;
183 if (!msg->findBuffer(StringPrintf("csd-%d", i).c_str(), &csd)) {
184 break;
185 }
186
187 mCSD.push(csd);
188 }
189
190 return msg;
191}
192
193void DashPlayer::Decoder::onFillThisBuffer(const sp<AMessage> &msg) {
194 sp<AMessage> reply;
195 CHECK(msg->findMessage("reply", &reply));
196
197#if 0
198 sp<ABuffer> outBuffer;
199 CHECK(msg->findBuffer("buffer", &outBuffer));
200#else
201 sp<ABuffer> outBuffer;
202#endif
203
204 if (mCSDIndex < mCSD.size()) {
205 outBuffer = mCSD.editItemAt(mCSDIndex++);
206 outBuffer->meta()->setInt64("timeUs", 0);
207
208 reply->setBuffer("buffer", outBuffer);
209 reply->post();
210 return;
211 }
212
213 sp<AMessage> notify = mNotify->dup();
214 notify->setMessage("codec-request", msg);
215 notify->post();
216}
217
218void DashPlayer::Decoder::signalFlush() {
219 if (mCodec != NULL) {
220 mCodec->signalFlush();
221 }
222}
223
224void DashPlayer::Decoder::signalResume() {
225 if(mCodec != NULL) {
226 mCodec->signalResume();
227 }
228}
229
230void DashPlayer::Decoder::initiateShutdown() {
231 if (mCodec != NULL) {
232 mCodec->initiateShutdown();
233 }
234}
235
236} // namespace android
237