SoftOpus.cpp revision dfb280d3975afdce4da87602577d2814cb9eb30d
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 memcpy(&channel_mapping, 365 kDefaultOpusChannelLayout, 366 kMaxChannelsWithDefaultLayout); 367 368 int status = OPUS_INVALID_STATE; 369 mDecoder = opus_multistream_decoder_create(kRate, 370 mHeader->channels, 371 mHeader->num_streams, 372 mHeader->num_coupled, 373 channel_mapping, 374 &status); 375 if (!mDecoder || status != OPUS_OK) { 376 ALOGV("opus_multistream_decoder_create failed status=%s", 377 opus_strerror(status)); 378 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 379 return; 380 } 381 status = 382 opus_multistream_decoder_ctl(mDecoder, 383 OPUS_SET_GAIN(mHeader->gain_db)); 384 if (status != OPUS_OK) { 385 ALOGV("Failed to set OPUS header gain; status=%s", 386 opus_strerror(status)); 387 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 388 return; 389 } 390 } else if (mInputBufferCount == 1) { 391 mCodecDelay = ns_to_samples( 392 *(reinterpret_cast<int64_t*>(header->pBuffer + 393 header->nOffset)), 394 kRate); 395 mSamplesToDiscard = mCodecDelay; 396 } else { 397 mSeekPreRoll = ns_to_samples( 398 *(reinterpret_cast<int64_t*>(header->pBuffer + 399 header->nOffset)), 400 kRate); 401 notify(OMX_EventPortSettingsChanged, 1, 0, NULL); 402 mOutputPortSettingsChange = AWAITING_DISABLED; 403 } 404 405 inQueue.erase(inQueue.begin()); 406 info->mOwnedByUs = false; 407 notifyEmptyBufferDone(header); 408 ++mInputBufferCount; 409 return; 410 } 411 412 while (!inQueue.empty() && !outQueue.empty()) { 413 BufferInfo *inInfo = *inQueue.begin(); 414 OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 415 416 BufferInfo *outInfo = *outQueue.begin(); 417 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 418 419 if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 420 inQueue.erase(inQueue.begin()); 421 inInfo->mOwnedByUs = false; 422 notifyEmptyBufferDone(inHeader); 423 424 outHeader->nFilledLen = 0; 425 outHeader->nFlags = OMX_BUFFERFLAG_EOS; 426 427 outQueue.erase(outQueue.begin()); 428 outInfo->mOwnedByUs = false; 429 notifyFillBufferDone(outHeader); 430 return; 431 } 432 433 if (inHeader->nOffset == 0) { 434 mAnchorTimeUs = inHeader->nTimeStamp; 435 mNumFramesOutput = 0; 436 } 437 438 // When seeking to zero, |mCodecDelay| samples has to be discarded 439 // instead of |mSeekPreRoll| samples (as we would when seeking to any 440 // other timestamp). 441 if (inHeader->nTimeStamp == 0) { 442 mSamplesToDiscard = mCodecDelay; 443 } 444 445 const uint8_t *data = inHeader->pBuffer + inHeader->nOffset; 446 const uint32_t size = inHeader->nFilledLen; 447 size_t frameSize = kMaxOpusOutputPacketSizeSamples; 448 if (frameSize > outHeader->nAllocLen / sizeof(int16_t) / mHeader->channels) { 449 frameSize = outHeader->nAllocLen / sizeof(int16_t) / mHeader->channels; 450 android_errorWriteLog(0x534e4554, "27833616"); 451 } 452 453 int numFrames = opus_multistream_decode(mDecoder, 454 data, 455 size, 456 (int16_t *)outHeader->pBuffer, 457 frameSize, 458 0); 459 if (numFrames < 0) { 460 ALOGE("opus_multistream_decode returned %d", numFrames); 461 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 462 return; 463 } 464 465 outHeader->nOffset = 0; 466 if (mSamplesToDiscard > 0) { 467 if (mSamplesToDiscard > numFrames) { 468 mSamplesToDiscard -= numFrames; 469 numFrames = 0; 470 } else { 471 numFrames -= mSamplesToDiscard; 472 outHeader->nOffset = mSamplesToDiscard * sizeof(int16_t) * 473 mHeader->channels; 474 mSamplesToDiscard = 0; 475 } 476 } 477 478 outHeader->nFilledLen = numFrames * sizeof(int16_t) * mHeader->channels; 479 outHeader->nFlags = 0; 480 481 outHeader->nTimeStamp = mAnchorTimeUs + 482 (mNumFramesOutput * 1000000ll) / 483 kRate; 484 485 mNumFramesOutput += numFrames; 486 487 inInfo->mOwnedByUs = false; 488 inQueue.erase(inQueue.begin()); 489 inInfo = NULL; 490 notifyEmptyBufferDone(inHeader); 491 inHeader = NULL; 492 493 outInfo->mOwnedByUs = false; 494 outQueue.erase(outQueue.begin()); 495 outInfo = NULL; 496 notifyFillBufferDone(outHeader); 497 outHeader = NULL; 498 499 ++mInputBufferCount; 500 } 501} 502 503void SoftOpus::onPortFlushCompleted(OMX_U32 portIndex) { 504 if (portIndex == 0 && mDecoder != NULL) { 505 // Make sure that the next buffer output does not still 506 // depend on fragments from the last one decoded. 507 mNumFramesOutput = 0; 508 opus_multistream_decoder_ctl(mDecoder, OPUS_RESET_STATE); 509 mAnchorTimeUs = 0; 510 mSamplesToDiscard = mSeekPreRoll; 511 } 512} 513 514void SoftOpus::onReset() { 515 mInputBufferCount = 0; 516 mNumFramesOutput = 0; 517 if (mDecoder != NULL) { 518 opus_multistream_decoder_destroy(mDecoder); 519 mDecoder = NULL; 520 } 521 if (mHeader != NULL) { 522 delete mHeader; 523 mHeader = NULL; 524 } 525 526 mOutputPortSettingsChange = NONE; 527} 528 529void SoftOpus::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { 530 if (portIndex != 1) { 531 return; 532 } 533 534 switch (mOutputPortSettingsChange) { 535 case NONE: 536 break; 537 538 case AWAITING_DISABLED: 539 { 540 CHECK(!enabled); 541 mOutputPortSettingsChange = AWAITING_ENABLED; 542 break; 543 } 544 545 default: 546 { 547 CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); 548 CHECK(enabled); 549 mOutputPortSettingsChange = NONE; 550 break; 551 } 552 } 553} 554 555} // namespace android 556 557android::SoftOMXComponent *createSoftOMXComponent( 558 const char *name, const OMX_CALLBACKTYPE *callbacks, 559 OMX_PTR appData, OMX_COMPONENTTYPE **component) { 560 return new android::SoftOpus(name, callbacks, appData, component); 561} 562