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,
552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        kMaxOutputBufferSize = 65536,    //TODO check if this can be reduced
562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    };
572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    bool mSignalledError;
592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    OMX_U32 mNumChannels;
612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    OMX_U32 mSampleRate;
622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    OMX_U32 mCompressionLevel;
632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // should the data received by the callback be written to the output port
652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    bool        mEncoderWriteData;
662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    bool        mEncoderReturnedEncodedData;
672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    size_t      mEncoderReturnedNbBytes;
682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    OMX_TICKS  mCurrentInputTimeStamp;
692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    FLAC__StreamEncoder* mFlacStreamEncoder;
712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    void initPorts();
732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    OMX_ERRORTYPE configureEncoder();
752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder callbacks
772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // maps to encoderEncodeFlac()
782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    static FLAC__StreamEncoderWriteStatus flacEncoderWriteCallback(
792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[],
802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            size_t bytes, unsigned samples, unsigned current_frame, void *client_data);
812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    FLAC__StreamEncoderWriteStatus onEncodedFlacAvailable(
832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                const FLAC__byte buffer[],
842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                size_t bytes, unsigned samples, unsigned current_frame);
852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC takes samples aligned on 32bit boundaries, use this buffer for the conversion
872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // before passing the input data to the encoder
882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    FLAC__int32* mInputBufferPcm32;
892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER
912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    unsigned mHeaderOffset;
922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    bool mWroteHeader;
932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    char mHeader[128];
942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#endif
952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    DISALLOW_EVIL_CONSTRUCTORS(SoftFlacEncoder);
972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi};
982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}  // namespace android
1002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi#endif  // SOFT_FLAC_ENC_H_
1022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
103