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 ************************************************************************* 18 * @file VideoEditorAudioEncoder.cpp 19 * @brief StageFright shell Audio Encoder 20 ************************************************************************* 21 */ 22 23 #define LOG_NDEBUG 1 24 #define LOG_TAG "VIDEOEDITOR_AUDIOENCODER" 25 26 #include "M4OSA_Debug.h" 27 #include "VideoEditorAudioEncoder.h" 28 #include "VideoEditorUtils.h" 29 30 #include "utils/Log.h" 31 #include <media/stagefright/foundation/ADebug.h> 32 #include <media/stagefright/MediaSource.h> 33 #include <media/stagefright/MediaDefs.h> 34 #include <media/stagefright/MetaData.h> 35 #include <media/stagefright/OMXClient.h> 36 #include <media/stagefright/OMXCodec.h> 37 38 /*** DEFINITIONS ***/ 39 // Force using software encoder as engine does not support prefetch 40 #define VIDEOEDITOR_FORCECODEC kSoftwareCodecsOnly 41 42 namespace android { 43 struct VideoEditorAudioEncoderSource : public MediaSource { 44 public: 45 static sp<VideoEditorAudioEncoderSource> Create( 46 const sp<MetaData> &format); 47 virtual status_t start(MetaData *params = NULL); 48 virtual status_t stop(); 49 virtual sp<MetaData> getFormat(); 50 virtual status_t read(MediaBuffer **buffer, 51 const ReadOptions *options = NULL); 52 virtual int32_t storeBuffer(MediaBuffer *buffer); 53 54 protected: 55 virtual ~VideoEditorAudioEncoderSource(); 56 57 private: 58 struct MediaBufferChain { 59 MediaBuffer* buffer; 60 MediaBufferChain* nextLink; 61 }; 62 enum State { 63 CREATED, 64 STARTED, 65 ERROR 66 }; 67 68 MediaBufferChain* mFirstBufferLink; 69 MediaBufferChain* mLastBufferLink; 70 int32_t mNbBuffer; 71 State mState; 72 sp<MetaData> mEncFormat; 73 74 VideoEditorAudioEncoderSource(const sp<MetaData> &format); 75 76 // Don't call me. 77 VideoEditorAudioEncoderSource(const VideoEditorAudioEncoderSource&); 78 VideoEditorAudioEncoderSource& operator=( 79 const VideoEditorAudioEncoderSource&); 80 }; 81 82 sp<VideoEditorAudioEncoderSource> VideoEditorAudioEncoderSource::Create( 83 const sp<MetaData> &format) { 84 85 ALOGV("VideoEditorAudioEncoderSource::Create"); 86 sp<VideoEditorAudioEncoderSource> aSource = 87 new VideoEditorAudioEncoderSource(format); 88 89 return aSource; 90 } 91 92 VideoEditorAudioEncoderSource::VideoEditorAudioEncoderSource( 93 const sp<MetaData> &format): 94 mFirstBufferLink(NULL), 95 mLastBufferLink(NULL), 96 mNbBuffer(0), 97 mState(CREATED), 98 mEncFormat(format) { 99 ALOGV("VideoEditorAudioEncoderSource::VideoEditorAudioEncoderSource"); 100 } 101 102 103 VideoEditorAudioEncoderSource::~VideoEditorAudioEncoderSource() { 104 ALOGV("VideoEditorAudioEncoderSource::~VideoEditorAudioEncoderSource"); 105 106 if( STARTED == mState ) { 107 stop(); 108 } 109 } 110 111 status_t VideoEditorAudioEncoderSource::start(MetaData *meta) { 112 status_t err = OK; 113 114 ALOGV("VideoEditorAudioEncoderSource::start"); 115 116 if( CREATED != mState ) { 117 ALOGV("VideoEditorAudioEncoderSource::start ERROR : invalid state %d", 118 mState); 119 return UNKNOWN_ERROR; 120 } 121 122 mState = STARTED; 123 124 cleanUp: 125 ALOGV("VideoEditorAudioEncoderSource::start END (0x%x)", err); 126 return err; 127 } 128 129 status_t VideoEditorAudioEncoderSource::stop() { 130 status_t err = OK; 131 132 ALOGV("VideoEditorAudioEncoderSource::stop"); 133 134 if( STARTED != mState ) { 135 ALOGV("VideoEditorAudioEncoderSource::stop ERROR: invalid state %d", 136 mState); 137 return UNKNOWN_ERROR; 138 } 139 140 int32_t i = 0; 141 MediaBufferChain* tmpLink = NULL; 142 while( mFirstBufferLink ) { 143 i++; 144 tmpLink = mFirstBufferLink; 145 mFirstBufferLink = mFirstBufferLink->nextLink; 146 delete tmpLink; 147 } 148 ALOGV("VideoEditorAudioEncoderSource::stop : %d buffer remained", i); 149 mFirstBufferLink = NULL; 150 mLastBufferLink = NULL; 151 152 mState = CREATED; 153 154 ALOGV("VideoEditorAudioEncoderSource::stop END (0x%x)", err); 155 return err; 156 } 157 158 sp<MetaData> VideoEditorAudioEncoderSource::getFormat() { 159 ALOGV("VideoEditorAudioEncoderSource::getFormat"); 160 return mEncFormat; 161 } 162 163 status_t VideoEditorAudioEncoderSource::read(MediaBuffer **buffer, 164 const ReadOptions *options) { 165 MediaSource::ReadOptions readOptions; 166 status_t err = OK; 167 MediaBufferChain* tmpLink = NULL; 168 169 ALOGV("VideoEditorAudioEncoderSource::read"); 170 171 if ( STARTED != mState ) { 172 ALOGV("VideoEditorAudioEncoderSource::read ERROR : invalid state %d", 173 mState); 174 return UNKNOWN_ERROR; 175 } 176 177 if( NULL == mFirstBufferLink ) { 178 *buffer = NULL; 179 ALOGV("VideoEditorAudioEncoderSource::read : EOS"); 180 return ERROR_END_OF_STREAM; 181 } 182 *buffer = mFirstBufferLink->buffer; 183 184 tmpLink = mFirstBufferLink; 185 mFirstBufferLink = mFirstBufferLink->nextLink; 186 if( NULL == mFirstBufferLink ) { 187 mLastBufferLink = NULL; 188 } 189 delete tmpLink; 190 mNbBuffer--; 191 192 ALOGV("VideoEditorAudioEncoderSource::read END (0x%x)", err); 193 return err; 194 } 195 196 int32_t VideoEditorAudioEncoderSource::storeBuffer(MediaBuffer *buffer) { 197 status_t err = OK; 198 199 ALOGV("VideoEditorAudioEncoderSource::storeBuffer"); 200 201 MediaBufferChain* newLink = new MediaBufferChain; 202 newLink->buffer = buffer; 203 newLink->nextLink = NULL; 204 if( NULL != mLastBufferLink ) { 205 mLastBufferLink->nextLink = newLink; 206 } else { 207 mFirstBufferLink = newLink; 208 } 209 mLastBufferLink = newLink; 210 mNbBuffer++; 211 212 ALOGV("VideoEditorAudioEncoderSource::storeBuffer END"); 213 return mNbBuffer; 214 } 215 216 /******************** 217 * ENGINE INTERFACE * 218 ********************/ 219 /** 220 ****************************************************************************** 221 * structure VideoEditorAudioEncoder_Context 222 * @brief This structure defines the context of the StageFright audio 223 * encoder shell 224 ****************************************************************************** 225 */ 226 typedef struct { 227 M4ENCODER_AudioFormat mFormat; 228 M4ENCODER_AudioParams* mCodecParams; 229 M4ENCODER_AudioDecSpecificInfo mDSI; 230 sp<VideoEditorAudioEncoderSource> mEncoderSource; 231 OMXClient mClient; 232 sp<MediaSource> mEncoder; 233 uint32_t mNbInputFrames; 234 uint32_t mNbOutputFrames; 235 int64_t mFirstOutputCts; 236 int64_t mLastOutputCts; 237 } VideoEditorAudioEncoder_Context; 238 239 M4OSA_ERR VideoEditorAudioEncoder_cleanup(M4OSA_Context pContext) { 240 241 M4OSA_ERR err = M4NO_ERROR; 242 VideoEditorAudioEncoder_Context* pEncoderContext = M4OSA_NULL; 243 244 ALOGV("VideoEditorAudioEncoder_cleanup begin"); 245 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 246 pEncoderContext = (VideoEditorAudioEncoder_Context*)pContext; 247 248 SAFE_FREE(pEncoderContext->mDSI.pInfo); 249 SAFE_FREE(pEncoderContext); 250 pContext = M4OSA_NULL; 251 252 cleanUp: 253 if( M4NO_ERROR == err ) { 254 ALOGV("VideoEditorAudioEncoder_cleanup no error"); 255 } else { 256 ALOGV("VideoEditorAudioEncoder_cleanup ERROR 0x%X", err); 257 } 258 ALOGV("VideoEditorAudioEncoder_cleanup end"); 259 return err; 260 } 261 262 M4OSA_ERR VideoEditorAudioEncoder_init(M4ENCODER_AudioFormat format, 263 M4OSA_Context* pContext, M4OSA_Void* pUserData) { 264 265 M4OSA_ERR err = M4NO_ERROR; 266 VideoEditorAudioEncoder_Context* pEncoderContext = M4OSA_NULL; 267 268 ALOGV(" VideoEditorAudioEncoder_init begin: format %d", format); 269 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 270 271 SAFE_MALLOC(pEncoderContext, VideoEditorAudioEncoder_Context, 1, 272 "VideoEditorAudioEncoder"); 273 pEncoderContext->mFormat = format; 274 275 *pContext = pEncoderContext; 276 277 cleanUp: 278 if( M4NO_ERROR == err ) { 279 ALOGV("VideoEditorAudioEncoder_init no error"); 280 } else { 281 VideoEditorAudioEncoder_cleanup(pEncoderContext); 282 *pContext = M4OSA_NULL; 283 ALOGV("VideoEditorAudioEncoder_init ERROR 0x%X", err); 284 } 285 ALOGV("VideoEditorAudioEncoder_init end"); 286 return err; 287 } 288 289 M4OSA_ERR VideoEditorAudioEncoder_init_AAC(M4OSA_Context* pContext, 290 M4OSA_Void* pUserData) { 291 return VideoEditorAudioEncoder_init(M4ENCODER_kAAC, pContext, pUserData); 292 } 293 294 M4OSA_ERR VideoEditorAudioEncoder_init_AMRNB(M4OSA_Context* pContext, 295 M4OSA_Void* pUserData) { 296 return VideoEditorAudioEncoder_init(M4ENCODER_kAMRNB, pContext, pUserData); 297 } 298 299 M4OSA_ERR VideoEditorAudioEncoder_init_MP3(M4OSA_Context* pContext, 300 M4OSA_Void* pUserData) { 301 return VideoEditorAudioEncoder_init(M4ENCODER_kMP3, pContext, pUserData); 302 } 303 304 M4OSA_ERR VideoEditorAudioEncoder_close(M4OSA_Context pContext) { 305 306 M4OSA_ERR err = M4NO_ERROR; 307 VideoEditorAudioEncoder_Context* pEncoderContext = M4OSA_NULL; 308 309 ALOGV("VideoEditorAudioEncoder_close begin"); 310 311 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 312 pEncoderContext = (VideoEditorAudioEncoder_Context*)pContext; 313 314 SAFE_FREE(pEncoderContext->mCodecParams); 315 316 pEncoderContext->mEncoder->stop(); 317 pEncoderContext->mEncoder.clear(); 318 pEncoderContext->mClient.disconnect(); 319 pEncoderContext->mEncoderSource.clear(); 320 321 ALOGV("AudioEncoder_close:IN %d frames,OUT %d frames from %lld to %lld", 322 pEncoderContext->mNbInputFrames, 323 pEncoderContext->mNbOutputFrames, pEncoderContext->mFirstOutputCts, 324 pEncoderContext->mLastOutputCts); 325 326 if( pEncoderContext->mNbInputFrames != pEncoderContext->mNbInputFrames ) { 327 ALOGV("VideoEditorAudioEncoder_close:some frames were not encoded %d %d", 328 pEncoderContext->mNbInputFrames, pEncoderContext->mNbInputFrames); 329 } 330 331 cleanUp: 332 if( M4NO_ERROR == err ) { 333 ALOGV("VideoEditorAudioEncoder_close no error"); 334 } else { 335 ALOGV("VideoEditorAudioEncoder_close ERROR 0x%X", err); 336 } 337 ALOGV("VideoEditorAudioEncoder_close begin end"); 338 return err; 339 } 340 341 M4OSA_ERR VideoEditorAudioEncoder_open(M4OSA_Context pContext, 342 M4ENCODER_AudioParams *pParams, M4ENCODER_AudioDecSpecificInfo *pDSI, 343 M4OSA_Context pGrabberContext) { 344 345 M4OSA_ERR err = M4NO_ERROR; 346 VideoEditorAudioEncoder_Context* pEncoderContext = M4OSA_NULL; 347 status_t result = OK; 348 sp<MetaData> encoderMetadata = NULL; 349 const char* mime = NULL; 350 int32_t iNbChannel = 0; 351 uint32_t codecFlags = 0; 352 353 ALOGV("VideoEditorAudioEncoder_open begin"); 354 355 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 356 VIDEOEDITOR_CHECK(M4OSA_NULL != pParams, M4ERR_PARAMETER); 357 VIDEOEDITOR_CHECK(M4OSA_NULL != pDSI, M4ERR_PARAMETER); 358 359 pEncoderContext = (VideoEditorAudioEncoder_Context*)pContext; 360 pDSI->pInfo = M4OSA_NULL; 361 pDSI->infoSize = 0; 362 363 pEncoderContext->mNbInputFrames = 0; 364 pEncoderContext->mNbOutputFrames = 0; 365 pEncoderContext->mFirstOutputCts = -1; 366 pEncoderContext->mLastOutputCts = -1; 367 368 // Allocate & initialize the encoding parameters 369 ALOGV("VideoEditorAudioEncoder_open : params F=%d CN=%d BR=%d F=%d", 370 pParams->Frequency, pParams->ChannelNum, pParams->Bitrate, 371 pParams->Format); 372 SAFE_MALLOC(pEncoderContext->mCodecParams, M4ENCODER_AudioParams, 1, 373 "VIDEOEDITOR CodecParams"); 374 pEncoderContext->mCodecParams->Frequency = pParams->Frequency; 375 pEncoderContext->mCodecParams->ChannelNum = pParams->ChannelNum; 376 pEncoderContext->mCodecParams->Bitrate = pParams->Bitrate; 377 pEncoderContext->mCodecParams->Format = pParams->Format; 378 379 // Check output format consistency 380 VIDEOEDITOR_CHECK(pEncoderContext->mCodecParams->Format == 381 pEncoderContext->mFormat, M4ERR_PARAMETER); 382 383 /** 384 * StageFright graph building 385 */ 386 // Create the meta data for the encoder 387 encoderMetadata = new MetaData; 388 switch( pEncoderContext->mCodecParams->Format ) { 389 case M4ENCODER_kAAC: 390 { 391 mime = MEDIA_MIMETYPE_AUDIO_AAC; 392 break; 393 } 394 case M4ENCODER_kAMRNB: 395 { 396 mime = MEDIA_MIMETYPE_AUDIO_AMR_NB; 397 break; 398 } 399 default: 400 { 401 VIDEOEDITOR_CHECK(!"AudioEncoder_open : incorrect input format", 402 M4ERR_PARAMETER); 403 break; 404 } 405 } 406 encoderMetadata->setCString(kKeyMIMEType, mime); 407 encoderMetadata->setInt32(kKeySampleRate, 408 (int32_t)pEncoderContext->mCodecParams->Frequency); 409 encoderMetadata->setInt32(kKeyBitRate, 410 (int32_t)pEncoderContext->mCodecParams->Bitrate); 411 412 switch( pEncoderContext->mCodecParams->ChannelNum ) { 413 case M4ENCODER_kMono: 414 { 415 iNbChannel = 1; 416 break; 417 } 418 case M4ENCODER_kStereo: 419 { 420 iNbChannel = 2; 421 break; 422 } 423 default: 424 { 425 VIDEOEDITOR_CHECK(!"AudioEncoder_open : incorrect channel number", 426 M4ERR_STATE); 427 break; 428 } 429 } 430 encoderMetadata->setInt32(kKeyChannelCount, iNbChannel); 431 432 // Create the encoder source 433 pEncoderContext->mEncoderSource = VideoEditorAudioEncoderSource::Create( 434 encoderMetadata); 435 VIDEOEDITOR_CHECK(NULL != pEncoderContext->mEncoderSource.get(), 436 M4ERR_STATE); 437 438 // Connect to the OMX client 439 result = pEncoderContext->mClient.connect(); 440 VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE); 441 442 // Create the OMX codec 443 #ifdef VIDEOEDITOR_FORCECODEC 444 codecFlags |= OMXCodec::VIDEOEDITOR_FORCECODEC; 445 #endif /* VIDEOEDITOR_FORCECODEC */ 446 // FIXME: 447 // We are moving away to use software AACEncoder and instead use OMX-based 448 // software AAC audio encoder. We want to use AACEncoder for now. After we 449 // fix the interface issue with the OMX-based AAC audio encoder, we should 450 // then set the component name back to NULL to allow the system to pick up 451 // the right AAC audio encoder. 452 pEncoderContext->mEncoder = OMXCodec::Create( 453 pEncoderContext->mClient.interface(), encoderMetadata, true, 454 pEncoderContext->mEncoderSource, "AACEncoder" /* component name */, 455 codecFlags); 456 VIDEOEDITOR_CHECK(NULL != pEncoderContext->mEncoder.get(), M4ERR_STATE); 457 458 // Start the graph 459 result = pEncoderContext->mEncoder->start(); 460 VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE); 461 462 // Get AAC DSI, this code can only work with software encoder 463 if( M4ENCODER_kAAC == pEncoderContext->mCodecParams->Format ) { 464 int32_t isCodecConfig = 0; 465 MediaBuffer* buffer = NULL; 466 467 // Read once to get the DSI 468 result = pEncoderContext->mEncoder->read(&buffer, NULL); 469 VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE); 470 VIDEOEDITOR_CHECK(buffer->meta_data()->findInt32(kKeyIsCodecConfig, 471 &isCodecConfig) && isCodecConfig, M4ERR_STATE); 472 473 // Save the DSI 474 pEncoderContext->mDSI.infoSize = (M4OSA_UInt32)buffer->range_length(); 475 SAFE_MALLOC(pEncoderContext->mDSI.pInfo, M4OSA_Int8, 476 pEncoderContext->mDSI.infoSize, "Encoder header"); 477 478 memcpy((void *)pEncoderContext->mDSI.pInfo, 479 (void *)((M4OSA_MemAddr8)(buffer->data())+buffer->range_offset()), 480 pEncoderContext->mDSI.infoSize); 481 482 buffer->release(); 483 *pDSI = pEncoderContext->mDSI; 484 } 485 ALOGV("VideoEditorAudioEncoder_open : DONE"); 486 487 cleanUp: 488 if( M4NO_ERROR == err ) { 489 ALOGV("VideoEditorAudioEncoder_open no error"); 490 } else { 491 VideoEditorAudioEncoder_close(pEncoderContext); 492 ALOGV("VideoEditorAudioEncoder_open ERROR 0x%X", err); 493 } 494 ALOGV("VideoEditorAudioEncoder_open end"); 495 return err; 496 } 497 498 M4OSA_ERR VideoEditorAudioEncoder_processInputBuffer(M4OSA_Context pContext, 499 M4ENCODER_AudioBuffer* pInBuffer) { 500 501 M4OSA_ERR err = M4NO_ERROR; 502 VideoEditorAudioEncoder_Context* pEncoderContext = M4OSA_NULL; 503 M4OSA_Int8* pData = M4OSA_NULL; 504 MediaBuffer* buffer = NULL; 505 int32_t nbBuffer = 0; 506 507 ALOGV("VideoEditorAudioEncoder_processInputBuffer begin"); 508 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 509 510 pEncoderContext = (VideoEditorAudioEncoder_Context*)pContext; 511 512 switch( pEncoderContext->mCodecParams->ChannelNum ) { 513 case M4ENCODER_kMono: 514 case M4ENCODER_kStereo: 515 // Let the MediaBuffer own the data so we don't have to free it 516 buffer = new MediaBuffer((size_t)pInBuffer->pTableBufferSize[0]); 517 pData = (M4OSA_Int8*)buffer->data() + buffer->range_offset(); 518 memcpy((void *)pData, (void *)pInBuffer->pTableBuffer[0], 519 pInBuffer->pTableBufferSize[0]); 520 break; 521 default: 522 ALOGV("VEAE_processInputBuffer unsupported channel configuration %d", 523 pEncoderContext->mCodecParams->ChannelNum); 524 VIDEOEDITOR_CHECK(M4OSA_FALSE, M4ERR_PARAMETER); 525 break; 526 } 527 528 ALOGV("VideoEditorAudioEncoder_processInputBuffer : store %d bytes", 529 buffer->range_length()); 530 // Push the buffer to the source 531 nbBuffer = pEncoderContext->mEncoderSource->storeBuffer(buffer); 532 533 cleanUp: 534 if( M4NO_ERROR == err ) { 535 ALOGV("VideoEditorAudioEncoder_processInputBuffer no error"); 536 } else { 537 if( NULL != buffer ) { 538 buffer->release(); 539 } 540 ALOGV("VideoEditorAudioEncoder_processInputBuffer ERROR 0x%X", err); 541 } 542 ALOGV("VideoEditorAudioEncoder_processInputBuffer end"); 543 return err; 544 } 545 546 M4OSA_ERR VideoEditorAudioEncoder_processOutputBuffer(M4OSA_Context pContext, 547 MediaBuffer* buffer, M4ENCODER_AudioBuffer* pOutBuffer) { 548 549 M4OSA_ERR err = M4NO_ERROR; 550 VideoEditorAudioEncoder_Context* pEncoderContext = M4OSA_NULL; 551 M4OSA_UInt32 Cts = 0; 552 int32_t i32Tmp = 0; 553 int64_t i64Tmp = 0; 554 status_t result = OK; 555 556 ALOGV("VideoEditorAudioEncoder_processOutputBuffer begin"); 557 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 558 VIDEOEDITOR_CHECK(M4OSA_NULL != buffer, M4ERR_PARAMETER); 559 VIDEOEDITOR_CHECK(M4OSA_NULL != pOutBuffer, M4ERR_PARAMETER); 560 561 pEncoderContext = (VideoEditorAudioEncoder_Context*)pContext; 562 563 // Process the returned AU 564 if( 0 == buffer->range_length() ) { 565 // Encoder has no data yet, nothing unusual 566 ALOGV("VideoEditorAudioEncoder_processOutputBuffer : buffer is empty"); 567 pOutBuffer->pTableBufferSize[0] = 0; 568 goto cleanUp; 569 } 570 if( buffer->meta_data()->findInt32(kKeyIsCodecConfig, &i32Tmp) && i32Tmp ) { 571 /* This should not happen with software encoder, 572 * DSI was retrieved beforehand */ 573 VIDEOEDITOR_CHECK(M4OSA_FALSE, M4ERR_STATE); 574 } else { 575 // Check the CTS 576 VIDEOEDITOR_CHECK(buffer->meta_data()->findInt64(kKeyTime, &i64Tmp), 577 M4ERR_STATE); 578 Cts = (M4OSA_Int32)(i64Tmp/1000); 579 580 pEncoderContext->mNbOutputFrames++; 581 if( 0 > pEncoderContext->mFirstOutputCts ) { 582 pEncoderContext->mFirstOutputCts = i64Tmp; 583 } 584 pEncoderContext->mLastOutputCts = i64Tmp; 585 586 // Format the AU 587 memcpy((void *)pOutBuffer->pTableBuffer[0], 588 (void *)((M4OSA_MemAddr8)(buffer->data())+buffer->range_offset()), 589 buffer->range_length()); 590 pOutBuffer->pTableBufferSize[0] = (M4OSA_UInt32)buffer->range_length(); 591 } 592 593 cleanUp: 594 // Release the buffer 595 buffer->release(); 596 if( M4NO_ERROR == err ) { 597 ALOGV("VideoEditorAudioEncoder_processOutputBuffer no error"); 598 } else { 599 ALOGV("VideoEditorAudioEncoder_processOutputBuffer ERROR 0x%X", err); 600 } 601 ALOGV("VideoEditorAudioEncoder_processOutputBuffer end"); 602 return err; 603 } 604 605 M4OSA_ERR VideoEditorAudioEncoder_step(M4OSA_Context pContext, 606 M4ENCODER_AudioBuffer* pInBuffer, M4ENCODER_AudioBuffer* pOutBuffer) { 607 M4OSA_ERR err = M4NO_ERROR; 608 VideoEditorAudioEncoder_Context* pEncoderContext = M4OSA_NULL; 609 status_t result = OK; 610 MediaBuffer* buffer = NULL; 611 612 ALOGV("VideoEditorAudioEncoder_step begin"); 613 614 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 615 VIDEOEDITOR_CHECK(M4OSA_NULL != pInBuffer, M4ERR_PARAMETER); 616 VIDEOEDITOR_CHECK(M4OSA_NULL != pOutBuffer, M4ERR_PARAMETER); 617 618 pEncoderContext = (VideoEditorAudioEncoder_Context*)pContext; 619 pEncoderContext->mNbInputFrames++; 620 621 // Push the input buffer to the encoder source 622 err = VideoEditorAudioEncoder_processInputBuffer(pEncoderContext,pInBuffer); 623 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 624 625 // Read 626 result = pEncoderContext->mEncoder->read(&buffer, NULL); 627 VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE); 628 629 // Provide the encoded AU to the writer 630 err = VideoEditorAudioEncoder_processOutputBuffer(pEncoderContext, buffer, 631 pOutBuffer); 632 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 633 634 cleanUp: 635 if( M4NO_ERROR == err ) { 636 ALOGV("VideoEditorAudioEncoder_step no error"); 637 } else { 638 ALOGV("VideoEditorAudioEncoder_step ERROR 0x%X", err); 639 } 640 ALOGV("VideoEditorAudioEncoder_step end"); 641 return err; 642 } 643 644 M4OSA_ERR VideoEditorAudioEncoder_getOption(M4OSA_Context pContext, 645 M4OSA_OptionID optionID, M4OSA_DataOption* optionValue) { 646 M4OSA_ERR err = M4NO_ERROR; 647 VideoEditorAudioEncoder_Context* pEncoderContext = M4OSA_NULL; 648 649 ALOGV("VideoEditorAudioEncoder_getOption begin optionID 0x%X", optionID); 650 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 651 652 pEncoderContext = (VideoEditorAudioEncoder_Context*)pContext; 653 654 switch( optionID ) { 655 default: 656 ALOGV("VideoEditorAudioEncoder_getOption: unsupported optionId 0x%X", 657 optionID); 658 VIDEOEDITOR_CHECK(M4OSA_FALSE, M4ERR_BAD_OPTION_ID); 659 break; 660 } 661 662 cleanUp: 663 if( M4NO_ERROR == err ) { 664 ALOGV("VideoEditorAudioEncoder_getOption no error"); 665 } else { 666 ALOGV("VideoEditorAudioEncoder_getOption ERROR 0x%X", err); 667 } 668 ALOGV("VideoEditorAudioEncoder_getOption end"); 669 return err; 670 } 671 672 M4OSA_ERR VideoEditorAudioEncoder_getInterface( 673 M4ENCODER_AudioFormat format, M4ENCODER_AudioFormat* pFormat, 674 M4ENCODER_AudioGlobalInterface** pEncoderInterface) { 675 M4OSA_ERR err = M4NO_ERROR; 676 677 // Input parameters check 678 VIDEOEDITOR_CHECK(M4OSA_NULL != pFormat, M4ERR_PARAMETER); 679 VIDEOEDITOR_CHECK(M4OSA_NULL != pEncoderInterface, M4ERR_PARAMETER); 680 681 ALOGV("VideoEditorAudioEncoder_getInterface 0x%x 0x%x",pFormat, 682 pEncoderInterface); 683 SAFE_MALLOC(*pEncoderInterface, M4ENCODER_AudioGlobalInterface, 1, 684 "AudioEncoder"); 685 686 *pFormat = format; 687 688 switch( format ) { 689 case M4ENCODER_kAAC: 690 { 691 (*pEncoderInterface)->pFctInit = VideoEditorAudioEncoder_init_AAC; 692 break; 693 } 694 case M4ENCODER_kAMRNB: 695 { 696 (*pEncoderInterface)->pFctInit = VideoEditorAudioEncoder_init_AMRNB; 697 break; 698 } 699 case M4ENCODER_kMP3: 700 { 701 (*pEncoderInterface)->pFctInit = VideoEditorAudioEncoder_init_MP3; 702 break; 703 } 704 default: 705 { 706 ALOGV("VideoEditorAudioEncoder_getInterface: unsupported format %d", 707 format); 708 VIDEOEDITOR_CHECK(M4OSA_FALSE, M4ERR_PARAMETER); 709 break; 710 } 711 } 712 (*pEncoderInterface)->pFctCleanUp = VideoEditorAudioEncoder_cleanup; 713 (*pEncoderInterface)->pFctOpen = VideoEditorAudioEncoder_open; 714 (*pEncoderInterface)->pFctClose = VideoEditorAudioEncoder_close; 715 (*pEncoderInterface)->pFctStep = VideoEditorAudioEncoder_step; 716 (*pEncoderInterface)->pFctGetOption = VideoEditorAudioEncoder_getOption; 717 718 cleanUp: 719 if( M4NO_ERROR == err ) { 720 ALOGV("VideoEditorAudioEncoder_getInterface no error"); 721 } else { 722 *pEncoderInterface = M4OSA_NULL; 723 ALOGV("VideoEditorAudioEncoder_getInterface ERROR 0x%X", err); 724 } 725 return err; 726 } 727 extern "C" { 728 729 M4OSA_ERR VideoEditorAudioEncoder_getInterface_AAC( 730 M4ENCODER_AudioFormat* pFormat, 731 M4ENCODER_AudioGlobalInterface** pEncoderInterface) { 732 return VideoEditorAudioEncoder_getInterface( 733 M4ENCODER_kAAC, pFormat, pEncoderInterface); 734 } 735 736 M4OSA_ERR VideoEditorAudioEncoder_getInterface_AMRNB( 737 M4ENCODER_AudioFormat* pFormat, 738 M4ENCODER_AudioGlobalInterface** pEncoderInterface) { 739 740 return VideoEditorAudioEncoder_getInterface( 741 M4ENCODER_kAMRNB, pFormat, pEncoderInterface); 742 } 743 744 M4OSA_ERR VideoEditorAudioEncoder_getInterface_MP3( 745 M4ENCODER_AudioFormat* pFormat, 746 M4ENCODER_AudioGlobalInterface** pEncoderInterface) { 747 ALOGV("VideoEditorAudioEncoder_getInterface_MP3 no error"); 748 749 return VideoEditorAudioEncoder_getInterface( 750 M4ENCODER_kMP3, pFormat, pEncoderInterface); 751 } 752 753 } // extern "C" 754 755 } // namespace android 756