1 /* test_libFLAC - Unit tester for libFLAC
2 * Copyright (C) 2002-2009 Josh Coalson
3 * Copyright (C) 2011-2016 Xiph.Org Foundation
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include "FLAC/assert.h"
30 #include "FLAC/stream_decoder.h"
31 #include "share/grabbag.h"
32 #include "share/compat.h"
33 #include "share/safe_str.h"
34 #include "test_libs_common/file_utils_flac.h"
35 #include "test_libs_common/metadata_utils.h"
38 LAYER_STREAM
= 0, /* FLAC__stream_decoder_init_[ogg_]stream() without seeking */
39 LAYER_SEEKABLE_STREAM
, /* FLAC__stream_decoder_init_[ogg_]stream() with seeking */
40 LAYER_FILE
, /* FLAC__stream_decoder_init_[ogg_]FILE() */
41 LAYER_FILENAME
/* FLAC__stream_decoder_init_[ogg_]file() */
44 static const char * const LayerString
[] = {
55 uint32_t current_metadata_number
;
56 FLAC__bool ignore_errors
;
57 FLAC__bool error_occurred
;
58 } StreamDecoderClientData
;
60 static FLAC__StreamMetadata streaminfo_
, padding_
, seektable_
, application1_
, application2_
, vorbiscomment_
, cuesheet_
, picture_
, unknown_
;
61 static FLAC__StreamMetadata
*expected_metadata_sequence_
[9];
62 static uint32_t num_expected_
;
63 static FLAC__off_t flacfilesize_
;
65 static const char *flacfilename(FLAC__bool is_ogg
)
67 return is_ogg
? "metadata.oga" : "metadata.flac";
70 static FLAC__bool
die_(const char *msg
)
72 printf("ERROR: %s\n", msg
);
76 static FLAC__bool
die_s_(const char *msg
, const FLAC__StreamDecoder
*decoder
)
78 FLAC__StreamDecoderState state
= FLAC__stream_decoder_get_state(decoder
);
81 printf("FAILED, %s", msg
);
85 printf(", state = %u (%s)\n", (uint32_t)state
, FLAC__StreamDecoderStateString
[state
]);
90 static void open_test_file(StreamDecoderClientData
* pdcd
, int is_ogg
, const char * mode
)
92 pdcd
->file
= flac_fopen(flacfilename(is_ogg
), mode
);
93 safe_strncpy(pdcd
->filename
, flacfilename(is_ogg
), sizeof (pdcd
->filename
));
96 static void init_metadata_blocks_(void)
98 mutils__init_metadata_blocks(&streaminfo_
, &padding_
, &seektable_
, &application1_
, &application2_
, &vorbiscomment_
, &cuesheet_
, &picture_
, &unknown_
);
101 static void free_metadata_blocks_(void)
103 mutils__free_metadata_blocks(&streaminfo_
, &padding_
, &seektable_
, &application1_
, &application2_
, &vorbiscomment_
, &cuesheet_
, &picture_
, &unknown_
);
106 static FLAC__bool
generate_file_(FLAC__bool is_ogg
)
108 printf("\n\ngenerating %sFLAC file for decoder tests...\n", is_ogg
? "Ogg ":"");
111 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
112 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
113 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
114 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
115 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
116 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
117 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
118 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
119 /* WATCHOUT: for Ogg FLAC the encoder should move the VORBIS_COMMENT block to the front, right after STREAMINFO */
121 if(!file_utils__generate_flacfile(is_ogg
, flacfilename(is_ogg
), &flacfilesize_
, 512 * 1024, &streaminfo_
, expected_metadata_sequence_
, num_expected_
))
122 return die_("creating the encoded file");
127 static FLAC__StreamDecoderReadStatus
stream_decoder_read_callback_(const FLAC__StreamDecoder
*decoder
, FLAC__byte buffer
[], size_t *bytes
, void *client_data
)
129 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
130 const size_t requested_bytes
= *bytes
;
135 printf("ERROR: client_data in read callback is NULL\n");
136 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
;
139 if(dcd
->error_occurred
)
140 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
;
142 if(feof(dcd
->file
)) {
144 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
;
146 else if(requested_bytes
> 0) {
147 *bytes
= fread(buffer
, 1, requested_bytes
, dcd
->file
);
150 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
;
152 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
;
155 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE
;
159 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
; /* abort to avoid a deadlock */
162 static FLAC__StreamDecoderSeekStatus
stream_decoder_seek_callback_(const FLAC__StreamDecoder
*decoder
, FLAC__uint64 absolute_byte_offset
, void *client_data
)
164 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
169 printf("ERROR: client_data in seek callback is NULL\n");
170 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR
;
173 if(dcd
->error_occurred
)
174 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR
;
176 if(fseeko(dcd
->file
, (FLAC__off_t
)absolute_byte_offset
, SEEK_SET
) < 0) {
177 dcd
->error_occurred
= true;
178 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR
;
181 return FLAC__STREAM_DECODER_SEEK_STATUS_OK
;
184 static FLAC__StreamDecoderTellStatus
stream_decoder_tell_callback_(const FLAC__StreamDecoder
*decoder
, FLAC__uint64
*absolute_byte_offset
, void *client_data
)
186 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
192 printf("ERROR: client_data in tell callback is NULL\n");
193 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR
;
196 if(dcd
->error_occurred
)
197 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR
;
199 offset
= ftello(dcd
->file
);
200 *absolute_byte_offset
= (FLAC__uint64
)offset
;
203 dcd
->error_occurred
= true;
204 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR
;
207 return FLAC__STREAM_DECODER_TELL_STATUS_OK
;
210 static FLAC__StreamDecoderLengthStatus
stream_decoder_length_callback_(const FLAC__StreamDecoder
*decoder
, FLAC__uint64
*stream_length
, void *client_data
)
212 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
217 printf("ERROR: client_data in length callback is NULL\n");
218 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR
;
221 if(dcd
->error_occurred
)
222 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR
;
224 *stream_length
= (FLAC__uint64
)flacfilesize_
;
225 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK
;
228 static FLAC__bool
stream_decoder_eof_callback_(const FLAC__StreamDecoder
*decoder
, void *client_data
)
230 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
235 printf("ERROR: client_data in eof callback is NULL\n");
239 if(dcd
->error_occurred
)
242 return feof(dcd
->file
);
245 static FLAC__StreamDecoderWriteStatus
stream_decoder_write_callback_(const FLAC__StreamDecoder
*decoder
, const FLAC__Frame
*frame
, const FLAC__int32
* const buffer
[], void *client_data
)
247 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
249 (void)decoder
, (void)buffer
;
252 printf("ERROR: client_data in write callback is NULL\n");
253 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT
;
256 if(dcd
->error_occurred
)
257 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT
;
260 (frame
->header
.number_type
== FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER
&& frame
->header
.number
.frame_number
== 0) ||
261 (frame
->header
.number_type
== FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER
&& frame
->header
.number
.sample_number
== 0)
263 printf("content... ");
267 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE
;
270 static void stream_decoder_metadata_callback_(const FLAC__StreamDecoder
*decoder
, const FLAC__StreamMetadata
*metadata
, void *client_data
)
272 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
277 printf("ERROR: client_data in metadata callback is NULL\n");
281 if(dcd
->error_occurred
)
284 if (metadata
->type
== FLAC__METADATA_TYPE_APPLICATION
) {
285 printf ("%u ('%c%c%c%c')... ", dcd
->current_metadata_number
, metadata
->data
.application
.id
[0], metadata
->data
.application
.id
[1], metadata
->data
.application
.id
[2], metadata
->data
.application
.id
[3]);
288 printf("%u... ", dcd
->current_metadata_number
);
293 if(dcd
->current_metadata_number
>= num_expected_
) {
294 (void)die_("got more metadata blocks than expected");
295 dcd
->error_occurred
= true;
298 if(!mutils__compare_block(expected_metadata_sequence_
[dcd
->current_metadata_number
], metadata
)) {
299 (void)die_("metadata block mismatch");
300 dcd
->error_occurred
= true;
303 dcd
->current_metadata_number
++;
306 static void stream_decoder_error_callback_(const FLAC__StreamDecoder
*decoder
, FLAC__StreamDecoderErrorStatus status
, void *client_data
)
308 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
313 printf("ERROR: client_data in error callback is NULL\n");
317 if(!dcd
->ignore_errors
) {
318 printf("ERROR: got error callback: err = %u (%s)\n", (uint32_t)status
, FLAC__StreamDecoderErrorStatusString
[status
]);
319 dcd
->error_occurred
= true;
323 static FLAC__bool
stream_decoder_test_respond_(FLAC__StreamDecoder
*decoder
, StreamDecoderClientData
*dcd
, FLAC__bool is_ogg
)
325 FLAC__StreamDecoderInitStatus init_status
;
327 if(!FLAC__stream_decoder_set_md5_checking(decoder
, true))
328 return die_s_("at FLAC__stream_decoder_set_md5_checking(), returned false", decoder
);
330 /* for FLAC__stream_encoder_init_FILE(), the FLAC__stream_encoder_finish() closes the file so we have to keep re-opening: */
331 if(dcd
->layer
== LAYER_FILE
) {
332 printf("opening %sFLAC file... ", is_ogg
? "Ogg ":"");
333 open_test_file(dcd
, is_ogg
, "rb");
335 printf("ERROR (%s)\n", strerror(errno
));
343 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg
? "ogg_":"");
344 init_status
= is_ogg
?
345 FLAC__stream_decoder_init_ogg_stream(decoder
, stream_decoder_read_callback_
, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
) :
346 FLAC__stream_decoder_init_stream(decoder
, stream_decoder_read_callback_
, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
)
349 case LAYER_SEEKABLE_STREAM
:
350 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg
? "ogg_":"");
351 init_status
= is_ogg
?
352 FLAC__stream_decoder_init_ogg_stream(decoder
, stream_decoder_read_callback_
, stream_decoder_seek_callback_
, stream_decoder_tell_callback_
, stream_decoder_length_callback_
, stream_decoder_eof_callback_
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
) :
353 FLAC__stream_decoder_init_stream(decoder
, stream_decoder_read_callback_
, stream_decoder_seek_callback_
, stream_decoder_tell_callback_
, stream_decoder_length_callback_
, stream_decoder_eof_callback_
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
);
356 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg
? "ogg_":"");
357 init_status
= is_ogg
?
358 FLAC__stream_decoder_init_ogg_FILE(decoder
, dcd
->file
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
) :
359 FLAC__stream_decoder_init_FILE(decoder
, dcd
->file
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
);
362 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg
? "ogg_":"");
363 init_status
= is_ogg
?
364 FLAC__stream_decoder_init_ogg_file(decoder
, flacfilename(is_ogg
), stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
) :
365 FLAC__stream_decoder_init_file(decoder
, flacfilename(is_ogg
), stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
);
368 die_("internal error 000");
371 if(init_status
!= FLAC__STREAM_DECODER_INIT_STATUS_OK
)
372 return die_s_(0, decoder
);
375 dcd
->current_metadata_number
= 0;
377 if(dcd
->layer
< LAYER_FILE
&& fseeko(dcd
->file
, 0, SEEK_SET
) < 0) {
378 printf("FAILED rewinding input, errno = %d\n", errno
);
382 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
383 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder
))
384 return die_s_("returned false", decoder
);
387 printf("testing FLAC__stream_decoder_finish()... ");
388 if(!FLAC__stream_decoder_finish(decoder
))
389 return die_s_("returned false", decoder
);
395 static FLAC__bool
test_stream_decoder(Layer layer
, FLAC__bool is_ogg
)
397 FLAC__StreamDecoder
*decoder
;
398 FLAC__StreamDecoderInitStatus init_status
;
399 FLAC__StreamDecoderState state
;
400 StreamDecoderClientData decoder_client_data
;
403 decoder_client_data
.layer
= layer
;
405 printf("\n+++ libFLAC unit test: FLAC__StreamDecoder (layer: %s, format: %s)\n\n", LayerString
[layer
], is_ogg
? "Ogg FLAC" : "FLAC");
407 printf("testing FLAC__stream_decoder_new()... ");
408 decoder
= FLAC__stream_decoder_new();
410 printf("FAILED, returned NULL\n");
415 printf("testing FLAC__stream_decoder_delete()... ");
416 FLAC__stream_decoder_delete(decoder
);
419 printf("testing FLAC__stream_decoder_new()... ");
420 decoder
= FLAC__stream_decoder_new();
422 printf("FAILED, returned NULL\n");
429 case LAYER_SEEKABLE_STREAM
:
430 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg
? "ogg_":"");
431 init_status
= is_ogg
?
432 FLAC__stream_decoder_init_ogg_stream(decoder
, 0, 0, 0, 0, 0, 0, 0, 0, 0) :
433 FLAC__stream_decoder_init_stream(decoder
, 0, 0, 0, 0, 0, 0, 0, 0, 0);
436 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg
? "ogg_":"");
437 init_status
= is_ogg
?
438 FLAC__stream_decoder_init_ogg_FILE(decoder
, stdin
, 0, 0, 0, 0) :
439 FLAC__stream_decoder_init_FILE(decoder
, stdin
, 0, 0, 0, 0);
442 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg
? "ogg_":"");
443 init_status
= is_ogg
?
444 FLAC__stream_decoder_init_ogg_file(decoder
, flacfilename(is_ogg
), 0, 0, 0, 0) :
445 FLAC__stream_decoder_init_file(decoder
, flacfilename(is_ogg
), 0, 0, 0, 0);
448 die_("internal error 003");
451 if(init_status
!= FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS
)
452 return die_s_(0, decoder
);
455 printf("testing FLAC__stream_decoder_delete()... ");
456 FLAC__stream_decoder_delete(decoder
);
460 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
462 printf("testing FLAC__stream_decoder_new()... ");
463 decoder
= FLAC__stream_decoder_new();
465 printf("FAILED, returned NULL\n");
471 printf("testing FLAC__stream_decoder_set_ogg_serial_number()... ");
472 if(!FLAC__stream_decoder_set_ogg_serial_number(decoder
, file_utils__ogg_serial_number
))
473 return die_s_("returned false", decoder
);
477 printf("testing FLAC__stream_decoder_set_md5_checking()... ");
478 if(!FLAC__stream_decoder_set_md5_checking(decoder
, true))
479 return die_s_("returned false", decoder
);
482 if(layer
< LAYER_FILENAME
) {
483 printf("opening %sFLAC file... ", is_ogg
? "Ogg ":"");
484 open_test_file(&decoder_client_data
, is_ogg
, "rb");
485 if(0 == decoder_client_data
.file
) {
486 printf("ERROR (%s)\n", strerror(errno
));
494 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg
? "ogg_":"");
495 init_status
= is_ogg
?
496 FLAC__stream_decoder_init_ogg_stream(decoder
, stream_decoder_read_callback_
, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
) :
497 FLAC__stream_decoder_init_stream(decoder
, stream_decoder_read_callback_
, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
);
499 case LAYER_SEEKABLE_STREAM
:
500 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg
? "ogg_":"");
501 init_status
= is_ogg
?
502 FLAC__stream_decoder_init_ogg_stream(decoder
, stream_decoder_read_callback_
, stream_decoder_seek_callback_
, stream_decoder_tell_callback_
, stream_decoder_length_callback_
, stream_decoder_eof_callback_
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
) :
503 FLAC__stream_decoder_init_stream(decoder
, stream_decoder_read_callback_
, stream_decoder_seek_callback_
, stream_decoder_tell_callback_
, stream_decoder_length_callback_
, stream_decoder_eof_callback_
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
);
506 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg
? "ogg_":"");
507 init_status
= is_ogg
?
508 FLAC__stream_decoder_init_ogg_FILE(decoder
, decoder_client_data
.file
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
) :
509 FLAC__stream_decoder_init_FILE(decoder
, decoder_client_data
.file
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
);
512 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg
? "ogg_":"");
513 init_status
= is_ogg
?
514 FLAC__stream_decoder_init_ogg_file(decoder
, flacfilename(is_ogg
), stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
) :
515 FLAC__stream_decoder_init_file(decoder
, flacfilename(is_ogg
), stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
);
518 die_("internal error 009");
521 if(init_status
!= FLAC__STREAM_DECODER_INIT_STATUS_OK
)
522 return die_s_(0, decoder
);
525 printf("testing FLAC__stream_decoder_get_state()... ");
526 state
= FLAC__stream_decoder_get_state(decoder
);
527 printf("returned state = %u (%s)... OK\n", state
, FLAC__StreamDecoderStateString
[state
]);
529 decoder_client_data
.current_metadata_number
= 0;
530 decoder_client_data
.ignore_errors
= false;
531 decoder_client_data
.error_occurred
= false;
533 printf("testing FLAC__stream_decoder_get_md5_checking()... ");
534 if(!FLAC__stream_decoder_get_md5_checking(decoder
)) {
535 printf("FAILED, returned false, expected true\n");
540 printf("testing FLAC__stream_decoder_process_until_end_of_metadata()... ");
541 if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder
))
542 return die_s_("returned false", decoder
);
545 printf("testing FLAC__stream_decoder_process_single()... ");
546 if(!FLAC__stream_decoder_process_single(decoder
))
547 return die_s_("returned false", decoder
);
550 printf("testing FLAC__stream_decoder_skip_single_frame()... ");
551 if(!FLAC__stream_decoder_skip_single_frame(decoder
))
552 return die_s_("returned false", decoder
);
555 if(layer
< LAYER_FILE
) {
556 printf("testing FLAC__stream_decoder_flush()... ");
557 if(!FLAC__stream_decoder_flush(decoder
))
558 return die_s_("returned false", decoder
);
561 decoder_client_data
.ignore_errors
= true;
562 printf("testing FLAC__stream_decoder_process_single()... ");
563 if(!FLAC__stream_decoder_process_single(decoder
))
564 return die_s_("returned false", decoder
);
566 decoder_client_data
.ignore_errors
= false;
569 expect
= (layer
!= LAYER_STREAM
);
570 printf("testing FLAC__stream_decoder_seek_absolute()... ");
571 if(FLAC__stream_decoder_seek_absolute(decoder
, 0) != expect
)
572 return die_s_(expect
? "returned false" : "returned true", decoder
);
575 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
576 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder
))
577 return die_s_("returned false", decoder
);
580 expect
= (layer
!= LAYER_STREAM
);
581 printf("testing FLAC__stream_decoder_seek_absolute()... ");
582 if(FLAC__stream_decoder_seek_absolute(decoder
, 0) != expect
)
583 return die_s_(expect
? "returned false" : "returned true", decoder
);
586 printf("testing FLAC__stream_decoder_get_channels()... ");
588 uint32_t channels
= FLAC__stream_decoder_get_channels(decoder
);
589 if(channels
!= streaminfo_
.data
.stream_info
.channels
) {
590 printf("FAILED, returned %u, expected %u\n", channels
, streaminfo_
.data
.stream_info
.channels
);
596 printf("testing FLAC__stream_decoder_get_bits_per_sample()... ");
598 uint32_t bits_per_sample
= FLAC__stream_decoder_get_bits_per_sample(decoder
);
599 if(bits_per_sample
!= streaminfo_
.data
.stream_info
.bits_per_sample
) {
600 printf("FAILED, returned %u, expected %u\n", bits_per_sample
, streaminfo_
.data
.stream_info
.bits_per_sample
);
606 printf("testing FLAC__stream_decoder_get_sample_rate()... ");
608 uint32_t sample_rate
= FLAC__stream_decoder_get_sample_rate(decoder
);
609 if(sample_rate
!= streaminfo_
.data
.stream_info
.sample_rate
) {
610 printf("FAILED, returned %u, expected %u\n", sample_rate
, streaminfo_
.data
.stream_info
.sample_rate
);
616 printf("testing FLAC__stream_decoder_get_blocksize()... ");
618 uint32_t blocksize
= FLAC__stream_decoder_get_blocksize(decoder
);
619 /* value could be anything since we're at the last block, so accept any reasonable answer */
620 printf("returned %u... %s\n", blocksize
, blocksize
>0? "OK" : "FAILED");
625 printf("testing FLAC__stream_decoder_get_channel_assignment()... ");
627 FLAC__ChannelAssignment ca
= FLAC__stream_decoder_get_channel_assignment(decoder
);
628 printf("returned %u (%s)... OK\n", (uint32_t)ca
, FLAC__ChannelAssignmentString
[ca
]);
631 if(layer
< LAYER_FILE
) {
632 printf("testing FLAC__stream_decoder_reset()... ");
633 if(!FLAC__stream_decoder_reset(decoder
)) {
634 state
= FLAC__stream_decoder_get_state(decoder
);
635 printf("FAILED, returned false, state = %u (%s)\n", state
, FLAC__StreamDecoderStateString
[state
]);
640 if(layer
== LAYER_STREAM
) {
641 /* after a reset() we have to rewind the input ourselves */
642 printf("rewinding input... ");
643 if(fseeko(decoder_client_data
.file
, 0, SEEK_SET
) < 0) {
644 printf("FAILED, errno = %d\n", errno
);
650 decoder_client_data
.current_metadata_number
= 0;
652 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
653 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder
))
654 return die_s_("returned false", decoder
);
658 printf("testing FLAC__stream_decoder_finish()... ");
659 if(!FLAC__stream_decoder_finish(decoder
))
660 return die_s_("returned false", decoder
);
667 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
668 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
669 return die_s_("returned false", decoder
);
673 if(is_ogg
) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
674 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
675 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
676 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
677 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
678 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
679 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
680 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
681 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
682 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
685 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
686 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
687 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
688 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
689 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
690 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
691 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
692 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
693 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
696 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
703 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
704 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
705 return die_s_("returned false", decoder
);
710 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
714 * respond all, ignore VORBIS_COMMENT
717 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
718 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
719 return die_s_("returned false", decoder
);
722 printf("testing FLAC__stream_decoder_set_metadata_ignore(VORBIS_COMMENT)... ");
723 if(!FLAC__stream_decoder_set_metadata_ignore(decoder
, FLAC__METADATA_TYPE_VORBIS_COMMENT
))
724 return die_s_("returned false", decoder
);
728 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
729 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
730 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
731 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
732 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
733 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
734 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
735 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
737 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
741 * respond all, ignore APPLICATION
744 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
745 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
746 return die_s_("returned false", decoder
);
749 printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
750 if(!FLAC__stream_decoder_set_metadata_ignore(decoder
, FLAC__METADATA_TYPE_APPLICATION
))
751 return die_s_("returned false", decoder
);
755 if(is_ogg
) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
756 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
757 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
758 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
759 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
760 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
761 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
762 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
765 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
766 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
767 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
768 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
769 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
770 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
771 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
774 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
778 * respond all, ignore APPLICATION id of app#1
781 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
782 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
783 return die_s_("returned false", decoder
);
786 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
787 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder
, application1_
.data
.application
.id
))
788 return die_s_("returned false", decoder
);
792 if(is_ogg
) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
793 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
794 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
795 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
796 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
797 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
798 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
799 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
800 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
803 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
804 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
805 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
806 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
807 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
808 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
809 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
810 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
813 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
817 * respond all, ignore APPLICATION id of app#1 & app#2
820 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
821 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
822 return die_s_("returned false", decoder
);
825 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
826 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder
, application1_
.data
.application
.id
))
827 return die_s_("returned false", decoder
);
830 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #2)... ");
831 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder
, application2_
.data
.application
.id
))
832 return die_s_("returned false", decoder
);
836 if(is_ogg
) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
837 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
838 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
839 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
840 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
841 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
842 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
843 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
846 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
847 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
848 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
849 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
850 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
851 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
852 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
855 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
859 * ignore all, respond VORBIS_COMMENT
862 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
863 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
864 return die_s_("returned false", decoder
);
867 printf("testing FLAC__stream_decoder_set_metadata_respond(VORBIS_COMMENT)... ");
868 if(!FLAC__stream_decoder_set_metadata_respond(decoder
, FLAC__METADATA_TYPE_VORBIS_COMMENT
))
869 return die_s_("returned false", decoder
);
873 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
875 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
879 * ignore all, respond APPLICATION
882 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
883 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
884 return die_s_("returned false", decoder
);
887 printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
888 if(!FLAC__stream_decoder_set_metadata_respond(decoder
, FLAC__METADATA_TYPE_APPLICATION
))
889 return die_s_("returned false", decoder
);
893 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
894 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
896 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
900 * ignore all, respond APPLICATION id of app#1
903 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
904 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
905 return die_s_("returned false", decoder
);
908 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
909 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder
, application1_
.data
.application
.id
))
910 return die_s_("returned false", decoder
);
914 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
916 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
920 * ignore all, respond APPLICATION id of app#1 & app#2
923 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
924 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
925 return die_s_("returned false", decoder
);
928 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
929 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder
, application1_
.data
.application
.id
))
930 return die_s_("returned false", decoder
);
933 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #2)... ");
934 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder
, application2_
.data
.application
.id
))
935 return die_s_("returned false", decoder
);
939 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
940 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
942 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
946 * respond all, ignore APPLICATION, respond APPLICATION id of app#1
949 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
950 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
951 return die_s_("returned false", decoder
);
954 printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
955 if(!FLAC__stream_decoder_set_metadata_ignore(decoder
, FLAC__METADATA_TYPE_APPLICATION
))
956 return die_s_("returned false", decoder
);
959 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
960 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder
, application1_
.data
.application
.id
))
961 return die_s_("returned false", decoder
);
965 if(is_ogg
) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
966 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
967 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
968 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
969 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
970 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
971 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
972 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
973 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
976 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
977 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
978 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
979 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
980 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
981 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
982 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
983 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
986 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
990 * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
993 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
994 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
995 return die_s_("returned false", decoder
);
998 printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
999 if(!FLAC__stream_decoder_set_metadata_respond(decoder
, FLAC__METADATA_TYPE_APPLICATION
))
1000 return die_s_("returned false", decoder
);
1003 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
1004 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder
, application1_
.data
.application
.id
))
1005 return die_s_("returned false", decoder
);
1009 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
1011 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
1014 if(layer
< LAYER_FILE
) /* for LAYER_FILE, FLAC__stream_decoder_finish() closes the file */
1015 fclose(decoder_client_data
.file
);
1017 printf("testing FLAC__stream_decoder_delete()... ");
1018 FLAC__stream_decoder_delete(decoder
);
1021 printf("\nPASSED!\n");
1026 FLAC__bool
test_decoders(void)
1028 FLAC__bool is_ogg
= false;
1031 init_metadata_blocks_();
1033 if(!generate_file_(is_ogg
))
1036 if(!test_stream_decoder(LAYER_STREAM
, is_ogg
))
1039 if(!test_stream_decoder(LAYER_SEEKABLE_STREAM
, is_ogg
))
1042 if(!test_stream_decoder(LAYER_FILE
, is_ogg
))
1045 if(!test_stream_decoder(LAYER_FILENAME
, is_ogg
))
1048 (void) grabbag__file_remove_file(flacfilename(is_ogg
));
1050 free_metadata_blocks_();
1052 if(!FLAC_API_SUPPORTS_OGG_FLAC
|| is_ogg
)