12f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi/*
22f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * Copyright (C) 2012 The Android Open Source Project
32f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi *
42f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
52f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * you may not use this file except in compliance with the License.
62f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * You may obtain a copy of the License at
72f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi *
82f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
92f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi *
102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * See the License for the specific language governing permissions and
142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi * limitations under the License.
152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi */
162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#ifndef SOFT_FLAC_ENC_H_
182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#define SOFT_FLAC_ENC_H_
202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#include "SimpleSoftOMXComponent.h"
222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#include "FLAC/stream_encoder.h"
242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi// use this symbol to have the first output buffer start with FLAC frame header so a dump of
262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi// all the output buffers can be opened as a .flac file
272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi//#define WRITE_FLAC_HEADER_IN_FIRST_BUFFER
282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivinamespace android {
302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistruct SoftFlacEncoder : public SimpleSoftOMXComponent {
322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    SoftFlacEncoder(const char *name,
332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            const OMX_CALLBACKTYPE *callbacks,
342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            OMX_PTR appData,
352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            OMX_COMPONENTTYPE **component);
362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    virtual OMX_ERRORTYPE initCheck() const;
382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Triviprotected:
402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    virtual ~SoftFlacEncoder();
412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    virtual OMX_ERRORTYPE internalGetParameter(
432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            OMX_INDEXTYPE index, OMX_PTR params);
442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    virtual OMX_ERRORTYPE internalSetParameter(
462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            OMX_INDEXTYPE index, const OMX_PTR params);
472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    virtual void onQueueFilled(OMX_U32 portIndex);
492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Triviprivate:
512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    enum {
532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        kNumBuffers = 2,
542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        kMaxNumSamplesPerFrame = 1152,
55eb8709e3c65b59e85b882b5ca8710068708671beAndreas Huber        kMaxInputBufferSize = kMaxNumSamplesPerFrame * sizeof(int16_t) * 2,
562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        kMaxOutputBufferSize = 65536,    //TODO check if this can be reduced
572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    };
582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    bool mSignalledError;
602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    OMX_U32 mNumChannels;
622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    OMX_U32 mSampleRate;
632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    OMX_U32 mCompressionLevel;
642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // should the data received by the callback be written to the output port
662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    bool        mEncoderWriteData;
672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    bool        mEncoderReturnedEncodedData;
682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    size_t      mEncoderReturnedNbBytes;
692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    OMX_TICKS  mCurrentInputTimeStamp;
702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    FLAC__StreamEncoder* mFlacStreamEncoder;
722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    void initPorts();
742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    OMX_ERRORTYPE configureEncoder();
762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder callbacks
782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // maps to encoderEncodeFlac()
792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    static FLAC__StreamEncoderWriteStatus flacEncoderWriteCallback(
802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[],
812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            size_t bytes, unsigned samples, unsigned current_frame, void *client_data);
822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    FLAC__StreamEncoderWriteStatus onEncodedFlacAvailable(
842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                const FLAC__byte buffer[],
852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                size_t bytes, unsigned samples, unsigned current_frame);
862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC takes samples aligned on 32bit boundaries, use this buffer for the conversion
882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // before passing the input data to the encoder
892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    FLAC__int32* mInputBufferPcm32;
902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER
922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    unsigned mHeaderOffset;
932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    bool mWroteHeader;
942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    char mHeader[128];
952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#endif
962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    DISALLOW_EVIL_CONSTRUCTORS(SoftFlacEncoder);
982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi};
992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}  // namespace android
1012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#endif  // SOFT_FLAC_ENC_H_
1032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
104