blob: 098fcf97454c7a5f76a773562930127f4e88ca71 [file] [log] [blame]
Glenn Kasten856990b2011-01-13 11:17:00 -08001/*
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//#define LOG_NDEBUG 0
18#define LOG_TAG "FLACExtractor"
19#include <utils/Log.h>
20
21#include "include/FLACExtractor.h"
22// Vorbis comments
23#include "include/OggExtractor.h"
24// libFLAC parser
25#include "FLAC/stream_decoder.h"
26
27#include <media/stagefright/foundation/ADebug.h>
28#include <media/stagefright/DataSource.h>
29#include <media/stagefright/MediaBufferGroup.h>
30#include <media/stagefright/MediaDefs.h>
31#include <media/stagefright/MetaData.h>
32#include <media/stagefright/MediaSource.h>
33#include <media/stagefright/MediaBuffer.h>
34
35namespace android {
36
37class FLACParser;
38
39class FLACSource : public MediaSource {
40
41public:
42 FLACSource(
43 const sp<DataSource> &dataSource,
44 const sp<MetaData> &trackMetadata);
45
46 virtual status_t start(MetaData *params);
47 virtual status_t stop();
48 virtual sp<MetaData> getFormat();
49
50 virtual status_t read(
51 MediaBuffer **buffer, const ReadOptions *options = NULL);
52
53protected:
54 virtual ~FLACSource();
55
56private:
57 sp<DataSource> mDataSource;
58 sp<MetaData> mTrackMetadata;
59 sp<FLACParser> mParser;
60 bool mInitCheck;
61 bool mStarted;
62
63 status_t init();
64
65 // no copy constructor or assignment
66 FLACSource(const FLACSource &);
67 FLACSource &operator=(const FLACSource &);
68
69};
70
71// FLACParser wraps a C libFLAC parser aka stream decoder
72
73class FLACParser : public RefBase {
74
75public:
76 FLACParser(
77 const sp<DataSource> &dataSource,
78 // If metadata pointers aren't provided, we don't fill them
79 const sp<MetaData> &fileMetadata = 0,
80 const sp<MetaData> &trackMetadata = 0);
81
82 status_t initCheck() const {
83 return mInitCheck;
84 }
85
86 // stream properties
87 unsigned getMaxBlockSize() const {
88 return mStreamInfo.max_blocksize;
89 }
90 unsigned getSampleRate() const {
91 return mStreamInfo.sample_rate;
92 }
93 unsigned getChannels() const {
94 return mStreamInfo.channels;
95 }
96 unsigned getBitsPerSample() const {
97 return mStreamInfo.bits_per_sample;
98 }
99 FLAC__uint64 getTotalSamples() const {
100 return mStreamInfo.total_samples;
101 }
102
103 // media buffers
104 void allocateBuffers();
105 void releaseBuffers();
106 MediaBuffer *readBuffer() {
107 return readBuffer(false, 0LL);
108 }
109 MediaBuffer *readBuffer(FLAC__uint64 sample) {
110 return readBuffer(true, sample);
111 }
112
113protected:
114 virtual ~FLACParser();
115
116private:
117 sp<DataSource> mDataSource;
118 sp<MetaData> mFileMetadata;
119 sp<MetaData> mTrackMetadata;
120 bool mInitCheck;
121
122 // media buffers
123 size_t mMaxBufferSize;
124 MediaBufferGroup *mGroup;
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100125 void (*mCopy)(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels);
Glenn Kasten856990b2011-01-13 11:17:00 -0800126
127 // handle to underlying libFLAC parser
128 FLAC__StreamDecoder *mDecoder;
129
130 // current position within the data source
131 off64_t mCurrentPos;
132 bool mEOF;
133
134 // cached when the STREAMINFO metadata is parsed by libFLAC
135 FLAC__StreamMetadata_StreamInfo mStreamInfo;
136 bool mStreamInfoValid;
137
138 // cached when a decoded PCM block is "written" by libFLAC parser
139 bool mWriteRequested;
140 bool mWriteCompleted;
141 FLAC__FrameHeader mWriteHeader;
142 const FLAC__int32 * const *mWriteBuffer;
143
144 // most recent error reported by libFLAC parser
145 FLAC__StreamDecoderErrorStatus mErrorStatus;
146
147 status_t init();
148 MediaBuffer *readBuffer(bool doSeek, FLAC__uint64 sample);
149
150 // no copy constructor or assignment
151 FLACParser(const FLACParser &);
152 FLACParser &operator=(const FLACParser &);
153
154 // FLAC parser callbacks as C++ instance methods
155 FLAC__StreamDecoderReadStatus readCallback(
156 FLAC__byte buffer[], size_t *bytes);
157 FLAC__StreamDecoderSeekStatus seekCallback(
158 FLAC__uint64 absolute_byte_offset);
159 FLAC__StreamDecoderTellStatus tellCallback(
160 FLAC__uint64 *absolute_byte_offset);
161 FLAC__StreamDecoderLengthStatus lengthCallback(
162 FLAC__uint64 *stream_length);
163 FLAC__bool eofCallback();
164 FLAC__StreamDecoderWriteStatus writeCallback(
165 const FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
166 void metadataCallback(const FLAC__StreamMetadata *metadata);
167 void errorCallback(FLAC__StreamDecoderErrorStatus status);
168
169 // FLAC parser callbacks as C-callable functions
170 static FLAC__StreamDecoderReadStatus read_callback(
171 const FLAC__StreamDecoder *decoder,
172 FLAC__byte buffer[], size_t *bytes,
173 void *client_data);
174 static FLAC__StreamDecoderSeekStatus seek_callback(
175 const FLAC__StreamDecoder *decoder,
176 FLAC__uint64 absolute_byte_offset,
177 void *client_data);
178 static FLAC__StreamDecoderTellStatus tell_callback(
179 const FLAC__StreamDecoder *decoder,
180 FLAC__uint64 *absolute_byte_offset,
181 void *client_data);
182 static FLAC__StreamDecoderLengthStatus length_callback(
183 const FLAC__StreamDecoder *decoder,
184 FLAC__uint64 *stream_length,
185 void *client_data);
186 static FLAC__bool eof_callback(
187 const FLAC__StreamDecoder *decoder,
188 void *client_data);
189 static FLAC__StreamDecoderWriteStatus write_callback(
190 const FLAC__StreamDecoder *decoder,
191 const FLAC__Frame *frame, const FLAC__int32 * const buffer[],
192 void *client_data);
193 static void metadata_callback(
194 const FLAC__StreamDecoder *decoder,
195 const FLAC__StreamMetadata *metadata,
196 void *client_data);
197 static void error_callback(
198 const FLAC__StreamDecoder *decoder,
199 FLAC__StreamDecoderErrorStatus status,
200 void *client_data);
201
202};
203
204// The FLAC parser calls our C++ static callbacks using C calling conventions,
205// inside FLAC__stream_decoder_process_until_end_of_metadata
206// and FLAC__stream_decoder_process_single.
207// We immediately then call our corresponding C++ instance methods
208// with the same parameter list, but discard redundant information.
209
210FLAC__StreamDecoderReadStatus FLACParser::read_callback(
211 const FLAC__StreamDecoder *decoder, FLAC__byte buffer[],
212 size_t *bytes, void *client_data)
213{
214 return ((FLACParser *) client_data)->readCallback(buffer, bytes);
215}
216
217FLAC__StreamDecoderSeekStatus FLACParser::seek_callback(
218 const FLAC__StreamDecoder *decoder,
219 FLAC__uint64 absolute_byte_offset, void *client_data)
220{
221 return ((FLACParser *) client_data)->seekCallback(absolute_byte_offset);
222}
223
224FLAC__StreamDecoderTellStatus FLACParser::tell_callback(
225 const FLAC__StreamDecoder *decoder,
226 FLAC__uint64 *absolute_byte_offset, void *client_data)
227{
228 return ((FLACParser *) client_data)->tellCallback(absolute_byte_offset);
229}
230
231FLAC__StreamDecoderLengthStatus FLACParser::length_callback(
232 const FLAC__StreamDecoder *decoder,
233 FLAC__uint64 *stream_length, void *client_data)
234{
235 return ((FLACParser *) client_data)->lengthCallback(stream_length);
236}
237
238FLAC__bool FLACParser::eof_callback(
239 const FLAC__StreamDecoder *decoder, void *client_data)
240{
241 return ((FLACParser *) client_data)->eofCallback();
242}
243
244FLAC__StreamDecoderWriteStatus FLACParser::write_callback(
245 const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame,
246 const FLAC__int32 * const buffer[], void *client_data)
247{
248 return ((FLACParser *) client_data)->writeCallback(frame, buffer);
249}
250
251void FLACParser::metadata_callback(
252 const FLAC__StreamDecoder *decoder,
253 const FLAC__StreamMetadata *metadata, void *client_data)
254{
255 ((FLACParser *) client_data)->metadataCallback(metadata);
256}
257
258void FLACParser::error_callback(
259 const FLAC__StreamDecoder *decoder,
260 FLAC__StreamDecoderErrorStatus status, void *client_data)
261{
262 ((FLACParser *) client_data)->errorCallback(status);
263}
264
265// These are the corresponding callbacks with C++ calling conventions
266
267FLAC__StreamDecoderReadStatus FLACParser::readCallback(
268 FLAC__byte buffer[], size_t *bytes)
269{
270 size_t requested = *bytes;
271 ssize_t actual = mDataSource->readAt(mCurrentPos, buffer, requested);
272 if (0 > actual) {
273 *bytes = 0;
274 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
275 } else if (0 == actual) {
276 *bytes = 0;
277 mEOF = true;
278 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
279 } else {
280 assert(actual <= requested);
281 *bytes = actual;
282 mCurrentPos += actual;
283 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
284 }
285}
286
287FLAC__StreamDecoderSeekStatus FLACParser::seekCallback(
288 FLAC__uint64 absolute_byte_offset)
289{
290 mCurrentPos = absolute_byte_offset;
291 mEOF = false;
292 return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
293}
294
295FLAC__StreamDecoderTellStatus FLACParser::tellCallback(
296 FLAC__uint64 *absolute_byte_offset)
297{
298 *absolute_byte_offset = mCurrentPos;
299 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
300}
301
302FLAC__StreamDecoderLengthStatus FLACParser::lengthCallback(
303 FLAC__uint64 *stream_length)
304{
305 off64_t size;
306 if (OK == mDataSource->getSize(&size)) {
307 *stream_length = size;
308 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
309 } else {
310 return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
311 }
312}
313
314FLAC__bool FLACParser::eofCallback()
315{
316 return mEOF;
317}
318
319FLAC__StreamDecoderWriteStatus FLACParser::writeCallback(
320 const FLAC__Frame *frame, const FLAC__int32 * const buffer[])
321{
322 if (mWriteRequested) {
323 mWriteRequested = false;
324 // FLAC parser doesn't free or realloc buffer until next frame or finish
325 mWriteHeader = frame->header;
326 mWriteBuffer = buffer;
327 mWriteCompleted = true;
328 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
329 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000330 ALOGE("FLACParser::writeCallback unexpected");
Glenn Kasten856990b2011-01-13 11:17:00 -0800331 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
332 }
333}
334
335void FLACParser::metadataCallback(const FLAC__StreamMetadata *metadata)
336{
337 switch (metadata->type) {
338 case FLAC__METADATA_TYPE_STREAMINFO:
339 if (!mStreamInfoValid) {
340 mStreamInfo = metadata->data.stream_info;
341 mStreamInfoValid = true;
342 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000343 ALOGE("FLACParser::metadataCallback unexpected STREAMINFO");
Glenn Kasten856990b2011-01-13 11:17:00 -0800344 }
345 break;
346 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
347 {
348 const FLAC__StreamMetadata_VorbisComment *vc;
349 vc = &metadata->data.vorbis_comment;
350 for (FLAC__uint32 i = 0; i < vc->num_comments; ++i) {
351 FLAC__StreamMetadata_VorbisComment_Entry *vce;
352 vce = &vc->comments[i];
Glenn Kastenaf2e65c2012-06-19 14:44:41 -0700353 if (mFileMetadata != 0 && vce->entry != NULL) {
Glenn Kasten856990b2011-01-13 11:17:00 -0800354 parseVorbisComment(mFileMetadata, (const char *) vce->entry,
355 vce->length);
356 }
357 }
358 }
359 break;
360 case FLAC__METADATA_TYPE_PICTURE:
361 if (mFileMetadata != 0) {
362 const FLAC__StreamMetadata_Picture *p = &metadata->data.picture;
363 mFileMetadata->setData(kKeyAlbumArt,
364 MetaData::TYPE_NONE, p->data, p->data_length);
365 mFileMetadata->setCString(kKeyAlbumArtMIME, p->mime_type);
366 }
367 break;
368 default:
Steve Block5ff1dd52012-01-05 23:22:43 +0000369 ALOGW("FLACParser::metadataCallback unexpected type %u", metadata->type);
Glenn Kasten856990b2011-01-13 11:17:00 -0800370 break;
371 }
372}
373
374void FLACParser::errorCallback(FLAC__StreamDecoderErrorStatus status)
375{
Steve Block29357bc2012-01-06 19:20:56 +0000376 ALOGE("FLACParser::errorCallback status=%d", status);
Glenn Kasten856990b2011-01-13 11:17:00 -0800377 mErrorStatus = status;
378}
379
380// Copy samples from FLAC native 32-bit non-interleaved to 16-bit interleaved.
381// These are candidates for optimization if needed.
382
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100383static void copyMono8(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
Glenn Kasten856990b2011-01-13 11:17:00 -0800384{
385 for (unsigned i = 0; i < nSamples; ++i) {
386 *dst++ = src[0][i] << 8;
387 }
388}
389
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100390static void copyStereo8(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
Glenn Kasten856990b2011-01-13 11:17:00 -0800391{
392 for (unsigned i = 0; i < nSamples; ++i) {
393 *dst++ = src[0][i] << 8;
394 *dst++ = src[1][i] << 8;
395 }
396}
397
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100398static void copyMultiCh8(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
399{
400 for (unsigned i = 0; i < nSamples; ++i) {
401 for (unsigned c = 0; c < nChannels; ++c) {
402 *dst++ = src[c][i] << 8;
403 }
404 }
405}
406
407static void copyMono16(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
Glenn Kasten856990b2011-01-13 11:17:00 -0800408{
409 for (unsigned i = 0; i < nSamples; ++i) {
410 *dst++ = src[0][i];
411 }
412}
413
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100414static void copyStereo16(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
Glenn Kasten856990b2011-01-13 11:17:00 -0800415{
416 for (unsigned i = 0; i < nSamples; ++i) {
417 *dst++ = src[0][i];
418 *dst++ = src[1][i];
419 }
420}
421
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100422static void copyMultiCh16(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
423{
424 for (unsigned i = 0; i < nSamples; ++i) {
425 for (unsigned c = 0; c < nChannels; ++c) {
426 *dst++ = src[c][i];
427 }
428 }
429}
430
Glenn Kasten856990b2011-01-13 11:17:00 -0800431// 24-bit versions should do dithering or noise-shaping, here or in AudioFlinger
432
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100433static void copyMono24(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
Glenn Kasten856990b2011-01-13 11:17:00 -0800434{
435 for (unsigned i = 0; i < nSamples; ++i) {
436 *dst++ = src[0][i] >> 8;
437 }
438}
439
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100440static void copyStereo24(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
Glenn Kasten856990b2011-01-13 11:17:00 -0800441{
442 for (unsigned i = 0; i < nSamples; ++i) {
443 *dst++ = src[0][i] >> 8;
444 *dst++ = src[1][i] >> 8;
445 }
446}
447
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100448static void copyMultiCh24(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
449{
450 for (unsigned i = 0; i < nSamples; ++i) {
451 for (unsigned c = 0; c < nChannels; ++c) {
452 *dst++ = src[c][i] >> 8;
453 }
454 }
455}
456
457static void copyTrespass(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
Glenn Kasten856990b2011-01-13 11:17:00 -0800458{
459 TRESPASS();
460}
461
462// FLACParser
463
464FLACParser::FLACParser(
465 const sp<DataSource> &dataSource,
466 const sp<MetaData> &fileMetadata,
467 const sp<MetaData> &trackMetadata)
468 : mDataSource(dataSource),
469 mFileMetadata(fileMetadata),
470 mTrackMetadata(trackMetadata),
471 mInitCheck(false),
472 mMaxBufferSize(0),
473 mGroup(NULL),
474 mCopy(copyTrespass),
475 mDecoder(NULL),
476 mCurrentPos(0LL),
477 mEOF(false),
478 mStreamInfoValid(false),
479 mWriteRequested(false),
480 mWriteCompleted(false),
481 mWriteBuffer(NULL),
482 mErrorStatus((FLAC__StreamDecoderErrorStatus) -1)
483{
Steve Block3856b092011-10-20 11:56:00 +0100484 ALOGV("FLACParser::FLACParser");
Glenn Kasten856990b2011-01-13 11:17:00 -0800485 memset(&mStreamInfo, 0, sizeof(mStreamInfo));
486 memset(&mWriteHeader, 0, sizeof(mWriteHeader));
487 mInitCheck = init();
488}
489
490FLACParser::~FLACParser()
491{
Steve Block3856b092011-10-20 11:56:00 +0100492 ALOGV("FLACParser::~FLACParser");
Glenn Kasten856990b2011-01-13 11:17:00 -0800493 if (mDecoder != NULL) {
494 FLAC__stream_decoder_delete(mDecoder);
495 mDecoder = NULL;
496 }
497}
498
499status_t FLACParser::init()
500{
501 // setup libFLAC parser
502 mDecoder = FLAC__stream_decoder_new();
503 if (mDecoder == NULL) {
504 // The new should succeed, since probably all it does is a malloc
505 // that always succeeds in Android. But to avoid dependence on the
506 // libFLAC internals, we check and log here.
Steve Block29357bc2012-01-06 19:20:56 +0000507 ALOGE("new failed");
Glenn Kasten856990b2011-01-13 11:17:00 -0800508 return NO_INIT;
509 }
510 FLAC__stream_decoder_set_md5_checking(mDecoder, false);
511 FLAC__stream_decoder_set_metadata_ignore_all(mDecoder);
512 FLAC__stream_decoder_set_metadata_respond(
513 mDecoder, FLAC__METADATA_TYPE_STREAMINFO);
514 FLAC__stream_decoder_set_metadata_respond(
515 mDecoder, FLAC__METADATA_TYPE_PICTURE);
516 FLAC__stream_decoder_set_metadata_respond(
517 mDecoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
518 FLAC__StreamDecoderInitStatus initStatus;
519 initStatus = FLAC__stream_decoder_init_stream(
520 mDecoder,
521 read_callback, seek_callback, tell_callback,
522 length_callback, eof_callback, write_callback,
523 metadata_callback, error_callback, (void *) this);
524 if (initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
525 // A failure here probably indicates a programming error and so is
526 // unlikely to happen. But we check and log here similarly to above.
Steve Block29357bc2012-01-06 19:20:56 +0000527 ALOGE("init_stream failed %d", initStatus);
Glenn Kasten856990b2011-01-13 11:17:00 -0800528 return NO_INIT;
529 }
530 // parse all metadata
531 if (!FLAC__stream_decoder_process_until_end_of_metadata(mDecoder)) {
Steve Block29357bc2012-01-06 19:20:56 +0000532 ALOGE("end_of_metadata failed");
Glenn Kasten856990b2011-01-13 11:17:00 -0800533 return NO_INIT;
534 }
535 if (mStreamInfoValid) {
536 // check channel count
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100537 if (getChannels() == 0 || getChannels() > 8) {
Steve Block29357bc2012-01-06 19:20:56 +0000538 ALOGE("unsupported channel count %u", getChannels());
Glenn Kasten856990b2011-01-13 11:17:00 -0800539 return NO_INIT;
540 }
541 // check bit depth
542 switch (getBitsPerSample()) {
543 case 8:
544 case 16:
545 case 24:
546 break;
547 default:
Steve Block29357bc2012-01-06 19:20:56 +0000548 ALOGE("unsupported bits per sample %u", getBitsPerSample());
Glenn Kasten856990b2011-01-13 11:17:00 -0800549 return NO_INIT;
550 }
551 // check sample rate
552 switch (getSampleRate()) {
553 case 8000:
554 case 11025:
555 case 12000:
556 case 16000:
557 case 22050:
558 case 24000:
559 case 32000:
560 case 44100:
561 case 48000:
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100562 case 88200:
563 case 96000:
Glenn Kasten856990b2011-01-13 11:17:00 -0800564 break;
565 default:
Steve Block29357bc2012-01-06 19:20:56 +0000566 ALOGE("unsupported sample rate %u", getSampleRate());
Glenn Kasten856990b2011-01-13 11:17:00 -0800567 return NO_INIT;
568 }
569 // configure the appropriate copy function, defaulting to trespass
570 static const struct {
571 unsigned mChannels;
572 unsigned mBitsPerSample;
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100573 void (*mCopy)(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels);
Glenn Kasten856990b2011-01-13 11:17:00 -0800574 } table[] = {
575 { 1, 8, copyMono8 },
576 { 2, 8, copyStereo8 },
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100577 { 8, 8, copyMultiCh8 },
Glenn Kasten856990b2011-01-13 11:17:00 -0800578 { 1, 16, copyMono16 },
579 { 2, 16, copyStereo16 },
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100580 { 8, 16, copyMultiCh16 },
Glenn Kasten856990b2011-01-13 11:17:00 -0800581 { 1, 24, copyMono24 },
582 { 2, 24, copyStereo24 },
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100583 { 8, 24, copyMultiCh24 },
Glenn Kasten856990b2011-01-13 11:17:00 -0800584 };
585 for (unsigned i = 0; i < sizeof(table)/sizeof(table[0]); ++i) {
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100586 if (table[i].mChannels >= getChannels() &&
Glenn Kasten856990b2011-01-13 11:17:00 -0800587 table[i].mBitsPerSample == getBitsPerSample()) {
588 mCopy = table[i].mCopy;
589 break;
590 }
591 }
592 // populate track metadata
593 if (mTrackMetadata != 0) {
594 mTrackMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
595 mTrackMetadata->setInt32(kKeyChannelCount, getChannels());
596 mTrackMetadata->setInt32(kKeySampleRate, getSampleRate());
597 // sample rate is non-zero, so division by zero not possible
598 mTrackMetadata->setInt64(kKeyDuration,
599 (getTotalSamples() * 1000000LL) / getSampleRate());
600 }
601 } else {
Steve Block29357bc2012-01-06 19:20:56 +0000602 ALOGE("missing STREAMINFO");
Glenn Kasten856990b2011-01-13 11:17:00 -0800603 return NO_INIT;
604 }
605 if (mFileMetadata != 0) {
606 mFileMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FLAC);
607 }
608 return OK;
609}
610
611void FLACParser::allocateBuffers()
612{
613 CHECK(mGroup == NULL);
614 mGroup = new MediaBufferGroup;
615 mMaxBufferSize = getMaxBlockSize() * getChannels() * sizeof(short);
616 mGroup->add_buffer(new MediaBuffer(mMaxBufferSize));
617}
618
619void FLACParser::releaseBuffers()
620{
621 CHECK(mGroup != NULL);
622 delete mGroup;
623 mGroup = NULL;
624}
625
626MediaBuffer *FLACParser::readBuffer(bool doSeek, FLAC__uint64 sample)
627{
628 mWriteRequested = true;
629 mWriteCompleted = false;
630 if (doSeek) {
631 // We implement the seek callback, so this works without explicit flush
632 if (!FLAC__stream_decoder_seek_absolute(mDecoder, sample)) {
Steve Block29357bc2012-01-06 19:20:56 +0000633 ALOGE("FLACParser::readBuffer seek to sample %llu failed", sample);
Glenn Kasten856990b2011-01-13 11:17:00 -0800634 return NULL;
635 }
Steve Block3856b092011-10-20 11:56:00 +0100636 ALOGV("FLACParser::readBuffer seek to sample %llu succeeded", sample);
Glenn Kasten856990b2011-01-13 11:17:00 -0800637 } else {
638 if (!FLAC__stream_decoder_process_single(mDecoder)) {
Steve Block29357bc2012-01-06 19:20:56 +0000639 ALOGE("FLACParser::readBuffer process_single failed");
Glenn Kasten856990b2011-01-13 11:17:00 -0800640 return NULL;
641 }
642 }
643 if (!mWriteCompleted) {
Steve Block3856b092011-10-20 11:56:00 +0100644 ALOGV("FLACParser::readBuffer write did not complete");
Glenn Kasten856990b2011-01-13 11:17:00 -0800645 return NULL;
646 }
647 // verify that block header keeps the promises made by STREAMINFO
648 unsigned blocksize = mWriteHeader.blocksize;
649 if (blocksize == 0 || blocksize > getMaxBlockSize()) {
Steve Block29357bc2012-01-06 19:20:56 +0000650 ALOGE("FLACParser::readBuffer write invalid blocksize %u", blocksize);
Glenn Kasten856990b2011-01-13 11:17:00 -0800651 return NULL;
652 }
653 if (mWriteHeader.sample_rate != getSampleRate() ||
654 mWriteHeader.channels != getChannels() ||
655 mWriteHeader.bits_per_sample != getBitsPerSample()) {
Steve Block29357bc2012-01-06 19:20:56 +0000656 ALOGE("FLACParser::readBuffer write changed parameters mid-stream");
Glenn Kasten856990b2011-01-13 11:17:00 -0800657 }
658 // acquire a media buffer
659 CHECK(mGroup != NULL);
660 MediaBuffer *buffer;
661 status_t err = mGroup->acquire_buffer(&buffer);
662 if (err != OK) {
663 return NULL;
664 }
665 size_t bufferSize = blocksize * getChannels() * sizeof(short);
666 CHECK(bufferSize <= mMaxBufferSize);
667 short *data = (short *) buffer->data();
668 buffer->set_range(0, bufferSize);
669 // copy PCM from FLAC write buffer to our media buffer, with interleaving
Patrik2 Carlsson91de11b2012-11-16 16:34:33 +0100670 (*mCopy)(data, mWriteBuffer, blocksize, getChannels());
Glenn Kasten856990b2011-01-13 11:17:00 -0800671 // fill in buffer metadata
672 CHECK(mWriteHeader.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER);
673 FLAC__uint64 sampleNumber = mWriteHeader.number.sample_number;
674 int64_t timeUs = (1000000LL * sampleNumber) / getSampleRate();
675 buffer->meta_data()->setInt64(kKeyTime, timeUs);
676 buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
677 return buffer;
678}
679
680// FLACsource
681
682FLACSource::FLACSource(
683 const sp<DataSource> &dataSource,
684 const sp<MetaData> &trackMetadata)
685 : mDataSource(dataSource),
686 mTrackMetadata(trackMetadata),
687 mParser(0),
688 mInitCheck(false),
689 mStarted(false)
690{
Steve Block3856b092011-10-20 11:56:00 +0100691 ALOGV("FLACSource::FLACSource");
Glenn Kasten856990b2011-01-13 11:17:00 -0800692 mInitCheck = init();
693}
694
695FLACSource::~FLACSource()
696{
Steve Block3856b092011-10-20 11:56:00 +0100697 ALOGV("~FLACSource::FLACSource");
Glenn Kasten856990b2011-01-13 11:17:00 -0800698 if (mStarted) {
699 stop();
700 }
701}
702
703status_t FLACSource::start(MetaData *params)
704{
Steve Block3856b092011-10-20 11:56:00 +0100705 ALOGV("FLACSource::start");
Glenn Kasten856990b2011-01-13 11:17:00 -0800706
707 CHECK(!mStarted);
708 mParser->allocateBuffers();
709 mStarted = true;
710
711 return OK;
712}
713
714status_t FLACSource::stop()
715{
Steve Block3856b092011-10-20 11:56:00 +0100716 ALOGV("FLACSource::stop");
Glenn Kasten856990b2011-01-13 11:17:00 -0800717
718 CHECK(mStarted);
719 mParser->releaseBuffers();
720 mStarted = false;
721
722 return OK;
723}
724
725sp<MetaData> FLACSource::getFormat()
726{
727 return mTrackMetadata;
728}
729
730status_t FLACSource::read(
731 MediaBuffer **outBuffer, const ReadOptions *options)
732{
733 MediaBuffer *buffer;
734 // process an optional seek request
735 int64_t seekTimeUs;
736 ReadOptions::SeekMode mode;
737 if ((NULL != options) && options->getSeekTo(&seekTimeUs, &mode)) {
738 FLAC__uint64 sample;
739 if (seekTimeUs <= 0LL) {
740 sample = 0LL;
741 } else {
742 // sample and total samples are both zero-based, and seek to EOF ok
743 sample = (seekTimeUs * mParser->getSampleRate()) / 1000000LL;
744 if (sample >= mParser->getTotalSamples()) {
745 sample = mParser->getTotalSamples();
746 }
747 }
748 buffer = mParser->readBuffer(sample);
749 // otherwise read sequentially
750 } else {
751 buffer = mParser->readBuffer();
752 }
753 *outBuffer = buffer;
754 return buffer != NULL ? (status_t) OK : (status_t) ERROR_END_OF_STREAM;
755}
756
757status_t FLACSource::init()
758{
Steve Block3856b092011-10-20 11:56:00 +0100759 ALOGV("FLACSource::init");
Glenn Kasten856990b2011-01-13 11:17:00 -0800760 // re-use the same track metadata passed into constructor from FLACExtractor
761 mParser = new FLACParser(mDataSource);
762 return mParser->initCheck();
763}
764
765// FLACExtractor
766
767FLACExtractor::FLACExtractor(
768 const sp<DataSource> &dataSource)
769 : mDataSource(dataSource),
770 mInitCheck(false)
771{
Steve Block3856b092011-10-20 11:56:00 +0100772 ALOGV("FLACExtractor::FLACExtractor");
Glenn Kasten856990b2011-01-13 11:17:00 -0800773 mInitCheck = init();
774}
775
776FLACExtractor::~FLACExtractor()
777{
Steve Block3856b092011-10-20 11:56:00 +0100778 ALOGV("~FLACExtractor::FLACExtractor");
Glenn Kasten856990b2011-01-13 11:17:00 -0800779}
780
781size_t FLACExtractor::countTracks()
782{
783 return mInitCheck == OK ? 1 : 0;
784}
785
786sp<MediaSource> FLACExtractor::getTrack(size_t index)
787{
788 if (mInitCheck != OK || index > 0) {
789 return NULL;
790 }
791 return new FLACSource(mDataSource, mTrackMetadata);
792}
793
794sp<MetaData> FLACExtractor::getTrackMetaData(
795 size_t index, uint32_t flags)
796{
797 if (mInitCheck != OK || index > 0) {
798 return NULL;
799 }
800 return mTrackMetadata;
801}
802
803status_t FLACExtractor::init()
804{
805 mFileMetadata = new MetaData;
806 mTrackMetadata = new MetaData;
807 // FLACParser will fill in the metadata for us
808 mParser = new FLACParser(mDataSource, mFileMetadata, mTrackMetadata);
809 return mParser->initCheck();
810}
811
812sp<MetaData> FLACExtractor::getMetaData()
813{
814 return mFileMetadata;
815}
816
817// Sniffer
818
819bool SniffFLAC(
820 const sp<DataSource> &source, String8 *mimeType, float *confidence,
821 sp<AMessage> *)
822{
823 // first 4 is the signature word
824 // second 4 is the sizeof STREAMINFO
825 // 042 is the mandatory STREAMINFO
826 // no need to read rest of the header, as a premature EOF will be caught later
827 uint8_t header[4+4];
828 if (source->readAt(0, header, sizeof(header)) != sizeof(header)
829 || memcmp("fLaC\0\0\0\042", header, 4+4))
830 {
831 return false;
832 }
833
834 *mimeType = MEDIA_MIMETYPE_AUDIO_FLAC;
835 *confidence = 0.5;
836
837 return true;
838}
839
840} // namespace android