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