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 271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/ICrypto.h> 28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h> 305bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <media/stagefright/foundation/AMessage.h> 31095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <media/stagefright/MediaBuffer.h> 321cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaCodec.h> 33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h> 341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaErrors.h> 35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "avc_utils.h" 377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#include "ATSParser.h" 387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 39f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android { 40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 41f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::Decoder( 421173118eace0e9e347cb007f0da817cee87579edGlenn Kasten const sp<AMessage> ¬ify, 43c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia const sp<Source> &source, 44c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia const sp<Renderer> &renderer, 457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<NativeWindowWrapper> &nativeWindow, 467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<CCDecoder> &ccDecoder) 47202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung : DecoderBase(notify), 481cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mNativeWindow(nativeWindow), 49c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSource(source), 50c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mRenderer(renderer), 517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder(ccDecoder), 52c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSkipRenderingUntilMediaTimeUs(-1ll), 537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNumFramesTotal(0ll), 547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNumFramesDropped(0ll), 557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio(true), 567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsVideoAVC(false), 577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsSecure(false), 587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mFormatChangePending(false), 59704e72658b1082264a26a83c50046da34f07d1a1Wei Jia mPaused(true), 60f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending(false), 611cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName("decoder") { 621cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodecLooper = new ALooper; 639e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen mCodecLooper->setName("NPDecoder-CL"); 641cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 67f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::~Decoder() { 684923cee4fb3b29538d8f46bceeea7d5128242a71Wei Jia releaseAndResetMediaBuffers(); 69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::getStats( 727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int64_t *numFramesTotal, 737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int64_t *numFramesDropped) const { 747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang *numFramesTotal = mNumFramesTotal; 757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang *numFramesDropped = mNumFramesDropped; 767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 77095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { 797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str()); 80095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang switch (msg->what()) { 827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang case kWhatCodecNotify: 837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang { 847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!isStaleReply(msg)) { 857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t numInput, numOutput; 86095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!msg->findInt32("input-buffers", &numInput)) { 887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang numInput = INT32_MAX; 897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 90095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!msg->findInt32("output-buffers", &numOutput)) { 927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang numOutput = INT32_MAX; 937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mPaused) { 967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang while (numInput-- > 0 && handleAnInputBuffer()) {} 977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang while (numOutput-- > 0 && handleAnOutputBuffer()) {} 1007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang requestCodecNotification(); 10387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar break; 10487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 1057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang case kWhatRenderBuffer: 1077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang { 1087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!isStaleReply(msg)) { 1097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onRenderBuffer(msg); 1107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 1127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 1137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang default: 1157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang DecoderBase::onMessageReceived(msg); 1167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 11787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 11887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar} 11987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 1201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { 121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mCodec == NULL); 122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mFormatChangePending = false; 1247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ++mBufferGeneration; 1261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 127840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber AString mime; 128840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(format->findString("mime", &mime)); 129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio = !strncasecmp("audio/", mime.c_str(), 6); 1317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str()); 1327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 1331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<Surface> surface = NULL; 1341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mNativeWindow != NULL) { 1351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar surface = mNativeWindow->getSurfaceTextureClient(); 1361cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1381cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName = mime; 1391cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.append(" decoder"); 1401cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), surface.get()); 141840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1421cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodec = MediaCodec::CreateByType(mCodecLooper, mime.c_str(), false /* encoder */); 143095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar int32_t secure = 0; 144095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (format->findInt32("secure", &secure) && secure != 0) { 145095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (mCodec != NULL) { 146095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec->getName(&mComponentName); 147095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mComponentName.append(".secure"); 148095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec->release(); 149095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGI("[%s] creating", mComponentName.c_str()); 150095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec = MediaCodec::CreateByComponentName( 151095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodecLooper, mComponentName.c_str()); 152095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 153095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 1541cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mCodec == NULL) { 155095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGE("Failed to create %s%s decoder", 156095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar (secure ? "secure " : ""), mime.c_str()); 1571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(UNKNOWN_ERROR); 1581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 159840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 1607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsSecure = secure; 161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1621cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodec->getName(&mComponentName); 1631cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 16414986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar status_t err; 1651173118eace0e9e347cb007f0da817cee87579edGlenn Kasten if (mNativeWindow != NULL) { 1661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // disconnect from surface as MediaCodec will reconnect 16714986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar err = native_window_api_disconnect( 16814986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar surface.get(), NATIVE_WINDOW_API_MEDIA); 16914986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar // We treat this as a warning, as this is a preparatory step. 17014986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar // Codec will try to connect to the surface, which is where 17114986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar // any error signaling will occur. 17214986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err); 1731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 17414986f6cca08b9ab0407cc2d31f92bfb02b5cb8cLajos Molnar err = mCodec->configure( 1751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar format, surface, NULL /* crypto */, 0 /* flags */); 1761cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 1771cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err); 1782abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec->release(); 1792abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec.clear(); 1801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 1811cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 1821cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 18387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar rememberCodecSpecificData(format); 18487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 1851cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // the following should work in configured state 1861cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat)); 1871cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat)); 1881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 1891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar err = mCodec->start(); 1901cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 1911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err); 1922abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec->release(); 1932abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung mCodec.clear(); 1941cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 1951cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1981cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // the following should work after start 1991cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getInputBuffers(&mInputBuffers)); 200095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar releaseAndResetMediaBuffers(); 2011cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getOutputBuffers(&mOutputBuffers)); 2021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGV("[%s] got %zu input and %zu output buffers", 2031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), 2041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mInputBuffers.size(), 2051cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mOutputBuffers.size()); 206078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 207c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (mRenderer != NULL) { 208c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia requestCodecNotification(); 209c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 210704e72658b1082264a26a83c50046da34f07d1a1Wei Jia mPaused = false; 211f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending = false; 2121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 213078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 2147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) { 2157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool hadNoRenderer = (mRenderer == NULL); 2167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer = renderer; 2177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (hadNoRenderer && mRenderer != NULL) { 2187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang requestCodecNotification(); 21981e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia } 2207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 2217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onGetInputBuffers( 2237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang Vector<sp<ABuffer> > *dstBuffers) { 2247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang dstBuffers->clear(); 2257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mInputBuffers.size(); i++) { 2267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang dstBuffers->push(mInputBuffers[i]); 22781e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia } 2287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 2292245fc625910e47d1ba3c339e205c21ab58a47adWei Jia 230f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::onResume(bool notifyComplete) { 2317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPaused = false; 232f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 233f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang if (notifyComplete) { 234f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending = true; 235f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang } 236095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar} 237095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 2387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onFlush(bool notifyComplete) { 2397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCCDecoder != NULL) { 2407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder->flush(); 2417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mRenderer != NULL) { 2447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->flush(mIsAudio, notifyComplete); 2457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->signalTimeDiscontinuity(); 2467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 2491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mCodec != NULL) { 2507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = mCodec->flush(); 2517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator 2527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ++mBufferGeneration; 253078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 254078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 2557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err != OK) { 2567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err); 2577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang handleError(err); 2587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // finish with posting kWhatFlushCompleted. 2597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // we attempt to release the buffers even if flush fails. 2607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang releaseAndResetMediaBuffers(); 262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (notifyComplete) { 2647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> notify = mNotify->dup(); 2657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->setInt32("what", kWhatFlushCompleted); 2667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->post(); 2677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPaused = true; 2687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::onShutdown(bool notifyComplete) { 2727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 273f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 274f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang // if there is a pending resume request, notify complete now 275f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notifyResumeCompleteIfNecessary(); 276f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 2777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCodec != NULL) { 2787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = mCodec->release(); 2797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCodec = NULL; 2807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ++mBufferGeneration; 2811cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 2827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mNativeWindow != NULL) { 2837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // reconnect to surface as MediaCodec disconnected from it 2847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t error = 2857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang native_window_api_connect( 2867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mNativeWindow->getNativeWindow().get(), 2877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang NATIVE_WINDOW_API_MEDIA); 2887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGW_IF(error != NO_ERROR, 2897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang "[%s] failed to connect to native window, error=%d", 2907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), error); 2917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName = "decoder"; 2937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 2947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang releaseAndResetMediaBuffers(); 2967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 2977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err != OK) { 2987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err); 2997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang handleError(err); 3007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // finish with posting kWhatShutdownCompleted. 3017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 302c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 3037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (notifyComplete) { 3047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> notify = mNotify->dup(); 3057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->setInt32("what", kWhatShutdownCompleted); 3067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->post(); 3077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPaused = true; 3087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 30987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar} 31087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 3117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::doRequestBuffers() { 3127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mFormatChangePending) { 3137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return; 3147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = OK; 3167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang while (!mDequeuedInputBuffers.empty()) { 3177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t bufferIx = *mDequeuedInputBuffers.begin(); 3187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = new AMessage(); 3197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->setSize("buffer-ix", bufferIx); 3207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = fetchInputData(msg); 3217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err != OK) { 3227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 3237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin()); 3257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 3267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mPendingInputMessages.empty() 3277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang || !onInputBufferFetched(msg)) { 3287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingInputMessages.push_back(msg); 3297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 331095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 3327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err == -EWOULDBLOCK 3337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang && mSource->feedMoreTSData() == OK) { 3347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang scheduleRequestBuffers(); 3357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 336095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar} 337095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 3381cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarbool NuPlayer::Decoder::handleAnInputBuffer() { 3397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mFormatChangePending) { 3407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return false; 3417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3421cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar size_t bufferIx = -1; 3431cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t res = mCodec->dequeueInputBuffer(&bufferIx); 3441cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGV("[%s] dequeued input: %d", 3451cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), res == OK ? (int)bufferIx : res); 3461cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (res != OK) { 3471cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (res != -EAGAIN) { 348cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung ALOGE("Failed to dequeue input buffer for %s (err=%d)", 349cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mComponentName.c_str(), res); 3501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(res); 351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 3521cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return false; 3531cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_LT(bufferIx, mInputBuffers.size()); 3561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 357095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (mMediaBuffers[bufferIx] != NULL) { 358095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mMediaBuffers[bufferIx]->release(); 359095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mMediaBuffers.editItemAt(bufferIx) = NULL; 360095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 361095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mInputBufferIsDequeued.editItemAt(bufferIx) = true; 362095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 36387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar if (!mCSDsToSubmit.isEmpty()) { 3647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = new AMessage(); 3657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->setSize("buffer-ix", bufferIx); 3667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 36787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0); 36887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar ALOGI("[%s] resubmitting CSD", mComponentName.c_str()); 3697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->setBuffer("buffer", buffer); 37087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar mCSDsToSubmit.removeAt(0); 3717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(onInputBufferFetched(msg)); 3722245fc625910e47d1ba3c339e205c21ab58a47adWei Jia return true; 3732245fc625910e47d1ba3c339e205c21ab58a47adWei Jia } 3742245fc625910e47d1ba3c339e205c21ab58a47adWei Jia 3752245fc625910e47d1ba3c339e205c21ab58a47adWei Jia while (!mPendingInputMessages.empty()) { 3762245fc625910e47d1ba3c339e205c21ab58a47adWei Jia sp<AMessage> msg = *mPendingInputMessages.begin(); 3777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!onInputBufferFetched(msg)) { 3782245fc625910e47d1ba3c339e205c21ab58a47adWei Jia break; 3792245fc625910e47d1ba3c339e205c21ab58a47adWei Jia } 3802245fc625910e47d1ba3c339e205c21ab58a47adWei Jia mPendingInputMessages.erase(mPendingInputMessages.begin()); 3812245fc625910e47d1ba3c339e205c21ab58a47adWei Jia } 3822245fc625910e47d1ba3c339e205c21ab58a47adWei Jia 3832245fc625910e47d1ba3c339e205c21ab58a47adWei Jia if (!mInputBufferIsDequeued.editItemAt(bufferIx)) { 38487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar return true; 38587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 38687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 3877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mDequeuedInputBuffers.push_back(bufferIx); 3887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 3897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onRequestInputBuffers(); 3901cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return true; 3911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 3921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 3937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::handleAnOutputBuffer() { 3947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mFormatChangePending) { 3957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return false; 3967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 3977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t bufferIx = -1; 3987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t offset; 3997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t size; 4007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int64_t timeUs; 4017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang uint32_t flags; 4027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t res = mCodec->dequeueOutputBuffer( 4037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang &bufferIx, &offset, &size, &timeUs, &flags); 4041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 4057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (res != OK) { 4067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] dequeued output: %d", mComponentName.c_str(), res); 4077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else { 4087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] dequeued output: %d (time=%lld flags=%" PRIu32 ")", 4097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), (int)bufferIx, timeUs, flags); 4107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 411095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 4127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (res == INFO_OUTPUT_BUFFERS_CHANGED) { 4137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang res = mCodec->getOutputBuffers(&mOutputBuffers); 4147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (res != OK) { 4157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGE("Failed to get output buffers for %s after INFO event (err=%d)", 4167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), res); 4177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang handleError(res); 4187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return false; 4197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // NuPlayer ignores this 4217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return true; 4227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (res == INFO_FORMAT_CHANGED) { 4237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> format = new AMessage(); 4247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang res = mCodec->getOutputFormat(&format); 4257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (res != OK) { 4267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGE("Failed to get output format for %s after INFO event (err=%d)", 4277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), res); 4287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang handleError(res); 4297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return false; 4307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 431095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 4327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mIsAudio) { 4337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> notify = mNotify->dup(); 4347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->setInt32("what", kWhatVideoSizeChanged); 4357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->setMessage("format", format); 4367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang notify->post(); 4377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (mRenderer != NULL) { 4387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang uint32_t flags; 4397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int64_t durationUs; 4407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool hasVideo = (mSource->getFormat(false /* audio */) != NULL); 4417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!hasVideo && 4427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mSource->getDuration(&durationUs) == OK && 4437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang durationUs 4447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) { 4457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER; 4467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else { 4477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang flags = AUDIO_OUTPUT_FLAG_NONE; 448095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 4497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 450202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung res = mRenderer->openAudioSink( 451202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung format, false /* offloadOnly */, hasVideo, flags, NULL /* isOffloaded */); 452202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung if (res != OK) { 453202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung ALOGE("Failed to open AudioSink on format change for %s (err=%d)", 454202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung mComponentName.c_str(), res); 455202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung handleError(res); 456202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung return false; 457202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung } 4587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return true; 4607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (res == INFO_DISCONTINUITY) { 4617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // nothing to do 4627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return true; 4637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (res != OK) { 4647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (res != -EAGAIN) { 4657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGE("Failed to dequeue output buffer for %s (err=%d)", 4667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), res); 4677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang handleError(res); 468095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 4697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return false; 470095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 471095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 4727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK_LT(bufferIx, mOutputBuffers.size()); 4737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> buffer = mOutputBuffers[bufferIx]; 4747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->setRange(offset, size); 4757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->meta()->clear(); 4767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->meta()->setInt64("timeUs", timeUs); 4777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (flags & MediaCodec::BUFFER_FLAG_EOS) { 4787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang buffer->meta()->setInt32("eos", true); 479474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia notifyResumeCompleteIfNecessary(); 4807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // we do not expect CODECCONFIG or SYNCFRAME for decoder 4827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 4837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> reply = new AMessage(kWhatRenderBuffer, id()); 4847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setSize("buffer-ix", bufferIx); 4857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("generation", mBufferGeneration); 4867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 4877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mSkipRenderingUntilMediaTimeUs >= 0) { 4887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (timeUs < mSkipRenderingUntilMediaTimeUs) { 4897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] dropping buffer at time %lld as requested.", 4907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), (long long)timeUs); 4917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 4927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->post(); 4937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return true; 4947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 4967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mSkipRenderingUntilMediaTimeUs = -1; 4977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 4987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 499f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang // wait until 1st frame comes out to signal resume complete 500f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notifyResumeCompleteIfNecessary(); 501f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 5027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mRenderer != NULL) { 5037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // send the buffer to renderer. 5047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->queueBuffer(mIsAudio, buffer, reply); 5057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (flags & MediaCodec::BUFFER_FLAG_EOS) { 5067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM); 5077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return true; 5117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 5127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::releaseAndResetMediaBuffers() { 5147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mMediaBuffers.size(); i++) { 5157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mMediaBuffers[i] != NULL) { 5167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers[i]->release(); 5177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers.editItemAt(i) = NULL; 5187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers.resize(mInputBuffers.size()); 5217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mMediaBuffers.size(); i++) { 5227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mMediaBuffers.editItemAt(i) = NULL; 5237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mInputBufferIsDequeued.clear(); 5257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mInputBufferIsDequeued.resize(mInputBuffers.size()); 5267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) { 5277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mInputBufferIsDequeued.editItemAt(i) = false; 5287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mPendingInputMessages.clear(); 5317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mDequeuedInputBuffers.clear(); 5327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mSkipRenderingUntilMediaTimeUs = -1; 5337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 5347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::requestCodecNotification() { 5367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mFormatChangePending) { 5377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return; 5387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCodec != NULL) { 5407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> reply = new AMessage(kWhatCodecNotify, id()); 5417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("generation", mBufferGeneration); 5427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCodec->requestActivityNotification(reply); 5437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 5457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) { 5477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t generation; 5487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findInt32("generation", &generation)); 5497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return generation != mBufferGeneration; 5507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 5517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangstatus_t NuPlayer::Decoder::fetchInputData(sp<AMessage> &reply) { 5537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> accessUnit; 5547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool dropAccessUnit; 5557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang do { 5567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit); 5577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err == -EWOULDBLOCK) { 5597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return err; 5607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (err != OK) { 5617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (err == INFO_DISCONTINUITY) { 5627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t type; 5637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(accessUnit->meta()->findInt32("discontinuity", &type)); 5647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool formatChange = 5667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (mIsAudio && 5677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT)) 5687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang || (!mIsAudio && 5697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT)); 5707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0; 5727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGI("%s discontinuity (format=%d, time=%d)", 5747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio ? "audio" : "video", formatChange, timeChange); 5757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool seamlessFormatChange = false; 5777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> newFormat = mSource->getFormat(mIsAudio); 5787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (formatChange) { 5797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang seamlessFormatChange = 5807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang supportsSeamlessFormatChange(newFormat); 5817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // treat seamless format change separately 5827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang formatChange = !seamlessFormatChange; 5837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (formatChange || timeChange) { 5867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<AMessage> msg = mNotify->dup(); 5877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->setInt32("what", kWhatInputDiscontinuity); 5887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->setInt32("formatChange", formatChange); 5897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang msg->post(); 5907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 5917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 5927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (formatChange /* not seamless */) { 5937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // must change decoder 5947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // return EOS and wait to be killed 5957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mFormatChangePending = true; 5967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return ERROR_END_OF_STREAM; 5977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (timeChange) { 5987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // need to flush 5997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // TODO: Ideally we shouldn't need a flush upon time 6007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // discontinuity, flushing will cause loss of frames. 6017137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // We probably should queue a time change marker to the 6027137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // output queue, and handles it in renderer instead. 6037137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang rememberCodecSpecificData(newFormat); 6047137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang onFlush(false /* notifyComplete */); 6057137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = OK; 6067137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else if (seamlessFormatChange) { 6077137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // reuse existing decoder and don't flush 6087137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang rememberCodecSpecificData(newFormat); 6097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang err = OK; 6107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } else { 6117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // This stream is unaffected by the discontinuity 6127137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return -EWOULDBLOCK; 6137137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6157137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6167137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setInt32("err", err); 6177137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return OK; 6187137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6197137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mIsAudio) { 6217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ++mNumFramesTotal; 6227137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6237137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang dropAccessUnit = false; 6257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mIsAudio 6267137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang && !mIsSecure 6277137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang && mRenderer->getVideoLateByUs() > 100000ll 6287137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang && mIsVideoAVC 6297137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang && !IsAVCReferenceFrame(accessUnit)) { 6307137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang dropAccessUnit = true; 6317137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ++mNumFramesDropped; 6327137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6337137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } while (dropAccessUnit); 6347137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6357137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video"); 6367137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#if 0 6377137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int64_t mediaTimeUs; 6387137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs)); 6397137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("feeding %s input buffer at media time %.2f secs", 6407137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mIsAudio ? "audio" : "video", 6417137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaTimeUs / 1E6); 6427137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang#endif 6437137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6447137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCCDecoder != NULL) { 6457137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder->decode(accessUnit); 6467137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6477137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6487137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang reply->setBuffer("buffer", accessUnit); 6497137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6507137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return OK; 6517137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang} 6527137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6537137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::onInputBufferFetched(const sp<AMessage> &msg) { 6547137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t bufferIx; 6557137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findSize("buffer-ix", &bufferIx)); 6567137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK_LT(bufferIx, mInputBuffers.size()); 6577137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> codecBuffer = mInputBuffers[bufferIx]; 6587137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6597137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> buffer; 6607137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bool hasBuffer = msg->findBuffer("buffer", &buffer); 6617137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6627137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // handle widevine classic source - that fills an arbitrary input buffer 6637137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang MediaBuffer *mediaBuffer = NULL; 6647137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (hasBuffer) { 6657137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer = (MediaBuffer *)(buffer->getMediaBufferBase()); 6667137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mediaBuffer != NULL) { 6677137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // likely filled another buffer than we requested: adjust buffer index 6687137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang size_t ix; 6697137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (ix = 0; ix < mInputBuffers.size(); ix++) { 6707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<ABuffer> &buf = mInputBuffers[ix]; 6717137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (buf->data() == mediaBuffer->data()) { 6727137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // all input buffers are dequeued on start, hence the check 6737137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mInputBufferIsDequeued[ix]) { 6747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu", 6757137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mComponentName.c_str(), ix, bufferIx); 6767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer->release(); 6777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang return false; 6787137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // TRICKY: need buffer for the metadata, so instead, set 6817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // codecBuffer to the same (though incorrect) buffer to 6827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang // avoid a memcpy into the codecBuffer 6837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang codecBuffer = buffer; 6847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang codecBuffer->setRange( 6857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer->range_offset(), 6867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mediaBuffer->range_length()); 6877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang bufferIx = ix; 6887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 6897137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(ix < mInputBuffers.size()); 6927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 6947137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6957137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (buffer == NULL /* includes !hasBuffer */) { 6967137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang int32_t streamErr = ERROR_END_OF_STREAM; 6977137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); 6987137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 6997137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (streamErr == OK) { 7007137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang /* buffers are returned to hold on to */ 7012245fc625910e47d1ba3c339e205c21ab58a47adWei Jia return true; 7021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 7031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 7041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // attempt to queue EOS 7051cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err = mCodec->queueInputBuffer( 7061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar bufferIx, 7071cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 7081cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 7091cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 7101cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar MediaCodec::BUFFER_FLAG_EOS); 711cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung if (err == OK) { 712cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mInputBufferIsDequeued.editItemAt(bufferIx) = false; 713cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } else if (streamErr == ERROR_END_OF_STREAM) { 7141cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar streamErr = err; 7151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // err will not be ERROR_END_OF_STREAM 7161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 7171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 7181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (streamErr != ERROR_END_OF_STREAM) { 719cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung ALOGE("Stream error for %s (err=%d), EOS %s queued", 720cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mComponentName.c_str(), 721cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung streamErr, 722cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung err == OK ? "successfully" : "unsuccessfully"); 7231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(streamErr); 7241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 7251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else { 726c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia sp<AMessage> extra; 727c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) { 728c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia int64_t resumeAtMediaTimeUs; 729c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia if (extra->findInt64( 730c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) { 731c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia ALOGI("[%s] suppressing rendering until %lld us", 732c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mComponentName.c_str(), (long long)resumeAtMediaTimeUs); 733c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs; 734c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 735c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 736c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 7371cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int64_t timeUs = 0; 7381cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar uint32_t flags = 0; 7391cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 7401cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 74187603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar int32_t eos, csd; 74287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar // we do not expect SYNCFRAME for decoder 7431cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (buffer->meta()->findInt32("eos", &eos) && eos) { 7441cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar flags |= MediaCodec::BUFFER_FLAG_EOS; 74587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } else if (buffer->meta()->findInt32("csd", &csd) && csd) { 74687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; 7471cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 7481cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 7491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // copy into codec buffer 7501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (buffer != codecBuffer) { 7511cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_LE(buffer->size(), codecBuffer->capacity()); 7521cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar codecBuffer->setRange(0, buffer->size()); 7531cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar memcpy(codecBuffer->data(), buffer->data(), buffer->size()); 7541cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 7551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 7561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err = mCodec->queueInputBuffer( 7571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar bufferIx, 7581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar codecBuffer->offset(), 7591cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar codecBuffer->size(), 7601cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar timeUs, 7611cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar flags); 7621cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 763cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung if (mediaBuffer != NULL) { 764cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mediaBuffer->release(); 765cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } 7661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to queue input buffer for %s (err=%d)", 7671cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), err); 7681cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 769cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } else { 770cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mInputBufferIsDequeued.editItemAt(bufferIx) = false; 771cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung if (mediaBuffer != NULL) { 772cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung CHECK(mMediaBuffers[bufferIx] == NULL); 773cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung mMediaBuffers.editItemAt(bufferIx) = mediaBuffer; 774cf31f1eecf46d599428e115dfee8dd47b76c83fcAndy Hung } 775095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 7772245fc625910e47d1ba3c339e205c21ab58a47adWei Jia return true; 778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) { 7811cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err; 7821cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int32_t render; 7831cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar size_t bufferIx; 7841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(msg->findSize("buffer-ix", &bufferIx)); 785c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 7867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!mIsAudio) { 787c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia int64_t timeUs; 788c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia sp<ABuffer> buffer = mOutputBuffers[bufferIx]; 789c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia buffer->meta()->findInt64("timeUs", &timeUs); 7907137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang 7917137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (mCCDecoder != NULL && mCCDecoder->isSelected()) { 7927137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCCDecoder->display(timeUs); 7937137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 794c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia } 795c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia 7961cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (msg->findInt32("render", &render) && render) { 797dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar int64_t timestampNs; 798dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar CHECK(msg->findInt64("timestampNs", ×tampNs)); 799dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar err = mCodec->renderOutputBufferAndRelease(bufferIx, timestampNs); 8001cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else { 8011cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar err = mCodec->releaseOutputBuffer(bufferIx); 8021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 8031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 8041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("failed to release output buffer for %s (err=%d)", 8051cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), err); 8061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 8107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangbool NuPlayer::Decoder::supportsSeamlessAudioFormatChange( 8117137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang const sp<AMessage> &targetFormat) const { 8126d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (targetFormat == NULL) { 8136d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return true; 8146d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 8156d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 8166d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih AString mime; 8176d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (!targetFormat->findString("mime", &mime)) { 8186d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 8196d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 8206d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 8216d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 8226d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih // field-by-field comparison 8236d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih const char * keys[] = { "channel-count", "sample-rate", "is-adts" }; 8246d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) { 8256d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih int32_t oldVal, newVal; 8267abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (!mInputFormat->findInt32(keys[i], &oldVal) || 8271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar !targetFormat->findInt32(keys[i], &newVal) || 8281cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar oldVal != newVal) { 8296d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 8306d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 8316d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 8326d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 8336d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih sp<ABuffer> oldBuf, newBuf; 8347abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (mInputFormat->findBuffer("csd-0", &oldBuf) && 8351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar targetFormat->findBuffer("csd-0", &newBuf)) { 8366d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (oldBuf->size() != newBuf->size()) { 8376d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 8386d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 8396d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size()); 8406d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 8416d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 8426d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 8436d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih} 8446d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 8456d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shihbool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const { 8467abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (mInputFormat == NULL) { 8476d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 8486d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 8496d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 8506d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (targetFormat == NULL) { 8516d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return true; 8526d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 8536d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 8546d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih AString oldMime, newMime; 8557abbd4c954e26fb69235831e11090ad61cec7b94joakim johansson if (!mInputFormat->findString("mime", &oldMime) 8566d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih || !targetFormat->findString("mime", &newMime) 8576d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih || !(oldMime == newMime)) { 8586d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 8596d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 8606d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 8616d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/")); 8626d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih bool seamless; 8636d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (audio) { 8646d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih seamless = supportsSeamlessAudioFormatChange(targetFormat); 8656d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } else { 8661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int32_t isAdaptive; 8671cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar seamless = (mCodec != NULL && 8681cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mInputFormat->findInt32("adaptive-playback", &isAdaptive) && 8691cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar isAdaptive); 8706d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 8716d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 8726d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str()); 8736d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return seamless; 8746d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih} 8756d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 8767137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhangvoid NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) { 8777137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (format == NULL) { 878a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang return; 879a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 8807137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCSDsForCurrentFormat.clear(); 8817137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang for (int32_t i = 0; ; ++i) { 8827137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang AString tag = "csd-"; 8837137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang tag.append(i); 8847137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang sp<ABuffer> buffer; 8857137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang if (!format->findBuffer(tag.c_str(), &buffer)) { 8867137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang break; 8877137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang } 8887137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang mCSDsForCurrentFormat.push(buffer); 889a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 890b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang} 891b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 892f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhangvoid NuPlayer::Decoder::notifyResumeCompleteIfNecessary() { 893f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang if (mResumePending) { 894f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang mResumePending = false; 895f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 896f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang sp<AMessage> notify = mNotify->dup(); 897f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notify->setInt32("what", kWhatResumeCompleted); 898f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang notify->post(); 899f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang } 900f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang} 901f8d717772f6d185cb07720cd5091df9b7d612e0bChong Zhang 902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} // namespace android 903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 904