Home | History | Annotate | Download | only in dec
      1 /*
      2  * Copyright (C) 2014 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 "SoftOpus"
     19 #include <utils/Log.h>
     20 
     21 #include "SoftOpus.h"
     22 #include <OMX_AudioExt.h>
     23 #include <OMX_IndexExt.h>
     24 
     25 #include <media/stagefright/foundation/ADebug.h>
     26 #include <media/stagefright/MediaDefs.h>
     27 
     28 extern "C" {
     29     #include <opus.h>
     30     #include <opus_multistream.h>
     31 }
     32 
     33 namespace android {
     34 
     35 static const int kRate = 48000;
     36 
     37 // Opus uses Vorbis channel mapping, and Vorbis channel mapping specifies
     38 // mappings for up to 8 channels. This information is part of the Vorbis I
     39 // Specification:
     40 // http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html
     41 static const int kMaxChannels = 8;
     42 
     43 template<class T>
     44 static void InitOMXParams(T *params) {
     45     params->nSize = sizeof(T);
     46     params->nVersion.s.nVersionMajor = 1;
     47     params->nVersion.s.nVersionMinor = 0;
     48     params->nVersion.s.nRevision = 0;
     49     params->nVersion.s.nStep = 0;
     50 }
     51 
     52 SoftOpus::SoftOpus(
     53         const char *name,
     54         const OMX_CALLBACKTYPE *callbacks,
     55         OMX_PTR appData,
     56         OMX_COMPONENTTYPE **component)
     57     : SimpleSoftOMXComponent(name, callbacks, appData, component),
     58       mInputBufferCount(0),
     59       mDecoder(NULL),
     60       mHeader(NULL),
     61       mCodecDelay(0),
     62       mSeekPreRoll(0),
     63       mAnchorTimeUs(0),
     64       mNumFramesOutput(0),
     65       mOutputPortSettingsChange(NONE) {
     66     initPorts();
     67     CHECK_EQ(initDecoder(), (status_t)OK);
     68 }
     69 
     70 SoftOpus::~SoftOpus() {
     71     if (mDecoder != NULL) {
     72         opus_multistream_decoder_destroy(mDecoder);
     73         mDecoder = NULL;
     74     }
     75     if (mHeader != NULL) {
     76         delete mHeader;
     77         mHeader = NULL;
     78     }
     79 }
     80 
     81 void SoftOpus::initPorts() {
     82     OMX_PARAM_PORTDEFINITIONTYPE def;
     83     InitOMXParams(&def);
     84 
     85     def.nPortIndex = 0;
     86     def.eDir = OMX_DirInput;
     87     def.nBufferCountMin = kNumBuffers;
     88     def.nBufferCountActual = def.nBufferCountMin;
     89     def.nBufferSize = 960 * 6;
     90     def.bEnabled = OMX_TRUE;
     91     def.bPopulated = OMX_FALSE;
     92     def.eDomain = OMX_PortDomainAudio;
     93     def.bBuffersContiguous = OMX_FALSE;
     94     def.nBufferAlignment = 1;
     95 
     96     def.format.audio.cMIMEType =
     97         const_cast<char *>(MEDIA_MIMETYPE_AUDIO_OPUS);
     98 
     99     def.format.audio.pNativeRender = NULL;
    100     def.format.audio.bFlagErrorConcealment = OMX_FALSE;
    101     def.format.audio.eEncoding =
    102         (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidOPUS;
    103 
    104     addPort(def);
    105 
    106     def.nPortIndex = 1;
    107     def.eDir = OMX_DirOutput;
    108     def.nBufferCountMin = kNumBuffers;
    109     def.nBufferCountActual = def.nBufferCountMin;
    110     def.nBufferSize = kMaxNumSamplesPerBuffer * sizeof(int16_t) * kMaxChannels;
    111     def.bEnabled = OMX_TRUE;
    112     def.bPopulated = OMX_FALSE;
    113     def.eDomain = OMX_PortDomainAudio;
    114     def.bBuffersContiguous = OMX_FALSE;
    115     def.nBufferAlignment = 2;
    116 
    117     def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
    118     def.format.audio.pNativeRender = NULL;
    119     def.format.audio.bFlagErrorConcealment = OMX_FALSE;
    120     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
    121 
    122     addPort(def);
    123 }
    124 
    125 status_t SoftOpus::initDecoder() {
    126     return OK;
    127 }
    128 
    129 OMX_ERRORTYPE SoftOpus::internalGetParameter(
    130         OMX_INDEXTYPE index, OMX_PTR params) {
    131     switch ((int)index) {
    132         case OMX_IndexParamAudioAndroidOpus:
    133         {
    134             OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *opusParams =
    135                 (OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *)params;
    136 
    137             if (opusParams->nPortIndex != 0) {
    138                 return OMX_ErrorUndefined;
    139             }
    140 
    141             opusParams->nAudioBandWidth = 0;
    142             opusParams->nSampleRate = kRate;
    143             opusParams->nBitRate = 0;
    144 
    145             if (!isConfigured()) {
    146                 opusParams->nChannels = 1;
    147             } else {
    148                 opusParams->nChannels = mHeader->channels;
    149             }
    150 
    151             return OMX_ErrorNone;
    152         }
    153 
    154         case OMX_IndexParamAudioPcm:
    155         {
    156             OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
    157                 (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
    158 
    159             if (pcmParams->nPortIndex != 1) {
    160                 return OMX_ErrorUndefined;
    161             }
    162 
    163             pcmParams->eNumData = OMX_NumericalDataSigned;
    164             pcmParams->eEndian = OMX_EndianBig;
    165             pcmParams->bInterleaved = OMX_TRUE;
    166             pcmParams->nBitPerSample = 16;
    167             pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
    168             pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
    169             pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
    170             pcmParams->nSamplingRate = kRate;
    171 
    172             if (!isConfigured()) {
    173                 pcmParams->nChannels = 1;
    174             } else {
    175                 pcmParams->nChannels = mHeader->channels;
    176             }
    177 
    178             return OMX_ErrorNone;
    179         }
    180 
    181         default:
    182             return SimpleSoftOMXComponent::internalGetParameter(index, params);
    183     }
    184 }
    185 
    186 OMX_ERRORTYPE SoftOpus::internalSetParameter(
    187         OMX_INDEXTYPE index, const OMX_PTR params) {
    188     switch ((int)index) {
    189         case OMX_IndexParamStandardComponentRole:
    190         {
    191             const OMX_PARAM_COMPONENTROLETYPE *roleParams =
    192                 (const OMX_PARAM_COMPONENTROLETYPE *)params;
    193 
    194             if (strncmp((const char *)roleParams->cRole,
    195                         "audio_decoder.opus",
    196                         OMX_MAX_STRINGNAME_SIZE - 1)) {
    197                 return OMX_ErrorUndefined;
    198             }
    199 
    200             return OMX_ErrorNone;
    201         }
    202 
    203         case OMX_IndexParamAudioAndroidOpus:
    204         {
    205             const OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *opusParams =
    206                 (const OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *)params;
    207 
    208             if (opusParams->nPortIndex != 0) {
    209                 return OMX_ErrorUndefined;
    210             }
    211 
    212             return OMX_ErrorNone;
    213         }
    214 
    215         default:
    216             return SimpleSoftOMXComponent::internalSetParameter(index, params);
    217     }
    218 }
    219 
    220 bool SoftOpus::isConfigured() const {
    221     return mInputBufferCount >= 1;
    222 }
    223 
    224 static uint16_t ReadLE16(const uint8_t *data, size_t data_size,
    225                          uint32_t read_offset) {
    226     if (read_offset + 1 > data_size)
    227         return 0;
    228     uint16_t val;
    229     val = data[read_offset];
    230     val |= data[read_offset + 1] << 8;
    231     return val;
    232 }
    233 
    234 // Maximum packet size used in Xiph's opusdec.
    235 static const int kMaxOpusOutputPacketSizeSamples = 960 * 6;
    236 
    237 // Default audio output channel layout. Used to initialize |stream_map| in
    238 // OpusHeader, and passed to opus_multistream_decoder_create() when the header
    239 // does not contain mapping information. The values are valid only for mono and
    240 // stereo output: Opus streams with more than 2 channels require a stream map.
    241 static const int kMaxChannelsWithDefaultLayout = 2;
    242 static const uint8_t kDefaultOpusChannelLayout[kMaxChannelsWithDefaultLayout] = { 0, 1 };
    243 
    244 // Parses Opus Header. Header spec: http://wiki.xiph.org/OggOpus#ID_Header
    245 static bool ParseOpusHeader(const uint8_t *data, size_t data_size,
    246                             OpusHeader* header) {
    247     // Size of the Opus header excluding optional mapping information.
    248     const size_t kOpusHeaderSize = 19;
    249 
    250     // Offset to the channel count byte in the Opus header.
    251     const size_t kOpusHeaderChannelsOffset = 9;
    252 
    253     // Offset to the pre-skip value in the Opus header.
    254     const size_t kOpusHeaderSkipSamplesOffset = 10;
    255 
    256     // Offset to the gain value in the Opus header.
    257     const size_t kOpusHeaderGainOffset = 16;
    258 
    259     // Offset to the channel mapping byte in the Opus header.
    260     const size_t kOpusHeaderChannelMappingOffset = 18;
    261 
    262     // Opus Header contains a stream map. The mapping values are in the header
    263     // beyond the always present |kOpusHeaderSize| bytes of data. The mapping
    264     // data contains stream count, coupling information, and per channel mapping
    265     // values:
    266     //   - Byte 0: Number of streams.
    267     //   - Byte 1: Number coupled.
    268     //   - Byte 2: Starting at byte 2 are |header->channels| uint8 mapping
    269     //             values.
    270     const size_t kOpusHeaderNumStreamsOffset = kOpusHeaderSize;
    271     const size_t kOpusHeaderNumCoupledOffset = kOpusHeaderNumStreamsOffset + 1;
    272     const size_t kOpusHeaderStreamMapOffset = kOpusHeaderNumStreamsOffset + 2;
    273 
    274     if (data_size < kOpusHeaderSize) {
    275         ALOGV("Header size is too small.");
    276         return false;
    277     }
    278     header->channels = *(data + kOpusHeaderChannelsOffset);
    279 
    280     if (header->channels <= 0 || header->channels > kMaxChannels) {
    281         ALOGV("Invalid Header, wrong channel count: %d", header->channels);
    282         return false;
    283     }
    284     header->skip_samples = ReadLE16(data, data_size,
    285                                         kOpusHeaderSkipSamplesOffset);
    286     header->gain_db = static_cast<int16_t>(
    287                               ReadLE16(data, data_size,
    288                                        kOpusHeaderGainOffset));
    289     header->channel_mapping = *(data + kOpusHeaderChannelMappingOffset);
    290     if (!header->channel_mapping) {
    291         if (header->channels > kMaxChannelsWithDefaultLayout) {
    292             ALOGV("Invalid Header, missing stream map.");
    293             return false;
    294         }
    295         header->num_streams = 1;
    296         header->num_coupled = header->channels > 1;
    297         header->stream_map[0] = 0;
    298         header->stream_map[1] = 1;
    299         return true;
    300     }
    301     if (data_size < kOpusHeaderStreamMapOffset + header->channels) {
    302         ALOGV("Invalid stream map; insufficient data for current channel "
    303               "count: %d", header->channels);
    304         return false;
    305     }
    306     header->num_streams = *(data + kOpusHeaderNumStreamsOffset);
    307     header->num_coupled = *(data + kOpusHeaderNumCoupledOffset);
    308     if (header->num_streams + header->num_coupled != header->channels) {
    309         ALOGV("Inconsistent channel mapping.");
    310         return false;
    311     }
    312     for (int i = 0; i < header->channels; ++i)
    313       header->stream_map[i] = *(data + kOpusHeaderStreamMapOffset + i);
    314     return true;
    315 }
    316 
    317 // Convert nanoseconds to number of samples.
    318 static uint64_t ns_to_samples(uint64_t ns, int kRate) {
    319     return static_cast<double>(ns) * kRate / 1000000000;
    320 }
    321 
    322 void SoftOpus::onQueueFilled(OMX_U32 portIndex) {
    323     List<BufferInfo *> &inQueue = getPortQueue(0);
    324     List<BufferInfo *> &outQueue = getPortQueue(1);
    325 
    326     if (mOutputPortSettingsChange != NONE) {
    327         return;
    328     }
    329 
    330     if (portIndex == 0 && mInputBufferCount < 3) {
    331         BufferInfo *info = *inQueue.begin();
    332         OMX_BUFFERHEADERTYPE *header = info->mHeader;
    333 
    334         const uint8_t *data = header->pBuffer + header->nOffset;
    335         size_t size = header->nFilledLen;
    336 
    337         if (mInputBufferCount == 0) {
    338             CHECK(mHeader == NULL);
    339             mHeader = new OpusHeader();
    340             memset(mHeader, 0, sizeof(*mHeader));
    341             if (!ParseOpusHeader(data, size, mHeader)) {
    342                 ALOGV("Parsing Opus Header failed.");
    343                 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
    344                 return;
    345             }
    346 
    347             uint8_t channel_mapping[kMaxChannels] = {0};
    348             if (mHeader->channels <= kMaxChannelsWithDefaultLayout) {
    349                 memcpy(&channel_mapping,
    350                        kDefaultOpusChannelLayout,
    351                        kMaxChannelsWithDefaultLayout);
    352             } else {
    353                 memcpy(&channel_mapping,
    354                        mHeader->stream_map,
    355                        mHeader->channels);
    356             }
    357 
    358             int status = OPUS_INVALID_STATE;
    359             mDecoder = opus_multistream_decoder_create(kRate,
    360                                                        mHeader->channels,
    361                                                        mHeader->num_streams,
    362                                                        mHeader->num_coupled,
    363                                                        channel_mapping,
    364                                                        &status);
    365             if (!mDecoder || status != OPUS_OK) {
    366                 ALOGV("opus_multistream_decoder_create failed status=%s",
    367                       opus_strerror(status));
    368                 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
    369                 return;
    370             }
    371             status =
    372                 opus_multistream_decoder_ctl(mDecoder,
    373                                              OPUS_SET_GAIN(mHeader->gain_db));
    374             if (status != OPUS_OK) {
    375                 ALOGV("Failed to set OPUS header gain; status=%s",
    376                       opus_strerror(status));
    377                 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
    378                 return;
    379             }
    380         } else if (mInputBufferCount == 1) {
    381             mCodecDelay = ns_to_samples(
    382                               *(reinterpret_cast<int64_t*>(header->pBuffer +
    383                                                            header->nOffset)),
    384                               kRate);
    385             mSamplesToDiscard = mCodecDelay;
    386         } else {
    387             mSeekPreRoll = ns_to_samples(
    388                                *(reinterpret_cast<int64_t*>(header->pBuffer +
    389                                                             header->nOffset)),
    390                                kRate);
    391             notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
    392             mOutputPortSettingsChange = AWAITING_DISABLED;
    393         }
    394 
    395         inQueue.erase(inQueue.begin());
    396         info->mOwnedByUs = false;
    397         notifyEmptyBufferDone(header);
    398         ++mInputBufferCount;
    399         return;
    400     }
    401 
    402     while (!inQueue.empty() && !outQueue.empty()) {
    403         BufferInfo *inInfo = *inQueue.begin();
    404         OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
    405 
    406         // Ignore CSD re-submissions.
    407         if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
    408             inQueue.erase(inQueue.begin());
    409             inInfo->mOwnedByUs = false;
    410             notifyEmptyBufferDone(inHeader);
    411             return;
    412         }
    413 
    414         BufferInfo *outInfo = *outQueue.begin();
    415         OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
    416 
    417         if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
    418             inQueue.erase(inQueue.begin());
    419             inInfo->mOwnedByUs = false;
    420             notifyEmptyBufferDone(inHeader);
    421 
    422             outHeader->nFilledLen = 0;
    423             outHeader->nFlags = OMX_BUFFERFLAG_EOS;
    424 
    425             outQueue.erase(outQueue.begin());
    426             outInfo->mOwnedByUs = false;
    427             notifyFillBufferDone(outHeader);
    428             return;
    429         }
    430 
    431         if (inHeader->nOffset == 0) {
    432             mAnchorTimeUs = inHeader->nTimeStamp;
    433             mNumFramesOutput = 0;
    434         }
    435 
    436         // When seeking to zero, |mCodecDelay| samples has to be discarded
    437         // instead of |mSeekPreRoll| samples (as we would when seeking to any
    438         // other timestamp).
    439         if (inHeader->nTimeStamp == 0) {
    440             mSamplesToDiscard = mCodecDelay;
    441         }
    442 
    443         const uint8_t *data = inHeader->pBuffer + inHeader->nOffset;
    444         const uint32_t size = inHeader->nFilledLen;
    445 
    446         int numFrames = opus_multistream_decode(mDecoder,
    447                                                 data,
    448                                                 size,
    449                                                 (int16_t *)outHeader->pBuffer,
    450                                                 kMaxOpusOutputPacketSizeSamples,
    451                                                 0);
    452         if (numFrames < 0) {
    453             ALOGE("opus_multistream_decode returned %d", numFrames);
    454             notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
    455             return;
    456         }
    457 
    458         outHeader->nOffset = 0;
    459         if (mSamplesToDiscard > 0) {
    460             if (mSamplesToDiscard > numFrames) {
    461                 mSamplesToDiscard -= numFrames;
    462                 numFrames = 0;
    463             } else {
    464                 numFrames -= mSamplesToDiscard;
    465                 outHeader->nOffset = mSamplesToDiscard * sizeof(int16_t) *
    466                                      mHeader->channels;
    467                 mSamplesToDiscard = 0;
    468             }
    469         }
    470 
    471         outHeader->nFilledLen = numFrames * sizeof(int16_t) * mHeader->channels;
    472         outHeader->nFlags = 0;
    473 
    474         outHeader->nTimeStamp = mAnchorTimeUs +
    475                                 (mNumFramesOutput * 1000000ll) /
    476                                 kRate;
    477 
    478         mNumFramesOutput += numFrames;
    479 
    480         inInfo->mOwnedByUs = false;
    481         inQueue.erase(inQueue.begin());
    482         inInfo = NULL;
    483         notifyEmptyBufferDone(inHeader);
    484         inHeader = NULL;
    485 
    486         outInfo->mOwnedByUs = false;
    487         outQueue.erase(outQueue.begin());
    488         outInfo = NULL;
    489         notifyFillBufferDone(outHeader);
    490         outHeader = NULL;
    491 
    492         ++mInputBufferCount;
    493     }
    494 }
    495 
    496 void SoftOpus::onPortFlushCompleted(OMX_U32 portIndex) {
    497     if (portIndex == 0 && mDecoder != NULL) {
    498         // Make sure that the next buffer output does not still
    499         // depend on fragments from the last one decoded.
    500         mNumFramesOutput = 0;
    501         opus_multistream_decoder_ctl(mDecoder, OPUS_RESET_STATE);
    502         mAnchorTimeUs = 0;
    503         mSamplesToDiscard = mSeekPreRoll;
    504     }
    505 }
    506 
    507 void SoftOpus::onReset() {
    508     mInputBufferCount = 0;
    509     mNumFramesOutput = 0;
    510     if (mDecoder != NULL) {
    511         opus_multistream_decoder_destroy(mDecoder);
    512         mDecoder = NULL;
    513     }
    514     if (mHeader != NULL) {
    515         delete mHeader;
    516         mHeader = NULL;
    517     }
    518 
    519     mOutputPortSettingsChange = NONE;
    520 }
    521 
    522 void SoftOpus::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
    523     if (portIndex != 1) {
    524         return;
    525     }
    526 
    527     switch (mOutputPortSettingsChange) {
    528         case NONE:
    529             break;
    530 
    531         case AWAITING_DISABLED:
    532         {
    533             CHECK(!enabled);
    534             mOutputPortSettingsChange = AWAITING_ENABLED;
    535             break;
    536         }
    537 
    538         default:
    539         {
    540             CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
    541             CHECK(enabled);
    542             mOutputPortSettingsChange = NONE;
    543             break;
    544         }
    545     }
    546 }
    547 
    548 }  // namespace android
    549 
    550 android::SoftOMXComponent *createSoftOMXComponent(
    551         const char *name, const OMX_CALLBACKTYPE *callbacks,
    552         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
    553     return new android::SoftOpus(name, callbacks, appData, component);
    554 }
    555