10c1bc742181ded4930842b46e9507372f0b1b963James Dong/* 20c1bc742181ded4930842b46e9507372f0b1b963James Dong * Copyright (C) 2011 The Android Open Source Project 30c1bc742181ded4930842b46e9507372f0b1b963James Dong * 40c1bc742181ded4930842b46e9507372f0b1b963James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 50c1bc742181ded4930842b46e9507372f0b1b963James Dong * you may not use this file except in compliance with the License. 60c1bc742181ded4930842b46e9507372f0b1b963James Dong * You may obtain a copy of the License at 70c1bc742181ded4930842b46e9507372f0b1b963James Dong * 80c1bc742181ded4930842b46e9507372f0b1b963James Dong * http://www.apache.org/licenses/LICENSE-2.0 90c1bc742181ded4930842b46e9507372f0b1b963James Dong * 100c1bc742181ded4930842b46e9507372f0b1b963James Dong * Unless required by applicable law or agreed to in writing, software 110c1bc742181ded4930842b46e9507372f0b1b963James Dong * distributed under the License is distributed on an "AS IS" BASIS, 120c1bc742181ded4930842b46e9507372f0b1b963James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130c1bc742181ded4930842b46e9507372f0b1b963James Dong * See the License for the specific language governing permissions and 140c1bc742181ded4930842b46e9507372f0b1b963James Dong * limitations under the License. 150c1bc742181ded4930842b46e9507372f0b1b963James Dong */ 160c1bc742181ded4930842b46e9507372f0b1b963James Dong 170c1bc742181ded4930842b46e9507372f0b1b963James Dong//#define LOG_NDEBUG 0 180c1bc742181ded4930842b46e9507372f0b1b963James Dong#define LOG_TAG "SoftAVC" 190c1bc742181ded4930842b46e9507372f0b1b963James Dong#include <utils/Log.h> 200c1bc742181ded4930842b46e9507372f0b1b963James Dong 210c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "SoftAVC.h" 220c1bc742181ded4930842b46e9507372f0b1b963James Dong 230c1bc742181ded4930842b46e9507372f0b1b963James Dong#include <media/stagefright/foundation/ADebug.h> 240c1bc742181ded4930842b46e9507372f0b1b963James Dong#include <media/stagefright/MediaDefs.h> 250c1bc742181ded4930842b46e9507372f0b1b963James Dong#include <media/stagefright/MediaErrors.h> 26457116d3a01618acf9a875020ca5860551ba03a6James Dong#include <media/IOMX.h> 270c1bc742181ded4930842b46e9507372f0b1b963James Dong 280c1bc742181ded4930842b46e9507372f0b1b963James Dong 290c1bc742181ded4930842b46e9507372f0b1b963James Dongnamespace android { 300c1bc742181ded4930842b46e9507372f0b1b963James Dong 31457116d3a01618acf9a875020ca5860551ba03a6James Dongstatic const CodecProfileLevel kProfileLevels[] = { 32457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1 }, 33457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b }, 34457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11 }, 35457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12 }, 36457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13 }, 37457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2 }, 38457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21 }, 39457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22 }, 40457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3 }, 41457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31 }, 42457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32 }, 43457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4 }, 44457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41 }, 45457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42 }, 46457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel5 }, 47457116d3a01618acf9a875020ca5860551ba03a6James Dong { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel51 }, 48457116d3a01618acf9a875020ca5860551ba03a6James Dong}; 49457116d3a01618acf9a875020ca5860551ba03a6James Dong 500c1bc742181ded4930842b46e9507372f0b1b963James Dongtemplate<class T> 510c1bc742181ded4930842b46e9507372f0b1b963James Dongstatic void InitOMXParams(T *params) { 520c1bc742181ded4930842b46e9507372f0b1b963James Dong params->nSize = sizeof(T); 530c1bc742181ded4930842b46e9507372f0b1b963James Dong params->nVersion.s.nVersionMajor = 1; 540c1bc742181ded4930842b46e9507372f0b1b963James Dong params->nVersion.s.nVersionMinor = 0; 550c1bc742181ded4930842b46e9507372f0b1b963James Dong params->nVersion.s.nRevision = 0; 560c1bc742181ded4930842b46e9507372f0b1b963James Dong params->nVersion.s.nStep = 0; 570c1bc742181ded4930842b46e9507372f0b1b963James Dong} 580c1bc742181ded4930842b46e9507372f0b1b963James Dong 590c1bc742181ded4930842b46e9507372f0b1b963James DongSoftAVC::SoftAVC( 600c1bc742181ded4930842b46e9507372f0b1b963James Dong const char *name, 610c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMX_CALLBACKTYPE *callbacks, 620c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_PTR appData, 630c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_COMPONENTTYPE **component) 640c1bc742181ded4930842b46e9507372f0b1b963James Dong : SimpleSoftOMXComponent(name, callbacks, appData, component), 650c1bc742181ded4930842b46e9507372f0b1b963James Dong mHandle(NULL), 660c1bc742181ded4930842b46e9507372f0b1b963James Dong mInputBufferCount(0), 670c1bc742181ded4930842b46e9507372f0b1b963James Dong mWidth(320), 680c1bc742181ded4930842b46e9507372f0b1b963James Dong mHeight(240), 690c1bc742181ded4930842b46e9507372f0b1b963James Dong mPictureSize(mWidth * mHeight * 3 / 2), 700c1bc742181ded4930842b46e9507372f0b1b963James Dong mCropLeft(0), 710c1bc742181ded4930842b46e9507372f0b1b963James Dong mCropTop(0), 72639ffaca514deb9de538bc2dc6e712380db68fd3James Dong mCropWidth(mWidth), 73639ffaca514deb9de538bc2dc6e712380db68fd3James Dong mCropHeight(mHeight), 740c1bc742181ded4930842b46e9507372f0b1b963James Dong mFirstPicture(NULL), 750c1bc742181ded4930842b46e9507372f0b1b963James Dong mFirstPictureId(-1), 760c1bc742181ded4930842b46e9507372f0b1b963James Dong mPicId(0), 770c1bc742181ded4930842b46e9507372f0b1b963James Dong mHeadersDecoded(false), 780c1bc742181ded4930842b46e9507372f0b1b963James Dong mEOSStatus(INPUT_DATA_AVAILABLE), 792961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber mOutputPortSettingsChange(NONE), 802961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber mSignalledError(false) { 810c1bc742181ded4930842b46e9507372f0b1b963James Dong initPorts(); 820c1bc742181ded4930842b46e9507372f0b1b963James Dong CHECK_EQ(initDecoder(), (status_t)OK); 830c1bc742181ded4930842b46e9507372f0b1b963James Dong} 840c1bc742181ded4930842b46e9507372f0b1b963James Dong 850c1bc742181ded4930842b46e9507372f0b1b963James DongSoftAVC::~SoftAVC() { 860c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecRelease(mHandle); 870c1bc742181ded4930842b46e9507372f0b1b963James Dong mHandle = NULL; 880c1bc742181ded4930842b46e9507372f0b1b963James Dong 890c1bc742181ded4930842b46e9507372f0b1b963James Dong while (mPicToHeaderMap.size() != 0) { 900c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_BUFFERHEADERTYPE *header = mPicToHeaderMap.editValueAt(0); 910c1bc742181ded4930842b46e9507372f0b1b963James Dong mPicToHeaderMap.removeItemsAt(0); 920c1bc742181ded4930842b46e9507372f0b1b963James Dong delete header; 930c1bc742181ded4930842b46e9507372f0b1b963James Dong header = NULL; 940c1bc742181ded4930842b46e9507372f0b1b963James Dong } 950c1bc742181ded4930842b46e9507372f0b1b963James Dong List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex); 960c1bc742181ded4930842b46e9507372f0b1b963James Dong List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex); 970c1bc742181ded4930842b46e9507372f0b1b963James Dong CHECK(outQueue.empty()); 980c1bc742181ded4930842b46e9507372f0b1b963James Dong CHECK(inQueue.empty()); 990c1bc742181ded4930842b46e9507372f0b1b963James Dong 1000c1bc742181ded4930842b46e9507372f0b1b963James Dong delete[] mFirstPicture; 1010c1bc742181ded4930842b46e9507372f0b1b963James Dong} 1020c1bc742181ded4930842b46e9507372f0b1b963James Dong 1030c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid SoftAVC::initPorts() { 1040c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_PARAM_PORTDEFINITIONTYPE def; 1050c1bc742181ded4930842b46e9507372f0b1b963James Dong InitOMXParams(&def); 1060c1bc742181ded4930842b46e9507372f0b1b963James Dong 1070c1bc742181ded4930842b46e9507372f0b1b963James Dong def.nPortIndex = kInputPortIndex; 1080c1bc742181ded4930842b46e9507372f0b1b963James Dong def.eDir = OMX_DirInput; 1090c1bc742181ded4930842b46e9507372f0b1b963James Dong def.nBufferCountMin = kNumInputBuffers; 1100c1bc742181ded4930842b46e9507372f0b1b963James Dong def.nBufferCountActual = def.nBufferCountMin; 1110c1bc742181ded4930842b46e9507372f0b1b963James Dong def.nBufferSize = 8192; 1120c1bc742181ded4930842b46e9507372f0b1b963James Dong def.bEnabled = OMX_TRUE; 1130c1bc742181ded4930842b46e9507372f0b1b963James Dong def.bPopulated = OMX_FALSE; 1140c1bc742181ded4930842b46e9507372f0b1b963James Dong def.eDomain = OMX_PortDomainVideo; 1150c1bc742181ded4930842b46e9507372f0b1b963James Dong def.bBuffersContiguous = OMX_FALSE; 1160c1bc742181ded4930842b46e9507372f0b1b963James Dong def.nBufferAlignment = 1; 1170c1bc742181ded4930842b46e9507372f0b1b963James Dong 1180c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_AVC); 1190c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.pNativeRender = NULL; 1200c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.nFrameWidth = mWidth; 1210c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.nFrameHeight = mHeight; 1220c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.nStride = def.format.video.nFrameWidth; 1230c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.nSliceHeight = def.format.video.nFrameHeight; 1240c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.nBitrate = 0; 1250c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.xFramerate = 0; 1260c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.bFlagErrorConcealment = OMX_FALSE; 1270c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; 1280c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.eColorFormat = OMX_COLOR_FormatUnused; 1290c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.pNativeWindow = NULL; 1300c1bc742181ded4930842b46e9507372f0b1b963James Dong 1310c1bc742181ded4930842b46e9507372f0b1b963James Dong addPort(def); 1320c1bc742181ded4930842b46e9507372f0b1b963James Dong 1330c1bc742181ded4930842b46e9507372f0b1b963James Dong def.nPortIndex = kOutputPortIndex; 1340c1bc742181ded4930842b46e9507372f0b1b963James Dong def.eDir = OMX_DirOutput; 1350c1bc742181ded4930842b46e9507372f0b1b963James Dong def.nBufferCountMin = kNumOutputBuffers; 1360c1bc742181ded4930842b46e9507372f0b1b963James Dong def.nBufferCountActual = def.nBufferCountMin; 1370c1bc742181ded4930842b46e9507372f0b1b963James Dong def.bEnabled = OMX_TRUE; 1380c1bc742181ded4930842b46e9507372f0b1b963James Dong def.bPopulated = OMX_FALSE; 1390c1bc742181ded4930842b46e9507372f0b1b963James Dong def.eDomain = OMX_PortDomainVideo; 1400c1bc742181ded4930842b46e9507372f0b1b963James Dong def.bBuffersContiguous = OMX_FALSE; 1410c1bc742181ded4930842b46e9507372f0b1b963James Dong def.nBufferAlignment = 2; 1420c1bc742181ded4930842b46e9507372f0b1b963James Dong 1430c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_RAW); 1440c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.pNativeRender = NULL; 1450c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.nFrameWidth = mWidth; 1460c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.nFrameHeight = mHeight; 1470c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.nStride = def.format.video.nFrameWidth; 1480c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.nSliceHeight = def.format.video.nFrameHeight; 1490c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.nBitrate = 0; 1500c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.xFramerate = 0; 1510c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.bFlagErrorConcealment = OMX_FALSE; 1520c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 1530c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; 1540c1bc742181ded4930842b46e9507372f0b1b963James Dong def.format.video.pNativeWindow = NULL; 1550c1bc742181ded4930842b46e9507372f0b1b963James Dong 1560c1bc742181ded4930842b46e9507372f0b1b963James Dong def.nBufferSize = 1570c1bc742181ded4930842b46e9507372f0b1b963James Dong (def.format.video.nFrameWidth * def.format.video.nFrameHeight * 3) / 2; 1580c1bc742181ded4930842b46e9507372f0b1b963James Dong 1590c1bc742181ded4930842b46e9507372f0b1b963James Dong addPort(def); 1600c1bc742181ded4930842b46e9507372f0b1b963James Dong} 1610c1bc742181ded4930842b46e9507372f0b1b963James Dong 1620c1bc742181ded4930842b46e9507372f0b1b963James Dongstatus_t SoftAVC::initDecoder() { 163486247017e0bfb9db9994a53a28c0dacfebf8567James Dong // Force decoder to output buffers in display order. 164486247017e0bfb9db9994a53a28c0dacfebf8567James Dong if (H264SwDecInit(&mHandle, 0) == H264SWDEC_OK) { 1650c1bc742181ded4930842b46e9507372f0b1b963James Dong return OK; 1660c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1670c1bc742181ded4930842b46e9507372f0b1b963James Dong return UNKNOWN_ERROR; 1680c1bc742181ded4930842b46e9507372f0b1b963James Dong} 1690c1bc742181ded4930842b46e9507372f0b1b963James Dong 1700c1bc742181ded4930842b46e9507372f0b1b963James DongOMX_ERRORTYPE SoftAVC::internalGetParameter( 1710c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INDEXTYPE index, OMX_PTR params) { 1720c1bc742181ded4930842b46e9507372f0b1b963James Dong switch (index) { 1730c1bc742181ded4930842b46e9507372f0b1b963James Dong case OMX_IndexParamVideoPortFormat: 1740c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1750c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = 1760c1bc742181ded4930842b46e9507372f0b1b963James Dong (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; 1770c1bc742181ded4930842b46e9507372f0b1b963James Dong 1780c1bc742181ded4930842b46e9507372f0b1b963James Dong if (formatParams->nPortIndex > kOutputPortIndex) { 1790c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_ErrorUndefined; 1800c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1810c1bc742181ded4930842b46e9507372f0b1b963James Dong 1820c1bc742181ded4930842b46e9507372f0b1b963James Dong if (formatParams->nIndex != 0) { 1830c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_ErrorNoMore; 1840c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1850c1bc742181ded4930842b46e9507372f0b1b963James Dong 1860c1bc742181ded4930842b46e9507372f0b1b963James Dong if (formatParams->nPortIndex == kInputPortIndex) { 1870c1bc742181ded4930842b46e9507372f0b1b963James Dong formatParams->eCompressionFormat = OMX_VIDEO_CodingAVC; 1880c1bc742181ded4930842b46e9507372f0b1b963James Dong formatParams->eColorFormat = OMX_COLOR_FormatUnused; 1890c1bc742181ded4930842b46e9507372f0b1b963James Dong formatParams->xFramerate = 0; 1900c1bc742181ded4930842b46e9507372f0b1b963James Dong } else { 1910c1bc742181ded4930842b46e9507372f0b1b963James Dong CHECK(formatParams->nPortIndex == kOutputPortIndex); 1920c1bc742181ded4930842b46e9507372f0b1b963James Dong 1930c1bc742181ded4930842b46e9507372f0b1b963James Dong formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused; 1940c1bc742181ded4930842b46e9507372f0b1b963James Dong formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar; 1950c1bc742181ded4930842b46e9507372f0b1b963James Dong formatParams->xFramerate = 0; 1960c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1970c1bc742181ded4930842b46e9507372f0b1b963James Dong 1980c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_ErrorNone; 199457116d3a01618acf9a875020ca5860551ba03a6James Dong } 200457116d3a01618acf9a875020ca5860551ba03a6James Dong 201457116d3a01618acf9a875020ca5860551ba03a6James Dong case OMX_IndexParamVideoProfileLevelQuerySupported: 202457116d3a01618acf9a875020ca5860551ba03a6James Dong { 203457116d3a01618acf9a875020ca5860551ba03a6James Dong OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel = 204457116d3a01618acf9a875020ca5860551ba03a6James Dong (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) params; 205457116d3a01618acf9a875020ca5860551ba03a6James Dong 206457116d3a01618acf9a875020ca5860551ba03a6James Dong if (profileLevel->nPortIndex != kInputPortIndex) { 20729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid port index: %ld", profileLevel->nPortIndex); 208457116d3a01618acf9a875020ca5860551ba03a6James Dong return OMX_ErrorUnsupportedIndex; 209457116d3a01618acf9a875020ca5860551ba03a6James Dong } 210457116d3a01618acf9a875020ca5860551ba03a6James Dong 211457116d3a01618acf9a875020ca5860551ba03a6James Dong size_t index = profileLevel->nProfileIndex; 212457116d3a01618acf9a875020ca5860551ba03a6James Dong size_t nProfileLevels = 213457116d3a01618acf9a875020ca5860551ba03a6James Dong sizeof(kProfileLevels) / sizeof(kProfileLevels[0]); 214457116d3a01618acf9a875020ca5860551ba03a6James Dong if (index >= nProfileLevels) { 215457116d3a01618acf9a875020ca5860551ba03a6James Dong return OMX_ErrorNoMore; 216457116d3a01618acf9a875020ca5860551ba03a6James Dong } 217457116d3a01618acf9a875020ca5860551ba03a6James Dong 218457116d3a01618acf9a875020ca5860551ba03a6James Dong profileLevel->eProfile = kProfileLevels[index].mProfile; 219457116d3a01618acf9a875020ca5860551ba03a6James Dong profileLevel->eLevel = kProfileLevels[index].mLevel; 220457116d3a01618acf9a875020ca5860551ba03a6James Dong return OMX_ErrorNone; 2210c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2220c1bc742181ded4930842b46e9507372f0b1b963James Dong 2230c1bc742181ded4930842b46e9507372f0b1b963James Dong default: 2240c1bc742181ded4930842b46e9507372f0b1b963James Dong return SimpleSoftOMXComponent::internalGetParameter(index, params); 2250c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2260c1bc742181ded4930842b46e9507372f0b1b963James Dong} 2270c1bc742181ded4930842b46e9507372f0b1b963James Dong 2280c1bc742181ded4930842b46e9507372f0b1b963James DongOMX_ERRORTYPE SoftAVC::internalSetParameter( 2290c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INDEXTYPE index, const OMX_PTR params) { 2300c1bc742181ded4930842b46e9507372f0b1b963James Dong switch (index) { 2310c1bc742181ded4930842b46e9507372f0b1b963James Dong case OMX_IndexParamStandardComponentRole: 2320c1bc742181ded4930842b46e9507372f0b1b963James Dong { 2330c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMX_PARAM_COMPONENTROLETYPE *roleParams = 2340c1bc742181ded4930842b46e9507372f0b1b963James Dong (const OMX_PARAM_COMPONENTROLETYPE *)params; 2350c1bc742181ded4930842b46e9507372f0b1b963James Dong 2360c1bc742181ded4930842b46e9507372f0b1b963James Dong if (strncmp((const char *)roleParams->cRole, 2370c1bc742181ded4930842b46e9507372f0b1b963James Dong "video_decoder.avc", 2380c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_MAX_STRINGNAME_SIZE - 1)) { 2390c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_ErrorUndefined; 2400c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2410c1bc742181ded4930842b46e9507372f0b1b963James Dong 2420c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_ErrorNone; 2430c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2440c1bc742181ded4930842b46e9507372f0b1b963James Dong 2450c1bc742181ded4930842b46e9507372f0b1b963James Dong case OMX_IndexParamVideoPortFormat: 2460c1bc742181ded4930842b46e9507372f0b1b963James Dong { 2470c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = 2480c1bc742181ded4930842b46e9507372f0b1b963James Dong (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; 2490c1bc742181ded4930842b46e9507372f0b1b963James Dong 2500c1bc742181ded4930842b46e9507372f0b1b963James Dong if (formatParams->nPortIndex > kOutputPortIndex) { 2510c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_ErrorUndefined; 2520c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2530c1bc742181ded4930842b46e9507372f0b1b963James Dong 2540c1bc742181ded4930842b46e9507372f0b1b963James Dong if (formatParams->nIndex != 0) { 2550c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_ErrorNoMore; 2560c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2570c1bc742181ded4930842b46e9507372f0b1b963James Dong 2580c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_ErrorNone; 2590c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2600c1bc742181ded4930842b46e9507372f0b1b963James Dong 2610c1bc742181ded4930842b46e9507372f0b1b963James Dong default: 2620c1bc742181ded4930842b46e9507372f0b1b963James Dong return SimpleSoftOMXComponent::internalSetParameter(index, params); 2630c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2640c1bc742181ded4930842b46e9507372f0b1b963James Dong} 2650c1bc742181ded4930842b46e9507372f0b1b963James Dong 2660c1bc742181ded4930842b46e9507372f0b1b963James DongOMX_ERRORTYPE SoftAVC::getConfig( 2670c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INDEXTYPE index, OMX_PTR params) { 2680c1bc742181ded4930842b46e9507372f0b1b963James Dong switch (index) { 2690c1bc742181ded4930842b46e9507372f0b1b963James Dong case OMX_IndexConfigCommonOutputCrop: 2700c1bc742181ded4930842b46e9507372f0b1b963James Dong { 2710c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)params; 2720c1bc742181ded4930842b46e9507372f0b1b963James Dong 2730c1bc742181ded4930842b46e9507372f0b1b963James Dong if (rectParams->nPortIndex != 1) { 2740c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_ErrorUndefined; 2750c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2760c1bc742181ded4930842b46e9507372f0b1b963James Dong 2770c1bc742181ded4930842b46e9507372f0b1b963James Dong rectParams->nLeft = mCropLeft; 2780c1bc742181ded4930842b46e9507372f0b1b963James Dong rectParams->nTop = mCropTop; 279639ffaca514deb9de538bc2dc6e712380db68fd3James Dong rectParams->nWidth = mCropWidth; 280639ffaca514deb9de538bc2dc6e712380db68fd3James Dong rectParams->nHeight = mCropHeight; 2810c1bc742181ded4930842b46e9507372f0b1b963James Dong 2820c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_ErrorNone; 2830c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2840c1bc742181ded4930842b46e9507372f0b1b963James Dong 2850c1bc742181ded4930842b46e9507372f0b1b963James Dong default: 2860c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_ErrorUnsupportedIndex; 2870c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2880c1bc742181ded4930842b46e9507372f0b1b963James Dong} 2890c1bc742181ded4930842b46e9507372f0b1b963James Dong 2900c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid SoftAVC::onQueueFilled(OMX_U32 portIndex) { 2912961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber if (mSignalledError || mOutputPortSettingsChange != NONE) { 2920c1bc742181ded4930842b46e9507372f0b1b963James Dong return; 2930c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2940c1bc742181ded4930842b46e9507372f0b1b963James Dong 2950c1bc742181ded4930842b46e9507372f0b1b963James Dong if (mEOSStatus == OUTPUT_FRAMES_FLUSHED) { 2960c1bc742181ded4930842b46e9507372f0b1b963James Dong return; 2970c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2980c1bc742181ded4930842b46e9507372f0b1b963James Dong 2990c1bc742181ded4930842b46e9507372f0b1b963James Dong List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex); 3000c1bc742181ded4930842b46e9507372f0b1b963James Dong List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex); 3010c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecRet ret = H264SWDEC_PIC_RDY; 3020c1bc742181ded4930842b46e9507372f0b1b963James Dong bool portSettingsChanged = false; 3030c1bc742181ded4930842b46e9507372f0b1b963James Dong while ((mEOSStatus != INPUT_DATA_AVAILABLE || !inQueue.empty()) 3040c1bc742181ded4930842b46e9507372f0b1b963James Dong && outQueue.size() == kNumOutputBuffers) { 3050c1bc742181ded4930842b46e9507372f0b1b963James Dong 3060c1bc742181ded4930842b46e9507372f0b1b963James Dong if (mEOSStatus == INPUT_EOS_SEEN) { 3070c1bc742181ded4930842b46e9507372f0b1b963James Dong drainAllOutputBuffers(); 3080c1bc742181ded4930842b46e9507372f0b1b963James Dong return; 3090c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3100c1bc742181ded4930842b46e9507372f0b1b963James Dong 3110c1bc742181ded4930842b46e9507372f0b1b963James Dong BufferInfo *inInfo = *inQueue.begin(); 3120c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 3130c1bc742181ded4930842b46e9507372f0b1b963James Dong ++mPicId; 3140c1bc742181ded4930842b46e9507372f0b1b963James Dong 3150c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_BUFFERHEADERTYPE *header = new OMX_BUFFERHEADERTYPE; 3160c1bc742181ded4930842b46e9507372f0b1b963James Dong memset(header, 0, sizeof(OMX_BUFFERHEADERTYPE)); 3170c1bc742181ded4930842b46e9507372f0b1b963James Dong header->nTimeStamp = inHeader->nTimeStamp; 3180c1bc742181ded4930842b46e9507372f0b1b963James Dong header->nFlags = inHeader->nFlags; 31979399a427dad4a65e20dafc6c8f7cb07c8d719c7Marco Nelissen if (header->nFlags & OMX_BUFFERFLAG_EOS) { 32079399a427dad4a65e20dafc6c8f7cb07c8d719c7Marco Nelissen mEOSStatus = INPUT_EOS_SEEN; 32179399a427dad4a65e20dafc6c8f7cb07c8d719c7Marco Nelissen } 3220c1bc742181ded4930842b46e9507372f0b1b963James Dong mPicToHeaderMap.add(mPicId, header); 3230c1bc742181ded4930842b46e9507372f0b1b963James Dong inQueue.erase(inQueue.begin()); 3240c1bc742181ded4930842b46e9507372f0b1b963James Dong 3250c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecInput inPicture; 3260c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecOutput outPicture; 3270c1bc742181ded4930842b46e9507372f0b1b963James Dong memset(&inPicture, 0, sizeof(inPicture)); 3280c1bc742181ded4930842b46e9507372f0b1b963James Dong inPicture.dataLen = inHeader->nFilledLen; 3290c1bc742181ded4930842b46e9507372f0b1b963James Dong inPicture.pStream = inHeader->pBuffer + inHeader->nOffset; 3300c1bc742181ded4930842b46e9507372f0b1b963James Dong inPicture.picId = mPicId; 3310c1bc742181ded4930842b46e9507372f0b1b963James Dong inPicture.intraConcealmentMethod = 1; 3320c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecPicture decodedPicture; 3330c1bc742181ded4930842b46e9507372f0b1b963James Dong 3340c1bc742181ded4930842b46e9507372f0b1b963James Dong while (inPicture.dataLen > 0) { 3350c1bc742181ded4930842b46e9507372f0b1b963James Dong ret = H264SwDecDecode(mHandle, &inPicture, &outPicture); 3360c1bc742181ded4930842b46e9507372f0b1b963James Dong if (ret == H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY || 3370c1bc742181ded4930842b46e9507372f0b1b963James Dong ret == H264SWDEC_PIC_RDY_BUFF_NOT_EMPTY) { 3380c1bc742181ded4930842b46e9507372f0b1b963James Dong inPicture.dataLen -= (u32)(outPicture.pStrmCurrPos - inPicture.pStream); 3390c1bc742181ded4930842b46e9507372f0b1b963James Dong inPicture.pStream = outPicture.pStrmCurrPos; 3400c1bc742181ded4930842b46e9507372f0b1b963James Dong if (ret == H264SWDEC_HDRS_RDY_BUFF_NOT_EMPTY) { 3410c1bc742181ded4930842b46e9507372f0b1b963James Dong mHeadersDecoded = true; 3420c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecInfo decoderInfo; 3430c1bc742181ded4930842b46e9507372f0b1b963James Dong CHECK(H264SwDecGetInfo(mHandle, &decoderInfo) == H264SWDEC_OK); 3440c1bc742181ded4930842b46e9507372f0b1b963James Dong 3450c1bc742181ded4930842b46e9507372f0b1b963James Dong if (handlePortSettingChangeEvent(&decoderInfo)) { 3460c1bc742181ded4930842b46e9507372f0b1b963James Dong portSettingsChanged = true; 3470c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3480c1bc742181ded4930842b46e9507372f0b1b963James Dong 3490c1bc742181ded4930842b46e9507372f0b1b963James Dong if (decoderInfo.croppingFlag && 3500c1bc742181ded4930842b46e9507372f0b1b963James Dong handleCropRectEvent(&decoderInfo.cropParams)) { 3510c1bc742181ded4930842b46e9507372f0b1b963James Dong portSettingsChanged = true; 3520c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3530c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3540c1bc742181ded4930842b46e9507372f0b1b963James Dong } else { 3550c1bc742181ded4930842b46e9507372f0b1b963James Dong if (portSettingsChanged) { 3560c1bc742181ded4930842b46e9507372f0b1b963James Dong if (H264SwDecNextPicture(mHandle, &decodedPicture, 0) 3570c1bc742181ded4930842b46e9507372f0b1b963James Dong == H264SWDEC_PIC_RDY) { 3580c1bc742181ded4930842b46e9507372f0b1b963James Dong 3590c1bc742181ded4930842b46e9507372f0b1b963James Dong // Save this output buffer; otherwise, it will be 3600c1bc742181ded4930842b46e9507372f0b1b963James Dong // lost during dynamic port reconfiguration because 3610c1bc742181ded4930842b46e9507372f0b1b963James Dong // OpenMAX client will delete _all_ output buffers 3620c1bc742181ded4930842b46e9507372f0b1b963James Dong // in the process. 3630c1bc742181ded4930842b46e9507372f0b1b963James Dong saveFirstOutputBuffer( 3640c1bc742181ded4930842b46e9507372f0b1b963James Dong decodedPicture.picId, 3650c1bc742181ded4930842b46e9507372f0b1b963James Dong (uint8_t *)decodedPicture.pOutputPicture); 3660c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3670c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3680c1bc742181ded4930842b46e9507372f0b1b963James Dong inPicture.dataLen = 0; 3690c1bc742181ded4930842b46e9507372f0b1b963James Dong if (ret < 0) { 37029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Decoder failed: %d", ret); 3712961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber 3722961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber notify(OMX_EventError, OMX_ErrorUndefined, 3732961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber ERROR_MALFORMED, NULL); 3742961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber 3752961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber mSignalledError = true; 3762961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber return; 3770c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3780c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3790c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3800c1bc742181ded4930842b46e9507372f0b1b963James Dong inInfo->mOwnedByUs = false; 3810c1bc742181ded4930842b46e9507372f0b1b963James Dong notifyEmptyBufferDone(inHeader); 3820c1bc742181ded4930842b46e9507372f0b1b963James Dong 3830c1bc742181ded4930842b46e9507372f0b1b963James Dong if (portSettingsChanged) { 3840c1bc742181ded4930842b46e9507372f0b1b963James Dong portSettingsChanged = false; 3850c1bc742181ded4930842b46e9507372f0b1b963James Dong return; 3860c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3870c1bc742181ded4930842b46e9507372f0b1b963James Dong 3880c1bc742181ded4930842b46e9507372f0b1b963James Dong if (mFirstPicture && !outQueue.empty()) { 3890c1bc742181ded4930842b46e9507372f0b1b963James Dong drainOneOutputBuffer(mFirstPictureId, mFirstPicture); 3900c1bc742181ded4930842b46e9507372f0b1b963James Dong delete[] mFirstPicture; 3910c1bc742181ded4930842b46e9507372f0b1b963James Dong mFirstPicture = NULL; 3920c1bc742181ded4930842b46e9507372f0b1b963James Dong mFirstPictureId = -1; 3930c1bc742181ded4930842b46e9507372f0b1b963James Dong } 3940c1bc742181ded4930842b46e9507372f0b1b963James Dong 3950c1bc742181ded4930842b46e9507372f0b1b963James Dong while (!outQueue.empty() && 3960c1bc742181ded4930842b46e9507372f0b1b963James Dong mHeadersDecoded && 3970c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecNextPicture(mHandle, &decodedPicture, 0) 3980c1bc742181ded4930842b46e9507372f0b1b963James Dong == H264SWDEC_PIC_RDY) { 3990c1bc742181ded4930842b46e9507372f0b1b963James Dong 4000c1bc742181ded4930842b46e9507372f0b1b963James Dong int32_t picId = decodedPicture.picId; 4010c1bc742181ded4930842b46e9507372f0b1b963James Dong uint8_t *data = (uint8_t *) decodedPicture.pOutputPicture; 4020c1bc742181ded4930842b46e9507372f0b1b963James Dong drainOneOutputBuffer(picId, data); 4030c1bc742181ded4930842b46e9507372f0b1b963James Dong } 4040c1bc742181ded4930842b46e9507372f0b1b963James Dong } 4050c1bc742181ded4930842b46e9507372f0b1b963James Dong} 4060c1bc742181ded4930842b46e9507372f0b1b963James Dong 4070c1bc742181ded4930842b46e9507372f0b1b963James Dongbool SoftAVC::handlePortSettingChangeEvent(const H264SwDecInfo *info) { 4080c1bc742181ded4930842b46e9507372f0b1b963James Dong if (mWidth != info->picWidth || mHeight != info->picHeight) { 4090c1bc742181ded4930842b46e9507372f0b1b963James Dong mWidth = info->picWidth; 4100c1bc742181ded4930842b46e9507372f0b1b963James Dong mHeight = info->picHeight; 4110c1bc742181ded4930842b46e9507372f0b1b963James Dong mPictureSize = mWidth * mHeight * 3 / 2; 412639ffaca514deb9de538bc2dc6e712380db68fd3James Dong mCropWidth = mWidth; 413639ffaca514deb9de538bc2dc6e712380db68fd3James Dong mCropHeight = mHeight; 4140c1bc742181ded4930842b46e9507372f0b1b963James Dong updatePortDefinitions(); 4150c1bc742181ded4930842b46e9507372f0b1b963James Dong notify(OMX_EventPortSettingsChanged, 1, 0, NULL); 4160c1bc742181ded4930842b46e9507372f0b1b963James Dong mOutputPortSettingsChange = AWAITING_DISABLED; 4170c1bc742181ded4930842b46e9507372f0b1b963James Dong return true; 4180c1bc742181ded4930842b46e9507372f0b1b963James Dong } 4190c1bc742181ded4930842b46e9507372f0b1b963James Dong 4200c1bc742181ded4930842b46e9507372f0b1b963James Dong return false; 4210c1bc742181ded4930842b46e9507372f0b1b963James Dong} 4220c1bc742181ded4930842b46e9507372f0b1b963James Dong 4230c1bc742181ded4930842b46e9507372f0b1b963James Dongbool SoftAVC::handleCropRectEvent(const CropParams *crop) { 4240c1bc742181ded4930842b46e9507372f0b1b963James Dong if (mCropLeft != crop->cropLeftOffset || 4250c1bc742181ded4930842b46e9507372f0b1b963James Dong mCropTop != crop->cropTopOffset || 426639ffaca514deb9de538bc2dc6e712380db68fd3James Dong mCropWidth != crop->cropOutWidth || 427639ffaca514deb9de538bc2dc6e712380db68fd3James Dong mCropHeight != crop->cropOutHeight) { 4280c1bc742181ded4930842b46e9507372f0b1b963James Dong mCropLeft = crop->cropLeftOffset; 4290c1bc742181ded4930842b46e9507372f0b1b963James Dong mCropTop = crop->cropTopOffset; 430639ffaca514deb9de538bc2dc6e712380db68fd3James Dong mCropWidth = crop->cropOutWidth; 431639ffaca514deb9de538bc2dc6e712380db68fd3James Dong mCropHeight = crop->cropOutHeight; 4320c1bc742181ded4930842b46e9507372f0b1b963James Dong 4330c1bc742181ded4930842b46e9507372f0b1b963James Dong notify(OMX_EventPortSettingsChanged, 1, 4340c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_IndexConfigCommonOutputCrop, NULL); 4350c1bc742181ded4930842b46e9507372f0b1b963James Dong 4360c1bc742181ded4930842b46e9507372f0b1b963James Dong return true; 4370c1bc742181ded4930842b46e9507372f0b1b963James Dong } 4380c1bc742181ded4930842b46e9507372f0b1b963James Dong return false; 4390c1bc742181ded4930842b46e9507372f0b1b963James Dong} 4400c1bc742181ded4930842b46e9507372f0b1b963James Dong 4410c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid SoftAVC::saveFirstOutputBuffer(int32_t picId, uint8_t *data) { 4420c1bc742181ded4930842b46e9507372f0b1b963James Dong CHECK(mFirstPicture == NULL); 4430c1bc742181ded4930842b46e9507372f0b1b963James Dong mFirstPictureId = picId; 4440c1bc742181ded4930842b46e9507372f0b1b963James Dong 4450c1bc742181ded4930842b46e9507372f0b1b963James Dong mFirstPicture = new uint8_t[mPictureSize]; 4460c1bc742181ded4930842b46e9507372f0b1b963James Dong memcpy(mFirstPicture, data, mPictureSize); 4470c1bc742181ded4930842b46e9507372f0b1b963James Dong} 4480c1bc742181ded4930842b46e9507372f0b1b963James Dong 4490c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid SoftAVC::drainOneOutputBuffer(int32_t picId, uint8_t* data) { 4500c1bc742181ded4930842b46e9507372f0b1b963James Dong List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex); 4510c1bc742181ded4930842b46e9507372f0b1b963James Dong BufferInfo *outInfo = *outQueue.begin(); 4520c1bc742181ded4930842b46e9507372f0b1b963James Dong outQueue.erase(outQueue.begin()); 4530c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 4540c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_BUFFERHEADERTYPE *header = mPicToHeaderMap.valueFor(picId); 4550c1bc742181ded4930842b46e9507372f0b1b963James Dong outHeader->nTimeStamp = header->nTimeStamp; 4560c1bc742181ded4930842b46e9507372f0b1b963James Dong outHeader->nFlags = header->nFlags; 4570c1bc742181ded4930842b46e9507372f0b1b963James Dong outHeader->nFilledLen = mPictureSize; 4580c1bc742181ded4930842b46e9507372f0b1b963James Dong memcpy(outHeader->pBuffer + outHeader->nOffset, 4590c1bc742181ded4930842b46e9507372f0b1b963James Dong data, mPictureSize); 4600c1bc742181ded4930842b46e9507372f0b1b963James Dong mPicToHeaderMap.removeItem(picId); 4610c1bc742181ded4930842b46e9507372f0b1b963James Dong delete header; 4620c1bc742181ded4930842b46e9507372f0b1b963James Dong outInfo->mOwnedByUs = false; 4630c1bc742181ded4930842b46e9507372f0b1b963James Dong notifyFillBufferDone(outHeader); 4640c1bc742181ded4930842b46e9507372f0b1b963James Dong} 4650c1bc742181ded4930842b46e9507372f0b1b963James Dong 4660c1bc742181ded4930842b46e9507372f0b1b963James Dongbool SoftAVC::drainAllOutputBuffers() { 4670c1bc742181ded4930842b46e9507372f0b1b963James Dong List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex); 4680c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecPicture decodedPicture; 4690c1bc742181ded4930842b46e9507372f0b1b963James Dong 4700c1bc742181ded4930842b46e9507372f0b1b963James Dong while (!outQueue.empty()) { 4710c1bc742181ded4930842b46e9507372f0b1b963James Dong BufferInfo *outInfo = *outQueue.begin(); 4720c1bc742181ded4930842b46e9507372f0b1b963James Dong outQueue.erase(outQueue.begin()); 4730c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 4740c1bc742181ded4930842b46e9507372f0b1b963James Dong if (mHeadersDecoded && 4750c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SWDEC_PIC_RDY == 4760c1bc742181ded4930842b46e9507372f0b1b963James Dong H264SwDecNextPicture(mHandle, &decodedPicture, 1 /* flush */)) { 4770c1bc742181ded4930842b46e9507372f0b1b963James Dong 4780c1bc742181ded4930842b46e9507372f0b1b963James Dong int32_t picId = decodedPicture.picId; 4790c1bc742181ded4930842b46e9507372f0b1b963James Dong CHECK(mPicToHeaderMap.indexOfKey(picId) >= 0); 4800c1bc742181ded4930842b46e9507372f0b1b963James Dong 4810c1bc742181ded4930842b46e9507372f0b1b963James Dong memcpy(outHeader->pBuffer + outHeader->nOffset, 4820c1bc742181ded4930842b46e9507372f0b1b963James Dong decodedPicture.pOutputPicture, 4830c1bc742181ded4930842b46e9507372f0b1b963James Dong mPictureSize); 4840c1bc742181ded4930842b46e9507372f0b1b963James Dong 4850c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_BUFFERHEADERTYPE *header = mPicToHeaderMap.valueFor(picId); 4860c1bc742181ded4930842b46e9507372f0b1b963James Dong outHeader->nTimeStamp = header->nTimeStamp; 4870c1bc742181ded4930842b46e9507372f0b1b963James Dong outHeader->nFlags = header->nFlags; 4880c1bc742181ded4930842b46e9507372f0b1b963James Dong outHeader->nFilledLen = mPictureSize; 4890c1bc742181ded4930842b46e9507372f0b1b963James Dong mPicToHeaderMap.removeItem(picId); 4900c1bc742181ded4930842b46e9507372f0b1b963James Dong delete header; 4910c1bc742181ded4930842b46e9507372f0b1b963James Dong } else { 4920c1bc742181ded4930842b46e9507372f0b1b963James Dong outHeader->nTimeStamp = 0; 4930c1bc742181ded4930842b46e9507372f0b1b963James Dong outHeader->nFilledLen = 0; 4940c1bc742181ded4930842b46e9507372f0b1b963James Dong outHeader->nFlags = OMX_BUFFERFLAG_EOS; 4950c1bc742181ded4930842b46e9507372f0b1b963James Dong mEOSStatus = OUTPUT_FRAMES_FLUSHED; 4960c1bc742181ded4930842b46e9507372f0b1b963James Dong } 4970c1bc742181ded4930842b46e9507372f0b1b963James Dong 4980c1bc742181ded4930842b46e9507372f0b1b963James Dong outInfo->mOwnedByUs = false; 4990c1bc742181ded4930842b46e9507372f0b1b963James Dong notifyFillBufferDone(outHeader); 5000c1bc742181ded4930842b46e9507372f0b1b963James Dong } 5010c1bc742181ded4930842b46e9507372f0b1b963James Dong 5020c1bc742181ded4930842b46e9507372f0b1b963James Dong return true; 5030c1bc742181ded4930842b46e9507372f0b1b963James Dong} 5040c1bc742181ded4930842b46e9507372f0b1b963James Dong 5050c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid SoftAVC::onPortFlushCompleted(OMX_U32 portIndex) { 5060c1bc742181ded4930842b46e9507372f0b1b963James Dong if (portIndex == kInputPortIndex) { 5070c1bc742181ded4930842b46e9507372f0b1b963James Dong mEOSStatus = INPUT_DATA_AVAILABLE; 5080c1bc742181ded4930842b46e9507372f0b1b963James Dong } 5090c1bc742181ded4930842b46e9507372f0b1b963James Dong} 5100c1bc742181ded4930842b46e9507372f0b1b963James Dong 5110c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid SoftAVC::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { 5120c1bc742181ded4930842b46e9507372f0b1b963James Dong switch (mOutputPortSettingsChange) { 5130c1bc742181ded4930842b46e9507372f0b1b963James Dong case NONE: 5140c1bc742181ded4930842b46e9507372f0b1b963James Dong break; 5150c1bc742181ded4930842b46e9507372f0b1b963James Dong 5160c1bc742181ded4930842b46e9507372f0b1b963James Dong case AWAITING_DISABLED: 5170c1bc742181ded4930842b46e9507372f0b1b963James Dong { 5180c1bc742181ded4930842b46e9507372f0b1b963James Dong CHECK(!enabled); 5190c1bc742181ded4930842b46e9507372f0b1b963James Dong mOutputPortSettingsChange = AWAITING_ENABLED; 5200c1bc742181ded4930842b46e9507372f0b1b963James Dong break; 5210c1bc742181ded4930842b46e9507372f0b1b963James Dong } 5220c1bc742181ded4930842b46e9507372f0b1b963James Dong 5230c1bc742181ded4930842b46e9507372f0b1b963James Dong default: 5240c1bc742181ded4930842b46e9507372f0b1b963James Dong { 5250c1bc742181ded4930842b46e9507372f0b1b963James Dong CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); 5260c1bc742181ded4930842b46e9507372f0b1b963James Dong CHECK(enabled); 5270c1bc742181ded4930842b46e9507372f0b1b963James Dong mOutputPortSettingsChange = NONE; 5280c1bc742181ded4930842b46e9507372f0b1b963James Dong break; 5290c1bc742181ded4930842b46e9507372f0b1b963James Dong } 5300c1bc742181ded4930842b46e9507372f0b1b963James Dong } 5310c1bc742181ded4930842b46e9507372f0b1b963James Dong} 5320c1bc742181ded4930842b46e9507372f0b1b963James Dong 5330c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid SoftAVC::updatePortDefinitions() { 5340c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(0)->mDef; 5350c1bc742181ded4930842b46e9507372f0b1b963James Dong def->format.video.nFrameWidth = mWidth; 5360c1bc742181ded4930842b46e9507372f0b1b963James Dong def->format.video.nFrameHeight = mHeight; 5370c1bc742181ded4930842b46e9507372f0b1b963James Dong def->format.video.nStride = def->format.video.nFrameWidth; 5380c1bc742181ded4930842b46e9507372f0b1b963James Dong def->format.video.nSliceHeight = def->format.video.nFrameHeight; 5390c1bc742181ded4930842b46e9507372f0b1b963James Dong 5400c1bc742181ded4930842b46e9507372f0b1b963James Dong def = &editPortInfo(1)->mDef; 5410c1bc742181ded4930842b46e9507372f0b1b963James Dong def->format.video.nFrameWidth = mWidth; 5420c1bc742181ded4930842b46e9507372f0b1b963James Dong def->format.video.nFrameHeight = mHeight; 5430c1bc742181ded4930842b46e9507372f0b1b963James Dong def->format.video.nStride = def->format.video.nFrameWidth; 5440c1bc742181ded4930842b46e9507372f0b1b963James Dong def->format.video.nSliceHeight = def->format.video.nFrameHeight; 5450c1bc742181ded4930842b46e9507372f0b1b963James Dong 5460c1bc742181ded4930842b46e9507372f0b1b963James Dong def->nBufferSize = 5470c1bc742181ded4930842b46e9507372f0b1b963James Dong (def->format.video.nFrameWidth 5480c1bc742181ded4930842b46e9507372f0b1b963James Dong * def->format.video.nFrameHeight * 3) / 2; 5490c1bc742181ded4930842b46e9507372f0b1b963James Dong} 5500c1bc742181ded4930842b46e9507372f0b1b963James Dong 5510c1bc742181ded4930842b46e9507372f0b1b963James Dong} // namespace android 5520c1bc742181ded4930842b46e9507372f0b1b963James Dong 5530c1bc742181ded4930842b46e9507372f0b1b963James Dongandroid::SoftOMXComponent *createSoftOMXComponent( 5540c1bc742181ded4930842b46e9507372f0b1b963James Dong const char *name, const OMX_CALLBACKTYPE *callbacks, 5550c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_PTR appData, OMX_COMPONENTTYPE **component) { 5560c1bc742181ded4930842b46e9507372f0b1b963James Dong return new android::SoftAVC(name, callbacks, appData, component); 5570c1bc742181ded4930842b46e9507372f0b1b963James Dong} 558