• 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 "NuPlayerDecoder"
19 #include <utils/Log.h>
20 
21 #include "NuPlayerDecoder.h"
22 
23 #include "ESDS.h"
24 
25 #include <media/stagefright/foundation/ABuffer.h>
26 #include <media/stagefright/foundation/ADebug.h>
27 #include <media/stagefright/foundation/AMessage.h>
28 #include <media/stagefright/ACodec.h>
29 #include <media/stagefright/MediaDefs.h>
30 #include <media/stagefright/MetaData.h>
31 #include <media/stagefright/Utils.h>
32 
33 namespace android {
34 
Decoder(const sp<AMessage> & notify,const sp<NativeWindowWrapper> & nativeWindow)35 NuPlayer::Decoder::Decoder(
36         const sp<AMessage> &notify,
37         const sp<NativeWindowWrapper> &nativeWindow)
38     : mNotify(notify),
39       mNativeWindow(nativeWindow) {
40 }
41 
~Decoder()42 NuPlayer::Decoder::~Decoder() {
43 }
44 
configure(const sp<MetaData> & meta)45 void NuPlayer::Decoder::configure(const sp<MetaData> &meta) {
46     CHECK(mCodec == NULL);
47 
48     const char *mime;
49     CHECK(meta->findCString(kKeyMIMEType, &mime));
50 
51     sp<AMessage> notifyMsg =
52         new AMessage(kWhatCodecNotify, id());
53 
54     sp<AMessage> format = makeFormat(meta);
55 
56     if (mNativeWindow != NULL) {
57         format->setObject("native-window", mNativeWindow);
58     }
59 
60     // Current video decoders do not return from OMX_FillThisBuffer
61     // quickly, violating the OpenMAX specs, until that is remedied
62     // we need to invest in an extra looper to free the main event
63     // queue.
64     bool needDedicatedLooper = !strncasecmp(mime, "video/", 6);
65 
66     mCodec = new ACodec;
67 
68     if (needDedicatedLooper && mCodecLooper == NULL) {
69         mCodecLooper = new ALooper;
70         mCodecLooper->setName("NuPlayerDecoder");
71         mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
72     }
73 
74     (needDedicatedLooper ? mCodecLooper : looper())->registerHandler(mCodec);
75 
76     mCodec->setNotificationMessage(notifyMsg);
77     mCodec->initiateSetup(format);
78 }
79 
onMessageReceived(const sp<AMessage> & msg)80 void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
81     switch (msg->what()) {
82         case kWhatCodecNotify:
83         {
84             int32_t what;
85             CHECK(msg->findInt32("what", &what));
86 
87             if (what == ACodec::kWhatFillThisBuffer) {
88                 onFillThisBuffer(msg);
89             } else {
90                 sp<AMessage> notify = mNotify->dup();
91                 notify->setMessage("codec-request", msg);
92                 notify->post();
93             }
94             break;
95         }
96 
97         default:
98             TRESPASS();
99             break;
100     }
101 }
102 
makeFormat(const sp<MetaData> & meta)103 sp<AMessage> NuPlayer::Decoder::makeFormat(const sp<MetaData> &meta) {
104     CHECK(mCSD.isEmpty());
105 
106     sp<AMessage> msg;
107     CHECK_EQ(convertMetaDataToMessage(meta, &msg), (status_t)OK);
108 
109     mCSDIndex = 0;
110     for (size_t i = 0;; ++i) {
111         sp<ABuffer> csd;
112         if (!msg->findBuffer(StringPrintf("csd-%d", i).c_str(), &csd)) {
113             break;
114         }
115 
116         mCSD.push(csd);
117     }
118 
119     return msg;
120 }
121 
onFillThisBuffer(const sp<AMessage> & msg)122 void NuPlayer::Decoder::onFillThisBuffer(const sp<AMessage> &msg) {
123     sp<AMessage> reply;
124     CHECK(msg->findMessage("reply", &reply));
125 
126 #if 0
127     sp<ABuffer> outBuffer;
128     CHECK(msg->findBuffer("buffer", &outBuffer));
129 #else
130     sp<ABuffer> outBuffer;
131 #endif
132 
133     if (mCSDIndex < mCSD.size()) {
134         outBuffer = mCSD.editItemAt(mCSDIndex++);
135         outBuffer->meta()->setInt64("timeUs", 0);
136 
137         reply->setBuffer("buffer", outBuffer);
138         reply->post();
139         return;
140     }
141 
142     sp<AMessage> notify = mNotify->dup();
143     notify->setMessage("codec-request", msg);
144     notify->post();
145 }
146 
signalFlush()147 void NuPlayer::Decoder::signalFlush() {
148     if (mCodec != NULL) {
149         mCodec->signalFlush();
150     }
151 }
152 
signalResume()153 void NuPlayer::Decoder::signalResume() {
154     if (mCodec != NULL) {
155         mCodec->signalResume();
156     }
157 }
158 
initiateShutdown()159 void NuPlayer::Decoder::initiateShutdown() {
160     if (mCodec != NULL) {
161         mCodec->initiateShutdown();
162     }
163 }
164 
165 }  // namespace android
166 
167