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