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