12f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi/* 22f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * Copyright (C) 2012 The Android Open Source Project 32f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * 42f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 52f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * you may not use this file except in compliance with the License. 62f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * You may obtain a copy of the License at 72f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * 82f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 92f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * 102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * See the License for the specific language governing permissions and 142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * limitations under the License. 152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi */ 162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi//#define LOG_NDEBUG 0 182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#define LOG_TAG "SoftFlacEncoder" 192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#include <utils/Log.h> 202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#include "SoftFlacEncoder.h" 222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#include <media/stagefright/foundation/ADebug.h> 242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#include <media/stagefright/MediaDefs.h> 252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#define FLAC_COMPRESSION_LEVEL_MIN 0 272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#define FLAC_COMPRESSION_LEVEL_DEFAULT 5 282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#define FLAC_COMPRESSION_LEVEL_MAX 8 292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 3084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#if LOG_NDEBUG 3184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED_UNLESS_VERBOSE(x) (void)(x) 3284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#else 3384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED_UNLESS_VERBOSE(x) 3484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#endif 3584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber 362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivinamespace android { 372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivitemplate<class T> 392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatic void InitOMXParams(T *params) { 402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi params->nSize = sizeof(T); 412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi params->nVersion.s.nVersionMajor = 1; 422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi params->nVersion.s.nVersionMinor = 0; 432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi params->nVersion.s.nRevision = 0; 442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi params->nVersion.s.nStep = 0; 452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} 462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel TriviSoftFlacEncoder::SoftFlacEncoder( 482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi const char *name, 492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi const OMX_CALLBACKTYPE *callbacks, 502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi OMX_PTR appData, 512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi OMX_COMPONENTTYPE **component) 522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi : SimpleSoftOMXComponent(name, callbacks, appData, component), 532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mSignalledError(false), 542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mNumChannels(1), 552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mSampleRate(44100), 562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mCompressionLevel(FLAC_COMPRESSION_LEVEL_DEFAULT), 572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mEncoderWriteData(false), 582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mEncoderReturnedEncodedData(false), 592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mEncoderReturnedNbBytes(0), 602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mInputBufferPcm32(NULL) 612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER 622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi , mHeaderOffset(0) 632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi , mWroteHeader(false) 642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#endif 652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi{ 662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGV("SoftFlacEncoder::SoftFlacEncoder(name=%s)", name); 672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi initPorts(); 682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mFlacStreamEncoder = FLAC__stream_encoder_new(); 702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (mFlacStreamEncoder == NULL) { 712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGE("SoftFlacEncoder::SoftFlacEncoder(name=%s) error instantiating FLAC encoder", name); 722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mSignalledError = true; 732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (!mSignalledError) { // no use allocating input buffer if we had an error above 762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mInputBufferPcm32 = (FLAC__int32*) malloc(sizeof(FLAC__int32) * 2 * kMaxNumSamplesPerFrame); 772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (mInputBufferPcm32 == NULL) { 782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGE("SoftFlacEncoder::SoftFlacEncoder(name=%s) error allocating internal input buffer", name); 792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mSignalledError = true; 802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} 832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel TriviSoftFlacEncoder::~SoftFlacEncoder() { 852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGV("SoftFlacEncoder::~SoftFlacEncoder()"); 862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (mFlacStreamEncoder != NULL) { 872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi FLAC__stream_encoder_delete(mFlacStreamEncoder); 882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mFlacStreamEncoder = NULL; 892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi free(mInputBufferPcm32); 912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mInputBufferPcm32 = NULL; 922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} 932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel TriviOMX_ERRORTYPE SoftFlacEncoder::initCheck() const { 952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (mSignalledError) { 962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (mFlacStreamEncoder == NULL) { 972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGE("initCheck() failed due to NULL encoder"); 982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } else if (mInputBufferPcm32 == NULL) { 992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGE("initCheck() failed due to error allocating internal input buffer"); 1002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 1012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return OMX_ErrorUndefined; 1022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } else { 1032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return SimpleSoftOMXComponent::initCheck(); 1042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 1052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} 1062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivivoid SoftFlacEncoder::initPorts() { 1082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGV("SoftFlacEncoder::initPorts()"); 1092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi OMX_PARAM_PORTDEFINITIONTYPE def; 1112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi InitOMXParams(&def); 1122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi // configure input port of the encoder 1142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.nPortIndex = 0; 1152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.eDir = OMX_DirInput; 1162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.nBufferCountMin = kNumBuffers;// TODO verify that 1 is enough 1172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.nBufferCountActual = def.nBufferCountMin; 118eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber def.nBufferSize = kMaxInputBufferSize; 1192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.bEnabled = OMX_TRUE; 1202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.bPopulated = OMX_FALSE; 1212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.eDomain = OMX_PortDomainAudio; 1222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.bBuffersContiguous = OMX_FALSE; 1232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.nBufferAlignment = 2; 1242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.format.audio.cMIMEType = const_cast<char *>("audio/raw"); 1262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.format.audio.pNativeRender = NULL; 1272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.format.audio.bFlagErrorConcealment = OMX_FALSE; 1282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 1292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi addPort(def); 1312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi // configure output port of the encoder 1332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.nPortIndex = 1; 1342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.eDir = OMX_DirOutput; 1352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.nBufferCountMin = kNumBuffers;// TODO verify that 1 is enough 1362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.nBufferCountActual = def.nBufferCountMin; 1372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.nBufferSize = kMaxOutputBufferSize; 1382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.bEnabled = OMX_TRUE; 1392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.bPopulated = OMX_FALSE; 1402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.eDomain = OMX_PortDomainAudio; 1412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.bBuffersContiguous = OMX_FALSE; 1422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.nBufferAlignment = 1; 1432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.format.audio.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_AUDIO_FLAC); 1452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.format.audio.pNativeRender = NULL; 1462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.format.audio.bFlagErrorConcealment = OMX_FALSE; 1472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi def.format.audio.eEncoding = OMX_AUDIO_CodingFLAC; 1482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi addPort(def); 1502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} 1512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel TriviOMX_ERRORTYPE SoftFlacEncoder::internalGetParameter( 1532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi OMX_INDEXTYPE index, OMX_PTR params) { 1542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGV("SoftFlacEncoder::internalGetParameter(index=0x%x)", index); 1552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi switch (index) { 1572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi case OMX_IndexParamAudioPcm: 1582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi { 1592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 1602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 1612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (pcmParams->nPortIndex > 1) { 1632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return OMX_ErrorUndefined; 1642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 1652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi pcmParams->eNumData = OMX_NumericalDataSigned; 1672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi pcmParams->eEndian = OMX_EndianBig; 1682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi pcmParams->bInterleaved = OMX_TRUE; 1692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi pcmParams->nBitPerSample = 16; 1702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; 1712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF; 1722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF; 1732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi pcmParams->nChannels = mNumChannels; 1752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi pcmParams->nSamplingRate = mSampleRate; 1762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return OMX_ErrorNone; 1782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 1792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi case OMX_IndexParamAudioFlac: 1812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi { 1822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi OMX_AUDIO_PARAM_FLACTYPE *flacParams = (OMX_AUDIO_PARAM_FLACTYPE *)params; 1832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi flacParams->nCompressionLevel = mCompressionLevel; 1842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi flacParams->nChannels = mNumChannels; 1852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi flacParams->nSampleRate = mSampleRate; 1862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return OMX_ErrorNone; 1872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 1882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi default: 1902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return SimpleSoftOMXComponent::internalGetParameter(index, params); 1912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 1922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} 1932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 1942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel TriviOMX_ERRORTYPE SoftFlacEncoder::internalSetParameter( 1952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi OMX_INDEXTYPE index, const OMX_PTR params) { 1962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi switch (index) { 1972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi case OMX_IndexParamAudioPcm: 1982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi { 1992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGV("SoftFlacEncoder::internalSetParameter(OMX_IndexParamAudioPcm)"); 2002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 2012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (pcmParams->nPortIndex != 0 && pcmParams->nPortIndex != 1) { 2032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGE("SoftFlacEncoder::internalSetParameter() Error #1"); 2042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return OMX_ErrorUndefined; 2052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 2062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (pcmParams->nChannels < 1 || pcmParams->nChannels > 2) { 2082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return OMX_ErrorUndefined; 2092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 2102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mNumChannels = pcmParams->nChannels; 2122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mSampleRate = pcmParams->nSamplingRate; 21366fe2e9ee30bcb4161bc487ec63d2ae4a05f4051Glenn Kasten ALOGV("will encode %d channels at %dHz", mNumChannels, mSampleRate); 2142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return configureEncoder(); 2162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 2172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi case OMX_IndexParamStandardComponentRole: 2192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi { 2202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGV("SoftFlacEncoder::internalSetParameter(OMX_IndexParamStandardComponentRole)"); 2212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi const OMX_PARAM_COMPONENTROLETYPE *roleParams = 2222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi (const OMX_PARAM_COMPONENTROLETYPE *)params; 2232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (strncmp((const char *)roleParams->cRole, 2252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi "audio_encoder.flac", 2262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi OMX_MAX_STRINGNAME_SIZE - 1)) { 2272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGE("SoftFlacEncoder::internalSetParameter(OMX_IndexParamStandardComponentRole)" 2282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi "error"); 2292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return OMX_ErrorUndefined; 2302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 2312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return OMX_ErrorNone; 2332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 2342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi case OMX_IndexParamAudioFlac: 2362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi { 2372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi // used only for setting the compression level 2382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi OMX_AUDIO_PARAM_FLACTYPE *flacParams = (OMX_AUDIO_PARAM_FLACTYPE *)params; 2392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mCompressionLevel = flacParams->nCompressionLevel; // range clamping done inside encoder 2402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return OMX_ErrorNone; 2412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 2422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 243eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber case OMX_IndexParamPortDefinition: 244eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber { 245eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber OMX_PARAM_PORTDEFINITIONTYPE *defParams = 246eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber (OMX_PARAM_PORTDEFINITIONTYPE *)params; 247eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber 248eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber if (defParams->nPortIndex == 0) { 249eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber if (defParams->nBufferSize > kMaxInputBufferSize) { 250b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGE("Input buffer size must be at most %d bytes", 251eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber kMaxInputBufferSize); 252eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber return OMX_ErrorUnsupportedSetting; 253eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber } 254eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber } 255eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber 256eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber // fall through 257eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber } 258eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber 2592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi default: 2602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGV("SoftFlacEncoder::internalSetParameter(default)"); 2612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return SimpleSoftOMXComponent::internalSetParameter(index, params); 2622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 2632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} 2642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivivoid SoftFlacEncoder::onQueueFilled(OMX_U32 portIndex) { 26684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(portIndex); 26766fe2e9ee30bcb4161bc487ec63d2ae4a05f4051Glenn Kasten ALOGV("SoftFlacEncoder::onQueueFilled(portIndex=%d)", portIndex); 2682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (mSignalledError) { 2702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return; 2712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 2722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi List<BufferInfo *> &inQueue = getPortQueue(0); 2742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi List<BufferInfo *> &outQueue = getPortQueue(1); 2752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi while (!inQueue.empty() && !outQueue.empty()) { 2772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi BufferInfo *inInfo = *inQueue.begin(); 2782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 2792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi BufferInfo *outInfo = *outQueue.begin(); 2812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 2822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 2842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi inQueue.erase(inQueue.begin()); 2852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi inInfo->mOwnedByUs = false; 2862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi notifyEmptyBufferDone(inHeader); 2872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi outHeader->nFilledLen = 0; 2892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi outHeader->nFlags = OMX_BUFFERFLAG_EOS; 2902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi outQueue.erase(outQueue.begin()); 2922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi outInfo->mOwnedByUs = false; 2932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi notifyFillBufferDone(outHeader); 2942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 2952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return; 2962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 2972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 298eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber if (inHeader->nFilledLen > kMaxInputBufferSize) { 29966fe2e9ee30bcb4161bc487ec63d2ae4a05f4051Glenn Kasten ALOGE("input buffer too large (%d).", inHeader->nFilledLen); 3002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mSignalledError = true; 3012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 3022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return; 3032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 3042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 3052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi assert(mNumChannels != 0); 3062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mEncoderWriteData = true; 3072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mEncoderReturnedEncodedData = false; 3082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mEncoderReturnedNbBytes = 0; 3092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mCurrentInputTimeStamp = inHeader->nTimeStamp; 3102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 3112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi const unsigned nbInputFrames = inHeader->nFilledLen / (2 * mNumChannels); 3122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi const unsigned nbInputSamples = inHeader->nFilledLen / 2; 3132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi const OMX_S16 * const pcm16 = reinterpret_cast<OMX_S16 *>(inHeader->pBuffer); 3142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 315eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber CHECK_LE(nbInputSamples, 2 * kMaxNumSamplesPerFrame); 3162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi for (unsigned i=0 ; i < nbInputSamples ; i++) { 3172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mInputBufferPcm32[i] = (FLAC__int32) pcm16[i]; 3182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 3192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGV(" about to encode %u samples per channel", nbInputFrames); 3202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi FLAC__bool ok = FLAC__stream_encoder_process_interleaved( 3212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mFlacStreamEncoder, 3222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mInputBufferPcm32, 3232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi nbInputFrames /*samples per channel*/ ); 3242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 3252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (ok) { 3262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (mEncoderReturnedEncodedData && (mEncoderReturnedNbBytes != 0)) { 3272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGV(" dequeueing buffer on output port after writing data"); 3282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi outInfo->mOwnedByUs = false; 3292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi outQueue.erase(outQueue.begin()); 3302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi outInfo = NULL; 3312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi notifyFillBufferDone(outHeader); 3322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi outHeader = NULL; 3332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mEncoderReturnedEncodedData = false; 3342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } else { 3352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGV(" encoder process_interleaved returned without data to write"); 3362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 3372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } else { 3382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGE(" error encountered during encoding"); 3392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mSignalledError = true; 3402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 3412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return; 3422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 3432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 3442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi inInfo->mOwnedByUs = false; 3452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi inQueue.erase(inQueue.begin()); 3462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi inInfo = NULL; 3472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi notifyEmptyBufferDone(inHeader); 3482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi inHeader = NULL; 3492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 3502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} 3512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 3522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel TriviFLAC__StreamEncoderWriteStatus SoftFlacEncoder::onEncodedFlacAvailable( 3532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi const FLAC__byte buffer[], 35484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber size_t bytes, unsigned samples, 35584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber unsigned current_frame) { 35684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(current_frame); 357b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("SoftFlacEncoder::onEncodedFlacAvailable(bytes=%zu, samples=%u, curr_frame=%u)", 3582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi bytes, samples, current_frame); 3592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 3602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER 3612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (samples == 0) { 362b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGI(" saving %zu bytes of header", bytes); 3632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi memcpy(mHeader + mHeaderOffset, buffer, bytes); 3642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mHeaderOffset += bytes;// will contain header size when finished receiving header 3652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; 3662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 3672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 3682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#endif 3692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 3702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if ((samples == 0) || !mEncoderWriteData) { 3712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi // called by the encoder because there's header data to save, but it's not the role 3722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi // of this component (unless WRITE_FLAC_HEADER_IN_FIRST_BUFFER is defined) 373b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("ignoring %zu bytes of header data (samples=%d)", bytes, samples); 3742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; 3752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 3762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 3772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi List<BufferInfo *> &outQueue = getPortQueue(1); 3782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi CHECK(!outQueue.empty()); 3792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi BufferInfo *outInfo = *outQueue.begin(); 3802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 3812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 3822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER 3832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (!mWroteHeader) { 3842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGI(" writing %d bytes of header on output port", mHeaderOffset); 3852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi memcpy(outHeader->pBuffer + outHeader->nOffset + outHeader->nFilledLen, 3862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mHeader, mHeaderOffset); 3872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi outHeader->nFilledLen += mHeaderOffset; 3882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi outHeader->nOffset += mHeaderOffset; 3892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mWroteHeader = true; 3902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 3912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#endif 3922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 3932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi // write encoded data 394b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV(" writing %zu bytes of encoded data on output port", bytes); 3952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (bytes > outHeader->nAllocLen - outHeader->nOffset - outHeader->nFilledLen) { 396b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGE(" not enough space left to write encoded data, dropping %zu bytes", bytes); 3972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi // a fatal error would stop the encoding 3982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; 3992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 4002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi memcpy(outHeader->pBuffer + outHeader->nOffset, buffer, bytes); 4012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 4022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi outHeader->nTimeStamp = mCurrentInputTimeStamp; 4032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi outHeader->nOffset = 0; 4042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi outHeader->nFilledLen += bytes; 4052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi outHeader->nFlags = 0; 4062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 4072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mEncoderReturnedEncodedData = true; 4082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mEncoderReturnedNbBytes += bytes; 4092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 4102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; 4112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} 4122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 4132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 4142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel TriviOMX_ERRORTYPE SoftFlacEncoder::configureEncoder() { 41566fe2e9ee30bcb4161bc487ec63d2ae4a05f4051Glenn Kasten ALOGV("SoftFlacEncoder::configureEncoder() numChannel=%d, sampleRate=%d", 4162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi mNumChannels, mSampleRate); 4172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 4182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (mSignalledError || (mFlacStreamEncoder == NULL)) { 4192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGE("can't configure encoder: no encoder or invalid state"); 4202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return OMX_ErrorInvalidState; 4212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 4222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 4232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi FLAC__bool ok = true; 4242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi FLAC__StreamEncoderInitStatus initStatus = FLAC__STREAM_ENCODER_INIT_STATUS_OK; 4252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ok = ok && FLAC__stream_encoder_set_channels(mFlacStreamEncoder, mNumChannels); 4262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ok = ok && FLAC__stream_encoder_set_sample_rate(mFlacStreamEncoder, mSampleRate); 4272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ok = ok && FLAC__stream_encoder_set_bits_per_sample(mFlacStreamEncoder, 16); 4282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ok = ok && FLAC__stream_encoder_set_compression_level(mFlacStreamEncoder, 4292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi (unsigned)mCompressionLevel); 4302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ok = ok && FLAC__stream_encoder_set_verify(mFlacStreamEncoder, false); 4312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (!ok) { goto return_result; } 4322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 4332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ok &= FLAC__STREAM_ENCODER_INIT_STATUS_OK == 4342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi FLAC__stream_encoder_init_stream(mFlacStreamEncoder, 4352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi flacEncoderWriteCallback /*write_callback*/, 4362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi NULL /*seek_callback*/, 4372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi NULL /*tell_callback*/, 4382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi NULL /*metadata_callback*/, 4392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi (void *) this /*client_data*/); 4402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 4412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivireturn_result: 4422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi if (ok) { 4432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGV("encoder successfully configured"); 4442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return OMX_ErrorNone; 4452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } else { 4462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi ALOGE("unknown error when configuring encoder"); 4472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return OMX_ErrorUndefined; 4482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi } 4492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} 4502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 4512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 4522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi// static 4532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel TriviFLAC__StreamEncoderWriteStatus SoftFlacEncoder::flacEncoderWriteCallback( 45484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber const FLAC__StreamEncoder * /* encoder */, 45584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber const FLAC__byte buffer[], 45684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber size_t bytes, 45784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber unsigned samples, 45884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber unsigned current_frame, 45984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber void *client_data) { 4602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return ((SoftFlacEncoder*) client_data)->onEncodedFlacAvailable( 4612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi buffer, bytes, samples, current_frame); 4622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} 4632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 4642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} // namespace android 4652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 4662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 4672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Triviandroid::SoftOMXComponent *createSoftOMXComponent( 4682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi const char *name, const OMX_CALLBACKTYPE *callbacks, 4692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi OMX_PTR appData, OMX_COMPONENTTYPE **component) { 4702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi return new android::SoftFlacEncoder(name, callbacks, appData, component); 4712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi} 4722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi 473