MediaCodec.cpp revision 575a5361fc970476cd7979638ee3ac00cc6e5024
1f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat/* 2f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Copyright 2012, The Android Open Source Project 3f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 4f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * you may not use this file except in compliance with the License. 6f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * You may obtain a copy of the License at 7f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 8f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * http://www.apache.org/licenses/LICENSE-2.0 9f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 10f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Unless required by applicable law or agreed to in writing, software 11f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * See the License for the specific language governing permissions and 14f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * limitations under the License. 15f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat */ 16f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 17f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat//#define LOG_NDEBUG 0 18fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#define LOG_TAG "MediaCodec" 19fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#include <utils/Log.h> 20f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 21a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <media/stagefright/MediaCodec.h> 22a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 23a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat#include "include/SoftwareRenderer.h" 24a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 25a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat#include <gui/SurfaceTextureClient.h> 26a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <media/ICrypto.h> 27f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <media/stagefright/foundation/ABuffer.h> 28f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <media/stagefright/foundation/ADebug.h> 29f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <media/stagefright/foundation/AMessage.h> 30f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <media/stagefright/foundation/AString.h> 31f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <media/stagefright/foundation/hexdump.h> 32fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#include <media/stagefright/ACodec.h> 33fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#include <media/stagefright/MediaErrors.h> 34f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <media/stagefright/MetaData.h> 35ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehat#include <media/stagefright/NativeWindowWrapper.h> 36a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 37a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatnamespace android { 38a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 39b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat// static 40f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatsp<MediaCodec> MediaCodec::CreateByType( 4123969931fad6e993832208f099f6eea0f6f76eb5San Mehat const sp<ALooper> &looper, const char *mime, bool encoder) { 4223969931fad6e993832208f099f6eea0f6f76eb5San Mehat sp<MediaCodec> codec = new MediaCodec(looper); 43f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (codec->init(mime, true /* nameIsType */, encoder) != OK) { 44f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return NULL; 45f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 46f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 47f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return codec; 48f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 49f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 50f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat// static 51f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatsp<MediaCodec> MediaCodec::CreateByComponentName( 52f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat const sp<ALooper> &looper, const char *name) { 53f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat sp<MediaCodec> codec = new MediaCodec(looper); 54f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (codec->init(name, false /* nameIsType */, false /* encoder */) != OK) { 55a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return NULL; 56f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 57f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 58f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return codec; 59f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 60f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 61f1b736bc5605e92e917ab27f5abf3ba839be2270San MehatMediaCodec::MediaCodec(const sp<ALooper> &looper) 62f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat : mState(UNINITIALIZED), 63f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mLooper(looper), 64f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mCodec(new ACodec), 65f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mFlags(0), 66f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mSoftRenderer(NULL), 67f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mDequeueInputTimeoutGeneration(0), 68f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mDequeueInputReplyID(0), 69f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mDequeueOutputTimeoutGeneration(0), 70f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mDequeueOutputReplyID(0) { 71f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 72f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 73f1b736bc5605e92e917ab27f5abf3ba839be2270San MehatMediaCodec::~MediaCodec() { 74f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat CHECK_EQ(mState, UNINITIALIZED); 75a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 76a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 77a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat// static 78a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatstatus_t MediaCodec::PostAndAwaitResponse( 79a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat const sp<AMessage> &msg, sp<AMessage> *response) { 80a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat status_t err = msg->postAndAwaitResponse(response); 81a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 82a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (err != OK) { 83a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return err; 84a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 85a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 86a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (!(*response)->findInt32("err", &err)) { 87a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat err = OK; 88a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 89a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 90a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return err; 910cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat} 92a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 93a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatstatus_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) { 94a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat // Current video decoders do not return from OMX_FillThisBuffer 950cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat // quickly, violating the OpenMAX specs, until that is remedied 960cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat // we need to invest in an extra looper to free the main event 970cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat // queue. 980cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat bool needDedicatedLooper = false; 990cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat if (nameIsType && !strncasecmp(name, "video/", 6)) { 100a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat needDedicatedLooper = true; 101a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else if (!nameIsType && !strncmp(name, "OMX.TI.DUCATI1.VIDEO.", 21)) { 102a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat needDedicatedLooper = true; 103a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 104a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 105a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (needDedicatedLooper) { 106a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (mCodecLooper == NULL) { 107a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mCodecLooper = new ALooper; 108a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mCodecLooper->setName("CodecLooper"); 109a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 110a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 111a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 112fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat mCodecLooper->registerHandler(mCodec); 113fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat } else { 114f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mLooper->registerHandler(mCodec); 115fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat } 116f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 117f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mLooper->registerHandler(this); 118f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 119fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, id())); 120a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 121a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat sp<AMessage> msg = new AMessage(kWhatInit, id()); 122a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat msg->setString("name", name); 123f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat msg->setInt32("nameIsType", nameIsType); 124f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 125f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (nameIsType) { 126f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat msg->setInt32("encoder", encoder); 127f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 128f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 129a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat sp<AMessage> response; 130fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat return PostAndAwaitResponse(msg, &response); 131a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 132f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 133f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatstatus_t MediaCodec::configure( 134f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat const sp<AMessage> &format, 135f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat const sp<SurfaceTextureClient> &nativeWindow, 136f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat const sp<ICrypto> &crypto, 137f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat uint32_t flags) { 138f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat sp<AMessage> msg = new AMessage(kWhatConfigure, id()); 139f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 140f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat msg->setMessage("format", format); 141f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat msg->setInt32("flags", flags); 142f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 143a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (nativeWindow != NULL) { 144f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat msg->setObject( 145f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat "native-window", 146a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat new NativeWindowWrapper(nativeWindow)); 147f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 148f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 14949e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat if (crypto != NULL) { 150a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat msg->setPointer("crypto", crypto.get()); 151a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 152a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 153a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat sp<AMessage> response; 154a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return PostAndAwaitResponse(msg, &response); 155a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 156a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 157a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatstatus_t MediaCodec::start() { 158a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat sp<AMessage> msg = new AMessage(kWhatStart, id()); 159a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 160a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat sp<AMessage> response; 161a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return PostAndAwaitResponse(msg, &response); 162a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 163a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 164a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::stop() { 165a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> msg = new AMessage(kWhatStop, id()); 166a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 167a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> response; 168a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return PostAndAwaitResponse(msg, &response); 169a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 170a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 171a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::release() { 172a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> msg = new AMessage(kWhatRelease, id()); 173a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 174a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> response; 175a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return PostAndAwaitResponse(msg, &response); 176a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 177a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 178a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::queueInputBuffer( 179a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat size_t index, 180a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat size_t offset, 181a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat size_t size, 182a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat int64_t presentationTimeUs, 183a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat uint32_t flags, 184a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat AString *errorDetailMsg) { 185a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat if (errorDetailMsg != NULL) { 186a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat errorDetailMsg->clear(); 187a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 188a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 189a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id()); 190a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat msg->setSize("index", index); 191a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat msg->setSize("offset", offset); 192a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat msg->setSize("size", size); 193a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat msg->setInt64("timeUs", presentationTimeUs); 194a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat msg->setInt32("flags", flags); 195a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat msg->setPointer("errorDetailMsg", errorDetailMsg); 196a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 197a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> response; 198a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return PostAndAwaitResponse(msg, &response); 199a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 200a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 201a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::queueSecureInputBuffer( 2028da6bcb006f4e4257cdd685e35e910a6334f6ceaSan Mehat size_t index, 203a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat size_t offset, 204a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat const CryptoPlugin::SubSample *subSamples, 205a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat size_t numSubSamples, 206a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat const uint8_t key[16], 207a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat const uint8_t iv[16], 208b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat CryptoPlugin::Mode mode, 209b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat int64_t presentationTimeUs, 210a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat uint32_t flags, 211b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat AString *errorDetailMsg) { 212b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (errorDetailMsg != NULL) { 213b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat errorDetailMsg->clear(); 214b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 215b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 216b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id()); 217b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat msg->setSize("index", index); 218b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat msg->setSize("offset", offset); 219b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat msg->setPointer("subSamples", (void *)subSamples); 220b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat msg->setSize("numSubSamples", numSubSamples); 221b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat msg->setPointer("key", (void *)key); 222b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat msg->setPointer("iv", (void *)iv); 223b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat msg->setInt32("mode", mode); 224b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat msg->setInt64("timeUs", presentationTimeUs); 225a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat msg->setInt32("flags", flags); 226b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat msg->setPointer("errorDetailMsg", errorDetailMsg); 227b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 228b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat sp<AMessage> response; 229a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat status_t err = PostAndAwaitResponse(msg, &response); 230a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 231a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return err; 232a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 233a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 234a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 235a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id()); 236a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat msg->setInt64("timeoutUs", timeoutUs); 237a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 238eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat sp<AMessage> response; 239eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat status_t err; 240b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 241b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return err; 242b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 243eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat 244eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat CHECK(response->findSize("index", index)); 245eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat 246eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat return OK; 247a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 248a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 249b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatstatus_t MediaCodec::dequeueOutputBuffer( 250cff5ec3d360b699ad13df05670efe0d0a7386fbeSan Mehat size_t *index, 251cff5ec3d360b699ad13df05670efe0d0a7386fbeSan Mehat size_t *offset, 252a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat size_t *size, 253b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat int64_t *presentationTimeUs, 254b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat uint32_t *flags, 255b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat int64_t timeoutUs) { 256a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, id()); 257a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat msg->setInt64("timeoutUs", timeoutUs); 258a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 259a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> response; 260a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat status_t err; 261a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 262a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return err; 263a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 264a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 265a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat CHECK(response->findSize("index", index)); 266a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat CHECK(response->findSize("offset", offset)); 267a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat CHECK(response->findSize("size", size)); 268a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat CHECK(response->findInt64("timeUs", presentationTimeUs)); 269a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat CHECK(response->findInt32("flags", (int32_t *)flags)); 270a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 271a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return OK; 272a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 273a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 274a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) { 275a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id()); 276a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat msg->setSize("index", index); 277a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat msg->setInt32("render", true); 278fff0b47998a722d57eea6a07350bbd7a6032b3ccSan Mehat 279fff0b47998a722d57eea6a07350bbd7a6032b3ccSan Mehat sp<AMessage> response; 280a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return PostAndAwaitResponse(msg, &response); 281a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 282a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 283a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::releaseOutputBuffer(size_t index) { 284a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id()); 285a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat msg->setSize("index", index); 286a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 287a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> response; 288b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return PostAndAwaitResponse(msg, &response); 289a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 290a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 291a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const { 292a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id()); 293a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 294a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> response; 295a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat status_t err; 296a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 297b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return err; 298b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 299b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 300b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat CHECK(response->findMessage("format", format)); 30123969931fad6e993832208f099f6eea0f6f76eb5San Mehat 302b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return OK; 303b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat} 304b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 305b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { 306b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat sp<AMessage> msg = new AMessage(kWhatGetBuffers, id()); 307a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat msg->setInt32("portIndex", kPortIndexInput); 308b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat msg->setPointer("buffers", buffers); 309b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 310b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat sp<AMessage> response; 311a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return PostAndAwaitResponse(msg, &response); 312b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat} 313b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 314b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const { 315b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat sp<AMessage> msg = new AMessage(kWhatGetBuffers, id()); 316b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat msg->setInt32("portIndex", kPortIndexOutput); 317b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat msg->setPointer("buffers", buffers); 318b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 319b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat sp<AMessage> response; 320b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return PostAndAwaitResponse(msg, &response); 321b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat} 322b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 323b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatstatus_t MediaCodec::flush() { 324b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat sp<AMessage> msg = new AMessage(kWhatFlush, id()); 325b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 326b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat sp<AMessage> response; 327b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return PostAndAwaitResponse(msg, &response); 328b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat} 329a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 330a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::requestIDRFrame() { 331a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat (new AMessage(kWhatRequestIDRFrame, id()))->post(); 332a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 333a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return OK; 334a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 335b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 336b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatvoid MediaCodec::requestActivityNotification(const sp<AMessage> ¬ify) { 337b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, id()); 338b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat msg->setMessage("notify", notify); 339b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat msg->post(); 340b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat} 341b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 342b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat//////////////////////////////////////////////////////////////////////////////// 343b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 344b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatvoid MediaCodec::cancelPendingDequeueOperations() { 345b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (mFlags & kFlagDequeueInputPending) { 346b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat sp<AMessage> response = new AMessage; 347b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat response->setInt32("err", INVALID_OPERATION); 348a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat response->postReply(mDequeueInputReplyID); 349a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 350a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat ++mDequeueInputTimeoutGeneration; 351a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat mDequeueInputReplyID = 0; 352a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat mFlags &= ~kFlagDequeueInputPending; 353a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 354a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 355a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat if (mFlags & kFlagDequeueOutputPending) { 356a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> response = new AMessage; 357a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat response->setInt32("err", INVALID_OPERATION); 358a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat response->postReply(mDequeueOutputReplyID); 359a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 360a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat ++mDequeueOutputTimeoutGeneration; 361a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat mDequeueOutputReplyID = 0; 362a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat mFlags &= ~kFlagDequeueOutputPending; 363a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 364a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 365a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 366a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatbool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) { 367a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat if (mState != STARTED 368a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat || (mFlags & kFlagStickyError) 369a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat || (newRequest && (mFlags & kFlagDequeueInputPending))) { 370a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<AMessage> response = new AMessage; 3718da6bcb006f4e4257cdd685e35e910a6334f6ceaSan Mehat response->setInt32("err", INVALID_OPERATION); 372a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 373a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat response->postReply(replyID); 374a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 375b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return true; 376b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 377b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 378b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat ssize_t index = dequeuePortBuffer(kPortIndexInput); 379b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 380b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (index < 0) { 381b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat CHECK_EQ(index, -EAGAIN); 382b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return false; 383b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 384b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 385b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat sp<AMessage> response = new AMessage; 386b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat response->setSize("index", index); 387b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat response->postReply(replyID); 388b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 389b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return true; 390b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat} 391b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 392b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatbool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) { 393b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat sp<AMessage> response = new AMessage; 394b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 395b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (mState != STARTED 396b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat || (mFlags & kFlagStickyError) 397b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat || (newRequest && (mFlags & kFlagDequeueOutputPending))) { 398b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat response->setInt32("err", INVALID_OPERATION); 399b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } else if (mFlags & kFlagOutputBuffersChanged) { 400b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED); 401b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat mFlags &= ~kFlagOutputBuffersChanged; 402b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } else if (mFlags & kFlagOutputFormatChanged) { 403b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat response->setInt32("err", INFO_FORMAT_CHANGED); 404b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat mFlags &= ~kFlagOutputFormatChanged; 405b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } else { 406b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat ssize_t index = dequeuePortBuffer(kPortIndexOutput); 407b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 408b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (index < 0) { 409b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat CHECK_EQ(index, -EAGAIN); 410b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return false; 411b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 412b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 413b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat const sp<ABuffer> &buffer = 414a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat mPortBuffers[kPortIndexOutput].itemAt(index).mData; 415a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 416a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat response->setSize("index", index); 417b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat response->setSize("offset", buffer->offset()); 418b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat response->setSize("size", buffer->size()); 419b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 420b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat int64_t timeUs; 421b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 422b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 423b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat response->setInt64("timeUs", timeUs); 424b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 425a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat int32_t omxFlags; 426a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 427b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 428cff5ec3d360b699ad13df05670efe0d0a7386fbeSan Mehat uint32_t flags = 0; 429cff5ec3d360b699ad13df05670efe0d0a7386fbeSan Mehat if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 430a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat flags |= BUFFER_FLAG_SYNCFRAME; 431b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 432b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 433b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat flags |= BUFFER_FLAG_CODECCONFIG; 434b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 435a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat if (omxFlags & OMX_BUFFERFLAG_EOS) { 436a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat flags |= BUFFER_FLAG_EOS; 437a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 438a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 439a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat response->setInt32("flags", flags); 440a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 441a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 44249e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat response->postReply(replyID); 44349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 44449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat return true; 44549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat} 44649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 44749e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehatvoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) { 44849e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat switch (msg->what()) { 44949e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat case kWhatCodecNotify: 450a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat { 451a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat int32_t what; 452a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat CHECK(msg->findInt32("what", &what)); 453a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 454a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat switch (what) { 455a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat case ACodec::kWhatError: 456a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat { 457a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat int32_t omxError, internalError; 458a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat CHECK(msg->findInt32("omx-error", &omxError)); 459a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat CHECK(msg->findInt32("err", &internalError)); 460a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 461a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat ALOGE("Codec reported an error. " 462a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat "(omx error 0x%08x, internalError %d)", 463a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat omxError, internalError); 464a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 465a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat bool sendErrorReponse = true; 466a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 467a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat switch (mState) { 468a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat case INITIALIZING: 469a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat { 470a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat setState(UNINITIALIZED); 471a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat break; 472a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 473a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 474a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat case CONFIGURING: 475a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat { 476a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat setState(INITIALIZED); 477a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat break; 478a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 479a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 480a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat case STARTING: 481a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat { 482a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat setState(CONFIGURED); 483a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat break; 484a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 485a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 486a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat case STOPPING: 487a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat case RELEASING: 488a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat { 489a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat // Ignore the error, assuming we'll still get 490a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat // the shutdown complete notification. 491a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 492a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat sendErrorReponse = false; 493a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat break; 494a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 495a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 496a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat case FLUSHING: 497a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat { 498a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat setState(STARTED); 499a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat break; 500a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 501a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 502a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat case STARTED: 503a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat { 504a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat sendErrorReponse = false; 505a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 506a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mFlags |= kFlagStickyError; 507a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat postActivityNotificationIfPossible(); 50849e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 509a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat cancelPendingDequeueOperations(); 51049e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat break; 51149e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat } 51249e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 51349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat default: 514a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat { 515a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat sendErrorReponse = false; 516a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 517a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mFlags |= kFlagStickyError; 518a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat postActivityNotificationIfPossible(); 519a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat break; 520a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 521a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 522a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 523a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (sendErrorReponse) { 524a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat sp<AMessage> response = new AMessage; 525a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat response->setInt32("err", UNKNOWN_ERROR); 526a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 5270cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat response->postReply(mReplyID); 5280cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat } 529a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat break; 530a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 531a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 532a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat case ACodec::kWhatComponentAllocated: 533a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat { 534a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat CHECK_EQ(mState, INITIALIZING); 535a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat setState(INITIALIZED); 536a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 537a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat AString componentName; 538a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat CHECK(msg->findString("componentName", &componentName)); 539a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 540a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (componentName.startsWith("OMX.google.")) { 541a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mFlags |= kFlagIsSoftwareCodec; 542a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else { 543a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mFlags &= ~kFlagIsSoftwareCodec; 544a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 545a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 546a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (componentName.endsWith(".secure")) { 547a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mFlags |= kFlagIsSecure; 548a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else { 549a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mFlags &= ~kFlagIsSecure; 550a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 551a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 552a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat (new AMessage)->postReply(mReplyID); 553a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat break; 554a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 555a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 556a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat case ACodec::kWhatComponentConfigured: 557a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat { 558a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat CHECK_EQ(mState, CONFIGURING); 559a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat setState(CONFIGURED); 560a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 561a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat (new AMessage)->postReply(mReplyID); 562a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat break; 563a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 564a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 565a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat case ACodec::kWhatBuffersAllocated: 566a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat { 567a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat int32_t portIndex; 568a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat CHECK(msg->findInt32("portIndex", &portIndex)); 569a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 5700cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat ALOGV("%s buffers allocated", 571a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat portIndex == kPortIndexInput ? "input" : "output"); 572a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 573a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat CHECK(portIndex == kPortIndexInput 574a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat || portIndex == kPortIndexOutput); 575a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 576a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mPortBuffers[portIndex].clear(); 577a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 578a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 579a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 580a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat sp<RefBase> obj; 581a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat CHECK(msg->findObject("portDesc", &obj)); 582a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 583a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat sp<ACodec::PortDescription> portDesc = 584a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat static_cast<ACodec::PortDescription *>(obj.get()); 58549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 58649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat size_t numBuffers = portDesc->countBuffers(); 58749e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 58849e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat for (size_t i = 0; i < numBuffers; ++i) { 58949e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat BufferInfo info; 59049e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat info.mBufferID = portDesc->bufferIDAt(i); 59149e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat info.mOwnedByClient = false; 59249e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat info.mData = portDesc->bufferAt(i); 59349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 59449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat if (portIndex == kPortIndexInput && mCrypto != NULL) { 595a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat info.mEncryptedData = 596a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat new ABuffer(info.mData->capacity()); 597a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 598a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 599a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat buffers->push_back(info); 60049e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat } 601a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 602a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (portIndex == kPortIndexOutput) { 60349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat if (mState == STARTING) { 60449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat // We're always allocating output buffers after 60549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat // allocating input buffers, so this is a good 60649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat // indication that now all buffers are allocated. 607a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat setState(STARTED); 60849e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat (new AMessage)->postReply(mReplyID); 60949e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat } else { 610a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mFlags |= kFlagOutputBuffersChanged; 611a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat postActivityNotificationIfPossible(); 612a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 61349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat } 61449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat break; 61549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat } 61649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 617a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat case ACodec::kWhatOutputFormatChanged: 618a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat { 619a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat ALOGV("codec output format changed"); 620a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 621a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if ((mFlags & kFlagIsSoftwareCodec) 622a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat && mNativeWindow != NULL) { 623a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat AString mime; 62449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat CHECK(msg->findString("mime", &mime)); 62549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 62649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat if (!strncasecmp("video/", mime.c_str(), 6)) { 627a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat delete mSoftRenderer; 628a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat mSoftRenderer = NULL; 629a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 630a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat int32_t width, height; 631a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat CHECK(msg->findInt32("width", &width)); 632a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat CHECK(msg->findInt32("height", &height)); 633a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 634a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat int32_t colorFormat; 635a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat CHECK(msg->findInt32( 636a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat "color-format", &colorFormat)); 637a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 638a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sp<MetaData> meta = new MetaData; 639a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat meta->setInt32(kKeyWidth, width); 640a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat meta->setInt32(kKeyHeight, height); 641a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat meta->setInt32(kKeyColorFormat, colorFormat); 642a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 643a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat mSoftRenderer = 644a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat new SoftwareRenderer(mNativeWindow, meta); 645a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 646a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 647a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 648a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat mOutputFormat = msg; 649a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat mFlags |= kFlagOutputFormatChanged; 650a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat postActivityNotificationIfPossible(); 651a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat break; 652a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 653a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 654a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat case ACodec::kWhatFillThisBuffer: 655 { 656 /* size_t index = */updateBuffers(kPortIndexInput, msg); 657 658 if (mState == FLUSHING 659 || mState == STOPPING 660 || mState == RELEASING) { 661 returnBuffersToCodecOnPort(kPortIndexInput); 662 break; 663 } 664 665 if (!mCSD.empty()) { 666 ssize_t index = dequeuePortBuffer(kPortIndexInput); 667 CHECK_GE(index, 0); 668 669 // If codec specific data had been specified as 670 // part of the format in the call to configure and 671 // if there's more csd left, we submit it here 672 // clients only get access to input buffers once 673 // this data has been exhausted. 674 675 status_t err = queueCSDInputBuffer(index); 676 677 if (err != OK) { 678 ALOGE("queueCSDInputBuffer failed w/ error %d", 679 err); 680 681 mFlags |= kFlagStickyError; 682 postActivityNotificationIfPossible(); 683 684 cancelPendingDequeueOperations(); 685 } 686 break; 687 } 688 689 if (mFlags & kFlagDequeueInputPending) { 690 CHECK(handleDequeueInputBuffer(mDequeueInputReplyID)); 691 692 ++mDequeueInputTimeoutGeneration; 693 mFlags &= ~kFlagDequeueInputPending; 694 mDequeueInputReplyID = 0; 695 } else { 696 postActivityNotificationIfPossible(); 697 } 698 break; 699 } 700 701 case ACodec::kWhatDrainThisBuffer: 702 { 703 /* size_t index = */updateBuffers(kPortIndexOutput, msg); 704 705 if (mState == FLUSHING 706 || mState == STOPPING 707 || mState == RELEASING) { 708 returnBuffersToCodecOnPort(kPortIndexOutput); 709 break; 710 } 711 712 sp<ABuffer> buffer; 713 CHECK(msg->findBuffer("buffer", &buffer)); 714 715 int32_t omxFlags; 716 CHECK(msg->findInt32("flags", &omxFlags)); 717 718 buffer->meta()->setInt32("omxFlags", omxFlags); 719 720 if (mFlags & kFlagDequeueOutputPending) { 721 CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID)); 722 723 ++mDequeueOutputTimeoutGeneration; 724 mFlags &= ~kFlagDequeueOutputPending; 725 mDequeueOutputReplyID = 0; 726 } else { 727 postActivityNotificationIfPossible(); 728 } 729 730 break; 731 } 732 733 case ACodec::kWhatEOS: 734 { 735 // We already notify the client of this by using the 736 // corresponding flag in "onOutputBufferReady". 737 break; 738 } 739 740 case ACodec::kWhatShutdownCompleted: 741 { 742 if (mState == STOPPING) { 743 setState(INITIALIZED); 744 } else { 745 CHECK_EQ(mState, RELEASING); 746 setState(UNINITIALIZED); 747 } 748 749 (new AMessage)->postReply(mReplyID); 750 break; 751 } 752 753 case ACodec::kWhatFlushCompleted: 754 { 755 CHECK_EQ(mState, FLUSHING); 756 setState(STARTED); 757 758 mCodec->signalResume(); 759 760 (new AMessage)->postReply(mReplyID); 761 break; 762 } 763 764 default: 765 TRESPASS(); 766 } 767 break; 768 } 769 770 case kWhatInit: 771 { 772 uint32_t replyID; 773 CHECK(msg->senderAwaitsResponse(&replyID)); 774 775 if (mState != UNINITIALIZED) { 776 sp<AMessage> response = new AMessage; 777 response->setInt32("err", INVALID_OPERATION); 778 779 response->postReply(replyID); 780 break; 781 } 782 783 mReplyID = replyID; 784 setState(INITIALIZING); 785 786 AString name; 787 CHECK(msg->findString("name", &name)); 788 789 int32_t nameIsType; 790 int32_t encoder = false; 791 CHECK(msg->findInt32("nameIsType", &nameIsType)); 792 if (nameIsType) { 793 CHECK(msg->findInt32("encoder", &encoder)); 794 } 795 796 sp<AMessage> format = new AMessage; 797 798 if (nameIsType) { 799 format->setString("mime", name.c_str()); 800 format->setInt32("encoder", encoder); 801 } else { 802 format->setString("componentName", name.c_str()); 803 } 804 805 mCodec->initiateAllocateComponent(format); 806 break; 807 } 808 809 case kWhatConfigure: 810 { 811 uint32_t replyID; 812 CHECK(msg->senderAwaitsResponse(&replyID)); 813 814 if (mState != INITIALIZED) { 815 sp<AMessage> response = new AMessage; 816 response->setInt32("err", INVALID_OPERATION); 817 818 response->postReply(replyID); 819 break; 820 } 821 822 sp<RefBase> obj; 823 if (!msg->findObject("native-window", &obj)) { 824 obj.clear(); 825 } 826 827 sp<AMessage> format; 828 CHECK(msg->findMessage("format", &format)); 829 830 if (obj != NULL) { 831 format->setObject("native-window", obj); 832 833 status_t err = setNativeWindow( 834 static_cast<NativeWindowWrapper *>(obj.get()) 835 ->getSurfaceTextureClient()); 836 837 if (err != OK) { 838 sp<AMessage> response = new AMessage; 839 response->setInt32("err", err); 840 841 response->postReply(replyID); 842 break; 843 } 844 } else { 845 setNativeWindow(NULL); 846 } 847 848 mReplyID = replyID; 849 setState(CONFIGURING); 850 851 void *crypto; 852 if (!msg->findPointer("crypto", &crypto)) { 853 crypto = NULL; 854 } 855 856 mCrypto = static_cast<ICrypto *>(crypto); 857 858 uint32_t flags; 859 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 860 861 if (flags & CONFIGURE_FLAG_ENCODE) { 862 format->setInt32("encoder", true); 863 } 864 865 extractCSD(format); 866 867 mCodec->initiateConfigureComponent(format); 868 break; 869 } 870 871 case kWhatStart: 872 { 873 uint32_t replyID; 874 CHECK(msg->senderAwaitsResponse(&replyID)); 875 876 if (mState != CONFIGURED) { 877 sp<AMessage> response = new AMessage; 878 response->setInt32("err", INVALID_OPERATION); 879 880 response->postReply(replyID); 881 break; 882 } 883 884 mReplyID = replyID; 885 setState(STARTING); 886 887 mCodec->initiateStart(); 888 break; 889 } 890 891 case kWhatStop: 892 { 893 uint32_t replyID; 894 CHECK(msg->senderAwaitsResponse(&replyID)); 895 896 if (mState != INITIALIZED 897 && mState != CONFIGURED && mState != STARTED) { 898 sp<AMessage> response = new AMessage; 899 response->setInt32("err", INVALID_OPERATION); 900 901 response->postReply(replyID); 902 break; 903 } 904 905 mReplyID = replyID; 906 setState(STOPPING); 907 908 mCodec->initiateShutdown(true /* keepComponentAllocated */); 909 returnBuffersToCodec(); 910 break; 911 } 912 913 case kWhatRelease: 914 { 915 uint32_t replyID; 916 CHECK(msg->senderAwaitsResponse(&replyID)); 917 918 if (mState != INITIALIZED 919 && mState != CONFIGURED && mState != STARTED) { 920 sp<AMessage> response = new AMessage; 921 response->setInt32("err", INVALID_OPERATION); 922 923 response->postReply(replyID); 924 break; 925 } 926 927 mReplyID = replyID; 928 setState(RELEASING); 929 930 mCodec->initiateShutdown(); 931 returnBuffersToCodec(); 932 break; 933 } 934 935 case kWhatDequeueInputBuffer: 936 { 937 uint32_t replyID; 938 CHECK(msg->senderAwaitsResponse(&replyID)); 939 940 if (handleDequeueInputBuffer(replyID, true /* new request */)) { 941 break; 942 } 943 944 int64_t timeoutUs; 945 CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 946 947 if (timeoutUs == 0ll) { 948 sp<AMessage> response = new AMessage; 949 response->setInt32("err", -EAGAIN); 950 response->postReply(replyID); 951 break; 952 } 953 954 mFlags |= kFlagDequeueInputPending; 955 mDequeueInputReplyID = replyID; 956 957 if (timeoutUs > 0ll) { 958 sp<AMessage> timeoutMsg = 959 new AMessage(kWhatDequeueInputTimedOut, id()); 960 timeoutMsg->setInt32( 961 "generation", ++mDequeueInputTimeoutGeneration); 962 timeoutMsg->post(timeoutUs); 963 } 964 break; 965 } 966 967 case kWhatDequeueInputTimedOut: 968 { 969 int32_t generation; 970 CHECK(msg->findInt32("generation", &generation)); 971 972 if (generation != mDequeueInputTimeoutGeneration) { 973 // Obsolete 974 break; 975 } 976 977 CHECK(mFlags & kFlagDequeueInputPending); 978 979 sp<AMessage> response = new AMessage; 980 response->setInt32("err", -EAGAIN); 981 response->postReply(mDequeueInputReplyID); 982 983 mFlags &= ~kFlagDequeueInputPending; 984 mDequeueInputReplyID = 0; 985 break; 986 } 987 988 case kWhatQueueInputBuffer: 989 { 990 uint32_t replyID; 991 CHECK(msg->senderAwaitsResponse(&replyID)); 992 993 if (mState != STARTED || (mFlags & kFlagStickyError)) { 994 sp<AMessage> response = new AMessage; 995 response->setInt32("err", INVALID_OPERATION); 996 997 response->postReply(replyID); 998 break; 999 } 1000 1001 status_t err = onQueueInputBuffer(msg); 1002 1003 sp<AMessage> response = new AMessage; 1004 response->setInt32("err", err); 1005 response->postReply(replyID); 1006 break; 1007 } 1008 1009 case kWhatDequeueOutputBuffer: 1010 { 1011 uint32_t replyID; 1012 CHECK(msg->senderAwaitsResponse(&replyID)); 1013 1014 if (handleDequeueOutputBuffer(replyID, true /* new request */)) { 1015 break; 1016 } 1017 1018 int64_t timeoutUs; 1019 CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 1020 1021 if (timeoutUs == 0ll) { 1022 sp<AMessage> response = new AMessage; 1023 response->setInt32("err", -EAGAIN); 1024 response->postReply(replyID); 1025 break; 1026 } 1027 1028 mFlags |= kFlagDequeueOutputPending; 1029 mDequeueOutputReplyID = replyID; 1030 1031 if (timeoutUs > 0ll) { 1032 sp<AMessage> timeoutMsg = 1033 new AMessage(kWhatDequeueOutputTimedOut, id()); 1034 timeoutMsg->setInt32( 1035 "generation", ++mDequeueOutputTimeoutGeneration); 1036 timeoutMsg->post(timeoutUs); 1037 } 1038 break; 1039 } 1040 1041 case kWhatDequeueOutputTimedOut: 1042 { 1043 int32_t generation; 1044 CHECK(msg->findInt32("generation", &generation)); 1045 1046 if (generation != mDequeueOutputTimeoutGeneration) { 1047 // Obsolete 1048 break; 1049 } 1050 1051 CHECK(mFlags & kFlagDequeueOutputPending); 1052 1053 sp<AMessage> response = new AMessage; 1054 response->setInt32("err", -EAGAIN); 1055 response->postReply(mDequeueOutputReplyID); 1056 1057 mFlags &= ~kFlagDequeueOutputPending; 1058 mDequeueOutputReplyID = 0; 1059 break; 1060 } 1061 1062 case kWhatReleaseOutputBuffer: 1063 { 1064 uint32_t replyID; 1065 CHECK(msg->senderAwaitsResponse(&replyID)); 1066 1067 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1068 sp<AMessage> response = new AMessage; 1069 response->setInt32("err", INVALID_OPERATION); 1070 1071 response->postReply(replyID); 1072 break; 1073 } 1074 1075 status_t err = onReleaseOutputBuffer(msg); 1076 1077 sp<AMessage> response = new AMessage; 1078 response->setInt32("err", err); 1079 response->postReply(replyID); 1080 break; 1081 } 1082 1083 case kWhatGetBuffers: 1084 { 1085 uint32_t replyID; 1086 CHECK(msg->senderAwaitsResponse(&replyID)); 1087 1088 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1089 sp<AMessage> response = new AMessage; 1090 response->setInt32("err", INVALID_OPERATION); 1091 1092 response->postReply(replyID); 1093 break; 1094 } 1095 1096 int32_t portIndex; 1097 CHECK(msg->findInt32("portIndex", &portIndex)); 1098 1099 Vector<sp<ABuffer> > *dstBuffers; 1100 CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); 1101 1102 dstBuffers->clear(); 1103 const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex]; 1104 1105 for (size_t i = 0; i < srcBuffers.size(); ++i) { 1106 const BufferInfo &info = srcBuffers.itemAt(i); 1107 1108 dstBuffers->push_back( 1109 (portIndex == kPortIndexInput && mCrypto != NULL) 1110 ? info.mEncryptedData : info.mData); 1111 } 1112 1113 (new AMessage)->postReply(replyID); 1114 break; 1115 } 1116 1117 case kWhatFlush: 1118 { 1119 uint32_t replyID; 1120 CHECK(msg->senderAwaitsResponse(&replyID)); 1121 1122 if (mState != STARTED || (mFlags & kFlagStickyError)) { 1123 sp<AMessage> response = new AMessage; 1124 response->setInt32("err", INVALID_OPERATION); 1125 1126 response->postReply(replyID); 1127 break; 1128 } 1129 1130 mReplyID = replyID; 1131 setState(FLUSHING); 1132 1133 mCodec->signalFlush(); 1134 returnBuffersToCodec(); 1135 break; 1136 } 1137 1138 case kWhatGetOutputFormat: 1139 { 1140 uint32_t replyID; 1141 CHECK(msg->senderAwaitsResponse(&replyID)); 1142 1143 if ((mState != STARTED && mState != FLUSHING) 1144 || (mFlags & kFlagStickyError) 1145 || mOutputFormat == NULL) { 1146 sp<AMessage> response = new AMessage; 1147 response->setInt32("err", INVALID_OPERATION); 1148 1149 response->postReply(replyID); 1150 break; 1151 } 1152 1153 sp<AMessage> response = new AMessage; 1154 response->setMessage("format", mOutputFormat); 1155 response->postReply(replyID); 1156 break; 1157 } 1158 1159 case kWhatRequestIDRFrame: 1160 { 1161 mCodec->signalRequestIDRFrame(); 1162 break; 1163 } 1164 1165 case kWhatRequestActivityNotification: 1166 { 1167 CHECK(mActivityNotify == NULL); 1168 CHECK(msg->findMessage("notify", &mActivityNotify)); 1169 1170 postActivityNotificationIfPossible(); 1171 break; 1172 } 1173 1174 default: 1175 TRESPASS(); 1176 } 1177} 1178 1179void MediaCodec::extractCSD(const sp<AMessage> &format) { 1180 mCSD.clear(); 1181 1182 size_t i = 0; 1183 for (;;) { 1184 sp<ABuffer> csd; 1185 if (!format->findBuffer(StringPrintf("csd-%u", i).c_str(), &csd)) { 1186 break; 1187 } 1188 1189 mCSD.push_back(csd); 1190 ++i; 1191 } 1192 1193 ALOGV("Found %u pieces of codec specific data.", mCSD.size()); 1194} 1195 1196status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) { 1197 CHECK(!mCSD.empty()); 1198 1199 BufferInfo *info = 1200 &mPortBuffers[kPortIndexInput].editItemAt(bufferIndex); 1201 1202 sp<ABuffer> csd = *mCSD.begin(); 1203 mCSD.erase(mCSD.begin()); 1204 1205 const sp<ABuffer> &codecInputData = 1206 (mCrypto != NULL) ? info->mEncryptedData : info->mData; 1207 1208 if (csd->size() > codecInputData->capacity()) { 1209 return -EINVAL; 1210 } 1211 1212 memcpy(codecInputData->data(), csd->data(), csd->size()); 1213 1214 AString errorDetailMsg; 1215 1216 sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id()); 1217 msg->setSize("index", bufferIndex); 1218 msg->setSize("offset", 0); 1219 msg->setSize("size", csd->size()); 1220 msg->setInt64("timeUs", 0ll); 1221 msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG); 1222 msg->setPointer("errorDetailMsg", &errorDetailMsg); 1223 1224 return onQueueInputBuffer(msg); 1225} 1226 1227void MediaCodec::setState(State newState) { 1228 if (newState == INITIALIZED || newState == UNINITIALIZED) { 1229 delete mSoftRenderer; 1230 mSoftRenderer = NULL; 1231 1232 mCrypto.clear(); 1233 setNativeWindow(NULL); 1234 1235 mOutputFormat.clear(); 1236 mFlags &= ~kFlagOutputFormatChanged; 1237 mFlags &= ~kFlagOutputBuffersChanged; 1238 mFlags &= ~kFlagStickyError; 1239 1240 mActivityNotify.clear(); 1241 } 1242 1243 mState = newState; 1244 1245 cancelPendingDequeueOperations(); 1246} 1247 1248void MediaCodec::returnBuffersToCodec() { 1249 returnBuffersToCodecOnPort(kPortIndexInput); 1250 returnBuffersToCodecOnPort(kPortIndexOutput); 1251} 1252 1253void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) { 1254 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1255 1256 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1257 1258 for (size_t i = 0; i < buffers->size(); ++i) { 1259 BufferInfo *info = &buffers->editItemAt(i); 1260 1261 if (info->mNotify != NULL) { 1262 sp<AMessage> msg = info->mNotify; 1263 info->mNotify = NULL; 1264 info->mOwnedByClient = false; 1265 1266 if (portIndex == kPortIndexInput) { 1267 msg->setInt32("err", ERROR_END_OF_STREAM); 1268 } 1269 msg->post(); 1270 } 1271 } 1272 1273 mAvailPortBuffers[portIndex].clear(); 1274} 1275 1276size_t MediaCodec::updateBuffers( 1277 int32_t portIndex, const sp<AMessage> &msg) { 1278 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1279 1280 void *bufferID; 1281 CHECK(msg->findPointer("buffer-id", &bufferID)); 1282 1283 Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 1284 1285 for (size_t i = 0; i < buffers->size(); ++i) { 1286 BufferInfo *info = &buffers->editItemAt(i); 1287 1288 if (info->mBufferID == bufferID) { 1289 CHECK(info->mNotify == NULL); 1290 CHECK(msg->findMessage("reply", &info->mNotify)); 1291 1292 mAvailPortBuffers[portIndex].push_back(i); 1293 1294 return i; 1295 } 1296 } 1297 1298 TRESPASS(); 1299 1300 return 0; 1301} 1302 1303status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { 1304 size_t index; 1305 size_t offset; 1306 size_t size; 1307 int64_t timeUs; 1308 uint32_t flags; 1309 CHECK(msg->findSize("index", &index)); 1310 CHECK(msg->findSize("offset", &offset)); 1311 CHECK(msg->findInt64("timeUs", &timeUs)); 1312 CHECK(msg->findInt32("flags", (int32_t *)&flags)); 1313 1314 const CryptoPlugin::SubSample *subSamples; 1315 size_t numSubSamples; 1316 const uint8_t *key; 1317 const uint8_t *iv; 1318 CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted; 1319 1320 // We allow the simpler queueInputBuffer API to be used even in 1321 // secure mode, by fabricating a single unencrypted subSample. 1322 CryptoPlugin::SubSample ss; 1323 1324 if (msg->findSize("size", &size)) { 1325 if (mCrypto != NULL) { 1326 ss.mNumBytesOfClearData = size; 1327 ss.mNumBytesOfEncryptedData = 0; 1328 1329 subSamples = &ss; 1330 numSubSamples = 1; 1331 key = NULL; 1332 iv = NULL; 1333 } 1334 } else { 1335 if (mCrypto == NULL) { 1336 return -EINVAL; 1337 } 1338 1339 CHECK(msg->findPointer("subSamples", (void **)&subSamples)); 1340 CHECK(msg->findSize("numSubSamples", &numSubSamples)); 1341 CHECK(msg->findPointer("key", (void **)&key)); 1342 CHECK(msg->findPointer("iv", (void **)&iv)); 1343 1344 int32_t tmp; 1345 CHECK(msg->findInt32("mode", &tmp)); 1346 1347 mode = (CryptoPlugin::Mode)tmp; 1348 1349 size = 0; 1350 for (size_t i = 0; i < numSubSamples; ++i) { 1351 size += subSamples[i].mNumBytesOfClearData; 1352 size += subSamples[i].mNumBytesOfEncryptedData; 1353 } 1354 } 1355 1356 if (index >= mPortBuffers[kPortIndexInput].size()) { 1357 return -ERANGE; 1358 } 1359 1360 BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index); 1361 1362 if (info->mNotify == NULL || !info->mOwnedByClient) { 1363 return -EACCES; 1364 } 1365 1366 if (offset + size > info->mData->capacity()) { 1367 return -EINVAL; 1368 } 1369 1370 sp<AMessage> reply = info->mNotify; 1371 info->mData->setRange(offset, size); 1372 info->mData->meta()->setInt64("timeUs", timeUs); 1373 1374 if (flags & BUFFER_FLAG_EOS) { 1375 info->mData->meta()->setInt32("eos", true); 1376 } 1377 1378 if (flags & BUFFER_FLAG_CODECCONFIG) { 1379 info->mData->meta()->setInt32("csd", true); 1380 } 1381 1382 if (mCrypto != NULL) { 1383 if (size > info->mEncryptedData->capacity()) { 1384 return -ERANGE; 1385 } 1386 1387 AString *errorDetailMsg; 1388 CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg)); 1389 1390 ssize_t result = mCrypto->decrypt( 1391 (mFlags & kFlagIsSecure) != 0, 1392 key, 1393 iv, 1394 mode, 1395 info->mEncryptedData->base() + offset, 1396 subSamples, 1397 numSubSamples, 1398 info->mData->base(), 1399 errorDetailMsg); 1400 1401 if (result < 0) { 1402 return result; 1403 } 1404 1405 info->mData->setRange(0, result); 1406 } 1407 1408 reply->setBuffer("buffer", info->mData); 1409 reply->post(); 1410 1411 info->mNotify = NULL; 1412 info->mOwnedByClient = false; 1413 1414 return OK; 1415} 1416 1417status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) { 1418 size_t index; 1419 CHECK(msg->findSize("index", &index)); 1420 1421 int32_t render; 1422 if (!msg->findInt32("render", &render)) { 1423 render = 0; 1424 } 1425 1426 if (mState != STARTED) { 1427 return -EINVAL; 1428 } 1429 1430 if (index >= mPortBuffers[kPortIndexOutput].size()) { 1431 return -ERANGE; 1432 } 1433 1434 BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 1435 1436 if (info->mNotify == NULL || !info->mOwnedByClient) { 1437 return -EACCES; 1438 } 1439 1440 if (render) { 1441 info->mNotify->setInt32("render", true); 1442 1443 if (mSoftRenderer != NULL) { 1444 mSoftRenderer->render( 1445 info->mData->data(), info->mData->size(), NULL); 1446 } 1447 } 1448 1449 info->mNotify->post(); 1450 info->mNotify = NULL; 1451 info->mOwnedByClient = false; 1452 1453 return OK; 1454} 1455 1456ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) { 1457 CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 1458 1459 List<size_t> *availBuffers = &mAvailPortBuffers[portIndex]; 1460 1461 if (availBuffers->empty()) { 1462 return -EAGAIN; 1463 } 1464 1465 size_t index = *availBuffers->begin(); 1466 availBuffers->erase(availBuffers->begin()); 1467 1468 BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index); 1469 CHECK(!info->mOwnedByClient); 1470 info->mOwnedByClient = true; 1471 1472 return index; 1473} 1474 1475status_t MediaCodec::setNativeWindow( 1476 const sp<SurfaceTextureClient> &surfaceTextureClient) { 1477 status_t err; 1478 1479 if (mNativeWindow != NULL) { 1480 err = native_window_api_disconnect( 1481 mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA); 1482 1483 if (err != OK) { 1484 ALOGW("native_window_api_disconnect returned an error: %s (%d)", 1485 strerror(-err), err); 1486 } 1487 1488 mNativeWindow.clear(); 1489 } 1490 1491 if (surfaceTextureClient != NULL) { 1492 err = native_window_api_connect( 1493 surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA); 1494 1495 if (err != OK) { 1496 ALOGE("native_window_api_connect returned an error: %s (%d)", 1497 strerror(-err), err); 1498 1499 return err; 1500 } 1501 1502 mNativeWindow = surfaceTextureClient; 1503 } 1504 1505 return OK; 1506} 1507 1508void MediaCodec::postActivityNotificationIfPossible() { 1509 if (mActivityNotify == NULL) { 1510 return; 1511 } 1512 1513 if ((mFlags & (kFlagStickyError 1514 | kFlagOutputBuffersChanged 1515 | kFlagOutputFormatChanged)) 1516 || !mAvailPortBuffers[kPortIndexInput].empty() 1517 || !mAvailPortBuffers[kPortIndexOutput].empty()) { 1518 mActivityNotify->post(); 1519 mActivityNotify.clear(); 1520 } 1521} 1522 1523} // namespace android 1524