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
28extern "C" {
29    #include <opus.h>
30    #include <opus_multistream.h>
31}
32
33namespace android {
34
35static const int kRate = 48000;
36
37template<class T>
38static 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
46SoftOpus::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
64SoftOpus::~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
75void 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
119status_t SoftOpus::initDecoder() {
120    return OK;
121}
122
123OMX_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
180OMX_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
214bool SoftOpus::isConfigured() const {
215    return mInputBufferCount >= 1;
216}
217
218static 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
232static const int kMaxChannels = 8;
233
234// Maximum packet size used in Xiph's opusdec.
235static 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.
241static const int kMaxChannelsWithDefaultLayout = 2;
242static const uint8_t kDefaultOpusChannelLayout[kMaxChannelsWithDefaultLayout] = { 0, 1 };
243
244// Parses Opus Header. Header spec: http://wiki.xiph.org/OggOpus#ID_Header
245static 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.
318static uint64_t ns_to_samples(uint64_t ns, int kRate) {
319    return static_cast<double>(ns) * kRate / 1000000000;
320}
321
322void 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
482void 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
493void 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
508void 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
536android::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