MediaCodec.cpp revision ee4e1b1a63758941460ae79a064249d3a5189443
15778822d86b0337407514b9372562b86edfa91cdAndreas Huber/*
25778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Copyright 2012, The Android Open Source Project
35778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
45778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
55778822d86b0337407514b9372562b86edfa91cdAndreas Huber * you may not use this file except in compliance with the License.
65778822d86b0337407514b9372562b86edfa91cdAndreas Huber * You may obtain a copy of the License at
75778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
85778822d86b0337407514b9372562b86edfa91cdAndreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
95778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
105778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Unless required by applicable law or agreed to in writing, software
115778822d86b0337407514b9372562b86edfa91cdAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
125778822d86b0337407514b9372562b86edfa91cdAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135778822d86b0337407514b9372562b86edfa91cdAndreas Huber * See the License for the specific language governing permissions and
145778822d86b0337407514b9372562b86edfa91cdAndreas Huber * limitations under the License.
155778822d86b0337407514b9372562b86edfa91cdAndreas Huber */
165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
175778822d86b0337407514b9372562b86edfa91cdAndreas Huber//#define LOG_NDEBUG 0
185778822d86b0337407514b9372562b86edfa91cdAndreas Huber#define LOG_TAG "MediaCodec"
19fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#include <inttypes.h>
205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
212606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include "include/avc_utils.h"
225778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include "include/SoftwareRenderer.h"
235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
242606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <binder/IBatteryStats.h>
25c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/IMemory.h>
2667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <binder/IPCThreadState.h>
272606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <binder/IServiceManager.h>
28c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/MemoryDealer.h>
291a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h>
30ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/ICrypto.h>
3167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <media/IResourceManagerService.h>
325778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
335778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h>
345778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h>
355b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h>
36ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/hexdump.h>
375778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/ACodec.h>
387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
392606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <media/stagefright/MediaCodec.h>
406f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen#include <media/stagefright/MediaCodecList.h>
41e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include <media/stagefright/MediaDefs.h>
425778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h>
43744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/MediaFilter.h>
445778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h>
455778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/NativeWindowWrapper.h>
462606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <private/android_filesystem_config.h>
472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Log.h>
482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Singleton.h>
49e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
505778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic inline int getCallingPid() {
5367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return IPCThreadState::self()->getCallingPid();
5467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
5567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
5667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic int64_t getId(sp<IResourceManagerClient> client) {
5767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return (int64_t) client.get();
5867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
5967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic bool isResourceError(status_t err) {
6167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return (err == OMX_ErrorInsufficientResources);
6267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
6367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic const int kMaxRetry = 2;
6567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustruct ResourceManagerClient : public BnResourceManagerClient {
6767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {}
6867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual bool reclaimResource() {
7067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<MediaCodec> codec = mMediaCodec.promote();
7167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (codec == NULL) {
7267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // codec is already gone.
7367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            return true;
7467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
7567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        status_t err = codec->release();
7667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK) {
7767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGW("ResourceManagerClient failed to release codec with err %d", err);
7867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
7967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return (err == OK);
8067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
8167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
8267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprotected:
8367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual ~ResourceManagerClient() {}
8467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
8567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprivate:
8667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    wp<MediaCodec> mMediaCodec;
8767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
8867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
8967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu};
9067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
912606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangstruct MediaCodec::BatteryNotifier : public Singleton<BatteryNotifier> {
922606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    BatteryNotifier();
93d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    virtual ~BatteryNotifier();
942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
952606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStartVideo();
962606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStopVideo();
972606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStartAudio();
982606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStopAudio();
99d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    void onBatteryStatServiceDied();
1002606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1012606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangprivate:
102d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    struct DeathNotifier : public IBinder::DeathRecipient {
103d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        DeathNotifier() {}
104d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        virtual void binderDied(const wp<IBinder>& /*who*/) {
105d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            BatteryNotifier::getInstance().onBatteryStatServiceDied();
106d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
107d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    };
108d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
109d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex mLock;
1102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    int32_t mVideoRefCount;
1112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    int32_t mAudioRefCount;
1122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    sp<IBatteryStats> mBatteryStatService;
113d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<DeathNotifier> mDeathNotifier;
114d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
115d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> getBatteryService_l();
116d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
117d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    DISALLOW_EVIL_CONSTRUCTORS(BatteryNotifier);
1182606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang};
1192606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1202606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangANDROID_SINGLETON_STATIC_INSTANCE(MediaCodec::BatteryNotifier)
1212606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1222606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangMediaCodec::BatteryNotifier::BatteryNotifier() :
1232606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount(0),
1242606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount(0) {
125d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
126d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
127d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangsp<IBatteryStats> MediaCodec::BatteryNotifier::getBatteryService_l() {
128d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mBatteryStatService != NULL) {
129d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        return mBatteryStatService;
130d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    }
131d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // get battery service from service manager
1322606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    const sp<IServiceManager> sm(defaultServiceManager());
1332606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (sm != NULL) {
1342606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        const String16 name("batterystats");
135d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        mBatteryStatService =
136d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang                interface_cast<IBatteryStats>(sm->getService(name));
1372606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mBatteryStatService == NULL) {
1382606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            ALOGE("batterystats service unavailable!");
139d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            return NULL;
140d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
141d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        mDeathNotifier = new DeathNotifier();
142d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        if (IInterface::asBinder(mBatteryStatService)->
143d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang                linkToDeath(mDeathNotifier) != OK) {
144d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mBatteryStatService.clear();
145d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mDeathNotifier.clear();
146d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            return NULL;
1472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
148d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        // notify start now if media already started
149d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        if (mVideoRefCount > 0) {
150d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mBatteryStatService->noteStartVideo(AID_MEDIA);
151d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
152d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        if (mAudioRefCount > 0) {
153d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mBatteryStatService->noteStartAudio(AID_MEDIA);
154d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
155d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    }
156d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    return mBatteryStatService;
157d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
158d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
159d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong ZhangMediaCodec::BatteryNotifier::~BatteryNotifier() {
160d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mDeathNotifier != NULL) {
161d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        IInterface::asBinder(mBatteryStatService)->
162d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang                unlinkToDeath(mDeathNotifier);
1632606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1642606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1652606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1662606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartVideo() {
167d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
168d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
169d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mVideoRefCount == 0 && batteryService != NULL) {
170d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStartVideo(AID_MEDIA);
1712606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1722606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount++;
1732606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1742606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1752606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopVideo() {
176d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
1772606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mVideoRefCount == 0) {
1782606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        ALOGW("BatteryNotifier::noteStop(): video refcount is broken!");
1792606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        return;
1802606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1812606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1822606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount--;
183d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
184d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mVideoRefCount == 0 && batteryService != NULL) {
185d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStopVideo(AID_MEDIA);
1862606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1872606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1882606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1892606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartAudio() {
190d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
191d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
192d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mAudioRefCount == 0 && batteryService != NULL) {
193d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStartAudio(AID_MEDIA);
1942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1952606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount++;
1962606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1972606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1982606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopAudio() {
199d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
2002606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mAudioRefCount == 0) {
2012606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        ALOGW("BatteryNotifier::noteStop(): audio refcount is broken!");
2022606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        return;
2032606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
2042606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
2052606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount--;
206d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
207d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mAudioRefCount == 0 && batteryService != NULL) {
208d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStopAudio(AID_MEDIA);
2092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
2102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
211d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
212d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangvoid MediaCodec::BatteryNotifier::onBatteryStatServiceDied() {
213d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
214d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    mBatteryStatService.clear();
215d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    mDeathNotifier.clear();
216d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // Do not reset mVideoRefCount and mAudioRefCount here. The ref
217d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // counting is independent of the battery service availability.
218d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // We need this if battery service becomes available after media
219d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // started.
220d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
221d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
22267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy() {
22367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
22467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
22567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
22667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService != NULL) {
22767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        IInterface::asBinder(mService)->unlinkToDeath(this);
22867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
22967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
23067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
23167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::init() {
23267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IServiceManager> sm = defaultServiceManager();
23367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
23467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService = interface_cast<IResourceManagerService>(binder);
23567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
23667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        ALOGE("Failed to get ResourceManagerService");
23767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
23867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
23967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (IInterface::asBinder(mService)->linkToDeath(this) != OK) {
24067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        mService.clear();
24167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        ALOGE("Failed to linkToDeath to ResourceManagerService.");
24267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
24367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
24467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
24567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
24667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) {
24767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    ALOGW("ResourceManagerService died.");
24867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
24967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService.clear();
25067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
25167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
25267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::addResource(
25367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int pid,
25467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int64_t clientId,
25567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        const sp<IResourceManagerClient> client,
25667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        const Vector<MediaResource> &resources) {
25767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
25867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
25967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
26067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
26167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService->addResource(pid, clientId, client, resources);
26267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
26367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
26467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) {
26567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
26667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
26767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
26867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
26967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService->removeResource(clientId);
27067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
27167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
27267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wubool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
27367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int callingPid, const Vector<MediaResource> &resources) {
27467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
27567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
27667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return false;
27767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
27867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return mService->reclaimResource(callingPid, resources);
27967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
28067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
2815778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
2825778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType(
283251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err) {
2845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
2855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
286251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
287251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
288251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
289251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
290251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
2945778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName(
295251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const sp<ALooper> &looper, const char *name, status_t *err) {
2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
298251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */);
299251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
300251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
301251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
302251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3055778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::MediaCodec(const sp<ALooper> &looper)
3065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mState(UNINITIALIZED),
3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mLooper(looper),
30892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar      mCodec(NULL),
3097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden      mReplyID(0),
3105778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFlags(0),
311251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung      mStickyError(OK),
3125778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSoftRenderer(NULL),
313ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar      mResourceManagerClient(new ResourceManagerClient(this)),
314ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar      mResourceManagerService(new ResourceManagerServiceProxy()),
3152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mBatteryStatNotified(false),
3162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mIsVideo(false),
31767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoWidth(0),
31867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoHeight(0),
3195778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputTimeoutGeneration(0),
3205778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputReplyID(0),
3215778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueOutputTimeoutGeneration(0),
3226507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mDequeueOutputReplyID(0),
3233d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHaveInputSurface(false),
3243d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHavePendingInputBuffers(false) {
3255778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3275778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() {
3285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mState, UNINITIALIZED);
32967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->removeResource(getId(mResourceManagerClient));
3305778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
3335778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse(
3345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg, sp<AMessage> *response) {
3355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(response);
3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!(*response)->findInt32("err", &err)) {
3425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = OK;
3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
3465778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
348c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang// static
3493f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarvoid MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
350c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response = new AMessage;
351c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->setInt32("err", err);
352c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->postReply(replyID);
353c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
354c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
355dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hungstatus_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
35667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->init();
35767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
358671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // save init parameters for reset
359671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitName = name;
360671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitNameIsType = nameIsType;
361671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitIsEncoder = encoder;
362671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Current video decoders do not return from OMX_FillThisBuffer
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // quickly, violating the OpenMAX specs, until that is remedied
3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // we need to invest in an extra looper to free the main event
3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // queue.
367744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
368bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung    if (nameIsType || !strncasecmp(name.c_str(), "omx.", 4)) {
369744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        mCodec = new ACodec;
370744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    } else if (!nameIsType
371bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung            && !strncasecmp(name.c_str(), "android.filter.", 15)) {
372744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        mCodec = new MediaFilter;
373744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    } else {
374744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        return NAME_NOT_FOUND;
375744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    }
376744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
37767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    bool secureCodec = false;
378dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung    if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) {
37967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        mIsVideo = true;
3806f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen    } else {
3816f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        AString tmp = name;
3826f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (tmp.endsWith(".secure")) {
38367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            secureCodec = true;
3846f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            tmp.erase(tmp.size() - 7, 7);
3856f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
38660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
3876f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
3886f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (codecIdx >= 0) {
38960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx);
39060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            Vector<AString> mimes;
39160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            info->getSupportedMimes(&mimes);
39260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            for (size_t i = 0; i < mimes.size(); i++) {
39360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                if (mimes[i].startsWith("video/")) {
39467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mIsVideo = true;
39560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                    break;
3966f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                }
3976f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            }
3986f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
3995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
40267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // video codec needs dedicated looper
4035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCodecLooper == NULL) {
4045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper = new ALooper;
4055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->setName("CodecLooper");
4065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodecLooper->registerHandler(mCodec);
4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mLooper->registerHandler(mCodec);
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mLooper->registerHandler(this);
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4161d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this));
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4181d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatInit, this);
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("name", name);
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("nameIsType", nameIsType);
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType) {
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("encoder", encoder);
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
42767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
42867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = secureCodec ? kResourceSecureCodec : kResourceNonSecureCodec;
42967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(type), 1));
43067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
43167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
43267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
43367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) {
43467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
43567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
43667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
43767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
43867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
43967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
44067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
44167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
44267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
44367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
44467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
447c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) {
4481d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetCallback, this);
449c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    msg->setMessage("callback", callback);
450c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
451c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response;
452c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    return PostAndAwaitResponse(msg, &response);
453c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
454c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
4555778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure(
4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &format,
4571a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        const sp<Surface> &nativeWindow,
4581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        const sp<ICrypto> &crypto,
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags) {
4601d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
46367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("width", &mVideoWidth);
46467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("height", &mVideoHeight);
46567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
46667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setMessage("format", format);
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nativeWindow != NULL) {
4711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setObject(
4721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                "native-window",
4731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                new NativeWindowWrapper(nativeWindow));
4741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    }
4751bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
4761bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (crypto != NULL) {
4771bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setPointer("crypto", crypto.get());
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
48067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // save msg for reset
48167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mConfigureMsg = msg;
482f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
48367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
48467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
48567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = (mFlags & kFlagIsSecure) ?
48667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            kResourceSecureCodec : kResourceNonSecureCodec;
48767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(type), 1));
48867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
48967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
49067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
49167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
49267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
49367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
49467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) {
49567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
49667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
49767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
498f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
49967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
50067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
50167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK && err != INVALID_OPERATION) {
50267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // MediaCodec now set state to UNINITIALIZED upon any fatal error.
50367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // To maintain backward-compatibility, do a reset() to put codec
50467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // back into INITIALIZED state.
50567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // But don't reset if the err is INVALID_OPERATION, which means
50667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // the configure failure is due to wrong state.
50767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
50867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGE("configure failed with err 0x%08x, resetting...", err);
50967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            reset();
51067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
51167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
51267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
51367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
514f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    }
515f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    return err;
5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface(
5197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<IGraphicBufferProducer>* bufferProducer) {
5201d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this);
5217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
5237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err = PostAndAwaitResponse(msg, &response);
5247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == NO_ERROR) {
5257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // unwrap the sp<IGraphicBufferProducer>
5267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<RefBase> obj;
5277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        bool found = response->findObject("input-surface", &obj);
5287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        CHECK(found);
5297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<BufferProducerWrapper> wrapper(
5307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                static_cast<BufferProducerWrapper*>(obj.get()));
5317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        *bufferProducer = wrapper->getBufferProducer();
5327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
5337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGW("createInputSurface failed, err=%d", err);
5347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
5357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return err;
5367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
53867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuuint64_t MediaCodec::getGraphicBufferSize() {
53967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (!mIsVideo) {
54067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return 0;
54167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
54267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
54367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    uint64_t size = 0;
54467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]);
54567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (size_t i = 0; i < portNum; ++i) {
54667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // TODO: this is just an estimation, we should get the real buffer size from ACodec.
54767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2;
54867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
54967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return size;
55067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
55167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
55267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::addResource(const char *type, uint64_t value) {
55367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
55467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(type), value));
55567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->addResource(
55667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            getCallingPid(), getId(mResourceManagerClient), mResourceManagerClient, resources);
55767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
55867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() {
5601d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, this);
5615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
56267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
56367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
56467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = (mFlags & kFlagIsSecure) ?
56567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            kResourceSecureCodec : kResourceNonSecureCodec;
56667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(type), 1));
56767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
56867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
56967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
57067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
57167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
57267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
57367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) {
57467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
57567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
57667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Recover codec from previous error before retry start.
57767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = reset();
57867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
57967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to reset codec");
58067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
58167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
58267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            sp<AMessage> response;
58367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = PostAndAwaitResponse(mConfigureMsg, &response);
58467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
58567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to configure codec");
58667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
58767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
58867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
58967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
59067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
59167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
59267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
59367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
59467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
59567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
59667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
5975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() {
6001d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, this);
6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
6035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
6045778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
606c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() {
6071d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRelease, this);
608c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
609c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> response;
610c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return PostAndAwaitResponse(msg, &response);
611c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
612c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
613671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnarstatus_t MediaCodec::reset() {
614671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    /* When external-facing MediaCodec object is created,
615671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       it is already initialized.  Thus, reset is essentially
616671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       release() followed by init(), plus clearing the state */
617671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
618671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    status_t err = release();
619671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
620671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // unregister handlers
621671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (mCodec != NULL) {
622671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        if (mCodecLooper != NULL) {
623671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mCodecLooper->unregisterHandler(mCodec->id());
624671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        } else {
625671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mLooper->unregisterHandler(mCodec->id());
626671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        }
627671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mCodec = NULL;
628671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
629671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mLooper->unregisterHandler(id());
630671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
631671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mFlags = 0;    // clear all flags
632251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mStickyError = OK;
633671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
634671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // reset state not reset by setState(UNINITIALIZED)
635671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mReplyID = 0;
636671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputReplyID = 0;
637671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputReplyID = 0;
638671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputTimeoutGeneration = 0;
639671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputTimeoutGeneration = 0;
640671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mHaveInputSurface = false;
641671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
642671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (err == OK) {
643dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung        err = init(mInitName, mInitNameIsType, mInitIsEncoder);
644671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
645671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    return err;
646671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar}
647671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
6485778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer(
6495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index,
6505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t offset,
6515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t size,
6525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t presentationTimeUs,
6535b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
6545b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
6555b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
6565b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
6575b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
6585b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
6591d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
6605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
6615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("offset", offset);
6625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("size", size);
6635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
6645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
6655b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
6665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
6685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
6695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6714b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer(
6724b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t index,
6734b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t offset,
6744b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const CryptoPlugin::SubSample *subSamples,
6754b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t numSubSamples,
6764b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t key[16],
6774b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t iv[16],
6784b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CryptoPlugin::Mode mode,
6794b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int64_t presentationTimeUs,
6805b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
6815b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
6825b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
6835b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
6845b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
6855b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
6861d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
6874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("index", index);
6884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("offset", offset);
6894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("subSamples", (void *)subSamples);
6904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("numSubSamples", numSubSamples);
6914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("key", (void *)key);
6924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("iv", (void *)iv);
6934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("mode", mode);
6944b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
6954b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("flags", flags);
6965b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
6974b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
6984b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    sp<AMessage> response;
6995b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    status_t err = PostAndAwaitResponse(msg, &response);
7005b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
7015b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    return err;
7024b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber}
7034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
7045778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
7051d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this);
7065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
7075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
7155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
7175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer(
7205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *index,
7215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *offset,
7225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *size,
7235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t *presentationTimeUs,
7245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t *flags,
7255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeoutUs) {
7261d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this);
7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
7285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
7365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("offset", offset));
7375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("size", size));
7385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt64("timeUs", presentationTimeUs));
7395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt32("flags", (int32_t *)flags));
7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
7425778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
7451d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
7465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
7475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("render", true);
7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
7515778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
753fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) {
7541d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
755fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setSize("index", index);
756fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt32("render", true);
757fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt64("timestampNs", timestampNs);
758fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
759fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    sp<AMessage> response;
760fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    return PostAndAwaitResponse(msg, &response);
761fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar}
762fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
7635778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) {
7641d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
7655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
7665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
7695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() {
7721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this);
7737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
7747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
7757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return PostAndAwaitResponse(msg, &response);
7767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
7777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
7785778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
7791d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this);
7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findMessage("format", format));
7885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
7905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
792e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
7931d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this);
794e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
795e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> response;
796e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    status_t err;
797e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
798e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        return err;
799e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
800e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
801e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(response->findMessage("format", format));
802e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
803e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
804e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
805e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
806717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const {
8071d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetName, this);
808717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
809717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> response;
810717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    status_t err;
811717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
812717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        return err;
813717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
814717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
815717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    CHECK(response->findString("name", name));
816717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
817717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    return OK;
818717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo}
819717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
820e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnarstatus_t MediaCodec::getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const {
821e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
822e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setInt32("portIndex", kPortIndexInput);
823e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setPointer("buffers", buffers);
824e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setInt32("widevine", true);
825e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar
826e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    sp<AMessage> response;
827e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    return PostAndAwaitResponse(msg, &response);
828e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar}
829e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar
8305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
8311d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
8325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexInput);
8335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
8345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
8401d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
8415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexOutput);
8425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
8435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8465778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) {
8497bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
8507bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, buffer, &format);
8517bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8527bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8537bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) {
8547bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<ABuffer> buffer;
8557bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, &buffer, format);
8567bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8577bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8587bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) {
8597bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
8607bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexInput, index, buffer, &format);
8617bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8630e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnarbool MediaCodec::isExecuting() const {
8640e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    return mState == STARTED || mState == FLUSHED;
8650e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar}
8660e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar
8677bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat(
8687bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        size_t portIndex, size_t index,
8697bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        sp<ABuffer> *buffer, sp<AMessage> *format) {
8707bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // use mutex instead of a context switch
8717bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8727bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    buffer->clear();
8737bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    format->clear();
8740e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
8757bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        return INVALID_OPERATION;
8767bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
8777bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8787bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we do not want mPortBuffers to change during this section
8797bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we also don't want mOwnedByClient to change during this
8807bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
8817bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
8827bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    if (index < buffers->size()) {
8837bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        const BufferInfo &info = buffers->itemAt(index);
8847bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        if (info.mOwnedByClient) {
8850837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            // by the time buffers array is initialized, crypto is set
8860837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            if (portIndex == kPortIndexInput && mCrypto != NULL) {
8870837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar                *buffer = info.mEncryptedData;
8880837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            } else {
8890837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar                *buffer = info.mData;
8900837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            }
8917bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar            *format = info.mFormat;
8927bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        }
8937bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
8947bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return OK;
8957bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8967bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8975778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() {
8981d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatFlush, this);
8995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
9015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
9025778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
904496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() {
9051d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
906496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
907496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return OK;
908496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
909496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
910575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
9111d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this);
912575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->setMessage("notify", notify);
913575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->post();
914575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
915575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
9165778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
9175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9185778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() {
9195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueInputPending) {
920c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
9215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueInputTimeoutGeneration;
9235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueInputReplyID = 0;
9245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueInputPending;
9255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueOutputPending) {
928c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
9295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueOutputTimeoutGeneration;
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueOutputReplyID = 0;
9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueOutputPending;
9335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9363f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
9370e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
939c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(replyID, INVALID_OPERATION);
9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return true;
941251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
942251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        PostReplyWithError(replyID, getStickyError());
943251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return true;
9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = dequeuePortBuffer(kPortIndexInput);
9475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index < 0) {
9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(index, -EAGAIN);
9505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return false;
9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
9545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setSize("index", index);
9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
9565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9603f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
9625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9630e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
966251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
967251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        response->setInt32("err", getStickyError());
9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputBuffersChanged) {
9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputFormatChanged) {
9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_FORMAT_CHANGED);
9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
9745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
9755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (index < 0) {
9785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(index, -EAGAIN);
9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return false;
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ABuffer> &buffer =
9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
9845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("index", index);
9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("offset", buffer->offset());
9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("size", buffer->size());
9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeUs;
9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt64("timeUs", timeUs);
9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t omxFlags;
9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags = 0;
9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_SYNCFRAME;
10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_CODECCONFIG;
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_EOS) {
10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_EOS;
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("flags", flags);
10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10165778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatCodecNotify:
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t what;
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("what", &what));
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            switch (what) {
102492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatError:
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1026251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    int32_t err, actionCode;
1027251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("err", &err));
1028251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("actionCode", &actionCode));
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10309e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                    ALOGE("Codec reported err %#x, actionCode %d, while in state %d",
10319e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            err, actionCode, mState);
1032251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    if (err == DEAD_OBJECT) {
1033aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mFlags |= kFlagSawMediaServerDie;
103452dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                        mFlags &= ~kFlagIsComponentAllocated;
1035aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    }
1036aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
10375530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    bool sendErrorResponse = true;
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    switch (mState) {
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case INITIALIZING:
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(UNINITIALIZED);
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case CONFIGURING:
10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1048c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1049c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : INITIALIZED);
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTING:
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1055c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1056c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : CONFIGURED);
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STOPPING:
1061c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        case RELEASING:
10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // Ignore the error, assuming we'll still get
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // the shutdown complete notification.
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10665530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
106703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
1068aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            if (mFlags & kFlagSawMediaServerDie) {
106903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // MediaServer died, there definitely won't
107003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // be a shutdown complete notification after
107103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // all.
107203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
107303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // note that we're directly going from
107403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // STOPPING->UNINITIALIZED, instead of the
107503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // usual STOPPING->INITIALIZED state.
107603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                setState(UNINITIALIZED);
10776e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                if (mState == RELEASING) {
10786e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                    mComponentName.clear();
10796e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                }
108003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                (new AMessage)->postReply(mReplyID);
108103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                            }
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case FLUSHING:
10865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10879e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            if (actionCode == ACTION_CODE_FATAL) {
10889e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(UNINITIALIZED);
10899e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            } else {
10909e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(
10919e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                        (mFlags & kFlagIsAsync) ? FLUSHED : STARTED);
10929e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            }
10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10960e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        case FLUSHED:
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTED:
10985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10995530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
11005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1101251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1102575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
11035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            cancelPendingDequeueOperations();
1105c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1106c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1107251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1108251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1109251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1110251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1111251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1112251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1113251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1114251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1115251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1116251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1117251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1118c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        default:
11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11245530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1126251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1127575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1128c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1129251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            // actionCode in an uninitialized state is always fatal.
1130251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            if (mState == UNINITIALIZED) {
1131251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                actionCode = ACTION_CODE_FATAL;
1132251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1133c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1134251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1135251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1136251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1137251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1138251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1139251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1140251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1141251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1142251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1143251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1144251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1145c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11505530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (sendErrorResponse) {
1151251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                        PostReplyWithError(mReplyID, err);
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
115692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentAllocated:
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, INITIALIZING);
11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(INITIALIZED);
116052dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags |= kFlagIsComponentAllocated;
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1162717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    CHECK(msg->findString("componentName", &mComponentName));
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1164717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.startsWith("OMX.google.")) {
11653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    } else {
11673a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags &= ~kFlagUsesSoftwareRenderer;
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
117067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    String8 resourceType;
1171717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.endsWith(".secure")) {
11721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags |= kFlagIsSecure;
117367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                        resourceType = String8(kResourceSecureCodec);
11741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    } else {
11751bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags &= ~kFlagIsSecure;
117667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                        resourceType = String8(kResourceNonSecureCodec);
11771bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    }
117867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    addResource(resourceType, 1);
11791bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
118492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentConfigured:
11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, CONFIGURING);
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    // reset input surface flag
11896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    mHaveInputSurface = false;
11906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
1191e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("input-format", &mInputFormat));
1192e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("output-format", &mOutputFormat));
1193e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
11943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    int32_t usingSwRenderer;
11953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer)
11963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            && usingSwRenderer) {
11973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
11983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
11992606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang                    setState(CONFIGURED);
12005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
12025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
120492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatInputSurfaceCreated:
12057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
120692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to initiateCreateInputSurface()
12077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err = NO_ERROR;
12087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
12097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (!msg->findInt32("err", &err)) {
12107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        sp<RefBase> obj;
12117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        msg->findObject("input-surface", &obj);
12127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        CHECK(obj != NULL);
12137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setObject("input-surface", obj);
12146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                        mHaveInputSurface = true;
12157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    } else {
12167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
12177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
12187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
12197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
12207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
12217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
122292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatSignaledInputEOS:
12237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
122492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to signalEndOfInputStream()
12257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
12267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err;
12277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (msg->findInt32("err", &err)) {
12287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
12297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
12307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
12317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
12327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
12337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
123592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatBuffersAllocated:
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
12377bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar                    Mutex::Autolock al(mBufferLock);
12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t portIndex;
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("portIndex", &portIndex));
12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("%s buffers allocated",
12425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          portIndex == kPortIndexInput ? "input" : "output");
12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(portIndex == kPortIndexInput
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            || portIndex == kPortIndexOutput);
12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mPortBuffers[portIndex].clear();
12485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1251eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    sp<RefBase> obj;
1252eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    CHECK(msg->findObject("portDesc", &obj));
1253eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
125492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    sp<CodecBase::PortDescription> portDesc =
125592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                        static_cast<CodecBase::PortDescription *>(obj.get());
12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1257eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    size_t numBuffers = portDesc->countBuffers();
12585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1259c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    size_t totalSize = 0;
1260c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    for (size_t i = 0; i < numBuffers; ++i) {
1261c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1262c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            totalSize += portDesc->bufferAt(i)->capacity();
1263c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        }
1264c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1265c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1266c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    if (totalSize) {
1267c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        mDealer = new MemoryDealer(totalSize, "MediaCodec");
1268c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1269c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1270eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    for (size_t i = 0; i < numBuffers; ++i) {
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        BufferInfo info;
1272eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mBufferID = portDesc->bufferIDAt(i);
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mOwnedByClient = false;
1274eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mData = portDesc->bufferAt(i);
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12761bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1277c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            sp<IMemory> mem = mDealer->allocate(info.mData->capacity());
1278ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            info.mEncryptedData =
1279c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                                new ABuffer(mem->pointer(), info.mData->capacity());
1280c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            info.mSharedEncryptedBuffer = mem;
1281ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        }
1282ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        buffers->push_back(info);
12845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (portIndex == kPortIndexOutput) {
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (mState == STARTING) {
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // We're always allocating output buffers after
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // allocating input buffers, so this is a good
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // indication that now all buffers are allocated.
129167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            if (mIsVideo) {
129267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                                addResource(kResourceGraphicMemory, getGraphicBufferSize());
129367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            }
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
12955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            (new AMessage)->postReply(mReplyID);
12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        } else {
12975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagOutputBuffersChanged;
1298575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
12995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
130492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatOutputFormatChanged:
13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("codec output format changed");
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1308475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    if (mSoftRenderer == NULL &&
1309475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                            mNativeWindow != NULL &&
13103a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            (mFlags & kFlagUsesSoftwareRenderer)) {
13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        AString mime;
13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(msg->findString("mime", &mime));
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1314475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                        if (mime.startsWithIgnoreCase("video/")) {
1315475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                            mSoftRenderer = new SoftwareRenderer(mNativeWindow);
13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mOutputFormat = msg;
1320e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1321e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagIsEncoder) {
1322e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // Before we announce the format change we should
1323e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // collect codec specific data and amend the output
1324e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format as necessary.
1325e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagGatherCodecSpecificData;
1326c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagIsAsync) {
1327c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputFormatChanged();
1328e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
1329e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagOutputFormatChanged;
1330e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        postActivityNotificationIfPossible();
1331e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
13322514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
13332514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    // Notify mCrypto of video resolution changes
13342514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    if (mCrypto != NULL) {
13358140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        int32_t left, top, right, bottom, width, height;
13368140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
13378140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
13388140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        } else if (mOutputFormat->findInt32("width", &width)
13398140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                                && mOutputFormat->findInt32("height", &height)) {
13408140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(width, height);
13418140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        }
13422514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    }
13432514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
134792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFillThisBuffer:
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1351c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1352c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1353c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexInput);
13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13588ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    if (!mCSD.empty()) {
13598ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
13608ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        CHECK_GE(index, 0);
13618ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
13628ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // If codec specific data had been specified as
13638ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // part of the format in the call to configure and
13648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // if there's more csd left, we submit it here
13658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // clients only get access to input buffers once
13668ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // this data has been exhausted.
13678ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
13688ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        status_t err = queueCSDInputBuffer(index);
13698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
13708ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        if (err != OK) {
13718ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            ALOGE("queueCSDInputBuffer failed w/ error %d",
13728ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                                  err);
13738ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1374251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1375575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1376575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
13778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            cancelPendingDequeueOperations();
13788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        }
13798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        break;
13808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    }
13818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1382c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
13836e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        if (!mHaveInputSurface) {
13843d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            if (mState == FLUSHED) {
13853d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                mHavePendingInputBuffers = true;
13863d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            } else {
13873d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                onInputBufferAvailable();
13883d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            }
13896e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        }
1390c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueInputPending) {
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueInputTimeoutGeneration;
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueInputPending;
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueInputReplyID = 0;
1396575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1397575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
140292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatDrainThisBuffer:
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1406c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1407c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1408c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexOutput);
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14132d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    sp<ABuffer> buffer;
14142d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    CHECK(msg->findBuffer("buffer", &buffer));
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxFlags;
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("flags", &omxFlags));
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    buffer->meta()->setInt32("omxFlags", omxFlags);
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1421e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagGatherCodecSpecificData) {
1422e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // This is the very first output buffer after a
1423e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format change was signalled, it'll either contain
1424e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // the one piece of codec specific data we can expect
1425e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // or there won't be codec specific data.
1426e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
1427e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            status_t err =
1428e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                amendOutputFormatWithCodecSpecificData(buffer);
1429e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1430e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (err != OK) {
1431e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                ALOGE("Codec spit out malformed codec "
1432e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                      "specific data!");
1433e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
1434e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
1435e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1436e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags &= ~kFlagGatherCodecSpecificData;
1437c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        if (mFlags & kFlagIsAsync) {
1438c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            onOutputFormatChanged();
1439c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        } else {
1440c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            mFlags |= kFlagOutputFormatChanged;
1441c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        }
1442e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
1443e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1444c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
1445c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputBufferAvailable();
1446c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueOutputPending) {
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueOutputTimeoutGeneration;
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueOutputPending;
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueOutputReplyID = 0;
1452575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1453575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
1455575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
145992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatEOS:
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // We already notify the client of this by using the
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // corresponding flag in "onOutputBufferReady".
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
146692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatShutdownCompleted:
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1468c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == STOPPING) {
1469c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(INITIALIZED);
1470c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    } else {
1471c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        CHECK_EQ(mState, RELEASING);
1472c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(UNINITIALIZED);
14736e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        mComponentName.clear();
1474c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    }
147552dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags &= ~kFlagIsComponentAllocated;
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
147767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mResourceManagerService->removeResource(getId(mResourceManagerClient));
147867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
148392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFlushCompleted:
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14855530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (mState != FLUSHING) {
14865530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        ALOGW("received FlushCompleted message in state %d",
14875530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                                mState);
14885530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        break;
14895530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    }
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14910e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    if (mFlags & kFlagIsAsync) {
14920e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(FLUSHED);
14930e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    } else {
14940e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(STARTED);
14950e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        mCodec->signalResume();
14960e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    }
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                default:
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    TRESPASS();
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatInit:
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
15103f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != UNINITIALIZED) {
1514c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(INITIALIZING);
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            AString name;
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findString("name", &name));
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t nameIsType;
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t encoder = false;
15260db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            CHECK(msg->findInt32("nameIsType", &nameIsType));
15270db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            if (nameIsType) {
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(msg->findInt32("encoder", &encoder));
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format = new AMessage;
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (nameIsType) {
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("mime", name.c_str());
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", encoder);
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("componentName", name.c_str());
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateAllocateComponent(format);
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1544c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        case kWhatSetCallback:
1545c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        {
15463f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1547c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
1548c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1549c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mState == UNINITIALIZED
1550c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    || mState == INITIALIZING
15510e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    || isExecuting()) {
15520e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                // callback can't be set after codec is executing,
1553c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // or before it's initialized (as the callback
1554c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // will be cleared when it goes to INITIALIZED)
1555c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1556c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1557c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1558c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1559c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> callback;
1560c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->findMessage("callback", &callback));
1561c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1562c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mCallback = callback;
1563c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1564c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mCallback != NULL) {
1565c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGI("MediaCodec will operate in async mode");
1566c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags |= kFlagIsAsync;
1567c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            } else {
1568c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags &= ~kFlagIsAsync;
1569c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1570c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1571c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> response = new AMessage;
1572c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            response->postReply(replyID);
1573c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            break;
1574c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
1575c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatConfigure:
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
15783f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED) {
1582c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<RefBase> obj;
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findObject("native-window", &obj)) {
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                obj.clear();
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format;
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("format", &format));
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (obj != NULL) {
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setObject("native-window", obj);
15961bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
15977541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                status_t err = setNativeWindow(
15987541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    static_cast<NativeWindowWrapper *>(obj.get())
15997541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                        ->getSurfaceTextureClient());
16007541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
16017541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                if (err != OK) {
1602c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    PostReplyWithError(replyID, err);
16037541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    break;
16041bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
16051bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
16067541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                setNativeWindow(NULL);
16071bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            }
16081bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
16097541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            mReplyID = replyID;
16107541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            setState(CONFIGURING);
16117541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
16121bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *crypto;
16131bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!msg->findPointer("crypto", &crypto)) {
16141bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                crypto = NULL;
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16171bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            mCrypto = static_cast<ICrypto *>(crypto);
16181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags & CONFIGURE_FLAG_ENCODE) {
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", true);
1624e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                mFlags |= kFlagIsEncoder;
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16278ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            extractCSD(format);
16288ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateConfigureComponent(format);
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatCreateInputSurface:
16347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
16353f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
16377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
16387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            // Must be configured, but can't have been started yet.
16397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != CONFIGURED) {
1640c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
16427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
16437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
16447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
16457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->initiateCreateInputSurface();
16467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
16477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
16487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStart:
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
16513f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16540e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            if (mState == FLUSHED) {
1655d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                setState(STARTED);
16563d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                if (mHavePendingInputBuffers) {
16573d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    onInputBufferAvailable();
16583d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    mHavePendingInputBuffers = false;
16593d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                }
16600e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                mCodec->signalResume();
16610e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                PostReplyWithError(replyID, OK);
1662d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                break;
16630e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            } else if (mState != CONFIGURED) {
1664c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STARTING);
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateStart();
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStop:
1676c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case kWhatRelease:
1677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
1678aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            State targetState =
1679aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1680aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
16813f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1682c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1683c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
168433223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung            if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
168533223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                    && mState != INITIALIZED
16860e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    && mState != CONFIGURED && !isExecuting()) {
168733223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 1) Permit release to shut down the component if allocated.
168833223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                //
168933223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 2) We may be in "UNINITIALIZED" state already and
169052dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                // also shutdown the encoder/decoder without the
169103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // client being aware of this if media server died while
169203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // we were being stopped. The client would assume that
169303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // after stop() returned, it would be safe to call release()
169403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // and it should be in this case, no harm to allow a release()
169503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // if we're already uninitialized.
1696c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                sp<AMessage> response = new AMessage;
16976e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                status_t err = mState == targetState ? OK : INVALID_OPERATION;
16986e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                response->setInt32("err", err);
16996e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (err == OK && targetState == UNINITIALIZED) {
17006e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
17016e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1702c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                response->postReply(replyID);
1703c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                break;
1704c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
1705c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1706aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            if (mFlags & kFlagSawMediaServerDie) {
1707aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // It's dead, Jim. Don't expect initiateShutdown to yield
1708aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // any useful results now...
1709aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                setState(UNINITIALIZED);
17106e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (targetState == UNINITIALIZED) {
17116e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
17126e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1713aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (new AMessage)->postReply(replyID);
1714aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                break;
1715aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            }
1716aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1717c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mReplyID = replyID;
1718aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1719aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1720aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            mCodec->initiateShutdown(
1721aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    msg->what() == kWhatStop /* keepComponentAllocated */);
1722c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputBuffer:
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
17293f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1732c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1733c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1734c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1735c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1736c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1737c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
17386507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            if (mHaveInputSurface) {
17396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                ALOGE("dequeueInputBuffer can't be used with input surface");
1740c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
17416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                break;
17426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            }
17436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1752c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueInputPending;
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = replyID;
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
17611d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueInputTimedOut, this);
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueInputTimeoutGeneration);
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputTimedOut:
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueInputTimeoutGeneration) {
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueInputPending);
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1781c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueInputPending;
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = 0;
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatQueueInputBuffer:
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
17903f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1793251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1794c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1796251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1797251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1798251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onQueueInputBuffer(msg);
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1803c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputBuffer:
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18093f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1812c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1813c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1814c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1815c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1816c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1817c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1826c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueOutputPending;
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = replyID;
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
18351d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueOutputTimedOut, this);
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueOutputTimeoutGeneration);
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputTimedOut:
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueOutputTimeoutGeneration) {
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueOutputPending);
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1855c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueOutputPending;
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = 0;
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatReleaseOutputBuffer:
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18643f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1867251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1868c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1870251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1871251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1872251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onReleaseOutputBuffer(msg);
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1877c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatSignalEndOfInputStream:
18827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
18833f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
18857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
1886251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1887c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
18887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
1889251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1890251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1891251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
18927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
18937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
18947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
18957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalEndOfInputStream();
18967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
18977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
18987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetBuffers:
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19013f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1903e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // Unfortunately widevine legacy source requires knowing all of the
1904e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // codec input buffers, so we have to provide them even in async mode.
1905e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            int32_t widevine = 0;
1906e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            msg->findInt32("widevine", &widevine);
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1908e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            if (!isExecuting() || ((mFlags & kFlagIsAsync) && !widevine)) {
1909c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1911251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1912251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1913251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t portIndex;
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("portIndex", &portIndex));
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            Vector<sp<ABuffer> > *dstBuffers;
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            dstBuffers->clear();
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (size_t i = 0; i < srcBuffers.size(); ++i) {
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                const BufferInfo &info = srcBuffers.itemAt(i);
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1928ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                dstBuffers->push_back(
19291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        (portIndex == kPortIndexInput && mCrypto != NULL)
1930ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                ? info.mEncryptedData : info.mData);
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (new AMessage)->postReply(replyID);
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatFlush:
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19393f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1942251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1943c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1945251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1946251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1947251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
19510e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            // TODO: skip flushing if already FLUSHED
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(FLUSHING);
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalFlush();
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1959e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        case kWhatGetInputFormat:
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetOutputFormat:
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
1962e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            sp<AMessage> format =
1963e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
1964e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
19653f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1968e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if ((mState != CONFIGURED && mState != STARTING &&
19690e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != STARTED && mState != FLUSHING &&
19700e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != FLUSHED)
1971e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    || format == NULL) {
1972c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1974251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1975251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1976251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
1980e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            response->setMessage("format", format);
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1985496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
1986496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
1987496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mCodec->signalRequestIDRFrame();
1988496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
1989496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
1990496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
1991575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatRequestActivityNotification:
1992575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        {
1993575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(mActivityNotify == NULL);
1994575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(msg->findMessage("notify", &mActivityNotify));
1995575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1996575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            postActivityNotificationIfPossible();
1997575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
1998575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
1999575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2000717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        case kWhatGetName:
2001717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        {
20023f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2003717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            CHECK(msg->senderAwaitsResponse(&replyID));
2004717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2005717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            if (mComponentName.empty()) {
2006c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
2007717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                break;
2008717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            }
2009717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2010717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            sp<AMessage> response = new AMessage;
2011717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->setString("name", mComponentName.c_str());
2012717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->postReply(replyID);
2013717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            break;
2014717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        }
2015717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2016a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
2017a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
20183f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2019a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
2020a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2021a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
2022a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
2023a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2024a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = onSetParameters(params);
2025a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2026c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
2027a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
2028a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
2029a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20358ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) {
20368ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.clear();
20378ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20388ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    size_t i = 0;
20398ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    for (;;) {
20408ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        sp<ABuffer> csd;
2041a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes        if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) {
20428ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            break;
20438ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        }
20448ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20458ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        mCSD.push_back(csd);
20468ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        ++i;
20478ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
20488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
2049a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
20508ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
20518ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20528ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
20538ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    CHECK(!mCSD.empty());
20548ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20557bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    const BufferInfo *info =
20567bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        &mPortBuffers[kPortIndexInput].itemAt(bufferIndex);
20578ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20588ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<ABuffer> csd = *mCSD.begin();
20598ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.erase(mCSD.begin());
20608ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20618ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    const sp<ABuffer> &codecInputData =
20628ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
20638ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    if (csd->size() > codecInputData->capacity()) {
20658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        return -EINVAL;
20668ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
20678ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20688ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    memcpy(codecInputData->data(), csd->data(), csd->size());
20698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20708ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    AString errorDetailMsg;
20718ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
20738ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("index", bufferIndex);
20748ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("offset", 0);
20758ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("size", csd->size());
20768ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt64("timeUs", 0ll);
20778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
20788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setPointer("errorDetailMsg", &errorDetailMsg);
20798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    return onQueueInputBuffer(msg);
20818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
20828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20835778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) {
20847541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (newState == INITIALIZED || newState == UNINITIALIZED) {
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        delete mSoftRenderer;
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSoftRenderer = NULL;
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        mCrypto.clear();
20897541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        setNativeWindow(NULL);
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2091671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mInputFormat.clear();
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mOutputFormat.clear();
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagStickyError;
2096e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagIsEncoder;
2097e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagGatherCodecSpecificData;
2098c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mFlags &= ~kFlagIsAsync;
2099251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mStickyError = OK;
2100575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2101575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2102c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mCallback.clear();
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2105717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if (newState == UNINITIALIZED) {
2106671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        // return any straggling buffers, e.g. if we got here on an error
2107671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        returnBuffersToCodec();
2108671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
2109aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // The component is gone, mediaserver's probably back up already
2110aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // but should definitely be back up should we try to instantiate
2111aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // another component.. and the cycle continues.
2112aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        mFlags &= ~kFlagSawMediaServerDie;
2113717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
2114717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mState = newState;
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    cancelPendingDequeueOperations();
21182606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
21192606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    updateBatteryStat();
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21225778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() {
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexInput);
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexOutput);
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21275778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
21297bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mNotify != NULL) {
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> msg = info->mNotify;
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mNotify = NULL;
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mOwnedByClient = false;
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (portIndex == kPortIndexInput) {
21427fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                /* no error, just returning buffers */
21437fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                msg->setInt32("err", OK);
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->post();
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAvailPortBuffers[portIndex].clear();
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21525778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers(
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t portIndex, const sp<AMessage> &msg) {
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2156609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    uint32_t bufferID;
2157609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mBufferID == bufferID) {
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(info->mNotify == NULL);
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("reply", &info->mNotify));
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2168475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            info->mFormat =
2169475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat;
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mAvailPortBuffers[portIndex].push_back(i);
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return i;
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TRESPASS();
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t offset;
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t timeUs;
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t flags;
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("offset", &offset));
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("flags", (int32_t *)&flags));
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const CryptoPlugin::SubSample *subSamples;
21934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    size_t numSubSamples;
21944b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *key;
21954b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *iv;
21964b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
21974b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
21984b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // We allow the simpler queueInputBuffer API to be used even in
21994b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // secure mode, by fabricating a single unencrypted subSample.
22004b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::SubSample ss;
22014b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22024b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    if (msg->findSize("size", &size)) {
22034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto != NULL) {
22044b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfClearData = size;
22054b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfEncryptedData = 0;
22064b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22074b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            subSamples = &ss;
22084b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            numSubSamples = 1;
22094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = NULL;
22104b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = NULL;
22114b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
22124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    } else {
22134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto == NULL) {
22144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            return -EINVAL;
22154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
22164b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
22184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findSize("numSubSamples", &numSubSamples));
22194b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("key", (void **)&key));
22204b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("iv", (void **)&iv));
22214b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22224b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int32_t tmp;
22234b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findInt32("mode", &tmp));
22244b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22254b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        mode = (CryptoPlugin::Mode)tmp;
22264b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22274b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size = 0;
22284b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
22294b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfClearData;
22304b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfEncryptedData;
22314b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
22324b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    }
22334b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexInput].size()) {
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (offset + size > info->mData->capacity()) {
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> reply = info->mNotify;
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->setRange(offset, size);
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->meta()->setInt64("timeUs", timeUs);
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_EOS) {
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("eos", true);
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_CODECCONFIG) {
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("csd", true);
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (mCrypto != NULL) {
22611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (size > info->mEncryptedData->capacity()) {
22621bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return -ERANGE;
2263ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2264ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
22655b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg;
22665b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
22675b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2268fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        ssize_t result = mCrypto->decrypt(
22691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                (mFlags & kFlagIsSecure) != 0,
22701bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                key,
22711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                iv,
22721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                mode,
2273c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                info->mSharedEncryptedBuffer,
2274c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                offset,
22754b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                subSamples,
22764b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                numSubSamples,
22775b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                info->mData->base(),
22785b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                errorDetailMsg);
22791bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
2280fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        if (result < 0) {
2281fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            return result;
2282ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2283ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2284fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        info->mData->setRange(0, result);
2285ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2286ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
22877bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
22887bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
22897bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
22907bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
22917bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
22922d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    reply->setBuffer("buffer", info->mData);
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    reply->post();
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22955b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    info->mNotify = NULL;
22965b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t render;
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("render", &render)) {
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        render = 0;
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23090e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexOutput].size()) {
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23237bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
23247bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
23257bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
23267bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
23277bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
23287bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
232979ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou    if (render && info->mData != NULL && info->mData->size() != 0) {
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mNotify->setInt32("render", true);
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2332fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
2333fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (msg->findInt64("timestampNs", &timestampNs)) {
2334fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            info->mNotify->setInt64("timestampNs", timestampNs);
2335fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        } else {
2336fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
2337fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
2338fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
2339fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
2340fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
2341fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
234247aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
2343fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
2344fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
2345fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
2346fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
2347fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mSoftRenderer != NULL) {
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mSoftRenderer->render(
2350475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    info->mData->data(), info->mData->size(),
2351475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    timestampNs, NULL, info->mFormat);
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify->post();
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify = NULL;
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (availBuffers->empty()) {
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EAGAIN;
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index = *availBuffers->begin();
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    availBuffers->erase(availBuffers->begin());
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!info->mOwnedByClient);
23757bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
23767bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
23777bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = true;
237803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
237903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        // set image-data
238003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        if (info->mFormat != NULL) {
238103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            sp<ABuffer> imageData;
238203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findBuffer("image-data", &imageData)) {
238303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setBuffer("image-data", imageData);
238403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
238503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            int32_t left, top, right, bottom;
238603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) {
238703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
238803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
238903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        }
23907bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return index;
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23957541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huberstatus_t MediaCodec::setNativeWindow(
23961a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        const sp<Surface> &surfaceTextureClient) {
23977541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    status_t err;
23987541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
23997541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (mNativeWindow != NULL) {
24007541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_disconnect(
24017541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
24027541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24037541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
24047541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGW("native_window_api_disconnect returned an error: %s (%d)",
24057541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
24067541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
24077541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24087541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow.clear();
24097541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
24107541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24117541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (surfaceTextureClient != NULL) {
24127541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_connect(
24137541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
24147541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24157541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
24167541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGE("native_window_api_connect returned an error: %s (%d)",
24177541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
24187541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24197541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            return err;
24207541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
24217541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24227541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow = surfaceTextureClient;
24237541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
24247541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24257541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    return OK;
24267541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber}
24277541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
2428c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() {
2429c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2430c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
2431c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2432c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
2433c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2434c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2435c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2436c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2437c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2438c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() {
2439c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2440c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
2441c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        const sp<ABuffer> &buffer =
2442c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
2443c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2444c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
2445c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2446c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("offset", buffer->offset());
2447c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("size", buffer->size());
2448c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2449c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int64_t timeUs;
2450c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2451c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2452c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt64("timeUs", timeUs);
2453c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2454c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int32_t omxFlags;
2455c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
2456c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2457c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        uint32_t flags = 0;
2458c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
2459c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_SYNCFRAME;
2460c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2461c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
2462c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_CODECCONFIG;
2463c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2464c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_EOS) {
2465c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_EOS;
2466c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2467c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2468c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("flags", flags);
2469c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2470c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2471c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2472c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2473c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2474749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) {
2475c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2476c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2477c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_ERROR);
2478c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("err", err);
2479749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        msg->setInt32("actionCode", actionCode);
2480749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang
2481749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        if (detail != NULL) {
2482749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang            msg->setString("detail", detail);
2483749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        }
2484c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2485c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2486c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2487c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2488c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2489c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() {
2490c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2491c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2492c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
2493c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setMessage("format", mOutputFormat);
2494c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2495c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2496c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2497c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2498c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2499575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() {
2500575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mActivityNotify == NULL) {
2501575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        return;
2502575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2503575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2504e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    bool isErrorOrOutputChanged =
2505e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            (mFlags & (kFlagStickyError
2506575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputBuffersChanged
2507e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    | kFlagOutputFormatChanged));
2508e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2509e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    if (isErrorOrOutputChanged
2510575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexInput].empty()
2511575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
2512e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        mActivityNotify->setInt32("input-buffers",
2513e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                mAvailPortBuffers[kPortIndexInput].size());
2514e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2515e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        if (isErrorOrOutputChanged) {
2516e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            // we want consumer to dequeue as many times as it can
2517e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers", INT32_MAX);
2518e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        } else {
2519e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers",
2520e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    mAvailPortBuffers[kPortIndexOutput].size());
2521e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        }
2522575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify->post();
2523575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2524575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2525575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
2526575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2527a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> &params) {
25281d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
2529a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
2530a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2531a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> response;
2532a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return PostAndAwaitResponse(msg, &response);
2533a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2534a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2535a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
2536a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    mCodec->signalSetParameters(params);
2537a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2538a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
2539a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2540a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2541e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData(
2542e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const sp<ABuffer> &buffer) {
2543e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    AString mime;
2544e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    CHECK(mOutputFormat->findString("mime", &mime));
2545e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2546e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
2547e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // Codec specific data should be SPS and PPS in a single buffer,
2548e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
2549e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // We separate the two and put them into the output format
2550e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // under the keys "csd-0" and "csd-1".
2551e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2552e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        unsigned csdIndex = 0;
2553e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2554e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *data = buffer->data();
2555e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t size = buffer->size();
2556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *nalStart;
2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t nalSize;
2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
2560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            sp<ABuffer> csd = new ABuffer(nalSize + 4);
2561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data() + 4, nalStart, nalSize);
2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            mOutputFormat->setBuffer(
2565a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes                    AStringPrintf("csd-%u", csdIndex).c_str(), csd);
2566e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            ++csdIndex;
2568e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2569e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (csdIndex != 2) {
2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return ERROR_MALFORMED;
2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    } else {
2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // For everything else we just stash the codec specific data into
2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // the output format as a single piece of csd under "csd-0".
2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mOutputFormat->setBuffer("csd-0", buffer);
2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return OK;
2580e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2581e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
25822606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() {
25832606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mState == CONFIGURED && !mBatteryStatNotified) {
25842606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
25852606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
25862606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
25872606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartVideo();
25882606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
25892606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartAudio();
25902606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
25912606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
25922606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = true;
25932606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
25942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
25952606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
25962606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
25972606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopVideo();
25982606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
25992606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopAudio();
26002606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
26012606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26022606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = false;
26032606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
26042606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
26052606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
2607