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 229fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar#include <algorithm> 239fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar 247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "NuPlayerCCDecoder.h" 25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerDecoder.h" 26cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania#include "NuPlayerDrm.h" 27c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerRenderer.h" 28c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerSource.h" 29c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 30288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung#include <cutils/properties.h> 311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/ICrypto.h> 327e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include <media/MediaCodecBuffer.h> 33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h> 355bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <media/stagefright/foundation/AMessage.h> 36095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <media/stagefright/MediaBuffer.h> 371cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaCodec.h> 38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h> 391cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaErrors.h> 40181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang#include <media/stagefright/SurfaceUtils.h> 411de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h> 421de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar 437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "avc_utils.h" 447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "ATSParser.h" 457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 46f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android { 47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 489fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnarstatic float kDisplayRefreshingRate = 60.f; // TODO: get this from the display 49bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 50bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan// The default total video frame rate of a stream when that info is not available from 51bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan// the source. 52bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavanstatic float kDefaultVideoFrameRateTotal = 30.f; 53bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 54288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hungstatic inline bool getAudioDeepBufferSetting() { 55288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung return property_get_bool("media.stagefright.audio.deep", false /* default_value */); 56288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung} 57288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung 58f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::Decoder( 591173118eace0e9e347cb007f0da817cee87579edGlenn Kasten const sp<AMessage> ¬ify, 60c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia const sp<Source> &source, 6168845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu pid_t pid, 62f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia uid_t uid, 63c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia const sp<Renderer> &renderer, 641de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar const sp<Surface> &surface, 657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<CCDecoder> &ccDecoder) 66202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung : DecoderBase(notify), 671de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar mSurface(surface), 68c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSource(source), 69c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mRenderer(renderer), 707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder(ccDecoder), 7168845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu mPid(pid), 72f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia mUid(uid), 73c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSkipRenderingUntilMediaTimeUs(-1ll), 747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNumFramesTotal(0ll), 75e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumInputFramesDropped(0ll), 76e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumOutputFramesDropped(0ll), 77e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mVideoWidth(0), 78e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mVideoHeight(0), 797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio(true), 807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsVideoAVC(false), 817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsSecure(false), 8262dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania mIsEncrypted(false), 8362dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania mIsEncryptedObservedEarlier(false), 847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mFormatChangePending(false), 8566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending(false), 86bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mFrameRateTotal(kDefaultVideoFrameRateTotal), 87bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mPlaybackSpeed(1.0f), 889fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar mNumVideoTemporalLayerTotal(1), // decode all layers 89bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mNumVideoTemporalLayerAllowed(1), 90bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mCurrentMaxVideoTemporalLayerId(0), 91f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending(false), 921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName("decoder") { 931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodecLooper = new ALooper; 949e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen mCodecLooper->setName("NPDecoder-CL"); 951cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 96bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mVideoTemporalLayerAggregateFps[0] = mFrameRateTotal; 97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 99f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::~Decoder() { 10037ff0e6639e90ca49d4f0386a76c09437b459efdWei Jia // Need to stop looper first since mCodec could be accessed on the mDecoderLooper. 10137ff0e6639e90ca49d4f0386a76c09437b459efdWei Jia stopLooper(); 10237ff0e6639e90ca49d4f0386a76c09437b459efdWei Jia if (mCodec != NULL) { 10337ff0e6639e90ca49d4f0386a76c09437b459efdWei Jia mCodec->release(); 10437ff0e6639e90ca49d4f0386a76c09437b459efdWei Jia } 1054923cee4fb3b29538d8f46bceeea7d5128242a71Wei Jia releaseAndResetMediaBuffers(); 106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 108e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavansp<AMessage> NuPlayer::Decoder::getStats() const { 109e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt64("frames-total", mNumFramesTotal); 110e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt64("frames-dropped-input", mNumInputFramesDropped); 111e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt64("frames-dropped-output", mNumOutputFramesDropped); 112e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan return mStats; 1137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 114095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 115a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnarstatus_t NuPlayer::Decoder::setVideoSurface(const sp<Surface> &surface) { 116a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (surface == NULL || ADebug::isExperimentEnabled("legacy-setsurface")) { 117a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar return BAD_VALUE; 118a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 119a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 120a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this); 121a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 122a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar msg->setObject("surface", surface); 123a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<AMessage> response; 124a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar status_t err = msg->postAndAwaitResponse(&response); 125a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (err == OK && response != NULL) { 126a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar CHECK(response->findInt32("err", &err)); 127a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 128a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar return err; 129a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar} 130a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 1317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { 1327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str()); 133095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 1347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang switch (msg->what()) { 1357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang case kWhatCodecNotify: 1367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang { 1373b032b3865fd93173aadca0591eeea32853206f9Chong Zhang int32_t cbID; 1383b032b3865fd93173aadca0591eeea32853206f9Chong Zhang CHECK(msg->findInt32("callbackID", &cbID)); 1393b032b3865fd93173aadca0591eeea32853206f9Chong Zhang 1403b032b3865fd93173aadca0591eeea32853206f9Chong Zhang ALOGV("[%s] kWhatCodecNotify: cbID = %d, paused = %d", 1413b032b3865fd93173aadca0591eeea32853206f9Chong Zhang mIsAudio ? "audio" : "video", cbID, mPaused); 1423b032b3865fd93173aadca0591eeea32853206f9Chong Zhang 143421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (mPaused) { 144421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 145421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 146421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 147421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen switch (cbID) { 148421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_INPUT_AVAILABLE: 149421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 150421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t index; 151421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("index", &index)); 152095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 153421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleAnInputBuffer(index); 154421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 155421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 156421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 157421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_OUTPUT_AVAILABLE: 158421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 159421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t index; 160421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t offset; 161421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t size; 162421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int64_t timeUs; 163421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t flags; 164421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 165421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("index", &index)); 166421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findSize("offset", &offset)); 167421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findSize("size", &size)); 168421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt64("timeUs", &timeUs)); 169421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("flags", &flags)); 170421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 171421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleAnOutputBuffer(index, offset, size, timeUs, flags); 172421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 1737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 174095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 175421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_OUTPUT_FORMAT_CHANGED: 176421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 177421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> format; 178421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findMessage("format", &format)); 179421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 180421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleOutputFormatChange(format); 181421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 1827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 184421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_ERROR: 185421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 186421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen status_t err; 187421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("err", &err)); 188421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen ALOGE("Decoder (%s) reported error : 0x%x", 189421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mIsAudio ? "audio" : "video", err); 190421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 191421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleError(err); 192421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 1937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 195421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen default: 196421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 197421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen TRESPASS(); 198421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 199421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 2007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 20287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar break; 20387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 2047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang case kWhatRenderBuffer: 2067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang { 2077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!isStaleReply(msg)) { 2087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onRenderBuffer(msg); 2097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 2117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2139a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia case kWhatAudioOutputFormatChanged: 2149a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia { 2159a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia if (!isStaleReply(msg)) { 2169a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia status_t err; 2179a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia if (msg->findInt32("err", &err) && err != OK) { 2189a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia ALOGE("Renderer reported 0x%x when changing audio output format", err); 2199a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia handleError(err); 2209a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia } 2219a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia } 2229a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia break; 2239a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia } 2249a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia 225a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar case kWhatSetVideoSurface: 226a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar { 227a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<AReplyToken> replyID; 228a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 229a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 230a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<RefBase> obj; 231a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar CHECK(msg->findObject("surface", &obj)); 232a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<Surface> surface = static_cast<Surface *>(obj.get()); // non-null 233a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar int32_t err = INVALID_OPERATION; 234a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // NOTE: in practice mSurface is always non-null, but checking here for completeness 235a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (mCodec != NULL && mSurface != NULL) { 236a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // TODO: once AwesomePlayer is removed, remove this automatic connecting 237a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // to the surface by MediaPlayerService. 238a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // 239a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // at this point MediaPlayerService::client has already connected to the 240a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // surface, which MediaCodec does not expect 241181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang err = nativeWindowDisconnect(surface.get(), "kWhatSetVideoSurface(surface)"); 242a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (err == OK) { 243a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar err = mCodec->setSurface(surface); 244a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar ALOGI_IF(err, "codec setSurface returned: %d", err); 245a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (err == OK) { 246a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // reconnect to the old surface as MPS::Client will expect to 247a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // be able to disconnect from it. 248181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang (void)nativeWindowConnect(mSurface.get(), "kWhatSetVideoSurface(mSurface)"); 249a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar mSurface = surface; 250a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 251a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 252a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (err != OK) { 253a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // reconnect to the new surface on error as MPS::Client will expect to 254a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // be able to disconnect from it. 255181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang (void)nativeWindowConnect(surface.get(), "kWhatSetVideoSurface(err)"); 256a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 257a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 258a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 259a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<AMessage> response = new AMessage; 260a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar response->setInt32("err", err); 261a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar response->postReply(replyID); 262a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar break; 263a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 264a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 265cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania case kWhatDrmReleaseCrypto: 266cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania { 267cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania ALOGV("kWhatDrmReleaseCrypto"); 268cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania onReleaseCrypto(msg); 269cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania break; 270cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania } 271cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 2727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang default: 2737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang DecoderBase::onMessageReceived(msg); 2747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 27587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 27687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar} 27787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 2781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { 279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mCodec == NULL); 280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mFormatChangePending = false; 28266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending = false; 2837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ++mBufferGeneration; 2851cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 286840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber AString mime; 287840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(format->findString("mime", &mime)); 288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio = !strncasecmp("audio/", mime.c_str(), 6); 2907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str()); 2917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName = mime; 2931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.append(" decoder"); 2941de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get()); 295840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 29668845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu mCodec = MediaCodec::CreateByType( 297f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia mCodecLooper, mime.c_str(), false /* encoder */, NULL /* err */, mPid, mUid); 298095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar int32_t secure = 0; 299095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (format->findInt32("secure", &secure) && secure != 0) { 300095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (mCodec != NULL) { 301095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec->getName(&mComponentName); 302095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mComponentName.append(".secure"); 303095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec->release(); 304095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGI("[%s] creating", mComponentName.c_str()); 305095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec = MediaCodec::CreateByComponentName( 306f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia mCodecLooper, mComponentName.c_str(), NULL /* err */, mPid, mUid); 307095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 308095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 3091cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mCodec == NULL) { 310095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGE("Failed to create %s%s decoder", 311095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar (secure ? "secure " : ""), mime.c_str()); 3121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(UNKNOWN_ERROR); 3131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 314840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 3157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsSecure = secure; 316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodec->getName(&mComponentName); 3181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 31914986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar status_t err; 3201de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar if (mSurface != NULL) { 3211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // disconnect from surface as MediaCodec will reconnect 322181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang err = nativeWindowDisconnect(mSurface.get(), "onConfigure"); 32314986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar // We treat this as a warning, as this is a preparatory step. 32414986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar // Codec will try to connect to the surface, which is where 32514986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar // any error signaling will occur. 32614986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err); 3271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 328cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 329cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania // Modular DRM 330cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania void *pCrypto; 331cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania if (!format->findPointer("crypto", &pCrypto)) { 332cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania pCrypto = NULL; 333cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania } 334cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania sp<ICrypto> crypto = (ICrypto*)pCrypto; 33562dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania // non-encrypted source won't have a crypto 33662dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania mIsEncrypted = (crypto != NULL); 33762dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania // configure is called once; still using OR in case the behavior changes. 33862dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania mIsEncryptedObservedEarlier = mIsEncryptedObservedEarlier || mIsEncrypted; 339cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania ALOGV("onConfigure mCrypto: %p (%d) mIsSecure: %d", 340cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania crypto.get(), (crypto != NULL ? crypto->getStrongCount() : 0), mIsSecure); 341cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 34214986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar err = mCodec->configure( 343cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania format, mSurface, crypto, 0 /* flags */); 344cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 3451cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 3461cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err); 3472abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec->release(); 3482abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec.clear(); 3491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 3501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 3511cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 35287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar rememberCodecSpecificData(format); 35387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 3541cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // the following should work in configured state 3551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat)); 3561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat)); 3571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 358e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setString("mime", mime.c_str()); 359e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setString("component-name", mComponentName.c_str()); 360e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan 361e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan if (!mIsAudio) { 362e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan int32_t width, height; 363e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan if (mOutputFormat->findInt32("width", &width) 364e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan && mOutputFormat->findInt32("height", &height)) { 365e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("width", width); 366e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("height", height); 367e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan } 368e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan } 369e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan 370421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> reply = new AMessage(kWhatCodecNotify, this); 371421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->setCallback(reply); 372421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 3731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar err = mCodec->start(); 3741cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 3751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err); 3762abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec->release(); 3772abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec.clear(); 3781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 3791cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 382095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar releaseAndResetMediaBuffers(); 383078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 384704e72658b1082264a26a83c50046da34f07d1a1Wei Jia mPaused = false; 385f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending = false; 3861cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 387078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 3888db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wuvoid NuPlayer::Decoder::onSetParameters(const sp<AMessage> ¶ms) { 389bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan bool needAdjustLayers = false; 390bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan float frameRateTotal; 391bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (params->findFloat("frame-rate-total", &frameRateTotal) 392bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan && mFrameRateTotal != frameRateTotal) { 393bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan needAdjustLayers = true; 394bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mFrameRateTotal = frameRateTotal; 395bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 396bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 397bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan int32_t numVideoTemporalLayerTotal; 398bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (params->findInt32("temporal-layer-count", &numVideoTemporalLayerTotal) 3999fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar && numVideoTemporalLayerTotal >= 0 400bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan && numVideoTemporalLayerTotal <= kMaxNumVideoTemporalLayers 401bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan && mNumVideoTemporalLayerTotal != numVideoTemporalLayerTotal) { 402bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan needAdjustLayers = true; 4039fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar mNumVideoTemporalLayerTotal = std::max(numVideoTemporalLayerTotal, 1); 404bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 405bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 4069fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar if (needAdjustLayers && mNumVideoTemporalLayerTotal > 1) { 407bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan // TODO: For now, layer fps is calculated for some specific architectures. 408bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan // But it really should be extracted from the stream. 409bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mVideoTemporalLayerAggregateFps[0] = 410bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mFrameRateTotal / (float)(1ll << (mNumVideoTemporalLayerTotal - 1)); 411bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan for (int32_t i = 1; i < mNumVideoTemporalLayerTotal; ++i) { 412bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mVideoTemporalLayerAggregateFps[i] = 413bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mFrameRateTotal / (float)(1ll << (mNumVideoTemporalLayerTotal - i)) 414bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan + mVideoTemporalLayerAggregateFps[i - 1]; 415bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 416bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 417bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 418bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan float playbackSpeed; 419bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (params->findFloat("playback-speed", &playbackSpeed) 420bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan && mPlaybackSpeed != playbackSpeed) { 421bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan needAdjustLayers = true; 422bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mPlaybackSpeed = playbackSpeed; 423bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 424bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 425bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (needAdjustLayers) { 4269fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar float decodeFrameRate = mFrameRateTotal; 4279fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar // enable temporal layering optimization only if we know the layering depth 4289fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar if (mNumVideoTemporalLayerTotal > 1) { 4299fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar int32_t layerId; 4309fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar for (layerId = 0; layerId < mNumVideoTemporalLayerTotal - 1; ++layerId) { 4319fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar if (mVideoTemporalLayerAggregateFps[layerId] * mPlaybackSpeed 4329fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar >= kDisplayRefreshingRate * 0.9) { 4339fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar break; 4349fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar } 435bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 4369fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar mNumVideoTemporalLayerAllowed = layerId + 1; 4379fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar decodeFrameRate = mVideoTemporalLayerAggregateFps[layerId]; 438bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 4399fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar ALOGV("onSetParameters: allowed layers=%d, decodeFps=%g", 4409fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar mNumVideoTemporalLayerAllowed, decodeFrameRate); 441bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 442bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (mCodec == NULL) { 443bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan ALOGW("onSetParameters called before codec is created."); 444bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan return; 445bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 446bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 447bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan sp<AMessage> codecParams = new AMessage(); 4489fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar codecParams->setFloat("operating-rate", decodeFrameRate * mPlaybackSpeed); 449bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mCodec->setParameters(codecParams); 4508db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu } 4518db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu} 4528db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu 4537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) { 4547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer = renderer; 4557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 4562245fc625910e47d1ba3c339e205c21ab58a47adWei Jia 457f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::onResume(bool notifyComplete) { 4587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPaused = false; 459f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 460f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang if (notifyComplete) { 461f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending = true; 462f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang } 463421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->start(); 464095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar} 465095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 46666704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::doFlush(bool notifyComplete) { 4677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCCDecoder != NULL) { 4687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder->flush(); 4697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 4717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mRenderer != NULL) { 4727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->flush(mIsAudio, notifyComplete); 4737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->signalTimeDiscontinuity(); 4747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 4767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 4771cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mCodec != NULL) { 4787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = mCodec->flush(); 4797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator 4807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ++mBufferGeneration; 481078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 482078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 4837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err != OK) { 4847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err); 4857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang handleError(err); 4867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // finish with posting kWhatFlushCompleted. 4877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // we attempt to release the buffers even if flush fails. 4887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang releaseAndResetMediaBuffers(); 490421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mPaused = true; 49166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang} 492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 493421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 49466704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::onFlush() { 49566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang doFlush(true); 49666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 49766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (isDiscontinuityPending()) { 49866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // This could happen if the client starts seeking/shutdown 49966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // after we queued an EOS for discontinuities. 50066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // We can consider discontinuity handled. 50166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang finishHandleDiscontinuity(false /* flushOnTimeChange */); 5027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 50366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 50466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang sp<AMessage> notify = mNotify->dup(); 50566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang notify->setInt32("what", kWhatFlushCompleted); 50666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang notify->post(); 507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onShutdown(bool notifyComplete) { 5107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 511f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 512f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang // if there is a pending resume request, notify complete now 513f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notifyResumeCompleteIfNecessary(); 514f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 5157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCodec != NULL) { 5167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = mCodec->release(); 5177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCodec = NULL; 5187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ++mBufferGeneration; 5191cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 5201de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar if (mSurface != NULL) { 5217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // reconnect to surface as MediaCodec disconnected from it 522181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang status_t error = nativeWindowConnect(mSurface.get(), "onShutdown"); 5237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGW_IF(error != NO_ERROR, 5247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang "[%s] failed to connect to native window, error=%d", 5257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), error); 5267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName = "decoder"; 5287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang releaseAndResetMediaBuffers(); 5317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err != OK) { 5337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err); 5347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang handleError(err); 5357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // finish with posting kWhatShutdownCompleted. 5367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 537c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 5387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (notifyComplete) { 5397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> notify = mNotify->dup(); 5407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->setInt32("what", kWhatShutdownCompleted); 5417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->post(); 5427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPaused = true; 5437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 54487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar} 54587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 5463b032b3865fd93173aadca0591eeea32853206f9Chong Zhang/* 5473b032b3865fd93173aadca0591eeea32853206f9Chong Zhang * returns true if we should request more data 5483b032b3865fd93173aadca0591eeea32853206f9Chong Zhang */ 5493b032b3865fd93173aadca0591eeea32853206f9Chong Zhangbool NuPlayer::Decoder::doRequestBuffers() { 55029b7dcf6d3cdb97103467dc8106151c6260c239aJeff Tinker if (isDiscontinuityPending()) { 5513b032b3865fd93173aadca0591eeea32853206f9Chong Zhang return false; 5527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 55466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang while (err == OK && !mDequeuedInputBuffers.empty()) { 5557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t bufferIx = *mDequeuedInputBuffers.begin(); 5567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = new AMessage(); 5577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->setSize("buffer-ix", bufferIx); 5587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = fetchInputData(msg); 55966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (err != OK && err != ERROR_END_OF_STREAM) { 56066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // if EOS, need to queue EOS buffer 5617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 5627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin()); 5647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mPendingInputMessages.empty() 5667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang || !onInputBufferFetched(msg)) { 5677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingInputMessages.push_back(msg); 5687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 570095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 5713b032b3865fd93173aadca0591eeea32853206f9Chong Zhang return err == -EWOULDBLOCK 5723b032b3865fd93173aadca0591eeea32853206f9Chong Zhang && mSource->feedMoreTSData() == OK; 573095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar} 574095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 575421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleError(int32_t err) 576421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen{ 577421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen // We cannot immediately release the codec due to buffers still outstanding 578421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen // in the renderer. We signal to the player the error so it can shutdown/release the 579421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen // decoder after flushing and increment the generation to discard unnecessary messages. 580421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 581421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen ++mBufferGeneration; 582421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 583421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> notify = mNotify->dup(); 584421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setInt32("what", kWhatError); 585421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setInt32("err", err); 586421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->post(); 587421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen} 588421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 589cefac14261a32fb856b0d1ab31541787112e306eHassan Shojaniastatus_t NuPlayer::Decoder::releaseCrypto() 590cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania{ 591cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania ALOGV("releaseCrypto"); 592cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 593cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania sp<AMessage> msg = new AMessage(kWhatDrmReleaseCrypto, this); 594cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 595cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania sp<AMessage> response; 596cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania status_t status = msg->postAndAwaitResponse(&response); 597cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania if (status == OK && response != NULL) { 598cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania CHECK(response->findInt32("status", &status)); 599cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania ALOGV("releaseCrypto ret: %d ", status); 600cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania } else { 601cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania ALOGE("releaseCrypto err: %d", status); 602cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania } 603cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 604cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania return status; 605cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania} 606cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 607cefac14261a32fb856b0d1ab31541787112e306eHassan Shojaniavoid NuPlayer::Decoder::onReleaseCrypto(const sp<AMessage>& msg) 608cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania{ 609cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania status_t status = INVALID_OPERATION; 610cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania if (mCodec != NULL) { 611cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania status = mCodec->releaseCrypto(); 612cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania } else { 613cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania // returning OK if the codec has been already released 614cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania status = OK; 615cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania ALOGE("onReleaseCrypto No mCodec. err: %d", status); 616cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania } 617cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 618cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania sp<AMessage> response = new AMessage; 619cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania response->setInt32("status", status); 62062dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania // Clearing the state as it's tied to crypto. mIsEncryptedObservedEarlier is sticky though 62162dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania // and lasts for the lifetime of this codec. See its use in fetchInputData. 62262dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania mIsEncrypted = false; 623cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 624cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania sp<AReplyToken> replyID; 625cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania CHECK(msg->senderAwaitsResponse(&replyID)); 626cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania response->postReply(replyID); 627cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania} 628cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 629421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnInputBuffer(size_t index) { 63066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (isDiscontinuityPending()) { 6317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return false; 6327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 633421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 6347e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<MediaCodecBuffer> buffer; 635421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->getInputBuffer(index, &buffer); 636421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 6376301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia if (buffer == NULL) { 6386301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia handleError(UNKNOWN_ERROR); 6396301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia return false; 6406301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia } 6416301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia 642421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (index >= mInputBuffers.size()) { 643421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen for (size_t i = mInputBuffers.size(); i <= index; ++i) { 644421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBuffers.add(); 645421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers.add(); 646421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBufferIsDequeued.add(); 647421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers.editItemAt(i) = NULL; 648421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBufferIsDequeued.editItemAt(i) = false; 649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 6501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 651421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBuffers.editItemAt(index) = buffer; 652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 653421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen //CHECK_LT(bufferIx, mInputBuffers.size()); 6541cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 655421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (mMediaBuffers[index] != NULL) { 656421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers[index]->release(); 657421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers.editItemAt(index) = NULL; 658095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 659421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBufferIsDequeued.editItemAt(index) = true; 660095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 66187603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar if (!mCSDsToSubmit.isEmpty()) { 6627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = new AMessage(); 663421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen msg->setSize("buffer-ix", index); 6647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 66587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0); 66687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar ALOGI("[%s] resubmitting CSD", mComponentName.c_str()); 6677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->setBuffer("buffer", buffer); 66887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar mCSDsToSubmit.removeAt(0); 66956097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia if (!onInputBufferFetched(msg)) { 67056097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia handleError(UNKNOWN_ERROR); 67156097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia return false; 67256097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia } 6732245fc625910e47d1ba3c339e205c21ab58a47adWei Jia return true; 6742245fc625910e47d1ba3c339e205c21ab58a47adWei Jia } 6752245fc625910e47d1ba3c339e205c21ab58a47adWei Jia 6762245fc625910e47d1ba3c339e205c21ab58a47adWei Jia while (!mPendingInputMessages.empty()) { 6772245fc625910e47d1ba3c339e205c21ab58a47adWei Jia sp<AMessage> msg = *mPendingInputMessages.begin(); 6787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!onInputBufferFetched(msg)) { 6792245fc625910e47d1ba3c339e205c21ab58a47adWei Jia break; 6802245fc625910e47d1ba3c339e205c21ab58a47adWei Jia } 6812245fc625910e47d1ba3c339e205c21ab58a47adWei Jia mPendingInputMessages.erase(mPendingInputMessages.begin()); 6822245fc625910e47d1ba3c339e205c21ab58a47adWei Jia } 6832245fc625910e47d1ba3c339e205c21ab58a47adWei Jia 684421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (!mInputBufferIsDequeued.editItemAt(index)) { 68587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar return true; 68687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 68787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 688421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mDequeuedInputBuffers.push_back(index); 6897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onRequestInputBuffers(); 6911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return true; 6921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 6931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 694421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnOutputBuffer( 695421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t index, 696421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t offset, 697421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t size, 698421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int64_t timeUs, 699421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t flags) { 700421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen// CHECK_LT(bufferIx, mOutputBuffers.size()); 7017e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<MediaCodecBuffer> buffer; 702421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->getOutputBuffer(index, &buffer); 7037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7043539defd032864d33eed6add4820552f6fc4349bSanthosh Behara if (buffer == NULL) { 7053539defd032864d33eed6add4820552f6fc4349bSanthosh Behara handleError(UNKNOWN_ERROR); 7063539defd032864d33eed6add4820552f6fc4349bSanthosh Behara return false; 7073539defd032864d33eed6add4820552f6fc4349bSanthosh Behara } 7083539defd032864d33eed6add4820552f6fc4349bSanthosh Behara 709421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (index >= mOutputBuffers.size()) { 710421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen for (size_t i = mOutputBuffers.size(); i <= index; ++i) { 711421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mOutputBuffers.add(); 712095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 713095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 714095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 715421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mOutputBuffers.editItemAt(index) = buffer; 716421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 7177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->setRange(offset, size); 7187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->meta()->clear(); 7197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->meta()->setInt64("timeUs", timeUs); 72066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 72166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang bool eos = flags & MediaCodec::BUFFER_FLAG_EOS; 7227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // we do not expect CODECCONFIG or SYNCFRAME for decoder 7237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7241d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this); 725421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen reply->setSize("buffer-ix", index); 7267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("generation", mBufferGeneration); 7277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 72866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (eos) { 72966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video"); 73066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 73166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang buffer->meta()->setInt32("eos", true); 73266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang reply->setInt32("eos", true); 73366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } else if (mSkipRenderingUntilMediaTimeUs >= 0) { 7347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (timeUs < mSkipRenderingUntilMediaTimeUs) { 7357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] dropping buffer at time %lld as requested.", 7367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), (long long)timeUs); 7377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->post(); 7397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return true; 7407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mSkipRenderingUntilMediaTimeUs = -1; 7437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 745e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumFramesTotal += !mIsAudio; 746e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan 747f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang // wait until 1st frame comes out to signal resume complete 748f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notifyResumeCompleteIfNecessary(); 749f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 7507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mRenderer != NULL) { 7517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // send the buffer to renderer. 7527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->queueBuffer(mIsAudio, buffer, reply); 75366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (eos && !isDiscontinuityPending()) { 7547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM); 7557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return true; 7597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 7607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 761421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleOutputFormatChange(const sp<AMessage> &format) { 762421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (!mIsAudio) { 763e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan int32_t width, height; 764e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan if (format->findInt32("width", &width) 765e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan && format->findInt32("height", &height)) { 766e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("width", width); 767e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("height", height); 768e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan } 769421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> notify = mNotify->dup(); 770421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setInt32("what", kWhatVideoSizeChanged); 771421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setMessage("format", format); 772421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->post(); 773421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } else if (mRenderer != NULL) { 774421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen uint32_t flags; 775421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int64_t durationUs; 776421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen bool hasVideo = (mSource->getFormat(false /* audio */) != NULL); 777288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung if (getAudioDeepBufferSetting() // override regardless of source duration 77871c8e5c9565af4745cfd7ff0e327da1a27d77bf7Andy Hung || (mSource->getDuration(&durationUs) == OK 779288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung && durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US)) { 780421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 781421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } else { 782421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen flags = AUDIO_OUTPUT_FLAG_NONE; 783421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 784421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 7859a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia sp<AMessage> reply = new AMessage(kWhatAudioOutputFormatChanged, this); 7869a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia reply->setInt32("generation", mBufferGeneration); 7879a3101b22b5115717faeac986b43fc6618fd3b30Wei Jia mRenderer->changeAudioFormat( 788c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar format, false /* offloadOnly */, hasVideo, 789c387f2b719a1a26c8306f77d79cc9a6f26b36813Dhananjay Kumar flags, mSource->isStreaming(), reply); 790421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 791421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen} 792421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 7937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::releaseAndResetMediaBuffers() { 7947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mMediaBuffers.size(); i++) { 7957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mMediaBuffers[i] != NULL) { 7967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers[i]->release(); 7977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers.editItemAt(i) = NULL; 7987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers.resize(mInputBuffers.size()); 8017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mMediaBuffers.size(); i++) { 8027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers.editItemAt(i) = NULL; 8037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mInputBufferIsDequeued.clear(); 8057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mInputBufferIsDequeued.resize(mInputBuffers.size()); 8067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) { 8077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mInputBufferIsDequeued.editItemAt(i) = false; 8087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingInputMessages.clear(); 8117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mDequeuedInputBuffers.clear(); 8127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mSkipRenderingUntilMediaTimeUs = -1; 8137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 8147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::requestCodecNotification() { 8167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCodec != NULL) { 8171d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> reply = new AMessage(kWhatCodecNotify, this); 8187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("generation", mBufferGeneration); 8197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCodec->requestActivityNotification(reply); 8207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 8227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) { 8247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t generation; 8257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findInt32("generation", &generation)); 8267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return generation != mBufferGeneration; 8277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 8287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) { 8307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> accessUnit; 83159e9ca734f4d33fa1698466cdb2b66ab4ea1b82bRobert Shih bool dropAccessUnit = true; 8327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang do { 8337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit); 8347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err == -EWOULDBLOCK) { 8367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return err; 8377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (err != OK) { 8387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err == INFO_DISCONTINUITY) { 8397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t type; 8407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); 8417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool formatChange = 8437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (mIsAudio && 8447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT)) 8457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang || (!mIsAudio && 8467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT)); 8477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; 8497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGI("%s discontinuity (format=%d, time=%d)", 8517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio ? "audio" : "video", formatChange, timeChange); 8527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool seamlessFormatChange = false; 8547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> newFormat = mSource->getFormat(mIsAudio); 8557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (formatChange) { 8567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang seamlessFormatChange = 8577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang supportsSeamlessFormatChange(newFormat); 8587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // treat seamless format change separately 8597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang formatChange = !seamlessFormatChange; 8607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 86266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // For format or time change, return EOS to queue EOS input, 86366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // then wait for EOS on output. 8647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (formatChange /* not seamless */) { 8657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mFormatChangePending = true; 86666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang err = ERROR_END_OF_STREAM; 8677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (timeChange) { 8687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang rememberCodecSpecificData(newFormat); 86966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending = true; 87066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang err = ERROR_END_OF_STREAM; 8717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (seamlessFormatChange) { 8727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // reuse existing decoder and don't flush 8737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang rememberCodecSpecificData(newFormat); 87466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang continue; 8757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else { 8767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // This stream is unaffected by the discontinuity 8777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return -EWOULDBLOCK; 8787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 88166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // reply should only be returned without a buffer set 88266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // when there is an error (including EOS) 88366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang CHECK(err != OK); 88466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 8857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("err", err); 88666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang return ERROR_END_OF_STREAM; 8877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang dropAccessUnit = false; 89062dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania if (!mIsAudio && !mIsEncrypted) { 89162dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania // Extra safeguard if higher-level behavior changes. Otherwise, not required now. 89262dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania // Preventing the buffer from being processed (and sent to codec) if this is a later 89362dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania // round of playback but this time without prepareDrm. Or if there is a race between 89462dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania // stop (which is not blocking) and releaseDrm allowing buffers being processed after 89562dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania // Crypto has been released (GenericSource currently prevents this race though). 89662dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania // Particularly doing this check before IsAVCReferenceFrame call to prevent parsing 89762dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania // of encrypted data. 89862dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania if (mIsEncryptedObservedEarlier) { 89962dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania ALOGE("fetchInputData: mismatched mIsEncrypted/mIsEncryptedObservedEarlier (0/1)"); 90062dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania 90162dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania return INVALID_OPERATION; 90262dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania } 90362dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania 904bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan int32_t layerId = 0; 9059fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar bool haveLayerId = accessUnit->meta()->findInt32("temporal-layer-id", &layerId); 906bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (mRenderer->getVideoLateByUs() > 100000ll 907bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan && mIsVideoAVC 908bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan && !IsAVCReferenceFrame(accessUnit)) { 909bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan dropAccessUnit = true; 9109fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar } else if (haveLayerId && mNumVideoTemporalLayerTotal > 1) { 911bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan // Add only one layer each time. 912bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (layerId > mCurrentMaxVideoTemporalLayerId + 1 913bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan || layerId >= mNumVideoTemporalLayerAllowed) { 914bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan dropAccessUnit = true; 915bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan ALOGV("dropping layer(%d), speed=%g, allowed layer count=%d, max layerId=%d", 916bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan layerId, mPlaybackSpeed, mNumVideoTemporalLayerAllowed, 917bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mCurrentMaxVideoTemporalLayerId); 918bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } else if (layerId > mCurrentMaxVideoTemporalLayerId) { 919bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mCurrentMaxVideoTemporalLayerId = layerId; 9209fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar } else if (layerId == 0 && mNumVideoTemporalLayerTotal > 1 && IsIDR(accessUnit)) { 9219fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar mCurrentMaxVideoTemporalLayerId = mNumVideoTemporalLayerTotal - 1; 922bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 923bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 924bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (dropAccessUnit) { 9259fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar if (layerId <= mCurrentMaxVideoTemporalLayerId && layerId > 0) { 9269fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar mCurrentMaxVideoTemporalLayerId = layerId - 1; 9279fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar } 928bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan ++mNumInputFramesDropped; 929bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 9307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 9317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } while (dropAccessUnit); 9327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 9337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video"); 9347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#if 0 9357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int64_t mediaTimeUs; 9367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); 9375abbd3dcbb0bb32a3d4b90dddbcf90458967eb6fChong Zhang ALOGV("[%s] feeding input buffer at media time %.3f", 9387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio ? "audio" : "video", 9397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaTimeUs / 1E6); 9407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#endif 9417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 9427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCCDecoder != NULL) { 9437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder->decode(accessUnit); 9447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 9457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 9467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setBuffer("buffer", accessUnit); 9477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 9487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return OK; 9497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 9507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 9517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) { 9527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t bufferIx; 9537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findSize("buffer-ix", &bufferIx)); 9547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK_LT(bufferIx, mInputBuffers.size()); 9557e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<MediaCodecBuffer> codecBuffer = mInputBuffers[bufferIx]; 9567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 9577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> buffer; 9587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool hasBuffer = msg->findBuffer("buffer", &buffer); 9597e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim bool needsCopy = true; 9607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 9617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (buffer == NULL /* includes !hasBuffer */) { 9627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t streamErr = ERROR_END_OF_STREAM; 9637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); 9647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 96566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang CHECK(streamErr != OK); 9661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 9671cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // attempt to queue EOS 9681cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err = mCodec->queueInputBuffer( 9691cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar bufferIx, 9701cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 9711cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 9721cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 9731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar MediaCodec::BUFFER_FLAG_EOS); 974cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung if (err == OK) { 975cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mInputBufferIsDequeued.editItemAt(bufferIx) = false; 976cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } else if (streamErr == ERROR_END_OF_STREAM) { 9771cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar streamErr = err; 9781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // err will not be ERROR_END_OF_STREAM 9791cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 9801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 9811cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (streamErr != ERROR_END_OF_STREAM) { 982cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung ALOGE("Stream error for %s (err=%d), EOS %s queued", 983cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mComponentName.c_str(), 984cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung streamErr, 985cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung err == OK ? "successfully" : "unsuccessfully"); 9861cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(streamErr); 9871cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 9881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else { 989c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia sp<AMessage> extra; 990c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) { 991c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia int64_t resumeAtMediaTimeUs; 992c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (extra->findInt64( 993c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) { 994c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia ALOGI("[%s] suppressing rendering until %lld us", 995c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mComponentName.c_str(), (long long)resumeAtMediaTimeUs); 996c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs; 997c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 998c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 999c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 10001cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int64_t timeUs = 0; 10011cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar uint32_t flags = 0; 10021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 10031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 100487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar int32_t eos, csd; 100587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar // we do not expect SYNCFRAME for decoder 10061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (buffer->meta()->findInt32("eos", &eos) && eos) { 10071cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar flags |= MediaCodec::BUFFER_FLAG_EOS; 100887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } else if (buffer->meta()->findInt32("csd", &csd) && csd) { 100987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; 10101cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 10111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 1012cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania // Modular DRM 1013cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania MediaBuffer *mediaBuf = NULL; 1014cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania NuPlayerDrm::CryptoInfo *cryptInfo = NULL; 1015cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 10161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // copy into codec buffer 10177e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim if (needsCopy) { 101856097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia if (buffer->size() > codecBuffer->capacity()) { 101956097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia handleError(ERROR_BUFFER_TOO_SMALL); 102056097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia mDequeuedInputBuffers.push_back(bufferIx); 102156097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia return false; 102256097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia } 10231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 1024cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania if (buffer->data() != NULL) { 1025cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania codecBuffer->setRange(0, buffer->size()); 1026cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania memcpy(codecBuffer->data(), buffer->data(), buffer->size()); 1027cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania } else { // No buffer->data() 1028cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania //Modular DRM 1029cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania mediaBuf = (MediaBuffer*)buffer->getMediaBufferBase(); 1030cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania if (mediaBuf != NULL) { 1031cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania codecBuffer->setRange(0, mediaBuf->size()); 1032cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania memcpy(codecBuffer->data(), mediaBuf->data(), mediaBuf->size()); 1033cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 1034cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania sp<MetaData> meta_data = mediaBuf->meta_data(); 1035cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania cryptInfo = NuPlayerDrm::getSampleCryptoInfo(meta_data); 1036cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 1037cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania // since getMediaBuffer() has incremented the refCount 1038cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania mediaBuf->release(); 1039cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania } else { // No mediaBuf 1040cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania ALOGE("onInputBufferFetched: buffer->data()/mediaBuf are NULL for %p", 1041cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania buffer.get()); 1042cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania handleError(UNKNOWN_ERROR); 1043cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania return false; 1044cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania } 1045cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania } // buffer->data() 1046cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania } // needsCopy 1047cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 1048cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania status_t err; 1049cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania AString errorDetailMsg; 1050cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania if (cryptInfo != NULL) { 1051cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania err = mCodec->queueSecureInputBuffer( 1052cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania bufferIx, 1053cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania codecBuffer->offset(), 1054cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania cryptInfo->subSamples, 1055cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania cryptInfo->numSubSamples, 1056cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania cryptInfo->key, 1057cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania cryptInfo->iv, 1058cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania cryptInfo->mode, 1059cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania cryptInfo->pattern, 1060cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania timeUs, 1061cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania flags, 1062cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania &errorDetailMsg); 1063cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania // synchronous call so done with cryptInfo here 1064cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania free(cryptInfo); 1065cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania } else { 1066cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania err = mCodec->queueInputBuffer( 1067cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania bufferIx, 1068cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania codecBuffer->offset(), 1069cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania codecBuffer->size(), 1070cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania timeUs, 1071cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania flags, 1072cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania &errorDetailMsg); 1073cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania } // no cryptInfo 1074cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 10751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 1076cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania ALOGE("onInputBufferFetched: queue%sInputBuffer failed for %s (err=%d, %s)", 1077cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania (cryptInfo != NULL ? "Secure" : ""), 1078cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania mComponentName.c_str(), err, errorDetailMsg.c_str()); 10791cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 1080cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } else { 1081cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mInputBufferIsDequeued.editItemAt(bufferIx) = false; 1082095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 1083cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania 1084cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania } // buffer != NULL 10852245fc625910e47d1ba3c339e205c21ab58a47adWei Jia return true; 1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 10881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) { 10891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err; 10901cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int32_t render; 10911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar size_t bufferIx; 109266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang int32_t eos; 10931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(msg->findSize("buffer-ix", &bufferIx)); 1094c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 10957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mIsAudio) { 1096c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia int64_t timeUs; 10977e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<MediaCodecBuffer> buffer = mOutputBuffers[bufferIx]; 1098c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia buffer->meta()->findInt64("timeUs", &timeUs); 10997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 11007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCCDecoder != NULL && mCCDecoder->isSelected()) { 11017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder->display(timeUs); 11027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1103c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 1104c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 11051cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (msg->findInt32("render", &render) && render) { 1106dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t timestampNs; 1107dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar CHECK(msg->findInt64("timestampNs", ×tampNs)); 1108dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs); 11091cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else { 1110e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumOutputFramesDropped += !mIsAudio; 11111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar err = mCodec->releaseOutputBuffer(bufferIx); 11121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 11131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 11141cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("failed to release output buffer for %s (err=%d)", 11151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), err); 11161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 111866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (msg->findInt32("eos", &eos) && eos 111966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang && isDiscontinuityPending()) { 112066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang finishHandleDiscontinuity(true /* flushOnTimeChange */); 112166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } 112266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang} 112366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 112466704af4d82c2b6303609b29402641f861fdcb19Chong Zhangbool NuPlayer::Decoder::isDiscontinuityPending() const { 112566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang return mFormatChangePending || mTimeChangePending; 112666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang} 112766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 112866704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) { 112966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang ALOGV("finishHandleDiscontinuity: format %d, time %d, flush %d", 113066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mFormatChangePending, mTimeChangePending, flushOnTimeChange); 113166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 113266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // If we have format change, pause and wait to be killed; 113366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // If we have time change only, flush and restart fetching. 113466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 113566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (mFormatChangePending) { 113666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mPaused = true; 113766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } else if (mTimeChangePending) { 113866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (flushOnTimeChange) { 1139421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen doFlush(false /* notifyComplete */); 1140421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen signalResume(false /* notifyComplete */); 114166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } 114266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } 114366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 114466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // Notify NuPlayer to either shutdown decoder, or rescan sources 114566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang sp<AMessage> msg = mNotify->dup(); 114666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang msg->setInt32("what", kWhatInputDiscontinuity); 114766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang msg->setInt32("formatChange", mFormatChangePending); 114866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang msg->post(); 114966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 115066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mFormatChangePending = false; 115166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending = false; 1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 11547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::supportsSeamlessAudioFormatChange( 11557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<AMessage> &targetFormat) const { 11566d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (targetFormat == NULL) { 11576d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return true; 11586d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 11596d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 11606d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih AString mime; 11616d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (!targetFormat->findString("mime", &mime)) { 11626d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 11636d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 11646d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 11656d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 11666d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih // field-by-field comparison 11676d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih const char * keys[] = { "channel-count", "sample-rate", "is-adts" }; 11686d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) { 11696d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih int32_t oldVal, newVal; 11707abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (!mInputFormat->findInt32(keys[i], &oldVal) || 11711cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar !targetFormat->findInt32(keys[i], &newVal) || 11721cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar oldVal != newVal) { 11736d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 11746d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 11756d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 11766d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 11776d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih sp<ABuffer> oldBuf, newBuf; 11787abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (mInputFormat->findBuffer("csd-0", &oldBuf) && 11791cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar targetFormat->findBuffer("csd-0", &newBuf)) { 11806d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (oldBuf->size() != newBuf->size()) { 11816d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 11826d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 11836d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size()); 11846d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 11856d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 11866d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 11876d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih} 11886d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 11896d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shihbool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const { 11907abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (mInputFormat == NULL) { 11916d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 11926d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 11936d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 11946d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (targetFormat == NULL) { 11956d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return true; 11966d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 11976d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 11986d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih AString oldMime, newMime; 11997abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (!mInputFormat->findString("mime", &oldMime) 12006d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih || !targetFormat->findString("mime", &newMime) 12016d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih || !(oldMime == newMime)) { 12026d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 12036d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 12046d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 12056d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/")); 12066d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih bool seamless; 12076d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (audio) { 12086d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih seamless = supportsSeamlessAudioFormatChange(targetFormat); 12096d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } else { 12101cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int32_t isAdaptive; 12111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar seamless = (mCodec != NULL && 12121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mInputFormat->findInt32("adaptive-playback", &isAdaptive) && 12131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar isAdaptive); 12146d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 12156d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 12166d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str()); 12176d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return seamless; 12186d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih} 12196d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 12207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) { 12217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (format == NULL) { 1222a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang return; 1223a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 12247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCSDsForCurrentFormat.clear(); 12257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (int32_t i = 0; ; ++i) { 12267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang AString tag = "csd-"; 12277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang tag.append(i); 12287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> buffer; 12297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!format->findBuffer(tag.c_str(), &buffer)) { 12307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 12317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 12327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCSDsForCurrentFormat.push(buffer); 1233a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 1234b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang} 1235b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 1236f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::notifyResumeCompleteIfNecessary() { 1237f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang if (mResumePending) { 1238f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending = false; 1239f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 1240f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang sp<AMessage> notify = mNotify->dup(); 1241f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notify->setInt32("what", kWhatResumeCompleted); 1242f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notify->post(); 1243f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang } 1244f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang} 1245f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 1246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} // namespace android 1247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1248