1744f5739019d1fd917f981e740b353c3d73fd1a8David Smith/* 2744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * Copyright (C) 2014 The Android Open Source Project 3744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * 4744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * Licensed under the Apache License, Version 2.0 (the "License"); 5744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * you may not use this file except in compliance with the License. 6744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * You may obtain a copy of the License at 7744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * 8744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * http://www.apache.org/licenses/LICENSE-2.0 9744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * 10744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * Unless required by applicable law or agreed to in writing, software 11744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * distributed under the License is distributed on an "AS IS" BASIS, 12744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * See the License for the specific language governing permissions and 14744f5739019d1fd917f981e740b353c3d73fd1a8David Smith * limitations under the License. 15744f5739019d1fd917f981e740b353c3d73fd1a8David Smith */ 16744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 17744f5739019d1fd917f981e740b353c3d73fd1a8David Smith//#define LOG_NDEBUG 0 18744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#define LOG_TAG "MediaFilter" 19744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 20744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <inttypes.h> 21744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <utils/Trace.h> 22744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 23744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <binder/MemoryDealer.h> 24744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 25e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith#include <media/stagefright/BufferProducerWrapper.h> 26744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/foundation/ABuffer.h> 27744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/foundation/ADebug.h> 28744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/foundation/AMessage.h> 29744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 30744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/MediaDefs.h> 31744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/MediaErrors.h> 32744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/MediaFilter.h> 33744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 348ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza#include <gui/BufferItem.h> 358ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza 36e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith#include "ColorConvert.h" 37e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith#include "GraphicBufferListener.h" 38744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include "IntrinsicBlurFilter.h" 39c6c182f354142b47b7a5abfa9f95c82b236f5832David Smith#include "RSFilter.h" 40744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include "SaturationFilter.h" 41744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include "ZeroFilter.h" 42744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 43744f5739019d1fd917f981e740b353c3d73fd1a8David Smithnamespace android { 44744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 45744f5739019d1fd917f981e740b353c3d73fd1a8David Smith// parameter: number of input and output buffers 46744f5739019d1fd917f981e740b353c3d73fd1a8David Smithstatic const size_t kBufferCountActual = 4; 47744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 48744f5739019d1fd917f981e740b353c3d73fd1a8David SmithMediaFilter::MediaFilter() 49744f5739019d1fd917f981e740b353c3d73fd1a8David Smith : mState(UNINITIALIZED), 50e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith mGeneration(0), 51e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith mGraphicBufferListener(NULL) { 52744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 53744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 54744f5739019d1fd917f981e740b353c3d73fd1a8David SmithMediaFilter::~MediaFilter() { 55744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 56744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 57744f5739019d1fd917f981e740b353c3d73fd1a8David Smith//////////////////// PUBLIC FUNCTIONS ////////////////////////////////////////// 58744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 59744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::setNotificationMessage(const sp<AMessage> &msg) { 60744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mNotify = msg; 61744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 62744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 63744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::initiateAllocateComponent(const sp<AMessage> &msg) { 64744f5739019d1fd917f981e740b353c3d73fd1a8David Smith msg->setWhat(kWhatAllocateComponent); 651d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar msg->setTarget(this); 66744f5739019d1fd917f981e740b353c3d73fd1a8David Smith msg->post(); 67744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 68744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 69744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::initiateConfigureComponent(const sp<AMessage> &msg) { 70744f5739019d1fd917f981e740b353c3d73fd1a8David Smith msg->setWhat(kWhatConfigureComponent); 711d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar msg->setTarget(this); 72744f5739019d1fd917f981e740b353c3d73fd1a8David Smith msg->post(); 73744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 74744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 75744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::initiateCreateInputSurface() { 761d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatCreateInputSurface, this))->post(); 77744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 78744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 798f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid MediaFilter::initiateSetInputSurface( 80d291c222357303b9611cab89d0c3b047584ef377Chong Zhang const sp<PersistentSurface> & /* surface */) { 818f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang ALOGW("initiateSetInputSurface() unsupported"); 82d291c222357303b9611cab89d0c3b047584ef377Chong Zhang} 83d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 84744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::initiateStart() { 851d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatStart, this))->post(); 86744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 87744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 88744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::initiateShutdown(bool keepComponentAllocated) { 891d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatShutdown, this); 90744f5739019d1fd917f981e740b353c3d73fd1a8David Smith msg->setInt32("keepComponentAllocated", keepComponentAllocated); 91744f5739019d1fd917f981e740b353c3d73fd1a8David Smith msg->post(); 92744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 93744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 94744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::signalFlush() { 951d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatFlush, this))->post(); 96744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 97744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 98744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::signalResume() { 991d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatResume, this))->post(); 100744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 101744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 102744f5739019d1fd917f981e740b353c3d73fd1a8David Smith// nothing to do 103744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::signalRequestIDRFrame() { 104744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return; 105744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 106744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 107744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::signalSetParameters(const sp<AMessage> ¶ms) { 1081d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 109744f5739019d1fd917f981e740b353c3d73fd1a8David Smith msg->setMessage("params", params); 110744f5739019d1fd917f981e740b353c3d73fd1a8David Smith msg->post(); 111744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 112744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 113744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::signalEndOfInputStream() { 1141d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatSignalEndOfInputStream, this))->post(); 115744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 116744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 117744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::onMessageReceived(const sp<AMessage> &msg) { 118744f5739019d1fd917f981e740b353c3d73fd1a8David Smith switch (msg->what()) { 119744f5739019d1fd917f981e740b353c3d73fd1a8David Smith case kWhatAllocateComponent: 120744f5739019d1fd917f981e740b353c3d73fd1a8David Smith { 121744f5739019d1fd917f981e740b353c3d73fd1a8David Smith onAllocateComponent(msg); 122744f5739019d1fd917f981e740b353c3d73fd1a8David Smith break; 123744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 124744f5739019d1fd917f981e740b353c3d73fd1a8David Smith case kWhatConfigureComponent: 125744f5739019d1fd917f981e740b353c3d73fd1a8David Smith { 126744f5739019d1fd917f981e740b353c3d73fd1a8David Smith onConfigureComponent(msg); 127744f5739019d1fd917f981e740b353c3d73fd1a8David Smith break; 128744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 129744f5739019d1fd917f981e740b353c3d73fd1a8David Smith case kWhatStart: 130744f5739019d1fd917f981e740b353c3d73fd1a8David Smith { 131744f5739019d1fd917f981e740b353c3d73fd1a8David Smith onStart(); 132744f5739019d1fd917f981e740b353c3d73fd1a8David Smith break; 133744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 134744f5739019d1fd917f981e740b353c3d73fd1a8David Smith case kWhatProcessBuffers: 135744f5739019d1fd917f981e740b353c3d73fd1a8David Smith { 136744f5739019d1fd917f981e740b353c3d73fd1a8David Smith processBuffers(); 137744f5739019d1fd917f981e740b353c3d73fd1a8David Smith break; 138744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 139744f5739019d1fd917f981e740b353c3d73fd1a8David Smith case kWhatInputBufferFilled: 140744f5739019d1fd917f981e740b353c3d73fd1a8David Smith { 141744f5739019d1fd917f981e740b353c3d73fd1a8David Smith onInputBufferFilled(msg); 142744f5739019d1fd917f981e740b353c3d73fd1a8David Smith break; 143744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 144744f5739019d1fd917f981e740b353c3d73fd1a8David Smith case kWhatOutputBufferDrained: 145744f5739019d1fd917f981e740b353c3d73fd1a8David Smith { 146744f5739019d1fd917f981e740b353c3d73fd1a8David Smith onOutputBufferDrained(msg); 147744f5739019d1fd917f981e740b353c3d73fd1a8David Smith break; 148744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 149744f5739019d1fd917f981e740b353c3d73fd1a8David Smith case kWhatShutdown: 150744f5739019d1fd917f981e740b353c3d73fd1a8David Smith { 151744f5739019d1fd917f981e740b353c3d73fd1a8David Smith onShutdown(msg); 152744f5739019d1fd917f981e740b353c3d73fd1a8David Smith break; 153744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 154744f5739019d1fd917f981e740b353c3d73fd1a8David Smith case kWhatFlush: 155744f5739019d1fd917f981e740b353c3d73fd1a8David Smith { 156744f5739019d1fd917f981e740b353c3d73fd1a8David Smith onFlush(); 157744f5739019d1fd917f981e740b353c3d73fd1a8David Smith break; 158744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 159744f5739019d1fd917f981e740b353c3d73fd1a8David Smith case kWhatResume: 160744f5739019d1fd917f981e740b353c3d73fd1a8David Smith { 161744f5739019d1fd917f981e740b353c3d73fd1a8David Smith // nothing to do 162744f5739019d1fd917f981e740b353c3d73fd1a8David Smith break; 163744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 164744f5739019d1fd917f981e740b353c3d73fd1a8David Smith case kWhatSetParameters: 165744f5739019d1fd917f981e740b353c3d73fd1a8David Smith { 166744f5739019d1fd917f981e740b353c3d73fd1a8David Smith onSetParameters(msg); 167744f5739019d1fd917f981e740b353c3d73fd1a8David Smith break; 168744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 169e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith case kWhatCreateInputSurface: 170e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith { 171e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith onCreateInputSurface(); 172e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith break; 173e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith } 174e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith case GraphicBufferListener::kWhatFrameAvailable: 175e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith { 176e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith onInputFrameAvailable(); 177e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith break; 178e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith } 179e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith case kWhatSignalEndOfInputStream: 180e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith { 181e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith onSignalEndOfInputStream(); 182e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith break; 183e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith } 184744f5739019d1fd917f981e740b353c3d73fd1a8David Smith default: 185744f5739019d1fd917f981e740b353c3d73fd1a8David Smith { 186744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGE("Message not handled:\n%s", msg->debugString().c_str()); 187744f5739019d1fd917f981e740b353c3d73fd1a8David Smith break; 188744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 189744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 190744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 191744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 192744f5739019d1fd917f981e740b353c3d73fd1a8David Smith//////////////////// PORT DESCRIPTION ////////////////////////////////////////// 193744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 194744f5739019d1fd917f981e740b353c3d73fd1a8David SmithMediaFilter::PortDescription::PortDescription() { 195744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 196744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 197744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::PortDescription::addBuffer( 198744f5739019d1fd917f981e740b353c3d73fd1a8David Smith IOMX::buffer_id id, const sp<ABuffer> &buffer) { 199744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mBufferIDs.push_back(id); 200744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mBuffers.push_back(buffer); 201744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 202744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 203744f5739019d1fd917f981e740b353c3d73fd1a8David Smithsize_t MediaFilter::PortDescription::countBuffers() { 204744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return mBufferIDs.size(); 205744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 206744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 207744f5739019d1fd917f981e740b353c3d73fd1a8David SmithIOMX::buffer_id MediaFilter::PortDescription::bufferIDAt(size_t index) const { 208744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return mBufferIDs.itemAt(index); 209744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 210744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 211744f5739019d1fd917f981e740b353c3d73fd1a8David Smithsp<ABuffer> MediaFilter::PortDescription::bufferAt(size_t index) const { 212744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return mBuffers.itemAt(index); 213744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 214744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 215744f5739019d1fd917f981e740b353c3d73fd1a8David Smith//////////////////// HELPER FUNCTIONS ////////////////////////////////////////// 216744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 217744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::signalProcessBuffers() { 2181d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatProcessBuffers, this))->post(); 219744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 220744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 221744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::signalError(status_t error) { 222744f5739019d1fd917f981e740b353c3d73fd1a8David Smith sp<AMessage> notify = mNotify->dup(); 223744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("what", CodecBase::kWhatError); 224744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("err", error); 225744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->post(); 226744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 227744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 228744f5739019d1fd917f981e740b353c3d73fd1a8David Smithstatus_t MediaFilter::allocateBuffersOnPort(OMX_U32 portIndex) { 229744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 230744f5739019d1fd917f981e740b353c3d73fd1a8David Smith const bool isInput = portIndex == kPortIndexInput; 231744f5739019d1fd917f981e740b353c3d73fd1a8David Smith const size_t bufferSize = isInput ? mMaxInputSize : mMaxOutputSize; 232744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 233744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK(mDealer[portIndex] == NULL); 234744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK(mBuffers[portIndex].isEmpty()); 235744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 236744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGV("Allocating %zu buffers of size %zu on %s port", 237744f5739019d1fd917f981e740b353c3d73fd1a8David Smith kBufferCountActual, bufferSize, 238744f5739019d1fd917f981e740b353c3d73fd1a8David Smith isInput ? "input" : "output"); 239744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 240744f5739019d1fd917f981e740b353c3d73fd1a8David Smith size_t totalSize = kBufferCountActual * bufferSize; 241744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 242744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mDealer[portIndex] = new MemoryDealer(totalSize, "MediaFilter"); 243744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 244744f5739019d1fd917f981e740b353c3d73fd1a8David Smith for (size_t i = 0; i < kBufferCountActual; ++i) { 245744f5739019d1fd917f981e740b353c3d73fd1a8David Smith sp<IMemory> mem = mDealer[portIndex]->allocate(bufferSize); 246744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK(mem.get() != NULL); 247744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 248744f5739019d1fd917f981e740b353c3d73fd1a8David Smith BufferInfo info; 249744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info.mStatus = BufferInfo::OWNED_BY_US; 250744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info.mBufferID = i; 251744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info.mGeneration = mGeneration; 252744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info.mOutputFlags = 0; 253744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info.mData = new ABuffer(mem->pointer(), bufferSize); 254744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info.mData->meta()->setInt64("timeUs", 0); 255744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 256744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mBuffers[portIndex].push_back(info); 257744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 258744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (!isInput) { 259744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mAvailableOutputBuffers.push( 260744f5739019d1fd917f981e740b353c3d73fd1a8David Smith &mBuffers[portIndex].editItemAt(i)); 261744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 262744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 263744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 264744f5739019d1fd917f981e740b353c3d73fd1a8David Smith sp<AMessage> notify = mNotify->dup(); 265744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("what", CodecBase::kWhatBuffersAllocated); 266744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 267744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("portIndex", portIndex); 268744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 269744f5739019d1fd917f981e740b353c3d73fd1a8David Smith sp<PortDescription> desc = new PortDescription; 270744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 271744f5739019d1fd917f981e740b353c3d73fd1a8David Smith for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 272744f5739019d1fd917f981e740b353c3d73fd1a8David Smith const BufferInfo &info = mBuffers[portIndex][i]; 273744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 274744f5739019d1fd917f981e740b353c3d73fd1a8David Smith desc->addBuffer(info.mBufferID, info.mData); 275744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 276744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 277744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setObject("portDesc", desc); 278744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->post(); 279744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 280744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return OK; 281744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 282744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 283744f5739019d1fd917f981e740b353c3d73fd1a8David SmithMediaFilter::BufferInfo* MediaFilter::findBufferByID( 284744f5739019d1fd917f981e740b353c3d73fd1a8David Smith uint32_t portIndex, IOMX::buffer_id bufferID, 285744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ssize_t *index) { 286744f5739019d1fd917f981e740b353c3d73fd1a8David Smith for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) { 287744f5739019d1fd917f981e740b353c3d73fd1a8David Smith BufferInfo *info = &mBuffers[portIndex].editItemAt(i); 288744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 289744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (info->mBufferID == bufferID) { 290744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (index != NULL) { 291744f5739019d1fd917f981e740b353c3d73fd1a8David Smith *index = i; 292744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 293744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return info; 294744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 295744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 296744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 297744f5739019d1fd917f981e740b353c3d73fd1a8David Smith TRESPASS(); 298744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 299744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return NULL; 300744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 301744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 302744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::postFillThisBuffer(BufferInfo *info) { 3032897286dae2934562c48febd4427b8839aeb4007David Smith ALOGV("postFillThisBuffer on buffer %d", info->mBufferID); 304744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (mPortEOS[kPortIndexInput]) { 305744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return; 306744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 307744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 308744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 309744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 310744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info->mGeneration = mGeneration; 311744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 312744f5739019d1fd917f981e740b353c3d73fd1a8David Smith sp<AMessage> notify = mNotify->dup(); 313744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("what", CodecBase::kWhatFillThisBuffer); 314744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("buffer-id", info->mBufferID); 315744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 316744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info->mData->meta()->clear(); 317744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setBuffer("buffer", info->mData); 318744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 3191d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, this); 320744f5739019d1fd917f981e740b353c3d73fd1a8David Smith reply->setInt32("buffer-id", info->mBufferID); 321744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 322744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setMessage("reply", reply); 323744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 324744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info->mStatus = BufferInfo::OWNED_BY_UPSTREAM; 3252897286dae2934562c48febd4427b8839aeb4007David Smith notify->post(); 326744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 327744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 328744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::postDrainThisBuffer(BufferInfo *info) { 329744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US); 330744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 3312897286dae2934562c48febd4427b8839aeb4007David Smith info->mGeneration = mGeneration; 3322897286dae2934562c48febd4427b8839aeb4007David Smith 333744f5739019d1fd917f981e740b353c3d73fd1a8David Smith sp<AMessage> notify = mNotify->dup(); 334744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("what", CodecBase::kWhatDrainThisBuffer); 335744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("buffer-id", info->mBufferID); 336744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("flags", info->mOutputFlags); 337744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setBuffer("buffer", info->mData); 338744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 3391d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> reply = new AMessage(kWhatOutputBufferDrained, this); 340744f5739019d1fd917f981e740b353c3d73fd1a8David Smith reply->setInt32("buffer-id", info->mBufferID); 341744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 342744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setMessage("reply", reply); 343744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 344744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->post(); 345744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 346744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info->mStatus = BufferInfo::OWNED_BY_UPSTREAM; 347744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 348744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 349744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::postEOS() { 350744f5739019d1fd917f981e740b353c3d73fd1a8David Smith sp<AMessage> notify = mNotify->dup(); 351744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("what", CodecBase::kWhatEOS); 352744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("err", ERROR_END_OF_STREAM); 353744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->post(); 354744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 355744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGV("Sent kWhatEOS."); 356744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 357744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 358744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::sendFormatChange() { 359744f5739019d1fd917f981e740b353c3d73fd1a8David Smith sp<AMessage> notify = mNotify->dup(); 360744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 361744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("what", kWhatOutputFormatChanged); 362744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 363744f5739019d1fd917f981e740b353c3d73fd1a8David Smith AString mime; 364744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK(mOutputFormat->findString("mime", &mime)); 365744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setString("mime", mime.c_str()); 366744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 367744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("stride", mStride); 368744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("slice-height", mSliceHeight); 369744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("color-format", mColorFormatOut); 370744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setRect("crop", 0, 0, mStride - 1, mSliceHeight - 1); 371744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("width", mWidth); 372744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("height", mHeight); 373744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 374744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->post(); 375744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 376744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 377744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::requestFillEmptyInput() { 378744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (mPortEOS[kPortIndexInput]) { 379744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return; 380744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 381744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 382744f5739019d1fd917f981e740b353c3d73fd1a8David Smith for (size_t i = 0; i < mBuffers[kPortIndexInput].size(); ++i) { 383744f5739019d1fd917f981e740b353c3d73fd1a8David Smith BufferInfo *info = &mBuffers[kPortIndexInput].editItemAt(i); 384744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 385744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (info->mStatus == BufferInfo::OWNED_BY_US) { 386744f5739019d1fd917f981e740b353c3d73fd1a8David Smith postFillThisBuffer(info); 387744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 388744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 389744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 390744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 391744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::processBuffers() { 392744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (mAvailableInputBuffers.empty() || mAvailableOutputBuffers.empty()) { 393744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGV("Skipping process (buffers unavailable)"); 394744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return; 395744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 396744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 397744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (mPortEOS[kPortIndexOutput]) { 398744f5739019d1fd917f981e740b353c3d73fd1a8David Smith // TODO notify caller of queueInput error when it is supported 399744f5739019d1fd917f981e740b353c3d73fd1a8David Smith // in MediaCodec 400744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGW("Tried to process a buffer after EOS."); 401744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return; 402744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 403744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 404744f5739019d1fd917f981e740b353c3d73fd1a8David Smith BufferInfo *inputInfo = mAvailableInputBuffers[0]; 405744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mAvailableInputBuffers.removeAt(0); 406744f5739019d1fd917f981e740b353c3d73fd1a8David Smith BufferInfo *outputInfo = mAvailableOutputBuffers[0]; 407744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mAvailableOutputBuffers.removeAt(0); 408744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 409744f5739019d1fd917f981e740b353c3d73fd1a8David Smith status_t err; 410744f5739019d1fd917f981e740b353c3d73fd1a8David Smith err = mFilter->processBuffers(inputInfo->mData, outputInfo->mData); 411744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (err != (status_t)OK) { 412744f5739019d1fd917f981e740b353c3d73fd1a8David Smith outputInfo->mData->meta()->setInt32("err", err); 413744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 414744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 415744f5739019d1fd917f981e740b353c3d73fd1a8David Smith int64_t timeUs; 416744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK(inputInfo->mData->meta()->findInt64("timeUs", &timeUs)); 417744f5739019d1fd917f981e740b353c3d73fd1a8David Smith outputInfo->mData->meta()->setInt64("timeUs", timeUs); 418744f5739019d1fd917f981e740b353c3d73fd1a8David Smith outputInfo->mOutputFlags = 0; 419744f5739019d1fd917f981e740b353c3d73fd1a8David Smith int32_t eos = 0; 420744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (inputInfo->mData->meta()->findInt32("eos", &eos) && eos != 0) { 421744f5739019d1fd917f981e740b353c3d73fd1a8David Smith outputInfo->mOutputFlags |= OMX_BUFFERFLAG_EOS; 422744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mPortEOS[kPortIndexOutput] = true; 423744f5739019d1fd917f981e740b353c3d73fd1a8David Smith outputInfo->mData->meta()->setInt32("eos", eos); 424744f5739019d1fd917f981e740b353c3d73fd1a8David Smith postEOS(); 425744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGV("Output stream saw EOS."); 426744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 427744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 428744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGV("Processed input buffer %u [%zu], output buffer %u [%zu]", 429744f5739019d1fd917f981e740b353c3d73fd1a8David Smith inputInfo->mBufferID, inputInfo->mData->size(), 430744f5739019d1fd917f981e740b353c3d73fd1a8David Smith outputInfo->mBufferID, outputInfo->mData->size()); 431744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 432e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith if (mGraphicBufferListener != NULL) { 433e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith delete inputInfo; 434e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith } else { 435e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith postFillThisBuffer(inputInfo); 436e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith } 437744f5739019d1fd917f981e740b353c3d73fd1a8David Smith postDrainThisBuffer(outputInfo); 438744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 439744f5739019d1fd917f981e740b353c3d73fd1a8David Smith // prevent any corner case where buffers could get stuck in queue 440744f5739019d1fd917f981e740b353c3d73fd1a8David Smith signalProcessBuffers(); 441744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 442744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 443744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::onAllocateComponent(const sp<AMessage> &msg) { 444744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK_EQ(mState, UNINITIALIZED); 445744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 446744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK(msg->findString("componentName", &mComponentName)); 447744f5739019d1fd917f981e740b353c3d73fd1a8David Smith const char* name = mComponentName.c_str(); 448744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (!strcasecmp(name, "android.filter.zerofilter")) { 449744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mFilter = new ZeroFilter; 450744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } else if (!strcasecmp(name, "android.filter.saturation")) { 451744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mFilter = new SaturationFilter; 452744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } else if (!strcasecmp(name, "android.filter.intrinsicblur")) { 453744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mFilter = new IntrinsicBlurFilter; 454c6c182f354142b47b7a5abfa9f95c82b236f5832David Smith } else if (!strcasecmp(name, "android.filter.RenderScript")) { 455c6c182f354142b47b7a5abfa9f95c82b236f5832David Smith mFilter = new RSFilter; 456744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } else { 457744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGE("Unrecognized filter name: %s", name); 458744f5739019d1fd917f981e740b353c3d73fd1a8David Smith signalError(NAME_NOT_FOUND); 459744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return; 460744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 461744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 462744f5739019d1fd917f981e740b353c3d73fd1a8David Smith sp<AMessage> notify = mNotify->dup(); 463744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("what", kWhatComponentAllocated); 464744f5739019d1fd917f981e740b353c3d73fd1a8David Smith // HACK - need "OMX.google" to use MediaCodec's software renderer 465744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setString("componentName", "OMX.google.MediaFilter"); 466744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->post(); 467744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mState = INITIALIZED; 468744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGV("Handled kWhatAllocateComponent."); 469744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 470744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 471744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::onConfigureComponent(const sp<AMessage> &msg) { 472744f5739019d1fd917f981e740b353c3d73fd1a8David Smith // TODO: generalize to allow audio filters as well as video 473744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 474744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK_EQ(mState, INITIALIZED); 475744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 476744f5739019d1fd917f981e740b353c3d73fd1a8David Smith // get params - at least mime, width & height 477744f5739019d1fd917f981e740b353c3d73fd1a8David Smith AString mime; 478744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK(msg->findString("mime", &mime)); 479744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_RAW)) { 480744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGE("Bad mime: %s", mime.c_str()); 481744f5739019d1fd917f981e740b353c3d73fd1a8David Smith signalError(BAD_VALUE); 482744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return; 483744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 484744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 485744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK(msg->findInt32("width", &mWidth)); 486744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK(msg->findInt32("height", &mHeight)); 487744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (!msg->findInt32("stride", &mStride)) { 488744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mStride = mWidth; 489744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 490744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (!msg->findInt32("slice-height", &mSliceHeight)) { 491744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mSliceHeight = mHeight; 492744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 493744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 494744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mMaxInputSize = mWidth * mHeight * 4; // room for ARGB8888 495744f5739019d1fd917f981e740b353c3d73fd1a8David Smith int32_t maxInputSize; 496744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (msg->findInt32("max-input-size", &maxInputSize) 497744f5739019d1fd917f981e740b353c3d73fd1a8David Smith && (size_t)maxInputSize > mMaxInputSize) { 498744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mMaxInputSize = maxInputSize; 499744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 500744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 501744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (!msg->findInt32("color-format", &mColorFormatIn)) { 502744f5739019d1fd917f981e740b353c3d73fd1a8David Smith // default to OMX_COLOR_Format32bitARGB8888 503744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mColorFormatIn = OMX_COLOR_Format32bitARGB8888; 5046dad9ad21ff547fab7f192956e4a3732fd78488bDavid Smith msg->setInt32("color-format", mColorFormatIn); 505744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 506744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mColorFormatOut = mColorFormatIn; 507e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 508744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mMaxOutputSize = mWidth * mHeight * 4; // room for ARGB8888 509744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 510e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith AString cacheDir; 511e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith if (!msg->findString("cacheDir", &cacheDir)) { 512e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith ALOGE("Failed to find cache directory in config message."); 513e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith signalError(NAME_NOT_FOUND); 514e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith return; 515e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith } 516e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 517744f5739019d1fd917f981e740b353c3d73fd1a8David Smith status_t err; 5186dad9ad21ff547fab7f192956e4a3732fd78488bDavid Smith err = mFilter->configure(msg); 519744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (err != (status_t)OK) { 520744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGE("Failed to configure filter component, err %d", err); 521744f5739019d1fd917f981e740b353c3d73fd1a8David Smith signalError(err); 522744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return; 523744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 524744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 525744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mInputFormat = new AMessage(); 526744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mInputFormat->setString("mime", mime.c_str()); 527744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mInputFormat->setInt32("stride", mStride); 528744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mInputFormat->setInt32("slice-height", mSliceHeight); 529744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mInputFormat->setInt32("color-format", mColorFormatIn); 530744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mInputFormat->setRect("crop", 0, 0, mStride, mSliceHeight); 531744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mInputFormat->setInt32("width", mWidth); 532744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mInputFormat->setInt32("height", mHeight); 533744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 534744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mOutputFormat = new AMessage(); 535744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mOutputFormat->setString("mime", mime.c_str()); 536744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mOutputFormat->setInt32("stride", mStride); 537744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mOutputFormat->setInt32("slice-height", mSliceHeight); 538744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mOutputFormat->setInt32("color-format", mColorFormatOut); 539744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mOutputFormat->setRect("crop", 0, 0, mStride, mSliceHeight); 540744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mOutputFormat->setInt32("width", mWidth); 541744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mOutputFormat->setInt32("height", mHeight); 542744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 543744f5739019d1fd917f981e740b353c3d73fd1a8David Smith sp<AMessage> notify = mNotify->dup(); 544744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("what", kWhatComponentConfigured); 545744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setString("componentName", "MediaFilter"); 546744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setMessage("input-format", mInputFormat); 547744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setMessage("output-format", mOutputFormat); 548744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->post(); 549744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mState = CONFIGURED; 550744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGV("Handled kWhatConfigureComponent."); 551744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 552744f5739019d1fd917f981e740b353c3d73fd1a8David Smith sendFormatChange(); 553744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 554744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 555744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::onStart() { 556744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK_EQ(mState, CONFIGURED); 557744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 558744f5739019d1fd917f981e740b353c3d73fd1a8David Smith allocateBuffersOnPort(kPortIndexInput); 559744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 560744f5739019d1fd917f981e740b353c3d73fd1a8David Smith allocateBuffersOnPort(kPortIndexOutput); 561744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 562744f5739019d1fd917f981e740b353c3d73fd1a8David Smith status_t err = mFilter->start(); 563744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (err != (status_t)OK) { 564744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGE("Failed to start filter component, err %d", err); 565744f5739019d1fd917f981e740b353c3d73fd1a8David Smith signalError(err); 566744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return; 567744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 568744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 569744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mPortEOS[kPortIndexInput] = false; 570744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mPortEOS[kPortIndexOutput] = false; 571744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mInputEOSResult = OK; 572744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mState = STARTED; 573744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 574744f5739019d1fd917f981e740b353c3d73fd1a8David Smith requestFillEmptyInput(); 575744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGV("Handled kWhatStart."); 576744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 577744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 578744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::onInputBufferFilled(const sp<AMessage> &msg) { 579744f5739019d1fd917f981e740b353c3d73fd1a8David Smith IOMX::buffer_id bufferID; 580744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 581744f5739019d1fd917f981e740b353c3d73fd1a8David Smith BufferInfo *info = findBufferByID(kPortIndexInput, bufferID); 582744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 583744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (mState != STARTED) { 584744f5739019d1fd917f981e740b353c3d73fd1a8David Smith // we're not running, so we'll just keep that buffer... 585744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info->mStatus = BufferInfo::OWNED_BY_US; 586744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return; 587744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 588744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 589744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (info->mGeneration != mGeneration) { 5902897286dae2934562c48febd4427b8839aeb4007David Smith ALOGV("Caught a stale input buffer [ID %d]", bufferID); 591744f5739019d1fd917f981e740b353c3d73fd1a8David Smith // buffer is stale (taken before a flush/shutdown) - repost it 592744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK_EQ(info->mStatus, BufferInfo::OWNED_BY_US); 593744f5739019d1fd917f981e740b353c3d73fd1a8David Smith postFillThisBuffer(info); 5942897286dae2934562c48febd4427b8839aeb4007David Smith return; 595744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 596744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 597744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK_EQ(info->mStatus, BufferInfo::OWNED_BY_UPSTREAM); 598744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info->mStatus = BufferInfo::OWNED_BY_US; 599744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 600744f5739019d1fd917f981e740b353c3d73fd1a8David Smith sp<ABuffer> buffer; 601744f5739019d1fd917f981e740b353c3d73fd1a8David Smith int32_t err = OK; 602744f5739019d1fd917f981e740b353c3d73fd1a8David Smith bool eos = false; 603744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 604744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (!msg->findBuffer("buffer", &buffer)) { 605744f5739019d1fd917f981e740b353c3d73fd1a8David Smith // these are unfilled buffers returned by client 606744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK(msg->findInt32("err", &err)); 607744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 608744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (err == OK) { 609744f5739019d1fd917f981e740b353c3d73fd1a8David Smith // buffers with no errors are returned on MediaCodec.flush 610744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGV("saw unfilled buffer (MediaCodec.flush)"); 6112897286dae2934562c48febd4427b8839aeb4007David Smith postFillThisBuffer(info); 612744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return; 613744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } else { 614744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGV("saw error %d instead of an input buffer", err); 615744f5739019d1fd917f981e740b353c3d73fd1a8David Smith eos = true; 616744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 617744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 618744f5739019d1fd917f981e740b353c3d73fd1a8David Smith buffer.clear(); 619744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 620744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 621744f5739019d1fd917f981e740b353c3d73fd1a8David Smith int32_t isCSD; 622744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (buffer != NULL && buffer->meta()->findInt32("csd", &isCSD) 623744f5739019d1fd917f981e740b353c3d73fd1a8David Smith && isCSD != 0) { 624744f5739019d1fd917f981e740b353c3d73fd1a8David Smith // ignore codec-specific data buffers 625744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGW("MediaFilter received a codec-specific data buffer"); 626744f5739019d1fd917f981e740b353c3d73fd1a8David Smith postFillThisBuffer(info); 627744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return; 628744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 629744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 630744f5739019d1fd917f981e740b353c3d73fd1a8David Smith int32_t tmp; 631744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) { 632744f5739019d1fd917f981e740b353c3d73fd1a8David Smith eos = true; 633744f5739019d1fd917f981e740b353c3d73fd1a8David Smith err = ERROR_END_OF_STREAM; 634744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 635744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 636744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mAvailableInputBuffers.push_back(info); 637744f5739019d1fd917f981e740b353c3d73fd1a8David Smith processBuffers(); 638744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 639744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (eos) { 640744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mPortEOS[kPortIndexInput] = true; 641744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mInputEOSResult = err; 642744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 643744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 644e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith ALOGV("Handled kWhatInputBufferFilled. [ID %u]", bufferID); 645744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 646744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 647744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::onOutputBufferDrained(const sp<AMessage> &msg) { 648744f5739019d1fd917f981e740b353c3d73fd1a8David Smith IOMX::buffer_id bufferID; 6496dad9ad21ff547fab7f192956e4a3732fd78488bDavid Smith CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 650744f5739019d1fd917f981e740b353c3d73fd1a8David Smith BufferInfo *info = findBufferByID(kPortIndexOutput, bufferID); 651744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 652744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (mState != STARTED) { 653744f5739019d1fd917f981e740b353c3d73fd1a8David Smith // we're not running, so we'll just keep that buffer... 654744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info->mStatus = BufferInfo::OWNED_BY_US; 655744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return; 656744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 657744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 6582897286dae2934562c48febd4427b8839aeb4007David Smith if (info->mGeneration != mGeneration) { 6592897286dae2934562c48febd4427b8839aeb4007David Smith ALOGV("Caught a stale output buffer [ID %d]", bufferID); 6602897286dae2934562c48febd4427b8839aeb4007David Smith // buffer is stale (taken before a flush/shutdown) - keep it 6612897286dae2934562c48febd4427b8839aeb4007David Smith CHECK_EQ(info->mStatus, BufferInfo::OWNED_BY_US); 6622897286dae2934562c48febd4427b8839aeb4007David Smith return; 6632897286dae2934562c48febd4427b8839aeb4007David Smith } 6642897286dae2934562c48febd4427b8839aeb4007David Smith 665744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK_EQ(info->mStatus, BufferInfo::OWNED_BY_UPSTREAM); 666744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info->mStatus = BufferInfo::OWNED_BY_US; 667744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 668744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mAvailableOutputBuffers.push_back(info); 669744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 670744f5739019d1fd917f981e740b353c3d73fd1a8David Smith processBuffers(); 671744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 672744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGV("Handled kWhatOutputBufferDrained. [ID %u]", 673744f5739019d1fd917f981e740b353c3d73fd1a8David Smith bufferID); 674744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 675744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 676744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::onShutdown(const sp<AMessage> &msg) { 677744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mGeneration++; 678744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 679744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (mState != UNINITIALIZED) { 680744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mFilter->reset(); 681744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 682744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 683744f5739019d1fd917f981e740b353c3d73fd1a8David Smith int32_t keepComponentAllocated; 684744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK(msg->findInt32("keepComponentAllocated", &keepComponentAllocated)); 685744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (!keepComponentAllocated || mState == UNINITIALIZED) { 686744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mState = UNINITIALIZED; 687744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } else { 688744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mState = INITIALIZED; 689744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 690744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 691744f5739019d1fd917f981e740b353c3d73fd1a8David Smith sp<AMessage> notify = mNotify->dup(); 692744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("what", CodecBase::kWhatShutdownCompleted); 693744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->post(); 694744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 695744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 696744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::onFlush() { 697744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mGeneration++; 698744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 6992897286dae2934562c48febd4427b8839aeb4007David Smith mAvailableInputBuffers.clear(); 700744f5739019d1fd917f981e740b353c3d73fd1a8David Smith for (size_t i = 0; i < mBuffers[kPortIndexInput].size(); ++i) { 701744f5739019d1fd917f981e740b353c3d73fd1a8David Smith BufferInfo *info = &mBuffers[kPortIndexInput].editItemAt(i); 702744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info->mStatus = BufferInfo::OWNED_BY_US; 703744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 7042897286dae2934562c48febd4427b8839aeb4007David Smith mAvailableOutputBuffers.clear(); 705744f5739019d1fd917f981e740b353c3d73fd1a8David Smith for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) { 706744f5739019d1fd917f981e740b353c3d73fd1a8David Smith BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i); 707744f5739019d1fd917f981e740b353c3d73fd1a8David Smith info->mStatus = BufferInfo::OWNED_BY_US; 7082897286dae2934562c48febd4427b8839aeb4007David Smith mAvailableOutputBuffers.push_back(info); 709744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 710744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 711744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mPortEOS[kPortIndexInput] = false; 712744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mPortEOS[kPortIndexOutput] = false; 713744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mInputEOSResult = OK; 714744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 715744f5739019d1fd917f981e740b353c3d73fd1a8David Smith sp<AMessage> notify = mNotify->dup(); 716744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->setInt32("what", CodecBase::kWhatFlushCompleted); 717744f5739019d1fd917f981e740b353c3d73fd1a8David Smith notify->post(); 7182897286dae2934562c48febd4427b8839aeb4007David Smith ALOGV("Posted kWhatFlushCompleted"); 719744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 7202897286dae2934562c48febd4427b8839aeb4007David Smith // MediaCodec returns all input buffers after flush, so in 7212897286dae2934562c48febd4427b8839aeb4007David Smith // onInputBufferFilled we call postFillThisBuffer on them 722744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 723744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 724744f5739019d1fd917f981e740b353c3d73fd1a8David Smithvoid MediaFilter::onSetParameters(const sp<AMessage> &msg) { 725744f5739019d1fd917f981e740b353c3d73fd1a8David Smith CHECK(mState != STARTED); 726744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 727744f5739019d1fd917f981e740b353c3d73fd1a8David Smith status_t err = mFilter->setParameters(msg); 728744f5739019d1fd917f981e740b353c3d73fd1a8David Smith if (err != (status_t)OK) { 729744f5739019d1fd917f981e740b353c3d73fd1a8David Smith ALOGE("setParameters returned err %d", err); 730744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 731744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} 732744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 733e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smithvoid MediaFilter::onCreateInputSurface() { 734e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith CHECK(mState == CONFIGURED); 735e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 736e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith mGraphicBufferListener = new GraphicBufferListener; 737e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 738e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith sp<AMessage> notify = new AMessage(); 7391d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar notify->setTarget(this); 740e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith status_t err = mGraphicBufferListener->init( 741e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith notify, mStride, mSliceHeight, kBufferCountActual); 742e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 743e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith if (err != OK) { 744e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith ALOGE("Failed to init mGraphicBufferListener: %d", err); 745e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith signalError(err); 746e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith return; 747e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith } 748e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 749e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith sp<AMessage> reply = mNotify->dup(); 750e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith reply->setInt32("what", CodecBase::kWhatInputSurfaceCreated); 751e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith reply->setObject( 752e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith "input-surface", 753e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith new BufferProducerWrapper( 754e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith mGraphicBufferListener->getIGraphicBufferProducer())); 755e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith reply->post(); 756e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith} 757e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 758e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smithvoid MediaFilter::onInputFrameAvailable() { 7598ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza BufferItem item = mGraphicBufferListener->getBufferItem(); 760e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith sp<GraphicBuffer> buf = mGraphicBufferListener->getBuffer(item); 761e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 762e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith // get pointer to graphic buffer 763e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith void* bufPtr; 764e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith buf->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &bufPtr); 765e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 766e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith // HACK - there is no OMX_COLOR_FORMATTYPE value for RGBA, so the format 767e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith // conversion is hardcoded until we add this. 768e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith // TODO: check input format and convert only if necessary 769e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith // copy RGBA graphic buffer into temporary ARGB input buffer 770e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith BufferInfo *inputInfo = new BufferInfo; 771e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith inputInfo->mData = new ABuffer(buf->getWidth() * buf->getHeight() * 4); 772e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith ALOGV("Copying surface data into temp buffer."); 773e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith convertRGBAToARGB( 774e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith (uint8_t*)bufPtr, buf->getWidth(), buf->getHeight(), 775e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith buf->getStride(), inputInfo->mData->data()); 776a8f5e0c24143299e3b3d722487de7322f7761559Pablo Ceballos inputInfo->mBufferID = item.mSlot; 777e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith inputInfo->mGeneration = mGeneration; 778e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith inputInfo->mOutputFlags = 0; 779e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith inputInfo->mStatus = BufferInfo::OWNED_BY_US; 780e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith inputInfo->mData->meta()->setInt64("timeUs", item.mTimestamp / 1000); 781e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 782e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith mAvailableInputBuffers.push_back(inputInfo); 783e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 784e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith mGraphicBufferListener->releaseBuffer(item); 785e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 786e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith signalProcessBuffers(); 787e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith} 788e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 789e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smithvoid MediaFilter::onSignalEndOfInputStream() { 790e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith // if using input surface, need to send an EOS output buffer 791e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith if (mGraphicBufferListener != NULL) { 792e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith Vector<BufferInfo> *outputBufs = &mBuffers[kPortIndexOutput]; 793e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith BufferInfo* eosBuf; 794e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith bool foundBuf = false; 795e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith for (size_t i = 0; i < kBufferCountActual; i++) { 796e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith eosBuf = &outputBufs->editItemAt(i); 797e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith if (eosBuf->mStatus == BufferInfo::OWNED_BY_US) { 798e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith foundBuf = true; 799e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith break; 800e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith } 801e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith } 802e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 803e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith if (!foundBuf) { 804e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith ALOGE("onSignalEndOfInputStream failed to find an output buffer"); 805e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith return; 806e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith } 807e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 808e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith eosBuf->mOutputFlags = OMX_BUFFERFLAG_EOS; 809e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith eosBuf->mGeneration = mGeneration; 810e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith eosBuf->mData->setRange(0, 0); 811e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith postDrainThisBuffer(eosBuf); 812ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("Posted EOS on output buffer %u", eosBuf->mBufferID); 813e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith } 814e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 815e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith mPortEOS[kPortIndexOutput] = true; 816e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith sp<AMessage> notify = mNotify->dup(); 817e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith notify->setInt32("what", CodecBase::kWhatSignaledInputEOS); 818e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith notify->post(); 819e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 820e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith ALOGV("Output stream saw EOS."); 821e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith} 822e7f4e676bb88b17241d71731f9ea50c18cfcb039David Smith 823744f5739019d1fd917f981e740b353c3d73fd1a8David Smith} // namespace android 824