NuPlayerDecoder.cpp revision e1e5d7a3d3d4d6d644e6c731f977422e004140d5
1f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/* 27137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang * Copyright 2014 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> 201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <inttypes.h> 21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "NuPlayerCCDecoder.h" 23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerDecoder.h" 24c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerRenderer.h" 25c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerSource.h" 26c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 27288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung#include <cutils/properties.h> 281cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/ICrypto.h> 29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h> 315bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <media/stagefright/foundation/AMessage.h> 32095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <media/stagefright/MediaBuffer.h> 331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaCodec.h> 34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h> 351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaErrors.h> 36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 371de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h> 381de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar 397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "avc_utils.h" 407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "ATSParser.h" 417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 42f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android { 43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 44288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hungstatic inline bool getAudioDeepBufferSetting() { 45288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung return property_get_bool("media.stagefright.audio.deep", false /* default_value */); 46288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung} 47288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung 48f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::Decoder( 491173118eace0e9e347cb007f0da817cee87579edGlenn Kasten const sp<AMessage> ¬ify, 50c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia const sp<Source> &source, 51c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia const sp<Renderer> &renderer, 521de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar const sp<Surface> &surface, 537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<CCDecoder> &ccDecoder) 54202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung : DecoderBase(notify), 551de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar mSurface(surface), 56c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSource(source), 57c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mRenderer(renderer), 587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder(ccDecoder), 59c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSkipRenderingUntilMediaTimeUs(-1ll), 607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNumFramesTotal(0ll), 61e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumInputFramesDropped(0ll), 62e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumOutputFramesDropped(0ll), 63e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mVideoWidth(0), 64e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mVideoHeight(0), 657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio(true), 667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsVideoAVC(false), 677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsSecure(false), 687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mFormatChangePending(false), 6966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending(false), 70704e72658b1082264a26a83c50046da34f07d1a1Wei Jia mPaused(true), 71f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending(false), 721cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName("decoder") { 731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodecLooper = new ALooper; 749e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen mCodecLooper->setName("NPDecoder-CL"); 751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 78f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::~Decoder() { 79faeb0f291330134dc4468359a36e099aae508449Ronghua Wu mCodec->release(); 804923cee4fb3b29538d8f46bceeea7d5128242a71Wei Jia releaseAndResetMediaBuffers(); 81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 83e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavansp<AMessage> NuPlayer::Decoder::getStats() const { 84e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt64("frames-total", mNumFramesTotal); 85e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt64("frames-dropped-input", mNumInputFramesDropped); 86e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt64("frames-dropped-output", mNumOutputFramesDropped); 87e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan return mStats; 887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 89095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { 917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str()); 92095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang switch (msg->what()) { 947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang case kWhatCodecNotify: 957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang { 963b032b3865fd93173aadca0591eeea32853206f9Chong Zhang int32_t cbID; 973b032b3865fd93173aadca0591eeea32853206f9Chong Zhang CHECK(msg->findInt32("callbackID", &cbID)); 983b032b3865fd93173aadca0591eeea32853206f9Chong Zhang 993b032b3865fd93173aadca0591eeea32853206f9Chong Zhang ALOGV("[%s] kWhatCodecNotify: cbID = %d, paused = %d", 1003b032b3865fd93173aadca0591eeea32853206f9Chong Zhang mIsAudio ? "audio" : "video", cbID, mPaused); 1013b032b3865fd93173aadca0591eeea32853206f9Chong Zhang 102421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (mPaused) { 103421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 104421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 105421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 106421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen switch (cbID) { 107421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_INPUT_AVAILABLE: 108421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 109421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t index; 110421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("index", &index)); 111095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 112421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleAnInputBuffer(index); 113421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 114421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 115421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 116421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_OUTPUT_AVAILABLE: 117421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 118421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t index; 119421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t offset; 120421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t size; 121421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int64_t timeUs; 122421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t flags; 123421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 124421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("index", &index)); 125421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findSize("offset", &offset)); 126421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findSize("size", &size)); 127421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt64("timeUs", &timeUs)); 128421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("flags", &flags)); 129421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 130421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleAnOutputBuffer(index, offset, size, timeUs, flags); 131421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 1327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 133095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 134421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_OUTPUT_FORMAT_CHANGED: 135421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 136421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> format; 137421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findMessage("format", &format)); 138421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 139421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleOutputFormatChange(format); 140421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 1417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 143421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_ERROR: 144421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 145421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen status_t err; 146421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("err", &err)); 147421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen ALOGE("Decoder (%s) reported error : 0x%x", 148421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mIsAudio ? "audio" : "video", err); 149421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 150421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleError(err); 151421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 1527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 154421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen default: 155421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 156421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen TRESPASS(); 157421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 158421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 1597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 16187603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar break; 16287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 1637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang case kWhatRenderBuffer: 1657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang { 1667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!isStaleReply(msg)) { 1677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onRenderBuffer(msg); 1687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 1707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang default: 1737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang DecoderBase::onMessageReceived(msg); 1747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 17587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 17687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar} 17787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 1781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { 179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mCodec == NULL); 180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mFormatChangePending = false; 18266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending = false; 1837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ++mBufferGeneration; 1851cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 186840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber AString mime; 187840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(format->findString("mime", &mime)); 188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio = !strncasecmp("audio/", mime.c_str(), 6); 1907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str()); 1917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName = mime; 1931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.append(" decoder"); 1941de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get()); 195840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1961cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodec = MediaCodec::CreateByType(mCodecLooper, mime.c_str(), false /* encoder */); 197095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar int32_t secure = 0; 198095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (format->findInt32("secure", &secure) && secure != 0) { 199095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (mCodec != NULL) { 200095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec->getName(&mComponentName); 201095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mComponentName.append(".secure"); 202095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec->release(); 203095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGI("[%s] creating", mComponentName.c_str()); 204095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec = MediaCodec::CreateByComponentName( 205095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodecLooper, mComponentName.c_str()); 206095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 207095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 2081cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mCodec == NULL) { 209095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGE("Failed to create %s%s decoder", 210095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar (secure ? "secure " : ""), mime.c_str()); 2111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(UNKNOWN_ERROR); 2121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 213840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 2147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsSecure = secure; 215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodec->getName(&mComponentName); 2171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 21814986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar status_t err; 2191de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar if (mSurface != NULL) { 2201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // disconnect from surface as MediaCodec will reconnect 22114986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar err = native_window_api_disconnect( 2221de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar mSurface.get(), NATIVE_WINDOW_API_MEDIA); 22314986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar // We treat this as a warning, as this is a preparatory step. 22414986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar // Codec will try to connect to the surface, which is where 22514986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar // any error signaling will occur. 22614986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err); 2271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 22814986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar err = mCodec->configure( 2291de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar format, mSurface, NULL /* crypto */, 0 /* flags */); 2301cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 2311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err); 2322abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec->release(); 2332abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec.clear(); 2341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 2351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 2361cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 23787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar rememberCodecSpecificData(format); 23887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 2391cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // the following should work in configured state 2401cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat)); 2411cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat)); 2421cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 243e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setString("mime", mime.c_str()); 244e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setString("component-name", mComponentName.c_str()); 245e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan 246e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan if (!mIsAudio) { 247e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan int32_t width, height; 248e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan if (mOutputFormat->findInt32("width", &width) 249e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan && mOutputFormat->findInt32("height", &height)) { 250e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("width", width); 251e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("height", height); 252e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan } 253e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan } 254e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan 255421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> reply = new AMessage(kWhatCodecNotify, this); 256421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->setCallback(reply); 257421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 2581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar err = mCodec->start(); 2591cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 2601cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err); 2612abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec->release(); 2622abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec.clear(); 2631cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 2641cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 267095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar releaseAndResetMediaBuffers(); 268078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 269704e72658b1082264a26a83c50046da34f07d1a1Wei Jia mPaused = false; 270f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending = false; 2711cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 272078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 2738db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wuvoid NuPlayer::Decoder::onSetParameters(const sp<AMessage> ¶ms) { 2748db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu if (mCodec == NULL) { 2758db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu ALOGW("onSetParameters called before codec is created."); 2768db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu return; 2778db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu } 2788db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu mCodec->setParameters(params); 2798db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu} 2808db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu 2817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) { 2827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool hadNoRenderer = (mRenderer == NULL); 2837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer = renderer; 2847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (hadNoRenderer && mRenderer != NULL) { 285e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // this means that the widevine legacy source is ready 286e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar onRequestInputBuffers(); 28781e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia } 2887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 2897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onGetInputBuffers( 2917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang Vector<sp<ABuffer> > *dstBuffers) { 292e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getWidevineLegacyBuffers(dstBuffers)); 2937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 2942245fc625910e47d1ba3c339e205c21ab58a47adWei Jia 295f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::onResume(bool notifyComplete) { 2967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPaused = false; 297f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 298f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang if (notifyComplete) { 299f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending = true; 300f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang } 301421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->start(); 302095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar} 303095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 30466704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::doFlush(bool notifyComplete) { 3057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCCDecoder != NULL) { 3067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder->flush(); 3077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 3097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mRenderer != NULL) { 3107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->flush(mIsAudio, notifyComplete); 3117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->signalTimeDiscontinuity(); 3127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 3147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 3151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mCodec != NULL) { 3167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = mCodec->flush(); 3177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator 3187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ++mBufferGeneration; 319078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 320078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 3217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err != OK) { 3227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err); 3237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang handleError(err); 3247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // finish with posting kWhatFlushCompleted. 3257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // we attempt to release the buffers even if flush fails. 3267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang releaseAndResetMediaBuffers(); 328421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mPaused = true; 32966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang} 330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 331421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 33266704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::onFlush() { 33366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang doFlush(true); 33466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 33566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (isDiscontinuityPending()) { 33666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // This could happen if the client starts seeking/shutdown 33766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // after we queued an EOS for discontinuities. 33866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // We can consider discontinuity handled. 33966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang finishHandleDiscontinuity(false /* flushOnTimeChange */); 3407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 34166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 34266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang sp<AMessage> notify = mNotify->dup(); 34366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang notify->setInt32("what", kWhatFlushCompleted); 34466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang notify->post(); 345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onShutdown(bool notifyComplete) { 3487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 349f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 350f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang // if there is a pending resume request, notify complete now 351f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notifyResumeCompleteIfNecessary(); 352f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 3537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCodec != NULL) { 3547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = mCodec->release(); 3557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCodec = NULL; 3567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ++mBufferGeneration; 3571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 3581de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar if (mSurface != NULL) { 3597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // reconnect to surface as MediaCodec disconnected from it 3607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t error = 3611de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_MEDIA); 3627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGW_IF(error != NO_ERROR, 3637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang "[%s] failed to connect to native window, error=%d", 3647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), error); 3657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName = "decoder"; 3677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 3697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang releaseAndResetMediaBuffers(); 3707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 3717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err != OK) { 3727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err); 3737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang handleError(err); 3747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // finish with posting kWhatShutdownCompleted. 3757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 376c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 3777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (notifyComplete) { 3787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> notify = mNotify->dup(); 3797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->setInt32("what", kWhatShutdownCompleted); 3807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->post(); 3817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPaused = true; 3827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 38387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar} 38487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 3853b032b3865fd93173aadca0591eeea32853206f9Chong Zhang/* 3863b032b3865fd93173aadca0591eeea32853206f9Chong Zhang * returns true if we should request more data 3873b032b3865fd93173aadca0591eeea32853206f9Chong Zhang */ 3883b032b3865fd93173aadca0591eeea32853206f9Chong Zhangbool NuPlayer::Decoder::doRequestBuffers() { 389e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // mRenderer is only NULL if we have a legacy widevine source that 390e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // is not yet ready. In this case we must not fetch input. 391e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar if (isDiscontinuityPending() || mRenderer == NULL) { 3923b032b3865fd93173aadca0591eeea32853206f9Chong Zhang return false; 3937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 39566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang while (err == OK && !mDequeuedInputBuffers.empty()) { 3967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t bufferIx = *mDequeuedInputBuffers.begin(); 3977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = new AMessage(); 3987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->setSize("buffer-ix", bufferIx); 3997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = fetchInputData(msg); 40066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (err != OK && err != ERROR_END_OF_STREAM) { 40166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // if EOS, need to queue EOS buffer 4027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 4037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin()); 4057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 4067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mPendingInputMessages.empty() 4077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang || !onInputBufferFetched(msg)) { 4087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingInputMessages.push_back(msg); 4097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 411095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 4123b032b3865fd93173aadca0591eeea32853206f9Chong Zhang return err == -EWOULDBLOCK 4133b032b3865fd93173aadca0591eeea32853206f9Chong Zhang && mSource->feedMoreTSData() == OK; 414095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar} 415095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 416421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleError(int32_t err) 417421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen{ 418421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen // We cannot immediately release the codec due to buffers still outstanding 419421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen // in the renderer. We signal to the player the error so it can shutdown/release the 420421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen // decoder after flushing and increment the generation to discard unnecessary messages. 421421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 422421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen ++mBufferGeneration; 423421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 424421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> notify = mNotify->dup(); 425421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setInt32("what", kWhatError); 426421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setInt32("err", err); 427421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->post(); 428421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen} 429421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 430421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnInputBuffer(size_t index) { 43166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (isDiscontinuityPending()) { 4327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return false; 4337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 434421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 435421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<ABuffer> buffer; 436421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->getInputBuffer(index, &buffer); 437421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 4386301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia if (buffer == NULL) { 4396301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia handleError(UNKNOWN_ERROR); 4406301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia return false; 4416301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia } 4426301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia 443421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (index >= mInputBuffers.size()) { 444421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen for (size_t i = mInputBuffers.size(); i <= index; ++i) { 445421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBuffers.add(); 446421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers.add(); 447421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBufferIsDequeued.add(); 448421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers.editItemAt(i) = NULL; 449421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBufferIsDequeued.editItemAt(i) = false; 450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 4511cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 452421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBuffers.editItemAt(index) = buffer; 453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 454421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen //CHECK_LT(bufferIx, mInputBuffers.size()); 4551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 456421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (mMediaBuffers[index] != NULL) { 457421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers[index]->release(); 458421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers.editItemAt(index) = NULL; 459095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 460421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBufferIsDequeued.editItemAt(index) = true; 461095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 46287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar if (!mCSDsToSubmit.isEmpty()) { 4637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = new AMessage(); 464421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen msg->setSize("buffer-ix", index); 4657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 46687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0); 46787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar ALOGI("[%s] resubmitting CSD", mComponentName.c_str()); 4687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->setBuffer("buffer", buffer); 46987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar mCSDsToSubmit.removeAt(0); 4707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(onInputBufferFetched(msg)); 4712245fc625910e47d1ba3c339e205c21ab58a47adWei Jia return true; 4722245fc625910e47d1ba3c339e205c21ab58a47adWei Jia } 4732245fc625910e47d1ba3c339e205c21ab58a47adWei Jia 4742245fc625910e47d1ba3c339e205c21ab58a47adWei Jia while (!mPendingInputMessages.empty()) { 4752245fc625910e47d1ba3c339e205c21ab58a47adWei Jia sp<AMessage> msg = *mPendingInputMessages.begin(); 4767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!onInputBufferFetched(msg)) { 4772245fc625910e47d1ba3c339e205c21ab58a47adWei Jia break; 4782245fc625910e47d1ba3c339e205c21ab58a47adWei Jia } 4792245fc625910e47d1ba3c339e205c21ab58a47adWei Jia mPendingInputMessages.erase(mPendingInputMessages.begin()); 4802245fc625910e47d1ba3c339e205c21ab58a47adWei Jia } 4812245fc625910e47d1ba3c339e205c21ab58a47adWei Jia 482421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (!mInputBufferIsDequeued.editItemAt(index)) { 48387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar return true; 48487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 48587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 486421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mDequeuedInputBuffers.push_back(index); 4877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 4887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onRequestInputBuffers(); 4891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return true; 4901cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 4911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 492421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnOutputBuffer( 493421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t index, 494421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t offset, 495421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t size, 496421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int64_t timeUs, 497421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t flags) { 498421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen// CHECK_LT(bufferIx, mOutputBuffers.size()); 499421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<ABuffer> buffer; 500421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->getOutputBuffer(index, &buffer); 5017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 502421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (index >= mOutputBuffers.size()) { 503421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen for (size_t i = mOutputBuffers.size(); i <= index; ++i) { 504421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mOutputBuffers.add(); 505095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 506095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 507095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 508421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mOutputBuffers.editItemAt(index) = buffer; 509421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 5107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->setRange(offset, size); 5117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->meta()->clear(); 5127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->meta()->setInt64("timeUs", timeUs); 51366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 51466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang bool eos = flags & MediaCodec::BUFFER_FLAG_EOS; 5157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // we do not expect CODECCONFIG or SYNCFRAME for decoder 5167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5171d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this); 518421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen reply->setSize("buffer-ix", index); 5197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("generation", mBufferGeneration); 5207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 52166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (eos) { 52266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video"); 52366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 52466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang buffer->meta()->setInt32("eos", true); 52566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang reply->setInt32("eos", true); 52666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } else if (mSkipRenderingUntilMediaTimeUs >= 0) { 5277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (timeUs < mSkipRenderingUntilMediaTimeUs) { 5287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] dropping buffer at time %lld as requested.", 5297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), (long long)timeUs); 5307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->post(); 5327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return true; 5337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mSkipRenderingUntilMediaTimeUs = -1; 5367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 538e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumFramesTotal += !mIsAudio; 539e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan 540f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang // wait until 1st frame comes out to signal resume complete 541f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notifyResumeCompleteIfNecessary(); 542f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 5437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mRenderer != NULL) { 5447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // send the buffer to renderer. 5457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->queueBuffer(mIsAudio, buffer, reply); 54666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (eos && !isDiscontinuityPending()) { 5477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM); 5487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return true; 5527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 5537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 554421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleOutputFormatChange(const sp<AMessage> &format) { 555421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (!mIsAudio) { 556e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan int32_t width, height; 557e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan if (format->findInt32("width", &width) 558e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan && format->findInt32("height", &height)) { 559e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("width", width); 560e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("height", height); 561e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan } 562421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> notify = mNotify->dup(); 563421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setInt32("what", kWhatVideoSizeChanged); 564421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setMessage("format", format); 565421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->post(); 566421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } else if (mRenderer != NULL) { 567421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen uint32_t flags; 568421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int64_t durationUs; 569421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen bool hasVideo = (mSource->getFormat(false /* audio */) != NULL); 570288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung if (getAudioDeepBufferSetting() // override regardless of source duration 571288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung || (!hasVideo 572288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung && mSource->getDuration(&durationUs) == OK 573288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung && durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US)) { 574421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 575421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } else { 576421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen flags = AUDIO_OUTPUT_FLAG_NONE; 577421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 578421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 579421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mRenderer->openAudioSink( 580421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaed */); 581421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 582421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen} 583421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 5847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::releaseAndResetMediaBuffers() { 5857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mMediaBuffers.size(); i++) { 5867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mMediaBuffers[i] != NULL) { 5877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers[i]->release(); 5887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers.editItemAt(i) = NULL; 5897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers.resize(mInputBuffers.size()); 5927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mMediaBuffers.size(); i++) { 5937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers.editItemAt(i) = NULL; 5947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mInputBufferIsDequeued.clear(); 5967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mInputBufferIsDequeued.resize(mInputBuffers.size()); 5977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) { 5987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mInputBufferIsDequeued.editItemAt(i) = false; 5997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingInputMessages.clear(); 6027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mDequeuedInputBuffers.clear(); 6037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mSkipRenderingUntilMediaTimeUs = -1; 6047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 6057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::requestCodecNotification() { 6077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCodec != NULL) { 6081d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> reply = new AMessage(kWhatCodecNotify, this); 6097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("generation", mBufferGeneration); 6107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCodec->requestActivityNotification(reply); 6117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 6137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) { 6157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t generation; 6167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findInt32("generation", &generation)); 6177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return generation != mBufferGeneration; 6187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 6197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) { 6217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> accessUnit; 6227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool dropAccessUnit; 6237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang do { 6247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit); 6257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err == -EWOULDBLOCK) { 6277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return err; 6287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (err != OK) { 6297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err == INFO_DISCONTINUITY) { 6307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t type; 6317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); 6327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool formatChange = 6347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (mIsAudio && 6357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT)) 6367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang || (!mIsAudio && 6377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT)); 6387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; 6407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGI("%s discontinuity (format=%d, time=%d)", 6427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio ? "audio" : "video", formatChange, timeChange); 6437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool seamlessFormatChange = false; 6457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> newFormat = mSource->getFormat(mIsAudio); 6467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (formatChange) { 6477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang seamlessFormatChange = 6487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang supportsSeamlessFormatChange(newFormat); 6497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // treat seamless format change separately 6507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang formatChange = !seamlessFormatChange; 6517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 65366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // For format or time change, return EOS to queue EOS input, 65466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // then wait for EOS on output. 6557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (formatChange /* not seamless */) { 6567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mFormatChangePending = true; 65766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang err = ERROR_END_OF_STREAM; 6587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (timeChange) { 6597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang rememberCodecSpecificData(newFormat); 66066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending = true; 66166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang err = ERROR_END_OF_STREAM; 6627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (seamlessFormatChange) { 6637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // reuse existing decoder and don't flush 6647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang rememberCodecSpecificData(newFormat); 66566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang continue; 6667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else { 6677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // This stream is unaffected by the discontinuity 6687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return -EWOULDBLOCK; 6697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 67266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // reply should only be returned without a buffer set 67366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // when there is an error (including EOS) 67466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang CHECK(err != OK); 67566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 6767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("err", err); 67766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang return ERROR_END_OF_STREAM; 6787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang dropAccessUnit = false; 6817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mIsAudio 6827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang && !mIsSecure 6837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang && mRenderer->getVideoLateByUs() > 100000ll 6847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang && mIsVideoAVC 6857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang && !IsAVCReferenceFrame(accessUnit)) { 6867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang dropAccessUnit = true; 687e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan ++mNumInputFramesDropped; 6887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } while (dropAccessUnit); 6907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video"); 6927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#if 0 6937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int64_t mediaTimeUs; 6947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); 6955abbd3dcbb0bb32a3d4b90dddbcf90458967eb6fChong Zhang ALOGV("[%s] feeding input buffer at media time %.3f", 6967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio ? "audio" : "video", 6977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaTimeUs / 1E6); 6987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#endif 6997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCCDecoder != NULL) { 7017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder->decode(accessUnit); 7027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setBuffer("buffer", accessUnit); 7057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return OK; 7077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 7087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) { 7107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t bufferIx; 7117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findSize("buffer-ix", &bufferIx)); 7127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK_LT(bufferIx, mInputBuffers.size()); 7137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> codecBuffer = mInputBuffers[bufferIx]; 7147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> buffer; 7167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool hasBuffer = msg->findBuffer("buffer", &buffer); 7177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // handle widevine classic source - that fills an arbitrary input buffer 7197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang MediaBuffer *mediaBuffer = NULL; 7207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (hasBuffer) { 7217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer = (MediaBuffer *)(buffer->getMediaBufferBase()); 7227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mediaBuffer != NULL) { 7237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // likely filled another buffer than we requested: adjust buffer index 7247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t ix; 7257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (ix = 0; ix < mInputBuffers.size(); ix++) { 7267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<ABuffer> &buf = mInputBuffers[ix]; 7277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (buf->data() == mediaBuffer->data()) { 7287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // all input buffers are dequeued on start, hence the check 7297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mInputBufferIsDequeued[ix]) { 7307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu", 7317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), ix, bufferIx); 7327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer->release(); 7337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return false; 7347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // TRICKY: need buffer for the metadata, so instead, set 7377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // codecBuffer to the same (though incorrect) buffer to 7387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // avoid a memcpy into the codecBuffer 7397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang codecBuffer = buffer; 7407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang codecBuffer->setRange( 7417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer->range_offset(), 7427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer->range_length()); 7437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bufferIx = ix; 7447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 7457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(ix < mInputBuffers.size()); 7487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (buffer == NULL /* includes !hasBuffer */) { 7527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t streamErr = ERROR_END_OF_STREAM; 7537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); 7547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 75566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang CHECK(streamErr != OK); 7561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 7571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // attempt to queue EOS 7581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err = mCodec->queueInputBuffer( 7591cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar bufferIx, 7601cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 7611cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 7621cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 7631cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar MediaCodec::BUFFER_FLAG_EOS); 764cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung if (err == OK) { 765cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mInputBufferIsDequeued.editItemAt(bufferIx) = false; 766cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } else if (streamErr == ERROR_END_OF_STREAM) { 7671cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar streamErr = err; 7681cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // err will not be ERROR_END_OF_STREAM 7691cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 7701cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 7711cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (streamErr != ERROR_END_OF_STREAM) { 772cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung ALOGE("Stream error for %s (err=%d), EOS %s queued", 773cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mComponentName.c_str(), 774cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung streamErr, 775cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung err == OK ? "successfully" : "unsuccessfully"); 7761cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(streamErr); 7771cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 7781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else { 779c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia sp<AMessage> extra; 780c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) { 781c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia int64_t resumeAtMediaTimeUs; 782c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (extra->findInt64( 783c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) { 784c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia ALOGI("[%s] suppressing rendering until %lld us", 785c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mComponentName.c_str(), (long long)resumeAtMediaTimeUs); 786c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs; 787c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 788c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 789c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 7901cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int64_t timeUs = 0; 7911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar uint32_t flags = 0; 7921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 7931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 79487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar int32_t eos, csd; 79587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar // we do not expect SYNCFRAME for decoder 7961cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (buffer->meta()->findInt32("eos", &eos) && eos) { 7971cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar flags |= MediaCodec::BUFFER_FLAG_EOS; 79887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } else if (buffer->meta()->findInt32("csd", &csd) && csd) { 79987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; 8001cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 8011cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 8021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // copy into codec buffer 8031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (buffer != codecBuffer) { 8041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_LE(buffer->size(), codecBuffer->capacity()); 8051cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar codecBuffer->setRange(0, buffer->size()); 8061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar memcpy(codecBuffer->data(), buffer->data(), buffer->size()); 8071cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 8081cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 8091cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err = mCodec->queueInputBuffer( 8101cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar bufferIx, 8111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar codecBuffer->offset(), 8121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar codecBuffer->size(), 8131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar timeUs, 8141cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar flags); 8151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 816cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung if (mediaBuffer != NULL) { 817cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mediaBuffer->release(); 818cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } 8191cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to queue input buffer for %s (err=%d)", 8201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), err); 8211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 822cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } else { 823cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mInputBufferIsDequeued.editItemAt(bufferIx) = false; 824cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung if (mediaBuffer != NULL) { 825cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung CHECK(mMediaBuffers[bufferIx] == NULL); 826cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mMediaBuffers.editItemAt(bufferIx) = mediaBuffer; 827cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } 828095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 8302245fc625910e47d1ba3c339e205c21ab58a47adWei Jia return true; 831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 8331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) { 8341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err; 8351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int32_t render; 8361cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar size_t bufferIx; 83766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang int32_t eos; 8381cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(msg->findSize("buffer-ix", &bufferIx)); 839c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 8407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mIsAudio) { 841c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia int64_t timeUs; 842c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia sp<ABuffer> buffer = mOutputBuffers[bufferIx]; 843c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia buffer->meta()->findInt64("timeUs", &timeUs); 8447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCCDecoder != NULL && mCCDecoder->isSelected()) { 8467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder->display(timeUs); 8477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 848c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 849c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 8501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (msg->findInt32("render", &render) && render) { 851dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t timestampNs; 852dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar CHECK(msg->findInt64("timestampNs", ×tampNs)); 853dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs); 8541cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else { 855e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumOutputFramesDropped += !mIsAudio; 8561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar err = mCodec->releaseOutputBuffer(bufferIx); 8571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 8581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 8591cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("failed to release output buffer for %s (err=%d)", 8601cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), err); 8611cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 86366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (msg->findInt32("eos", &eos) && eos 86466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang && isDiscontinuityPending()) { 86566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang finishHandleDiscontinuity(true /* flushOnTimeChange */); 86666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } 86766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang} 86866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 86966704af4d82c2b6303609b29402641f861fdcb19Chong Zhangbool NuPlayer::Decoder::isDiscontinuityPending() const { 87066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang return mFormatChangePending || mTimeChangePending; 87166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang} 87266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 87366704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) { 87466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang ALOGV("finishHandleDiscontinuity: format %d, time %d, flush %d", 87566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mFormatChangePending, mTimeChangePending, flushOnTimeChange); 87666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 87766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // If we have format change, pause and wait to be killed; 87866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // If we have time change only, flush and restart fetching. 87966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 88066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (mFormatChangePending) { 88166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mPaused = true; 88266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } else if (mTimeChangePending) { 88366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (flushOnTimeChange) { 884421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen doFlush(false /* notifyComplete */); 885421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen signalResume(false /* notifyComplete */); 88666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } 88766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } 88866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 88966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // Notify NuPlayer to either shutdown decoder, or rescan sources 89066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang sp<AMessage> msg = mNotify->dup(); 89166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang msg->setInt32("what", kWhatInputDiscontinuity); 89266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang msg->setInt32("formatChange", mFormatChangePending); 89366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang msg->post(); 89466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 89566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mFormatChangePending = false; 89666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending = false; 897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 8997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::supportsSeamlessAudioFormatChange( 9007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<AMessage> &targetFormat) const { 9016d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (targetFormat == NULL) { 9026d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return true; 9036d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9046d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 9056d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih AString mime; 9066d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (!targetFormat->findString("mime", &mime)) { 9076d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 9086d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9096d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 9106d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 9116d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih // field-by-field comparison 9126d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih const char * keys[] = { "channel-count", "sample-rate", "is-adts" }; 9136d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) { 9146d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih int32_t oldVal, newVal; 9157abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (!mInputFormat->findInt32(keys[i], &oldVal) || 9161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar !targetFormat->findInt32(keys[i], &newVal) || 9171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar oldVal != newVal) { 9186d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 9196d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9206d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9216d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 9226d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih sp<ABuffer> oldBuf, newBuf; 9237abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (mInputFormat->findBuffer("csd-0", &oldBuf) && 9241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar targetFormat->findBuffer("csd-0", &newBuf)) { 9256d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (oldBuf->size() != newBuf->size()) { 9266d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 9276d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9286d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size()); 9296d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9306d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9316d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 9326d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih} 9336d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 9346d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shihbool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const { 9357abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (mInputFormat == NULL) { 9366d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 9376d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9386d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 9396d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (targetFormat == NULL) { 9406d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return true; 9416d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9426d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 9436d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih AString oldMime, newMime; 9447abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (!mInputFormat->findString("mime", &oldMime) 9456d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih || !targetFormat->findString("mime", &newMime) 9466d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih || !(oldMime == newMime)) { 9476d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 9486d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9496d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 9506d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/")); 9516d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih bool seamless; 9526d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (audio) { 9536d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih seamless = supportsSeamlessAudioFormatChange(targetFormat); 9546d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } else { 9551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int32_t isAdaptive; 9561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar seamless = (mCodec != NULL && 9571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mInputFormat->findInt32("adaptive-playback", &isAdaptive) && 9581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar isAdaptive); 9596d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9606d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 9616d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str()); 9626d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return seamless; 9636d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih} 9646d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 9657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) { 9667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (format == NULL) { 967a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang return; 968a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 9697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCSDsForCurrentFormat.clear(); 9707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (int32_t i = 0; ; ++i) { 9717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang AString tag = "csd-"; 9727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang tag.append(i); 9737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> buffer; 9747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!format->findBuffer(tag.c_str(), &buffer)) { 9757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 9767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 9777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCSDsForCurrentFormat.push(buffer); 978a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 979b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang} 980b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 981f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::notifyResumeCompleteIfNecessary() { 982f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang if (mResumePending) { 983f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending = false; 984f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 985f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang sp<AMessage> notify = mNotify->dup(); 986f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notify->setInt32("what", kWhatResumeCompleted); 987f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notify->post(); 988f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang } 989f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang} 990f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} // namespace android 992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 993