Home | History | Annotate | Download | only in raw
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "SoftRaw"
     19 #include <utils/Log.h>
     20 
     21 #include "SoftRaw.h"
     22 
     23 #include <media/stagefright/foundation/ADebug.h>
     24 #include <media/stagefright/foundation/hexdump.h>
     25 
     26 namespace android {
     27 
     28 template<class T>
     29 static void InitOMXParams(T *params) {
     30     params->nSize = sizeof(T);
     31     params->nVersion.s.nVersionMajor = 1;
     32     params->nVersion.s.nVersionMinor = 0;
     33     params->nVersion.s.nRevision = 0;
     34     params->nVersion.s.nStep = 0;
     35 }
     36 
     37 SoftRaw::SoftRaw(
     38         const char *name,
     39         const OMX_CALLBACKTYPE *callbacks,
     40         OMX_PTR appData,
     41         OMX_COMPONENTTYPE **component)
     42     : SimpleSoftOMXComponent(name, callbacks, appData, component),
     43       mSignalledError(false),
     44       mChannelCount(2),
     45       mSampleRate(44100) {
     46     initPorts();
     47     CHECK_EQ(initDecoder(), (status_t)OK);
     48 }
     49 
     50 SoftRaw::~SoftRaw() {
     51 }
     52 
     53 void SoftRaw::initPorts() {
     54     OMX_PARAM_PORTDEFINITIONTYPE def;
     55     InitOMXParams(&def);
     56 
     57     def.nPortIndex = 0;
     58     def.eDir = OMX_DirInput;
     59     def.nBufferCountMin = kNumBuffers;
     60     def.nBufferCountActual = def.nBufferCountMin;
     61     def.nBufferSize = 32 * 1024;
     62     def.bEnabled = OMX_TRUE;
     63     def.bPopulated = OMX_FALSE;
     64     def.eDomain = OMX_PortDomainAudio;
     65     def.bBuffersContiguous = OMX_FALSE;
     66     def.nBufferAlignment = 1;
     67 
     68     def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
     69     def.format.audio.pNativeRender = NULL;
     70     def.format.audio.bFlagErrorConcealment = OMX_FALSE;
     71     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
     72 
     73     addPort(def);
     74 
     75     def.nPortIndex = 1;
     76     def.eDir = OMX_DirOutput;
     77     def.nBufferCountMin = kNumBuffers;
     78     def.nBufferCountActual = def.nBufferCountMin;
     79     def.nBufferSize = 32 * 1024;
     80     def.bEnabled = OMX_TRUE;
     81     def.bPopulated = OMX_FALSE;
     82     def.eDomain = OMX_PortDomainAudio;
     83     def.bBuffersContiguous = OMX_FALSE;
     84     def.nBufferAlignment = 2;
     85 
     86     def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
     87     def.format.audio.pNativeRender = NULL;
     88     def.format.audio.bFlagErrorConcealment = OMX_FALSE;
     89     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
     90 
     91     addPort(def);
     92 }
     93 
     94 status_t SoftRaw::initDecoder() {
     95     return OK;
     96 }
     97 
     98 OMX_ERRORTYPE SoftRaw::internalGetParameter(
     99         OMX_INDEXTYPE index, OMX_PTR params) {
    100     switch (index) {
    101         case OMX_IndexParamAudioPcm:
    102         {
    103             OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
    104                 (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
    105 
    106             if (pcmParams->nPortIndex != 0 && pcmParams->nPortIndex != 1) {
    107                 return OMX_ErrorUndefined;
    108             }
    109 
    110             pcmParams->eNumData = OMX_NumericalDataSigned;
    111             pcmParams->eEndian = OMX_EndianBig;
    112             pcmParams->bInterleaved = OMX_TRUE;
    113             pcmParams->nBitPerSample = 16;
    114             pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
    115             pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
    116             pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
    117 
    118             pcmParams->nChannels = mChannelCount;
    119             pcmParams->nSamplingRate = mSampleRate;
    120 
    121             return OMX_ErrorNone;
    122         }
    123 
    124         default:
    125             return SimpleSoftOMXComponent::internalGetParameter(index, params);
    126     }
    127 }
    128 
    129 OMX_ERRORTYPE SoftRaw::internalSetParameter(
    130         OMX_INDEXTYPE index, const OMX_PTR params) {
    131     switch (index) {
    132         case OMX_IndexParamStandardComponentRole:
    133         {
    134             const OMX_PARAM_COMPONENTROLETYPE *roleParams =
    135                 (const OMX_PARAM_COMPONENTROLETYPE *)params;
    136 
    137             if (strncmp((const char *)roleParams->cRole,
    138                         "audio_decoder.raw",
    139                         OMX_MAX_STRINGNAME_SIZE - 1)) {
    140                 return OMX_ErrorUndefined;
    141             }
    142 
    143             return OMX_ErrorNone;
    144         }
    145 
    146         case OMX_IndexParamAudioPcm:
    147         {
    148             const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
    149                 (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
    150 
    151             if (pcmParams->nPortIndex != 0) {
    152                 return OMX_ErrorUndefined;
    153             }
    154 
    155             mChannelCount = pcmParams->nChannels;
    156             mSampleRate = pcmParams->nSamplingRate;
    157 
    158             return OMX_ErrorNone;
    159         }
    160 
    161         default:
    162             return SimpleSoftOMXComponent::internalSetParameter(index, params);
    163     }
    164 }
    165 
    166 void SoftRaw::onQueueFilled(OMX_U32 portIndex) {
    167     if (mSignalledError) {
    168         return;
    169     }
    170 
    171     List<BufferInfo *> &inQueue = getPortQueue(0);
    172     List<BufferInfo *> &outQueue = getPortQueue(1);
    173 
    174     while (!inQueue.empty() && !outQueue.empty()) {
    175         BufferInfo *inInfo = *inQueue.begin();
    176         OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
    177 
    178         BufferInfo *outInfo = *outQueue.begin();
    179         OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
    180 
    181         CHECK_GE(outHeader->nAllocLen, inHeader->nFilledLen);
    182         memcpy(outHeader->pBuffer,
    183                inHeader->pBuffer + inHeader->nOffset,
    184                inHeader->nFilledLen);
    185 
    186         outHeader->nFlags = inHeader->nFlags;
    187         outHeader->nOffset = 0;
    188         outHeader->nFilledLen = inHeader->nFilledLen;
    189         outHeader->nTimeStamp = inHeader->nTimeStamp;
    190 
    191         bool sawEOS = (inHeader->nFlags & OMX_BUFFERFLAG_EOS) != 0;
    192 
    193         inQueue.erase(inQueue.begin());
    194         inInfo->mOwnedByUs = false;
    195         notifyEmptyBufferDone(inHeader);
    196 
    197         outQueue.erase(outQueue.begin());
    198         outInfo->mOwnedByUs = false;
    199         notifyFillBufferDone(outHeader);
    200 
    201         if (sawEOS) {
    202             break;
    203         }
    204     }
    205 }
    206 
    207 }  // namespace android
    208 
    209 android::SoftOMXComponent *createSoftOMXComponent(
    210         const char *name, const OMX_CALLBACKTYPE *callbacks,
    211         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
    212     return new android::SoftRaw(name, callbacks, appData, component);
    213 }
    214