NuPlayerDecoder.cpp revision b86e68f834b7040518b99d1d0245d5f2e5cb9c86
1f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/* 2f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Copyright (C) 2010 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 22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "NuPlayerDecoder.h" 23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/ICrypto.h> 25a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang#include <media/stagefright/foundation/ABitReader.h> 26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h> 285bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <media/stagefright/foundation/AMessage.h> 29095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar#include <media/stagefright/MediaBuffer.h> 301cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaCodec.h> 31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h> 321cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar#include <media/stagefright/MediaErrors.h> 33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 34f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android { 35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 36f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::Decoder( 371173118eace0e9e347cb007f0da817cee87579edGlenn Kasten const sp<AMessage> ¬ify, 381173118eace0e9e347cb007f0da817cee87579edGlenn Kasten const sp<NativeWindowWrapper> &nativeWindow) 39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : mNotify(notify), 401cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mNativeWindow(nativeWindow), 411cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mBufferGeneration(0), 42704e72658b1082264a26a83c50046da34f07d1a1Wei Jia mPaused(true), 431cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName("decoder") { 441cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // Every decoder has its own looper because MediaCodec operations 451cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // are blocking, but NuPlayer needs asynchronous operations. 461cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mDecoderLooper = new ALooper; 479e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen mDecoderLooper->setName("NPDecoder"); 481cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodecLooper = new ALooper; 519e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen mCodecLooper->setName("NPDecoder-CL"); 521cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 55f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::Decoder::~Decoder() { 56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 58095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnarstatic 59095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnarstatus_t PostAndAwaitResponse( 60095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar const sp<AMessage> &msg, sp<AMessage> *response) { 61095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar status_t err = msg->postAndAwaitResponse(response); 62095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 63095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (err != OK) { 64095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar return err; 65095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 66095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 67095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (!(*response)->findInt32("err", &err)) { 68095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar err = OK; 69095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 70095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 71095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar return err; 72095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar} 73095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 7487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnarvoid NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) { 7587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar mCSDsForCurrentFormat.clear(); 7687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar for (int32_t i = 0; ; ++i) { 7787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar AString tag = "csd-"; 7887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar tag.append(i); 7987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar sp<ABuffer> buffer; 8087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar if (!format->findBuffer(tag.c_str(), &buffer)) { 8187603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar break; 8287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 8387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar mCSDsForCurrentFormat.push(buffer); 8487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 8587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar} 8687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 871cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) { 88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mCodec == NULL); 89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 901cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ++mBufferGeneration; 911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 92840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber AString mime; 93840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber CHECK(format->findString("mime", &mime)); 94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 951cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<Surface> surface = NULL; 961cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mNativeWindow != NULL) { 971cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar surface = mNativeWindow->getSurfaceTextureClient(); 981cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1001cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName = mime; 1011cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.append(" decoder"); 1021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGV("[%s] onConfigure (surface=%p)", mComponentName.c_str(), surface.get()); 103840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 1041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodec = MediaCodec::CreateByType(mCodecLooper, mime.c_str(), false /* encoder */); 105095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar int32_t secure = 0; 106095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (format->findInt32("secure", &secure) && secure != 0) { 107095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (mCodec != NULL) { 108095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec->getName(&mComponentName); 109095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mComponentName.append(".secure"); 110095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec->release(); 111095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGI("[%s] creating", mComponentName.c_str()); 112095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodec = MediaCodec::CreateByComponentName( 113095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mCodecLooper, mComponentName.c_str()); 114095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 115095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 1161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mCodec == NULL) { 117095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGE("Failed to create %s%s decoder", 118095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar (secure ? "secure " : ""), mime.c_str()); 1191cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(UNKNOWN_ERROR); 1201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 121840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber } 122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodec->getName(&mComponentName); 1241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 1251173118eace0e9e347cb007f0da817cee87579edGlenn Kasten if (mNativeWindow != NULL) { 1261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // disconnect from surface as MediaCodec will reconnect 1271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((int)NO_ERROR, 1281cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar native_window_api_disconnect( 1291cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar surface.get(), 1301cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar NATIVE_WINDOW_API_MEDIA)); 1311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 1321cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err = mCodec->configure( 1331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar format, surface, NULL /* crypto */, 0 /* flags */); 1341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 1351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err); 1361cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 1371cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 1381cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 13987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar rememberCodecSpecificData(format); 14087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 1411cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // the following should work in configured state 1421cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat)); 1431cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat)); 1441cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 1451cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar err = mCodec->start(); 1461cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 1471cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err); 1481cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 1491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1521cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // the following should work after start 1531cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getInputBuffers(&mInputBuffers)); 154095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar releaseAndResetMediaBuffers(); 1551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_EQ((status_t)OK, mCodec->getOutputBuffers(&mOutputBuffers)); 1561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGV("[%s] got %zu input and %zu output buffers", 1571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), 1581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mInputBuffers.size(), 1591cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mOutputBuffers.size()); 160078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 1611cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar requestCodecNotification(); 162704e72658b1082264a26a83c50046da34f07d1a1Wei Jia mPaused = false; 1631cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 164078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 165095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnarvoid NuPlayer::Decoder::releaseAndResetMediaBuffers() { 166095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar for (size_t i = 0; i < mMediaBuffers.size(); i++) { 167095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (mMediaBuffers[i] != NULL) { 168095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mMediaBuffers[i]->release(); 169095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mMediaBuffers.editItemAt(i) = NULL; 170095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 171095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 172095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mMediaBuffers.resize(mInputBuffers.size()); 17381e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia for (size_t i = 0; i < mMediaBuffers.size(); i++) { 17481e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia mMediaBuffers.editItemAt(i) = NULL; 17581e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia } 176095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mInputBufferIsDequeued.clear(); 177095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mInputBufferIsDequeued.resize(mInputBuffers.size()); 17881e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) { 17981e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia mInputBufferIsDequeued.editItemAt(i) = false; 18081e50d0c782cc18eab4ef40ecd6c7f36df50fea5Wei Jia } 181095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar} 182095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 1831cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::requestCodecNotification() { 1841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mCodec != NULL) { 1851cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<AMessage> reply = new AMessage(kWhatCodecNotify, id()); 1861cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar reply->setInt32("generation", mBufferGeneration); 1871cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodec->requestActivityNotification(reply); 188078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 1891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 190078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 1911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarbool NuPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) { 1921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int32_t generation; 1931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(msg->findInt32("generation", &generation)); 1941cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return generation != mBufferGeneration; 1951cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1971cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::init() { 1981cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mDecoderLooper->registerHandler(this); 199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2011cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::configure(const sp<AMessage> &format) { 2021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<AMessage> msg = new AMessage(kWhatConfigure, id()); 2031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar msg->setMessage("format", format); 2041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar msg->post(); 2051cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 2061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 20787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnarvoid NuPlayer::Decoder::signalUpdateFormat(const sp<AMessage> &format) { 20887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar sp<AMessage> msg = new AMessage(kWhatUpdateFormat, id()); 20987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar msg->setMessage("format", format); 21087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar msg->post(); 21187603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar} 21287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 213095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnarstatus_t NuPlayer::Decoder::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { 214095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, id()); 215095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar msg->setPointer("buffers", buffers); 216095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 217095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar sp<AMessage> response; 218095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar return PostAndAwaitResponse(msg, &response); 219095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar} 220095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 2211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::handleError(int32_t err) 2221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar{ 223c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia mCodec->release(); 224c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia 2251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<AMessage> notify = mNotify->dup(); 2261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->setInt32("what", kWhatError); 2271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->setInt32("err", err); 2281cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->post(); 2291cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 2301cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 2311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarbool NuPlayer::Decoder::handleAnInputBuffer() { 2321cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar size_t bufferIx = -1; 2331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t res = mCodec->dequeueInputBuffer(&bufferIx); 2341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGV("[%s] dequeued input: %d", 2351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), res == OK ? (int)bufferIx : res); 2361cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (res != OK) { 2371cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (res != -EAGAIN) { 2381cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(res); 239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 2401cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return false; 2411cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2431cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_LT(bufferIx, mInputBuffers.size()); 2441cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 245095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (mMediaBuffers[bufferIx] != NULL) { 246095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mMediaBuffers[bufferIx]->release(); 247095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mMediaBuffers.editItemAt(bufferIx) = NULL; 248095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 249095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mInputBufferIsDequeued.editItemAt(bufferIx) = true; 250095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 2511cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, id()); 2521cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar reply->setSize("buffer-ix", bufferIx); 2531cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar reply->setInt32("generation", mBufferGeneration); 2541cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 25587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar if (!mCSDsToSubmit.isEmpty()) { 25687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0); 25787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar ALOGI("[%s] resubmitting CSD", mComponentName.c_str()); 25887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar reply->setBuffer("buffer", buffer); 25987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar mCSDsToSubmit.removeAt(0); 26087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar reply->post(); 26187603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar return true; 26287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 26387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 2641cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<AMessage> notify = mNotify->dup(); 2651cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->setInt32("what", kWhatFillThisBuffer); 2661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->setBuffer("buffer", mInputBuffers[bufferIx]); 2671cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->setMessage("reply", reply); 2681cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->post(); 2691cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return true; 2701cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 2711cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 2721cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) { 2731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar size_t bufferIx; 2741cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(msg->findSize("buffer-ix", &bufferIx)); 2751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_LT(bufferIx, mInputBuffers.size()); 2761cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<ABuffer> codecBuffer = mInputBuffers[bufferIx]; 2771cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 2781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<ABuffer> buffer; 2791cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar bool hasBuffer = msg->findBuffer("buffer", &buffer); 280095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 281095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar // handle widevine classic source - that fills an arbitrary input buffer 282095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar MediaBuffer *mediaBuffer = NULL; 283095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (hasBuffer && buffer->meta()->findPointer( 284095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar "mediaBuffer", (void **)&mediaBuffer)) { 285095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (mediaBuffer == NULL) { 286095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar // received no actual buffer 287095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGW("[%s] received null MediaBuffer %s", 288095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mComponentName.c_str(), msg->debugString().c_str()); 289095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar buffer = NULL; 290095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } else { 291095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar // likely filled another buffer than we requested: adjust buffer index 292095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar size_t ix; 293095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar for (ix = 0; ix < mInputBuffers.size(); ix++) { 294095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar const sp<ABuffer> &buf = mInputBuffers[ix]; 295095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (buf->data() == mediaBuffer->data()) { 296095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar // all input buffers are dequeued on start, hence the check 297095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar CHECK(mInputBufferIsDequeued[ix]); 298095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar ALOGV("[%s] received MediaBuffer for #%zu instead of #%zu", 299095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mComponentName.c_str(), ix, bufferIx); 300095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 301095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar // TRICKY: need buffer for the metadata, so instead, set 302095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar // codecBuffer to the same (though incorrect) buffer to 303095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar // avoid a memcpy into the codecBuffer 304095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar codecBuffer = buffer; 305095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar codecBuffer->setRange( 306095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mediaBuffer->range_offset(), 307095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mediaBuffer->range_length()); 308095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar bufferIx = ix; 309095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar break; 310095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 311095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 312095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar CHECK(ix < mInputBuffers.size()); 313095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 314095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 315095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 316095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mInputBufferIsDequeued.editItemAt(bufferIx) = false; 317095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 3181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (buffer == NULL /* includes !hasBuffer */) { 3191cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int32_t streamErr = ERROR_END_OF_STREAM; 3201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(msg->findInt32("err", &streamErr) || !hasBuffer); 3211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 3221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (streamErr == OK) { 3231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar /* buffers are returned to hold on to */ 3241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 3251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 3261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 3271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // attempt to queue EOS 3281cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err = mCodec->queueInputBuffer( 3291cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar bufferIx, 3301cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 3311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 3321cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 0, 3331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar MediaCodec::BUFFER_FLAG_EOS); 3341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (streamErr == ERROR_END_OF_STREAM && err != OK) { 3351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar streamErr = err; 3361cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // err will not be ERROR_END_OF_STREAM 3371cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 3381cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 3391cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (streamErr != ERROR_END_OF_STREAM) { 3401cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(streamErr); 3411cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 3421cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else { 3431cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int64_t timeUs = 0; 3441cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar uint32_t flags = 0; 3451cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 3461cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 34787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar int32_t eos, csd; 34887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar // we do not expect SYNCFRAME for decoder 3491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (buffer->meta()->findInt32("eos", &eos) && eos) { 3501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar flags |= MediaCodec::BUFFER_FLAG_EOS; 35187603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } else if (buffer->meta()->findInt32("csd", &csd) && csd) { 35287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; 3531cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 3541cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 3551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // copy into codec buffer 3561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (buffer != codecBuffer) { 3571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_LE(buffer->size(), codecBuffer->capacity()); 3581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar codecBuffer->setRange(0, buffer->size()); 3591cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar memcpy(codecBuffer->data(), buffer->data(), buffer->size()); 3601cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 3611cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 3621cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err = mCodec->queueInputBuffer( 3631cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar bufferIx, 3641cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar codecBuffer->offset(), 3651cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar codecBuffer->size(), 3661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar timeUs, 3671cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar flags); 3681cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 3691cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to queue input buffer for %s (err=%d)", 3701cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), err); 3711cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 3721cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 373095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 374095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar if (mediaBuffer != NULL) { 375095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar CHECK(mMediaBuffers[bufferIx] == NULL); 376095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar mMediaBuffers.editItemAt(bufferIx) = mediaBuffer; 377095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3811cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarbool NuPlayer::Decoder::handleAnOutputBuffer() { 3821cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar size_t bufferIx = -1; 3831cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar size_t offset; 3841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar size_t size; 3851cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int64_t timeUs; 3861cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar uint32_t flags; 3871cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t res = mCodec->dequeueOutputBuffer( 3881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar &bufferIx, &offset, &size, &timeUs, &flags); 3891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 3901cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (res != OK) { 3911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGV("[%s] dequeued output: %d", mComponentName.c_str(), res); 3921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else { 3931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGV("[%s] dequeued output: %d (time=%lld flags=%" PRIu32 ")", 3941cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), (int)bufferIx, timeUs, flags); 3951cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 3971cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (res == INFO_OUTPUT_BUFFERS_CHANGED) { 3981cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar res = mCodec->getOutputBuffers(&mOutputBuffers); 3991cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (res != OK) { 4001cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to get output buffers for %s after INFO event (err=%d)", 4011cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), res); 4021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(res); 4031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return false; 4041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 4051cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // NuPlayer ignores this 4061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return true; 4071cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else if (res == INFO_FORMAT_CHANGED) { 4081cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<AMessage> format = new AMessage(); 4091cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar res = mCodec->getOutputFormat(&format); 4101cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (res != OK) { 4111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("Failed to get output format for %s after INFO event (err=%d)", 4121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), res); 4131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(res); 4141cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return false; 4151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<AMessage> notify = mNotify->dup(); 4181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->setInt32("what", kWhatOutputFormatChanged); 4191cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->setMessage("format", format); 4201cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->post(); 4211cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return true; 4221cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else if (res == INFO_DISCONTINUITY) { 4231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // nothing to do 4241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return true; 4251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else if (res != OK) { 4261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (res != -EAGAIN) { 4271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(res); 4281cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 4291cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return false; 4301cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4321cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK_LT(bufferIx, mOutputBuffers.size()); 4331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<ABuffer> buffer = mOutputBuffers[bufferIx]; 4341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar buffer->setRange(offset, size); 4351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar buffer->meta()->clear(); 4361cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar buffer->meta()->setInt64("timeUs", timeUs); 4371cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (flags & MediaCodec::BUFFER_FLAG_EOS) { 4381cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar buffer->meta()->setInt32("eos", true); 439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 4401cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // we do not expect CODECCONFIG or SYNCFRAME for decoder 4411cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 4421cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<AMessage> reply = new AMessage(kWhatRenderBuffer, id()); 4431cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar reply->setSize("buffer-ix", bufferIx); 4441cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar reply->setInt32("generation", mBufferGeneration); 445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> notify = mNotify->dup(); 4471cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->setInt32("what", kWhatDrainThisBuffer); 4481cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->setBuffer("buffer", buffer); 4491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->setMessage("reply", reply); 450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber notify->post(); 4511cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 4521cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // FIXME: This should be handled after rendering is complete, 4531cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // but Renderer needs it now 4541cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (flags & MediaCodec::BUFFER_FLAG_EOS) { 4551cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGV("queueing eos [%s]", mComponentName.c_str()); 4561cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<AMessage> notify = mNotify->dup(); 4571cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->setInt32("what", kWhatEOS); 4581cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->setInt32("err", ERROR_END_OF_STREAM); 4591cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->post(); 4601cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 4611cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return true; 462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4641cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) { 4651cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err; 4661cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int32_t render; 4671cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar size_t bufferIx; 4681cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(msg->findSize("buffer-ix", &bufferIx)); 4691cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (msg->findInt32("render", &render) && render) { 4701cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar err = mCodec->renderOutputBufferAndRelease(bufferIx); 4711cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } else { 4721cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar err = mCodec->releaseOutputBuffer(bufferIx); 4731cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 4741cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 4751cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("failed to release output buffer for %s (err=%d)", 4761cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName.c_str(), err); 4771cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 4811cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onFlush() { 4821cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err = OK; 483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mCodec != NULL) { 4841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar err = mCodec->flush(); 48587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator 4861cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ++mBufferGeneration; 487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 4881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 4891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 4901cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("failed to flush %s (err=%d)", mComponentName.c_str(), err); 4911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 4921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 4931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 4941cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 495095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar releaseAndResetMediaBuffers(); 496095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 4971cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<AMessage> notify = mNotify->dup(); 4981cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->setInt32("what", kWhatFlushCompleted); 4991cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->post(); 500704e72658b1082264a26a83c50046da34f07d1a1Wei Jia mPaused = true; 501704e72658b1082264a26a83c50046da34f07d1a1Wei Jia} 502704e72658b1082264a26a83c50046da34f07d1a1Wei Jia 503704e72658b1082264a26a83c50046da34f07d1a1Wei Jiavoid NuPlayer::Decoder::onResume() { 504704e72658b1082264a26a83c50046da34f07d1a1Wei Jia mPaused = false; 505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5071cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onShutdown() { 5081cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar status_t err = OK; 5093831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber if (mCodec != NULL) { 5101cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar err = mCodec->release(); 5111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mCodec = NULL; 5121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ++mBufferGeneration; 5131cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 5141cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mNativeWindow != NULL) { 5151cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar // reconnect to surface as MediaCodec disconnected from it 5163fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia status_t error = 5171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar native_window_api_connect( 5181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mNativeWindow->getNativeWindow().get(), 5193fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia NATIVE_WINDOW_API_MEDIA); 5203fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia ALOGW_IF(error != NO_ERROR, 5213fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia "[%s] failed to connect to native window, error=%d", 5223fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia mComponentName.c_str(), error); 5231cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 5241cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mComponentName = "decoder"; 5251cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 5261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 527095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar releaseAndResetMediaBuffers(); 528095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 5291cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (err != OK) { 5301cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGE("failed to release %s (err=%d)", mComponentName.c_str(), err); 5311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar handleError(err); 5321cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar return; 5331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 5341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 5351cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<AMessage> notify = mNotify->dup(); 5361cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->setInt32("what", kWhatShutdownCompleted); 5371cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar notify->post(); 538704e72658b1082264a26a83c50046da34f07d1a1Wei Jia mPaused = true; 5391cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 5401cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 5411cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) { 5421cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str()); 5431cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 5441cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar switch (msg->what()) { 5451cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar case kWhatConfigure: 5461cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar { 5471cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar sp<AMessage> format; 5481cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar CHECK(msg->findMessage("format", &format)); 5491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar onConfigure(format); 5501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar break; 5511cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 5521cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 55387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar case kWhatUpdateFormat: 55487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar { 55587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar sp<AMessage> format; 55687603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar CHECK(msg->findMessage("format", &format)); 55787603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar rememberCodecSpecificData(format); 55887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar break; 55987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 56087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar 561095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar case kWhatGetInputBuffers: 562095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar { 563095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar uint32_t replyID; 564095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 565095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 566095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar Vector<sp<ABuffer> > *dstBuffers; 567095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); 568095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 569095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar dstBuffers->clear(); 570095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar for (size_t i = 0; i < mInputBuffers.size(); i++) { 571095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar dstBuffers->push(mInputBuffers[i]); 572095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 573095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 574095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar (new AMessage)->postReply(replyID); 575095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar break; 576095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar } 577095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar 5781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar case kWhatCodecNotify: 5791cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar { 5801cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (!isStaleReply(msg)) { 581704e72658b1082264a26a83c50046da34f07d1a1Wei Jia if (!mPaused) { 582704e72658b1082264a26a83c50046da34f07d1a1Wei Jia while (handleAnInputBuffer()) { 583704e72658b1082264a26a83c50046da34f07d1a1Wei Jia } 5841cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 5851cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 5861cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar while (handleAnOutputBuffer()) { 5871cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 5881cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 5891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 5901cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar requestCodecNotification(); 5911cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar break; 5921cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 5931cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 5941cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar case kWhatInputBufferFilled: 5951cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar { 5961cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (!isStaleReply(msg)) { 5971cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar onInputBufferFilled(msg); 5981cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 5991cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar break; 6001cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 6011cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 6021cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar case kWhatRenderBuffer: 6031cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar { 6041cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (!isStaleReply(msg)) { 6051cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar onRenderBuffer(msg); 6061cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 6071cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar break; 6081cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 6091cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 6101cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar case kWhatFlush: 6111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar { 61287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar sp<AMessage> format; 61387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar if (msg->findMessage("new-format", &format)) { 61487603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar rememberCodecSpecificData(format); 61587603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 6161cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar onFlush(); 6171cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar break; 6181cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 6191cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 620704e72658b1082264a26a83c50046da34f07d1a1Wei Jia case kWhatResume: 621704e72658b1082264a26a83c50046da34f07d1a1Wei Jia { 622704e72658b1082264a26a83c50046da34f07d1a1Wei Jia onResume(); 623704e72658b1082264a26a83c50046da34f07d1a1Wei Jia break; 624704e72658b1082264a26a83c50046da34f07d1a1Wei Jia } 625704e72658b1082264a26a83c50046da34f07d1a1Wei Jia 6261cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar case kWhatShutdown: 6271cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar { 6281cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar onShutdown(); 6291cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar break; 6301cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar } 6311cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 6321cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar default: 6331cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar TRESPASS(); 6341cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar break; 6353831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber } 6363831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber} 6373831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber 63887603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnarvoid NuPlayer::Decoder::signalFlush(const sp<AMessage> &format) { 63987603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar sp<AMessage> msg = new AMessage(kWhatFlush, id()); 64087603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar if (format != NULL) { 64187603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar msg->setMessage("new-format", format); 64287603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar } 64387603c0dd1f4e62e52feffa8d6e960ad21f68893Lajos Molnar msg->post(); 6441cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 6451cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 6461cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::signalResume() { 647704e72658b1082264a26a83c50046da34f07d1a1Wei Jia (new AMessage(kWhatResume, id()))->post(); 6481cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 6491cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 6501cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnarvoid NuPlayer::Decoder::initiateShutdown() { 6511cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar (new AMessage(kWhatShutdown, id()))->post(); 6521cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar} 6531cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar 6546d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shihbool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const { 6556d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (targetFormat == NULL) { 6566d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return true; 6576d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 6586d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 6596d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih AString mime; 6606d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (!targetFormat->findString("mime", &mime)) { 6616d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 6626d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 6636d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 6646d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 6656d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih // field-by-field comparison 6666d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih const char * keys[] = { "channel-count", "sample-rate", "is-adts" }; 6676d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) { 6686d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih int32_t oldVal, newVal; 6691cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (!mOutputFormat->findInt32(keys[i], &oldVal) || 6701cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar !targetFormat->findInt32(keys[i], &newVal) || 6711cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar oldVal != newVal) { 6726d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 6736d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 6746d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 6756d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 6766d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih sp<ABuffer> oldBuf, newBuf; 6771cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mOutputFormat->findBuffer("csd-0", &oldBuf) && 6781cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar targetFormat->findBuffer("csd-0", &newBuf)) { 6796d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (oldBuf->size() != newBuf->size()) { 6806d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 6816d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 6826d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size()); 6836d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 6846d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 6856d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 6866d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih} 6876d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 6886d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shihbool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const { 6891cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (mOutputFormat == NULL) { 6906d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 6916d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 6926d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 6936d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (targetFormat == NULL) { 6946d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return true; 6956d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 6966d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 6976d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih AString oldMime, newMime; 6981cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar if (!mOutputFormat->findString("mime", &oldMime) 6996d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih || !targetFormat->findString("mime", &newMime) 7006d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih || !(oldMime == newMime)) { 7016d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return false; 7026d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 7036d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 7046d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/")); 7056d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih bool seamless; 7066d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih if (audio) { 7076d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih seamless = supportsSeamlessAudioFormatChange(targetFormat); 7086d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } else { 7091cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar int32_t isAdaptive; 7101cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar seamless = (mCodec != NULL && 7111cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar mInputFormat->findInt32("adaptive-playback", &isAdaptive) && 7121cd139824b2e6832f239cd27d8962d3239053c02Lajos Molnar isAdaptive); 7136d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih } 7146d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 7156d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str()); 7166d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih return seamless; 7176d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih} 7186d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aabRobert Shih 719b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhangstruct CCData { 720a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang CCData(uint8_t type, uint8_t data1, uint8_t data2) 721a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang : mType(type), mData1(data1), mData2(data2) { 722a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 723b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang bool getChannel(size_t *channel) const { 724b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang if (mData1 >= 0x10 && mData1 <= 0x1f) { 725b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang *channel = (mData1 >= 0x18 ? 1 : 0) + (mType ? 2 : 0); 726b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return true; 727b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang } 728b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return false; 729b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang } 730a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 731a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang uint8_t mType; 732a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang uint8_t mData1; 733a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang uint8_t mData2; 734a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang}; 735a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 736b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhangstatic bool isNullPad(CCData *cc) { 737a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang return cc->mData1 < 0x10 && cc->mData2 < 0x10; 738a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang} 739a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 740b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhangstatic void dumpBytePair(const sp<ABuffer> &ccBuf) { 741a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang size_t offset = 0; 742a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang AString out; 743a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 744a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang while (offset < ccBuf->size()) { 745a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang char tmp[128]; 746a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 747a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang CCData *cc = (CCData *) (ccBuf->data() + offset); 748a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 749a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang if (isNullPad(cc)) { 750a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // 1 null pad or XDS metadata, ignore 751a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang offset += sizeof(CCData); 752a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang continue; 753a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 754a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 755a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang if (cc->mData1 >= 0x20 && cc->mData1 <= 0x7f) { 756a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // 2 basic chars 757a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang sprintf(tmp, "[%d]Basic: %c %c", cc->mType, cc->mData1, cc->mData2); 758a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } else if ((cc->mData1 == 0x11 || cc->mData1 == 0x19) 759a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang && cc->mData2 >= 0x30 && cc->mData2 <= 0x3f) { 760a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // 1 special char 761a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang sprintf(tmp, "[%d]Special: %02x %02x", cc->mType, cc->mData1, cc->mData2); 762a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } else if ((cc->mData1 == 0x12 || cc->mData1 == 0x1A) 763a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang && cc->mData2 >= 0x20 && cc->mData2 <= 0x3f){ 764a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // 1 Spanish/French char 765a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang sprintf(tmp, "[%d]Spanish: %02x %02x", cc->mType, cc->mData1, cc->mData2); 766a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } else if ((cc->mData1 == 0x13 || cc->mData1 == 0x1B) 767a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang && cc->mData2 >= 0x20 && cc->mData2 <= 0x3f){ 768a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // 1 Portuguese/German/Danish char 769a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang sprintf(tmp, "[%d]German: %02x %02x", cc->mType, cc->mData1, cc->mData2); 770a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } else if ((cc->mData1 == 0x11 || cc->mData1 == 0x19) 771a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang && cc->mData2 >= 0x20 && cc->mData2 <= 0x2f){ 772a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // Mid-Row Codes (Table 69) 773a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang sprintf(tmp, "[%d]Mid-row: %02x %02x", cc->mType, cc->mData1, cc->mData2); 774a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } else if (((cc->mData1 == 0x14 || cc->mData1 == 0x1c) 775a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang && cc->mData2 >= 0x20 && cc->mData2 <= 0x2f) 776a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang || 777a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang ((cc->mData1 == 0x17 || cc->mData1 == 0x1f) 778a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang && cc->mData2 >= 0x21 && cc->mData2 <= 0x23)){ 779a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // Misc Control Codes (Table 70) 780a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang sprintf(tmp, "[%d]Ctrl: %02x %02x", cc->mType, cc->mData1, cc->mData2); 781a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } else if ((cc->mData1 & 0x70) == 0x10 782a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang && (cc->mData2 & 0x40) == 0x40 783a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang && ((cc->mData1 & 0x07) || !(cc->mData2 & 0x20)) ) { 784a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // Preamble Address Codes (Table 71) 785a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang sprintf(tmp, "[%d]PAC: %02x %02x", cc->mType, cc->mData1, cc->mData2); 786a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } else { 787a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang sprintf(tmp, "[%d]Invalid: %02x %02x", cc->mType, cc->mData1, cc->mData2); 788a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 789a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 790a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang if (out.size() > 0) { 791a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang out.append(", "); 792a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 793a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 794a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang out.append(tmp); 795a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 796a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang offset += sizeof(CCData); 797a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 798a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 799a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang ALOGI("%s", out.c_str()); 800a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang} 801a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 802b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong ZhangNuPlayer::CCDecoder::CCDecoder(const sp<AMessage> ¬ify) 803b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang : mNotify(notify), 804b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang mCurrentChannel(0), 805b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang mSelectedTrack(-1) { 806b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang for (size_t i = 0; i < sizeof(mTrackIndices)/sizeof(mTrackIndices[0]); ++i) { 807b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang mTrackIndices[i] = -1; 808b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang } 809b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang} 810b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 811b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhangsize_t NuPlayer::CCDecoder::getTrackCount() const { 812b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return mFoundChannels.size(); 813b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang} 814b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 815b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhangsp<AMessage> NuPlayer::CCDecoder::getTrackInfo(size_t index) const { 816b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang if (!isTrackValid(index)) { 817b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return NULL; 818b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang } 819b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 820b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang sp<AMessage> format = new AMessage(); 821b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 822b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang format->setInt32("type", MEDIA_TRACK_TYPE_SUBTITLE); 823b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang format->setString("language", "und"); 824b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang format->setString("mime", MEDIA_MIMETYPE_TEXT_CEA_608); 825b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang //CC1, field 0 channel 0 826b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang bool isDefaultAuto = (mFoundChannels[index] == 0); 827b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang format->setInt32("auto", isDefaultAuto); 828b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang format->setInt32("default", isDefaultAuto); 829b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang format->setInt32("forced", 0); 830b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 831b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return format; 832b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang} 833b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 834b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhangstatus_t NuPlayer::CCDecoder::selectTrack(size_t index, bool select) { 835b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang if (!isTrackValid(index)) { 836b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return BAD_VALUE; 837b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang } 838b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 839b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang if (select) { 840b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang if (mSelectedTrack == (ssize_t)index) { 841b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang ALOGE("track %zu already selected", index); 842b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return BAD_VALUE; 843b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang } 844b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang ALOGV("selected track %zu", index); 845b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang mSelectedTrack = index; 846b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang } else { 847b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang if (mSelectedTrack != (ssize_t)index) { 848b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang ALOGE("track %zu is not selected", index); 849b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return BAD_VALUE; 850b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang } 851b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang ALOGV("unselected track %zu", index); 852b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang mSelectedTrack = -1; 853b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang } 854b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 855b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return OK; 856b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang} 857b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 858b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhangbool NuPlayer::CCDecoder::isSelected() const { 859b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return mSelectedTrack >= 0 && mSelectedTrack < (int32_t) getTrackCount(); 860b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang} 861b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 862b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhangbool NuPlayer::CCDecoder::isTrackValid(size_t index) const { 863b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return index < getTrackCount(); 864b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang} 865b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 866b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhangint32_t NuPlayer::CCDecoder::getTrackIndex(size_t channel) const { 867b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang if (channel < sizeof(mTrackIndices)/sizeof(mTrackIndices[0])) { 868b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return mTrackIndices[channel]; 869b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang } 870b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return -1; 871b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang} 872b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 873b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang// returns true if a new CC track is found 874a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhangbool NuPlayer::CCDecoder::extractFromSEI(const sp<ABuffer> &accessUnit) { 875a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang int64_t timeUs; 876a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 877a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 878a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang sp<ABuffer> sei; 879a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang if (!accessUnit->meta()->findBuffer("sei", &sei) || sei == NULL) { 880a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang return false; 881a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 882a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 883b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang bool trackAdded = false; 884a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 885862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang NALBitReader br(sei->data() + 1, sei->size() - 1); 886a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // sei_message() 887862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang while (br.atLeastNumBitsLeft(16)) { // at least 16-bit for sei_message() 888a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang uint32_t payload_type = 0; 889a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang size_t payload_size = 0; 890a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang uint8_t last_byte; 891a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 892a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang do { 893a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang last_byte = br.getBits(8); 894a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang payload_type += last_byte; 895a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } while (last_byte == 0xFF); 896a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 897a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang do { 898a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang last_byte = br.getBits(8); 899a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang payload_size += last_byte; 900a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } while (last_byte == 0xFF); 901a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 902a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // sei_payload() 903a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang if (payload_type == 4) { 904a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // user_data_registered_itu_t_t35() 905a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 906a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // ATSC A/72: 6.4.2 907a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang uint8_t itu_t_t35_country_code = br.getBits(8); 908a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang uint16_t itu_t_t35_provider_code = br.getBits(16); 909a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang uint32_t user_identifier = br.getBits(32); 910a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang uint8_t user_data_type_code = br.getBits(8); 911a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 912a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang payload_size -= 1 + 2 + 4 + 1; 913a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 914a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang if (itu_t_t35_country_code == 0xB5 915a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang && itu_t_t35_provider_code == 0x0031 916a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang && user_identifier == 'GA94' 917a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang && user_data_type_code == 0x3) { 918a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // MPEG_cc_data() 919a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // ATSC A/53 Part 4: 6.2.3.1 920a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang br.skipBits(1); //process_em_data_flag 921a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang bool process_cc_data_flag = br.getBits(1); 922a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang br.skipBits(1); //additional_data_flag 923a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang size_t cc_count = br.getBits(5); 924a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang br.skipBits(8); // em_data; 925a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang payload_size -= 2; 926a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 927a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang if (process_cc_data_flag) { 928a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang AString out; 929a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 930a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang sp<ABuffer> ccBuf = new ABuffer(cc_count * sizeof(CCData)); 931a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang ccBuf->setRange(0, 0); 932a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 933a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang for (size_t i = 0; i < cc_count; i++) { 934a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang uint8_t marker = br.getBits(5); 935a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang CHECK_EQ(marker, 0x1f); 936a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 937a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang bool cc_valid = br.getBits(1); 938a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang uint8_t cc_type = br.getBits(2); 939a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // remove odd parity bit 940a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang uint8_t cc_data_1 = br.getBits(8) & 0x7f; 941a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang uint8_t cc_data_2 = br.getBits(8) & 0x7f; 942a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 943a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang if (cc_valid 944a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang && (cc_type == 0 || cc_type == 1)) { 945a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang CCData cc(cc_type, cc_data_1, cc_data_2); 946a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang if (!isNullPad(&cc)) { 947b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang size_t channel; 948b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang if (cc.getChannel(&channel) && getTrackIndex(channel) < 0) { 949b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang mTrackIndices[channel] = mFoundChannels.size(); 950b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang mFoundChannels.push_back(channel); 951b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang trackAdded = true; 952b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang } 953a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang memcpy(ccBuf->data() + ccBuf->size(), 954a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang (void *)&cc, sizeof(cc)); 955a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang ccBuf->setRange(0, ccBuf->size() + sizeof(CCData)); 956a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 957a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 958a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 959a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang payload_size -= cc_count * 3; 960a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 961a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang mCCMap.add(timeUs, ccBuf); 962a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang break; 963a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 964a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } else { 965a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang ALOGV("Malformed SEI payload type 4"); 966a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 967a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } else { 968a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang ALOGV("Unsupported SEI payload type %d", payload_type); 969a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 970a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 971a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // skipping remaining bits of this payload 972a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang br.skipBits(payload_size * 8); 973a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 974a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 975b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return trackAdded; 976a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang} 977a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 978b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhangsp<ABuffer> NuPlayer::CCDecoder::filterCCBuf( 979b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang const sp<ABuffer> &ccBuf, size_t index) { 980b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang sp<ABuffer> filteredCCBuf = new ABuffer(ccBuf->size()); 981b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang filteredCCBuf->setRange(0, 0); 982b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 983b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang size_t cc_count = ccBuf->size() / sizeof(CCData); 984b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang const CCData* cc_data = (const CCData*)ccBuf->data(); 985b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang for (size_t i = 0; i < cc_count; ++i) { 986b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang size_t channel; 987b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang if (cc_data[i].getChannel(&channel)) { 988b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang mCurrentChannel = channel; 989b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang } 990b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang if (mCurrentChannel == mFoundChannels[index]) { 991b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang memcpy(filteredCCBuf->data() + filteredCCBuf->size(), 992b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang (void *)&cc_data[i], sizeof(CCData)); 993b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang filteredCCBuf->setRange(0, filteredCCBuf->size() + sizeof(CCData)); 994b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang } 995b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang } 996b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 997b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return filteredCCBuf; 998b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang} 999a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 1000b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhangvoid NuPlayer::CCDecoder::decode(const sp<ABuffer> &accessUnit) { 1001b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang if (extractFromSEI(accessUnit)) { 1002a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang ALOGI("Found CEA-608 track"); 1003a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang sp<AMessage> msg = mNotify->dup(); 1004a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang msg->setInt32("what", kWhatTrackAdded); 1005a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang msg->post(); 1006a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 1007a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // TODO: extract CC from other sources 1008a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang} 1009a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 1010a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhangvoid NuPlayer::CCDecoder::display(int64_t timeUs) { 1011b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang if (!isTrackValid(mSelectedTrack)) { 1012b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang ALOGE("Could not find current track(index=%d)", mSelectedTrack); 1013b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang return; 1014b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang } 1015b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 1016a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang ssize_t index = mCCMap.indexOfKey(timeUs); 1017a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang if (index < 0) { 1018a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang ALOGV("cc for timestamp %" PRId64 " not found", timeUs); 1019a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang return; 1020a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 1021a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 1022b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang sp<ABuffer> ccBuf = filterCCBuf(mCCMap.valueAt(index), mSelectedTrack); 1023a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 1024a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang if (ccBuf->size() > 0) { 1025a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang#if 0 1026a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang dumpBytePair(ccBuf); 1027a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang#endif 1028a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 1029a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang ccBuf->meta()->setInt32("trackIndex", mSelectedTrack); 1030a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang ccBuf->meta()->setInt64("timeUs", timeUs); 1031a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang ccBuf->meta()->setInt64("durationUs", 0ll); 1032a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 1033a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang sp<AMessage> msg = mNotify->dup(); 1034a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang msg->setInt32("what", kWhatClosedCaptionData); 1035a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang msg->setBuffer("buffer", ccBuf); 1036a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang msg->post(); 1037a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang } 1038a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 1039a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang // remove all entries before timeUs 1040a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang mCCMap.removeItemsAt(0, index + 1); 1041a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang} 1042a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang 1043b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhangvoid NuPlayer::CCDecoder::flush() { 1044b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang mCCMap.clear(); 1045b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang} 1046b86e68f834b7040518b99d1d0245d5f2e5cb9c86Chong Zhang 1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} // namespace android 1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1049