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
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
41static const int kMaxChannels = 8;
42
43template<class T>
44static 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
52SoftOpus::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
70SoftOpus::~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
81void 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
125status_t SoftOpus::initDecoder() {
126    return OK;
127}
128
129OMX_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 (!isValidOMXParam(opusParams)) {
138                return OMX_ErrorBadParameter;
139            }
140
141            if (opusParams->nPortIndex != 0) {
142                return OMX_ErrorUndefined;
143            }
144
145            opusParams->nAudioBandWidth = 0;
146            opusParams->nSampleRate = kRate;
147            opusParams->nBitRate = 0;
148
149            if (!isConfigured()) {
150                opusParams->nChannels = 1;
151            } else {
152                opusParams->nChannels = mHeader->channels;
153            }
154
155            return OMX_ErrorNone;
156        }
157
158        case OMX_IndexParamAudioPcm:
159        {
160            OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
161                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
162
163            if (!isValidOMXParam(pcmParams)) {
164                return OMX_ErrorBadParameter;
165            }
166
167            if (pcmParams->nPortIndex != 1) {
168                return OMX_ErrorUndefined;
169            }
170
171            pcmParams->eNumData = OMX_NumericalDataSigned;
172            pcmParams->eEndian = OMX_EndianBig;
173            pcmParams->bInterleaved = OMX_TRUE;
174            pcmParams->nBitPerSample = 16;
175            pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
176            pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
177            pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
178            pcmParams->nSamplingRate = kRate;
179
180            if (!isConfigured()) {
181                pcmParams->nChannels = 1;
182            } else {
183                pcmParams->nChannels = mHeader->channels;
184            }
185
186            return OMX_ErrorNone;
187        }
188
189        default:
190            return SimpleSoftOMXComponent::internalGetParameter(index, params);
191    }
192}
193
194OMX_ERRORTYPE SoftOpus::internalSetParameter(
195        OMX_INDEXTYPE index, const OMX_PTR params) {
196    switch ((int)index) {
197        case OMX_IndexParamStandardComponentRole:
198        {
199            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
200                (const OMX_PARAM_COMPONENTROLETYPE *)params;
201
202            if (!isValidOMXParam(roleParams)) {
203                return OMX_ErrorBadParameter;
204            }
205
206            if (strncmp((const char *)roleParams->cRole,
207                        "audio_decoder.opus",
208                        OMX_MAX_STRINGNAME_SIZE - 1)) {
209                return OMX_ErrorUndefined;
210            }
211
212            return OMX_ErrorNone;
213        }
214
215        case OMX_IndexParamAudioAndroidOpus:
216        {
217            const OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *opusParams =
218                (const OMX_AUDIO_PARAM_ANDROID_OPUSTYPE *)params;
219
220            if (!isValidOMXParam(opusParams)) {
221                return OMX_ErrorBadParameter;
222            }
223
224            if (opusParams->nPortIndex != 0) {
225                return OMX_ErrorUndefined;
226            }
227
228            return OMX_ErrorNone;
229        }
230
231        default:
232            return SimpleSoftOMXComponent::internalSetParameter(index, params);
233    }
234}
235
236bool SoftOpus::isConfigured() const {
237    return mInputBufferCount >= 1;
238}
239
240static uint16_t ReadLE16(const uint8_t *data, size_t data_size,
241                         uint32_t read_offset) {
242    if (read_offset + 1 > data_size)
243        return 0;
244    uint16_t val;
245    val = data[read_offset];
246    val |= data[read_offset + 1] << 8;
247    return val;
248}
249
250// Maximum packet size used in Xiph's opusdec.
251static const int kMaxOpusOutputPacketSizeSamples = 960 * 6;
252
253// Default audio output channel layout. Used to initialize |stream_map| in
254// OpusHeader, and passed to opus_multistream_decoder_create() when the header
255// does not contain mapping information. The values are valid only for mono and
256// stereo output: Opus streams with more than 2 channels require a stream map.
257static const int kMaxChannelsWithDefaultLayout = 2;
258static const uint8_t kDefaultOpusChannelLayout[kMaxChannelsWithDefaultLayout] = { 0, 1 };
259
260// Parses Opus Header. Header spec: http://wiki.xiph.org/OggOpus#ID_Header
261static bool ParseOpusHeader(const uint8_t *data, size_t data_size,
262                            OpusHeader* header) {
263    // Size of the Opus header excluding optional mapping information.
264    const size_t kOpusHeaderSize = 19;
265
266    // Offset to the channel count byte in the Opus header.
267    const size_t kOpusHeaderChannelsOffset = 9;
268
269    // Offset to the pre-skip value in the Opus header.
270    const size_t kOpusHeaderSkipSamplesOffset = 10;
271
272    // Offset to the gain value in the Opus header.
273    const size_t kOpusHeaderGainOffset = 16;
274
275    // Offset to the channel mapping byte in the Opus header.
276    const size_t kOpusHeaderChannelMappingOffset = 18;
277
278    // Opus Header contains a stream map. The mapping values are in the header
279    // beyond the always present |kOpusHeaderSize| bytes of data. The mapping
280    // data contains stream count, coupling information, and per channel mapping
281    // values:
282    //   - Byte 0: Number of streams.
283    //   - Byte 1: Number coupled.
284    //   - Byte 2: Starting at byte 2 are |header->channels| uint8 mapping
285    //             values.
286    const size_t kOpusHeaderNumStreamsOffset = kOpusHeaderSize;
287    const size_t kOpusHeaderNumCoupledOffset = kOpusHeaderNumStreamsOffset + 1;
288    const size_t kOpusHeaderStreamMapOffset = kOpusHeaderNumStreamsOffset + 2;
289
290    if (data_size < kOpusHeaderSize) {
291        ALOGV("Header size is too small.");
292        return false;
293    }
294    header->channels = *(data + kOpusHeaderChannelsOffset);
295
296    if (header->channels <= 0 || header->channels > kMaxChannels) {
297        ALOGV("Invalid Header, wrong channel count: %d", header->channels);
298        return false;
299    }
300    header->skip_samples = ReadLE16(data, data_size,
301                                        kOpusHeaderSkipSamplesOffset);
302    header->gain_db = static_cast<int16_t>(
303                              ReadLE16(data, data_size,
304                                       kOpusHeaderGainOffset));
305    header->channel_mapping = *(data + kOpusHeaderChannelMappingOffset);
306    if (!header->channel_mapping) {
307        if (header->channels > kMaxChannelsWithDefaultLayout) {
308            ALOGV("Invalid Header, missing stream map.");
309            return false;
310        }
311        header->num_streams = 1;
312        header->num_coupled = header->channels > 1;
313        header->stream_map[0] = 0;
314        header->stream_map[1] = 1;
315        return true;
316    }
317    if (data_size < kOpusHeaderStreamMapOffset + header->channels) {
318        ALOGV("Invalid stream map; insufficient data for current channel "
319              "count: %d", header->channels);
320        return false;
321    }
322    header->num_streams = *(data + kOpusHeaderNumStreamsOffset);
323    header->num_coupled = *(data + kOpusHeaderNumCoupledOffset);
324    if (header->num_streams + header->num_coupled != header->channels) {
325        ALOGV("Inconsistent channel mapping.");
326        return false;
327    }
328    for (int i = 0; i < header->channels; ++i)
329      header->stream_map[i] = *(data + kOpusHeaderStreamMapOffset + i);
330    return true;
331}
332
333// Convert nanoseconds to number of samples.
334static uint64_t ns_to_samples(uint64_t ns, int kRate) {
335    return static_cast<double>(ns) * kRate / 1000000000;
336}
337
338void SoftOpus::onQueueFilled(OMX_U32 portIndex) {
339    List<BufferInfo *> &inQueue = getPortQueue(0);
340    List<BufferInfo *> &outQueue = getPortQueue(1);
341
342    if (mOutputPortSettingsChange != NONE) {
343        return;
344    }
345
346    if (portIndex == 0 && mInputBufferCount < 3) {
347        BufferInfo *info = *inQueue.begin();
348        OMX_BUFFERHEADERTYPE *header = info->mHeader;
349
350        const uint8_t *data = header->pBuffer + header->nOffset;
351        size_t size = header->nFilledLen;
352
353        if (mInputBufferCount == 0) {
354            CHECK(mHeader == NULL);
355            mHeader = new OpusHeader();
356            memset(mHeader, 0, sizeof(*mHeader));
357            if (!ParseOpusHeader(data, size, mHeader)) {
358                ALOGV("Parsing Opus Header failed.");
359                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
360                return;
361            }
362
363            uint8_t channel_mapping[kMaxChannels] = {0};
364            if (mHeader->channels <= kMaxChannelsWithDefaultLayout) {
365                memcpy(&channel_mapping,
366                       kDefaultOpusChannelLayout,
367                       kMaxChannelsWithDefaultLayout);
368            } else {
369                memcpy(&channel_mapping,
370                       mHeader->stream_map,
371                       mHeader->channels);
372            }
373
374            int status = OPUS_INVALID_STATE;
375            mDecoder = opus_multistream_decoder_create(kRate,
376                                                       mHeader->channels,
377                                                       mHeader->num_streams,
378                                                       mHeader->num_coupled,
379                                                       channel_mapping,
380                                                       &status);
381            if (!mDecoder || status != OPUS_OK) {
382                ALOGV("opus_multistream_decoder_create failed status=%s",
383                      opus_strerror(status));
384                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
385                return;
386            }
387            status =
388                opus_multistream_decoder_ctl(mDecoder,
389                                             OPUS_SET_GAIN(mHeader->gain_db));
390            if (status != OPUS_OK) {
391                ALOGV("Failed to set OPUS header gain; status=%s",
392                      opus_strerror(status));
393                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
394                return;
395            }
396        } else if (mInputBufferCount == 1) {
397            mCodecDelay = ns_to_samples(
398                              *(reinterpret_cast<int64_t*>(header->pBuffer +
399                                                           header->nOffset)),
400                              kRate);
401            mSamplesToDiscard = mCodecDelay;
402        } else {
403            mSeekPreRoll = ns_to_samples(
404                               *(reinterpret_cast<int64_t*>(header->pBuffer +
405                                                            header->nOffset)),
406                               kRate);
407            notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
408            mOutputPortSettingsChange = AWAITING_DISABLED;
409        }
410
411        inQueue.erase(inQueue.begin());
412        info->mOwnedByUs = false;
413        notifyEmptyBufferDone(header);
414        ++mInputBufferCount;
415        return;
416    }
417
418    while (!inQueue.empty() && !outQueue.empty()) {
419        BufferInfo *inInfo = *inQueue.begin();
420        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
421
422        // Ignore CSD re-submissions.
423        if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
424            inQueue.erase(inQueue.begin());
425            inInfo->mOwnedByUs = false;
426            notifyEmptyBufferDone(inHeader);
427            return;
428        }
429
430        BufferInfo *outInfo = *outQueue.begin();
431        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
432
433        if ((inHeader->nFlags & OMX_BUFFERFLAG_EOS) && inHeader->nFilledLen == 0) {
434            inQueue.erase(inQueue.begin());
435            inInfo->mOwnedByUs = false;
436            notifyEmptyBufferDone(inHeader);
437
438            outHeader->nFilledLen = 0;
439            outHeader->nFlags = OMX_BUFFERFLAG_EOS;
440
441            outQueue.erase(outQueue.begin());
442            outInfo->mOwnedByUs = false;
443            notifyFillBufferDone(outHeader);
444            return;
445        }
446
447        if (inHeader->nOffset == 0) {
448            mAnchorTimeUs = inHeader->nTimeStamp;
449            mNumFramesOutput = 0;
450        }
451
452        // When seeking to zero, |mCodecDelay| samples has to be discarded
453        // instead of |mSeekPreRoll| samples (as we would when seeking to any
454        // other timestamp).
455        if (inHeader->nTimeStamp == 0) {
456            mSamplesToDiscard = mCodecDelay;
457        }
458
459        const uint8_t *data = inHeader->pBuffer + inHeader->nOffset;
460        const uint32_t size = inHeader->nFilledLen;
461        size_t frameSize = kMaxOpusOutputPacketSizeSamples;
462        if (frameSize > outHeader->nAllocLen / sizeof(int16_t) / mHeader->channels) {
463            frameSize = outHeader->nAllocLen / sizeof(int16_t) / mHeader->channels;
464            android_errorWriteLog(0x534e4554, "27833616");
465        }
466
467        int numFrames = opus_multistream_decode(mDecoder,
468                                                data,
469                                                size,
470                                                (int16_t *)outHeader->pBuffer,
471                                                frameSize,
472                                                0);
473        if (numFrames < 0) {
474            ALOGE("opus_multistream_decode returned %d", numFrames);
475            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
476            return;
477        }
478
479        outHeader->nOffset = 0;
480        if (mSamplesToDiscard > 0) {
481            if (mSamplesToDiscard > numFrames) {
482                mSamplesToDiscard -= numFrames;
483                numFrames = 0;
484            } else {
485                numFrames -= mSamplesToDiscard;
486                outHeader->nOffset = mSamplesToDiscard * sizeof(int16_t) *
487                                     mHeader->channels;
488                mSamplesToDiscard = 0;
489            }
490        }
491
492        outHeader->nFilledLen = numFrames * sizeof(int16_t) * mHeader->channels;
493        outHeader->nFlags = 0;
494
495        outHeader->nTimeStamp = mAnchorTimeUs +
496                                (mNumFramesOutput * 1000000ll) /
497                                kRate;
498
499        mNumFramesOutput += numFrames;
500
501        if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
502            inHeader->nFilledLen = 0;
503        } else {
504            inInfo->mOwnedByUs = false;
505            inQueue.erase(inQueue.begin());
506            inInfo = NULL;
507            notifyEmptyBufferDone(inHeader);
508            inHeader = NULL;
509        }
510
511        outInfo->mOwnedByUs = false;
512        outQueue.erase(outQueue.begin());
513        outInfo = NULL;
514        notifyFillBufferDone(outHeader);
515        outHeader = NULL;
516
517        ++mInputBufferCount;
518    }
519}
520
521void SoftOpus::onPortFlushCompleted(OMX_U32 portIndex) {
522    if (portIndex == 0 && mDecoder != NULL) {
523        // Make sure that the next buffer output does not still
524        // depend on fragments from the last one decoded.
525        mNumFramesOutput = 0;
526        opus_multistream_decoder_ctl(mDecoder, OPUS_RESET_STATE);
527        mAnchorTimeUs = 0;
528        mSamplesToDiscard = mSeekPreRoll;
529    }
530}
531
532void SoftOpus::onReset() {
533    mInputBufferCount = 0;
534    mNumFramesOutput = 0;
535    if (mDecoder != NULL) {
536        opus_multistream_decoder_destroy(mDecoder);
537        mDecoder = NULL;
538    }
539    if (mHeader != NULL) {
540        delete mHeader;
541        mHeader = NULL;
542    }
543
544    mOutputPortSettingsChange = NONE;
545}
546
547void SoftOpus::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
548    if (portIndex != 1) {
549        return;
550    }
551
552    switch (mOutputPortSettingsChange) {
553        case NONE:
554            break;
555
556        case AWAITING_DISABLED:
557        {
558            CHECK(!enabled);
559            mOutputPortSettingsChange = AWAITING_ENABLED;
560            break;
561        }
562
563        default:
564        {
565            CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
566            CHECK(enabled);
567            mOutputPortSettingsChange = NONE;
568            break;
569        }
570    }
571}
572
573}  // namespace android
574
575android::SoftOMXComponent *createSoftOMXComponent(
576        const char *name, const OMX_CALLBACKTYPE *callbacks,
577        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
578    return new android::SoftOpus(name, callbacks, appData, component);
579}
580