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> &notify,
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> &notify)
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