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