1/*
2 * Copyright (C) 2017 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#ifndef FLAC_DECODER_H_
18#define FLAC_DECODER_H_
19
20#include <media/stagefright/foundation/ABase.h>
21#include <utils/RefBase.h>
22#include <utils/String8.h>
23
24#include "FLAC/stream_decoder.h"
25
26namespace android {
27
28// packet based FLAC decoder, wrapps libFLAC stream decoder.
29class FLACDecoder : public RefBase {
30
31public:
32    enum {
33        kMaxChannels = 8,
34    };
35
36    static sp<FLACDecoder> Create();
37
38    FLAC__StreamMetadata_StreamInfo getStreamInfo() const {
39        return mStreamInfo;
40    }
41
42    status_t parseMetadata(const uint8_t *inBuffer, size_t inBufferLen);
43    status_t decodeOneFrame(const uint8_t *inBuffer, size_t inBufferLen,
44            short *outBuffer, size_t *outBufferLen);
45    void flush();
46
47protected:
48    FLACDecoder();
49    virtual ~FLACDecoder() override;
50
51private:
52    // stream properties
53    unsigned getMaxBlockSize() const {
54        return mStreamInfo.max_blocksize;
55    }
56    unsigned getSampleRate() const {
57        return mStreamInfo.sample_rate;
58    }
59    unsigned getChannels() const {
60        return mStreamInfo.channels;
61    }
62    unsigned getBitsPerSample() const {
63        return mStreamInfo.bits_per_sample;
64    }
65    FLAC__uint64 getTotalSamples() const {
66        return mStreamInfo.total_samples;
67    }
68
69    status_t addDataToBuffer(const uint8_t *inBuffer, size_t inBufferLen);
70
71    FLAC__StreamDecoder *mDecoder;
72
73    uint8_t *mBuffer;  // cache input bit stream data
74    size_t mBufferLen;  // the memory size of |mBuffer|
75    size_t mBufferPos;  // next byte to read in |mBuffer|
76    // size of input data stored in |mBuffer|, always started at offset 0
77    size_t mBufferDataSize;
78
79    // cached when the STREAMINFO metadata is parsed by libFLAC
80    FLAC__StreamMetadata_StreamInfo mStreamInfo;
81    bool mStreamInfoValid;
82
83    // cached when a decoded PCM block is "written" by libFLAC decoder
84    bool mWriteRequested;
85    bool mWriteCompleted;
86    FLAC__FrameHeader mWriteHeader;
87    FLAC__int32 const * mWriteBuffer[kMaxChannels];
88
89    // most recent error reported by libFLAC decoder
90    FLAC__StreamDecoderErrorStatus mErrorStatus;
91
92    void (*mCopy)(short *dst, const int *src[kMaxChannels], unsigned nSamples, unsigned nChannels);
93
94    status_t init();
95
96    // FLAC stream decoder callbacks as C++ instance methods
97    FLAC__StreamDecoderReadStatus readCallback(FLAC__byte buffer[], size_t *bytes);
98    FLAC__StreamDecoderWriteStatus writeCallback(
99            const FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
100    void metadataCallback(const FLAC__StreamMetadata *metadata);
101    void errorCallback(FLAC__StreamDecoderErrorStatus status);
102
103    DISALLOW_EVIL_CONSTRUCTORS(FLACDecoder);
104};
105
106}  // namespace android
107
108#endif  // FLAC_DECODER_H_
109