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