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> &params) {
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