1f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/* 2f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Copyright (C) 2010 The Android Open Source Project 3f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 4f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * you may not use this file except in compliance with the License. 6f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * You may obtain a copy of the License at 7f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 8f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 10f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Unless required by applicable law or agreed to in writing, software 11f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * See the License for the specific language governing permissions and 14f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * limitations under the License. 15f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 16f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0 18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "NuPlayerDecoder" 19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Log.h> 20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerDecoder.h" 22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h> 255bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <media/stagefright/foundation/AMessage.h> 26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h> 27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h> 28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 29f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android { 30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 31f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::Decoder( 321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten const sp<AMessage> ¬ify, 331173118eace0e9e347cb007f0da817cee87579edGlenn Kasten const sp<NativeWindowWrapper> &nativeWindow) 34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : mNotify(notify), 351173118eace0e9e347cb007f0da817cee87579edGlenn Kasten mNativeWindow(nativeWindow) { 36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 38f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::~Decoder() { 39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 41840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubervoid NuPlayer::Decoder::configure(const sp<AMessage> &format) { 42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mCodec == NULL); 43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 44840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber AString mime; 45840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(format->findString("mime", &mime)); 46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notifyMsg = 48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber new AMessage(kWhatCodecNotify, id()); 49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 50840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mCSDIndex = 0; 51840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber for (size_t i = 0;; ++i) { 52840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber sp<ABuffer> csd; 53840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if (!format->findBuffer(StringPrintf("csd-%d", i).c_str(), &csd)) { 54840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber break; 55840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 56840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 57840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber mCSD.push(csd); 58840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 601173118eace0e9e347cb007f0da817cee87579edGlenn Kasten if (mNativeWindow != NULL) { 611173118eace0e9e347cb007f0da817cee87579edGlenn Kasten format->setObject("native-window", mNativeWindow); 62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 64078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // Current video decoders do not return from OMX_FillThisBuffer 65078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // quickly, violating the OpenMAX specs, until that is remedied 66078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // we need to invest in an extra looper to free the main event 67078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber // queue. 68840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber bool needDedicatedLooper = !strncasecmp(mime.c_str(), "video/", 6); 69078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 700523da8f16557a85395da86ab76be6d8cb771da0Robert Shih mFormat = format; 7100f4951088805442e86ff9c2a20ddad79fc2410aAndreas Huber mCodec = new ACodec; 72078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 73078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber if (needDedicatedLooper && mCodecLooper == NULL) { 74078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mCodecLooper = new ALooper; 75078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mCodecLooper->setName("NuPlayerDecoder"); 76078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 77078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 78078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 79078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber (needDedicatedLooper ? mCodecLooper : looper())->registerHandler(mCodec); 80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 8100f4951088805442e86ff9c2a20ddad79fc2410aAndreas Huber mCodec->setNotificationMessage(notifyMsg); 8200f4951088805442e86ff9c2a20ddad79fc2410aAndreas Huber mCodec->initiateSetup(format); 83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 85f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { 86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatCodecNotify: 88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t what; 90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("what", &what)); 91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (what == ACodec::kWhatFillThisBuffer) { 93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onFillThisBuffer(msg); 94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mNotify->dup(); 96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setMessage("codec-request", msg); 97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->post(); 98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber TRESPASS(); 104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 108f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Decoder::onFillThisBuffer(const sp<AMessage> &msg) { 109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> reply; 110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findMessage("reply", &reply)); 111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0 1132d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber sp<ABuffer> outBuffer; 1142d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber CHECK(msg->findBuffer("buffer", &outBuffer)); 115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#else 116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ABuffer> outBuffer; 117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif 118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mCSDIndex < mCSD.size()) { 120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer = mCSD.editItemAt(mCSDIndex++); 121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer->meta()->setInt64("timeUs", 0); 122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1232d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber reply->setBuffer("buffer", outBuffer); 124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->post(); 125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mNotify->dup(); 129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->setMessage("codec-request", msg); 130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->post(); 131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 133f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Decoder::signalFlush() { 134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mCodec != NULL) { 135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->signalFlush(); 136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 139f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::Decoder::signalResume() { 140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mCodec != NULL) { 141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->signalResume(); 142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1453831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Hubervoid NuPlayer::Decoder::initiateShutdown() { 1463831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber if (mCodec != NULL) { 1473831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber mCodec->initiateShutdown(); 1483831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 1493831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber} 1503831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 1510523da8f16557a85395da86ab76be6d8cb771da0Robert Shihbool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const { 1520523da8f16557a85395da86ab76be6d8cb771da0Robert Shih if (targetFormat == NULL) { 1530523da8f16557a85395da86ab76be6d8cb771da0Robert Shih return true; 1540523da8f16557a85395da86ab76be6d8cb771da0Robert Shih } 1550523da8f16557a85395da86ab76be6d8cb771da0Robert Shih 1560523da8f16557a85395da86ab76be6d8cb771da0Robert Shih AString mime; 1570523da8f16557a85395da86ab76be6d8cb771da0Robert Shih if (!targetFormat->findString("mime", &mime)) { 1580523da8f16557a85395da86ab76be6d8cb771da0Robert Shih return false; 1590523da8f16557a85395da86ab76be6d8cb771da0Robert Shih } 1600523da8f16557a85395da86ab76be6d8cb771da0Robert Shih 1610523da8f16557a85395da86ab76be6d8cb771da0Robert Shih if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 1620523da8f16557a85395da86ab76be6d8cb771da0Robert Shih // field-by-field comparison 1630523da8f16557a85395da86ab76be6d8cb771da0Robert Shih const char * keys[] = { "channel-count", "sample-rate", "is-adts" }; 1640523da8f16557a85395da86ab76be6d8cb771da0Robert Shih for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) { 1650523da8f16557a85395da86ab76be6d8cb771da0Robert Shih int32_t oldVal, newVal; 1660523da8f16557a85395da86ab76be6d8cb771da0Robert Shih if (!mFormat->findInt32(keys[i], &oldVal) || !targetFormat->findInt32(keys[i], &newVal) 1670523da8f16557a85395da86ab76be6d8cb771da0Robert Shih || oldVal != newVal) { 1680523da8f16557a85395da86ab76be6d8cb771da0Robert Shih return false; 1690523da8f16557a85395da86ab76be6d8cb771da0Robert Shih } 1700523da8f16557a85395da86ab76be6d8cb771da0Robert Shih } 1710523da8f16557a85395da86ab76be6d8cb771da0Robert Shih 1720523da8f16557a85395da86ab76be6d8cb771da0Robert Shih sp<ABuffer> oldBuf, newBuf; 1730523da8f16557a85395da86ab76be6d8cb771da0Robert Shih if (mFormat->findBuffer("csd-0", &oldBuf) && targetFormat->findBuffer("csd-0", &newBuf)) { 1740523da8f16557a85395da86ab76be6d8cb771da0Robert Shih if (oldBuf->size() != newBuf->size()) { 1750523da8f16557a85395da86ab76be6d8cb771da0Robert Shih return false; 1760523da8f16557a85395da86ab76be6d8cb771da0Robert Shih } 1770523da8f16557a85395da86ab76be6d8cb771da0Robert Shih return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size()); 1780523da8f16557a85395da86ab76be6d8cb771da0Robert Shih } 1790523da8f16557a85395da86ab76be6d8cb771da0Robert Shih } 1800523da8f16557a85395da86ab76be6d8cb771da0Robert Shih return false; 1810523da8f16557a85395da86ab76be6d8cb771da0Robert Shih} 1820523da8f16557a85395da86ab76be6d8cb771da0Robert Shih 1830523da8f16557a85395da86ab76be6d8cb771da0Robert Shihbool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const { 1840523da8f16557a85395da86ab76be6d8cb771da0Robert Shih if (mFormat == NULL) { 1850523da8f16557a85395da86ab76be6d8cb771da0Robert Shih return false; 1860523da8f16557a85395da86ab76be6d8cb771da0Robert Shih } 1870523da8f16557a85395da86ab76be6d8cb771da0Robert Shih 1880523da8f16557a85395da86ab76be6d8cb771da0Robert Shih if (targetFormat == NULL) { 1890523da8f16557a85395da86ab76be6d8cb771da0Robert Shih return true; 1900523da8f16557a85395da86ab76be6d8cb771da0Robert Shih } 1910523da8f16557a85395da86ab76be6d8cb771da0Robert Shih 1920523da8f16557a85395da86ab76be6d8cb771da0Robert Shih AString oldMime, newMime; 1930523da8f16557a85395da86ab76be6d8cb771da0Robert Shih if (!mFormat->findString("mime", &oldMime) 1940523da8f16557a85395da86ab76be6d8cb771da0Robert Shih || !targetFormat->findString("mime", &newMime) 1950523da8f16557a85395da86ab76be6d8cb771da0Robert Shih || !(oldMime == newMime)) { 1960523da8f16557a85395da86ab76be6d8cb771da0Robert Shih return false; 1970523da8f16557a85395da86ab76be6d8cb771da0Robert Shih } 1980523da8f16557a85395da86ab76be6d8cb771da0Robert Shih 1990523da8f16557a85395da86ab76be6d8cb771da0Robert Shih bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/")); 2000523da8f16557a85395da86ab76be6d8cb771da0Robert Shih bool seamless; 2010523da8f16557a85395da86ab76be6d8cb771da0Robert Shih if (audio) { 2020523da8f16557a85395da86ab76be6d8cb771da0Robert Shih seamless = supportsSeamlessAudioFormatChange(targetFormat); 2030523da8f16557a85395da86ab76be6d8cb771da0Robert Shih } else { 2040523da8f16557a85395da86ab76be6d8cb771da0Robert Shih seamless = mCodec != NULL && mCodec->isConfiguredForAdaptivePlayback(); 2050523da8f16557a85395da86ab76be6d8cb771da0Robert Shih } 2060523da8f16557a85395da86ab76be6d8cb771da0Robert Shih 2070523da8f16557a85395da86ab76be6d8cb771da0Robert Shih ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str()); 2080523da8f16557a85395da86ab76be6d8cb771da0Robert Shih return seamless; 2090523da8f16557a85395da86ab76be6d8cb771da0Robert Shih} 2100523da8f16557a85395da86ab76be6d8cb771da0Robert Shih 211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} // namespace android 212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 213