NuPlayerDecoder.cpp revision 1de1e25cba872bd4c077c2e394f8ca9c70b65856
116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood/* 216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Copyright 2014 The Android Open Source Project 316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * 416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License"); 516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * you may not use this file except in compliance with the License. 616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * You may obtain a copy of the License at 716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * 816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * http://www.apache.org/licenses/LICENSE-2.0 916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * 1016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Unless required by applicable law or agreed to in writing, software 1116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS, 1216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * See the License for the specific language governing permissions and 1416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * limitations under the License. 1516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood */ 1616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 17b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood//#define LOG_NDEBUG 0 18b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#define LOG_TAG "NuPlayerDecoder" 1916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <utils/Log.h> 2016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <inttypes.h> 2116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 2216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "NuPlayerCCDecoder.h" 230cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood#include "NuPlayerDecoder.h" 240cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood#include "NuPlayerRenderer.h" 2516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "NuPlayerSource.h" 2616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 2716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <media/ICrypto.h> 287850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood#include <media/stagefright/foundation/ABuffer.h> 297850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood#include <media/stagefright/foundation/ADebug.h> 3016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <media/stagefright/foundation/AMessage.h> 3144c190826d72589f5c9e13d69e32673bd8bd7c64Mike Lockwood#include <media/stagefright/MediaBuffer.h> 3216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <media/stagefright/MediaCodec.h> 3316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <media/stagefright/MediaDefs.h> 3416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <media/stagefright/MediaErrors.h> 3516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 3616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <gui/Surface.h> 3716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 3816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "avc_utils.h" 3916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "ATSParser.h" 4016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 4116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodnamespace android { 4216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 4316864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodNuPlayer::Decoder::Decoder( 4416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood const sp<AMessage> ¬ify, 4516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood const sp<Source> &source, 4616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood const sp<Renderer> &renderer, 4716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood const sp<Surface> &surface, 4816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood const sp<CCDecoder> &ccDecoder) 4916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood : DecoderBase(notify), 5016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSurface(surface), 5116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mSource(source), 52ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mRenderer(renderer), 53ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mCCDecoder(ccDecoder), 54ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mSkipRenderingUntilMediaTimeUs(-1ll), 55ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mNumFramesTotal(0ll), 56ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mNumFramesDropped(0ll), 57ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mIsAudio(true), 58ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mIsVideoAVC(false), 59ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mIsSecure(false), 60ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mFormatChangePending(false), 61ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mTimeChangePending(false), 6216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPaused(true), 63ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mResumePending(false), 64ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mComponentName("decoder") { 65ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mCodecLooper = new ALooper; 6616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mCodecLooper->setName("NPDecoder-CL"); 6716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 68ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood} 69ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 70ab063847e6e893740749029a04cce1f6b7345ed5Mike LockwoodNuPlayer::Decoder::~Decoder() { 7116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood releaseAndResetMediaBuffers(); 72ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood} 7316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 74ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodvoid NuPlayer::Decoder::getStats( 75ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood int64_t *numFramesTotal, 7616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int64_t *numFramesDropped) const { 7716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood *numFramesTotal = mNumFramesTotal; 78ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood *numFramesDropped = mNumFramesDropped; 79ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood} 80ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 8116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { 82ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str()); 8316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 8416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood switch (msg->what()) { 8516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case kWhatCodecNotify: 86ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood { 87ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood int32_t cbID; 8816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood CHECK(msg->findInt32("callbackID", &cbID)); 8916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 90ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood ALOGV("[%s] kWhatCodecNotify: cbID = %d, paused = %d", 91ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mIsAudio ? "audio" : "video", cbID, mPaused); 92a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood 93a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood if (mPaused) { 94ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood break; 9516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 96ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 9716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood switch (cbID) { 9816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood case MediaCodec::CB_INPUT_AVAILABLE: 99335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood { 100ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood int32_t index; 101ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood CHECK(msg->findInt32("index", &index)); 102ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 103335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood handleAnInputBuffer(index); 104ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood break; 105ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 106ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 107ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood case MediaCodec::CB_OUTPUT_AVAILABLE: 108ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood { 109ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood int32_t index; 110ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood size_t offset; 111ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood size_t size; 112335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood int64_t timeUs; 113335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood int32_t flags; 114335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 115335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood CHECK(msg->findInt32("index", &index)); 116ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood CHECK(msg->findSize("offset", &offset)); 117ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood CHECK(msg->findSize("size", &size)); 118ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood CHECK(msg->findInt64("timeUs", &timeUs)); 119335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood CHECK(msg->findInt32("flags", &flags)); 120ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 121ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood handleAnOutputBuffer(index, offset, size, timeUs, flags); 122ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood break; 123ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 124ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 125ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood case MediaCodec::CB_OUTPUT_FORMAT_CHANGED: 126ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood { 127ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood sp<AMessage> format; 128335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood CHECK(msg->findMessage("format", &format)); 129335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 130335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood handleOutputFormatChange(format); 131335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood break; 132ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 133ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 134ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood case MediaCodec::CB_ERROR: 135335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood { 136ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood status_t err; 137ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood CHECK(msg->findInt32("err", &err)); 138ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood ALOGE("Decoder (%s) reported error : 0x%x", 139ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mIsAudio ? "audio" : "video", err); 140ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 141ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood handleError(err); 142ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood break; 143ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 144335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 145335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood default: 146335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood { 147335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood TRESPASS(); 148ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood break; 149ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 150ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 151335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 152ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood break; 153ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 154ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 155ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood case kWhatRenderBuffer: 156ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood { 157ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!isStaleReply(msg)) { 158ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood onRenderBuffer(msg); 159ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 160335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood break; 161335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood } 162335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 163335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood default: 164ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood DecoderBase::onMessageReceived(msg); 165ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood break; 166ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 167335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 168ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 169ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodvoid NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { 170ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood CHECK(mCodec == NULL); 171ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 172ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mFormatChangePending = false; 173ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mTimeChangePending = false; 174ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 175ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood ++mBufferGeneration; 176335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 177335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood AString mime; 178335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood CHECK(format->findString("mime", &mime)); 179335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 180ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mIsAudio = !strncasecmp("audio/", mime.c_str(), 6); 181ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str()); 182ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 183335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood mComponentName = mime; 184ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mComponentName.append(" decoder"); 185ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get()); 186ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 187ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mCodec = MediaCodec::CreateByType(mCodecLooper, mime.c_str(), false /* encoder */); 188ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood int32_t secure = 0; 189ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (format->findInt32("secure", &secure) && secure != 0) { 190ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (mCodec != NULL) { 191ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mCodec->getName(&mComponentName); 192335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood mComponentName.append(".secure"); 193335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood mCodec->release(); 194335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood ALOGI("[%s] creating", mComponentName.c_str()); 195335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood mCodec = MediaCodec::CreateByComponentName( 196ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mCodecLooper, mComponentName.c_str()); 197ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 198ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 199335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood if (mCodec == NULL) { 200ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood ALOGE("Failed to create %s%s decoder", 201ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood (secure ? "secure " : ""), mime.c_str()); 202ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood handleError(UNKNOWN_ERROR); 203ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return; 204ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 205ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mIsSecure = secure; 206ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 207ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mCodec->getName(&mComponentName); 208335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 209335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood status_t err; 210335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood if (mSurface != NULL) { 211335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood // disconnect from surface as MediaCodec will reconnect 212ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood err = native_window_api_disconnect( 213ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mSurface.get(), NATIVE_WINDOW_API_MEDIA); 214ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood // We treat this as a warning, as this is a preparatory step. 215335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood // Codec will try to connect to the surface, which is where 216ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood // any error signaling will occur. 217ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err); 218ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 219ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood err = mCodec->configure( 220ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood format, mSurface, NULL /* crypto */, 0 /* flags */); 221ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (err != OK) { 222ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err); 223ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mCodec->release(); 224335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood mCodec.clear(); 225335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood handleError(err); 226335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return; 22716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 22816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood rememberCodecSpecificData(format); 22916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 23016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // the following should work in configured state 23116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat)); 23216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat)); 23316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 23416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood sp<AMessage> reply = new AMessage(kWhatCodecNotify, this); 23516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mCodec->setCallback(reply); 23616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 23716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood err = mCodec->start(); 23816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (err != OK) { 23916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err); 24016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mCodec->release(); 24116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mCodec.clear(); 24216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood handleError(err); 24316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return; 24416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 24516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 24616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood releaseAndResetMediaBuffers(); 24716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 24816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPaused = false; 24916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mResumePending = false; 25016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 25116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 25216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid NuPlayer::Decoder::onSetParameters(const sp<AMessage> ¶ms) { 25316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mCodec == NULL) { 25416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ALOGW("onSetParameters called before codec is created."); 25516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return; 25616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 25716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mCodec->setParameters(params); 25816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 25916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 26016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) { 26116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood bool hadNoRenderer = (mRenderer == NULL); 26216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mRenderer = renderer; 26316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (hadNoRenderer && mRenderer != NULL) { 26416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // this means that the widevine legacy source is ready 26516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood onRequestInputBuffers(); 26616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 26716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 26816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 26916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid NuPlayer::Decoder::onGetInputBuffers( 27016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood Vector<sp<ABuffer> > *dstBuffers) { 27116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood CHECK_EQ((status_t)OK, mCodec->getWidevineLegacyBuffers(dstBuffers)); 27216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 27316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 27416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid NuPlayer::Decoder::onResume(bool notifyComplete) { 27516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPaused = false; 27616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 27716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (notifyComplete) { 27816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mResumePending = true; 27916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 28016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mCodec->start(); 28116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 28216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 28316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid NuPlayer::Decoder::doFlush(bool notifyComplete) { 28416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mCCDecoder != NULL) { 28516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mCCDecoder->flush(); 28616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 28716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 28816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mRenderer != NULL) { 28916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mRenderer->flush(mIsAudio, notifyComplete); 29016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mRenderer->signalTimeDiscontinuity(); 29116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 29216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 29316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood status_t err = OK; 29416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mCodec != NULL) { 29516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood err = mCodec->flush(); 29616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator 29716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ++mBufferGeneration; 29816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 29916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 30016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (err != OK) { 30116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err); 30216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood handleError(err); 30316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // finish with posting kWhatFlushCompleted. 30416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // we attempt to release the buffers even if flush fails. 305a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood } 306a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood releaseAndResetMediaBuffers(); 307a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood mPaused = true; 308a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood} 309a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood 310a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood 311a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwoodvoid NuPlayer::Decoder::onFlush() { 312a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood doFlush(true); 313a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood 314a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood if (isDiscontinuityPending()) { 315a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood // This could happen if the client starts seeking/shutdown 316a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood // after we queued an EOS for discontinuities. 317a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood // We can consider discontinuity handled. 318a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood finishHandleDiscontinuity(false /* flushOnTimeChange */); 3198277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood } 3208277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 3215959988b63ace3fba2fc78b135a4f5ef25dcf860Mike Lockwood sp<AMessage> notify = mNotify->dup(); 3228277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood notify->setInt32("what", kWhatFlushCompleted); 3238277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood notify->post(); 3248277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood} 3258277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 3268277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwoodvoid NuPlayer::Decoder::onShutdown(bool notifyComplete) { 3278277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood status_t err = OK; 3288277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 32916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // if there is a pending resume request, notify complete now 33016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood notifyResumeCompleteIfNecessary(); 33116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 33216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mCodec != NULL) { 33316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood err = mCodec->release(); 33416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mCodec = NULL; 33516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ++mBufferGeneration; 33616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 33716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mSurface != NULL) { 33816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // reconnect to surface as MediaCodec disconnected from it 33916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood status_t error = 34016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_MEDIA); 34116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ALOGW_IF(error != NO_ERROR, 34216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood "[%s] failed to connect to native window, error=%d", 34316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mComponentName.c_str(), error); 34416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 34516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mComponentName = "decoder"; 34616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 34716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 34816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood releaseAndResetMediaBuffers(); 34916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 35016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (err != OK) { 35116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err); 35216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood handleError(err); 353782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood // finish with posting kWhatShutdownCompleted. 354782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood } 355782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood 356782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood if (notifyComplete) { 357782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood sp<AMessage> notify = mNotify->dup(); 358782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood notify->setInt32("what", kWhatShutdownCompleted); 359782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood notify->post(); 36016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPaused = true; 36116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 36216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 36316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 36416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood/* 36516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * returns true if we should request more data 36616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood */ 36716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodbool NuPlayer::Decoder::doRequestBuffers() { 36816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // mRenderer is only NULL if we have a legacy widevine source that 36916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // is not yet ready. In this case we must not fetch input. 37016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (isDiscontinuityPending() || mRenderer == NULL) { 37116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return false; 37216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 37316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood status_t err = OK; 37416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood while (err == OK && !mDequeuedInputBuffers.empty()) { 37516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood size_t bufferIx = *mDequeuedInputBuffers.begin(); 37616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood sp<AMessage> msg = new AMessage(); 37716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood msg->setSize("buffer-ix", bufferIx); 37816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood err = fetchInputData(msg); 37916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (err != OK && err != ERROR_END_OF_STREAM) { 38016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // if EOS, need to queue EOS buffer 38116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 38216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 38316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin()); 38416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 38516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!mPendingInputMessages.empty() 38616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood || !onInputBufferFetched(msg)) { 38716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPendingInputMessages.push_back(msg); 38816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 38916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 39016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 39116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return err == -EWOULDBLOCK 39216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood && mSource->feedMoreTSData() == OK; 39316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 39416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 3951865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodvoid NuPlayer::Decoder::handleError(int32_t err) 39616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{ 39716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // We cannot immediately release the codec due to buffers still outstanding 39816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // in the renderer. We signal to the player the error so it can shutdown/release the 3991865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood // decoder after flushing and increment the generation to discard unnecessary messages. 40016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 40116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ++mBufferGeneration; 40216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 40316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood sp<AMessage> notify = mNotify->dup(); 4041865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood notify->setInt32("what", kWhatError); 4051865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood notify->setInt32("err", err); 406014897f5aece2c6212418934bd4618326979f17aYin Liu notify->post(); 4071865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood} 4081865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood 4091865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodbool NuPlayer::Decoder::handleAnInputBuffer(size_t index) { 4101865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood if (isDiscontinuityPending()) { 4111865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood return false; 412de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood } 4131865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood 4141865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood sp<ABuffer> buffer; 415de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood mCodec->getInputBuffer(index, &buffer); 416de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood 417de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood if (index >= mInputBuffers.size()) { 4181865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood for (size_t i = mInputBuffers.size(); i <= index; ++i) { 4191865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood mInputBuffers.add(); 42016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mMediaBuffers.add(); 42116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mInputBufferIsDequeued.add(); 42244c190826d72589f5c9e13d69e32673bd8bd7c64Mike Lockwood mMediaBuffers.editItemAt(i) = NULL; 423ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood mInputBufferIsDequeued.editItemAt(i) = false; 42416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 425ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood } 42616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mInputBuffers.editItemAt(index) = buffer; 42716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 42816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood //CHECK_LT(bufferIx, mInputBuffers.size()); 42916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 43016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mMediaBuffers[index] != NULL) { 43116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mMediaBuffers[index]->release(); 43216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mMediaBuffers.editItemAt(index) = NULL; 433ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood } 43416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mInputBufferIsDequeued.editItemAt(index) = true; 43516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 43664000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood if (!mCSDsToSubmit.isEmpty()) { 43764000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood sp<AMessage> msg = new AMessage(); 438ebb1081a624a773a67c49b279c775e18e693c4fcMarco Nelissen msg->setSize("buffer-ix", index); 439ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood 440ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0); 441ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood ALOGI("[%s] resubmitting CSD", mComponentName.c_str()); 44264000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood msg->setBuffer("buffer", buffer); 443ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood mCSDsToSubmit.removeAt(0); 44464000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood CHECK(onInputBufferFetched(msg)); 44564000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood return true; 44664000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood } 44716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 44816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood while (!mPendingInputMessages.empty()) { 44916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood sp<AMessage> msg = *mPendingInputMessages.begin(); 45042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood if (!onInputBufferFetched(msg)) { 45116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood break; 45242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood } 45342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood mPendingInputMessages.erase(mPendingInputMessages.begin()); 45442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood } 455437e945013318de54746422c8b44306e6d5319caMike Lockwood 4563e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood if (!mInputBufferIsDequeued.editItemAt(index)) { 4573e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood return true; 45833bde8d8c4fc71fb3cdd8356fd0df70ffb44fcd7Mike Lockwood } 459b3be006498f28f2630264135e88d266b540bcec3Daichi Hirono 46042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood mDequeuedInputBuffers.push_back(index); 46133bde8d8c4fc71fb3cdd8356fd0df70ffb44fcd7Mike Lockwood 46242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood onRequestInputBuffers(); 4633e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood return true; 4643e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood} 4653e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood 4663e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwoodbool NuPlayer::Decoder::handleAnOutputBuffer( 4673e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood size_t index, 4683e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood size_t offset, 4693e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood size_t size, 4703e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood int64_t timeUs, 4713e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood int32_t flags) { 4723e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood// CHECK_LT(bufferIx, mOutputBuffers.size()); 4733e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood sp<ABuffer> buffer; 47416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mCodec->getOutputBuffer(index, &buffer); 47516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 47642d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood if (index >= mOutputBuffers.size()) { 4770cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood for (size_t i = mOutputBuffers.size(); i <= index; ++i) { 4780cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mOutputBuffers.add(); 47942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood } 48042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood } 48142d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood 4820cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mOutputBuffers.editItemAt(index) = buffer; 4830cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 4840cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood buffer->setRange(offset, size); 4850cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood buffer->meta()->clear(); 4860cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood buffer->meta()->setInt64("timeUs", timeUs); 4870cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 4880cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood bool eos = flags & MediaCodec::BUFFER_FLAG_EOS; 4890cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood // we do not expect CODECCONFIG or SYNCFRAME for decoder 490b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood 49142d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this); 49242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood reply->setSize("buffer-ix", index); 49329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block reply->setInt32("generation", mBufferGeneration); 494b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood 495b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood if (eos) { 496b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video"); 497b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood 498b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood buffer->meta()->setInt32("eos", true); 499b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood reply->setInt32("eos", true); 50042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood } else if (mSkipRenderingUntilMediaTimeUs >= 0) { 50142d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood if (timeUs < mSkipRenderingUntilMediaTimeUs) { 50242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood ALOGV("[%s] dropping buffer at time %lld as requested.", 503b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood mComponentName.c_str(), (long long)timeUs); 504b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood 50542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood reply->post(); 50642d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood return true; 50742d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood } 50842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood 5090cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mSkipRenderingUntilMediaTimeUs = -1; 5100cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 5110cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 5120cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood // wait until 1st frame comes out to signal resume complete 5130cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood notifyResumeCompleteIfNecessary(); 51442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood 5150cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (mRenderer != NULL) { 5160cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood // send the buffer to renderer. 51742d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood mRenderer->queueBuffer(mIsAudio, buffer, reply); 51842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood if (eos && !isDiscontinuityPending()) { 51942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM); 5200cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 5210cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 5220cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 52342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood return true; 52416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 52516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 52642d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodvoid NuPlayer::Decoder::handleOutputFormatChange(const sp<AMessage> &format) { 52764c948bf5041fdfe391553315c9d028e1ee56382Tomasz Mikolajewski if (!mIsAudio) { 52842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood sp<AMessage> notify = mNotify->dup(); 52916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood notify->setInt32("what", kWhatVideoSizeChanged); 53016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood notify->setMessage("format", format); 53116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood notify->post(); 53242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood } else if (mRenderer != NULL) { 53342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood uint32_t flags; 53442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood int64_t durationUs; 53542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood bool hasVideo = (mSource->getFormat(false /* audio */) != NULL); 5360cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (!hasVideo && 5370cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mSource->getDuration(&durationUs) == OK && 5380cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) { 53916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 5407850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood } else { 5414fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hirono flags = AUDIO_OUTPUT_FLAG_NONE; 5423e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood } 5433e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood 5443e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood mRenderer->openAudioSink( 5453e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaed */); 5463e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood } 5474fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hirono} 5483e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood 5493e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwoodvoid NuPlayer::Decoder::releaseAndResetMediaBuffers() { 5503e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood for (size_t i = 0; i < mMediaBuffers.size(); i++) { 5514fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hirono if (mMediaBuffers[i] != NULL) { 5523e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood mMediaBuffers[i]->release(); 5533e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood mMediaBuffers.editItemAt(i) = NULL; 5543e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood } 5557850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood } 556 mMediaBuffers.resize(mInputBuffers.size()); 557 for (size_t i = 0; i < mMediaBuffers.size(); i++) { 558 mMediaBuffers.editItemAt(i) = NULL; 559 } 560 mInputBufferIsDequeued.clear(); 561 mInputBufferIsDequeued.resize(mInputBuffers.size()); 562 for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) { 563 mInputBufferIsDequeued.editItemAt(i) = false; 564 } 565 566 mPendingInputMessages.clear(); 567 mDequeuedInputBuffers.clear(); 568 mSkipRenderingUntilMediaTimeUs = -1; 569} 570 571void NuPlayer::Decoder::requestCodecNotification() { 572 if (mCodec != NULL) { 573 sp<AMessage> reply = new AMessage(kWhatCodecNotify, this); 574 reply->setInt32("generation", mBufferGeneration); 575 mCodec->requestActivityNotification(reply); 576 } 577} 578 579bool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) { 580 int32_t generation; 581 CHECK(msg->findInt32("generation", &generation)); 582 return generation != mBufferGeneration; 583} 584 585status_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) { 586 sp<ABuffer> accessUnit; 587 bool dropAccessUnit; 588 do { 589 status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit); 590 591 if (err == -EWOULDBLOCK) { 592 return err; 593 } else if (err != OK) { 594 if (err == INFO_DISCONTINUITY) { 595 int32_t type; 596 CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); 597 598 bool formatChange = 599 (mIsAudio && 600 (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT)) 601 || (!mIsAudio && 602 (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT)); 603 604 bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; 605 606 ALOGI("%s discontinuity (format=%d, time=%d)", 607 mIsAudio ? "audio" : "video", formatChange, timeChange); 608 609 bool seamlessFormatChange = false; 610 sp<AMessage> newFormat = mSource->getFormat(mIsAudio); 611 if (formatChange) { 612 seamlessFormatChange = 613 supportsSeamlessFormatChange(newFormat); 614 // treat seamless format change separately 615 formatChange = !seamlessFormatChange; 616 } 617 618 // For format or time change, return EOS to queue EOS input, 619 // then wait for EOS on output. 620 if (formatChange /* not seamless */) { 621 mFormatChangePending = true; 622 err = ERROR_END_OF_STREAM; 623 } else if (timeChange) { 624 rememberCodecSpecificData(newFormat); 625 mTimeChangePending = true; 626 err = ERROR_END_OF_STREAM; 627 } else if (seamlessFormatChange) { 628 // reuse existing decoder and don't flush 629 rememberCodecSpecificData(newFormat); 630 continue; 631 } else { 632 // This stream is unaffected by the discontinuity 633 return -EWOULDBLOCK; 634 } 635 } 636 637 // reply should only be returned without a buffer set 638 // when there is an error (including EOS) 639 CHECK(err != OK); 640 641 reply->setInt32("err", err); 642 return ERROR_END_OF_STREAM; 643 } 644 645 if (!mIsAudio) { 646 ++mNumFramesTotal; 647 } 648 649 dropAccessUnit = false; 650 if (!mIsAudio 651 && !mIsSecure 652 && mRenderer->getVideoLateByUs() > 100000ll 653 && mIsVideoAVC 654 && !IsAVCReferenceFrame(accessUnit)) { 655 dropAccessUnit = true; 656 ++mNumFramesDropped; 657 } 658 } while (dropAccessUnit); 659 660 // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video"); 661#if 0 662 int64_t mediaTimeUs; 663 CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); 664 ALOGV("[%s] feeding input buffer at media time %.3f", 665 mIsAudio ? "audio" : "video", 666 mediaTimeUs / 1E6); 667#endif 668 669 if (mCCDecoder != NULL) { 670 mCCDecoder->decode(accessUnit); 671 } 672 673 reply->setBuffer("buffer", accessUnit); 674 675 return OK; 676} 677 678bool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) { 679 size_t bufferIx; 680 CHECK(msg->findSize("buffer-ix", &bufferIx)); 681 CHECK_LT(bufferIx, mInputBuffers.size()); 682 sp<ABuffer> codecBuffer = mInputBuffers[bufferIx]; 683 684 sp<ABuffer> buffer; 685 bool hasBuffer = msg->findBuffer("buffer", &buffer); 686 687 // handle widevine classic source - that fills an arbitrary input buffer 688 MediaBuffer *mediaBuffer = NULL; 689 if (hasBuffer) { 690 mediaBuffer = (MediaBuffer *)(buffer->getMediaBufferBase()); 691 if (mediaBuffer != NULL) { 692 // likely filled another buffer than we requested: adjust buffer index 693 size_t ix; 694 for (ix = 0; ix < mInputBuffers.size(); ix++) { 695 const sp<ABuffer> &buf = mInputBuffers[ix]; 696 if (buf->data() == mediaBuffer->data()) { 697 // all input buffers are dequeued on start, hence the check 698 if (!mInputBufferIsDequeued[ix]) { 699 ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu", 700 mComponentName.c_str(), ix, bufferIx); 701 mediaBuffer->release(); 702 return false; 703 } 704 705 // TRICKY: need buffer for the metadata, so instead, set 706 // codecBuffer to the same (though incorrect) buffer to 707 // avoid a memcpy into the codecBuffer 708 codecBuffer = buffer; 709 codecBuffer->setRange( 710 mediaBuffer->range_offset(), 711 mediaBuffer->range_length()); 712 bufferIx = ix; 713 break; 714 } 715 } 716 CHECK(ix < mInputBuffers.size()); 717 } 718 } 719 720 if (buffer == NULL /* includes !hasBuffer */) { 721 int32_t streamErr = ERROR_END_OF_STREAM; 722 CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); 723 724 CHECK(streamErr != OK); 725 726 // attempt to queue EOS 727 status_t err = mCodec->queueInputBuffer( 728 bufferIx, 729 0, 730 0, 731 0, 732 MediaCodec::BUFFER_FLAG_EOS); 733 if (err == OK) { 734 mInputBufferIsDequeued.editItemAt(bufferIx) = false; 735 } else if (streamErr == ERROR_END_OF_STREAM) { 736 streamErr = err; 737 // err will not be ERROR_END_OF_STREAM 738 } 739 740 if (streamErr != ERROR_END_OF_STREAM) { 741 ALOGE("Stream error for %s (err=%d), EOS %s queued", 742 mComponentName.c_str(), 743 streamErr, 744 err == OK ? "successfully" : "unsuccessfully"); 745 handleError(streamErr); 746 } 747 } else { 748 sp<AMessage> extra; 749 if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) { 750 int64_t resumeAtMediaTimeUs; 751 if (extra->findInt64( 752 "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) { 753 ALOGI("[%s] suppressing rendering until %lld us", 754 mComponentName.c_str(), (long long)resumeAtMediaTimeUs); 755 mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs; 756 } 757 } 758 759 int64_t timeUs = 0; 760 uint32_t flags = 0; 761 CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 762 763 int32_t eos, csd; 764 // we do not expect SYNCFRAME for decoder 765 if (buffer->meta()->findInt32("eos", &eos) && eos) { 766 flags |= MediaCodec::BUFFER_FLAG_EOS; 767 } else if (buffer->meta()->findInt32("csd", &csd) && csd) { 768 flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; 769 } 770 771 // copy into codec buffer 772 if (buffer != codecBuffer) { 773 CHECK_LE(buffer->size(), codecBuffer->capacity()); 774 codecBuffer->setRange(0, buffer->size()); 775 memcpy(codecBuffer->data(), buffer->data(), buffer->size()); 776 } 777 778 status_t err = mCodec->queueInputBuffer( 779 bufferIx, 780 codecBuffer->offset(), 781 codecBuffer->size(), 782 timeUs, 783 flags); 784 if (err != OK) { 785 if (mediaBuffer != NULL) { 786 mediaBuffer->release(); 787 } 788 ALOGE("Failed to queue input buffer for %s (err=%d)", 789 mComponentName.c_str(), err); 790 handleError(err); 791 } else { 792 mInputBufferIsDequeued.editItemAt(bufferIx) = false; 793 if (mediaBuffer != NULL) { 794 CHECK(mMediaBuffers[bufferIx] == NULL); 795 mMediaBuffers.editItemAt(bufferIx) = mediaBuffer; 796 } 797 } 798 } 799 return true; 800} 801 802void NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) { 803 status_t err; 804 int32_t render; 805 size_t bufferIx; 806 int32_t eos; 807 CHECK(msg->findSize("buffer-ix", &bufferIx)); 808 809 if (!mIsAudio) { 810 int64_t timeUs; 811 sp<ABuffer> buffer = mOutputBuffers[bufferIx]; 812 buffer->meta()->findInt64("timeUs", &timeUs); 813 814 if (mCCDecoder != NULL && mCCDecoder->isSelected()) { 815 mCCDecoder->display(timeUs); 816 } 817 } 818 819 if (msg->findInt32("render", &render) && render) { 820 int64_t timestampNs; 821 CHECK(msg->findInt64("timestampNs", ×tampNs)); 822 err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs); 823 } else { 824 err = mCodec->releaseOutputBuffer(bufferIx); 825 } 826 if (err != OK) { 827 ALOGE("failed to release output buffer for %s (err=%d)", 828 mComponentName.c_str(), err); 829 handleError(err); 830 } 831 if (msg->findInt32("eos", &eos) && eos 832 && isDiscontinuityPending()) { 833 finishHandleDiscontinuity(true /* flushOnTimeChange */); 834 } 835} 836 837bool NuPlayer::Decoder::isDiscontinuityPending() const { 838 return mFormatChangePending || mTimeChangePending; 839} 840 841void NuPlayer::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) { 842 ALOGV("finishHandleDiscontinuity: format %d, time %d, flush %d", 843 mFormatChangePending, mTimeChangePending, flushOnTimeChange); 844 845 // If we have format change, pause and wait to be killed; 846 // If we have time change only, flush and restart fetching. 847 848 if (mFormatChangePending) { 849 mPaused = true; 850 } else if (mTimeChangePending) { 851 if (flushOnTimeChange) { 852 doFlush(false /* notifyComplete */); 853 signalResume(false /* notifyComplete */); 854 } 855 } 856 857 // Notify NuPlayer to either shutdown decoder, or rescan sources 858 sp<AMessage> msg = mNotify->dup(); 859 msg->setInt32("what", kWhatInputDiscontinuity); 860 msg->setInt32("formatChange", mFormatChangePending); 861 msg->post(); 862 863 mFormatChangePending = false; 864 mTimeChangePending = false; 865} 866 867bool NuPlayer::Decoder::supportsSeamlessAudioFormatChange( 868 const sp<AMessage> &targetFormat) const { 869 if (targetFormat == NULL) { 870 return true; 871 } 872 873 AString mime; 874 if (!targetFormat->findString("mime", &mime)) { 875 return false; 876 } 877 878 if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 879 // field-by-field comparison 880 const char * keys[] = { "channel-count", "sample-rate", "is-adts" }; 881 for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) { 882 int32_t oldVal, newVal; 883 if (!mInputFormat->findInt32(keys[i], &oldVal) || 884 !targetFormat->findInt32(keys[i], &newVal) || 885 oldVal != newVal) { 886 return false; 887 } 888 } 889 890 sp<ABuffer> oldBuf, newBuf; 891 if (mInputFormat->findBuffer("csd-0", &oldBuf) && 892 targetFormat->findBuffer("csd-0", &newBuf)) { 893 if (oldBuf->size() != newBuf->size()) { 894 return false; 895 } 896 return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size()); 897 } 898 } 899 return false; 900} 901 902bool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const { 903 if (mInputFormat == NULL) { 904 return false; 905 } 906 907 if (targetFormat == NULL) { 908 return true; 909 } 910 911 AString oldMime, newMime; 912 if (!mInputFormat->findString("mime", &oldMime) 913 || !targetFormat->findString("mime", &newMime) 914 || !(oldMime == newMime)) { 915 return false; 916 } 917 918 bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/")); 919 bool seamless; 920 if (audio) { 921 seamless = supportsSeamlessAudioFormatChange(targetFormat); 922 } else { 923 int32_t isAdaptive; 924 seamless = (mCodec != NULL && 925 mInputFormat->findInt32("adaptive-playback", &isAdaptive) && 926 isAdaptive); 927 } 928 929 ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str()); 930 return seamless; 931} 932 933void NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) { 934 if (format == NULL) { 935 return; 936 } 937 mCSDsForCurrentFormat.clear(); 938 for (int32_t i = 0; ; ++i) { 939 AString tag = "csd-"; 940 tag.append(i); 941 sp<ABuffer> buffer; 942 if (!format->findBuffer(tag.c_str(), &buffer)) { 943 break; 944 } 945 mCSDsForCurrentFormat.push(buffer); 946 } 947} 948 949void NuPlayer::Decoder::notifyResumeCompleteIfNecessary() { 950 if (mResumePending) { 951 mResumePending = false; 952 953 sp<AMessage> notify = mNotify->dup(); 954 notify->setInt32("what", kWhatResumeCompleted); 955 notify->post(); 956 } 957} 958 959} // namespace android 960 961