1/* test_libFLAC - Unit tester for libFLAC 2 * Copyright (C) 2002,2003,2004,2005,2006,2007 Josh Coalson 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 */ 18 19#if HAVE_CONFIG_H 20# include <config.h> 21#endif 22 23#include <errno.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include <string.h> 27#if defined _MSC_VER || defined __MINGW32__ 28#if _MSC_VER <= 1600 /* @@@ [2G limit] */ 29#define fseeko fseek 30#define ftello ftell 31#endif 32#endif 33#include "decoders.h" 34#include "FLAC/assert.h" 35#include "FLAC/stream_decoder.h" 36#include "share/grabbag.h" 37#include "test_libs_common/file_utils_flac.h" 38#include "test_libs_common/metadata_utils.h" 39 40typedef enum { 41 LAYER_STREAM = 0, /* FLAC__stream_decoder_init_[ogg_]stream() without seeking */ 42 LAYER_SEEKABLE_STREAM, /* FLAC__stream_decoder_init_[ogg_]stream() with seeking */ 43 LAYER_FILE, /* FLAC__stream_decoder_init_[ogg_]FILE() */ 44 LAYER_FILENAME /* FLAC__stream_decoder_init_[ogg_]file() */ 45} Layer; 46 47static const char * const LayerString[] = { 48 "Stream", 49 "Seekable Stream", 50 "FILE*", 51 "Filename" 52}; 53 54typedef struct { 55 Layer layer; 56 FILE *file; 57 unsigned current_metadata_number; 58 FLAC__bool ignore_errors; 59 FLAC__bool error_occurred; 60} StreamDecoderClientData; 61 62static FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_, picture_, unknown_; 63static FLAC__StreamMetadata *expected_metadata_sequence_[9]; 64static unsigned num_expected_; 65static off_t flacfilesize_; 66 67static const char *flacfilename(FLAC__bool is_ogg) 68{ 69 return is_ogg? "metadata.oga" : "metadata.flac"; 70} 71 72static FLAC__bool die_(const char *msg) 73{ 74 printf("ERROR: %s\n", msg); 75 return false; 76} 77 78static FLAC__bool die_s_(const char *msg, const FLAC__StreamDecoder *decoder) 79{ 80 FLAC__StreamDecoderState state = FLAC__stream_decoder_get_state(decoder); 81 82 if(msg) 83 printf("FAILED, %s", msg); 84 else 85 printf("FAILED"); 86 87 printf(", state = %u (%s)\n", (unsigned)state, FLAC__StreamDecoderStateString[state]); 88 89 return false; 90} 91 92static void init_metadata_blocks_(void) 93{ 94 mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_); 95} 96 97static void free_metadata_blocks_(void) 98{ 99 mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_); 100} 101 102static FLAC__bool generate_file_(FLAC__bool is_ogg) 103{ 104 printf("\n\ngenerating %sFLAC file for decoder tests...\n", is_ogg? "Ogg ":""); 105 106 num_expected_ = 0; 107 expected_metadata_sequence_[num_expected_++] = &padding_; 108 expected_metadata_sequence_[num_expected_++] = &seektable_; 109 expected_metadata_sequence_[num_expected_++] = &application1_; 110 expected_metadata_sequence_[num_expected_++] = &application2_; 111 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 112 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 113 expected_metadata_sequence_[num_expected_++] = &picture_; 114 expected_metadata_sequence_[num_expected_++] = &unknown_; 115 /* WATCHOUT: for Ogg FLAC the encoder should move the VORBIS_COMMENT block to the front, right after STREAMINFO */ 116 117 if(!file_utils__generate_flacfile(is_ogg, flacfilename(is_ogg), &flacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_)) 118 return die_("creating the encoded file"); 119 120 return true; 121} 122 123static FLAC__StreamDecoderReadStatus stream_decoder_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) 124{ 125 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data; 126 const size_t requested_bytes = *bytes; 127 128 (void)decoder; 129 130 if(0 == dcd) { 131 printf("ERROR: client_data in read callback is NULL\n"); 132 return FLAC__STREAM_DECODER_READ_STATUS_ABORT; 133 } 134 135 if(dcd->error_occurred) 136 return FLAC__STREAM_DECODER_READ_STATUS_ABORT; 137 138 if(feof(dcd->file)) { 139 *bytes = 0; 140 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; 141 } 142 else if(requested_bytes > 0) { 143 *bytes = fread(buffer, 1, requested_bytes, dcd->file); 144 if(*bytes == 0) { 145 if(feof(dcd->file)) 146 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; 147 else 148 return FLAC__STREAM_DECODER_READ_STATUS_ABORT; 149 } 150 else { 151 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; 152 } 153 } 154 else 155 return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */ 156} 157 158static FLAC__StreamDecoderSeekStatus stream_decoder_seek_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) 159{ 160 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data; 161 162 (void)decoder; 163 164 if(0 == dcd) { 165 printf("ERROR: client_data in seek callback is NULL\n"); 166 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; 167 } 168 169 if(dcd->error_occurred) 170 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; 171 172 if(fseeko(dcd->file, (off_t)absolute_byte_offset, SEEK_SET) < 0) { 173 dcd->error_occurred = true; 174 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; 175 } 176 177 return FLAC__STREAM_DECODER_SEEK_STATUS_OK; 178} 179 180static FLAC__StreamDecoderTellStatus stream_decoder_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) 181{ 182 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data; 183 off_t offset; 184 185 (void)decoder; 186 187 if(0 == dcd) { 188 printf("ERROR: client_data in tell callback is NULL\n"); 189 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; 190 } 191 192 if(dcd->error_occurred) 193 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; 194 195 offset = ftello(dcd->file); 196 *absolute_byte_offset = (FLAC__uint64)offset; 197 198 if(offset < 0) { 199 dcd->error_occurred = true; 200 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; 201 } 202 203 return FLAC__STREAM_DECODER_TELL_STATUS_OK; 204} 205 206static FLAC__StreamDecoderLengthStatus stream_decoder_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) 207{ 208 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data; 209 210 (void)decoder; 211 212 if(0 == dcd) { 213 printf("ERROR: client_data in length callback is NULL\n"); 214 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; 215 } 216 217 if(dcd->error_occurred) 218 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; 219 220 *stream_length = (FLAC__uint64)flacfilesize_; 221 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; 222} 223 224static FLAC__bool stream_decoder_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_data) 225{ 226 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data; 227 228 (void)decoder; 229 230 if(0 == dcd) { 231 printf("ERROR: client_data in eof callback is NULL\n"); 232 return true; 233 } 234 235 if(dcd->error_occurred) 236 return true; 237 238 return feof(dcd->file); 239} 240 241static FLAC__StreamDecoderWriteStatus stream_decoder_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) 242{ 243 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data; 244 245 (void)decoder, (void)buffer; 246 247 if(0 == dcd) { 248 printf("ERROR: client_data in write callback is NULL\n"); 249 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; 250 } 251 252 if(dcd->error_occurred) 253 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; 254 255 if( 256 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER && frame->header.number.frame_number == 0) || 257 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER && frame->header.number.sample_number == 0) 258 ) { 259 printf("content... "); 260 fflush(stdout); 261 } 262 263 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; 264} 265 266static void stream_decoder_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) 267{ 268 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data; 269 270 (void)decoder; 271 272 if(0 == dcd) { 273 printf("ERROR: client_data in metadata callback is NULL\n"); 274 return; 275 } 276 277 if(dcd->error_occurred) 278 return; 279 280 printf("%d... ", dcd->current_metadata_number); 281 fflush(stdout); 282 283 if(dcd->current_metadata_number >= num_expected_) { 284 (void)die_("got more metadata blocks than expected"); 285 dcd->error_occurred = true; 286 } 287 else { 288 if(!mutils__compare_block(expected_metadata_sequence_[dcd->current_metadata_number], metadata)) { 289 (void)die_("metadata block mismatch"); 290 dcd->error_occurred = true; 291 } 292 } 293 dcd->current_metadata_number++; 294} 295 296static void stream_decoder_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) 297{ 298 StreamDecoderClientData *dcd = (StreamDecoderClientData*)client_data; 299 300 (void)decoder; 301 302 if(0 == dcd) { 303 printf("ERROR: client_data in error callback is NULL\n"); 304 return; 305 } 306 307 if(!dcd->ignore_errors) { 308 printf("ERROR: got error callback: err = %u (%s)\n", (unsigned)status, FLAC__StreamDecoderErrorStatusString[status]); 309 dcd->error_occurred = true; 310 } 311} 312 313static FLAC__bool stream_decoder_test_respond_(FLAC__StreamDecoder *decoder, StreamDecoderClientData *dcd, FLAC__bool is_ogg) 314{ 315 FLAC__StreamDecoderInitStatus init_status; 316 317 if(!FLAC__stream_decoder_set_md5_checking(decoder, true)) 318 return die_s_("at FLAC__stream_decoder_set_md5_checking(), returned false", decoder); 319 320 /* for FLAC__stream_encoder_init_FILE(), the FLAC__stream_encoder_finish() closes the file so we have to keep re-opening: */ 321 if(dcd->layer == LAYER_FILE) { 322 printf("opening %sFLAC file... ", is_ogg? "Ogg ":""); 323 dcd->file = fopen(flacfilename(is_ogg), "rb"); 324 if(0 == dcd->file) { 325 printf("ERROR (%s)\n", strerror(errno)); 326 return false; 327 } 328 printf("OK\n"); 329 } 330 331 switch(dcd->layer) { 332 case LAYER_STREAM: 333 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":""); 334 init_status = is_ogg? 335 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) : 336 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) 337 ; 338 break; 339 case LAYER_SEEKABLE_STREAM: 340 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":""); 341 init_status = is_ogg? 342 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) : 343 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); 344 break; 345 case LAYER_FILE: 346 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":""); 347 init_status = is_ogg? 348 FLAC__stream_decoder_init_ogg_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) : 349 FLAC__stream_decoder_init_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd); 350 break; 351 case LAYER_FILENAME: 352 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":""); 353 init_status = is_ogg? 354 FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) : 355 FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd); 356 break; 357 default: 358 die_("internal error 000"); 359 return false; 360 } 361 if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) 362 return die_s_(0, decoder); 363 printf("OK\n"); 364 365 dcd->current_metadata_number = 0; 366 367 if(dcd->layer < LAYER_FILE && fseeko(dcd->file, 0, SEEK_SET) < 0) { 368 printf("FAILED rewinding input, errno = %d\n", errno); 369 return false; 370 } 371 372 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... "); 373 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder)) 374 return die_s_("returned false", decoder); 375 printf("OK\n"); 376 377 printf("testing FLAC__stream_decoder_finish()... "); 378 if(!FLAC__stream_decoder_finish(decoder)) 379 return die_s_("returned false", decoder); 380 printf("OK\n"); 381 382 return true; 383} 384 385static FLAC__bool test_stream_decoder(Layer layer, FLAC__bool is_ogg) 386{ 387 FLAC__StreamDecoder *decoder; 388 FLAC__StreamDecoderInitStatus init_status; 389 FLAC__StreamDecoderState state; 390 StreamDecoderClientData decoder_client_data; 391 FLAC__bool expect; 392 393 decoder_client_data.layer = layer; 394 395 printf("\n+++ libFLAC unit test: FLAC__StreamDecoder (layer: %s, format: %s)\n\n", LayerString[layer], is_ogg? "Ogg FLAC" : "FLAC"); 396 397 printf("testing FLAC__stream_decoder_new()... "); 398 decoder = FLAC__stream_decoder_new(); 399 if(0 == decoder) { 400 printf("FAILED, returned NULL\n"); 401 return false; 402 } 403 printf("OK\n"); 404 405 printf("testing FLAC__stream_decoder_delete()... "); 406 FLAC__stream_decoder_delete(decoder); 407 printf("OK\n"); 408 409 printf("testing FLAC__stream_decoder_new()... "); 410 decoder = FLAC__stream_decoder_new(); 411 if(0 == decoder) { 412 printf("FAILED, returned NULL\n"); 413 return false; 414 } 415 printf("OK\n"); 416 417 switch(layer) { 418 case LAYER_STREAM: 419 case LAYER_SEEKABLE_STREAM: 420 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":""); 421 init_status = is_ogg? 422 FLAC__stream_decoder_init_ogg_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0) : 423 FLAC__stream_decoder_init_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0); 424 break; 425 case LAYER_FILE: 426 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":""); 427 init_status = is_ogg? 428 FLAC__stream_decoder_init_ogg_FILE(decoder, stdin, 0, 0, 0, 0) : 429 FLAC__stream_decoder_init_FILE(decoder, stdin, 0, 0, 0, 0); 430 break; 431 case LAYER_FILENAME: 432 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":""); 433 init_status = is_ogg? 434 FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0) : 435 FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0); 436 break; 437 default: 438 die_("internal error 003"); 439 return false; 440 } 441 if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS) 442 return die_s_(0, decoder); 443 printf("OK\n"); 444 445 printf("testing FLAC__stream_decoder_delete()... "); 446 FLAC__stream_decoder_delete(decoder); 447 printf("OK\n"); 448 449 num_expected_ = 0; 450 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 451 452 printf("testing FLAC__stream_decoder_new()... "); 453 decoder = FLAC__stream_decoder_new(); 454 if(0 == decoder) { 455 printf("FAILED, returned NULL\n"); 456 return false; 457 } 458 printf("OK\n"); 459 460 if(is_ogg) { 461 printf("testing FLAC__stream_decoder_set_ogg_serial_number()... "); 462 if(!FLAC__stream_decoder_set_ogg_serial_number(decoder, file_utils__ogg_serial_number)) 463 return die_s_("returned false", decoder); 464 printf("OK\n"); 465 } 466 467 printf("testing FLAC__stream_decoder_set_md5_checking()... "); 468 if(!FLAC__stream_decoder_set_md5_checking(decoder, true)) 469 return die_s_("returned false", decoder); 470 printf("OK\n"); 471 472 if(layer < LAYER_FILENAME) { 473 printf("opening %sFLAC file... ", is_ogg? "Ogg ":""); 474 decoder_client_data.file = fopen(flacfilename(is_ogg), "rb"); 475 if(0 == decoder_client_data.file) { 476 printf("ERROR (%s)\n", strerror(errno)); 477 return false; 478 } 479 printf("OK\n"); 480 } 481 482 switch(layer) { 483 case LAYER_STREAM: 484 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":""); 485 init_status = is_ogg? 486 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) : 487 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); 488 break; 489 case LAYER_SEEKABLE_STREAM: 490 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":""); 491 init_status = is_ogg? 492 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) : 493 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); 494 break; 495 case LAYER_FILE: 496 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":""); 497 init_status = is_ogg? 498 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) : 499 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); 500 break; 501 case LAYER_FILENAME: 502 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":""); 503 init_status = is_ogg? 504 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) : 505 FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data); 506 break; 507 default: 508 die_("internal error 009"); 509 return false; 510 } 511 if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) 512 return die_s_(0, decoder); 513 printf("OK\n"); 514 515 printf("testing FLAC__stream_decoder_get_state()... "); 516 state = FLAC__stream_decoder_get_state(decoder); 517 printf("returned state = %u (%s)... OK\n", state, FLAC__StreamDecoderStateString[state]); 518 519 decoder_client_data.current_metadata_number = 0; 520 decoder_client_data.ignore_errors = false; 521 decoder_client_data.error_occurred = false; 522 523 printf("testing FLAC__stream_decoder_get_md5_checking()... "); 524 if(!FLAC__stream_decoder_get_md5_checking(decoder)) { 525 printf("FAILED, returned false, expected true\n"); 526 return false; 527 } 528 printf("OK\n"); 529 530 printf("testing FLAC__stream_decoder_process_until_end_of_metadata()... "); 531 if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) 532 return die_s_("returned false", decoder); 533 printf("OK\n"); 534 535 printf("testing FLAC__stream_decoder_process_single()... "); 536 if(!FLAC__stream_decoder_process_single(decoder)) 537 return die_s_("returned false", decoder); 538 printf("OK\n"); 539 540 printf("testing FLAC__stream_decoder_skip_single_frame()... "); 541 if(!FLAC__stream_decoder_skip_single_frame(decoder)) 542 return die_s_("returned false", decoder); 543 printf("OK\n"); 544 545 if(layer < LAYER_FILE) { 546 printf("testing FLAC__stream_decoder_flush()... "); 547 if(!FLAC__stream_decoder_flush(decoder)) 548 return die_s_("returned false", decoder); 549 printf("OK\n"); 550 551 decoder_client_data.ignore_errors = true; 552 printf("testing FLAC__stream_decoder_process_single()... "); 553 if(!FLAC__stream_decoder_process_single(decoder)) 554 return die_s_("returned false", decoder); 555 printf("OK\n"); 556 decoder_client_data.ignore_errors = false; 557 } 558 559 expect = (layer != LAYER_STREAM); 560 printf("testing FLAC__stream_decoder_seek_absolute()... "); 561 if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect) 562 return die_s_(expect? "returned false" : "returned true", decoder); 563 printf("OK\n"); 564 565 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... "); 566 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder)) 567 return die_s_("returned false", decoder); 568 printf("OK\n"); 569 570 expect = (layer != LAYER_STREAM); 571 printf("testing FLAC__stream_decoder_seek_absolute()... "); 572 if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect) 573 return die_s_(expect? "returned false" : "returned true", decoder); 574 printf("OK\n"); 575 576 printf("testing FLAC__stream_decoder_get_channels()... "); 577 { 578 unsigned channels = FLAC__stream_decoder_get_channels(decoder); 579 if(channels != streaminfo_.data.stream_info.channels) { 580 printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels); 581 return false; 582 } 583 } 584 printf("OK\n"); 585 586 printf("testing FLAC__stream_decoder_get_bits_per_sample()... "); 587 { 588 unsigned bits_per_sample = FLAC__stream_decoder_get_bits_per_sample(decoder); 589 if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) { 590 printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample); 591 return false; 592 } 593 } 594 printf("OK\n"); 595 596 printf("testing FLAC__stream_decoder_get_sample_rate()... "); 597 { 598 unsigned sample_rate = FLAC__stream_decoder_get_sample_rate(decoder); 599 if(sample_rate != streaminfo_.data.stream_info.sample_rate) { 600 printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate); 601 return false; 602 } 603 } 604 printf("OK\n"); 605 606 printf("testing FLAC__stream_decoder_get_blocksize()... "); 607 { 608 unsigned blocksize = FLAC__stream_decoder_get_blocksize(decoder); 609 /* value could be anything since we're at the last block, so accept any reasonable answer */ 610 printf("returned %u... %s\n", blocksize, blocksize>0? "OK" : "FAILED"); 611 if(blocksize == 0) 612 return false; 613 } 614 615 printf("testing FLAC__stream_decoder_get_channel_assignment()... "); 616 { 617 FLAC__ChannelAssignment ca = FLAC__stream_decoder_get_channel_assignment(decoder); 618 printf("returned %u (%s)... OK\n", (unsigned)ca, FLAC__ChannelAssignmentString[ca]); 619 } 620 621 if(layer < LAYER_FILE) { 622 printf("testing FLAC__stream_decoder_reset()... "); 623 if(!FLAC__stream_decoder_reset(decoder)) { 624 state = FLAC__stream_decoder_get_state(decoder); 625 printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]); 626 return false; 627 } 628 printf("OK\n"); 629 630 if(layer == LAYER_STREAM) { 631 /* after a reset() we have to rewind the input ourselves */ 632 printf("rewinding input... "); 633 if(fseeko(decoder_client_data.file, 0, SEEK_SET) < 0) { 634 printf("FAILED, errno = %d\n", errno); 635 return false; 636 } 637 printf("OK\n"); 638 } 639 640 decoder_client_data.current_metadata_number = 0; 641 642 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... "); 643 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder)) 644 return die_s_("returned false", decoder); 645 printf("OK\n"); 646 } 647 648 printf("testing FLAC__stream_decoder_finish()... "); 649 if(!FLAC__stream_decoder_finish(decoder)) 650 return die_s_("returned false", decoder); 651 printf("OK\n"); 652 653 /* 654 * respond all 655 */ 656 657 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... "); 658 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) 659 return die_s_("returned false", decoder); 660 printf("OK\n"); 661 662 num_expected_ = 0; 663 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */ 664 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 665 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 666 expected_metadata_sequence_[num_expected_++] = &padding_; 667 expected_metadata_sequence_[num_expected_++] = &seektable_; 668 expected_metadata_sequence_[num_expected_++] = &application1_; 669 expected_metadata_sequence_[num_expected_++] = &application2_; 670 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 671 expected_metadata_sequence_[num_expected_++] = &picture_; 672 expected_metadata_sequence_[num_expected_++] = &unknown_; 673 } 674 else { 675 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 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_++] = &vorbiscomment_; 681 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 682 expected_metadata_sequence_[num_expected_++] = &picture_; 683 expected_metadata_sequence_[num_expected_++] = &unknown_; 684 } 685 686 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg)) 687 return false; 688 689 /* 690 * ignore all 691 */ 692 693 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... "); 694 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) 695 return die_s_("returned false", decoder); 696 printf("OK\n"); 697 698 num_expected_ = 0; 699 700 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg)) 701 return false; 702 703 /* 704 * respond all, ignore VORBIS_COMMENT 705 */ 706 707 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... "); 708 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) 709 return die_s_("returned false", decoder); 710 printf("OK\n"); 711 712 printf("testing FLAC__stream_decoder_set_metadata_ignore(VORBIS_COMMENT)... "); 713 if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT)) 714 return die_s_("returned false", decoder); 715 printf("OK\n"); 716 717 num_expected_ = 0; 718 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 719 expected_metadata_sequence_[num_expected_++] = &padding_; 720 expected_metadata_sequence_[num_expected_++] = &seektable_; 721 expected_metadata_sequence_[num_expected_++] = &application1_; 722 expected_metadata_sequence_[num_expected_++] = &application2_; 723 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 724 expected_metadata_sequence_[num_expected_++] = &picture_; 725 expected_metadata_sequence_[num_expected_++] = &unknown_; 726 727 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg)) 728 return false; 729 730 /* 731 * respond all, ignore APPLICATION 732 */ 733 734 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... "); 735 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) 736 return die_s_("returned false", decoder); 737 printf("OK\n"); 738 739 printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... "); 740 if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION)) 741 return die_s_("returned false", decoder); 742 printf("OK\n"); 743 744 num_expected_ = 0; 745 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */ 746 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 747 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 748 expected_metadata_sequence_[num_expected_++] = &padding_; 749 expected_metadata_sequence_[num_expected_++] = &seektable_; 750 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 751 expected_metadata_sequence_[num_expected_++] = &picture_; 752 expected_metadata_sequence_[num_expected_++] = &unknown_; 753 } 754 else { 755 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 756 expected_metadata_sequence_[num_expected_++] = &padding_; 757 expected_metadata_sequence_[num_expected_++] = &seektable_; 758 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 759 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 760 expected_metadata_sequence_[num_expected_++] = &picture_; 761 expected_metadata_sequence_[num_expected_++] = &unknown_; 762 } 763 764 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg)) 765 return false; 766 767 /* 768 * respond all, ignore APPLICATION id of app#1 769 */ 770 771 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... "); 772 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) 773 return die_s_("returned false", decoder); 774 printf("OK\n"); 775 776 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... "); 777 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) 778 return die_s_("returned false", decoder); 779 printf("OK\n"); 780 781 num_expected_ = 0; 782 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */ 783 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 784 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 785 expected_metadata_sequence_[num_expected_++] = &padding_; 786 expected_metadata_sequence_[num_expected_++] = &seektable_; 787 expected_metadata_sequence_[num_expected_++] = &application2_; 788 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 789 expected_metadata_sequence_[num_expected_++] = &picture_; 790 expected_metadata_sequence_[num_expected_++] = &unknown_; 791 } 792 else { 793 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 794 expected_metadata_sequence_[num_expected_++] = &padding_; 795 expected_metadata_sequence_[num_expected_++] = &seektable_; 796 expected_metadata_sequence_[num_expected_++] = &application2_; 797 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 798 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 799 expected_metadata_sequence_[num_expected_++] = &picture_; 800 expected_metadata_sequence_[num_expected_++] = &unknown_; 801 } 802 803 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg)) 804 return false; 805 806 /* 807 * respond all, ignore APPLICATION id of app#1 & app#2 808 */ 809 810 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... "); 811 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) 812 return die_s_("returned false", decoder); 813 printf("OK\n"); 814 815 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... "); 816 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) 817 return die_s_("returned false", decoder); 818 printf("OK\n"); 819 820 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #2)... "); 821 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application2_.data.application.id)) 822 return die_s_("returned false", decoder); 823 printf("OK\n"); 824 825 num_expected_ = 0; 826 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */ 827 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 828 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 829 expected_metadata_sequence_[num_expected_++] = &padding_; 830 expected_metadata_sequence_[num_expected_++] = &seektable_; 831 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 832 expected_metadata_sequence_[num_expected_++] = &picture_; 833 expected_metadata_sequence_[num_expected_++] = &unknown_; 834 } 835 else { 836 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 837 expected_metadata_sequence_[num_expected_++] = &padding_; 838 expected_metadata_sequence_[num_expected_++] = &seektable_; 839 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 840 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 841 expected_metadata_sequence_[num_expected_++] = &picture_; 842 expected_metadata_sequence_[num_expected_++] = &unknown_; 843 } 844 845 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg)) 846 return false; 847 848 /* 849 * ignore all, respond VORBIS_COMMENT 850 */ 851 852 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... "); 853 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) 854 return die_s_("returned false", decoder); 855 printf("OK\n"); 856 857 printf("testing FLAC__stream_decoder_set_metadata_respond(VORBIS_COMMENT)... "); 858 if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT)) 859 return die_s_("returned false", decoder); 860 printf("OK\n"); 861 862 num_expected_ = 0; 863 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 864 865 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg)) 866 return false; 867 868 /* 869 * ignore all, respond APPLICATION 870 */ 871 872 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... "); 873 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) 874 return die_s_("returned false", decoder); 875 printf("OK\n"); 876 877 printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... "); 878 if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION)) 879 return die_s_("returned false", decoder); 880 printf("OK\n"); 881 882 num_expected_ = 0; 883 expected_metadata_sequence_[num_expected_++] = &application1_; 884 expected_metadata_sequence_[num_expected_++] = &application2_; 885 886 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg)) 887 return false; 888 889 /* 890 * ignore all, respond APPLICATION id of app#1 891 */ 892 893 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... "); 894 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) 895 return die_s_("returned false", decoder); 896 printf("OK\n"); 897 898 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... "); 899 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) 900 return die_s_("returned false", decoder); 901 printf("OK\n"); 902 903 num_expected_ = 0; 904 expected_metadata_sequence_[num_expected_++] = &application1_; 905 906 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg)) 907 return false; 908 909 /* 910 * ignore all, respond APPLICATION id of app#1 & app#2 911 */ 912 913 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... "); 914 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) 915 return die_s_("returned false", decoder); 916 printf("OK\n"); 917 918 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... "); 919 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) 920 return die_s_("returned false", decoder); 921 printf("OK\n"); 922 923 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #2)... "); 924 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application2_.data.application.id)) 925 return die_s_("returned false", decoder); 926 printf("OK\n"); 927 928 num_expected_ = 0; 929 expected_metadata_sequence_[num_expected_++] = &application1_; 930 expected_metadata_sequence_[num_expected_++] = &application2_; 931 932 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg)) 933 return false; 934 935 /* 936 * respond all, ignore APPLICATION, respond APPLICATION id of app#1 937 */ 938 939 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... "); 940 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) 941 return die_s_("returned false", decoder); 942 printf("OK\n"); 943 944 printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... "); 945 if(!FLAC__stream_decoder_set_metadata_ignore(decoder, FLAC__METADATA_TYPE_APPLICATION)) 946 return die_s_("returned false", decoder); 947 printf("OK\n"); 948 949 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... "); 950 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder, application1_.data.application.id)) 951 return die_s_("returned false", decoder); 952 printf("OK\n"); 953 954 num_expected_ = 0; 955 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */ 956 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 957 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 958 expected_metadata_sequence_[num_expected_++] = &padding_; 959 expected_metadata_sequence_[num_expected_++] = &seektable_; 960 expected_metadata_sequence_[num_expected_++] = &application1_; 961 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 962 expected_metadata_sequence_[num_expected_++] = &picture_; 963 expected_metadata_sequence_[num_expected_++] = &unknown_; 964 } 965 else { 966 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 967 expected_metadata_sequence_[num_expected_++] = &padding_; 968 expected_metadata_sequence_[num_expected_++] = &seektable_; 969 expected_metadata_sequence_[num_expected_++] = &application1_; 970 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 971 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 972 expected_metadata_sequence_[num_expected_++] = &picture_; 973 expected_metadata_sequence_[num_expected_++] = &unknown_; 974 } 975 976 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg)) 977 return false; 978 979 /* 980 * ignore all, respond APPLICATION, ignore APPLICATION id of app#1 981 */ 982 983 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... "); 984 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder)) 985 return die_s_("returned false", decoder); 986 printf("OK\n"); 987 988 printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... "); 989 if(!FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_APPLICATION)) 990 return die_s_("returned false", decoder); 991 printf("OK\n"); 992 993 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... "); 994 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder, application1_.data.application.id)) 995 return die_s_("returned false", decoder); 996 printf("OK\n"); 997 998 num_expected_ = 0; 999 expected_metadata_sequence_[num_expected_++] = &application2_; 1000 1001 if(!stream_decoder_test_respond_(decoder, &decoder_client_data, is_ogg)) 1002 return false; 1003 1004 if(layer < LAYER_FILE) /* for LAYER_FILE, FLAC__stream_decoder_finish() closes the file */ 1005 fclose(decoder_client_data.file); 1006 1007 printf("testing FLAC__stream_decoder_delete()... "); 1008 FLAC__stream_decoder_delete(decoder); 1009 printf("OK\n"); 1010 1011 printf("\nPASSED!\n"); 1012 1013 return true; 1014} 1015 1016FLAC__bool test_decoders(void) 1017{ 1018 FLAC__bool is_ogg = false; 1019 1020 while(1) { 1021 init_metadata_blocks_(); 1022 1023 if(!generate_file_(is_ogg)) 1024 return false; 1025 1026 if(!test_stream_decoder(LAYER_STREAM, is_ogg)) 1027 return false; 1028 1029 if(!test_stream_decoder(LAYER_SEEKABLE_STREAM, is_ogg)) 1030 return false; 1031 1032 if(!test_stream_decoder(LAYER_FILE, is_ogg)) 1033 return false; 1034 1035 if(!test_stream_decoder(LAYER_FILENAME, is_ogg)) 1036 return false; 1037 1038 (void) grabbag__file_remove_file(flacfilename(is_ogg)); 1039 1040 free_metadata_blocks_(); 1041 1042 if(!FLAC_API_SUPPORTS_OGG_FLAC || is_ogg) 1043 break; 1044 is_ogg = true; 1045 } 1046 1047 return true; 1048} 1049