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