• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //#define LOG_NDEBUG 0
18 #define LOG_TAG "FLACDecoder"
19 #include <utils/Log.h>
20 
21 #include "FLACDecoder.h"
22 
23 #include <audio_utils/primitives.h> // float_from_i32
24 #include <media/stagefright/foundation/ADebug.h>
25 #include <media/stagefright/foundation/hexdump.h>
26 #include <media/stagefright/MediaDefs.h>
27 #include <media/stagefright/MediaErrors.h>
28 #include <media/stagefright/MetaData.h>
29 
30 namespace android {
31 
32 // These are the corresponding callbacks with C++ calling conventions
readCallback(FLAC__byte buffer[],size_t * bytes)33 FLAC__StreamDecoderReadStatus FLACDecoder::readCallback(
34         FLAC__byte buffer[], size_t *bytes) {
35     if (mBuffer == nullptr || mBufferLen == 0) {
36         *bytes = 0;
37         return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
38     }
39 
40     size_t actual = *bytes;
41     if (actual > mBufferDataSize - mBufferPos) {
42         actual = mBufferDataSize - mBufferPos;
43     }
44     memcpy(buffer, mBuffer + mBufferPos, actual);
45     mBufferPos += actual;
46     *bytes = actual;
47     return (actual == 0 ? FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
48                         : FLAC__STREAM_DECODER_READ_STATUS_CONTINUE);
49 }
50 
writeCallback(const FLAC__Frame * frame,const FLAC__int32 * const buffer[])51 FLAC__StreamDecoderWriteStatus FLACDecoder::writeCallback(
52         const FLAC__Frame *frame, const FLAC__int32 * const buffer[])
53 {
54     if (!mWriteRequested) {
55         ALOGE("writeCallback: unexpected");
56         return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
57     }
58 
59     mWriteRequested = false;
60     // FLAC decoder doesn't free or realloc buffer until next frame or finish
61     mWriteHeader = frame->header;
62     memmove(mWriteBuffer, buffer, sizeof(const FLAC__int32 * const) * getChannels());
63     mWriteCompleted = true;
64     return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
65 }
66 
metadataCallback(const FLAC__StreamMetadata * metadata)67 void FLACDecoder::metadataCallback(const FLAC__StreamMetadata *metadata)
68 {
69     switch (metadata->type) {
70         case FLAC__METADATA_TYPE_STREAMINFO:
71         {
72             if (mStreamInfoValid) {
73                 ALOGE("metadataCallback: unexpected STREAMINFO");
74             } else {
75                 mStreamInfo = metadata->data.stream_info;
76                 mStreamInfoValid = true;
77             }
78             break;
79         }
80 
81         /* TODO: enable metadata parsing below.
82         case FLAC__METADATA_TYPE_VORBIS_COMMENT:
83         {
84             const FLAC__StreamMetadata_VorbisComment *vc;
85             vc = &metadata->data.vorbis_comment;
86             for (FLAC__uint32 i = 0; i < vc->num_comments; ++i) {
87                 FLAC__StreamMetadata_VorbisComment_Entry *vce;
88                 vce = &vc->comments[i];
89                 if (mFileMetadata != 0 && vce->entry != NULL) {
90                     parseVorbisComment(mFileMetadata, (const char *) vce->entry,
91                             vce->length);
92                 }
93             }
94             break;
95         }
96 
97         case FLAC__METADATA_TYPE_PICTURE:
98         {
99             if (mFileMetadata != 0) {
100                 const FLAC__StreamMetadata_Picture *p = &metadata->data.picture;
101                 mFileMetadata->setData(kKeyAlbumArt,
102                         MetaData::TYPE_NONE, p->data, p->data_length);
103                 mFileMetadata->setCString(kKeyAlbumArtMIME, p->mime_type);
104             }
105             break;
106         }
107         */
108 
109         default:
110             ALOGW("metadataCallback: unexpected type %u", metadata->type);
111             break;
112     }
113 }
114 
errorCallback(FLAC__StreamDecoderErrorStatus status)115 void FLACDecoder::errorCallback(FLAC__StreamDecoderErrorStatus status)
116 {
117     ALOGE("errorCallback: status=%d", status);
118     mErrorStatus = status;
119 }
120 
121 // Copy samples from FLAC native 32-bit non-interleaved to 16-bit signed
122 // or 32-bit float interleaved.
123 // TODO: Consider moving to audio_utils.  See similar code at FLACExtractor.cpp
124 // These are candidates for optimization if needed.
copyTo16Signed(short * dst,const int * const * src,unsigned nSamples,unsigned nChannels,unsigned bitsPerSample)125 static void copyTo16Signed(
126         short *dst,
127         const int *const *src,
128         unsigned nSamples,
129         unsigned nChannels,
130         unsigned bitsPerSample) {
131     const int leftShift = 16 - (int)bitsPerSample; // cast to int to prevent unsigned overflow.
132     if (leftShift >= 0) {
133         for (unsigned i = 0; i < nSamples; ++i) {
134             for (unsigned c = 0; c < nChannels; ++c) {
135                 *dst++ = src[c][i] << leftShift;
136             }
137         }
138     } else {
139         const int rightShift = -leftShift;
140         for (unsigned i = 0; i < nSamples; ++i) {
141             for (unsigned c = 0; c < nChannels; ++c) {
142                 *dst++ = src[c][i] >> rightShift;
143             }
144         }
145     }
146 }
147 
copyToFloat(float * dst,const int * const * src,unsigned nSamples,unsigned nChannels,unsigned bitsPerSample)148 static void copyToFloat(
149         float *dst,
150         const int *const *src,
151         unsigned nSamples,
152         unsigned nChannels,
153         unsigned bitsPerSample) {
154     const unsigned leftShift = 32 - bitsPerSample;
155     for (unsigned i = 0; i < nSamples; ++i) {
156         for (unsigned c = 0; c < nChannels; ++c) {
157             *dst++ = float_from_i32(src[c][i] << leftShift);
158         }
159     }
160 }
161 
162 // static
Create()163 FLACDecoder *FLACDecoder::Create() {
164     FLACDecoder *decoder = new (std::nothrow) FLACDecoder();
165     if (decoder == NULL || decoder->init() != OK) {
166         delete decoder;
167         return NULL;
168     }
169     return decoder;
170 }
171 
FLACDecoder()172 FLACDecoder::FLACDecoder()
173     : mDecoder(NULL),
174       mBuffer(NULL),
175       mBufferLen(0),
176       mBufferPos(0),
177       mBufferDataSize(0),
178       mStreamInfoValid(false),
179       mWriteRequested(false),
180       mWriteCompleted(false),
181       mErrorStatus((FLAC__StreamDecoderErrorStatus) -1) {
182     ALOGV("ctor:");
183     memset(&mStreamInfo, 0, sizeof(mStreamInfo));
184     memset(&mWriteHeader, 0, sizeof(mWriteHeader));
185     memset(&mWriteBuffer, 0, sizeof(mWriteBuffer));
186 }
187 
~FLACDecoder()188 FLACDecoder::~FLACDecoder() {
189     ALOGV("dtor:");
190     if (mDecoder != NULL) {
191         FLAC__stream_decoder_delete(mDecoder);
192         mDecoder = NULL;
193     }
194     if (mBuffer != NULL) {
195         free(mBuffer);
196     }
197 }
198 
init()199 status_t FLACDecoder::init() {
200     ALOGV("init:");
201     // setup libFLAC stream decoder
202     mDecoder = FLAC__stream_decoder_new();
203     if (mDecoder == NULL) {
204         ALOGE("init: failed to create libFLAC stream decoder");
205         return NO_INIT;
206     }
207     FLAC__stream_decoder_set_md5_checking(mDecoder, false);
208     FLAC__stream_decoder_set_metadata_ignore_all(mDecoder);
209     FLAC__stream_decoder_set_metadata_respond(
210             mDecoder, FLAC__METADATA_TYPE_STREAMINFO);
211     /*
212     FLAC__stream_decoder_set_metadata_respond(
213             mDecoder, FLAC__METADATA_TYPE_PICTURE);
214     FLAC__stream_decoder_set_metadata_respond(
215             mDecoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
216     */
217     static auto read_callback =
218         [] (const FLAC__StreamDecoder * /* decoder */,
219             FLAC__byte buffer[],
220             size_t *bytes,
221             void *client_data) -> FLAC__StreamDecoderReadStatus {
222             return ((FLACDecoder *) client_data)->readCallback(buffer, bytes); };
223 
224     static auto write_callback =
225         [] (const FLAC__StreamDecoder * /* decoder */,
226             const FLAC__Frame *frame,
227             const FLAC__int32 * const buffer[],
228             void *client_data) -> FLAC__StreamDecoderWriteStatus {
229             return ((FLACDecoder *) client_data)->writeCallback(frame, buffer); };
230 
231     static auto metadata_callback =
232         [] (const FLAC__StreamDecoder * /* decoder */,
233             const FLAC__StreamMetadata *metadata,
234             void *client_data) {
235             ((FLACDecoder *) client_data)->metadataCallback(metadata); };
236 
237     static auto error_callback =
238         [] (const FLAC__StreamDecoder * /* decoder */,
239             FLAC__StreamDecoderErrorStatus status,
240             void *client_data) {
241             ((FLACDecoder *) client_data)->errorCallback(status); };
242 
243     FLAC__StreamDecoderInitStatus initStatus =
244         FLAC__stream_decoder_init_stream(
245                 mDecoder,
246                 read_callback,
247                 NULL /* seek_callback */,
248                 NULL /* tell_callback */,
249                 NULL /* length_callback */,
250                 NULL /* eof_callback */,
251                 write_callback,
252                 metadata_callback,
253                 error_callback,
254                 (void *)this);
255     if (initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
256         ALOGE("init: init_stream failed, returned %d", initStatus);
257         return NO_INIT;
258     }
259     return OK;
260 }
261 
flush()262 void FLACDecoder::flush() {
263     ALOGV("flush:");
264     mBufferPos = 0;
265     mBufferDataSize = 0;
266     mStreamInfoValid = false;
267     if (!FLAC__stream_decoder_reset(mDecoder)) {
268         ALOGE("flush: failed to reset FLAC stream decoder");
269     }
270 }
271 
parseMetadata(const uint8_t * inBuffer,size_t inBufferLen)272 status_t FLACDecoder::parseMetadata(const uint8_t *inBuffer, size_t inBufferLen) {
273     ALOGV("parseMetadata: input size(%zu)", inBufferLen);
274     //hexdump(inBuffer, inBufferLen);
275 
276     if (mStreamInfoValid) {
277         ALOGE("parseMetadata: already have full metadata blocks");
278         return ERROR_MALFORMED;
279     }
280 
281     status_t err = addDataToBuffer(inBuffer, inBufferLen);
282     if (err != OK) {
283         ALOGE("parseMetadata: addDataToBuffer returns error %d", err);
284         return err;
285     }
286 
287     if (!FLAC__stream_decoder_process_until_end_of_metadata(mDecoder)) {
288         if (!FLAC__stream_decoder_reset(mDecoder)) {
289             ALOGE("parseMetadata: failed to reset FLAC stream decoder");
290             return FAILED_TRANSACTION;
291         }
292         mBufferPos = 0;
293         ALOGV("parseMetadata: do not have full metadata blocks yet");
294         return WOULD_BLOCK;
295     }
296 
297     if (!mStreamInfoValid) {
298         ALOGE("parseMetadata: missing STREAMINFO");
299         return ERROR_MALFORMED;
300     }
301 
302     // check block size
303     if (getMaxBlockSize() == 0) {
304         ALOGE("wrong max blocksize %u", getMaxBlockSize());
305         mStreamInfoValid = false;
306         return ERROR_MALFORMED;
307     }
308 
309     // check channel count
310     if (getChannels() == 0 || getChannels() > kMaxChannels) {
311         ALOGE("unsupported channel count %u", getChannels());
312         mStreamInfoValid = false;
313         return ERROR_MALFORMED;
314     }
315 
316     // check bit depth
317     switch (getBitsPerSample()) {
318         case 8:
319         case 16:
320         case 24:
321         case 32: // generally rare, but is supported in the framework
322             break;
323 
324         default:
325             ALOGE("parseMetadata: unsupported bits per sample %u", getBitsPerSample());
326             mStreamInfoValid = false;
327             return ERROR_MALFORMED;
328     }
329 
330     // Now we have all metadata blocks.
331     mBufferPos = 0;
332     mBufferDataSize = 0;
333 
334     return OK;
335 }
336 
decodeOneFrame(const uint8_t * inBuffer,size_t inBufferLen,void * outBuffer,size_t * outBufferLen,bool outputFloat)337 status_t FLACDecoder::decodeOneFrame(const uint8_t *inBuffer, size_t inBufferLen,
338         void *outBuffer, size_t *outBufferLen, bool outputFloat) {
339     ALOGV("decodeOneFrame: input size(%zu)", inBufferLen);
340 
341     if (!mStreamInfoValid) {
342         ALOGW("decodeOneFrame: no streaminfo metadata block");
343     }
344 
345     if (inBufferLen != 0) {
346         status_t err = addDataToBuffer(inBuffer, inBufferLen);
347         if (err != OK) {
348             ALOGW("decodeOneFrame: addDataToBuffer returns error %d", err);
349             return err;
350         }
351     }
352 
353     mWriteRequested = true;
354     mWriteCompleted = false;
355     if (!FLAC__stream_decoder_process_single(mDecoder)) {
356         ALOGE("decodeOneFrame: process_single failed");
357         return ERROR_MALFORMED;
358     }
359     if (!mWriteCompleted) {
360         ALOGV("decodeOneFrame: write did not complete");
361         if (outBufferLen) {
362             *outBufferLen = 0;
363         }
364         return OK;
365     }
366 
367     // frame header should be consistent with STREAMINFO
368     unsigned blocksize = mWriteHeader.blocksize;
369     if (blocksize == 0 || blocksize > getMaxBlockSize()) {
370         ALOGE("decodeOneFrame: write invalid blocksize %u", blocksize);
371         return ERROR_MALFORMED;
372     }
373     if (mWriteHeader.sample_rate != getSampleRate() ||
374         mWriteHeader.channels != getChannels() ||
375         mWriteHeader.bits_per_sample != getBitsPerSample()) {
376         ALOGE("decodeOneFrame: parameters are changed mid-stream: %d/%d/%d -> %d/%d/%d",
377                 getSampleRate(), getChannels(), getBitsPerSample(),
378                 mWriteHeader.sample_rate, mWriteHeader.channels, mWriteHeader.bits_per_sample);
379         return ERROR_MALFORMED;
380     }
381     if (mWriteHeader.number_type != FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER) {
382         ALOGE("decodeOneFrame: number type is %d, expected %d",
383                 mWriteHeader.number_type, FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
384         return ERROR_MALFORMED;
385     }
386 
387     const unsigned channels = getChannels();
388     const size_t sampleSize = outputFloat ? sizeof(float) : sizeof(int16_t);
389     const size_t frameSize = channels * sampleSize;
390     size_t bufferSize = blocksize * frameSize;
391     if (bufferSize > *outBufferLen) {
392         ALOGW("decodeOneFrame: output buffer holds only partial frame %zu:%zu",
393                 *outBufferLen, bufferSize);
394         blocksize = *outBufferLen / frameSize;
395         bufferSize = blocksize * frameSize;
396     }
397 
398     // copy PCM from FLAC write buffer to output buffer, with interleaving
399 
400     const unsigned bitsPerSample = getBitsPerSample();
401     if (outputFloat) {
402         copyToFloat(reinterpret_cast<float*>(outBuffer),
403                     mWriteBuffer,
404                     blocksize,
405                     channels,
406                     bitsPerSample);
407     } else {
408         copyTo16Signed(reinterpret_cast<short*>(outBuffer),
409                        mWriteBuffer,
410                        blocksize,
411                        channels,
412                        bitsPerSample);
413     }
414     *outBufferLen = bufferSize;
415     return OK;
416 }
417 
addDataToBuffer(const uint8_t * inBuffer,size_t inBufferLen)418 status_t FLACDecoder::addDataToBuffer(const uint8_t *inBuffer, size_t inBufferLen) {
419     // mBufferPos should be no larger than mBufferDataSize
420     if (inBufferLen > SIZE_MAX - (mBufferDataSize - mBufferPos)) {
421         ALOGE("addDataToBuffer: input buffer is too large");
422         return ERROR_MALFORMED;
423     }
424 
425     if (inBufferLen > mBufferLen - mBufferDataSize) {
426         if (mBufferPos > 0) {
427             memmove(mBuffer, mBuffer + mBufferPos, mBufferDataSize - mBufferPos);
428             mBufferDataSize -= mBufferPos;
429             mBufferPos = 0;
430         }
431         if (inBufferLen > mBufferLen - mBufferDataSize) {
432             mBuffer = (uint8_t*)realloc(mBuffer, mBufferDataSize + inBufferLen);
433             if (mBuffer == nullptr) {
434                 mBufferDataSize = 0;
435                 mBufferLen = 0;
436                 ALOGE("addDataToBuffer: failed to allocate memory for input buffer");
437                 return NO_MEMORY;
438             }
439             mBufferLen = mBufferDataSize + inBufferLen;
440         }
441     }
442 
443     memcpy(mBuffer + mBufferDataSize, inBuffer, inBufferLen);
444     mBufferDataSize += inBufferLen;
445     return OK;
446 }
447 
448 }  // namespace android
449