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