NuPlayerDecoder.cpp revision 9fb815244cc33927e14ce0fe70539786a611daf9
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" 26c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerRenderer.h" 27c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerSource.h" 28c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 29288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung#include <cutils/properties.h> 301cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/ICrypto.h> 31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h> 335bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <media/stagefright/foundation/AMessage.h> 34095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <media/stagefright/MediaBuffer.h> 351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaCodec.h> 36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h> 371cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaErrors.h> 38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 391de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h> 401de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar 417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "avc_utils.h" 427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "ATSParser.h" 437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 44f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android { 45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 469fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnarstatic float kDisplayRefreshingRate = 60.f; // TODO: get this from the display 47bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 48bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan// The default total video frame rate of a stream when that info is not available from 49bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan// the source. 50bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavanstatic float kDefaultVideoFrameRateTotal = 30.f; 51bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 52288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hungstatic inline bool getAudioDeepBufferSetting() { 53288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung return property_get_bool("media.stagefright.audio.deep", false /* default_value */); 54288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung} 55288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung 56f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::Decoder( 571173118eace0e9e347cb007f0da817cee87579edGlenn Kasten const sp<AMessage> ¬ify, 58c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia const sp<Source> &source, 5968845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu pid_t pid, 60c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia const sp<Renderer> &renderer, 611de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar const sp<Surface> &surface, 627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<CCDecoder> &ccDecoder) 63202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung : DecoderBase(notify), 641de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar mSurface(surface), 65c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSource(source), 66c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mRenderer(renderer), 677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder(ccDecoder), 6868845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu mPid(pid), 69c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSkipRenderingUntilMediaTimeUs(-1ll), 707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNumFramesTotal(0ll), 71e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumInputFramesDropped(0ll), 72e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumOutputFramesDropped(0ll), 73e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mVideoWidth(0), 74e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mVideoHeight(0), 757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio(true), 767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsVideoAVC(false), 777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsSecure(false), 787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mFormatChangePending(false), 7966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending(false), 80bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mFrameRateTotal(kDefaultVideoFrameRateTotal), 81bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mPlaybackSpeed(1.0f), 829fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar mNumVideoTemporalLayerTotal(1), // decode all layers 83bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mNumVideoTemporalLayerAllowed(1), 84bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mCurrentMaxVideoTemporalLayerId(0), 85f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending(false), 861cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName("decoder") { 871cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodecLooper = new ALooper; 889e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen mCodecLooper->setName("NPDecoder-CL"); 891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 90bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mVideoTemporalLayerAggregateFps[0] = mFrameRateTotal; 91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 93f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::~Decoder() { 94faeb0f291330134dc4468359a36e099aae508449Ronghua Wu mCodec->release(); 954923cee4fb3b29538d8f46bceeea7d5128242a71Wei Jia releaseAndResetMediaBuffers(); 96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 98e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavansp<AMessage> NuPlayer::Decoder::getStats() const { 99e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt64("frames-total", mNumFramesTotal); 100e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt64("frames-dropped-input", mNumInputFramesDropped); 101e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt64("frames-dropped-output", mNumOutputFramesDropped); 102e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan return mStats; 1037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 104095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 105a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnarstatus_t NuPlayer::Decoder::setVideoSurface(const sp<Surface> &surface) { 106a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (surface == NULL || ADebug::isExperimentEnabled("legacy-setsurface")) { 107a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar return BAD_VALUE; 108a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 109a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 110a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this); 111a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 112a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar msg->setObject("surface", surface); 113a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<AMessage> response; 114a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar status_t err = msg->postAndAwaitResponse(&response); 115a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (err == OK && response != NULL) { 116a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar CHECK(response->findInt32("err", &err)); 117a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 118a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar return err; 119a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar} 120a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 1217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { 1227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str()); 123095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 1247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang switch (msg->what()) { 1257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang case kWhatCodecNotify: 1267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang { 1273b032b3865fd93173aadca0591eeea32853206f9Chong Zhang int32_t cbID; 1283b032b3865fd93173aadca0591eeea32853206f9Chong Zhang CHECK(msg->findInt32("callbackID", &cbID)); 1293b032b3865fd93173aadca0591eeea32853206f9Chong Zhang 1303b032b3865fd93173aadca0591eeea32853206f9Chong Zhang ALOGV("[%s] kWhatCodecNotify: cbID = %d, paused = %d", 1313b032b3865fd93173aadca0591eeea32853206f9Chong Zhang mIsAudio ? "audio" : "video", cbID, mPaused); 1323b032b3865fd93173aadca0591eeea32853206f9Chong Zhang 133421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (mPaused) { 134421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 135421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 136421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 137421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen switch (cbID) { 138421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_INPUT_AVAILABLE: 139421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 140421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t index; 141421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("index", &index)); 142095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 143421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleAnInputBuffer(index); 144421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 145421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 146421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 147421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_OUTPUT_AVAILABLE: 148421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 149421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t index; 150421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t offset; 151421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t size; 152421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int64_t timeUs; 153421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t flags; 154421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 155421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("index", &index)); 156421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findSize("offset", &offset)); 157421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findSize("size", &size)); 158421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt64("timeUs", &timeUs)); 159421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("flags", &flags)); 160421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 161421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleAnOutputBuffer(index, offset, size, timeUs, flags); 162421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 1637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 164095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 165421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_OUTPUT_FORMAT_CHANGED: 166421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 167421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> format; 168421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findMessage("format", &format)); 169421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 170421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleOutputFormatChange(format); 171421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 1727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 174421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_ERROR: 175421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 176421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen status_t err; 177421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("err", &err)); 178421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen ALOGE("Decoder (%s) reported error : 0x%x", 179421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mIsAudio ? "audio" : "video", err); 180421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 181421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleError(err); 182421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 1837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 185421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen default: 186421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 187421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen TRESPASS(); 188421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 189421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 1907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 19287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar break; 19387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 1947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang case kWhatRenderBuffer: 1967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang { 1977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!isStaleReply(msg)) { 1987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onRenderBuffer(msg); 1997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 2017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 203a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar case kWhatSetVideoSurface: 204a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar { 205a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<AReplyToken> replyID; 206a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 207a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 208a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<RefBase> obj; 209a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar CHECK(msg->findObject("surface", &obj)); 210a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<Surface> surface = static_cast<Surface *>(obj.get()); // non-null 211a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar int32_t err = INVALID_OPERATION; 212a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // NOTE: in practice mSurface is always non-null, but checking here for completeness 213a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (mCodec != NULL && mSurface != NULL) { 214a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // TODO: once AwesomePlayer is removed, remove this automatic connecting 215a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // to the surface by MediaPlayerService. 216a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // 217a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // at this point MediaPlayerService::client has already connected to the 218a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // surface, which MediaCodec does not expect 219a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar err = native_window_api_disconnect(surface.get(), NATIVE_WINDOW_API_MEDIA); 220a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (err == OK) { 221a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar err = mCodec->setSurface(surface); 222a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar ALOGI_IF(err, "codec setSurface returned: %d", err); 223a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (err == OK) { 224a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // reconnect to the old surface as MPS::Client will expect to 225a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // be able to disconnect from it. 226a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar (void)native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_MEDIA); 227a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar mSurface = surface; 228a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 229a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 230a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (err != OK) { 231a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // reconnect to the new surface on error as MPS::Client will expect to 232a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // be able to disconnect from it. 233a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar (void)native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA); 234a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 235a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 236a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 237a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<AMessage> response = new AMessage; 238a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar response->setInt32("err", err); 239a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar response->postReply(replyID); 240a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar break; 241a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 242a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 2437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang default: 2447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang DecoderBase::onMessageReceived(msg); 2457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 24687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 24787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar} 24887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 2491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { 250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mCodec == NULL); 251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mFormatChangePending = false; 25366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending = false; 2547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ++mBufferGeneration; 2561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 257840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber AString mime; 258840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(format->findString("mime", &mime)); 259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio = !strncasecmp("audio/", mime.c_str(), 6); 2617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str()); 2627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2631cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName = mime; 2641cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.append(" decoder"); 2651de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get()); 266840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 26768845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu mCodec = MediaCodec::CreateByType( 26868845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu mCodecLooper, mime.c_str(), false /* encoder */, NULL /* err */, mPid); 269095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar int32_t secure = 0; 270095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (format->findInt32("secure", &secure) && secure != 0) { 271095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (mCodec != NULL) { 272095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec->getName(&mComponentName); 273095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mComponentName.append(".secure"); 274095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec->release(); 275095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGI("[%s] creating", mComponentName.c_str()); 276095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec = MediaCodec::CreateByComponentName( 27768845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu mCodecLooper, mComponentName.c_str(), NULL /* err */, mPid); 278095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 279095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 2801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mCodec == NULL) { 281095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGE("Failed to create %s%s decoder", 282095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar (secure ? "secure " : ""), mime.c_str()); 2831cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(UNKNOWN_ERROR); 2841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 285840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 2867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsSecure = secure; 287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodec->getName(&mComponentName); 2891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 29014986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar status_t err; 2911de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar if (mSurface != NULL) { 2921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // disconnect from surface as MediaCodec will reconnect 29314986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar err = native_window_api_disconnect( 2941de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar mSurface.get(), NATIVE_WINDOW_API_MEDIA); 29514986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar // We treat this as a warning, as this is a preparatory step. 29614986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar // Codec will try to connect to the surface, which is where 29714986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar // any error signaling will occur. 29814986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err); 2991cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 30014986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar err = mCodec->configure( 3011de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar format, mSurface, NULL /* crypto */, 0 /* flags */); 3021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 3031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err); 3042abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec->release(); 3052abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec.clear(); 3061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 3071cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 3081cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 30987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar rememberCodecSpecificData(format); 31087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 3111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // the following should work in configured state 3121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat)); 3131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat)); 3141cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 315e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setString("mime", mime.c_str()); 316e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setString("component-name", mComponentName.c_str()); 317e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan 318e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan if (!mIsAudio) { 319e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan int32_t width, height; 320e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan if (mOutputFormat->findInt32("width", &width) 321e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan && mOutputFormat->findInt32("height", &height)) { 322e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("width", width); 323e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("height", height); 324e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan } 325e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan } 326e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan 327421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> reply = new AMessage(kWhatCodecNotify, this); 328421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->setCallback(reply); 329421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 3301cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar err = mCodec->start(); 3311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 3321cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err); 3332abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec->release(); 3342abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec.clear(); 3351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 3361cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 339095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar releaseAndResetMediaBuffers(); 340078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 341704e72658b1082264a26a83c50046da34f07d1a1Wei Jia mPaused = false; 342f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending = false; 3431cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 344078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 3458db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wuvoid NuPlayer::Decoder::onSetParameters(const sp<AMessage> ¶ms) { 346bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan bool needAdjustLayers = false; 347bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan float frameRateTotal; 348bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (params->findFloat("frame-rate-total", &frameRateTotal) 349bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan && mFrameRateTotal != frameRateTotal) { 350bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan needAdjustLayers = true; 351bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mFrameRateTotal = frameRateTotal; 352bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 353bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 354bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan int32_t numVideoTemporalLayerTotal; 355bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (params->findInt32("temporal-layer-count", &numVideoTemporalLayerTotal) 3569fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar && numVideoTemporalLayerTotal >= 0 357bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan && numVideoTemporalLayerTotal <= kMaxNumVideoTemporalLayers 358bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan && mNumVideoTemporalLayerTotal != numVideoTemporalLayerTotal) { 359bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan needAdjustLayers = true; 3609fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar mNumVideoTemporalLayerTotal = std::max(numVideoTemporalLayerTotal, 1); 361bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 362bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 3639fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar if (needAdjustLayers && mNumVideoTemporalLayerTotal > 1) { 364bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan // TODO: For now, layer fps is calculated for some specific architectures. 365bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan // But it really should be extracted from the stream. 366bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mVideoTemporalLayerAggregateFps[0] = 367bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mFrameRateTotal / (float)(1ll << (mNumVideoTemporalLayerTotal - 1)); 368bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan for (int32_t i = 1; i < mNumVideoTemporalLayerTotal; ++i) { 369bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mVideoTemporalLayerAggregateFps[i] = 370bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mFrameRateTotal / (float)(1ll << (mNumVideoTemporalLayerTotal - i)) 371bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan + mVideoTemporalLayerAggregateFps[i - 1]; 372bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 373bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 374bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 375bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan float playbackSpeed; 376bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (params->findFloat("playback-speed", &playbackSpeed) 377bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan && mPlaybackSpeed != playbackSpeed) { 378bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan needAdjustLayers = true; 379bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mPlaybackSpeed = playbackSpeed; 380bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 381bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 382bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (needAdjustLayers) { 3839fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar float decodeFrameRate = mFrameRateTotal; 3849fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar // enable temporal layering optimization only if we know the layering depth 3859fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar if (mNumVideoTemporalLayerTotal > 1) { 3869fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar int32_t layerId; 3879fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar for (layerId = 0; layerId < mNumVideoTemporalLayerTotal - 1; ++layerId) { 3889fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar if (mVideoTemporalLayerAggregateFps[layerId] * mPlaybackSpeed 3899fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar >= kDisplayRefreshingRate * 0.9) { 3909fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar break; 3919fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar } 392bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 3939fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar mNumVideoTemporalLayerAllowed = layerId + 1; 3949fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar decodeFrameRate = mVideoTemporalLayerAggregateFps[layerId]; 395bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 3969fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar ALOGV("onSetParameters: allowed layers=%d, decodeFps=%g", 3979fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar mNumVideoTemporalLayerAllowed, decodeFrameRate); 398bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 399bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (mCodec == NULL) { 400bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan ALOGW("onSetParameters called before codec is created."); 401bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan return; 402bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 403bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan 404bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan sp<AMessage> codecParams = new AMessage(); 4059fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar codecParams->setFloat("operating-rate", decodeFrameRate * mPlaybackSpeed); 406bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mCodec->setParameters(codecParams); 4078db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu } 4088db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu} 4098db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu 4107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) { 4117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool hadNoRenderer = (mRenderer == NULL); 4127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer = renderer; 4137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (hadNoRenderer && mRenderer != NULL) { 414e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // this means that the widevine legacy source is ready 415e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar onRequestInputBuffers(); 41681e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia } 4177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 4187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 4197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onGetInputBuffers( 4207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang Vector<sp<ABuffer> > *dstBuffers) { 421e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getWidevineLegacyBuffers(dstBuffers)); 4227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 4232245fc625910e47d1ba3c339e205c21ab58a47adWei Jia 424f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::onResume(bool notifyComplete) { 4257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPaused = false; 426f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 427f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang if (notifyComplete) { 428f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending = true; 429f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang } 430421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->start(); 431095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar} 432095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 43366704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::doFlush(bool notifyComplete) { 4347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCCDecoder != NULL) { 4357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder->flush(); 4367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 4387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mRenderer != NULL) { 4397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->flush(mIsAudio, notifyComplete); 4407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->signalTimeDiscontinuity(); 4417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 4437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 4441cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mCodec != NULL) { 4457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = mCodec->flush(); 4467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator 4477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ++mBufferGeneration; 448078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 449078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 4507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err != OK) { 4517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err); 4527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang handleError(err); 4537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // finish with posting kWhatFlushCompleted. 4547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // we attempt to release the buffers even if flush fails. 4557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang releaseAndResetMediaBuffers(); 457421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mPaused = true; 45866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang} 459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 460421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 46166704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::onFlush() { 46266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang doFlush(true); 46366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 46466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (isDiscontinuityPending()) { 46566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // This could happen if the client starts seeking/shutdown 46666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // after we queued an EOS for discontinuities. 46766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // We can consider discontinuity handled. 46866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang finishHandleDiscontinuity(false /* flushOnTimeChange */); 4697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 47066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 47166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang sp<AMessage> notify = mNotify->dup(); 47266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang notify->setInt32("what", kWhatFlushCompleted); 47366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang notify->post(); 474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onShutdown(bool notifyComplete) { 4777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 478f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 479f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang // if there is a pending resume request, notify complete now 480f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notifyResumeCompleteIfNecessary(); 481f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 4827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCodec != NULL) { 4837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = mCodec->release(); 4847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCodec = NULL; 4857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ++mBufferGeneration; 4861cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 4871de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar if (mSurface != NULL) { 4887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // reconnect to surface as MediaCodec disconnected from it 4897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t error = 4901de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_MEDIA); 4917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGW_IF(error != NO_ERROR, 4927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang "[%s] failed to connect to native window, error=%d", 4937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), error); 4947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName = "decoder"; 4967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 4987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang releaseAndResetMediaBuffers(); 4997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err != OK) { 5017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err); 5027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang handleError(err); 5037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // finish with posting kWhatShutdownCompleted. 5047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 505c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 5067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (notifyComplete) { 5077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> notify = mNotify->dup(); 5087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->setInt32("what", kWhatShutdownCompleted); 5097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->post(); 5107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPaused = true; 5117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 51287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar} 51387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 5143b032b3865fd93173aadca0591eeea32853206f9Chong Zhang/* 5153b032b3865fd93173aadca0591eeea32853206f9Chong Zhang * returns true if we should request more data 5163b032b3865fd93173aadca0591eeea32853206f9Chong Zhang */ 5173b032b3865fd93173aadca0591eeea32853206f9Chong Zhangbool NuPlayer::Decoder::doRequestBuffers() { 518e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // mRenderer is only NULL if we have a legacy widevine source that 519e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // is not yet ready. In this case we must not fetch input. 520e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar if (isDiscontinuityPending() || mRenderer == NULL) { 5213b032b3865fd93173aadca0591eeea32853206f9Chong Zhang return false; 5227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 52466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang while (err == OK && !mDequeuedInputBuffers.empty()) { 5257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t bufferIx = *mDequeuedInputBuffers.begin(); 5267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = new AMessage(); 5277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->setSize("buffer-ix", bufferIx); 5287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = fetchInputData(msg); 52966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (err != OK && err != ERROR_END_OF_STREAM) { 53066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // if EOS, need to queue EOS buffer 5317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 5327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin()); 5347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mPendingInputMessages.empty() 5367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang || !onInputBufferFetched(msg)) { 5377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingInputMessages.push_back(msg); 5387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 540095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 5413b032b3865fd93173aadca0591eeea32853206f9Chong Zhang return err == -EWOULDBLOCK 5423b032b3865fd93173aadca0591eeea32853206f9Chong Zhang && mSource->feedMoreTSData() == OK; 543095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar} 544095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 545421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleError(int32_t err) 546421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen{ 547421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen // We cannot immediately release the codec due to buffers still outstanding 548421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen // in the renderer. We signal to the player the error so it can shutdown/release the 549421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen // decoder after flushing and increment the generation to discard unnecessary messages. 550421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 551421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen ++mBufferGeneration; 552421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 553421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> notify = mNotify->dup(); 554421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setInt32("what", kWhatError); 555421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setInt32("err", err); 556421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->post(); 557421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen} 558421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 559421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnInputBuffer(size_t index) { 56066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (isDiscontinuityPending()) { 5617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return false; 5627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 563421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 564421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<ABuffer> buffer; 565421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->getInputBuffer(index, &buffer); 566421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 5676301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia if (buffer == NULL) { 5686301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia handleError(UNKNOWN_ERROR); 5696301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia return false; 5706301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia } 5716301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia 572421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (index >= mInputBuffers.size()) { 573421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen for (size_t i = mInputBuffers.size(); i <= index; ++i) { 574421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBuffers.add(); 575421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers.add(); 576421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBufferIsDequeued.add(); 577421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers.editItemAt(i) = NULL; 578421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBufferIsDequeued.editItemAt(i) = false; 579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 581421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBuffers.editItemAt(index) = buffer; 582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 583421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen //CHECK_LT(bufferIx, mInputBuffers.size()); 5841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 585421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (mMediaBuffers[index] != NULL) { 586421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers[index]->release(); 587421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers.editItemAt(index) = NULL; 588095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 589421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBufferIsDequeued.editItemAt(index) = true; 590095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 59187603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar if (!mCSDsToSubmit.isEmpty()) { 5927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = new AMessage(); 593421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen msg->setSize("buffer-ix", index); 5947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 59587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0); 59687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar ALOGI("[%s] resubmitting CSD", mComponentName.c_str()); 5977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->setBuffer("buffer", buffer); 59887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar mCSDsToSubmit.removeAt(0); 59956097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia if (!onInputBufferFetched(msg)) { 60056097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia handleError(UNKNOWN_ERROR); 60156097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia return false; 60256097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia } 6032245fc625910e47d1ba3c339e205c21ab58a47adWei Jia return true; 6042245fc625910e47d1ba3c339e205c21ab58a47adWei Jia } 6052245fc625910e47d1ba3c339e205c21ab58a47adWei Jia 6062245fc625910e47d1ba3c339e205c21ab58a47adWei Jia while (!mPendingInputMessages.empty()) { 6072245fc625910e47d1ba3c339e205c21ab58a47adWei Jia sp<AMessage> msg = *mPendingInputMessages.begin(); 6087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!onInputBufferFetched(msg)) { 6092245fc625910e47d1ba3c339e205c21ab58a47adWei Jia break; 6102245fc625910e47d1ba3c339e205c21ab58a47adWei Jia } 6112245fc625910e47d1ba3c339e205c21ab58a47adWei Jia mPendingInputMessages.erase(mPendingInputMessages.begin()); 6122245fc625910e47d1ba3c339e205c21ab58a47adWei Jia } 6132245fc625910e47d1ba3c339e205c21ab58a47adWei Jia 614421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (!mInputBufferIsDequeued.editItemAt(index)) { 61587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar return true; 61687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 61787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 618421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mDequeuedInputBuffers.push_back(index); 6197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onRequestInputBuffers(); 6211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return true; 6221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 6231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 624421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnOutputBuffer( 625421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t index, 626421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t offset, 627421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t size, 628421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int64_t timeUs, 629421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t flags) { 630421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen// CHECK_LT(bufferIx, mOutputBuffers.size()); 631421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<ABuffer> buffer; 632421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->getOutputBuffer(index, &buffer); 6337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 634421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (index >= mOutputBuffers.size()) { 635421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen for (size_t i = mOutputBuffers.size(); i <= index; ++i) { 636421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mOutputBuffers.add(); 637095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 638095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 639095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 640421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mOutputBuffers.editItemAt(index) = buffer; 641421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 6427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->setRange(offset, size); 6437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->meta()->clear(); 6447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->meta()->setInt64("timeUs", timeUs); 64566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 64666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang bool eos = flags & MediaCodec::BUFFER_FLAG_EOS; 6477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // we do not expect CODECCONFIG or SYNCFRAME for decoder 6487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6491d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this); 650421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen reply->setSize("buffer-ix", index); 6517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("generation", mBufferGeneration); 6527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 65366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (eos) { 65466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video"); 65566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 65666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang buffer->meta()->setInt32("eos", true); 65766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang reply->setInt32("eos", true); 65866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } else if (mSkipRenderingUntilMediaTimeUs >= 0) { 6597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (timeUs < mSkipRenderingUntilMediaTimeUs) { 6607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] dropping buffer at time %lld as requested.", 6617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), (long long)timeUs); 6627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->post(); 6647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return true; 6657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mSkipRenderingUntilMediaTimeUs = -1; 6687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 670e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumFramesTotal += !mIsAudio; 671e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan 672f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang // wait until 1st frame comes out to signal resume complete 673f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notifyResumeCompleteIfNecessary(); 674f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 6757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mRenderer != NULL) { 6767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // send the buffer to renderer. 6777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->queueBuffer(mIsAudio, buffer, reply); 67866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (eos && !isDiscontinuityPending()) { 6797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM); 6807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return true; 6847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 6857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 686421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleOutputFormatChange(const sp<AMessage> &format) { 687421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (!mIsAudio) { 688e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan int32_t width, height; 689e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan if (format->findInt32("width", &width) 690e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan && format->findInt32("height", &height)) { 691e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("width", width); 692e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("height", height); 693e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan } 694421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> notify = mNotify->dup(); 695421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setInt32("what", kWhatVideoSizeChanged); 696421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setMessage("format", format); 697421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->post(); 698421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } else if (mRenderer != NULL) { 699421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen uint32_t flags; 700421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int64_t durationUs; 701421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen bool hasVideo = (mSource->getFormat(false /* audio */) != NULL); 702288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung if (getAudioDeepBufferSetting() // override regardless of source duration 703288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung || (!hasVideo 704288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung && mSource->getDuration(&durationUs) == OK 705288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung && durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US)) { 706421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 707421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } else { 708421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen flags = AUDIO_OUTPUT_FLAG_NONE; 709421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 710421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 711216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent status_t err = mRenderer->openAudioSink( 712421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaed */); 713216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent if (err != OK) { 714216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent handleError(err); 715216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent } 716421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 717421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen} 718421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 7197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::releaseAndResetMediaBuffers() { 7207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mMediaBuffers.size(); i++) { 7217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mMediaBuffers[i] != NULL) { 7227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers[i]->release(); 7237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers.editItemAt(i) = NULL; 7247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers.resize(mInputBuffers.size()); 7277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mMediaBuffers.size(); i++) { 7287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers.editItemAt(i) = NULL; 7297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mInputBufferIsDequeued.clear(); 7317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mInputBufferIsDequeued.resize(mInputBuffers.size()); 7327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) { 7337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mInputBufferIsDequeued.editItemAt(i) = false; 7347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingInputMessages.clear(); 7377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mDequeuedInputBuffers.clear(); 7387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mSkipRenderingUntilMediaTimeUs = -1; 7397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 7407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::requestCodecNotification() { 7427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCodec != NULL) { 7431d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> reply = new AMessage(kWhatCodecNotify, this); 7447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("generation", mBufferGeneration); 7457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCodec->requestActivityNotification(reply); 7467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 7487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) { 7507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t generation; 7517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findInt32("generation", &generation)); 7527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return generation != mBufferGeneration; 7537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 7547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) { 7567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> accessUnit; 7577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool dropAccessUnit; 7587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang do { 7597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit); 7607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err == -EWOULDBLOCK) { 7627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return err; 7637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (err != OK) { 7647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err == INFO_DISCONTINUITY) { 7657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t type; 7667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); 7677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool formatChange = 7697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (mIsAudio && 7707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT)) 7717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang || (!mIsAudio && 7727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT)); 7737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; 7757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGI("%s discontinuity (format=%d, time=%d)", 7777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio ? "audio" : "video", formatChange, timeChange); 7787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool seamlessFormatChange = false; 7807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> newFormat = mSource->getFormat(mIsAudio); 7817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (formatChange) { 7827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang seamlessFormatChange = 7837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang supportsSeamlessFormatChange(newFormat); 7847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // treat seamless format change separately 7857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang formatChange = !seamlessFormatChange; 7867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 78866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // For format or time change, return EOS to queue EOS input, 78966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // then wait for EOS on output. 7907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (formatChange /* not seamless */) { 7917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mFormatChangePending = true; 79266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang err = ERROR_END_OF_STREAM; 7937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (timeChange) { 7947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang rememberCodecSpecificData(newFormat); 79566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending = true; 79666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang err = ERROR_END_OF_STREAM; 7977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (seamlessFormatChange) { 7987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // reuse existing decoder and don't flush 7997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang rememberCodecSpecificData(newFormat); 80066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang continue; 8017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else { 8027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // This stream is unaffected by the discontinuity 8037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return -EWOULDBLOCK; 8047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 80766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // reply should only be returned without a buffer set 80866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // when there is an error (including EOS) 80966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang CHECK(err != OK); 81066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 8117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("err", err); 81266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang return ERROR_END_OF_STREAM; 8137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang dropAccessUnit = false; 816bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (!mIsAudio && !mIsSecure) { 817bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan int32_t layerId = 0; 8189fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar bool haveLayerId = accessUnit->meta()->findInt32("temporal-layer-id", &layerId); 819bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (mRenderer->getVideoLateByUs() > 100000ll 820bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan && mIsVideoAVC 821bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan && !IsAVCReferenceFrame(accessUnit)) { 822bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan dropAccessUnit = true; 8239fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar } else if (haveLayerId && mNumVideoTemporalLayerTotal > 1) { 824bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan // Add only one layer each time. 825bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (layerId > mCurrentMaxVideoTemporalLayerId + 1 826bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan || layerId >= mNumVideoTemporalLayerAllowed) { 827bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan dropAccessUnit = true; 828bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan ALOGV("dropping layer(%d), speed=%g, allowed layer count=%d, max layerId=%d", 829bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan layerId, mPlaybackSpeed, mNumVideoTemporalLayerAllowed, 830bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mCurrentMaxVideoTemporalLayerId); 831bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } else if (layerId > mCurrentMaxVideoTemporalLayerId) { 832bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan mCurrentMaxVideoTemporalLayerId = layerId; 8339fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar } else if (layerId == 0 && mNumVideoTemporalLayerTotal > 1 && IsIDR(accessUnit)) { 8349fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar mCurrentMaxVideoTemporalLayerId = mNumVideoTemporalLayerTotal - 1; 835bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 836bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 837bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan if (dropAccessUnit) { 8389fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar if (layerId <= mCurrentMaxVideoTemporalLayerId && layerId > 0) { 8399fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar mCurrentMaxVideoTemporalLayerId = layerId - 1; 8409fb815244cc33927e14ce0fe70539786a611daf9Lajos Molnar } 841bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan ++mNumInputFramesDropped; 842bbaa144657862e424ed6a199edbd36b5a93c93adPraveen Chavan } 8437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } while (dropAccessUnit); 8457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video"); 8477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#if 0 8487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int64_t mediaTimeUs; 8497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); 8505abbd3dcbb0bb32a3d4b90dddbcf90458967eb6fChong Zhang ALOGV("[%s] feeding input buffer at media time %.3f", 8517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio ? "audio" : "video", 8527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaTimeUs / 1E6); 8537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#endif 8547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCCDecoder != NULL) { 8567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder->decode(accessUnit); 8577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setBuffer("buffer", accessUnit); 8607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return OK; 8627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 8637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) { 8657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t bufferIx; 8667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findSize("buffer-ix", &bufferIx)); 8677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK_LT(bufferIx, mInputBuffers.size()); 8687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> codecBuffer = mInputBuffers[bufferIx]; 8697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> buffer; 8717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool hasBuffer = msg->findBuffer("buffer", &buffer); 8727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // handle widevine classic source - that fills an arbitrary input buffer 8747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang MediaBuffer *mediaBuffer = NULL; 8757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (hasBuffer) { 8767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer = (MediaBuffer *)(buffer->getMediaBufferBase()); 8777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mediaBuffer != NULL) { 8787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // likely filled another buffer than we requested: adjust buffer index 8797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t ix; 8807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (ix = 0; ix < mInputBuffers.size(); ix++) { 8817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<ABuffer> &buf = mInputBuffers[ix]; 8827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (buf->data() == mediaBuffer->data()) { 8837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // all input buffers are dequeued on start, hence the check 8847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mInputBufferIsDequeued[ix]) { 8857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu", 8867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), ix, bufferIx); 8877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer->release(); 8887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return false; 8897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // TRICKY: need buffer for the metadata, so instead, set 8927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // codecBuffer to the same (though incorrect) buffer to 8937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // avoid a memcpy into the codecBuffer 8947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang codecBuffer = buffer; 8957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang codecBuffer->setRange( 8967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer->range_offset(), 8977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer->range_length()); 8987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bufferIx = ix; 8997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 9007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 9017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 9027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(ix < mInputBuffers.size()); 9037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 9047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 9057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 9067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (buffer == NULL /* includes !hasBuffer */) { 9077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t streamErr = ERROR_END_OF_STREAM; 9087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); 9097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 91066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang CHECK(streamErr != OK); 9111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 9121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // attempt to queue EOS 9131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err = mCodec->queueInputBuffer( 9141cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar bufferIx, 9151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 9161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 9171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 9181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar MediaCodec::BUFFER_FLAG_EOS); 919cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung if (err == OK) { 920cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mInputBufferIsDequeued.editItemAt(bufferIx) = false; 921cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } else if (streamErr == ERROR_END_OF_STREAM) { 9221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar streamErr = err; 9231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // err will not be ERROR_END_OF_STREAM 9241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 9251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 9261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (streamErr != ERROR_END_OF_STREAM) { 927cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung ALOGE("Stream error for %s (err=%d), EOS %s queued", 928cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mComponentName.c_str(), 929cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung streamErr, 930cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung err == OK ? "successfully" : "unsuccessfully"); 9311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(streamErr); 9321cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 9331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else { 934c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia sp<AMessage> extra; 935c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) { 936c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia int64_t resumeAtMediaTimeUs; 937c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (extra->findInt64( 938c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) { 939c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia ALOGI("[%s] suppressing rendering until %lld us", 940c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mComponentName.c_str(), (long long)resumeAtMediaTimeUs); 941c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs; 942c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 943c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 944c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 9451cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int64_t timeUs = 0; 9461cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar uint32_t flags = 0; 9471cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 9481cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 94987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar int32_t eos, csd; 95087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar // we do not expect SYNCFRAME for decoder 9511cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (buffer->meta()->findInt32("eos", &eos) && eos) { 9521cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar flags |= MediaCodec::BUFFER_FLAG_EOS; 95387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } else if (buffer->meta()->findInt32("csd", &csd) && csd) { 95487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; 9551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 9561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 9571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // copy into codec buffer 9581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (buffer != codecBuffer) { 95956097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia if (buffer->size() > codecBuffer->capacity()) { 96056097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia handleError(ERROR_BUFFER_TOO_SMALL); 96156097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia mDequeuedInputBuffers.push_back(bufferIx); 96256097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia return false; 96356097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia } 9641cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar codecBuffer->setRange(0, buffer->size()); 9651cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar memcpy(codecBuffer->data(), buffer->data(), buffer->size()); 9661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 9671cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 9681cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err = mCodec->queueInputBuffer( 9691cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar bufferIx, 9701cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar codecBuffer->offset(), 9711cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar codecBuffer->size(), 9721cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar timeUs, 9731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar flags); 9741cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 975cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung if (mediaBuffer != NULL) { 976cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mediaBuffer->release(); 977cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } 9781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to queue input buffer for %s (err=%d)", 9791cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), err); 9801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 981cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } else { 982cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mInputBufferIsDequeued.editItemAt(bufferIx) = false; 983cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung if (mediaBuffer != NULL) { 984cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung CHECK(mMediaBuffers[bufferIx] == NULL); 985cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mMediaBuffers.editItemAt(bufferIx) = mediaBuffer; 986cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } 987095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 9892245fc625910e47d1ba3c339e205c21ab58a47adWei Jia return true; 990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 9921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) { 9931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err; 9941cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int32_t render; 9951cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar size_t bufferIx; 99666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang int32_t eos; 9971cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(msg->findSize("buffer-ix", &bufferIx)); 998c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 9997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mIsAudio) { 1000c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia int64_t timeUs; 1001c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia sp<ABuffer> buffer = mOutputBuffers[bufferIx]; 1002c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia buffer->meta()->findInt64("timeUs", &timeUs); 10037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 10047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCCDecoder != NULL && mCCDecoder->isSelected()) { 10057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder->display(timeUs); 10067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1007c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 1008c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 10091cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (msg->findInt32("render", &render) && render) { 1010dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t timestampNs; 1011dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar CHECK(msg->findInt64("timestampNs", ×tampNs)); 1012dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs); 10131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else { 1014e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumOutputFramesDropped += !mIsAudio; 10151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar err = mCodec->releaseOutputBuffer(bufferIx); 10161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 10171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 10181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("failed to release output buffer for %s (err=%d)", 10191cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), err); 10201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 102266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (msg->findInt32("eos", &eos) && eos 102366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang && isDiscontinuityPending()) { 102466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang finishHandleDiscontinuity(true /* flushOnTimeChange */); 102566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } 102666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang} 102766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 102866704af4d82c2b6303609b29402641f861fdcb19Chong Zhangbool NuPlayer::Decoder::isDiscontinuityPending() const { 102966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang return mFormatChangePending || mTimeChangePending; 103066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang} 103166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 103266704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) { 103366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang ALOGV("finishHandleDiscontinuity: format %d, time %d, flush %d", 103466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mFormatChangePending, mTimeChangePending, flushOnTimeChange); 103566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 103666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // If we have format change, pause and wait to be killed; 103766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // If we have time change only, flush and restart fetching. 103866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 103966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (mFormatChangePending) { 104066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mPaused = true; 104166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } else if (mTimeChangePending) { 104266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (flushOnTimeChange) { 1043421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen doFlush(false /* notifyComplete */); 1044421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen signalResume(false /* notifyComplete */); 104566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } 104666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } 104766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 104866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // Notify NuPlayer to either shutdown decoder, or rescan sources 104966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang sp<AMessage> msg = mNotify->dup(); 105066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang msg->setInt32("what", kWhatInputDiscontinuity); 105166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang msg->setInt32("formatChange", mFormatChangePending); 105266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang msg->post(); 105366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 105466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mFormatChangePending = false; 105566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending = false; 1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 10587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::supportsSeamlessAudioFormatChange( 10597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<AMessage> &targetFormat) const { 10606d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (targetFormat == NULL) { 10616d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return true; 10626d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 10636d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 10646d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih AString mime; 10656d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (!targetFormat->findString("mime", &mime)) { 10666d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 10676d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 10686d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 10696d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 10706d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih // field-by-field comparison 10716d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih const char * keys[] = { "channel-count", "sample-rate", "is-adts" }; 10726d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) { 10736d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih int32_t oldVal, newVal; 10747abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (!mInputFormat->findInt32(keys[i], &oldVal) || 10751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar !targetFormat->findInt32(keys[i], &newVal) || 10761cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar oldVal != newVal) { 10776d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 10786d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 10796d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 10806d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 10816d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih sp<ABuffer> oldBuf, newBuf; 10827abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (mInputFormat->findBuffer("csd-0", &oldBuf) && 10831cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar targetFormat->findBuffer("csd-0", &newBuf)) { 10846d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (oldBuf->size() != newBuf->size()) { 10856d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 10866d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 10876d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size()); 10886d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 10896d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 10906d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 10916d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih} 10926d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 10936d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shihbool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const { 10947abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (mInputFormat == NULL) { 10956d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 10966d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 10976d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 10986d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (targetFormat == NULL) { 10996d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return true; 11006d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 11016d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 11026d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih AString oldMime, newMime; 11037abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (!mInputFormat->findString("mime", &oldMime) 11046d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih || !targetFormat->findString("mime", &newMime) 11056d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih || !(oldMime == newMime)) { 11066d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 11076d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 11086d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 11096d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/")); 11106d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih bool seamless; 11116d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (audio) { 11126d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih seamless = supportsSeamlessAudioFormatChange(targetFormat); 11136d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } else { 11141cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int32_t isAdaptive; 11151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar seamless = (mCodec != NULL && 11161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mInputFormat->findInt32("adaptive-playback", &isAdaptive) && 11171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar isAdaptive); 11186d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 11196d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 11206d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str()); 11216d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return seamless; 11226d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih} 11236d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 11247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) { 11257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (format == NULL) { 1126a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang return; 1127a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 11287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCSDsForCurrentFormat.clear(); 11297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (int32_t i = 0; ; ++i) { 11307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang AString tag = "csd-"; 11317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang tag.append(i); 11327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> buffer; 11337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!format->findBuffer(tag.c_str(), &buffer)) { 11347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 11357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 11367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCSDsForCurrentFormat.push(buffer); 1137a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 1138b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang} 1139b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 1140f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::notifyResumeCompleteIfNecessary() { 1141f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang if (mResumePending) { 1142f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending = false; 1143f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 1144f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang sp<AMessage> notify = mNotify->dup(); 1145f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notify->setInt32("what", kWhatResumeCompleted); 1146f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notify->post(); 1147f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang } 1148f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang} 1149f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} // namespace android 1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1152