VideoEditorAudioEncoder.cpp revision 2703f23af496c13cfa39cc7e157fa12d1cb4c169
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 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 82sp<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 92VideoEditorAudioEncoderSource::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 103VideoEditorAudioEncoderSource::~VideoEditorAudioEncoderSource() { 104 ALOGV("VideoEditorAudioEncoderSource::~VideoEditorAudioEncoderSource"); 105 106 if( STARTED == mState ) { 107 stop(); 108 } 109} 110 111status_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 124cleanUp: 125 ALOGV("VideoEditorAudioEncoderSource::start END (0x%x)", err); 126 return err; 127} 128 129status_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 158sp<MetaData> VideoEditorAudioEncoderSource::getFormat() { 159 ALOGV("VideoEditorAudioEncoderSource::getFormat"); 160 return mEncFormat; 161} 162 163status_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 196int32_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*/ 226typedef 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 239M4OSA_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 252cleanUp: 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 262M4OSA_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 277cleanUp: 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 289M4OSA_ERR VideoEditorAudioEncoder_init_AAC(M4OSA_Context* pContext, 290 M4OSA_Void* pUserData) { 291 return VideoEditorAudioEncoder_init(M4ENCODER_kAAC, pContext, pUserData); 292} 293 294M4OSA_ERR VideoEditorAudioEncoder_init_AMRNB(M4OSA_Context* pContext, 295 M4OSA_Void* pUserData) { 296 return VideoEditorAudioEncoder_init(M4ENCODER_kAMRNB, pContext, pUserData); 297} 298 299M4OSA_ERR VideoEditorAudioEncoder_init_MP3(M4OSA_Context* pContext, 300 M4OSA_Void* pUserData) { 301 return VideoEditorAudioEncoder_init(M4ENCODER_kMP3, pContext, pUserData); 302} 303 304M4OSA_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 331cleanUp: 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 341M4OSA_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 pEncoderContext->mEncoder = OMXCodec::Create( 447 pEncoderContext->mClient.interface(), encoderMetadata, true, 448 pEncoderContext->mEncoderSource, NULL, codecFlags); 449 VIDEOEDITOR_CHECK(NULL != pEncoderContext->mEncoder.get(), M4ERR_STATE); 450 451 // Start the graph 452 result = pEncoderContext->mEncoder->start(); 453 VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE); 454 455 // Get AAC DSI, this code can only work with software encoder 456 if( M4ENCODER_kAAC == pEncoderContext->mCodecParams->Format ) { 457 int32_t isCodecConfig = 0; 458 MediaBuffer* buffer = NULL; 459 460 // Read once to get the DSI 461 result = pEncoderContext->mEncoder->read(&buffer, NULL); 462 VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE); 463 VIDEOEDITOR_CHECK(buffer->meta_data()->findInt32(kKeyIsCodecConfig, 464 &isCodecConfig) && isCodecConfig, M4ERR_STATE); 465 466 // Save the DSI 467 pEncoderContext->mDSI.infoSize = (M4OSA_UInt32)buffer->range_length(); 468 SAFE_MALLOC(pEncoderContext->mDSI.pInfo, M4OSA_Int8, 469 pEncoderContext->mDSI.infoSize, "Encoder header"); 470 471 memcpy((void *)pEncoderContext->mDSI.pInfo, 472 (void *)((M4OSA_MemAddr8)(buffer->data())+buffer->range_offset()), 473 pEncoderContext->mDSI.infoSize); 474 475 buffer->release(); 476 *pDSI = pEncoderContext->mDSI; 477 } 478 ALOGV("VideoEditorAudioEncoder_open : DONE"); 479 480cleanUp: 481 if( M4NO_ERROR == err ) { 482 ALOGV("VideoEditorAudioEncoder_open no error"); 483 } else { 484 VideoEditorAudioEncoder_close(pEncoderContext); 485 ALOGV("VideoEditorAudioEncoder_open ERROR 0x%X", err); 486 } 487 ALOGV("VideoEditorAudioEncoder_open end"); 488 return err; 489} 490 491M4OSA_ERR VideoEditorAudioEncoder_processInputBuffer(M4OSA_Context pContext, 492 M4ENCODER_AudioBuffer* pInBuffer) { 493 494 M4OSA_ERR err = M4NO_ERROR; 495 VideoEditorAudioEncoder_Context* pEncoderContext = M4OSA_NULL; 496 M4OSA_Int8* pData = M4OSA_NULL; 497 MediaBuffer* buffer = NULL; 498 int32_t nbBuffer = 0; 499 500 ALOGV("VideoEditorAudioEncoder_processInputBuffer begin"); 501 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 502 503 pEncoderContext = (VideoEditorAudioEncoder_Context*)pContext; 504 505 switch( pEncoderContext->mCodecParams->ChannelNum ) { 506 case M4ENCODER_kMono: 507 case M4ENCODER_kStereo: 508 // Let the MediaBuffer own the data so we don't have to free it 509 buffer = new MediaBuffer((size_t)pInBuffer->pTableBufferSize[0]); 510 pData = (M4OSA_Int8*)buffer->data() + buffer->range_offset(); 511 memcpy((void *)pData, (void *)pInBuffer->pTableBuffer[0], 512 pInBuffer->pTableBufferSize[0]); 513 break; 514 default: 515 ALOGV("VEAE_processInputBuffer unsupported channel configuration %d", 516 pEncoderContext->mCodecParams->ChannelNum); 517 VIDEOEDITOR_CHECK(M4OSA_FALSE, M4ERR_PARAMETER); 518 break; 519 } 520 521 ALOGV("VideoEditorAudioEncoder_processInputBuffer : store %d bytes", 522 buffer->range_length()); 523 // Push the buffer to the source 524 nbBuffer = pEncoderContext->mEncoderSource->storeBuffer(buffer); 525 526cleanUp: 527 if( M4NO_ERROR == err ) { 528 ALOGV("VideoEditorAudioEncoder_processInputBuffer no error"); 529 } else { 530 if( NULL != buffer ) { 531 buffer->release(); 532 } 533 ALOGV("VideoEditorAudioEncoder_processInputBuffer ERROR 0x%X", err); 534 } 535 ALOGV("VideoEditorAudioEncoder_processInputBuffer end"); 536 return err; 537} 538 539M4OSA_ERR VideoEditorAudioEncoder_processOutputBuffer(M4OSA_Context pContext, 540 MediaBuffer* buffer, M4ENCODER_AudioBuffer* pOutBuffer) { 541 542 M4OSA_ERR err = M4NO_ERROR; 543 VideoEditorAudioEncoder_Context* pEncoderContext = M4OSA_NULL; 544 M4OSA_UInt32 Cts = 0; 545 int32_t i32Tmp = 0; 546 int64_t i64Tmp = 0; 547 status_t result = OK; 548 549 ALOGV("VideoEditorAudioEncoder_processOutputBuffer begin"); 550 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 551 VIDEOEDITOR_CHECK(M4OSA_NULL != buffer, M4ERR_PARAMETER); 552 VIDEOEDITOR_CHECK(M4OSA_NULL != pOutBuffer, M4ERR_PARAMETER); 553 554 pEncoderContext = (VideoEditorAudioEncoder_Context*)pContext; 555 556 // Process the returned AU 557 if( 0 == buffer->range_length() ) { 558 // Encoder has no data yet, nothing unusual 559 ALOGV("VideoEditorAudioEncoder_processOutputBuffer : buffer is empty"); 560 pOutBuffer->pTableBufferSize[0] = 0; 561 goto cleanUp; 562 } 563 if( buffer->meta_data()->findInt32(kKeyIsCodecConfig, &i32Tmp) && i32Tmp ) { 564 /* This should not happen with software encoder, 565 * DSI was retrieved beforehand */ 566 VIDEOEDITOR_CHECK(M4OSA_FALSE, M4ERR_STATE); 567 } else { 568 // Check the CTS 569 VIDEOEDITOR_CHECK(buffer->meta_data()->findInt64(kKeyTime, &i64Tmp), 570 M4ERR_STATE); 571 Cts = (M4OSA_Int32)(i64Tmp/1000); 572 573 pEncoderContext->mNbOutputFrames++; 574 if( 0 > pEncoderContext->mFirstOutputCts ) { 575 pEncoderContext->mFirstOutputCts = i64Tmp; 576 } 577 pEncoderContext->mLastOutputCts = i64Tmp; 578 579 // Format the AU 580 memcpy((void *)pOutBuffer->pTableBuffer[0], 581 (void *)((M4OSA_MemAddr8)(buffer->data())+buffer->range_offset()), 582 buffer->range_length()); 583 pOutBuffer->pTableBufferSize[0] = (M4OSA_UInt32)buffer->range_length(); 584 } 585 586cleanUp: 587 // Release the buffer 588 buffer->release(); 589 if( M4NO_ERROR == err ) { 590 ALOGV("VideoEditorAudioEncoder_processOutputBuffer no error"); 591 } else { 592 ALOGV("VideoEditorAudioEncoder_processOutputBuffer ERROR 0x%X", err); 593 } 594 ALOGV("VideoEditorAudioEncoder_processOutputBuffer end"); 595 return err; 596} 597 598M4OSA_ERR VideoEditorAudioEncoder_step(M4OSA_Context pContext, 599 M4ENCODER_AudioBuffer* pInBuffer, M4ENCODER_AudioBuffer* pOutBuffer) { 600 M4OSA_ERR err = M4NO_ERROR; 601 VideoEditorAudioEncoder_Context* pEncoderContext = M4OSA_NULL; 602 status_t result = OK; 603 MediaBuffer* buffer = NULL; 604 605 ALOGV("VideoEditorAudioEncoder_step begin"); 606 607 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 608 VIDEOEDITOR_CHECK(M4OSA_NULL != pInBuffer, M4ERR_PARAMETER); 609 VIDEOEDITOR_CHECK(M4OSA_NULL != pOutBuffer, M4ERR_PARAMETER); 610 611 pEncoderContext = (VideoEditorAudioEncoder_Context*)pContext; 612 pEncoderContext->mNbInputFrames++; 613 614 // Push the input buffer to the encoder source 615 err = VideoEditorAudioEncoder_processInputBuffer(pEncoderContext,pInBuffer); 616 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 617 618 // Read 619 result = pEncoderContext->mEncoder->read(&buffer, NULL); 620 VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE); 621 622 // Provide the encoded AU to the writer 623 err = VideoEditorAudioEncoder_processOutputBuffer(pEncoderContext, buffer, 624 pOutBuffer); 625 VIDEOEDITOR_CHECK(M4NO_ERROR == err, err); 626 627cleanUp: 628 if( M4NO_ERROR == err ) { 629 ALOGV("VideoEditorAudioEncoder_step no error"); 630 } else { 631 ALOGV("VideoEditorAudioEncoder_step ERROR 0x%X", err); 632 } 633 ALOGV("VideoEditorAudioEncoder_step end"); 634 return err; 635} 636 637M4OSA_ERR VideoEditorAudioEncoder_getOption(M4OSA_Context pContext, 638 M4OSA_OptionID optionID, M4OSA_DataOption* optionValue) { 639 M4OSA_ERR err = M4NO_ERROR; 640 VideoEditorAudioEncoder_Context* pEncoderContext = M4OSA_NULL; 641 642 ALOGV("VideoEditorAudioEncoder_getOption begin optionID 0x%X", optionID); 643 VIDEOEDITOR_CHECK(M4OSA_NULL != pContext, M4ERR_PARAMETER); 644 645 pEncoderContext = (VideoEditorAudioEncoder_Context*)pContext; 646 647 switch( optionID ) { 648 default: 649 ALOGV("VideoEditorAudioEncoder_getOption: unsupported optionId 0x%X", 650 optionID); 651 VIDEOEDITOR_CHECK(M4OSA_FALSE, M4ERR_BAD_OPTION_ID); 652 break; 653 } 654 655cleanUp: 656 if( M4NO_ERROR == err ) { 657 ALOGV("VideoEditorAudioEncoder_getOption no error"); 658 } else { 659 ALOGV("VideoEditorAudioEncoder_getOption ERROR 0x%X", err); 660 } 661 ALOGV("VideoEditorAudioEncoder_getOption end"); 662 return err; 663} 664 665M4OSA_ERR VideoEditorAudioEncoder_getInterface( 666 M4ENCODER_AudioFormat format, M4ENCODER_AudioFormat* pFormat, 667 M4ENCODER_AudioGlobalInterface** pEncoderInterface) { 668 M4OSA_ERR err = M4NO_ERROR; 669 670 // Input parameters check 671 VIDEOEDITOR_CHECK(M4OSA_NULL != pFormat, M4ERR_PARAMETER); 672 VIDEOEDITOR_CHECK(M4OSA_NULL != pEncoderInterface, M4ERR_PARAMETER); 673 674 ALOGV("VideoEditorAudioEncoder_getInterface 0x%x 0x%x",pFormat, 675 pEncoderInterface); 676 SAFE_MALLOC(*pEncoderInterface, M4ENCODER_AudioGlobalInterface, 1, 677 "AudioEncoder"); 678 679 *pFormat = format; 680 681 switch( format ) { 682 case M4ENCODER_kAAC: 683 { 684 (*pEncoderInterface)->pFctInit = VideoEditorAudioEncoder_init_AAC; 685 break; 686 } 687 case M4ENCODER_kAMRNB: 688 { 689 (*pEncoderInterface)->pFctInit = VideoEditorAudioEncoder_init_AMRNB; 690 break; 691 } 692 case M4ENCODER_kMP3: 693 { 694 (*pEncoderInterface)->pFctInit = VideoEditorAudioEncoder_init_MP3; 695 break; 696 } 697 default: 698 { 699 ALOGV("VideoEditorAudioEncoder_getInterface: unsupported format %d", 700 format); 701 VIDEOEDITOR_CHECK(M4OSA_FALSE, M4ERR_PARAMETER); 702 break; 703 } 704 } 705 (*pEncoderInterface)->pFctCleanUp = VideoEditorAudioEncoder_cleanup; 706 (*pEncoderInterface)->pFctOpen = VideoEditorAudioEncoder_open; 707 (*pEncoderInterface)->pFctClose = VideoEditorAudioEncoder_close; 708 (*pEncoderInterface)->pFctStep = VideoEditorAudioEncoder_step; 709 (*pEncoderInterface)->pFctGetOption = VideoEditorAudioEncoder_getOption; 710 711cleanUp: 712 if( M4NO_ERROR == err ) { 713 ALOGV("VideoEditorAudioEncoder_getInterface no error"); 714 } else { 715 *pEncoderInterface = M4OSA_NULL; 716 ALOGV("VideoEditorAudioEncoder_getInterface ERROR 0x%X", err); 717 } 718 return err; 719} 720extern "C" { 721 722M4OSA_ERR VideoEditorAudioEncoder_getInterface_AAC( 723 M4ENCODER_AudioFormat* pFormat, 724 M4ENCODER_AudioGlobalInterface** pEncoderInterface) { 725 return VideoEditorAudioEncoder_getInterface( 726 M4ENCODER_kAAC, pFormat, pEncoderInterface); 727} 728 729M4OSA_ERR VideoEditorAudioEncoder_getInterface_AMRNB( 730 M4ENCODER_AudioFormat* pFormat, 731 M4ENCODER_AudioGlobalInterface** pEncoderInterface) { 732 733 return VideoEditorAudioEncoder_getInterface( 734 M4ENCODER_kAMRNB, pFormat, pEncoderInterface); 735} 736 737M4OSA_ERR VideoEditorAudioEncoder_getInterface_MP3( 738 M4ENCODER_AudioFormat* pFormat, 739 M4ENCODER_AudioGlobalInterface** pEncoderInterface) { 740 ALOGV("VideoEditorAudioEncoder_getInterface_MP3 no error"); 741 742 return VideoEditorAudioEncoder_getInterface( 743 M4ENCODER_kMP3, pFormat, pEncoderInterface); 744} 745 746} // extern "C" 747 748} // namespace android 749