1 /* 2 * Copyright (C) 2011 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 "SoftVorbis" 19 #include <utils/Log.h> 20 21 #include "SoftVorbis.h" 22 23 #include <media/stagefright/foundation/ADebug.h> 24 #include <media/stagefright/MediaDefs.h> 25 26 static int kDefaultChannelCount = 1; 27 static int kDefaultSamplingRate = 48000; 28 29 extern "C" { 30 #include <Tremolo/codec_internal.h> 31 32 int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb); 33 int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb); 34 int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb); 35 } 36 37 namespace android { 38 39 template<class T> 40 static void InitOMXParams(T *params) { 41 params->nSize = sizeof(T); 42 params->nVersion.s.nVersionMajor = 1; 43 params->nVersion.s.nVersionMinor = 0; 44 params->nVersion.s.nRevision = 0; 45 params->nVersion.s.nStep = 0; 46 } 47 48 SoftVorbis::SoftVorbis( 49 const char *name, 50 const OMX_CALLBACKTYPE *callbacks, 51 OMX_PTR appData, 52 OMX_COMPONENTTYPE **component) 53 : SimpleSoftOMXComponent(name, callbacks, appData, component), 54 mInputBufferCount(0), 55 mState(NULL), 56 mVi(NULL), 57 mAnchorTimeUs(0), 58 mNumFramesOutput(0), 59 mNumFramesLeftOnPage(-1), 60 mSawInputEos(false), 61 mSignalledOutputEos(false), 62 mSignalledError(false), 63 mOutputPortSettingsChange(NONE) { 64 initPorts(); 65 CHECK_EQ(initDecoder(), (status_t)OK); 66 } 67 68 SoftVorbis::~SoftVorbis() { 69 if (mState != NULL) { 70 vorbis_dsp_clear(mState); 71 delete mState; 72 mState = NULL; 73 } 74 75 if (mVi != NULL) { 76 vorbis_info_clear(mVi); 77 delete mVi; 78 mVi = NULL; 79 } 80 } 81 82 void SoftVorbis::initPorts() { 83 OMX_PARAM_PORTDEFINITIONTYPE def; 84 InitOMXParams(&def); 85 86 def.nPortIndex = 0; 87 def.eDir = OMX_DirInput; 88 def.nBufferCountMin = kNumBuffers; 89 def.nBufferCountActual = def.nBufferCountMin; 90 def.nBufferSize = kMaxNumSamplesPerBuffer * sizeof(int16_t); 91 def.bEnabled = OMX_TRUE; 92 def.bPopulated = OMX_FALSE; 93 def.eDomain = OMX_PortDomainAudio; 94 def.bBuffersContiguous = OMX_FALSE; 95 def.nBufferAlignment = 1; 96 97 def.format.audio.cMIMEType = 98 const_cast<char *>(MEDIA_MIMETYPE_AUDIO_VORBIS); 99 100 def.format.audio.pNativeRender = NULL; 101 def.format.audio.bFlagErrorConcealment = OMX_FALSE; 102 def.format.audio.eEncoding = OMX_AUDIO_CodingVORBIS; 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); 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 125 status_t SoftVorbis::initDecoder() { 126 return OK; 127 } 128 129 OMX_ERRORTYPE SoftVorbis::internalGetParameter( 130 OMX_INDEXTYPE index, OMX_PTR params) { 131 switch (index) { 132 case OMX_IndexParamAudioPortFormat: 133 { 134 OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = 135 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; 136 137 if (!isValidOMXParam(formatParams)) { 138 return OMX_ErrorBadParameter; 139 } 140 141 if (formatParams->nPortIndex > 1) { 142 return OMX_ErrorUndefined; 143 } 144 145 if (formatParams->nIndex > 0) { 146 return OMX_ErrorNoMore; 147 } 148 149 formatParams->eEncoding = 150 (formatParams->nPortIndex == 0) 151 ? OMX_AUDIO_CodingVORBIS : OMX_AUDIO_CodingPCM; 152 153 return OMX_ErrorNone; 154 } 155 156 case OMX_IndexParamAudioVorbis: 157 { 158 OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams = 159 (OMX_AUDIO_PARAM_VORBISTYPE *)params; 160 161 if (!isValidOMXParam(vorbisParams)) { 162 return OMX_ErrorBadParameter; 163 } 164 165 if (vorbisParams->nPortIndex != 0) { 166 return OMX_ErrorUndefined; 167 } 168 169 vorbisParams->nBitRate = 0; 170 vorbisParams->nMinBitRate = 0; 171 vorbisParams->nMaxBitRate = 0; 172 vorbisParams->nAudioBandWidth = 0; 173 vorbisParams->nQuality = 3; 174 vorbisParams->bManaged = OMX_FALSE; 175 vorbisParams->bDownmix = OMX_FALSE; 176 177 if (!isConfigured()) { 178 vorbisParams->nChannels = kDefaultChannelCount; 179 vorbisParams->nSampleRate = kDefaultSamplingRate; 180 } else { 181 vorbisParams->nChannels = mVi->channels; 182 vorbisParams->nSampleRate = mVi->rate; 183 vorbisParams->nBitRate = mVi->bitrate_nominal; 184 vorbisParams->nMinBitRate = mVi->bitrate_lower; 185 vorbisParams->nMaxBitRate = mVi->bitrate_upper; 186 } 187 return OMX_ErrorNone; 188 } 189 190 case OMX_IndexParamAudioPcm: 191 { 192 OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 193 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 194 195 if (!isValidOMXParam(pcmParams)) { 196 return OMX_ErrorBadParameter; 197 } 198 199 if (pcmParams->nPortIndex != 1) { 200 return OMX_ErrorUndefined; 201 } 202 203 pcmParams->eNumData = OMX_NumericalDataSigned; 204 pcmParams->eEndian = OMX_EndianBig; 205 pcmParams->bInterleaved = OMX_TRUE; 206 pcmParams->nBitPerSample = 16; 207 pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; 208 pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF; 209 pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF; 210 211 if (!isConfigured()) { 212 pcmParams->nChannels = kDefaultChannelCount; 213 pcmParams->nSamplingRate = kDefaultSamplingRate; 214 } else { 215 pcmParams->nChannels = mVi->channels; 216 pcmParams->nSamplingRate = mVi->rate; 217 } 218 219 return OMX_ErrorNone; 220 } 221 222 default: 223 return SimpleSoftOMXComponent::internalGetParameter(index, params); 224 } 225 } 226 227 OMX_ERRORTYPE SoftVorbis::internalSetParameter( 228 OMX_INDEXTYPE index, const OMX_PTR params) { 229 switch (index) { 230 case OMX_IndexParamStandardComponentRole: 231 { 232 const OMX_PARAM_COMPONENTROLETYPE *roleParams = 233 (const OMX_PARAM_COMPONENTROLETYPE *)params; 234 235 if (!isValidOMXParam(roleParams)) { 236 return OMX_ErrorBadParameter; 237 } 238 239 if (strncmp((const char *)roleParams->cRole, 240 "audio_decoder.vorbis", 241 OMX_MAX_STRINGNAME_SIZE - 1)) { 242 return OMX_ErrorUndefined; 243 } 244 245 return OMX_ErrorNone; 246 } 247 248 case OMX_IndexParamAudioPortFormat: 249 { 250 const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = 251 (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; 252 253 if (!isValidOMXParam(formatParams)) { 254 return OMX_ErrorBadParameter; 255 } 256 257 if (formatParams->nPortIndex > 1) { 258 return OMX_ErrorUndefined; 259 } 260 261 if ((formatParams->nPortIndex == 0 262 && formatParams->eEncoding != OMX_AUDIO_CodingVORBIS) 263 || (formatParams->nPortIndex == 1 264 && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) { 265 return OMX_ErrorUndefined; 266 } 267 268 return OMX_ErrorNone; 269 } 270 271 case OMX_IndexParamAudioVorbis: 272 { 273 const OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams = 274 (const OMX_AUDIO_PARAM_VORBISTYPE *)params; 275 276 if (!isValidOMXParam(vorbisParams)) { 277 return OMX_ErrorBadParameter; 278 } 279 280 if (vorbisParams->nPortIndex != 0) { 281 return OMX_ErrorUndefined; 282 } 283 284 return OMX_ErrorNone; 285 } 286 287 default: 288 return SimpleSoftOMXComponent::internalSetParameter(index, params); 289 } 290 } 291 292 bool SoftVorbis::isConfigured() const { 293 return mInputBufferCount >= 2; 294 } 295 296 static void makeBitReader( 297 const void *data, size_t size, 298 ogg_buffer *buf, ogg_reference *ref, oggpack_buffer *bits) { 299 buf->data = (uint8_t *)data; 300 buf->size = size; 301 buf->refcount = 1; 302 buf->ptr.owner = NULL; 303 304 ref->buffer = buf; 305 ref->begin = 0; 306 ref->length = size; 307 ref->next = NULL; 308 309 oggpack_readinit(bits, ref); 310 } 311 312 void SoftVorbis::handleEOS() { 313 List<BufferInfo *> &inQueue = getPortQueue(0); 314 List<BufferInfo *> &outQueue = getPortQueue(1); 315 316 CHECK(!inQueue.empty() && !outQueue.empty()); 317 318 mSawInputEos = true; 319 320 BufferInfo *outInfo = *outQueue.begin(); 321 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 322 outHeader->nFilledLen = 0; 323 outHeader->nFlags = OMX_BUFFERFLAG_EOS; 324 325 outQueue.erase(outQueue.begin()); 326 outInfo->mOwnedByUs = false; 327 notifyFillBufferDone(outHeader); 328 mSignalledOutputEos = true; 329 330 BufferInfo *inInfo = *inQueue.begin(); 331 OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 332 inQueue.erase(inQueue.begin()); 333 inInfo->mOwnedByUs = false; 334 notifyEmptyBufferDone(inHeader); 335 ++mInputBufferCount; 336 } 337 338 void SoftVorbis::onQueueFilled(OMX_U32 /* portIndex */) { 339 List<BufferInfo *> &inQueue = getPortQueue(0); 340 List<BufferInfo *> &outQueue = getPortQueue(1); 341 342 if (mSignalledError || mOutputPortSettingsChange != NONE) { 343 return; 344 } 345 346 while (!mSignalledOutputEos && (!inQueue.empty() || mSawInputEos) && !outQueue.empty()) { 347 BufferInfo *inInfo = NULL; 348 OMX_BUFFERHEADERTYPE *inHeader = NULL; 349 if (!inQueue.empty()) { 350 inInfo = *inQueue.begin(); 351 inHeader = inInfo->mHeader; 352 } 353 354 BufferInfo *outInfo = *outQueue.begin(); 355 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 356 357 int32_t numPageSamples = 0; 358 359 if (inHeader) { 360 if (mInputBufferCount < 2) { 361 const uint8_t *data = inHeader->pBuffer + inHeader->nOffset; 362 size_t size = inHeader->nFilledLen; 363 364 if ((inHeader->nFlags & OMX_BUFFERFLAG_EOS) && size == 0) { 365 handleEOS(); 366 return; 367 } 368 369 if (size < 7) { 370 ALOGE("Too small input buffer: %zu bytes", size); 371 android_errorWriteLog(0x534e4554, "27833616"); 372 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 373 mSignalledError = true; 374 return; 375 } 376 377 ogg_buffer buf; 378 ogg_reference ref; 379 oggpack_buffer bits; 380 381 makeBitReader((const uint8_t *)data + 7, size - 7, &buf, &ref, &bits); 382 383 if (mInputBufferCount == 0) { 384 CHECK(mVi == NULL); 385 mVi = new vorbis_info; 386 vorbis_info_init(mVi); 387 388 int ret = _vorbis_unpack_info(mVi, &bits); 389 if (ret != 0) { 390 notify(OMX_EventError, OMX_ErrorUndefined, ret, NULL); 391 mSignalledError = true; 392 return; 393 } 394 } else { 395 int ret = _vorbis_unpack_books(mVi, &bits); 396 if (ret != 0) { 397 notify(OMX_EventError, OMX_ErrorUndefined, ret, NULL); 398 mSignalledError = true; 399 return; 400 } 401 402 CHECK(mState == NULL); 403 mState = new vorbis_dsp_state; 404 CHECK_EQ(0, vorbis_dsp_init(mState, mVi)); 405 406 if (mVi->rate != kDefaultSamplingRate || 407 mVi->channels != kDefaultChannelCount) { 408 ALOGV("vorbis: rate/channels changed: %ld/%d", mVi->rate, mVi->channels); 409 notify(OMX_EventPortSettingsChanged, 1, 0, NULL); 410 mOutputPortSettingsChange = AWAITING_DISABLED; 411 } 412 } 413 414 if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 415 handleEOS(); 416 return; 417 } 418 419 inQueue.erase(inQueue.begin()); 420 inInfo->mOwnedByUs = false; 421 notifyEmptyBufferDone(inHeader); 422 ++mInputBufferCount; 423 424 continue; 425 } 426 427 if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 428 mSawInputEos = true; 429 } 430 431 if (inHeader->nFilledLen || !mSawInputEos) { 432 if (inHeader->nFilledLen < sizeof(numPageSamples)) { 433 notify(OMX_EventError, OMX_ErrorBadParameter, 0, NULL); 434 mSignalledError = true; 435 ALOGE("onQueueFilled, input header has nFilledLen %u, expected %zu", 436 inHeader->nFilledLen, sizeof(numPageSamples)); 437 return; 438 } 439 memcpy(&numPageSamples, 440 inHeader->pBuffer + inHeader->nOffset + inHeader->nFilledLen - 4, 441 sizeof(numPageSamples)); 442 443 if (inHeader->nOffset == 0) { 444 mAnchorTimeUs = inHeader->nTimeStamp; 445 mNumFramesOutput = 0; 446 } 447 448 inHeader->nFilledLen -= sizeof(numPageSamples);; 449 } 450 } 451 452 if (numPageSamples >= 0) { 453 mNumFramesLeftOnPage = numPageSamples; 454 } 455 456 ogg_buffer buf; 457 buf.data = inHeader ? inHeader->pBuffer + inHeader->nOffset : NULL; 458 buf.size = inHeader ? inHeader->nFilledLen : 0; 459 buf.refcount = 1; 460 buf.ptr.owner = NULL; 461 462 ogg_reference ref; 463 ref.buffer = &buf; 464 ref.begin = 0; 465 ref.length = buf.size; 466 ref.next = NULL; 467 468 ogg_packet pack; 469 pack.packet = &ref; 470 pack.bytes = ref.length; 471 pack.b_o_s = 0; 472 pack.e_o_s = 0; 473 pack.granulepos = 0; 474 pack.packetno = 0; 475 476 int numFrames = 0; 477 478 outHeader->nFlags = 0; 479 480 if (mState == nullptr || mVi == nullptr) { 481 notify(OMX_EventError, OMX_ErrorStreamCorrupt, 0, NULL); 482 mSignalledError = true; 483 ALOGE("onQueueFilled, input does not have CSD"); 484 return; 485 } 486 487 int err = vorbis_dsp_synthesis(mState, &pack, 1); 488 if (err != 0) { 489 // FIXME temporary workaround for log spam 490 #if !defined(__arm__) && !defined(__aarch64__) 491 ALOGV("vorbis_dsp_synthesis returned %d", err); 492 #else 493 ALOGW("vorbis_dsp_synthesis returned %d", err); 494 #endif 495 } else { 496 size_t numSamplesPerBuffer = kMaxNumSamplesPerBuffer; 497 if (numSamplesPerBuffer > outHeader->nAllocLen / sizeof(int16_t)) { 498 numSamplesPerBuffer = outHeader->nAllocLen / sizeof(int16_t); 499 android_errorWriteLog(0x534e4554, "27833616"); 500 } 501 numFrames = vorbis_dsp_pcmout( 502 mState, (int16_t *)outHeader->pBuffer, 503 (numSamplesPerBuffer / mVi->channels)); 504 505 if (numFrames < 0) { 506 ALOGE("vorbis_dsp_pcmout returned %d", numFrames); 507 numFrames = 0; 508 } 509 } 510 511 if (mNumFramesLeftOnPage >= 0) { 512 if (numFrames > mNumFramesLeftOnPage) { 513 ALOGV("discarding %d frames at end of page", 514 numFrames - mNumFramesLeftOnPage); 515 numFrames = mNumFramesLeftOnPage; 516 if (mSawInputEos) { 517 outHeader->nFlags = OMX_BUFFERFLAG_EOS; 518 mSignalledOutputEos = true; 519 } 520 } 521 mNumFramesLeftOnPage -= numFrames; 522 } 523 524 outHeader->nFilledLen = numFrames * sizeof(int16_t) * mVi->channels; 525 outHeader->nOffset = 0; 526 527 outHeader->nTimeStamp = 528 mAnchorTimeUs 529 + (mNumFramesOutput * 1000000ll) / mVi->rate; 530 531 mNumFramesOutput += numFrames; 532 533 if (inHeader) { 534 inInfo->mOwnedByUs = false; 535 inQueue.erase(inQueue.begin()); 536 notifyEmptyBufferDone(inHeader); 537 ++mInputBufferCount; 538 } 539 540 outInfo->mOwnedByUs = false; 541 outQueue.erase(outQueue.begin()); 542 notifyFillBufferDone(outHeader); 543 } 544 } 545 546 void SoftVorbis::onPortFlushCompleted(OMX_U32 portIndex) { 547 if (portIndex == 0 && mState != NULL) { 548 // Make sure that the next buffer output does not still 549 // depend on fragments from the last one decoded. 550 551 mNumFramesOutput = 0; 552 mSawInputEos = false; 553 mSignalledOutputEos = false; 554 mNumFramesLeftOnPage = -1; 555 vorbis_dsp_restart(mState); 556 } 557 } 558 559 void SoftVorbis::onReset() { 560 mInputBufferCount = 0; 561 mNumFramesOutput = 0; 562 if (mState != NULL) { 563 vorbis_dsp_clear(mState); 564 delete mState; 565 mState = NULL; 566 } 567 568 if (mVi != NULL) { 569 vorbis_info_clear(mVi); 570 delete mVi; 571 mVi = NULL; 572 } 573 574 mSawInputEos = false; 575 mSignalledOutputEos = false; 576 mSignalledError = false; 577 mOutputPortSettingsChange = NONE; 578 } 579 580 void SoftVorbis::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { 581 if (portIndex != 1) { 582 return; 583 } 584 585 switch (mOutputPortSettingsChange) { 586 case NONE: 587 break; 588 589 case AWAITING_DISABLED: 590 { 591 CHECK(!enabled); 592 mOutputPortSettingsChange = AWAITING_ENABLED; 593 break; 594 } 595 596 default: 597 { 598 CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); 599 CHECK(enabled); 600 mOutputPortSettingsChange = NONE; 601 break; 602 } 603 } 604 } 605 606 } // namespace android 607 608 android::SoftOMXComponent *createSoftOMXComponent( 609 const char *name, const OMX_CALLBACKTYPE *callbacks, 610 OMX_PTR appData, OMX_COMPONENTTYPE **component) { 611 return new android::SoftVorbis(name, callbacks, appData, component); 612 } 613