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 template<class T>
     38 static void InitOMXParams(T *params) {
     39     params->nSize = sizeof(T);
     40     params->nVersion.s.nVersionMajor = 1;
     41     params->nVersion.s.nVersionMinor = 0;
     42     params->nVersion.s.nRevision = 0;
     43     params->nVersion.s.nStep = 0;
     44 }
     45 
     46 SoftOpus::SoftOpus(
     47         const char *name,
     48         const OMX_CALLBACKTYPE *callbacks,
     49         OMX_PTR appData,
     50         OMX_COMPONENTTYPE **component)
     51     : SimpleSoftOMXComponent(name, callbacks, appData, component),
     52       mInputBufferCount(0),
     53       mDecoder(NULL),
     54       mHeader(NULL),
     55       mCodecDelay(0),
     56       mSeekPreRoll(0),
     57       mAnchorTimeUs(0),
     58       mNumFramesOutput(0),
     59       mOutputPortSettingsChange(NONE) {
     60     initPorts();
     61     CHECK_EQ(initDecoder(), (status_t)OK);
     62 }
     63 
     64 SoftOpus::~SoftOpus() {
     65     if (mDecoder != NULL) {
     66         opus_multistream_decoder_destroy(mDecoder);
     67         mDecoder = NULL;
     68     }
     69     if (mHeader != NULL) {
     70         delete mHeader;
     71         mHeader = NULL;
     72     }
     73 }
     74 
     75 void SoftOpus::initPorts() {
     76     OMX_PARAM_PORTDEFINITIONTYPE def;
     77     InitOMXParams(&def);
     78 
     79     def.nPortIndex = 0;
     80     def.eDir = OMX_DirInput;
     81     def.nBufferCountMin = kNumBuffers;
     82     def.nBufferCountActual = def.nBufferCountMin;
     83     def.nBufferSize = 960 * 6;
     84     def.bEnabled = OMX_TRUE;
     85     def.bPopulated = OMX_FALSE;
     86     def.eDomain = OMX_PortDomainAudio;
     87     def.bBuffersContiguous = OMX_FALSE;
     88     def.nBufferAlignment = 1;
     89 
     90     def.format.audio.cMIMEType =
     91         const_cast<char *>(MEDIA_MIMETYPE_AUDIO_OPUS);
     92 
     93     def.format.audio.pNativeRender = NULL;
     94     def.format.audio.bFlagErrorConcealment = OMX_FALSE;
     95     def.format.audio.eEncoding =
     96         (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidOPUS;
     97 
     98     addPort(def);
     99 
    100     def.nPortIndex = 1;
    101     def.eDir = OMX_DirOutput;
    102     def.nBufferCountMin = kNumBuffers;
    103     def.nBufferCountActual = def.nBufferCountMin;
    104     def.nBufferSize = kMaxNumSamplesPerBuffer * sizeof(int16_t);
    105     def.bEnabled = OMX_TRUE;
    106     def.bPopulated = OMX_FALSE;
    107     def.eDomain = OMX_PortDomainAudio;
    108     def.bBuffersContiguous = OMX_FALSE;
    109     def.nBufferAlignment = 2;
    110 
    111     def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
    112     def.format.audio.pNativeRender = NULL;
    113     def.format.audio.bFlagErrorConcealment = OMX_FALSE;
    114     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
    115 
    116     addPort(def);
    117 }
    118 
    119 status_t SoftOpus::initDecoder() {
    120     return OK;
    121 }
    122 
    123 OMX_ERRORTYPE SoftOpus::internalGetParameter(
    124         OMX_INDEXTYPE index, OMX_PTR params) {
    125     switch ((int)index) {
    126         case OMX_IndexParamAudioAndroidOpus:
    127         {
    128             OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *opusParams =
    129                 (OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *)params;
    130 
    131             if (opusParams->nPortIndex != 0) {
    132                 return OMX_ErrorUndefined;
    133             }
    134 
    135             opusParams->nAudioBandWidth = 0;
    136             opusParams->nSampleRate = kRate;
    137             opusParams->nBitRate = 0;
    138 
    139             if (!isConfigured()) {
    140                 opusParams->nChannels = 1;
    141             } else {
    142                 opusParams->nChannels = mHeader->channels;
    143             }
    144 
    145             return OMX_ErrorNone;
    146         }
    147 
    148         case OMX_IndexParamAudioPcm:
    149         {
    150             OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
    151                 (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
    152 
    153             if (pcmParams->nPortIndex != 1) {
    154                 return OMX_ErrorUndefined;
    155             }
    156 
    157             pcmParams->eNumData = OMX_NumericalDataSigned;
    158             pcmParams->eEndian = OMX_EndianBig;
    159             pcmParams->bInterleaved = OMX_TRUE;
    160             pcmParams->nBitPerSample = 16;
    161             pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
    162             pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
    163             pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
    164             pcmParams->nSamplingRate = kRate;
    165 
    166             if (!isConfigured()) {
    167                 pcmParams->nChannels = 1;
    168             } else {
    169                 pcmParams->nChannels = mHeader->channels;
    170             }
    171 
    172             return OMX_ErrorNone;
    173         }
    174 
    175         default:
    176             return SimpleSoftOMXComponent::internalGetParameter(index, params);
    177     }
    178 }
    179 
    180 OMX_ERRORTYPE SoftOpus::internalSetParameter(
    181         OMX_INDEXTYPE index, const OMX_PTR params) {
    182     switch ((int)index) {
    183         case OMX_IndexParamStandardComponentRole:
    184         {
    185             const OMX_PARAM_COMPONENTROLETYPE *roleParams =
    186                 (const OMX_PARAM_COMPONENTROLETYPE *)params;
    187 
    188             if (strncmp((const char *)roleParams->cRole,
    189                         "audio_decoder.opus",
    190                         OMX_MAX_STRINGNAME_SIZE - 1)) {
    191                 return OMX_ErrorUndefined;
    192             }
    193 
    194             return OMX_ErrorNone;
    195         }
    196 
    197         case OMX_IndexParamAudioAndroidOpus:
    198         {
    199             const OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *opusParams =
    200                 (const OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *)params;
    201 
    202             if (opusParams->nPortIndex != 0) {
    203                 return OMX_ErrorUndefined;
    204             }
    205 
    206             return OMX_ErrorNone;
    207         }
    208 
    209         default:
    210             return SimpleSoftOMXComponent::internalSetParameter(index, params);
    211     }
    212 }
    213 
    214 bool SoftOpus::isConfigured() const {
    215     return mInputBufferCount >= 1;
    216 }
    217 
    218 static uint16_t ReadLE16(const uint8_t *data, size_t data_size,
    219                          uint32_t read_offset) {
    220     if (read_offset + 1 > data_size)
    221         return 0;
    222     uint16_t val;
    223     val = data[read_offset];
    224     val |= data[read_offset + 1] << 8;
    225     return val;
    226 }
    227 
    228 // Opus uses Vorbis channel mapping, and Vorbis channel mapping specifies
    229 // mappings for up to 8 channels. This information is part of the Vorbis I
    230 // Specification:
    231 // http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html
    232 static const int kMaxChannels = 8;
    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             memcpy(&channel_mapping,
    349                    kDefaultOpusChannelLayout,
    350                    kMaxChannelsWithDefaultLayout);
    351 
    352             int status = OPUS_INVALID_STATE;
    353             mDecoder = opus_multistream_decoder_create(kRate,
    354                                                        mHeader->channels,
    355                                                        mHeader->num_streams,
    356                                                        mHeader->num_coupled,
    357                                                        channel_mapping,
    358                                                        &status);
    359             if (!mDecoder || status != OPUS_OK) {
    360                 ALOGV("opus_multistream_decoder_create failed status=%s",
    361                       opus_strerror(status));
    362                 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
    363                 return;
    364             }
    365             status =
    366                 opus_multistream_decoder_ctl(mDecoder,
    367                                              OPUS_SET_GAIN(mHeader->gain_db));
    368             if (status != OPUS_OK) {
    369                 ALOGV("Failed to set OPUS header gain; status=%s",
    370                       opus_strerror(status));
    371                 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
    372                 return;
    373             }
    374         } else if (mInputBufferCount == 1) {
    375             mCodecDelay = ns_to_samples(
    376                               *(reinterpret_cast<int64_t*>(header->pBuffer +
    377                                                            header->nOffset)),
    378                               kRate);
    379             mSamplesToDiscard = mCodecDelay;
    380         } else {
    381             mSeekPreRoll = ns_to_samples(
    382                                *(reinterpret_cast<int64_t*>(header->pBuffer +
    383                                                             header->nOffset)),
    384                                kRate);
    385             notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
    386             mOutputPortSettingsChange = AWAITING_DISABLED;
    387         }
    388 
    389         inQueue.erase(inQueue.begin());
    390         info->mOwnedByUs = false;
    391         notifyEmptyBufferDone(header);
    392         ++mInputBufferCount;
    393         return;
    394     }
    395 
    396     while (!inQueue.empty() && !outQueue.empty()) {
    397         BufferInfo *inInfo = *inQueue.begin();
    398         OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
    399 
    400         BufferInfo *outInfo = *outQueue.begin();
    401         OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
    402 
    403         if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
    404             inQueue.erase(inQueue.begin());
    405             inInfo->mOwnedByUs = false;
    406             notifyEmptyBufferDone(inHeader);
    407 
    408             outHeader->nFilledLen = 0;
    409             outHeader->nFlags = OMX_BUFFERFLAG_EOS;
    410 
    411             outQueue.erase(outQueue.begin());
    412             outInfo->mOwnedByUs = false;
    413             notifyFillBufferDone(outHeader);
    414             return;
    415         }
    416 
    417         if (inHeader->nOffset == 0) {
    418             mAnchorTimeUs = inHeader->nTimeStamp;
    419             mNumFramesOutput = 0;
    420         }
    421 
    422         // When seeking to zero, |mCodecDelay| samples has to be discarded
    423         // instead of |mSeekPreRoll| samples (as we would when seeking to any
    424         // other timestamp).
    425         if (inHeader->nTimeStamp == 0) {
    426             mSamplesToDiscard = mCodecDelay;
    427         }
    428 
    429         const uint8_t *data = inHeader->pBuffer + inHeader->nOffset;
    430         const uint32_t size = inHeader->nFilledLen;
    431 
    432         int numFrames = opus_multistream_decode(mDecoder,
    433                                                 data,
    434                                                 size,
    435                                                 (int16_t *)outHeader->pBuffer,
    436                                                 kMaxOpusOutputPacketSizeSamples,
    437                                                 0);
    438         if (numFrames < 0) {
    439             ALOGE("opus_multistream_decode returned %d", numFrames);
    440             notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
    441             return;
    442         }
    443 
    444         outHeader->nOffset = 0;
    445         if (mSamplesToDiscard > 0) {
    446             if (mSamplesToDiscard > numFrames) {
    447                 mSamplesToDiscard -= numFrames;
    448                 numFrames = 0;
    449             } else {
    450                 numFrames -= mSamplesToDiscard;
    451                 outHeader->nOffset = mSamplesToDiscard * sizeof(int16_t) *
    452                                      mHeader->channels;
    453                 mSamplesToDiscard = 0;
    454             }
    455         }
    456 
    457         outHeader->nFilledLen = numFrames * sizeof(int16_t) * mHeader->channels;
    458         outHeader->nFlags = 0;
    459 
    460         outHeader->nTimeStamp = mAnchorTimeUs +
    461                                 (mNumFramesOutput * 1000000ll) /
    462                                 kRate;
    463 
    464         mNumFramesOutput += numFrames;
    465 
    466         inInfo->mOwnedByUs = false;
    467         inQueue.erase(inQueue.begin());
    468         inInfo = NULL;
    469         notifyEmptyBufferDone(inHeader);
    470         inHeader = NULL;
    471 
    472         outInfo->mOwnedByUs = false;
    473         outQueue.erase(outQueue.begin());
    474         outInfo = NULL;
    475         notifyFillBufferDone(outHeader);
    476         outHeader = NULL;
    477 
    478         ++mInputBufferCount;
    479     }
    480 }
    481 
    482 void SoftOpus::onPortFlushCompleted(OMX_U32 portIndex) {
    483     if (portIndex == 0 && mDecoder != NULL) {
    484         // Make sure that the next buffer output does not still
    485         // depend on fragments from the last one decoded.
    486         mNumFramesOutput = 0;
    487         opus_multistream_decoder_ctl(mDecoder, OPUS_RESET_STATE);
    488         mAnchorTimeUs = 0;
    489         mSamplesToDiscard = mSeekPreRoll;
    490     }
    491 }
    492 
    493 void SoftOpus::onReset() {
    494     mInputBufferCount = 0;
    495     mNumFramesOutput = 0;
    496     if (mDecoder != NULL) {
    497         opus_multistream_decoder_destroy(mDecoder);
    498         mDecoder = NULL;
    499     }
    500     if (mHeader != NULL) {
    501         delete mHeader;
    502         mHeader = NULL;
    503     }
    504 
    505     mOutputPortSettingsChange = NONE;
    506 }
    507 
    508 void SoftOpus::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
    509     if (portIndex != 1) {
    510         return;
    511     }
    512 
    513     switch (mOutputPortSettingsChange) {
    514         case NONE:
    515             break;
    516 
    517         case AWAITING_DISABLED:
    518         {
    519             CHECK(!enabled);
    520             mOutputPortSettingsChange = AWAITING_ENABLED;
    521             break;
    522         }
    523 
    524         default:
    525         {
    526             CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
    527             CHECK(enabled);
    528             mOutputPortSettingsChange = NONE;
    529             break;
    530         }
    531     }
    532 }
    533 
    534 }  // namespace android
    535 
    536 android::SoftOMXComponent *createSoftOMXComponent(
    537         const char *name, const OMX_CALLBACKTYPE *callbacks,
    538         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
    539     return new android::SoftOpus(name, callbacks, appData, component);
    540 }
    541