1f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/* 27137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang * Copyright 2014 The Android Open Source Project 3f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 4f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * you may not use this file except in compliance with the License. 6f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * You may obtain a copy of the License at 7f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 8f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 10f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Unless required by applicable law or agreed to in writing, software 11f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * See the License for the specific language governing permissions and 14f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * limitations under the License. 15f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 16f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0 18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "NuPlayerDecoder" 19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Log.h> 201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <inttypes.h> 21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "NuPlayerCCDecoder.h" 23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerDecoder.h" 24c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerRenderer.h" 25c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia#include "NuPlayerSource.h" 26c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 27288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung#include <cutils/properties.h> 281cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/ICrypto.h> 29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h> 315bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <media/stagefright/foundation/AMessage.h> 32095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <media/stagefright/MediaBuffer.h> 331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaCodec.h> 34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h> 351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaErrors.h> 36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 371de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h> 381de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar 397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "avc_utils.h" 407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "ATSParser.h" 417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 42f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android { 43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 44288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hungstatic inline bool getAudioDeepBufferSetting() { 45288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung return property_get_bool("media.stagefright.audio.deep", false /* default_value */); 46288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung} 47288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung 48f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::Decoder( 491173118eace0e9e347cb007f0da817cee87579edGlenn Kasten const sp<AMessage> ¬ify, 50c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia const sp<Source> &source, 5168845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu pid_t pid, 52c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia const sp<Renderer> &renderer, 531de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar const sp<Surface> &surface, 547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<CCDecoder> &ccDecoder) 55202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung : DecoderBase(notify), 561de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar mSurface(surface), 57c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSource(source), 58c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mRenderer(renderer), 597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder(ccDecoder), 6068845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu mPid(pid), 61c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSkipRenderingUntilMediaTimeUs(-1ll), 627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNumFramesTotal(0ll), 63e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumInputFramesDropped(0ll), 64e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumOutputFramesDropped(0ll), 65e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mVideoWidth(0), 66e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mVideoHeight(0), 677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio(true), 687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsVideoAVC(false), 697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsSecure(false), 707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mFormatChangePending(false), 7166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending(false), 72f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending(false), 731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName("decoder") { 741cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodecLooper = new ALooper; 759e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen mCodecLooper->setName("NPDecoder-CL"); 761cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 79f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::~Decoder() { 80faeb0f291330134dc4468359a36e099aae508449Ronghua Wu mCodec->release(); 814923cee4fb3b29538d8f46bceeea7d5128242a71Wei Jia releaseAndResetMediaBuffers(); 82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 84e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavansp<AMessage> NuPlayer::Decoder::getStats() const { 85e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt64("frames-total", mNumFramesTotal); 86e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt64("frames-dropped-input", mNumInputFramesDropped); 87e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt64("frames-dropped-output", mNumOutputFramesDropped); 88e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan return mStats; 897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 90095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 91a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnarstatus_t NuPlayer::Decoder::setVideoSurface(const sp<Surface> &surface) { 92a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (surface == NULL || ADebug::isExperimentEnabled("legacy-setsurface")) { 93a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar return BAD_VALUE; 94a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 95a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 96a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this); 97a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 98a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar msg->setObject("surface", surface); 99a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<AMessage> response; 100a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar status_t err = msg->postAndAwaitResponse(&response); 101a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (err == OK && response != NULL) { 102a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar CHECK(response->findInt32("err", &err)); 103a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 104a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar return err; 105a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar} 106a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 1077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { 1087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str()); 109095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 1107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang switch (msg->what()) { 1117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang case kWhatCodecNotify: 1127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang { 1133b032b3865fd93173aadca0591eeea32853206f9Chong Zhang int32_t cbID; 1143b032b3865fd93173aadca0591eeea32853206f9Chong Zhang CHECK(msg->findInt32("callbackID", &cbID)); 1153b032b3865fd93173aadca0591eeea32853206f9Chong Zhang 1163b032b3865fd93173aadca0591eeea32853206f9Chong Zhang ALOGV("[%s] kWhatCodecNotify: cbID = %d, paused = %d", 1173b032b3865fd93173aadca0591eeea32853206f9Chong Zhang mIsAudio ? "audio" : "video", cbID, mPaused); 1183b032b3865fd93173aadca0591eeea32853206f9Chong Zhang 119421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (mPaused) { 120421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 121421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 122421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 123421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen switch (cbID) { 124421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_INPUT_AVAILABLE: 125421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 126421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t index; 127421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("index", &index)); 128095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 129421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleAnInputBuffer(index); 130421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 131421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 132421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 133421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_OUTPUT_AVAILABLE: 134421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 135421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t index; 136421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t offset; 137421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t size; 138421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int64_t timeUs; 139421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t flags; 140421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 141421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("index", &index)); 142421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findSize("offset", &offset)); 143421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findSize("size", &size)); 144421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt64("timeUs", &timeUs)); 145421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("flags", &flags)); 146421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 147421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleAnOutputBuffer(index, offset, size, timeUs, flags); 148421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 1497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 150095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 151421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_OUTPUT_FORMAT_CHANGED: 152421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 153421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> format; 154421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findMessage("format", &format)); 155421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 156421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleOutputFormatChange(format); 157421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 1587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 160421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen case MediaCodec::CB_ERROR: 161421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 162421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen status_t err; 163421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen CHECK(msg->findInt32("err", &err)); 164421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen ALOGE("Decoder (%s) reported error : 0x%x", 165421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mIsAudio ? "audio" : "video", err); 166421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 167421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen handleError(err); 168421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 1697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 171421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen default: 172421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen { 173421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen TRESPASS(); 174421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen break; 175421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 1767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 17887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar break; 17987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 1807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang case kWhatRenderBuffer: 1827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang { 1837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!isStaleReply(msg)) { 1847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onRenderBuffer(msg); 1857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 1877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 189a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar case kWhatSetVideoSurface: 190a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar { 191a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<AReplyToken> replyID; 192a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 193a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 194a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<RefBase> obj; 195a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar CHECK(msg->findObject("surface", &obj)); 196a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<Surface> surface = static_cast<Surface *>(obj.get()); // non-null 197a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar int32_t err = INVALID_OPERATION; 198a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // NOTE: in practice mSurface is always non-null, but checking here for completeness 199a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (mCodec != NULL && mSurface != NULL) { 200a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // TODO: once AwesomePlayer is removed, remove this automatic connecting 201a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // to the surface by MediaPlayerService. 202a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // 203a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // at this point MediaPlayerService::client has already connected to the 204a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // surface, which MediaCodec does not expect 205a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar err = native_window_api_disconnect(surface.get(), NATIVE_WINDOW_API_MEDIA); 206a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (err == OK) { 207a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar err = mCodec->setSurface(surface); 208a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar ALOGI_IF(err, "codec setSurface returned: %d", err); 209a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (err == OK) { 210a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // reconnect to the old surface as MPS::Client will expect to 211a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // be able to disconnect from it. 212a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar (void)native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_MEDIA); 213a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar mSurface = surface; 214a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 215a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 216a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar if (err != OK) { 217a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // reconnect to the new surface on error as MPS::Client will expect to 218a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar // be able to disconnect from it. 219a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar (void)native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA); 220a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 221a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 222a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 223a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar sp<AMessage> response = new AMessage; 224a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar response->setInt32("err", err); 225a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar response->postReply(replyID); 226a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar break; 227a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar } 228a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar 2297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang default: 2307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang DecoderBase::onMessageReceived(msg); 2317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 23287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 23387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar} 23487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 2351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { 236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mCodec == NULL); 237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mFormatChangePending = false; 23966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending = false; 2407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2411cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ++mBufferGeneration; 2421cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 243840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber AString mime; 244840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(format->findString("mime", &mime)); 245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio = !strncasecmp("audio/", mime.c_str(), 6); 2477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str()); 2487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName = mime; 2501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.append(" decoder"); 2511de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mSurface.get()); 252840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 25368845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu mCodec = MediaCodec::CreateByType( 25468845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu mCodecLooper, mime.c_str(), false /* encoder */, NULL /* err */, mPid); 255095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar int32_t secure = 0; 256095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (format->findInt32("secure", &secure) && secure != 0) { 257095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (mCodec != NULL) { 258095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec->getName(&mComponentName); 259095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mComponentName.append(".secure"); 260095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec->release(); 261095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGI("[%s] creating", mComponentName.c_str()); 262095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec = MediaCodec::CreateByComponentName( 26368845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu mCodecLooper, mComponentName.c_str(), NULL /* err */, mPid); 264095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 265095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 2661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mCodec == NULL) { 267095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGE("Failed to create %s%s decoder", 268095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar (secure ? "secure " : ""), mime.c_str()); 2691cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(UNKNOWN_ERROR); 2701cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 271840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 2727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsSecure = secure; 273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2741cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodec->getName(&mComponentName); 2751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 27614986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar status_t err; 2771de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar if (mSurface != NULL) { 2781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // disconnect from surface as MediaCodec will reconnect 27914986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar err = native_window_api_disconnect( 2801de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar mSurface.get(), NATIVE_WINDOW_API_MEDIA); 28114986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar // We treat this as a warning, as this is a preparatory step. 28214986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar // Codec will try to connect to the surface, which is where 28314986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar // any error signaling will occur. 28414986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err); 2851cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 28614986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar err = mCodec->configure( 2871de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar format, mSurface, NULL /* crypto */, 0 /* flags */); 2881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 2891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err); 2902abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec->release(); 2912abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec.clear(); 2921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 2931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 2941cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 29587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar rememberCodecSpecificData(format); 29687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 2971cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // the following should work in configured state 2981cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat)); 2991cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat)); 3001cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 301e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setString("mime", mime.c_str()); 302e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setString("component-name", mComponentName.c_str()); 303e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan 304e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan if (!mIsAudio) { 305e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan int32_t width, height; 306e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan if (mOutputFormat->findInt32("width", &width) 307e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan && mOutputFormat->findInt32("height", &height)) { 308e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("width", width); 309e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("height", height); 310e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan } 311e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan } 312e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan 313421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> reply = new AMessage(kWhatCodecNotify, this); 314421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->setCallback(reply); 315421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 3161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar err = mCodec->start(); 3171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 3181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err); 3192abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec->release(); 3202abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec.clear(); 3211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 3221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 325095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar releaseAndResetMediaBuffers(); 326078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 327704e72658b1082264a26a83c50046da34f07d1a1Wei Jia mPaused = false; 328f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending = false; 3291cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 330078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 3318db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wuvoid NuPlayer::Decoder::onSetParameters(const sp<AMessage> ¶ms) { 3328db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu if (mCodec == NULL) { 3338db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu ALOGW("onSetParameters called before codec is created."); 3348db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu return; 3358db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu } 3368db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu mCodec->setParameters(params); 3378db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu} 3388db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu 3397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) { 3407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool hadNoRenderer = (mRenderer == NULL); 3417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer = renderer; 3427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (hadNoRenderer && mRenderer != NULL) { 343e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // this means that the widevine legacy source is ready 344e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar onRequestInputBuffers(); 34581e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia } 3467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 3477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 3487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onGetInputBuffers( 3497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang Vector<sp<ABuffer> > *dstBuffers) { 350e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getWidevineLegacyBuffers(dstBuffers)); 3517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 3522245fc625910e47d1ba3c339e205c21ab58a47adWei Jia 353f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::onResume(bool notifyComplete) { 3547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPaused = false; 355f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 356f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang if (notifyComplete) { 357f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending = true; 358f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang } 359421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->start(); 360095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar} 361095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 36266704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::doFlush(bool notifyComplete) { 3637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCCDecoder != NULL) { 3647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder->flush(); 3657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 3677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mRenderer != NULL) { 3687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->flush(mIsAudio, notifyComplete); 3697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->signalTimeDiscontinuity(); 3707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 3727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 3731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mCodec != NULL) { 3747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = mCodec->flush(); 3757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator 3767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ++mBufferGeneration; 377078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 378078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 3797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err != OK) { 3807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err); 3817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang handleError(err); 3827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // finish with posting kWhatFlushCompleted. 3837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // we attempt to release the buffers even if flush fails. 3847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang releaseAndResetMediaBuffers(); 386421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mPaused = true; 38766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang} 388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 389421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 39066704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::onFlush() { 39166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang doFlush(true); 39266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 39366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (isDiscontinuityPending()) { 39466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // This could happen if the client starts seeking/shutdown 39566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // after we queued an EOS for discontinuities. 39666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // We can consider discontinuity handled. 39766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang finishHandleDiscontinuity(false /* flushOnTimeChange */); 3987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 39966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 40066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang sp<AMessage> notify = mNotify->dup(); 40166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang notify->setInt32("what", kWhatFlushCompleted); 40266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang notify->post(); 403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onShutdown(bool notifyComplete) { 4067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 407f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 408f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang // if there is a pending resume request, notify complete now 409f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notifyResumeCompleteIfNecessary(); 410f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 4117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCodec != NULL) { 4127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = mCodec->release(); 4137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCodec = NULL; 4147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ++mBufferGeneration; 4151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 4161de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar if (mSurface != NULL) { 4177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // reconnect to surface as MediaCodec disconnected from it 4187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t error = 4191de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_MEDIA); 4207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGW_IF(error != NO_ERROR, 4217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang "[%s] failed to connect to native window, error=%d", 4227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), error); 4237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName = "decoder"; 4257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 4277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang releaseAndResetMediaBuffers(); 4287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 4297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err != OK) { 4307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err); 4317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang handleError(err); 4327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // finish with posting kWhatShutdownCompleted. 4337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 434c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 4357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (notifyComplete) { 4367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> notify = mNotify->dup(); 4377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->setInt32("what", kWhatShutdownCompleted); 4387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->post(); 4397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPaused = true; 4407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 44187603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar} 44287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 4433b032b3865fd93173aadca0591eeea32853206f9Chong Zhang/* 4443b032b3865fd93173aadca0591eeea32853206f9Chong Zhang * returns true if we should request more data 4453b032b3865fd93173aadca0591eeea32853206f9Chong Zhang */ 4463b032b3865fd93173aadca0591eeea32853206f9Chong Zhangbool NuPlayer::Decoder::doRequestBuffers() { 447e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // mRenderer is only NULL if we have a legacy widevine source that 448e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // is not yet ready. In this case we must not fetch input. 449e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar if (isDiscontinuityPending() || mRenderer == NULL) { 4503b032b3865fd93173aadca0591eeea32853206f9Chong Zhang return false; 4517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 45366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang while (err == OK && !mDequeuedInputBuffers.empty()) { 4547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t bufferIx = *mDequeuedInputBuffers.begin(); 4557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = new AMessage(); 4567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->setSize("buffer-ix", bufferIx); 4577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = fetchInputData(msg); 45866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (err != OK && err != ERROR_END_OF_STREAM) { 45966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // if EOS, need to queue EOS buffer 4607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 4617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin()); 4637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 4647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mPendingInputMessages.empty() 4657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang || !onInputBufferFetched(msg)) { 4667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingInputMessages.push_back(msg); 4677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 469095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 4703b032b3865fd93173aadca0591eeea32853206f9Chong Zhang return err == -EWOULDBLOCK 4713b032b3865fd93173aadca0591eeea32853206f9Chong Zhang && mSource->feedMoreTSData() == OK; 472095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar} 473095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 474421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleError(int32_t err) 475421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen{ 476421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen // We cannot immediately release the codec due to buffers still outstanding 477421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen // in the renderer. We signal to the player the error so it can shutdown/release the 478421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen // decoder after flushing and increment the generation to discard unnecessary messages. 479421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 480421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen ++mBufferGeneration; 481421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 482421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> notify = mNotify->dup(); 483421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setInt32("what", kWhatError); 484421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setInt32("err", err); 485421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->post(); 486421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen} 487421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 488421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnInputBuffer(size_t index) { 48966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (isDiscontinuityPending()) { 4907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return false; 4917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 492421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 493421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<ABuffer> buffer; 494421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->getInputBuffer(index, &buffer); 495421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 4966301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia if (buffer == NULL) { 4976301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia handleError(UNKNOWN_ERROR); 4986301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia return false; 4996301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia } 5006301a5e94de3659b4e6e4910394861830f8ebfb7Wei Jia 501421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (index >= mInputBuffers.size()) { 502421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen for (size_t i = mInputBuffers.size(); i <= index; ++i) { 503421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBuffers.add(); 504421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers.add(); 505421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBufferIsDequeued.add(); 506421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers.editItemAt(i) = NULL; 507421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBufferIsDequeued.editItemAt(i) = false; 508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 5091cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 510421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBuffers.editItemAt(index) = buffer; 511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 512421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen //CHECK_LT(bufferIx, mInputBuffers.size()); 5131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 514421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (mMediaBuffers[index] != NULL) { 515421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers[index]->release(); 516421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mMediaBuffers.editItemAt(index) = NULL; 517095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 518421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mInputBufferIsDequeued.editItemAt(index) = true; 519095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 52087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar if (!mCSDsToSubmit.isEmpty()) { 5217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = new AMessage(); 522421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen msg->setSize("buffer-ix", index); 5237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 52487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0); 52587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar ALOGI("[%s] resubmitting CSD", mComponentName.c_str()); 5267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->setBuffer("buffer", buffer); 52787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar mCSDsToSubmit.removeAt(0); 52856097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia if (!onInputBufferFetched(msg)) { 52956097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia handleError(UNKNOWN_ERROR); 53056097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia return false; 53156097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia } 5322245fc625910e47d1ba3c339e205c21ab58a47adWei Jia return true; 5332245fc625910e47d1ba3c339e205c21ab58a47adWei Jia } 5342245fc625910e47d1ba3c339e205c21ab58a47adWei Jia 5352245fc625910e47d1ba3c339e205c21ab58a47adWei Jia while (!mPendingInputMessages.empty()) { 5362245fc625910e47d1ba3c339e205c21ab58a47adWei Jia sp<AMessage> msg = *mPendingInputMessages.begin(); 5377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!onInputBufferFetched(msg)) { 5382245fc625910e47d1ba3c339e205c21ab58a47adWei Jia break; 5392245fc625910e47d1ba3c339e205c21ab58a47adWei Jia } 5402245fc625910e47d1ba3c339e205c21ab58a47adWei Jia mPendingInputMessages.erase(mPendingInputMessages.begin()); 5412245fc625910e47d1ba3c339e205c21ab58a47adWei Jia } 5422245fc625910e47d1ba3c339e205c21ab58a47adWei Jia 543421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (!mInputBufferIsDequeued.editItemAt(index)) { 54487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar return true; 54587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 54687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 547421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mDequeuedInputBuffers.push_back(index); 5487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onRequestInputBuffers(); 5501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return true; 5511cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 5521cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 553421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenbool NuPlayer::Decoder::handleAnOutputBuffer( 554421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t index, 555421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t offset, 556421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen size_t size, 557421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int64_t timeUs, 558421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int32_t flags) { 559421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen// CHECK_LT(bufferIx, mOutputBuffers.size()); 560421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<ABuffer> buffer; 561421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mCodec->getOutputBuffer(index, &buffer); 5627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 563421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (index >= mOutputBuffers.size()) { 564421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen for (size_t i = mOutputBuffers.size(); i <= index; ++i) { 565421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mOutputBuffers.add(); 566095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 567095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 568095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 569421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen mOutputBuffers.editItemAt(index) = buffer; 570421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 5717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->setRange(offset, size); 5727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->meta()->clear(); 5737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->meta()->setInt64("timeUs", timeUs); 57466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 57566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang bool eos = flags & MediaCodec::BUFFER_FLAG_EOS; 5767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // we do not expect CODECCONFIG or SYNCFRAME for decoder 5777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5781d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this); 579421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen reply->setSize("buffer-ix", index); 5807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("generation", mBufferGeneration); 5817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 58266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (eos) { 58366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video"); 58466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 58566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang buffer->meta()->setInt32("eos", true); 58666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang reply->setInt32("eos", true); 58766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } else if (mSkipRenderingUntilMediaTimeUs >= 0) { 5887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (timeUs < mSkipRenderingUntilMediaTimeUs) { 5897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] dropping buffer at time %lld as requested.", 5907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), (long long)timeUs); 5917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->post(); 5937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return true; 5947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mSkipRenderingUntilMediaTimeUs = -1; 5977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 599e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumFramesTotal += !mIsAudio; 600e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan 601f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang // wait until 1st frame comes out to signal resume complete 602f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notifyResumeCompleteIfNecessary(); 603f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 6047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mRenderer != NULL) { 6057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // send the buffer to renderer. 6067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->queueBuffer(mIsAudio, buffer, reply); 60766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (eos && !isDiscontinuityPending()) { 6087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM); 6097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return true; 6137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 6147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 615421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissenvoid NuPlayer::Decoder::handleOutputFormatChange(const sp<AMessage> &format) { 616421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen if (!mIsAudio) { 617e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan int32_t width, height; 618e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan if (format->findInt32("width", &width) 619e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan && format->findInt32("height", &height)) { 620e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("width", width); 621e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mStats->setInt32("height", height); 622e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan } 623421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen sp<AMessage> notify = mNotify->dup(); 624421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setInt32("what", kWhatVideoSizeChanged); 625421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->setMessage("format", format); 626421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen notify->post(); 627421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } else if (mRenderer != NULL) { 628421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen uint32_t flags; 629421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen int64_t durationUs; 630421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen bool hasVideo = (mSource->getFormat(false /* audio */) != NULL); 631288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung if (getAudioDeepBufferSetting() // override regardless of source duration 632288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung || (!hasVideo 633288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung && mSource->getDuration(&durationUs) == OK 634288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung && durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US)) { 635421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 636421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } else { 637421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen flags = AUDIO_OUTPUT_FLAG_NONE; 638421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 639421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 640216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent status_t err = mRenderer->openAudioSink( 641421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaed */); 642216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent if (err != OK) { 643216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent handleError(err); 644216f0177cbfa0d8e911d64fc17ccbb5100ad87b4Eric Laurent } 645421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen } 646421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen} 647421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 6487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::releaseAndResetMediaBuffers() { 6497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mMediaBuffers.size(); i++) { 6507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mMediaBuffers[i] != NULL) { 6517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers[i]->release(); 6527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers.editItemAt(i) = NULL; 6537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers.resize(mInputBuffers.size()); 6567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mMediaBuffers.size(); i++) { 6577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers.editItemAt(i) = NULL; 6587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mInputBufferIsDequeued.clear(); 6607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mInputBufferIsDequeued.resize(mInputBuffers.size()); 6617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) { 6627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mInputBufferIsDequeued.editItemAt(i) = false; 6637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingInputMessages.clear(); 6667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mDequeuedInputBuffers.clear(); 6677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mSkipRenderingUntilMediaTimeUs = -1; 6687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 6697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::requestCodecNotification() { 6717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCodec != NULL) { 6721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> reply = new AMessage(kWhatCodecNotify, this); 6737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("generation", mBufferGeneration); 6747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCodec->requestActivityNotification(reply); 6757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 6777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) { 6797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t generation; 6807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findInt32("generation", &generation)); 6817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return generation != mBufferGeneration; 6827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 6837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) { 6857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> accessUnit; 6867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool dropAccessUnit; 6877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang do { 6887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit); 6897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err == -EWOULDBLOCK) { 6917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return err; 6927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (err != OK) { 6937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err == INFO_DISCONTINUITY) { 6947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t type; 6957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); 6967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool formatChange = 6987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (mIsAudio && 6997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT)) 7007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang || (!mIsAudio && 7017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT)); 7027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; 7047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGI("%s discontinuity (format=%d, time=%d)", 7067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio ? "audio" : "video", formatChange, timeChange); 7077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool seamlessFormatChange = false; 7097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> newFormat = mSource->getFormat(mIsAudio); 7107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (formatChange) { 7117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang seamlessFormatChange = 7127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang supportsSeamlessFormatChange(newFormat); 7137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // treat seamless format change separately 7147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang formatChange = !seamlessFormatChange; 7157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 71766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // For format or time change, return EOS to queue EOS input, 71866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // then wait for EOS on output. 7197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (formatChange /* not seamless */) { 7207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mFormatChangePending = true; 72166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang err = ERROR_END_OF_STREAM; 7227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (timeChange) { 7237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang rememberCodecSpecificData(newFormat); 72466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending = true; 72566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang err = ERROR_END_OF_STREAM; 7267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (seamlessFormatChange) { 7277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // reuse existing decoder and don't flush 7287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang rememberCodecSpecificData(newFormat); 72966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang continue; 7307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else { 7317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // This stream is unaffected by the discontinuity 7327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return -EWOULDBLOCK; 7337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 73666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // reply should only be returned without a buffer set 73766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // when there is an error (including EOS) 73866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang CHECK(err != OK); 73966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 7407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("err", err); 74166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang return ERROR_END_OF_STREAM; 7427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang dropAccessUnit = false; 7457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mIsAudio 7467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang && !mIsSecure 7477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang && mRenderer->getVideoLateByUs() > 100000ll 7487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang && mIsVideoAVC 7497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang && !IsAVCReferenceFrame(accessUnit)) { 7507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang dropAccessUnit = true; 751e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan ++mNumInputFramesDropped; 7527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } while (dropAccessUnit); 7547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video"); 7567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#if 0 7577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int64_t mediaTimeUs; 7587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); 7595abbd3dcbb0bb32a3d4b90dddbcf90458967eb6fChong Zhang ALOGV("[%s] feeding input buffer at media time %.3f", 7607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio ? "audio" : "video", 7617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaTimeUs / 1E6); 7627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#endif 7637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCCDecoder != NULL) { 7657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder->decode(accessUnit); 7667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setBuffer("buffer", accessUnit); 7697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return OK; 7717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 7727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) { 7747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t bufferIx; 7757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findSize("buffer-ix", &bufferIx)); 7767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK_LT(bufferIx, mInputBuffers.size()); 7777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> codecBuffer = mInputBuffers[bufferIx]; 7787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> buffer; 7807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool hasBuffer = msg->findBuffer("buffer", &buffer); 7817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // handle widevine classic source - that fills an arbitrary input buffer 7837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang MediaBuffer *mediaBuffer = NULL; 7847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (hasBuffer) { 7857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer = (MediaBuffer *)(buffer->getMediaBufferBase()); 7867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mediaBuffer != NULL) { 7877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // likely filled another buffer than we requested: adjust buffer index 7887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t ix; 7897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (ix = 0; ix < mInputBuffers.size(); ix++) { 7907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<ABuffer> &buf = mInputBuffers[ix]; 7917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (buf->data() == mediaBuffer->data()) { 7927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // all input buffers are dequeued on start, hence the check 7937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mInputBufferIsDequeued[ix]) { 7947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu", 7957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), ix, bufferIx); 7967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer->release(); 7977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return false; 7987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 7997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // TRICKY: need buffer for the metadata, so instead, set 8017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // codecBuffer to the same (though incorrect) buffer to 8027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // avoid a memcpy into the codecBuffer 8037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang codecBuffer = buffer; 8047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang codecBuffer->setRange( 8057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer->range_offset(), 8067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer->range_length()); 8077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bufferIx = ix; 8087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 8097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(ix < mInputBuffers.size()); 8127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 8157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (buffer == NULL /* includes !hasBuffer */) { 8167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t streamErr = ERROR_END_OF_STREAM; 8177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); 8187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 81966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang CHECK(streamErr != OK); 8201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 8211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // attempt to queue EOS 8221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err = mCodec->queueInputBuffer( 8231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar bufferIx, 8241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 8251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 8261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 8271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar MediaCodec::BUFFER_FLAG_EOS); 828cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung if (err == OK) { 829cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mInputBufferIsDequeued.editItemAt(bufferIx) = false; 830cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } else if (streamErr == ERROR_END_OF_STREAM) { 8311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar streamErr = err; 8321cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // err will not be ERROR_END_OF_STREAM 8331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 8341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 8351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (streamErr != ERROR_END_OF_STREAM) { 836cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung ALOGE("Stream error for %s (err=%d), EOS %s queued", 837cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mComponentName.c_str(), 838cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung streamErr, 839cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung err == OK ? "successfully" : "unsuccessfully"); 8401cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(streamErr); 8411cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 8421cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else { 843c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia sp<AMessage> extra; 844c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) { 845c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia int64_t resumeAtMediaTimeUs; 846c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (extra->findInt64( 847c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) { 848c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia ALOGI("[%s] suppressing rendering until %lld us", 849c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mComponentName.c_str(), (long long)resumeAtMediaTimeUs); 850c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs; 851c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 852c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 853c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 8541cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int64_t timeUs = 0; 8551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar uint32_t flags = 0; 8561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 8571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 85887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar int32_t eos, csd; 85987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar // we do not expect SYNCFRAME for decoder 8601cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (buffer->meta()->findInt32("eos", &eos) && eos) { 8611cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar flags |= MediaCodec::BUFFER_FLAG_EOS; 86287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } else if (buffer->meta()->findInt32("csd", &csd) && csd) { 86387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; 8641cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 8651cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 8661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // copy into codec buffer 8671cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (buffer != codecBuffer) { 86856097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia if (buffer->size() > codecBuffer->capacity()) { 86956097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia handleError(ERROR_BUFFER_TOO_SMALL); 87056097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia mDequeuedInputBuffers.push_back(bufferIx); 87156097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia return false; 87256097a8ecc31ec308a1caa38f92b69f99324eadaWei Jia } 8731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar codecBuffer->setRange(0, buffer->size()); 8741cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar memcpy(codecBuffer->data(), buffer->data(), buffer->size()); 8751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 8761cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 8771cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err = mCodec->queueInputBuffer( 8781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar bufferIx, 8791cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar codecBuffer->offset(), 8801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar codecBuffer->size(), 8811cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar timeUs, 8821cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar flags); 8831cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 884cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung if (mediaBuffer != NULL) { 885cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mediaBuffer->release(); 886cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } 8871cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to queue input buffer for %s (err=%d)", 8881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), err); 8891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 890cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } else { 891cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mInputBufferIsDequeued.editItemAt(bufferIx) = false; 892cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung if (mediaBuffer != NULL) { 893cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung CHECK(mMediaBuffers[bufferIx] == NULL); 894cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mMediaBuffers.editItemAt(bufferIx) = mediaBuffer; 895cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } 896095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 8982245fc625910e47d1ba3c339e205c21ab58a47adWei Jia return true; 899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 9011cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) { 9021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err; 9031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int32_t render; 9041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar size_t bufferIx; 90566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang int32_t eos; 9061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(msg->findSize("buffer-ix", &bufferIx)); 907c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 9087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mIsAudio) { 909c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia int64_t timeUs; 910c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia sp<ABuffer> buffer = mOutputBuffers[bufferIx]; 911c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia buffer->meta()->findInt64("timeUs", &timeUs); 9127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 9137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCCDecoder != NULL && mCCDecoder->isSelected()) { 9147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder->display(timeUs); 9157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 916c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 917c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 9181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (msg->findInt32("render", &render) && render) { 919dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t timestampNs; 920dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar CHECK(msg->findInt64("timestampNs", ×tampNs)); 921dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs); 9221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else { 923e1e5d7a3d3d4d6d644e6c731f977422e004140d5Praveen Chavan mNumOutputFramesDropped += !mIsAudio; 9241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar err = mCodec->releaseOutputBuffer(bufferIx); 9251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 9261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 9271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("failed to release output buffer for %s (err=%d)", 9281cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), err); 9291cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 93166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (msg->findInt32("eos", &eos) && eos 93266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang && isDiscontinuityPending()) { 93366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang finishHandleDiscontinuity(true /* flushOnTimeChange */); 93466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } 93566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang} 93666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 93766704af4d82c2b6303609b29402641f861fdcb19Chong Zhangbool NuPlayer::Decoder::isDiscontinuityPending() const { 93866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang return mFormatChangePending || mTimeChangePending; 93966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang} 94066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 94166704af4d82c2b6303609b29402641f861fdcb19Chong Zhangvoid NuPlayer::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) { 94266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang ALOGV("finishHandleDiscontinuity: format %d, time %d, flush %d", 94366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mFormatChangePending, mTimeChangePending, flushOnTimeChange); 94466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 94566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // If we have format change, pause and wait to be killed; 94666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // If we have time change only, flush and restart fetching. 94766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 94866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (mFormatChangePending) { 94966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mPaused = true; 95066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } else if (mTimeChangePending) { 95166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang if (flushOnTimeChange) { 952421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen doFlush(false /* notifyComplete */); 953421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen signalResume(false /* notifyComplete */); 95466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } 95566704af4d82c2b6303609b29402641f861fdcb19Chong Zhang } 95666704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 95766704af4d82c2b6303609b29402641f861fdcb19Chong Zhang // Notify NuPlayer to either shutdown decoder, or rescan sources 95866704af4d82c2b6303609b29402641f861fdcb19Chong Zhang sp<AMessage> msg = mNotify->dup(); 95966704af4d82c2b6303609b29402641f861fdcb19Chong Zhang msg->setInt32("what", kWhatInputDiscontinuity); 96066704af4d82c2b6303609b29402641f861fdcb19Chong Zhang msg->setInt32("formatChange", mFormatChangePending); 96166704af4d82c2b6303609b29402641f861fdcb19Chong Zhang msg->post(); 96266704af4d82c2b6303609b29402641f861fdcb19Chong Zhang 96366704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mFormatChangePending = false; 96466704af4d82c2b6303609b29402641f861fdcb19Chong Zhang mTimeChangePending = false; 965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 9677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::supportsSeamlessAudioFormatChange( 9687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<AMessage> &targetFormat) const { 9696d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (targetFormat == NULL) { 9706d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return true; 9716d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9726d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 9736d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih AString mime; 9746d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (!targetFormat->findString("mime", &mime)) { 9756d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 9766d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9776d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 9786d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 9796d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih // field-by-field comparison 9806d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih const char * keys[] = { "channel-count", "sample-rate", "is-adts" }; 9816d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) { 9826d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih int32_t oldVal, newVal; 9837abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (!mInputFormat->findInt32(keys[i], &oldVal) || 9841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar !targetFormat->findInt32(keys[i], &newVal) || 9851cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar oldVal != newVal) { 9866d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 9876d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9886d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9896d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 9906d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih sp<ABuffer> oldBuf, newBuf; 9917abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (mInputFormat->findBuffer("csd-0", &oldBuf) && 9921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar targetFormat->findBuffer("csd-0", &newBuf)) { 9936d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (oldBuf->size() != newBuf->size()) { 9946d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 9956d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9966d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size()); 9976d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9986d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 9996d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 10006d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih} 10016d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 10026d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shihbool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const { 10037abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (mInputFormat == NULL) { 10046d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 10056d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 10066d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 10076d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (targetFormat == NULL) { 10086d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return true; 10096d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 10106d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 10116d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih AString oldMime, newMime; 10127abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (!mInputFormat->findString("mime", &oldMime) 10136d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih || !targetFormat->findString("mime", &newMime) 10146d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih || !(oldMime == newMime)) { 10156d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 10166d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 10176d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 10186d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/")); 10196d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih bool seamless; 10206d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (audio) { 10216d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih seamless = supportsSeamlessAudioFormatChange(targetFormat); 10226d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } else { 10231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int32_t isAdaptive; 10241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar seamless = (mCodec != NULL && 10251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mInputFormat->findInt32("adaptive-playback", &isAdaptive) && 10261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar isAdaptive); 10276d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 10286d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 10296d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str()); 10306d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return seamless; 10316d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih} 10326d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 10337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) { 10347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (format == NULL) { 1035a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang return; 1036a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 10377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCSDsForCurrentFormat.clear(); 10387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (int32_t i = 0; ; ++i) { 10397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang AString tag = "csd-"; 10407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang tag.append(i); 10417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> buffer; 10427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!format->findBuffer(tag.c_str(), &buffer)) { 10437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 10447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 10457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCSDsForCurrentFormat.push(buffer); 1046a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 1047b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang} 1048b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 1049f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::notifyResumeCompleteIfNecessary() { 1050f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang if (mResumePending) { 1051f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending = false; 1052f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 1053f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang sp<AMessage> notify = mNotify->dup(); 1054f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notify->setInt32("what", kWhatResumeCompleted); 1055f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notify->post(); 1056f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang } 1057f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang} 1058f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} // namespace android 1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1061