NuPlayerDecoder.cpp revision 9806555d3930be43e11106281dee354820ac1c88
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 33namespace android { 34 35NuPlayer::Decoder::Decoder( 36 const sp<AMessage> ¬ify, 37 const sp<NativeWindowWrapper> &nativeWindow) 38 : mNotify(notify), 39 mNativeWindow(nativeWindow) { 40} 41 42NuPlayer::Decoder::~Decoder() { 43} 44 45void 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 80void 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 103sp<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 122void 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 147void NuPlayer::Decoder::signalFlush() { 148 if (mCodec != NULL) { 149 mCodec->signalFlush(); 150 } 151} 152 153void NuPlayer::Decoder::signalResume() { 154 if (mCodec != NULL) { 155 mCodec->signalResume(); 156 } 157} 158 159void NuPlayer::Decoder::initiateShutdown() { 160 if (mCodec != NULL) { 161 mCodec->initiateShutdown(); 162 } 163} 164 165} // namespace android 166 167