1bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian/* 2bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian * Copyright (C) 2014 The Android Open Source Project 3bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian * 4bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian * Licensed under the Apache License, Version 2.0 (the "License"); 5bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian * you may not use this file except in compliance with the License. 6bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian * You may obtain a copy of the License at 7bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian * 8bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian * http://www.apache.org/licenses/LICENSE-2.0 9bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian * 10bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian * Unless required by applicable law or agreed to in writing, software 11bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian * distributed under the License is distributed on an "AS IS" BASIS, 12bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian * See the License for the specific language governing permissions and 14bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian * limitations under the License. 15bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian */ 16bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 17bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian//#define LOG_NDEBUG 0 18bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian#define LOG_TAG "SoftOpus" 19bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian#include <utils/Log.h> 20bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 21bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian#include "SoftOpus.h" 2217d653523898c01816457743ab376a7b0427611fLajos Molnar#include <OMX_AudioExt.h> 2317d653523898c01816457743ab376a7b0427611fLajos Molnar#include <OMX_IndexExt.h> 24bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 25bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian#include <media/stagefright/foundation/ADebug.h> 26bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian#include <media/stagefright/MediaDefs.h> 27bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 28bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianextern "C" { 29bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian #include <opus.h> 30bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian #include <opus_multistream.h> 31bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 32bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 33bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramaniannamespace android { 34bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 35bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianstatic const int kRate = 48000; 36bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 3708e8227514f5ab99822dfae8b4d39414646ff59dVignesh Venkatasubramanian// Opus uses Vorbis channel mapping, and Vorbis channel mapping specifies 3808e8227514f5ab99822dfae8b4d39414646ff59dVignesh Venkatasubramanian// mappings for up to 8 channels. This information is part of the Vorbis I 3908e8227514f5ab99822dfae8b4d39414646ff59dVignesh Venkatasubramanian// Specification: 4008e8227514f5ab99822dfae8b4d39414646ff59dVignesh Venkatasubramanian// http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html 4108e8227514f5ab99822dfae8b4d39414646ff59dVignesh Venkatasubramanianstatic const int kMaxChannels = 8; 4208e8227514f5ab99822dfae8b4d39414646ff59dVignesh Venkatasubramanian 43bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramaniantemplate<class T> 44bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianstatic void InitOMXParams(T *params) { 45bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian params->nSize = sizeof(T); 46bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian params->nVersion.s.nVersionMajor = 1; 47bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian params->nVersion.s.nVersionMinor = 0; 48bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian params->nVersion.s.nRevision = 0; 49bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian params->nVersion.s.nStep = 0; 50bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 51bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 52bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh VenkatasubramanianSoftOpus::SoftOpus( 53bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian const char *name, 54bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian const OMX_CALLBACKTYPE *callbacks, 55bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian OMX_PTR appData, 56bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian OMX_COMPONENTTYPE **component) 57bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian : SimpleSoftOMXComponent(name, callbacks, appData, component), 58bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mInputBufferCount(0), 59bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mDecoder(NULL), 60bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mHeader(NULL), 61bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mCodecDelay(0), 62bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mSeekPreRoll(0), 63bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mAnchorTimeUs(0), 64bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mNumFramesOutput(0), 65bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mOutputPortSettingsChange(NONE) { 66bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian initPorts(); 67bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian CHECK_EQ(initDecoder(), (status_t)OK); 68bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 69bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 70bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh VenkatasubramanianSoftOpus::~SoftOpus() { 71bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (mDecoder != NULL) { 72bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian opus_multistream_decoder_destroy(mDecoder); 73bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mDecoder = NULL; 74bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 75bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (mHeader != NULL) { 76bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian delete mHeader; 77bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mHeader = NULL; 78bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 79bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 80bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 81bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianvoid SoftOpus::initPorts() { 82bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian OMX_PARAM_PORTDEFINITIONTYPE def; 83bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian InitOMXParams(&def); 84bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 85bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.nPortIndex = 0; 86bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.eDir = OMX_DirInput; 87bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.nBufferCountMin = kNumBuffers; 88bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.nBufferCountActual = def.nBufferCountMin; 89bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.nBufferSize = 960 * 6; 90bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.bEnabled = OMX_TRUE; 91bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.bPopulated = OMX_FALSE; 92bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.eDomain = OMX_PortDomainAudio; 93bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.bBuffersContiguous = OMX_FALSE; 94bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.nBufferAlignment = 1; 95bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 96bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.format.audio.cMIMEType = 97bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian const_cast<char *>(MEDIA_MIMETYPE_AUDIO_OPUS); 98bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 99bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.format.audio.pNativeRender = NULL; 100bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.format.audio.bFlagErrorConcealment = OMX_FALSE; 10117d653523898c01816457743ab376a7b0427611fLajos Molnar def.format.audio.eEncoding = 10217d653523898c01816457743ab376a7b0427611fLajos Molnar (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidOPUS; 103bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 104bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian addPort(def); 105bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 106bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.nPortIndex = 1; 107bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.eDir = OMX_DirOutput; 108bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.nBufferCountMin = kNumBuffers; 109bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.nBufferCountActual = def.nBufferCountMin; 11008e8227514f5ab99822dfae8b4d39414646ff59dVignesh Venkatasubramanian def.nBufferSize = kMaxNumSamplesPerBuffer * sizeof(int16_t) * kMaxChannels; 111bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.bEnabled = OMX_TRUE; 112bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.bPopulated = OMX_FALSE; 113bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.eDomain = OMX_PortDomainAudio; 114bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.bBuffersContiguous = OMX_FALSE; 115bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.nBufferAlignment = 2; 116bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 117bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.format.audio.cMIMEType = const_cast<char *>("audio/raw"); 118bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.format.audio.pNativeRender = NULL; 119bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.format.audio.bFlagErrorConcealment = OMX_FALSE; 120bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 121bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 122bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian addPort(def); 123bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 124bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 125bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianstatus_t SoftOpus::initDecoder() { 126bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return OK; 127bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 128bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 129bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh VenkatasubramanianOMX_ERRORTYPE SoftOpus::internalGetParameter( 130bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian OMX_INDEXTYPE index, OMX_PTR params) { 13117d653523898c01816457743ab376a7b0427611fLajos Molnar switch ((int)index) { 132bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian case OMX_IndexParamAudioAndroidOpus: 133bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian { 134bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *opusParams = 135bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian (OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *)params; 136bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 1372720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(opusParams)) { 1382720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 1392720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 1402720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 141bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (opusParams->nPortIndex != 0) { 142bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return OMX_ErrorUndefined; 143bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 144bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 145bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian opusParams->nAudioBandWidth = 0; 146bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian opusParams->nSampleRate = kRate; 147bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian opusParams->nBitRate = 0; 148bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 149bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (!isConfigured()) { 150bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian opusParams->nChannels = 1; 151bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } else { 152bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian opusParams->nChannels = mHeader->channels; 153bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 154bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 155bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return OMX_ErrorNone; 156bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 157bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 158bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian case OMX_IndexParamAudioPcm: 159bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian { 160bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 161bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 162bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 1632720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(pcmParams)) { 1642720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 1652720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 1662720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 167bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (pcmParams->nPortIndex != 1) { 168bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return OMX_ErrorUndefined; 169bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 170bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 171bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian pcmParams->eNumData = OMX_NumericalDataSigned; 172bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian pcmParams->eEndian = OMX_EndianBig; 173bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian pcmParams->bInterleaved = OMX_TRUE; 174bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian pcmParams->nBitPerSample = 16; 175bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; 176bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF; 177bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF; 178bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian pcmParams->nSamplingRate = kRate; 179bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 180bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (!isConfigured()) { 181bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian pcmParams->nChannels = 1; 182bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } else { 183bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian pcmParams->nChannels = mHeader->channels; 184bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 185bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 186bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return OMX_ErrorNone; 187bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 188bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 189bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian default: 190bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return SimpleSoftOMXComponent::internalGetParameter(index, params); 191bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 192bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 193bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 194bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh VenkatasubramanianOMX_ERRORTYPE SoftOpus::internalSetParameter( 195bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian OMX_INDEXTYPE index, const OMX_PTR params) { 19617d653523898c01816457743ab376a7b0427611fLajos Molnar switch ((int)index) { 197bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian case OMX_IndexParamStandardComponentRole: 198bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian { 199bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian const OMX_PARAM_COMPONENTROLETYPE *roleParams = 200bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian (const OMX_PARAM_COMPONENTROLETYPE *)params; 201bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 2022720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(roleParams)) { 2032720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 2042720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 2052720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 206bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (strncmp((const char *)roleParams->cRole, 207bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian "audio_decoder.opus", 208bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian OMX_MAX_STRINGNAME_SIZE - 1)) { 209bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return OMX_ErrorUndefined; 210bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 211bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 212bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return OMX_ErrorNone; 213bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 214bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 215bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian case OMX_IndexParamAudioAndroidOpus: 216bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian { 217bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian const OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *opusParams = 218bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian (const OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *)params; 219bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 2202720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(opusParams)) { 2212720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 2222720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 2232720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 224bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (opusParams->nPortIndex != 0) { 225bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return OMX_ErrorUndefined; 226bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 227bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 228bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return OMX_ErrorNone; 229bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 230bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 231bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian default: 232bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return SimpleSoftOMXComponent::internalSetParameter(index, params); 233bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 234bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 235bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 236bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianbool SoftOpus::isConfigured() const { 237bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return mInputBufferCount >= 1; 238bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 239bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 240bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianstatic uint16_t ReadLE16(const uint8_t *data, size_t data_size, 241bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian uint32_t read_offset) { 242bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (read_offset + 1 > data_size) 243bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return 0; 244bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian uint16_t val; 245bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian val = data[read_offset]; 246bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian val |= data[read_offset + 1] << 8; 247bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return val; 248bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 249bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 250bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian// Maximum packet size used in Xiph's opusdec. 251bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianstatic const int kMaxOpusOutputPacketSizeSamples = 960 * 6; 252bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 253bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian// Default audio output channel layout. Used to initialize |stream_map| in 254bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian// OpusHeader, and passed to opus_multistream_decoder_create() when the header 255bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian// does not contain mapping information. The values are valid only for mono and 256bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian// stereo output: Opus streams with more than 2 channels require a stream map. 257bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianstatic const int kMaxChannelsWithDefaultLayout = 2; 258bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianstatic const uint8_t kDefaultOpusChannelLayout[kMaxChannelsWithDefaultLayout] = { 0, 1 }; 259bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 260bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian// Parses Opus Header. Header spec: http://wiki.xiph.org/OggOpus#ID_Header 261bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianstatic bool ParseOpusHeader(const uint8_t *data, size_t data_size, 262bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian OpusHeader* header) { 263bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // Size of the Opus header excluding optional mapping information. 26417d653523898c01816457743ab376a7b0427611fLajos Molnar const size_t kOpusHeaderSize = 19; 265bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 266bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // Offset to the channel count byte in the Opus header. 26717d653523898c01816457743ab376a7b0427611fLajos Molnar const size_t kOpusHeaderChannelsOffset = 9; 268bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 269bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // Offset to the pre-skip value in the Opus header. 27017d653523898c01816457743ab376a7b0427611fLajos Molnar const size_t kOpusHeaderSkipSamplesOffset = 10; 271bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 272bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // Offset to the gain value in the Opus header. 27317d653523898c01816457743ab376a7b0427611fLajos Molnar const size_t kOpusHeaderGainOffset = 16; 274bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 275bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // Offset to the channel mapping byte in the Opus header. 27617d653523898c01816457743ab376a7b0427611fLajos Molnar const size_t kOpusHeaderChannelMappingOffset = 18; 277bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 278bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // Opus Header contains a stream map. The mapping values are in the header 279bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // beyond the always present |kOpusHeaderSize| bytes of data. The mapping 280bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // data contains stream count, coupling information, and per channel mapping 281bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // values: 282bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // - Byte 0: Number of streams. 283bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // - Byte 1: Number coupled. 284bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // - Byte 2: Starting at byte 2 are |header->channels| uint8 mapping 285bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // values. 28617d653523898c01816457743ab376a7b0427611fLajos Molnar const size_t kOpusHeaderNumStreamsOffset = kOpusHeaderSize; 28717d653523898c01816457743ab376a7b0427611fLajos Molnar const size_t kOpusHeaderNumCoupledOffset = kOpusHeaderNumStreamsOffset + 1; 28817d653523898c01816457743ab376a7b0427611fLajos Molnar const size_t kOpusHeaderStreamMapOffset = kOpusHeaderNumStreamsOffset + 2; 289bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 290bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (data_size < kOpusHeaderSize) { 291bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian ALOGV("Header size is too small."); 292bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return false; 293bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 294bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian header->channels = *(data + kOpusHeaderChannelsOffset); 295bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 296bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (header->channels <= 0 || header->channels > kMaxChannels) { 297bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian ALOGV("Invalid Header, wrong channel count: %d", header->channels); 298bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return false; 299bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 300bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian header->skip_samples = ReadLE16(data, data_size, 301bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian kOpusHeaderSkipSamplesOffset); 302bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian header->gain_db = static_cast<int16_t>( 303bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian ReadLE16(data, data_size, 304bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian kOpusHeaderGainOffset)); 305bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian header->channel_mapping = *(data + kOpusHeaderChannelMappingOffset); 306bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (!header->channel_mapping) { 307bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (header->channels > kMaxChannelsWithDefaultLayout) { 308bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian ALOGV("Invalid Header, missing stream map."); 309bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return false; 310bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 311bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian header->num_streams = 1; 312bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian header->num_coupled = header->channels > 1; 313bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian header->stream_map[0] = 0; 314bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian header->stream_map[1] = 1; 315bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return true; 316bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 317bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (data_size < kOpusHeaderStreamMapOffset + header->channels) { 318bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian ALOGV("Invalid stream map; insufficient data for current channel " 319bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian "count: %d", header->channels); 320bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return false; 321bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 322bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian header->num_streams = *(data + kOpusHeaderNumStreamsOffset); 323bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian header->num_coupled = *(data + kOpusHeaderNumCoupledOffset); 324bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (header->num_streams + header->num_coupled != header->channels) { 325bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian ALOGV("Inconsistent channel mapping."); 326bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return false; 327bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 328bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian for (int i = 0; i < header->channels; ++i) 329bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian header->stream_map[i] = *(data + kOpusHeaderStreamMapOffset + i); 330bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return true; 331bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 332bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 333bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian// Convert nanoseconds to number of samples. 334bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianstatic uint64_t ns_to_samples(uint64_t ns, int kRate) { 335bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return static_cast<double>(ns) * kRate / 1000000000; 336bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 337bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 338bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianvoid SoftOpus::onQueueFilled(OMX_U32 portIndex) { 339bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian List<BufferInfo *> &inQueue = getPortQueue(0); 340bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian List<BufferInfo *> &outQueue = getPortQueue(1); 341bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 342bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (mOutputPortSettingsChange != NONE) { 343bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return; 344bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 345bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 346bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (portIndex == 0 && mInputBufferCount < 3) { 347bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian BufferInfo *info = *inQueue.begin(); 348bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian OMX_BUFFERHEADERTYPE *header = info->mHeader; 349bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 350bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian const uint8_t *data = header->pBuffer + header->nOffset; 351bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian size_t size = header->nFilledLen; 352bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 353bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (mInputBufferCount == 0) { 354bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian CHECK(mHeader == NULL); 355bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mHeader = new OpusHeader(); 356bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian memset(mHeader, 0, sizeof(*mHeader)); 357bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (!ParseOpusHeader(data, size, mHeader)) { 358bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian ALOGV("Parsing Opus Header failed."); 359bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 360bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return; 361bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 362bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 363bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian uint8_t channel_mapping[kMaxChannels] = {0}; 3649b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian if (mHeader->channels <= kMaxChannelsWithDefaultLayout) { 3659b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian memcpy(&channel_mapping, 3669b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian kDefaultOpusChannelLayout, 3679b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian kMaxChannelsWithDefaultLayout); 3689b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian } else { 3699b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian memcpy(&channel_mapping, 3709b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian mHeader->stream_map, 3719b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian mHeader->channels); 3729b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian } 373bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 374bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian int status = OPUS_INVALID_STATE; 375bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mDecoder = opus_multistream_decoder_create(kRate, 376bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mHeader->channels, 377bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mHeader->num_streams, 378bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mHeader->num_coupled, 379bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian channel_mapping, 380bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian &status); 381bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (!mDecoder || status != OPUS_OK) { 382bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian ALOGV("opus_multistream_decoder_create failed status=%s", 383bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian opus_strerror(status)); 384bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 385bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return; 386bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 387bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian status = 388bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian opus_multistream_decoder_ctl(mDecoder, 389bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian OPUS_SET_GAIN(mHeader->gain_db)); 390bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (status != OPUS_OK) { 391bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian ALOGV("Failed to set OPUS header gain; status=%s", 392bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian opus_strerror(status)); 393bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 394bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return; 395bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 396bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } else if (mInputBufferCount == 1) { 397bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mCodecDelay = ns_to_samples( 398bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian *(reinterpret_cast<int64_t*>(header->pBuffer + 399bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian header->nOffset)), 400bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian kRate); 401bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mSamplesToDiscard = mCodecDelay; 402bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } else { 403bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mSeekPreRoll = ns_to_samples( 404bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian *(reinterpret_cast<int64_t*>(header->pBuffer + 405bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian header->nOffset)), 406bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian kRate); 407bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian notify(OMX_EventPortSettingsChanged, 1, 0, NULL); 408bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mOutputPortSettingsChange = AWAITING_DISABLED; 409bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 410bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 411bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian inQueue.erase(inQueue.begin()); 412bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian info->mOwnedByUs = false; 413bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian notifyEmptyBufferDone(header); 414bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian ++mInputBufferCount; 415bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return; 416bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 417bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 418bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian while (!inQueue.empty() && !outQueue.empty()) { 419bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian BufferInfo *inInfo = *inQueue.begin(); 420bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 421bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 4221b30bde3d4447e4c9b767c68584b8997bd930720Vignesh Venkatasubramanian // Ignore CSD re-submissions. 4231b30bde3d4447e4c9b767c68584b8997bd930720Vignesh Venkatasubramanian if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 4241b30bde3d4447e4c9b767c68584b8997bd930720Vignesh Venkatasubramanian inQueue.erase(inQueue.begin()); 4251b30bde3d4447e4c9b767c68584b8997bd930720Vignesh Venkatasubramanian inInfo->mOwnedByUs = false; 4261b30bde3d4447e4c9b767c68584b8997bd930720Vignesh Venkatasubramanian notifyEmptyBufferDone(inHeader); 4271b30bde3d4447e4c9b767c68584b8997bd930720Vignesh Venkatasubramanian return; 4281b30bde3d4447e4c9b767c68584b8997bd930720Vignesh Venkatasubramanian } 4291b30bde3d4447e4c9b767c68584b8997bd930720Vignesh Venkatasubramanian 430bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian BufferInfo *outInfo = *outQueue.begin(); 431bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 432bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 433bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 434bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian inQueue.erase(inQueue.begin()); 435bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian inInfo->mOwnedByUs = false; 436bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian notifyEmptyBufferDone(inHeader); 437bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 438bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian outHeader->nFilledLen = 0; 439bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian outHeader->nFlags = OMX_BUFFERFLAG_EOS; 440bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 441bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian outQueue.erase(outQueue.begin()); 442bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian outInfo->mOwnedByUs = false; 443bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian notifyFillBufferDone(outHeader); 444bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return; 445bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 446bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 447bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (inHeader->nOffset == 0) { 448bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mAnchorTimeUs = inHeader->nTimeStamp; 449bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mNumFramesOutput = 0; 450bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 451bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 452bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // When seeking to zero, |mCodecDelay| samples has to be discarded 453bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // instead of |mSeekPreRoll| samples (as we would when seeking to any 454bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // other timestamp). 455bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (inHeader->nTimeStamp == 0) { 456bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mSamplesToDiscard = mCodecDelay; 457bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 458bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 459bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian const uint8_t *data = inHeader->pBuffer + inHeader->nOffset; 460bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian const uint32_t size = inHeader->nFilledLen; 461e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim size_t frameSize = kMaxOpusOutputPacketSizeSamples; 462e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim if (frameSize > outHeader->nAllocLen / sizeof(int16_t) / mHeader->channels) { 463e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim frameSize = outHeader->nAllocLen / sizeof(int16_t) / mHeader->channels; 464ff64ea33382081f46d4b1061df00298bbbe3dd65Wonsik Kim android_errorWriteLog(0x534e4554, "27833616"); 465e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim } 466bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 467bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian int numFrames = opus_multistream_decode(mDecoder, 468bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian data, 469bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian size, 470bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian (int16_t *)outHeader->pBuffer, 471e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim frameSize, 472bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 0); 473bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (numFrames < 0) { 474bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian ALOGE("opus_multistream_decode returned %d", numFrames); 475bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 476bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return; 477bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 478bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 479bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian outHeader->nOffset = 0; 480bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (mSamplesToDiscard > 0) { 481bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (mSamplesToDiscard > numFrames) { 482bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mSamplesToDiscard -= numFrames; 483bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian numFrames = 0; 484bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } else { 485bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian numFrames -= mSamplesToDiscard; 486bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian outHeader->nOffset = mSamplesToDiscard * sizeof(int16_t) * 487bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mHeader->channels; 488bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mSamplesToDiscard = 0; 489bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 490bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 491bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 492bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian outHeader->nFilledLen = numFrames * sizeof(int16_t) * mHeader->channels; 493bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian outHeader->nFlags = 0; 494bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 495bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian outHeader->nTimeStamp = mAnchorTimeUs + 496bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian (mNumFramesOutput * 1000000ll) / 497bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian kRate; 498bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 499bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mNumFramesOutput += numFrames; 500bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 501bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian inInfo->mOwnedByUs = false; 502bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian inQueue.erase(inQueue.begin()); 503bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian inInfo = NULL; 504bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian notifyEmptyBufferDone(inHeader); 505bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian inHeader = NULL; 506bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 507bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian outInfo->mOwnedByUs = false; 508bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian outQueue.erase(outQueue.begin()); 509bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian outInfo = NULL; 510bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian notifyFillBufferDone(outHeader); 511bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian outHeader = NULL; 512bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 513bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian ++mInputBufferCount; 514bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 515bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 516bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 517bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianvoid SoftOpus::onPortFlushCompleted(OMX_U32 portIndex) { 518bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (portIndex == 0 && mDecoder != NULL) { 519bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // Make sure that the next buffer output does not still 520bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian // depend on fragments from the last one decoded. 521bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mNumFramesOutput = 0; 522bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian opus_multistream_decoder_ctl(mDecoder, OPUS_RESET_STATE); 523bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mAnchorTimeUs = 0; 524bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mSamplesToDiscard = mSeekPreRoll; 525bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 526bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 527bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 528bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianvoid SoftOpus::onReset() { 529bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mInputBufferCount = 0; 530bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mNumFramesOutput = 0; 531bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (mDecoder != NULL) { 532bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian opus_multistream_decoder_destroy(mDecoder); 533bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mDecoder = NULL; 534bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 535bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (mHeader != NULL) { 536bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian delete mHeader; 537bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mHeader = NULL; 538bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 539bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 540bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mOutputPortSettingsChange = NONE; 541bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 542bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 543bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianvoid SoftOpus::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { 544bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian if (portIndex != 1) { 545bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return; 546bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 547bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 548bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian switch (mOutputPortSettingsChange) { 549bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian case NONE: 550bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian break; 551bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 552bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian case AWAITING_DISABLED: 553bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian { 554bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian CHECK(!enabled); 555bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mOutputPortSettingsChange = AWAITING_ENABLED; 556bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian break; 557bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 558bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 559bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian default: 560bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian { 561bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); 562bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian CHECK(enabled); 563bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian mOutputPortSettingsChange = NONE; 564bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian break; 565bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 566bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } 567bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 568bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 569bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} // namespace android 570bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 571bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanianandroid::SoftOMXComponent *createSoftOMXComponent( 572bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian const char *name, const OMX_CALLBACKTYPE *callbacks, 573bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian OMX_PTR appData, OMX_COMPONENTTYPE **component) { 574bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian return new android::SoftOpus(name, callbacks, appData, component); 575bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian} 576