10f51f144dba401346c0078334f00f9e44d4146e5David Smith/*
20f51f144dba401346c0078334f00f9e44d4146e5David Smith * Copyright (C) 2014 The Android Open Source Project
30f51f144dba401346c0078334f00f9e44d4146e5David Smith *
40f51f144dba401346c0078334f00f9e44d4146e5David Smith * Licensed under the Apache License, Version 2.0 (the "License");
50f51f144dba401346c0078334f00f9e44d4146e5David Smith * you may not use this file except in compliance with the License.
60f51f144dba401346c0078334f00f9e44d4146e5David Smith * You may obtain a copy of the License at
70f51f144dba401346c0078334f00f9e44d4146e5David Smith *
80f51f144dba401346c0078334f00f9e44d4146e5David Smith *      http://www.apache.org/licenses/LICENSE-2.0
90f51f144dba401346c0078334f00f9e44d4146e5David Smith *
100f51f144dba401346c0078334f00f9e44d4146e5David Smith * Unless required by applicable law or agreed to in writing, software
110f51f144dba401346c0078334f00f9e44d4146e5David Smith * distributed under the License is distributed on an "AS IS" BASIS,
120f51f144dba401346c0078334f00f9e44d4146e5David Smith * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130f51f144dba401346c0078334f00f9e44d4146e5David Smith * See the License for the specific language governing permissions and
140f51f144dba401346c0078334f00f9e44d4146e5David Smith * limitations under the License.
150f51f144dba401346c0078334f00f9e44d4146e5David Smith */
160f51f144dba401346c0078334f00f9e44d4146e5David Smith
170f51f144dba401346c0078334f00f9e44d4146e5David Smith//#define LOG_NDEBUG 0
180f51f144dba401346c0078334f00f9e44d4146e5David Smith#define LOG_TAG "mediafilterTest"
190f51f144dba401346c0078334f00f9e44d4146e5David Smith
200f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <inttypes.h>
210f51f144dba401346c0078334f00f9e44d4146e5David Smith
220f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <binder/ProcessState.h>
230f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <filters/ColorConvert.h>
240f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <gui/ISurfaceComposer.h>
250f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <gui/SurfaceComposerClient.h>
260f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <gui/Surface.h>
270f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <media/ICrypto.h>
280f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <media/IMediaHTTPService.h>
290f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <media/stagefright/foundation/ABuffer.h>
300f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <media/stagefright/foundation/ADebug.h>
310f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <media/stagefright/foundation/AMessage.h>
320f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <media/stagefright/DataSource.h>
330f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <media/stagefright/MediaCodec.h>
340f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <media/stagefright/NuMediaExtractor.h>
350f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <media/stagefright/RenderScriptWrapper.h>
360f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <OMX_IVCommon.h>
370f51f144dba401346c0078334f00f9e44d4146e5David Smith#include <ui/DisplayInfo.h>
380f51f144dba401346c0078334f00f9e44d4146e5David Smith
390f51f144dba401346c0078334f00f9e44d4146e5David Smith#include "RenderScript.h"
400f51f144dba401346c0078334f00f9e44d4146e5David Smith#include "ScriptC_argbtorgba.h"
410f51f144dba401346c0078334f00f9e44d4146e5David Smith#include "ScriptC_nightvision.h"
420f51f144dba401346c0078334f00f9e44d4146e5David Smith#include "ScriptC_saturation.h"
430f51f144dba401346c0078334f00f9e44d4146e5David Smith
440f51f144dba401346c0078334f00f9e44d4146e5David Smith// test parameters
450f51f144dba401346c0078334f00f9e44d4146e5David Smithstatic const bool kTestFlush = true;        // Note: true will drop 1 out of
460f51f144dba401346c0078334f00f9e44d4146e5David Smithstatic const int kFlushAfterFrames = 25;    // kFlushAfterFrames output frames
470f51f144dba401346c0078334f00f9e44d4146e5David Smithstatic const int64_t kTimeout = 500ll;
480f51f144dba401346c0078334f00f9e44d4146e5David Smith
490f51f144dba401346c0078334f00f9e44d4146e5David Smith// built-in filter parameters
500f51f144dba401346c0078334f00f9e44d4146e5David Smithstatic const int32_t kInvert = false;   // ZeroFilter param
510f51f144dba401346c0078334f00f9e44d4146e5David Smithstatic const float kBlurRadius = 15.0f; // IntrinsicBlurFilter param
520f51f144dba401346c0078334f00f9e44d4146e5David Smithstatic const float kSaturation = 0.0f;  // SaturationFilter param
530f51f144dba401346c0078334f00f9e44d4146e5David Smith
540f51f144dba401346c0078334f00f9e44d4146e5David Smithstatic void usage(const char *me) {
550f51f144dba401346c0078334f00f9e44d4146e5David Smith    fprintf(stderr, "usage: [flags] %s\n"
560f51f144dba401346c0078334f00f9e44d4146e5David Smith                    "\t[-b] use IntrinsicBlurFilter\n"
570f51f144dba401346c0078334f00f9e44d4146e5David Smith                    "\t[-c] use argb to rgba conversion RSFilter\n"
580f51f144dba401346c0078334f00f9e44d4146e5David Smith                    "\t[-n] use night vision RSFilter\n"
590f51f144dba401346c0078334f00f9e44d4146e5David Smith                    "\t[-r] use saturation RSFilter\n"
600f51f144dba401346c0078334f00f9e44d4146e5David Smith                    "\t[-s] use SaturationFilter\n"
610f51f144dba401346c0078334f00f9e44d4146e5David Smith                    "\t[-z] use ZeroFilter (copy filter)\n"
620f51f144dba401346c0078334f00f9e44d4146e5David Smith                    "\t[-R] render output to surface (enables -S)\n"
630f51f144dba401346c0078334f00f9e44d4146e5David Smith                    "\t[-S] allocate buffers from a surface\n"
640f51f144dba401346c0078334f00f9e44d4146e5David Smith                    "\t[-T] use render timestamps (enables -R)\n",
650f51f144dba401346c0078334f00f9e44d4146e5David Smith                    me);
660f51f144dba401346c0078334f00f9e44d4146e5David Smith    exit(1);
670f51f144dba401346c0078334f00f9e44d4146e5David Smith}
680f51f144dba401346c0078334f00f9e44d4146e5David Smith
690f51f144dba401346c0078334f00f9e44d4146e5David Smithnamespace android {
700f51f144dba401346c0078334f00f9e44d4146e5David Smith
710f51f144dba401346c0078334f00f9e44d4146e5David Smithstruct SaturationRSFilter : RenderScriptWrapper::RSFilterCallback {
720f51f144dba401346c0078334f00f9e44d4146e5David Smith    void init(RSC::sp<RSC::RS> context) {
730f51f144dba401346c0078334f00f9e44d4146e5David Smith        mScript = new ScriptC_saturation(context);
740f51f144dba401346c0078334f00f9e44d4146e5David Smith        mScript->set_gSaturation(3.f);
750f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
760f51f144dba401346c0078334f00f9e44d4146e5David Smith
770f51f144dba401346c0078334f00f9e44d4146e5David Smith    virtual status_t processBuffers(
780f51f144dba401346c0078334f00f9e44d4146e5David Smith            RSC::Allocation *inBuffer, RSC::Allocation *outBuffer) {
790f51f144dba401346c0078334f00f9e44d4146e5David Smith        mScript->forEach_root(inBuffer, outBuffer);
800f51f144dba401346c0078334f00f9e44d4146e5David Smith
810f51f144dba401346c0078334f00f9e44d4146e5David Smith        return OK;
820f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
830f51f144dba401346c0078334f00f9e44d4146e5David Smith
8431de88566257d5546cf4eee9064d96926a4b0c24Lajos Molnar    status_t handleSetParameters(const sp<AMessage> &msg __unused) {
850f51f144dba401346c0078334f00f9e44d4146e5David Smith        return OK;
860f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
870f51f144dba401346c0078334f00f9e44d4146e5David Smith
880f51f144dba401346c0078334f00f9e44d4146e5David Smithprivate:
890f51f144dba401346c0078334f00f9e44d4146e5David Smith    RSC::sp<ScriptC_saturation> mScript;
900f51f144dba401346c0078334f00f9e44d4146e5David Smith};
910f51f144dba401346c0078334f00f9e44d4146e5David Smith
920f51f144dba401346c0078334f00f9e44d4146e5David Smithstruct NightVisionRSFilter : RenderScriptWrapper::RSFilterCallback {
930f51f144dba401346c0078334f00f9e44d4146e5David Smith    void init(RSC::sp<RSC::RS> context) {
940f51f144dba401346c0078334f00f9e44d4146e5David Smith        mScript = new ScriptC_nightvision(context);
950f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
960f51f144dba401346c0078334f00f9e44d4146e5David Smith
970f51f144dba401346c0078334f00f9e44d4146e5David Smith    virtual status_t processBuffers(
980f51f144dba401346c0078334f00f9e44d4146e5David Smith            RSC::Allocation *inBuffer, RSC::Allocation *outBuffer) {
990f51f144dba401346c0078334f00f9e44d4146e5David Smith        mScript->forEach_root(inBuffer, outBuffer);
1000f51f144dba401346c0078334f00f9e44d4146e5David Smith
1010f51f144dba401346c0078334f00f9e44d4146e5David Smith        return OK;
1020f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
1030f51f144dba401346c0078334f00f9e44d4146e5David Smith
10431de88566257d5546cf4eee9064d96926a4b0c24Lajos Molnar    status_t handleSetParameters(const sp<AMessage> &msg __unused) {
1050f51f144dba401346c0078334f00f9e44d4146e5David Smith        return OK;
1060f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
1070f51f144dba401346c0078334f00f9e44d4146e5David Smith
1080f51f144dba401346c0078334f00f9e44d4146e5David Smithprivate:
1090f51f144dba401346c0078334f00f9e44d4146e5David Smith    RSC::sp<ScriptC_nightvision> mScript;
1100f51f144dba401346c0078334f00f9e44d4146e5David Smith};
1110f51f144dba401346c0078334f00f9e44d4146e5David Smith
1120f51f144dba401346c0078334f00f9e44d4146e5David Smithstruct ARGBToRGBARSFilter : RenderScriptWrapper::RSFilterCallback {
1130f51f144dba401346c0078334f00f9e44d4146e5David Smith    void init(RSC::sp<RSC::RS> context) {
1140f51f144dba401346c0078334f00f9e44d4146e5David Smith        mScript = new ScriptC_argbtorgba(context);
1150f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
1160f51f144dba401346c0078334f00f9e44d4146e5David Smith
1170f51f144dba401346c0078334f00f9e44d4146e5David Smith    virtual status_t processBuffers(
1180f51f144dba401346c0078334f00f9e44d4146e5David Smith            RSC::Allocation *inBuffer, RSC::Allocation *outBuffer) {
1190f51f144dba401346c0078334f00f9e44d4146e5David Smith        mScript->forEach_root(inBuffer, outBuffer);
1200f51f144dba401346c0078334f00f9e44d4146e5David Smith
1210f51f144dba401346c0078334f00f9e44d4146e5David Smith        return OK;
1220f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
1230f51f144dba401346c0078334f00f9e44d4146e5David Smith
12431de88566257d5546cf4eee9064d96926a4b0c24Lajos Molnar    status_t handleSetParameters(const sp<AMessage> &msg __unused) {
1250f51f144dba401346c0078334f00f9e44d4146e5David Smith        return OK;
1260f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
1270f51f144dba401346c0078334f00f9e44d4146e5David Smith
1280f51f144dba401346c0078334f00f9e44d4146e5David Smithprivate:
1290f51f144dba401346c0078334f00f9e44d4146e5David Smith    RSC::sp<ScriptC_argbtorgba> mScript;
1300f51f144dba401346c0078334f00f9e44d4146e5David Smith};
1310f51f144dba401346c0078334f00f9e44d4146e5David Smith
1320f51f144dba401346c0078334f00f9e44d4146e5David Smithstruct CodecState {
1330f51f144dba401346c0078334f00f9e44d4146e5David Smith    sp<MediaCodec> mCodec;
1340f51f144dba401346c0078334f00f9e44d4146e5David Smith    Vector<sp<ABuffer> > mInBuffers;
1350f51f144dba401346c0078334f00f9e44d4146e5David Smith    Vector<sp<ABuffer> > mOutBuffers;
1360f51f144dba401346c0078334f00f9e44d4146e5David Smith    bool mSignalledInputEOS;
1370f51f144dba401346c0078334f00f9e44d4146e5David Smith    bool mSawOutputEOS;
1380f51f144dba401346c0078334f00f9e44d4146e5David Smith    int64_t mNumBuffersDecoded;
1390f51f144dba401346c0078334f00f9e44d4146e5David Smith};
1400f51f144dba401346c0078334f00f9e44d4146e5David Smith
1410f51f144dba401346c0078334f00f9e44d4146e5David Smithstruct DecodedFrame {
1420f51f144dba401346c0078334f00f9e44d4146e5David Smith    size_t index;
1430f51f144dba401346c0078334f00f9e44d4146e5David Smith    size_t offset;
1440f51f144dba401346c0078334f00f9e44d4146e5David Smith    size_t size;
1450f51f144dba401346c0078334f00f9e44d4146e5David Smith    int64_t presentationTimeUs;
1460f51f144dba401346c0078334f00f9e44d4146e5David Smith    uint32_t flags;
1470f51f144dba401346c0078334f00f9e44d4146e5David Smith};
1480f51f144dba401346c0078334f00f9e44d4146e5David Smith
1490f51f144dba401346c0078334f00f9e44d4146e5David Smithenum FilterType {
1500f51f144dba401346c0078334f00f9e44d4146e5David Smith    FILTERTYPE_ZERO,
1510f51f144dba401346c0078334f00f9e44d4146e5David Smith    FILTERTYPE_INTRINSIC_BLUR,
1520f51f144dba401346c0078334f00f9e44d4146e5David Smith    FILTERTYPE_SATURATION,
1530f51f144dba401346c0078334f00f9e44d4146e5David Smith    FILTERTYPE_RS_SATURATION,
1540f51f144dba401346c0078334f00f9e44d4146e5David Smith    FILTERTYPE_RS_NIGHT_VISION,
1550f51f144dba401346c0078334f00f9e44d4146e5David Smith    FILTERTYPE_RS_ARGB_TO_RGBA,
1560f51f144dba401346c0078334f00f9e44d4146e5David Smith};
1570f51f144dba401346c0078334f00f9e44d4146e5David Smith
1580f51f144dba401346c0078334f00f9e44d4146e5David Smithsize_t inputFramesSinceFlush = 0;
1590f51f144dba401346c0078334f00f9e44d4146e5David Smithvoid tryCopyDecodedBuffer(
1600f51f144dba401346c0078334f00f9e44d4146e5David Smith        List<DecodedFrame> *decodedFrameIndices,
1610f51f144dba401346c0078334f00f9e44d4146e5David Smith        CodecState *filterState,
1620f51f144dba401346c0078334f00f9e44d4146e5David Smith        CodecState *vidState) {
1630f51f144dba401346c0078334f00f9e44d4146e5David Smith    if (decodedFrameIndices->empty()) {
1640f51f144dba401346c0078334f00f9e44d4146e5David Smith        return;
1650f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
1660f51f144dba401346c0078334f00f9e44d4146e5David Smith
1670f51f144dba401346c0078334f00f9e44d4146e5David Smith    size_t filterIndex;
1680f51f144dba401346c0078334f00f9e44d4146e5David Smith    status_t err = filterState->mCodec->dequeueInputBuffer(
1690f51f144dba401346c0078334f00f9e44d4146e5David Smith            &filterIndex, kTimeout);
1700f51f144dba401346c0078334f00f9e44d4146e5David Smith    if (err != OK) {
1710f51f144dba401346c0078334f00f9e44d4146e5David Smith        return;
1720f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
1730f51f144dba401346c0078334f00f9e44d4146e5David Smith
1740f51f144dba401346c0078334f00f9e44d4146e5David Smith    ++inputFramesSinceFlush;
1750f51f144dba401346c0078334f00f9e44d4146e5David Smith
1760f51f144dba401346c0078334f00f9e44d4146e5David Smith    DecodedFrame frame = *decodedFrameIndices->begin();
1770f51f144dba401346c0078334f00f9e44d4146e5David Smith
1780f51f144dba401346c0078334f00f9e44d4146e5David Smith    // only consume a buffer if we are not going to flush, since we expect
1790f51f144dba401346c0078334f00f9e44d4146e5David Smith    // the dequeue -> flush -> queue operation to cause an error and
1800f51f144dba401346c0078334f00f9e44d4146e5David Smith    // not produce an output frame
1810f51f144dba401346c0078334f00f9e44d4146e5David Smith    if (!kTestFlush || inputFramesSinceFlush < kFlushAfterFrames) {
1820f51f144dba401346c0078334f00f9e44d4146e5David Smith        decodedFrameIndices->erase(decodedFrameIndices->begin());
1830f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
1840f51f144dba401346c0078334f00f9e44d4146e5David Smith    size_t outIndex = frame.index;
1850f51f144dba401346c0078334f00f9e44d4146e5David Smith
1860f51f144dba401346c0078334f00f9e44d4146e5David Smith    const sp<ABuffer> &srcBuffer =
1870f51f144dba401346c0078334f00f9e44d4146e5David Smith        vidState->mOutBuffers.itemAt(outIndex);
1880f51f144dba401346c0078334f00f9e44d4146e5David Smith    const sp<ABuffer> &destBuffer =
1890f51f144dba401346c0078334f00f9e44d4146e5David Smith        filterState->mInBuffers.itemAt(filterIndex);
1900f51f144dba401346c0078334f00f9e44d4146e5David Smith
1910f51f144dba401346c0078334f00f9e44d4146e5David Smith    sp<AMessage> srcFormat, destFormat;
1920f51f144dba401346c0078334f00f9e44d4146e5David Smith    vidState->mCodec->getOutputFormat(&srcFormat);
1930f51f144dba401346c0078334f00f9e44d4146e5David Smith    filterState->mCodec->getInputFormat(&destFormat);
1940f51f144dba401346c0078334f00f9e44d4146e5David Smith
1950f51f144dba401346c0078334f00f9e44d4146e5David Smith    int32_t srcWidth, srcHeight, srcStride, srcSliceHeight;
1960f51f144dba401346c0078334f00f9e44d4146e5David Smith    int32_t srcColorFormat, destColorFormat;
1970f51f144dba401346c0078334f00f9e44d4146e5David Smith    int32_t destWidth, destHeight, destStride, destSliceHeight;
1980f51f144dba401346c0078334f00f9e44d4146e5David Smith    CHECK(srcFormat->findInt32("stride", &srcStride)
1990f51f144dba401346c0078334f00f9e44d4146e5David Smith            && srcFormat->findInt32("slice-height", &srcSliceHeight)
2000f51f144dba401346c0078334f00f9e44d4146e5David Smith            && srcFormat->findInt32("width", &srcWidth)
2010f51f144dba401346c0078334f00f9e44d4146e5David Smith            && srcFormat->findInt32("height", & srcHeight)
2020f51f144dba401346c0078334f00f9e44d4146e5David Smith            && srcFormat->findInt32("color-format", &srcColorFormat));
2030f51f144dba401346c0078334f00f9e44d4146e5David Smith    CHECK(destFormat->findInt32("stride", &destStride)
2040f51f144dba401346c0078334f00f9e44d4146e5David Smith            && destFormat->findInt32("slice-height", &destSliceHeight)
2050f51f144dba401346c0078334f00f9e44d4146e5David Smith            && destFormat->findInt32("width", &destWidth)
2060f51f144dba401346c0078334f00f9e44d4146e5David Smith            && destFormat->findInt32("height", & destHeight)
2070f51f144dba401346c0078334f00f9e44d4146e5David Smith            && destFormat->findInt32("color-format", &destColorFormat));
2080f51f144dba401346c0078334f00f9e44d4146e5David Smith
2090f51f144dba401346c0078334f00f9e44d4146e5David Smith    CHECK(srcWidth <= destStride && srcHeight <= destSliceHeight);
2100f51f144dba401346c0078334f00f9e44d4146e5David Smith
2110f51f144dba401346c0078334f00f9e44d4146e5David Smith    convertYUV420spToARGB(
2120f51f144dba401346c0078334f00f9e44d4146e5David Smith            srcBuffer->data(),
2130f51f144dba401346c0078334f00f9e44d4146e5David Smith            srcBuffer->data() + srcStride * srcSliceHeight,
2140f51f144dba401346c0078334f00f9e44d4146e5David Smith            srcWidth,
2150f51f144dba401346c0078334f00f9e44d4146e5David Smith            srcHeight,
2160f51f144dba401346c0078334f00f9e44d4146e5David Smith            destBuffer->data());
2170f51f144dba401346c0078334f00f9e44d4146e5David Smith
2180f51f144dba401346c0078334f00f9e44d4146e5David Smith    // copy timestamp
2190f51f144dba401346c0078334f00f9e44d4146e5David Smith    int64_t timeUs;
2200f51f144dba401346c0078334f00f9e44d4146e5David Smith    CHECK(srcBuffer->meta()->findInt64("timeUs", &timeUs));
2210f51f144dba401346c0078334f00f9e44d4146e5David Smith    destBuffer->meta()->setInt64("timeUs", timeUs);
2220f51f144dba401346c0078334f00f9e44d4146e5David Smith
2230f51f144dba401346c0078334f00f9e44d4146e5David Smith    if (kTestFlush && inputFramesSinceFlush >= kFlushAfterFrames) {
2240f51f144dba401346c0078334f00f9e44d4146e5David Smith        inputFramesSinceFlush = 0;
2250f51f144dba401346c0078334f00f9e44d4146e5David Smith
2260f51f144dba401346c0078334f00f9e44d4146e5David Smith        // check that queueing a buffer that was dequeued before flush
2270f51f144dba401346c0078334f00f9e44d4146e5David Smith        // fails with expected error EACCES
2280f51f144dba401346c0078334f00f9e44d4146e5David Smith        filterState->mCodec->flush();
2290f51f144dba401346c0078334f00f9e44d4146e5David Smith
2300f51f144dba401346c0078334f00f9e44d4146e5David Smith        err = filterState->mCodec->queueInputBuffer(
2310f51f144dba401346c0078334f00f9e44d4146e5David Smith                filterIndex, 0 /* offset */, destBuffer->size(),
2320f51f144dba401346c0078334f00f9e44d4146e5David Smith                timeUs, frame.flags);
2330f51f144dba401346c0078334f00f9e44d4146e5David Smith
2340f51f144dba401346c0078334f00f9e44d4146e5David Smith        if (err == OK) {
2350f51f144dba401346c0078334f00f9e44d4146e5David Smith            ALOGE("FAIL: queue after flush returned OK");
2360f51f144dba401346c0078334f00f9e44d4146e5David Smith        } else if (err != -EACCES) {
2370f51f144dba401346c0078334f00f9e44d4146e5David Smith            ALOGE("queueInputBuffer after flush returned %d, "
2380f51f144dba401346c0078334f00f9e44d4146e5David Smith                    "expected -EACCES (-13)", err);
2390f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
2400f51f144dba401346c0078334f00f9e44d4146e5David Smith    } else {
2410f51f144dba401346c0078334f00f9e44d4146e5David Smith        err = filterState->mCodec->queueInputBuffer(
2420f51f144dba401346c0078334f00f9e44d4146e5David Smith                filterIndex, 0 /* offset */, destBuffer->size(),
2430f51f144dba401346c0078334f00f9e44d4146e5David Smith                timeUs, frame.flags);
2440f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK(err == OK);
2450f51f144dba401346c0078334f00f9e44d4146e5David Smith
2460f51f144dba401346c0078334f00f9e44d4146e5David Smith        err = vidState->mCodec->releaseOutputBuffer(outIndex);
2470f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK(err == OK);
2480f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
2490f51f144dba401346c0078334f00f9e44d4146e5David Smith}
2500f51f144dba401346c0078334f00f9e44d4146e5David Smith
2510f51f144dba401346c0078334f00f9e44d4146e5David Smithsize_t outputFramesSinceFlush = 0;
2520f51f144dba401346c0078334f00f9e44d4146e5David Smithvoid tryDrainOutputBuffer(
2530f51f144dba401346c0078334f00f9e44d4146e5David Smith        CodecState *filterState,
2540f51f144dba401346c0078334f00f9e44d4146e5David Smith        const sp<Surface> &surface, bool renderSurface,
2550f51f144dba401346c0078334f00f9e44d4146e5David Smith        bool useTimestamp, int64_t *startTimeRender) {
2560f51f144dba401346c0078334f00f9e44d4146e5David Smith    size_t index;
2570f51f144dba401346c0078334f00f9e44d4146e5David Smith    size_t offset;
2580f51f144dba401346c0078334f00f9e44d4146e5David Smith    size_t size;
2590f51f144dba401346c0078334f00f9e44d4146e5David Smith    int64_t presentationTimeUs;
2600f51f144dba401346c0078334f00f9e44d4146e5David Smith    uint32_t flags;
2610f51f144dba401346c0078334f00f9e44d4146e5David Smith    status_t err = filterState->mCodec->dequeueOutputBuffer(
2620f51f144dba401346c0078334f00f9e44d4146e5David Smith            &index, &offset, &size, &presentationTimeUs, &flags,
2630f51f144dba401346c0078334f00f9e44d4146e5David Smith            kTimeout);
2640f51f144dba401346c0078334f00f9e44d4146e5David Smith
2650f51f144dba401346c0078334f00f9e44d4146e5David Smith    if (err != OK) {
2660f51f144dba401346c0078334f00f9e44d4146e5David Smith        return;
2670f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
2680f51f144dba401346c0078334f00f9e44d4146e5David Smith
2690f51f144dba401346c0078334f00f9e44d4146e5David Smith    ++outputFramesSinceFlush;
2700f51f144dba401346c0078334f00f9e44d4146e5David Smith
2710f51f144dba401346c0078334f00f9e44d4146e5David Smith    if (kTestFlush && outputFramesSinceFlush >= kFlushAfterFrames) {
2720f51f144dba401346c0078334f00f9e44d4146e5David Smith        filterState->mCodec->flush();
2730f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
2740f51f144dba401346c0078334f00f9e44d4146e5David Smith
2750f51f144dba401346c0078334f00f9e44d4146e5David Smith    if (surface == NULL || !renderSurface) {
2760f51f144dba401346c0078334f00f9e44d4146e5David Smith        err = filterState->mCodec->releaseOutputBuffer(index);
2770f51f144dba401346c0078334f00f9e44d4146e5David Smith    } else if (useTimestamp) {
2780f51f144dba401346c0078334f00f9e44d4146e5David Smith        if (*startTimeRender == -1) {
2790f51f144dba401346c0078334f00f9e44d4146e5David Smith            // begin rendering 2 vsyncs after first decode
2800f51f144dba401346c0078334f00f9e44d4146e5David Smith            *startTimeRender = systemTime(SYSTEM_TIME_MONOTONIC)
2810f51f144dba401346c0078334f00f9e44d4146e5David Smith                    + 33000000 - (presentationTimeUs * 1000);
2820f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
2830f51f144dba401346c0078334f00f9e44d4146e5David Smith        presentationTimeUs =
2840f51f144dba401346c0078334f00f9e44d4146e5David Smith                (presentationTimeUs * 1000) + *startTimeRender;
2850f51f144dba401346c0078334f00f9e44d4146e5David Smith        err = filterState->mCodec->renderOutputBufferAndRelease(
2860f51f144dba401346c0078334f00f9e44d4146e5David Smith                index, presentationTimeUs);
2870f51f144dba401346c0078334f00f9e44d4146e5David Smith    } else {
2880f51f144dba401346c0078334f00f9e44d4146e5David Smith        err = filterState->mCodec->renderOutputBufferAndRelease(index);
2890f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
2900f51f144dba401346c0078334f00f9e44d4146e5David Smith
2910f51f144dba401346c0078334f00f9e44d4146e5David Smith    if (kTestFlush && outputFramesSinceFlush >= kFlushAfterFrames) {
2920f51f144dba401346c0078334f00f9e44d4146e5David Smith        outputFramesSinceFlush = 0;
2930f51f144dba401346c0078334f00f9e44d4146e5David Smith
2940f51f144dba401346c0078334f00f9e44d4146e5David Smith        // releasing the buffer dequeued before flush should cause an error
2950f51f144dba401346c0078334f00f9e44d4146e5David Smith        // if so, the frame will also be skipped in output stream
2960f51f144dba401346c0078334f00f9e44d4146e5David Smith        if (err == OK) {
2970f51f144dba401346c0078334f00f9e44d4146e5David Smith            ALOGE("FAIL: release after flush returned OK");
2980f51f144dba401346c0078334f00f9e44d4146e5David Smith        } else if (err != -EACCES) {
2990f51f144dba401346c0078334f00f9e44d4146e5David Smith            ALOGE("releaseOutputBuffer after flush returned %d, "
3000f51f144dba401346c0078334f00f9e44d4146e5David Smith                    "expected -EACCES (-13)", err);
3010f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
3020f51f144dba401346c0078334f00f9e44d4146e5David Smith    } else {
3030f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK(err == OK);
3040f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
3050f51f144dba401346c0078334f00f9e44d4146e5David Smith
3060f51f144dba401346c0078334f00f9e44d4146e5David Smith    if (flags & MediaCodec::BUFFER_FLAG_EOS) {
3070f51f144dba401346c0078334f00f9e44d4146e5David Smith        ALOGV("reached EOS on output.");
3080f51f144dba401346c0078334f00f9e44d4146e5David Smith        filterState->mSawOutputEOS = true;
3090f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
3100f51f144dba401346c0078334f00f9e44d4146e5David Smith}
3110f51f144dba401346c0078334f00f9e44d4146e5David Smith
3120f51f144dba401346c0078334f00f9e44d4146e5David Smithstatic int decode(
3130f51f144dba401346c0078334f00f9e44d4146e5David Smith        const sp<ALooper> &looper,
3140f51f144dba401346c0078334f00f9e44d4146e5David Smith        const char *path,
3150f51f144dba401346c0078334f00f9e44d4146e5David Smith        const sp<Surface> &surface,
3160f51f144dba401346c0078334f00f9e44d4146e5David Smith        bool renderSurface,
3170f51f144dba401346c0078334f00f9e44d4146e5David Smith        bool useTimestamp,
3180f51f144dba401346c0078334f00f9e44d4146e5David Smith        FilterType filterType) {
3190f51f144dba401346c0078334f00f9e44d4146e5David Smith
3200f51f144dba401346c0078334f00f9e44d4146e5David Smith    static int64_t kTimeout = 500ll;
3210f51f144dba401346c0078334f00f9e44d4146e5David Smith
3220f51f144dba401346c0078334f00f9e44d4146e5David Smith    sp<NuMediaExtractor> extractor = new NuMediaExtractor;
3230f51f144dba401346c0078334f00f9e44d4146e5David Smith    if (extractor->setDataSource(NULL /* httpService */, path) != OK) {
3240f51f144dba401346c0078334f00f9e44d4146e5David Smith        fprintf(stderr, "unable to instantiate extractor.\n");
3250f51f144dba401346c0078334f00f9e44d4146e5David Smith        return 1;
3260f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
3270f51f144dba401346c0078334f00f9e44d4146e5David Smith
3280f51f144dba401346c0078334f00f9e44d4146e5David Smith    KeyedVector<size_t, CodecState> stateByTrack;
3290f51f144dba401346c0078334f00f9e44d4146e5David Smith
3300f51f144dba401346c0078334f00f9e44d4146e5David Smith    CodecState *vidState = NULL;
3310f51f144dba401346c0078334f00f9e44d4146e5David Smith    for (size_t i = 0; i < extractor->countTracks(); ++i) {
3320f51f144dba401346c0078334f00f9e44d4146e5David Smith        sp<AMessage> format;
3330f51f144dba401346c0078334f00f9e44d4146e5David Smith        status_t err = extractor->getTrackFormat(i, &format);
3340f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK(err == OK);
3350f51f144dba401346c0078334f00f9e44d4146e5David Smith
3360f51f144dba401346c0078334f00f9e44d4146e5David Smith        AString mime;
3370f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK(format->findString("mime", &mime));
3380f51f144dba401346c0078334f00f9e44d4146e5David Smith        bool isVideo = !strncasecmp(mime.c_str(), "video/", 6);
3390f51f144dba401346c0078334f00f9e44d4146e5David Smith        if (!isVideo) {
3400f51f144dba401346c0078334f00f9e44d4146e5David Smith            continue;
3410f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
3420f51f144dba401346c0078334f00f9e44d4146e5David Smith
3430f51f144dba401346c0078334f00f9e44d4146e5David Smith        ALOGV("selecting track %zu", i);
3440f51f144dba401346c0078334f00f9e44d4146e5David Smith
3450f51f144dba401346c0078334f00f9e44d4146e5David Smith        err = extractor->selectTrack(i);
3460f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK(err == OK);
3470f51f144dba401346c0078334f00f9e44d4146e5David Smith
3480f51f144dba401346c0078334f00f9e44d4146e5David Smith        CodecState *state =
3490f51f144dba401346c0078334f00f9e44d4146e5David Smith            &stateByTrack.editValueAt(stateByTrack.add(i, CodecState()));
3500f51f144dba401346c0078334f00f9e44d4146e5David Smith
3510f51f144dba401346c0078334f00f9e44d4146e5David Smith        vidState = state;
3520f51f144dba401346c0078334f00f9e44d4146e5David Smith
3530f51f144dba401346c0078334f00f9e44d4146e5David Smith        state->mNumBuffersDecoded = 0;
3540f51f144dba401346c0078334f00f9e44d4146e5David Smith
3550f51f144dba401346c0078334f00f9e44d4146e5David Smith        state->mCodec = MediaCodec::CreateByType(
3560f51f144dba401346c0078334f00f9e44d4146e5David Smith                looper, mime.c_str(), false /* encoder */);
3570f51f144dba401346c0078334f00f9e44d4146e5David Smith
3580f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK(state->mCodec != NULL);
3590f51f144dba401346c0078334f00f9e44d4146e5David Smith
3600f51f144dba401346c0078334f00f9e44d4146e5David Smith        err = state->mCodec->configure(
3610f51f144dba401346c0078334f00f9e44d4146e5David Smith                format, NULL /* surface */, NULL /* crypto */, 0 /* flags */);
3620f51f144dba401346c0078334f00f9e44d4146e5David Smith
3630f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK(err == OK);
3640f51f144dba401346c0078334f00f9e44d4146e5David Smith
3650f51f144dba401346c0078334f00f9e44d4146e5David Smith        state->mSignalledInputEOS = false;
3660f51f144dba401346c0078334f00f9e44d4146e5David Smith        state->mSawOutputEOS = false;
3670f51f144dba401346c0078334f00f9e44d4146e5David Smith
3680f51f144dba401346c0078334f00f9e44d4146e5David Smith        break;
3690f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
3700f51f144dba401346c0078334f00f9e44d4146e5David Smith    CHECK(!stateByTrack.isEmpty());
3710f51f144dba401346c0078334f00f9e44d4146e5David Smith    CHECK(vidState != NULL);
3720f51f144dba401346c0078334f00f9e44d4146e5David Smith    sp<AMessage> vidFormat;
3730f51f144dba401346c0078334f00f9e44d4146e5David Smith    vidState->mCodec->getOutputFormat(&vidFormat);
3740f51f144dba401346c0078334f00f9e44d4146e5David Smith
3750f51f144dba401346c0078334f00f9e44d4146e5David Smith    // set filter to use ARGB8888
3760f51f144dba401346c0078334f00f9e44d4146e5David Smith    vidFormat->setInt32("color-format", OMX_COLOR_Format32bitARGB8888);
3770f51f144dba401346c0078334f00f9e44d4146e5David Smith    // set app cache directory path
3780f51f144dba401346c0078334f00f9e44d4146e5David Smith    vidFormat->setString("cacheDir", "/system/bin");
3790f51f144dba401346c0078334f00f9e44d4146e5David Smith
3800f51f144dba401346c0078334f00f9e44d4146e5David Smith    // create RenderScript context for RSFilters
3810f51f144dba401346c0078334f00f9e44d4146e5David Smith    RSC::sp<RSC::RS> context = new RSC::RS();
3820f51f144dba401346c0078334f00f9e44d4146e5David Smith    context->init("/system/bin");
3830f51f144dba401346c0078334f00f9e44d4146e5David Smith
3840f51f144dba401346c0078334f00f9e44d4146e5David Smith    sp<RenderScriptWrapper::RSFilterCallback> rsFilter;
3850f51f144dba401346c0078334f00f9e44d4146e5David Smith
3860f51f144dba401346c0078334f00f9e44d4146e5David Smith    // create renderscript wrapper for RSFilters
3870f51f144dba401346c0078334f00f9e44d4146e5David Smith    sp<RenderScriptWrapper> rsWrapper = new RenderScriptWrapper;
3880f51f144dba401346c0078334f00f9e44d4146e5David Smith    rsWrapper->mContext = context.get();
3890f51f144dba401346c0078334f00f9e44d4146e5David Smith
3900f51f144dba401346c0078334f00f9e44d4146e5David Smith    CodecState *filterState = new CodecState();
3910f51f144dba401346c0078334f00f9e44d4146e5David Smith    filterState->mNumBuffersDecoded = 0;
3920f51f144dba401346c0078334f00f9e44d4146e5David Smith
3930f51f144dba401346c0078334f00f9e44d4146e5David Smith    sp<AMessage> params = new AMessage();
3940f51f144dba401346c0078334f00f9e44d4146e5David Smith
3950f51f144dba401346c0078334f00f9e44d4146e5David Smith    switch (filterType) {
3960f51f144dba401346c0078334f00f9e44d4146e5David Smith        case FILTERTYPE_ZERO:
3970f51f144dba401346c0078334f00f9e44d4146e5David Smith        {
3980f51f144dba401346c0078334f00f9e44d4146e5David Smith            filterState->mCodec = MediaCodec::CreateByComponentName(
3990f51f144dba401346c0078334f00f9e44d4146e5David Smith                    looper, "android.filter.zerofilter");
4000f51f144dba401346c0078334f00f9e44d4146e5David Smith            params->setInt32("invert", kInvert);
4010f51f144dba401346c0078334f00f9e44d4146e5David Smith            break;
4020f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
4030f51f144dba401346c0078334f00f9e44d4146e5David Smith        case FILTERTYPE_INTRINSIC_BLUR:
4040f51f144dba401346c0078334f00f9e44d4146e5David Smith        {
4050f51f144dba401346c0078334f00f9e44d4146e5David Smith            filterState->mCodec = MediaCodec::CreateByComponentName(
4060f51f144dba401346c0078334f00f9e44d4146e5David Smith                    looper, "android.filter.intrinsicblur");
4070f51f144dba401346c0078334f00f9e44d4146e5David Smith            params->setFloat("blur-radius", kBlurRadius);
4080f51f144dba401346c0078334f00f9e44d4146e5David Smith            break;
4090f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
4100f51f144dba401346c0078334f00f9e44d4146e5David Smith        case FILTERTYPE_SATURATION:
4110f51f144dba401346c0078334f00f9e44d4146e5David Smith        {
4120f51f144dba401346c0078334f00f9e44d4146e5David Smith            filterState->mCodec = MediaCodec::CreateByComponentName(
4130f51f144dba401346c0078334f00f9e44d4146e5David Smith                    looper, "android.filter.saturation");
4140f51f144dba401346c0078334f00f9e44d4146e5David Smith            params->setFloat("saturation", kSaturation);
4150f51f144dba401346c0078334f00f9e44d4146e5David Smith            break;
4160f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
4170f51f144dba401346c0078334f00f9e44d4146e5David Smith        case FILTERTYPE_RS_SATURATION:
4180f51f144dba401346c0078334f00f9e44d4146e5David Smith        {
4190f51f144dba401346c0078334f00f9e44d4146e5David Smith            SaturationRSFilter *satFilter = new SaturationRSFilter;
4200f51f144dba401346c0078334f00f9e44d4146e5David Smith            satFilter->init(context);
4210f51f144dba401346c0078334f00f9e44d4146e5David Smith            rsFilter = satFilter;
4220f51f144dba401346c0078334f00f9e44d4146e5David Smith            rsWrapper->mCallback = rsFilter;
4230f51f144dba401346c0078334f00f9e44d4146e5David Smith            vidFormat->setObject("rs-wrapper", rsWrapper);
4240f51f144dba401346c0078334f00f9e44d4146e5David Smith
4250f51f144dba401346c0078334f00f9e44d4146e5David Smith            filterState->mCodec = MediaCodec::CreateByComponentName(
4260f51f144dba401346c0078334f00f9e44d4146e5David Smith                    looper, "android.filter.RenderScript");
4270f51f144dba401346c0078334f00f9e44d4146e5David Smith            break;
4280f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
4290f51f144dba401346c0078334f00f9e44d4146e5David Smith        case FILTERTYPE_RS_NIGHT_VISION:
4300f51f144dba401346c0078334f00f9e44d4146e5David Smith        {
4310f51f144dba401346c0078334f00f9e44d4146e5David Smith            NightVisionRSFilter *nightVisionFilter = new NightVisionRSFilter;
4320f51f144dba401346c0078334f00f9e44d4146e5David Smith            nightVisionFilter->init(context);
4330f51f144dba401346c0078334f00f9e44d4146e5David Smith            rsFilter = nightVisionFilter;
4340f51f144dba401346c0078334f00f9e44d4146e5David Smith            rsWrapper->mCallback = rsFilter;
4350f51f144dba401346c0078334f00f9e44d4146e5David Smith            vidFormat->setObject("rs-wrapper", rsWrapper);
4360f51f144dba401346c0078334f00f9e44d4146e5David Smith
4370f51f144dba401346c0078334f00f9e44d4146e5David Smith            filterState->mCodec = MediaCodec::CreateByComponentName(
4380f51f144dba401346c0078334f00f9e44d4146e5David Smith                    looper, "android.filter.RenderScript");
4390f51f144dba401346c0078334f00f9e44d4146e5David Smith            break;
4400f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
4410f51f144dba401346c0078334f00f9e44d4146e5David Smith        case FILTERTYPE_RS_ARGB_TO_RGBA:
4420f51f144dba401346c0078334f00f9e44d4146e5David Smith        {
4430f51f144dba401346c0078334f00f9e44d4146e5David Smith            ARGBToRGBARSFilter *argbToRgbaFilter = new ARGBToRGBARSFilter;
4440f51f144dba401346c0078334f00f9e44d4146e5David Smith            argbToRgbaFilter->init(context);
4450f51f144dba401346c0078334f00f9e44d4146e5David Smith            rsFilter = argbToRgbaFilter;
4460f51f144dba401346c0078334f00f9e44d4146e5David Smith            rsWrapper->mCallback = rsFilter;
4470f51f144dba401346c0078334f00f9e44d4146e5David Smith            vidFormat->setObject("rs-wrapper", rsWrapper);
4480f51f144dba401346c0078334f00f9e44d4146e5David Smith
4490f51f144dba401346c0078334f00f9e44d4146e5David Smith            filterState->mCodec = MediaCodec::CreateByComponentName(
4500f51f144dba401346c0078334f00f9e44d4146e5David Smith                    looper, "android.filter.RenderScript");
4510f51f144dba401346c0078334f00f9e44d4146e5David Smith            break;
4520f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
4530f51f144dba401346c0078334f00f9e44d4146e5David Smith        default:
4540f51f144dba401346c0078334f00f9e44d4146e5David Smith        {
4550f51f144dba401346c0078334f00f9e44d4146e5David Smith            LOG_ALWAYS_FATAL("mediacodec.cpp error: unrecognized FilterType");
4560f51f144dba401346c0078334f00f9e44d4146e5David Smith            break;
4570f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
4580f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
4590f51f144dba401346c0078334f00f9e44d4146e5David Smith    CHECK(filterState->mCodec != NULL);
4600f51f144dba401346c0078334f00f9e44d4146e5David Smith
4610f51f144dba401346c0078334f00f9e44d4146e5David Smith    status_t err = filterState->mCodec->configure(
4620f51f144dba401346c0078334f00f9e44d4146e5David Smith            vidFormat /* format */, surface, NULL /* crypto */, 0 /* flags */);
4630f51f144dba401346c0078334f00f9e44d4146e5David Smith    CHECK(err == OK);
4640f51f144dba401346c0078334f00f9e44d4146e5David Smith
4650f51f144dba401346c0078334f00f9e44d4146e5David Smith    filterState->mSignalledInputEOS = false;
4660f51f144dba401346c0078334f00f9e44d4146e5David Smith    filterState->mSawOutputEOS = false;
4670f51f144dba401346c0078334f00f9e44d4146e5David Smith
4680f51f144dba401346c0078334f00f9e44d4146e5David Smith    int64_t startTimeUs = ALooper::GetNowUs();
4690f51f144dba401346c0078334f00f9e44d4146e5David Smith    int64_t startTimeRender = -1;
4700f51f144dba401346c0078334f00f9e44d4146e5David Smith
4710f51f144dba401346c0078334f00f9e44d4146e5David Smith    for (size_t i = 0; i < stateByTrack.size(); ++i) {
4720f51f144dba401346c0078334f00f9e44d4146e5David Smith        CodecState *state = &stateByTrack.editValueAt(i);
4730f51f144dba401346c0078334f00f9e44d4146e5David Smith
4740f51f144dba401346c0078334f00f9e44d4146e5David Smith        sp<MediaCodec> codec = state->mCodec;
4750f51f144dba401346c0078334f00f9e44d4146e5David Smith
4760f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK_EQ((status_t)OK, codec->start());
4770f51f144dba401346c0078334f00f9e44d4146e5David Smith
4780f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK_EQ((status_t)OK, codec->getInputBuffers(&state->mInBuffers));
4790f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK_EQ((status_t)OK, codec->getOutputBuffers(&state->mOutBuffers));
4800f51f144dba401346c0078334f00f9e44d4146e5David Smith
4810f51f144dba401346c0078334f00f9e44d4146e5David Smith        ALOGV("got %zu input and %zu output buffers",
4820f51f144dba401346c0078334f00f9e44d4146e5David Smith                state->mInBuffers.size(), state->mOutBuffers.size());
4830f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
4840f51f144dba401346c0078334f00f9e44d4146e5David Smith
4850f51f144dba401346c0078334f00f9e44d4146e5David Smith    CHECK_EQ((status_t)OK, filterState->mCodec->setParameters(params));
4860f51f144dba401346c0078334f00f9e44d4146e5David Smith
4870f51f144dba401346c0078334f00f9e44d4146e5David Smith    if (kTestFlush) {
4880f51f144dba401346c0078334f00f9e44d4146e5David Smith        status_t flushErr = filterState->mCodec->flush();
4890f51f144dba401346c0078334f00f9e44d4146e5David Smith        if (flushErr == OK) {
4900f51f144dba401346c0078334f00f9e44d4146e5David Smith            ALOGE("FAIL: Flush before start returned OK");
4910f51f144dba401346c0078334f00f9e44d4146e5David Smith        } else {
4920f51f144dba401346c0078334f00f9e44d4146e5David Smith            ALOGV("Flush before start returned status %d, usually ENOSYS (-38)",
4930f51f144dba401346c0078334f00f9e44d4146e5David Smith                    flushErr);
4940f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
4950f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
4960f51f144dba401346c0078334f00f9e44d4146e5David Smith
4970f51f144dba401346c0078334f00f9e44d4146e5David Smith    CHECK_EQ((status_t)OK, filterState->mCodec->start());
4980f51f144dba401346c0078334f00f9e44d4146e5David Smith    CHECK_EQ((status_t)OK, filterState->mCodec->getInputBuffers(
4990f51f144dba401346c0078334f00f9e44d4146e5David Smith            &filterState->mInBuffers));
5000f51f144dba401346c0078334f00f9e44d4146e5David Smith    CHECK_EQ((status_t)OK, filterState->mCodec->getOutputBuffers(
5010f51f144dba401346c0078334f00f9e44d4146e5David Smith            &filterState->mOutBuffers));
5020f51f144dba401346c0078334f00f9e44d4146e5David Smith
5030f51f144dba401346c0078334f00f9e44d4146e5David Smith    if (kTestFlush) {
5040f51f144dba401346c0078334f00f9e44d4146e5David Smith        status_t flushErr = filterState->mCodec->flush();
5050f51f144dba401346c0078334f00f9e44d4146e5David Smith        if (flushErr != OK) {
5060f51f144dba401346c0078334f00f9e44d4146e5David Smith            ALOGE("FAIL: Flush after start returned %d, expect OK (0)",
5070f51f144dba401346c0078334f00f9e44d4146e5David Smith                    flushErr);
5080f51f144dba401346c0078334f00f9e44d4146e5David Smith        } else {
5090f51f144dba401346c0078334f00f9e44d4146e5David Smith            ALOGV("Flush immediately after start OK");
5100f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
5110f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
5120f51f144dba401346c0078334f00f9e44d4146e5David Smith
5130f51f144dba401346c0078334f00f9e44d4146e5David Smith    List<DecodedFrame> decodedFrameIndices;
5140f51f144dba401346c0078334f00f9e44d4146e5David Smith
5150f51f144dba401346c0078334f00f9e44d4146e5David Smith    // loop until decoder reaches EOS
5160f51f144dba401346c0078334f00f9e44d4146e5David Smith    bool sawInputEOS = false;
5170f51f144dba401346c0078334f00f9e44d4146e5David Smith    bool sawOutputEOSOnAllTracks = false;
5180f51f144dba401346c0078334f00f9e44d4146e5David Smith    while (!sawOutputEOSOnAllTracks) {
5190f51f144dba401346c0078334f00f9e44d4146e5David Smith        if (!sawInputEOS) {
5200f51f144dba401346c0078334f00f9e44d4146e5David Smith            size_t trackIndex;
5210f51f144dba401346c0078334f00f9e44d4146e5David Smith            status_t err = extractor->getSampleTrackIndex(&trackIndex);
5220f51f144dba401346c0078334f00f9e44d4146e5David Smith
5230f51f144dba401346c0078334f00f9e44d4146e5David Smith            if (err != OK) {
5240f51f144dba401346c0078334f00f9e44d4146e5David Smith                ALOGV("saw input eos");
5250f51f144dba401346c0078334f00f9e44d4146e5David Smith                sawInputEOS = true;
5260f51f144dba401346c0078334f00f9e44d4146e5David Smith            } else {
5270f51f144dba401346c0078334f00f9e44d4146e5David Smith                CodecState *state = &stateByTrack.editValueFor(trackIndex);
5280f51f144dba401346c0078334f00f9e44d4146e5David Smith
5290f51f144dba401346c0078334f00f9e44d4146e5David Smith                size_t index;
5300f51f144dba401346c0078334f00f9e44d4146e5David Smith                err = state->mCodec->dequeueInputBuffer(&index, kTimeout);
5310f51f144dba401346c0078334f00f9e44d4146e5David Smith
5320f51f144dba401346c0078334f00f9e44d4146e5David Smith                if (err == OK) {
5330f51f144dba401346c0078334f00f9e44d4146e5David Smith                    ALOGV("filling input buffer %zu", index);
5340f51f144dba401346c0078334f00f9e44d4146e5David Smith
5350f51f144dba401346c0078334f00f9e44d4146e5David Smith                    const sp<ABuffer> &buffer = state->mInBuffers.itemAt(index);
5360f51f144dba401346c0078334f00f9e44d4146e5David Smith
5370f51f144dba401346c0078334f00f9e44d4146e5David Smith                    err = extractor->readSampleData(buffer);
5380f51f144dba401346c0078334f00f9e44d4146e5David Smith                    CHECK(err == OK);
5390f51f144dba401346c0078334f00f9e44d4146e5David Smith
5400f51f144dba401346c0078334f00f9e44d4146e5David Smith                    int64_t timeUs;
5410f51f144dba401346c0078334f00f9e44d4146e5David Smith                    err = extractor->getSampleTime(&timeUs);
5420f51f144dba401346c0078334f00f9e44d4146e5David Smith                    CHECK(err == OK);
5430f51f144dba401346c0078334f00f9e44d4146e5David Smith
5440f51f144dba401346c0078334f00f9e44d4146e5David Smith                    uint32_t bufferFlags = 0;
5450f51f144dba401346c0078334f00f9e44d4146e5David Smith
5460f51f144dba401346c0078334f00f9e44d4146e5David Smith                    err = state->mCodec->queueInputBuffer(
5470f51f144dba401346c0078334f00f9e44d4146e5David Smith                            index, 0 /* offset */, buffer->size(),
5480f51f144dba401346c0078334f00f9e44d4146e5David Smith                            timeUs, bufferFlags);
5490f51f144dba401346c0078334f00f9e44d4146e5David Smith
5500f51f144dba401346c0078334f00f9e44d4146e5David Smith                    CHECK(err == OK);
5510f51f144dba401346c0078334f00f9e44d4146e5David Smith
5520f51f144dba401346c0078334f00f9e44d4146e5David Smith                    extractor->advance();
5530f51f144dba401346c0078334f00f9e44d4146e5David Smith                } else {
5540f51f144dba401346c0078334f00f9e44d4146e5David Smith                    CHECK_EQ(err, -EAGAIN);
5550f51f144dba401346c0078334f00f9e44d4146e5David Smith                }
5560f51f144dba401346c0078334f00f9e44d4146e5David Smith            }
5570f51f144dba401346c0078334f00f9e44d4146e5David Smith        } else {
5580f51f144dba401346c0078334f00f9e44d4146e5David Smith            for (size_t i = 0; i < stateByTrack.size(); ++i) {
5590f51f144dba401346c0078334f00f9e44d4146e5David Smith                CodecState *state = &stateByTrack.editValueAt(i);
5600f51f144dba401346c0078334f00f9e44d4146e5David Smith
5610f51f144dba401346c0078334f00f9e44d4146e5David Smith                if (!state->mSignalledInputEOS) {
5620f51f144dba401346c0078334f00f9e44d4146e5David Smith                    size_t index;
5630f51f144dba401346c0078334f00f9e44d4146e5David Smith                    status_t err =
5640f51f144dba401346c0078334f00f9e44d4146e5David Smith                        state->mCodec->dequeueInputBuffer(&index, kTimeout);
5650f51f144dba401346c0078334f00f9e44d4146e5David Smith
5660f51f144dba401346c0078334f00f9e44d4146e5David Smith                    if (err == OK) {
5670f51f144dba401346c0078334f00f9e44d4146e5David Smith                        ALOGV("signalling input EOS on track %zu", i);
5680f51f144dba401346c0078334f00f9e44d4146e5David Smith
5690f51f144dba401346c0078334f00f9e44d4146e5David Smith                        err = state->mCodec->queueInputBuffer(
5700f51f144dba401346c0078334f00f9e44d4146e5David Smith                                index, 0 /* offset */, 0 /* size */,
5710f51f144dba401346c0078334f00f9e44d4146e5David Smith                                0ll /* timeUs */, MediaCodec::BUFFER_FLAG_EOS);
5720f51f144dba401346c0078334f00f9e44d4146e5David Smith
5730f51f144dba401346c0078334f00f9e44d4146e5David Smith                        CHECK(err == OK);
5740f51f144dba401346c0078334f00f9e44d4146e5David Smith
5750f51f144dba401346c0078334f00f9e44d4146e5David Smith                        state->mSignalledInputEOS = true;
5760f51f144dba401346c0078334f00f9e44d4146e5David Smith                    } else {
5770f51f144dba401346c0078334f00f9e44d4146e5David Smith                        CHECK_EQ(err, -EAGAIN);
5780f51f144dba401346c0078334f00f9e44d4146e5David Smith                    }
5790f51f144dba401346c0078334f00f9e44d4146e5David Smith                }
5800f51f144dba401346c0078334f00f9e44d4146e5David Smith            }
5810f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
5820f51f144dba401346c0078334f00f9e44d4146e5David Smith
5830f51f144dba401346c0078334f00f9e44d4146e5David Smith        sawOutputEOSOnAllTracks = true;
5840f51f144dba401346c0078334f00f9e44d4146e5David Smith        for (size_t i = 0; i < stateByTrack.size(); ++i) {
5850f51f144dba401346c0078334f00f9e44d4146e5David Smith            CodecState *state = &stateByTrack.editValueAt(i);
5860f51f144dba401346c0078334f00f9e44d4146e5David Smith
5870f51f144dba401346c0078334f00f9e44d4146e5David Smith            if (state->mSawOutputEOS) {
5880f51f144dba401346c0078334f00f9e44d4146e5David Smith                continue;
5890f51f144dba401346c0078334f00f9e44d4146e5David Smith            } else {
5900f51f144dba401346c0078334f00f9e44d4146e5David Smith                sawOutputEOSOnAllTracks = false;
5910f51f144dba401346c0078334f00f9e44d4146e5David Smith            }
5920f51f144dba401346c0078334f00f9e44d4146e5David Smith
5930f51f144dba401346c0078334f00f9e44d4146e5David Smith            DecodedFrame frame;
5940f51f144dba401346c0078334f00f9e44d4146e5David Smith            status_t err = state->mCodec->dequeueOutputBuffer(
5950f51f144dba401346c0078334f00f9e44d4146e5David Smith                    &frame.index, &frame.offset, &frame.size,
5960f51f144dba401346c0078334f00f9e44d4146e5David Smith                    &frame.presentationTimeUs, &frame.flags, kTimeout);
5970f51f144dba401346c0078334f00f9e44d4146e5David Smith
5980f51f144dba401346c0078334f00f9e44d4146e5David Smith            if (err == OK) {
5990f51f144dba401346c0078334f00f9e44d4146e5David Smith                ALOGV("draining decoded buffer %zu, time = %lld us",
60031de88566257d5546cf4eee9064d96926a4b0c24Lajos Molnar                        frame.index, (long long)frame.presentationTimeUs);
6010f51f144dba401346c0078334f00f9e44d4146e5David Smith
6020f51f144dba401346c0078334f00f9e44d4146e5David Smith                ++(state->mNumBuffersDecoded);
6030f51f144dba401346c0078334f00f9e44d4146e5David Smith
6040f51f144dba401346c0078334f00f9e44d4146e5David Smith                decodedFrameIndices.push_back(frame);
6050f51f144dba401346c0078334f00f9e44d4146e5David Smith
6060f51f144dba401346c0078334f00f9e44d4146e5David Smith                if (frame.flags & MediaCodec::BUFFER_FLAG_EOS) {
6070f51f144dba401346c0078334f00f9e44d4146e5David Smith                    ALOGV("reached EOS on decoder output.");
6080f51f144dba401346c0078334f00f9e44d4146e5David Smith                    state->mSawOutputEOS = true;
6090f51f144dba401346c0078334f00f9e44d4146e5David Smith                }
6100f51f144dba401346c0078334f00f9e44d4146e5David Smith
6110f51f144dba401346c0078334f00f9e44d4146e5David Smith            } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
6120f51f144dba401346c0078334f00f9e44d4146e5David Smith                ALOGV("INFO_OUTPUT_BUFFERS_CHANGED");
6130f51f144dba401346c0078334f00f9e44d4146e5David Smith                CHECK_EQ((status_t)OK, state->mCodec->getOutputBuffers(
6140f51f144dba401346c0078334f00f9e44d4146e5David Smith                        &state->mOutBuffers));
6150f51f144dba401346c0078334f00f9e44d4146e5David Smith
6160f51f144dba401346c0078334f00f9e44d4146e5David Smith                ALOGV("got %zu output buffers", state->mOutBuffers.size());
6170f51f144dba401346c0078334f00f9e44d4146e5David Smith            } else if (err == INFO_FORMAT_CHANGED) {
6180f51f144dba401346c0078334f00f9e44d4146e5David Smith                sp<AMessage> format;
6190f51f144dba401346c0078334f00f9e44d4146e5David Smith                CHECK_EQ((status_t)OK, state->mCodec->getOutputFormat(&format));
6200f51f144dba401346c0078334f00f9e44d4146e5David Smith
6210f51f144dba401346c0078334f00f9e44d4146e5David Smith                ALOGV("INFO_FORMAT_CHANGED: %s",
6220f51f144dba401346c0078334f00f9e44d4146e5David Smith                        format->debugString().c_str());
6230f51f144dba401346c0078334f00f9e44d4146e5David Smith            } else {
6240f51f144dba401346c0078334f00f9e44d4146e5David Smith                CHECK_EQ(err, -EAGAIN);
6250f51f144dba401346c0078334f00f9e44d4146e5David Smith            }
6260f51f144dba401346c0078334f00f9e44d4146e5David Smith
6270f51f144dba401346c0078334f00f9e44d4146e5David Smith            tryCopyDecodedBuffer(&decodedFrameIndices, filterState, vidState);
6280f51f144dba401346c0078334f00f9e44d4146e5David Smith
6290f51f144dba401346c0078334f00f9e44d4146e5David Smith            tryDrainOutputBuffer(
6300f51f144dba401346c0078334f00f9e44d4146e5David Smith                    filterState, surface, renderSurface,
6310f51f144dba401346c0078334f00f9e44d4146e5David Smith                    useTimestamp, &startTimeRender);
6320f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
6330f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
6340f51f144dba401346c0078334f00f9e44d4146e5David Smith
6350f51f144dba401346c0078334f00f9e44d4146e5David Smith    // after EOS on decoder, let filter reach EOS
6360f51f144dba401346c0078334f00f9e44d4146e5David Smith    while (!filterState->mSawOutputEOS) {
6370f51f144dba401346c0078334f00f9e44d4146e5David Smith        tryCopyDecodedBuffer(&decodedFrameIndices, filterState, vidState);
6380f51f144dba401346c0078334f00f9e44d4146e5David Smith
6390f51f144dba401346c0078334f00f9e44d4146e5David Smith        tryDrainOutputBuffer(
6400f51f144dba401346c0078334f00f9e44d4146e5David Smith                filterState, surface, renderSurface,
6410f51f144dba401346c0078334f00f9e44d4146e5David Smith                useTimestamp, &startTimeRender);
6420f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
6430f51f144dba401346c0078334f00f9e44d4146e5David Smith
6440f51f144dba401346c0078334f00f9e44d4146e5David Smith    int64_t elapsedTimeUs = ALooper::GetNowUs() - startTimeUs;
6450f51f144dba401346c0078334f00f9e44d4146e5David Smith
6460f51f144dba401346c0078334f00f9e44d4146e5David Smith    for (size_t i = 0; i < stateByTrack.size(); ++i) {
6470f51f144dba401346c0078334f00f9e44d4146e5David Smith        CodecState *state = &stateByTrack.editValueAt(i);
6480f51f144dba401346c0078334f00f9e44d4146e5David Smith
6490f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK_EQ((status_t)OK, state->mCodec->release());
6500f51f144dba401346c0078334f00f9e44d4146e5David Smith
6510f51f144dba401346c0078334f00f9e44d4146e5David Smith        printf("track %zu: %" PRId64 " frames decoded and filtered, "
6520f51f144dba401346c0078334f00f9e44d4146e5David Smith                "%.2f fps.\n", i, state->mNumBuffersDecoded,
6530f51f144dba401346c0078334f00f9e44d4146e5David Smith                state->mNumBuffersDecoded * 1E6 / elapsedTimeUs);
6540f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
6550f51f144dba401346c0078334f00f9e44d4146e5David Smith
6560f51f144dba401346c0078334f00f9e44d4146e5David Smith    return 0;
6570f51f144dba401346c0078334f00f9e44d4146e5David Smith}
6580f51f144dba401346c0078334f00f9e44d4146e5David Smith
6590f51f144dba401346c0078334f00f9e44d4146e5David Smith}  // namespace android
6600f51f144dba401346c0078334f00f9e44d4146e5David Smith
6610f51f144dba401346c0078334f00f9e44d4146e5David Smithint main(int argc, char **argv) {
6620f51f144dba401346c0078334f00f9e44d4146e5David Smith    using namespace android;
6630f51f144dba401346c0078334f00f9e44d4146e5David Smith
6640f51f144dba401346c0078334f00f9e44d4146e5David Smith    const char *me = argv[0];
6650f51f144dba401346c0078334f00f9e44d4146e5David Smith
6660f51f144dba401346c0078334f00f9e44d4146e5David Smith    bool useSurface = false;
6670f51f144dba401346c0078334f00f9e44d4146e5David Smith    bool renderSurface = false;
6680f51f144dba401346c0078334f00f9e44d4146e5David Smith    bool useTimestamp = false;
6690f51f144dba401346c0078334f00f9e44d4146e5David Smith    FilterType filterType = FILTERTYPE_ZERO;
6700f51f144dba401346c0078334f00f9e44d4146e5David Smith
6710f51f144dba401346c0078334f00f9e44d4146e5David Smith    int res;
6720f51f144dba401346c0078334f00f9e44d4146e5David Smith    while ((res = getopt(argc, argv, "bcnrszTRSh")) >= 0) {
6730f51f144dba401346c0078334f00f9e44d4146e5David Smith        switch (res) {
6740f51f144dba401346c0078334f00f9e44d4146e5David Smith            case 'b':
6750f51f144dba401346c0078334f00f9e44d4146e5David Smith            {
6760f51f144dba401346c0078334f00f9e44d4146e5David Smith                filterType = FILTERTYPE_INTRINSIC_BLUR;
6770f51f144dba401346c0078334f00f9e44d4146e5David Smith                break;
6780f51f144dba401346c0078334f00f9e44d4146e5David Smith            }
6790f51f144dba401346c0078334f00f9e44d4146e5David Smith            case 'c':
6800f51f144dba401346c0078334f00f9e44d4146e5David Smith            {
6810f51f144dba401346c0078334f00f9e44d4146e5David Smith                filterType = FILTERTYPE_RS_ARGB_TO_RGBA;
6820f51f144dba401346c0078334f00f9e44d4146e5David Smith                break;
6830f51f144dba401346c0078334f00f9e44d4146e5David Smith            }
6840f51f144dba401346c0078334f00f9e44d4146e5David Smith            case 'n':
6850f51f144dba401346c0078334f00f9e44d4146e5David Smith            {
6860f51f144dba401346c0078334f00f9e44d4146e5David Smith                filterType = FILTERTYPE_RS_NIGHT_VISION;
6870f51f144dba401346c0078334f00f9e44d4146e5David Smith                break;
6880f51f144dba401346c0078334f00f9e44d4146e5David Smith            }
6890f51f144dba401346c0078334f00f9e44d4146e5David Smith            case 'r':
6900f51f144dba401346c0078334f00f9e44d4146e5David Smith            {
6910f51f144dba401346c0078334f00f9e44d4146e5David Smith                filterType = FILTERTYPE_RS_SATURATION;
6920f51f144dba401346c0078334f00f9e44d4146e5David Smith                break;
6930f51f144dba401346c0078334f00f9e44d4146e5David Smith            }
6940f51f144dba401346c0078334f00f9e44d4146e5David Smith            case 's':
6950f51f144dba401346c0078334f00f9e44d4146e5David Smith            {
6960f51f144dba401346c0078334f00f9e44d4146e5David Smith                filterType = FILTERTYPE_SATURATION;
6970f51f144dba401346c0078334f00f9e44d4146e5David Smith                break;
6980f51f144dba401346c0078334f00f9e44d4146e5David Smith            }
6990f51f144dba401346c0078334f00f9e44d4146e5David Smith            case 'z':
7000f51f144dba401346c0078334f00f9e44d4146e5David Smith            {
7010f51f144dba401346c0078334f00f9e44d4146e5David Smith                filterType = FILTERTYPE_ZERO;
7020f51f144dba401346c0078334f00f9e44d4146e5David Smith                break;
7030f51f144dba401346c0078334f00f9e44d4146e5David Smith            }
7040f51f144dba401346c0078334f00f9e44d4146e5David Smith            case 'T':
7050f51f144dba401346c0078334f00f9e44d4146e5David Smith            {
7060f51f144dba401346c0078334f00f9e44d4146e5David Smith                useTimestamp = true;
7070f51f144dba401346c0078334f00f9e44d4146e5David Smith            }
7080f51f144dba401346c0078334f00f9e44d4146e5David Smith            // fall through
7090f51f144dba401346c0078334f00f9e44d4146e5David Smith            case 'R':
7100f51f144dba401346c0078334f00f9e44d4146e5David Smith            {
7110f51f144dba401346c0078334f00f9e44d4146e5David Smith                renderSurface = true;
7120f51f144dba401346c0078334f00f9e44d4146e5David Smith            }
7130f51f144dba401346c0078334f00f9e44d4146e5David Smith            // fall through
7140f51f144dba401346c0078334f00f9e44d4146e5David Smith            case 'S':
7150f51f144dba401346c0078334f00f9e44d4146e5David Smith            {
7160f51f144dba401346c0078334f00f9e44d4146e5David Smith                useSurface = true;
7170f51f144dba401346c0078334f00f9e44d4146e5David Smith                break;
7180f51f144dba401346c0078334f00f9e44d4146e5David Smith            }
7190f51f144dba401346c0078334f00f9e44d4146e5David Smith            case '?':
7200f51f144dba401346c0078334f00f9e44d4146e5David Smith            case 'h':
7210f51f144dba401346c0078334f00f9e44d4146e5David Smith            default:
7220f51f144dba401346c0078334f00f9e44d4146e5David Smith            {
7230f51f144dba401346c0078334f00f9e44d4146e5David Smith                usage(me);
7240f51f144dba401346c0078334f00f9e44d4146e5David Smith                break;
7250f51f144dba401346c0078334f00f9e44d4146e5David Smith            }
7260f51f144dba401346c0078334f00f9e44d4146e5David Smith        }
7270f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
7280f51f144dba401346c0078334f00f9e44d4146e5David Smith
7290f51f144dba401346c0078334f00f9e44d4146e5David Smith    argc -= optind;
7300f51f144dba401346c0078334f00f9e44d4146e5David Smith    argv += optind;
7310f51f144dba401346c0078334f00f9e44d4146e5David Smith
7320f51f144dba401346c0078334f00f9e44d4146e5David Smith    if (argc != 1) {
7330f51f144dba401346c0078334f00f9e44d4146e5David Smith        usage(me);
7340f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
7350f51f144dba401346c0078334f00f9e44d4146e5David Smith
7360f51f144dba401346c0078334f00f9e44d4146e5David Smith    ProcessState::self()->startThreadPool();
7370f51f144dba401346c0078334f00f9e44d4146e5David Smith
7380f51f144dba401346c0078334f00f9e44d4146e5David Smith    DataSource::RegisterDefaultSniffers();
7390f51f144dba401346c0078334f00f9e44d4146e5David Smith
7400f51f144dba401346c0078334f00f9e44d4146e5David Smith    android::sp<ALooper> looper = new ALooper;
7410f51f144dba401346c0078334f00f9e44d4146e5David Smith    looper->start();
7420f51f144dba401346c0078334f00f9e44d4146e5David Smith
7430f51f144dba401346c0078334f00f9e44d4146e5David Smith    android::sp<SurfaceComposerClient> composerClient;
7440f51f144dba401346c0078334f00f9e44d4146e5David Smith    android::sp<SurfaceControl> control;
7450f51f144dba401346c0078334f00f9e44d4146e5David Smith    android::sp<Surface> surface;
7460f51f144dba401346c0078334f00f9e44d4146e5David Smith
7470f51f144dba401346c0078334f00f9e44d4146e5David Smith    if (useSurface) {
7480f51f144dba401346c0078334f00f9e44d4146e5David Smith        composerClient = new SurfaceComposerClient;
7490f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK_EQ((status_t)OK, composerClient->initCheck());
7500f51f144dba401346c0078334f00f9e44d4146e5David Smith
7510f51f144dba401346c0078334f00f9e44d4146e5David Smith        android::sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
7520f51f144dba401346c0078334f00f9e44d4146e5David Smith                ISurfaceComposer::eDisplayIdMain));
7530f51f144dba401346c0078334f00f9e44d4146e5David Smith        DisplayInfo info;
7540f51f144dba401346c0078334f00f9e44d4146e5David Smith        SurfaceComposerClient::getDisplayInfo(display, &info);
7550f51f144dba401346c0078334f00f9e44d4146e5David Smith        ssize_t displayWidth = info.w;
7560f51f144dba401346c0078334f00f9e44d4146e5David Smith        ssize_t displayHeight = info.h;
7570f51f144dba401346c0078334f00f9e44d4146e5David Smith
7580f51f144dba401346c0078334f00f9e44d4146e5David Smith        ALOGV("display is %zd x %zd", displayWidth, displayHeight);
7590f51f144dba401346c0078334f00f9e44d4146e5David Smith
7600f51f144dba401346c0078334f00f9e44d4146e5David Smith        control = composerClient->createSurface(
7610f51f144dba401346c0078334f00f9e44d4146e5David Smith                String8("A Surface"), displayWidth, displayHeight,
7620f51f144dba401346c0078334f00f9e44d4146e5David Smith                PIXEL_FORMAT_RGBA_8888, 0);
7630f51f144dba401346c0078334f00f9e44d4146e5David Smith
7640f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK(control != NULL);
7650f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK(control->isValid());
7660f51f144dba401346c0078334f00f9e44d4146e5David Smith
7670f51f144dba401346c0078334f00f9e44d4146e5David Smith        SurfaceComposerClient::openGlobalTransaction();
7680f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK_EQ((status_t)OK, control->setLayer(INT_MAX));
7690f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK_EQ((status_t)OK, control->show());
7700f51f144dba401346c0078334f00f9e44d4146e5David Smith        SurfaceComposerClient::closeGlobalTransaction();
7710f51f144dba401346c0078334f00f9e44d4146e5David Smith
7720f51f144dba401346c0078334f00f9e44d4146e5David Smith        surface = control->getSurface();
7730f51f144dba401346c0078334f00f9e44d4146e5David Smith        CHECK(surface != NULL);
7740f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
7750f51f144dba401346c0078334f00f9e44d4146e5David Smith
7760f51f144dba401346c0078334f00f9e44d4146e5David Smith    decode(looper, argv[0], surface, renderSurface, useTimestamp, filterType);
7770f51f144dba401346c0078334f00f9e44d4146e5David Smith
7780f51f144dba401346c0078334f00f9e44d4146e5David Smith    if (useSurface) {
7790f51f144dba401346c0078334f00f9e44d4146e5David Smith        composerClient->dispose();
7800f51f144dba401346c0078334f00f9e44d4146e5David Smith    }
7810f51f144dba401346c0078334f00f9e44d4146e5David Smith
7820f51f144dba401346c0078334f00f9e44d4146e5David Smith    looper->stop();
7830f51f144dba401346c0078334f00f9e44d4146e5David Smith
7840f51f144dba401346c0078334f00f9e44d4146e5David Smith    return 0;
7850f51f144dba401346c0078334f00f9e44d4146e5David Smith}
786