Mercurial > audlegacy-plugins
comparison src/flac112/plugin.c @ 489:ce4efa148521 trunk
[svn] flac 112 plugin: playback and detection use vfs; current situation is pretty similar to the one of flac 113 plugin
| author | giacomo |
|---|---|
| date | Sun, 21 Jan 2007 15:15:38 -0800 |
| parents | a157306caf03 |
| children | be4cde738a73 |
comparison
equal
deleted
inserted
replaced
| 488:5e375eca97da | 489:ce4efa148521 |
|---|---|
| 22 #include <glib.h> | 22 #include <glib.h> |
| 23 #include <pwd.h> | 23 #include <pwd.h> |
| 24 #include <sys/types.h> | 24 #include <sys/types.h> |
| 25 #include <unistd.h> | 25 #include <unistd.h> |
| 26 | 26 |
| 27 #include "audacious/plugin.h" | 27 #include <audacious/plugin.h> |
| 28 #include "audacious/output.h" | 28 #include <audacious/output.h> |
| 29 #include "audacious/util.h" | 29 #include <audacious/util.h> |
| 30 #include "audacious/configdb.h" | 30 #include <audacious/configdb.h> |
| 31 #include "audacious/titlestring.h" | 31 #include <audacious/titlestring.h> |
| 32 #include "audacious/vfs.h" | 32 #include <audacious/vfs.h> |
| 33 | 33 |
| 34 #ifdef HAVE_CONFIG_H | 34 #ifdef HAVE_CONFIG_H |
| 35 #include <config.h> | 35 #include <config.h> |
| 36 #endif | 36 #endif |
| 37 | 37 |
| 77 unsigned sample_format_bytes_per_sample; | 77 unsigned sample_format_bytes_per_sample; |
| 78 int seek_to_in_sec; | 78 int seek_to_in_sec; |
| 79 FLAC__bool has_replaygain; | 79 FLAC__bool has_replaygain; |
| 80 double replay_scale; | 80 double replay_scale; |
| 81 DitherContext dither_context; | 81 DitherContext dither_context; |
| 82 VFSFile *vfsfile; | |
| 82 } file_info_struct; | 83 } file_info_struct; |
| 83 | 84 |
| 84 typedef FLAC__StreamDecoderWriteStatus (*WriteCallback) (const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); | 85 typedef FLAC__StreamDecoderWriteStatus (*WriteCallback) (const void *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); |
| 85 typedef void (*MetadataCallback) (const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data); | 86 typedef void (*MetadataCallback) (const void *decoder, const FLAC__StreamMetadata *metadata, void *client_data); |
| 86 typedef void (*ErrorCallback) (const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); | 87 typedef void (*ErrorCallback) (const void *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); |
| 87 | 88 |
| 88 typedef struct { | 89 typedef struct { |
| 89 FLAC__bool seekable; | 90 FLAC__bool seekable; |
| 90 void* (*new_decoder) (void); | 91 void* (*new_decoder) (void); |
| 92 FLAC__bool (*set_source) (void *decoder, const char* source); | |
| 93 FLAC__bool (*unset_source) (void *decoder); | |
| 91 FLAC__bool (*set_md5_checking) (void *decoder, FLAC__bool value); | 94 FLAC__bool (*set_md5_checking) (void *decoder, FLAC__bool value); |
| 92 FLAC__bool (*set_source) (void *decoder, const char* source); | |
| 93 FLAC__bool (*set_metadata_ignore_all) (void *decoder); | 95 FLAC__bool (*set_metadata_ignore_all) (void *decoder); |
| 94 FLAC__bool (*set_metadata_respond) (void *decoder, FLAC__MetadataType type); | 96 FLAC__bool (*set_metadata_respond) (void *decoder, FLAC__MetadataType type); |
| 95 FLAC__bool (*set_write_callback) (void *decoder, WriteCallback value); | 97 FLAC__bool (*set_write_callback) (void *decoder, WriteCallback value); |
| 96 FLAC__bool (*set_metadata_callback) (void *decoder, MetadataCallback value); | 98 FLAC__bool (*set_metadata_callback) (void *decoder, MetadataCallback value); |
| 97 FLAC__bool (*set_error_callback) (void *decoder, ErrorCallback value); | 99 FLAC__bool (*set_error_callback) (void *decoder, ErrorCallback value); |
| 110 DECODER_HTTP | 112 DECODER_HTTP |
| 111 } decoder_t; | 113 } decoder_t; |
| 112 | 114 |
| 113 static void FLAC_XMMS__init(); | 115 static void FLAC_XMMS__init(); |
| 114 static int FLAC_XMMS__is_our_file(char *filename); | 116 static int FLAC_XMMS__is_our_file(char *filename); |
| 117 static int FLAC_XMMS__is_our_file_from_vfs(char *filename, VFSFile *vfsfile); | |
| 115 static void FLAC_XMMS__play_file(char *filename); | 118 static void FLAC_XMMS__play_file(char *filename); |
| 116 static void FLAC_XMMS__stop(); | 119 static void FLAC_XMMS__stop(); |
| 117 static void FLAC_XMMS__pause(short p); | 120 static void FLAC_XMMS__pause(short p); |
| 118 static void FLAC_XMMS__seek(int time); | 121 static void FLAC_XMMS__seek(int time); |
| 119 static int FLAC_XMMS__get_time(); | 122 static int FLAC_XMMS__get_time(); |
| 161 FLAC_XMMS__file_info_box, | 164 FLAC_XMMS__file_info_box, |
| 162 NULL, | 165 NULL, |
| 163 flac_get_tuple, | 166 flac_get_tuple, |
| 164 NULL, // set tuple | 167 NULL, // set tuple |
| 165 NULL, | 168 NULL, |
| 166 NULL, | 169 FLAC_XMMS__is_our_file_from_vfs, |
| 167 flac_fmts, | 170 flac_fmts, |
| 168 }; | 171 }; |
| 169 | 172 |
| 170 #define SAMPLES_PER_WRITE 512 | 173 #define SAMPLES_PER_WRITE 512 |
| 171 #define SAMPLE_BUFFER_SIZE ((FLAC__MAX_BLOCK_SIZE + SAMPLES_PER_WRITE) * FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS * (24/8)) | 174 #define SAMPLE_BUFFER_SIZE ((FLAC__MAX_BLOCK_SIZE + SAMPLES_PER_WRITE) * FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS * (24/8)) |
| 300 flac_cfg.stream.proxy_pass = NULL; | 303 flac_cfg.stream.proxy_pass = NULL; |
| 301 | 304 |
| 302 bmp_cfg_db_close(db); | 305 bmp_cfg_db_close(db); |
| 303 } | 306 } |
| 304 | 307 |
| 308 int FLAC_XMMS__is_our_file_from_vfs( gchar * filename , VFSFile * vfsfile ) | |
| 309 { | |
| 310 gchar magic_bytes[4]; | |
| 311 | |
| 312 if ( vfsfile == NULL ) | |
| 313 return 0; | |
| 314 | |
| 315 if ( vfs_fread( magic_bytes , 1 , 4 , vfsfile ) != 4 ) | |
| 316 return 0; | |
| 317 | |
| 318 if ( !strncmp( magic_bytes , "fLaC" , 4 ) ) | |
| 319 return 1; | |
| 320 else | |
| 321 return 0; | |
| 322 } | |
| 323 | |
| 305 int FLAC_XMMS__is_our_file(char *filename) | 324 int FLAC_XMMS__is_our_file(char *filename) |
| 306 { | 325 { |
| 307 FILE *f; | 326 VFSFile *vfsfile; |
| 308 FLAC__StreamMetadata streaminfo; | 327 gint result = 0; |
| 309 | 328 |
| 310 if (source_to_decoder_type (filename) == DECODER_FILE) { | 329 vfsfile = vfs_fopen( filename , "rb" ); |
| 311 if(0 == (f = fopen(filename, "r"))) | 330 |
| 312 return 0; | 331 if ( vfsfile == NULL ) return 0; |
| 313 fclose(f); | 332 |
| 314 if(!FLAC__metadata_get_streaminfo(filename, &streaminfo)) | 333 result = FLAC_XMMS__is_our_file_from_vfs( filename , vfsfile ); |
| 315 return 0; | 334 |
| 316 return 1; | 335 vfs_fclose( vfsfile ); |
| 317 } | 336 |
| 318 | 337 return result; |
| 319 if(!safe_decoder_init_(filename, &decoder2, &decoder_func_table2)) | |
| 320 return 0; | |
| 321 | |
| 322 decoder_func_table2 -> safe_decoder_finish(decoder2); | |
| 323 return 1; | |
| 324 } | 338 } |
| 325 | 339 |
| 326 void FLAC_XMMS__play_file(char *filename) | 340 void FLAC_XMMS__play_file(char *filename) |
| 327 { | 341 { |
| 328 FILE *f; | |
| 329 | |
| 330 sample_buffer_first_ = sample_buffer_last_ = 0; | 342 sample_buffer_first_ = sample_buffer_last_ = 0; |
| 331 audio_error_ = false; | 343 audio_error_ = false; |
| 332 file_info_.abort_flag = false; | 344 file_info_.abort_flag = false; |
| 333 file_info_.is_playing = false; | 345 file_info_.is_playing = false; |
| 334 file_info_.eof = false; | 346 file_info_.eof = false; |
| 335 file_info_.play_thread_open = false; | 347 file_info_.play_thread_open = false; |
| 336 file_info_.has_replaygain = false; | 348 file_info_.has_replaygain = false; |
| 337 | |
| 338 if (source_to_decoder_type (filename) == DECODER_FILE) { | |
| 339 if(0 == (f = fopen(filename, "r"))) | |
| 340 return; | |
| 341 fclose(f); | |
| 342 } | |
| 343 | 349 |
| 344 if(decoder_ == 0) | 350 if(decoder_ == 0) |
| 345 return; | 351 return; |
| 346 | 352 |
| 347 if(!safe_decoder_init_(filename, &decoder_, &decoder_func_table_)) | 353 if(!safe_decoder_init_(filename, &decoder_, &decoder_func_table_)) |
| 527 file_info_.eof = true; | 533 file_info_.eof = true; |
| 528 break; | 534 break; |
| 529 } | 535 } |
| 530 blocksize = sample_buffer_last_ - sample_buffer_first_ - s; | 536 blocksize = sample_buffer_last_ - sample_buffer_first_ - s; |
| 531 decode_position_frame_last = decode_position_frame; | 537 decode_position_frame_last = decode_position_frame; |
| 532 if(!decoder_func_table_->seekable || !FLAC__file_decoder_get_decode_position(decoder_, &decode_position_frame)) | 538 if(!decoder_func_table_->seekable || !FLAC__seekable_stream_decoder_get_decode_position(decoder_, &decode_position_frame)) |
| 533 decode_position_frame = 0; | 539 decode_position_frame = 0; |
| 534 } | 540 } |
| 535 if(sample_buffer_last_ - sample_buffer_first_ > 0) { | 541 if(sample_buffer_last_ - sample_buffer_first_ > 0) { |
| 536 const unsigned n = min(sample_buffer_last_ - sample_buffer_first_, SAMPLES_PER_WRITE); | 542 const unsigned n = min(sample_buffer_last_ - sample_buffer_first_, SAMPLES_PER_WRITE); |
| 537 int bytes = n * file_info_.channels * file_info_.sample_format_bytes_per_sample; | 543 int bytes = n * file_info_.channels * file_info_.sample_format_bytes_per_sample; |
| 569 else | 575 else |
| 570 xmms_usleep(10000); | 576 xmms_usleep(10000); |
| 571 if(decoder_func_table_->seekable && file_info_.seek_to_in_sec != -1) { | 577 if(decoder_func_table_->seekable && file_info_.seek_to_in_sec != -1) { |
| 572 const double distance = (double)file_info_.seek_to_in_sec * 1000.0 / (double)file_info_.length_in_msec; | 578 const double distance = (double)file_info_.seek_to_in_sec * 1000.0 / (double)file_info_.length_in_msec; |
| 573 unsigned target_sample = (unsigned)(distance * (double)file_info_.total_samples); | 579 unsigned target_sample = (unsigned)(distance * (double)file_info_.total_samples); |
| 574 if(FLAC__file_decoder_seek_absolute(decoder_, (FLAC__uint64)target_sample)) { | 580 if(FLAC__seekable_stream_decoder_seek_absolute(decoder_, (FLAC__uint64)target_sample)) { |
| 575 flac_ip.output->flush(file_info_.seek_to_in_sec * 1000); | 581 flac_ip.output->flush(file_info_.seek_to_in_sec * 1000); |
| 576 bh_index_last_w = bh_index_last_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE; | 582 bh_index_last_w = bh_index_last_o = flac_ip.output->output_time() / BITRATE_HIST_SEGMENT_MSEC % BITRATE_HIST_SIZE; |
| 577 if(!FLAC__file_decoder_get_decode_position(decoder_, &decode_position_frame)) | 583 if(!FLAC__seekable_stream_decoder_get_decode_position(decoder_, &decode_position_frame)) |
| 578 decode_position_frame = 0; | 584 decode_position_frame = 0; |
| 579 file_info_.seek_to_in_sec = -1; | 585 file_info_.seek_to_in_sec = -1; |
| 580 file_info_.eof = false; | 586 file_info_.eof = false; |
| 581 sample_buffer_first_ = sample_buffer_last_ = 0; | 587 sample_buffer_first_ = sample_buffer_last_ = 0; |
| 582 } | 588 } |
| 603 return 0; /* to silence the compiler warning about not returning a value */ | 609 return 0; /* to silence the compiler warning about not returning a value */ |
| 604 } | 610 } |
| 605 | 611 |
| 606 /*********** File decoder functions */ | 612 /*********** File decoder functions */ |
| 607 | 613 |
| 608 static FLAC__bool file_decoder_init (void *decoder) | 614 static FLAC__bool file_decoder_unset_source(void *decoder) |
| 609 { | 615 { |
| 610 return FLAC__file_decoder_init( (FLAC__FileDecoder*) decoder) == FLAC__FILE_DECODER_OK; | 616 if ( file_info_.vfsfile != NULL ) |
| 617 { | |
| 618 vfs_fclose( file_info_.vfsfile ); | |
| 619 file_info_.vfsfile = NULL; | |
| 620 } | |
| 611 } | 621 } |
| 612 | 622 |
| 613 static void file_decoder_safe_decoder_finish_(void *decoder) | 623 static void file_decoder_safe_decoder_finish_(void *decoder) |
| 614 { | 624 { |
| 615 if(decoder && FLAC__file_decoder_get_state((FLAC__FileDecoder *) decoder) != FLAC__FILE_DECODER_UNINITIALIZED) | 625 file_decoder_unset_source(decoder); |
| 616 FLAC__file_decoder_finish((FLAC__FileDecoder *) decoder); | 626 if(decoder && FLAC__seekable_stream_decoder_get_state((FLAC__SeekableStreamDecoder *) decoder) != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) |
| 627 FLAC__seekable_stream_decoder_finish((FLAC__SeekableStreamDecoder *) decoder); | |
| 617 } | 628 } |
| 618 | 629 |
| 619 static void file_decoder_safe_decoder_delete_(void *decoder) | 630 static void file_decoder_safe_decoder_delete_(void *decoder) |
| 620 { | 631 { |
| 621 if(decoder) { | 632 if(decoder) { |
| 622 file_decoder_safe_decoder_finish_(decoder); | 633 file_decoder_safe_decoder_finish_(decoder); |
| 623 FLAC__file_decoder_delete( (FLAC__FileDecoder *) decoder); | 634 FLAC__seekable_stream_decoder_delete( (FLAC__SeekableStreamDecoder *) decoder); |
| 624 } | 635 } |
| 625 } | 636 } |
| 626 | 637 |
| 627 static FLAC__bool file_decoder_is_eof(void *decoder) | 638 static FLAC__bool file_decoder_is_eof(void *decoder) |
| 628 { | 639 { |
| 629 return FLAC__file_decoder_get_state((FLAC__FileDecoder *) decoder) == FLAC__FILE_DECODER_END_OF_FILE; | 640 return FLAC__seekable_stream_decoder_get_state((FLAC__SeekableStreamDecoder *) decoder) == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM; |
| 641 } | |
| 642 | |
| 643 static FLAC__bool file_decoder_set_source(void *decoder, const char *filename) | |
| 644 { | |
| 645 if ( ( file_info_.vfsfile = vfs_fopen( filename , "rb" ) ) == NULL ) | |
| 646 return false; | |
| 647 else | |
| 648 return true; | |
| 649 } | |
| 650 | |
| 651 static FLAC__SeekableStreamDecoderReadStatus file_decoder_read_callback (const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data) | |
| 652 { | |
| 653 file_info_struct *file_info = (file_info_struct *)client_data; | |
| 654 (void) decoder; | |
| 655 | |
| 656 if( *bytes > 0 ) | |
| 657 { | |
| 658 *bytes = vfs_fread( buffer , sizeof(FLAC__byte) , *bytes , file_info->vfsfile ); | |
| 659 if ( *bytes == 0 ) | |
| 660 return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; | |
| 661 else | |
| 662 return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK; | |
| 663 } | |
| 664 else | |
| 665 return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; | |
| 666 } | |
| 667 | |
| 668 static FLAC__SeekableStreamDecoderSeekStatus file_decoder_seek_callback(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) | |
| 669 { | |
| 670 file_info_struct *file_info = (file_info_struct *)client_data; | |
| 671 (void) decoder; | |
| 672 | |
| 673 if ( vfs_fseek( file_info->vfsfile , (glong)absolute_byte_offset , SEEK_SET ) < 0 ) | |
| 674 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR; | |
| 675 else | |
| 676 return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK; | |
| 677 } | |
| 678 | |
| 679 static FLAC__SeekableStreamDecoderTellStatus file_decoder_tell_callback(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) | |
| 680 { | |
| 681 file_info_struct *file_info = (file_info_struct *)client_data; | |
| 682 glong pos; | |
| 683 (void)decoder; | |
| 684 | |
| 685 if ( (pos = vfs_ftell(file_info->vfsfile)) < 0 ) | |
| 686 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR; | |
| 687 else | |
| 688 { | |
| 689 *absolute_byte_offset = (FLAC__uint64)pos; | |
| 690 return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK; | |
| 691 } | |
| 692 } | |
| 693 | |
| 694 static FLAC__SeekableStreamDecoderLengthStatus file_decoder_length_callback(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) | |
| 695 { | |
| 696 file_info_struct *file_info = (file_info_struct *)client_data; | |
| 697 glong current_pos = 0; | |
| 698 glong length = 0; | |
| 699 (void)decoder; | |
| 700 | |
| 701 current_pos = vfs_ftell(file_info->vfsfile); | |
| 702 if ( current_pos < 0 ) | |
| 703 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR; | |
| 704 | |
| 705 if ( vfs_fseek( file_info->vfsfile , 0 , SEEK_END ) < 0 ) | |
| 706 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR; | |
| 707 | |
| 708 length = vfs_ftell(file_info->vfsfile); | |
| 709 if ( length < 0 ) | |
| 710 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR; | |
| 711 | |
| 712 /* put back stream position */ | |
| 713 if ( vfs_fseek( file_info->vfsfile , current_pos , SEEK_SET ) < 0 ) | |
| 714 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR; | |
| 715 else | |
| 716 { | |
| 717 *stream_length = (FLAC__uint64)length; | |
| 718 return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK; | |
| 719 } | |
| 720 } | |
| 721 | |
| 722 static FLAC__bool file_decoder_eof_callback (const FLAC__SeekableStreamDecoder *decoder, void *client_data) | |
| 723 { | |
| 724 file_info_struct *file_info = (file_info_struct *)client_data; | |
| 725 (void)decoder; | |
| 726 | |
| 727 return vfs_feof( file_info->vfsfile ); | |
| 728 } | |
| 729 | |
| 730 static FLAC__bool file_decoder_init (void *decoder) | |
| 731 { | |
| 732 gint result = 0; | |
| 733 FLAC__seekable_stream_decoder_set_read_callback(decoder, file_decoder_read_callback); | |
| 734 FLAC__seekable_stream_decoder_set_seek_callback(decoder, file_decoder_seek_callback); | |
| 735 FLAC__seekable_stream_decoder_set_tell_callback(decoder, file_decoder_tell_callback); | |
| 736 FLAC__seekable_stream_decoder_set_length_callback(decoder, file_decoder_length_callback); | |
| 737 FLAC__seekable_stream_decoder_set_eof_callback(decoder, file_decoder_eof_callback); | |
| 738 return FLAC__seekable_stream_decoder_init( (FLAC__SeekableStreamDecoder*) decoder) == FLAC__SEEKABLE_STREAM_DECODER_OK; | |
| 630 } | 739 } |
| 631 | 740 |
| 632 static const decoder_funcs_t FILE_DECODER_FUNCTIONS = { | 741 static const decoder_funcs_t FILE_DECODER_FUNCTIONS = { |
| 633 true, | 742 true, |
| 634 (void* (*) (void)) FLAC__file_decoder_new, | 743 (void* (*) (void)) FLAC__seekable_stream_decoder_new, |
| 635 (FLAC__bool (*) (void *, FLAC__bool)) FLAC__file_decoder_set_md5_checking, | 744 (FLAC__bool (*) (void *, const char*)) file_decoder_set_source, |
| 636 (FLAC__bool (*) (void *, const char*)) FLAC__file_decoder_set_filename, | 745 (FLAC__bool (*) (void *)) file_decoder_unset_source, |
| 637 (FLAC__bool (*) (void *)) FLAC__file_decoder_set_metadata_ignore_all, | 746 (FLAC__bool (*) (void *, FLAC__bool)) FLAC__seekable_stream_decoder_set_md5_checking, |
| 638 (FLAC__bool (*) (void *, FLAC__MetadataType)) FLAC__file_decoder_set_metadata_respond, | 747 (FLAC__bool (*) (void *)) FLAC__seekable_stream_decoder_set_metadata_ignore_all, |
| 639 (FLAC__bool (*) (void *, WriteCallback)) FLAC__file_decoder_set_write_callback, | 748 (FLAC__bool (*) (void *, FLAC__MetadataType)) FLAC__seekable_stream_decoder_set_metadata_respond, |
| 640 (FLAC__bool (*) (void *, MetadataCallback)) FLAC__file_decoder_set_metadata_callback, | 749 (FLAC__bool (*) (void *, WriteCallback)) FLAC__seekable_stream_decoder_set_write_callback, |
| 641 (FLAC__bool (*) (void *, ErrorCallback)) FLAC__file_decoder_set_error_callback, | 750 (FLAC__bool (*) (void *, MetadataCallback)) FLAC__seekable_stream_decoder_set_metadata_callback, |
| 642 (FLAC__bool (*) (void *, void *)) FLAC__file_decoder_set_client_data, | 751 (FLAC__bool (*) (void *, ErrorCallback)) FLAC__seekable_stream_decoder_set_error_callback, |
| 752 (FLAC__bool (*) (void *, void *)) FLAC__seekable_stream_decoder_set_client_data, | |
| 643 (FLAC__bool (*) (void *)) file_decoder_init, | 753 (FLAC__bool (*) (void *)) file_decoder_init, |
| 644 (void (*) (void *)) file_decoder_safe_decoder_finish_, | 754 (void (*) (void *)) file_decoder_safe_decoder_finish_, |
| 645 (void (*) (void *)) file_decoder_safe_decoder_delete_, | 755 (void (*) (void *)) file_decoder_safe_decoder_delete_, |
| 646 (FLAC__bool (*) (void *)) FLAC__file_decoder_process_until_end_of_metadata, | 756 (FLAC__bool (*) (void *)) FLAC__seekable_stream_decoder_process_until_end_of_metadata, |
| 647 (FLAC__bool (*) (void *)) FLAC__file_decoder_process_single, | 757 (FLAC__bool (*) (void *)) FLAC__seekable_stream_decoder_process_single, |
| 648 file_decoder_is_eof | 758 file_decoder_is_eof |
| 649 }; | 759 }; |
| 650 | 760 |
| 651 /*********** HTTP decoder functions */ | 761 /*********** HTTP decoder functions */ |
| 652 | 762 |
| 653 static gchar *url_; | 763 static gchar *url_ = NULL; |
| 654 | |
| 655 static FLAC__bool http_decoder_set_md5_checking (void *decoder, FLAC__bool value) | |
| 656 { | |
| 657 (void) value; | |
| 658 // operation unsupported | |
| 659 return FLAC__stream_decoder_get_state ((const FLAC__StreamDecoder *) decoder) == | |
| 660 FLAC__STREAM_DECODER_UNINITIALIZED; | |
| 661 } | |
| 662 | 764 |
| 663 static FLAC__bool http_decoder_set_url (void *decoder, const char* url) | 765 static FLAC__bool http_decoder_set_url (void *decoder, const char* url) |
| 664 { | 766 { |
| 665 (void) decoder; | 767 (void) decoder; |
| 666 url_ = g_strdup (url); | 768 url_ = g_strdup (url); |
| 769 return true; | |
| 770 } | |
| 771 | |
| 772 static FLAC__bool http_decoder_unset_url (void *decoder) | |
| 773 { | |
| 774 (void) decoder; | |
| 775 if ( url_ != NULL ) | |
| 776 { | |
| 777 g_free(url_); | |
| 778 url_ = NULL; | |
| 779 } | |
| 667 return true; | 780 return true; |
| 668 } | 781 } |
| 669 | 782 |
| 670 static FLAC__StreamDecoderReadStatus http_decoder_read_callback (const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data) | 783 static FLAC__StreamDecoderReadStatus http_decoder_read_callback (const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data) |
| 671 { | 784 { |
| 676 } | 789 } |
| 677 | 790 |
| 678 static FLAC__bool http_decoder_init (void *decoder) | 791 static FLAC__bool http_decoder_init (void *decoder) |
| 679 { | 792 { |
| 680 flac_http_open (url_, 0); | 793 flac_http_open (url_, 0); |
| 681 g_free (url_); | 794 http_decoder_unset_url(decoder); |
| 682 FLAC__stream_decoder_set_read_callback (decoder, http_decoder_read_callback); | 795 FLAC__stream_decoder_set_read_callback (decoder, http_decoder_read_callback); |
| 683 return FLAC__stream_decoder_init( (FLAC__StreamDecoder*) decoder) == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA; | 796 return FLAC__stream_decoder_init( (FLAC__StreamDecoder*) decoder) == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA; |
| 797 } | |
| 798 | |
| 799 static FLAC__bool http_decoder_set_md5_checking (void *decoder, FLAC__bool value) | |
| 800 { | |
| 801 return false; | |
| 684 } | 802 } |
| 685 | 803 |
| 686 static void http_decoder_safe_decoder_finish_(void *decoder) | 804 static void http_decoder_safe_decoder_finish_(void *decoder) |
| 687 { | 805 { |
| 688 if(decoder && FLAC__stream_decoder_get_state((FLAC__StreamDecoder *) decoder) != FLAC__STREAM_DECODER_UNINITIALIZED) { | 806 if(decoder && FLAC__stream_decoder_get_state((FLAC__StreamDecoder *) decoder) != FLAC__STREAM_DECODER_UNINITIALIZED) { |
| 705 } | 823 } |
| 706 | 824 |
| 707 static const decoder_funcs_t HTTP_DECODER_FUNCTIONS = { | 825 static const decoder_funcs_t HTTP_DECODER_FUNCTIONS = { |
| 708 false, | 826 false, |
| 709 (void* (*) (void)) FLAC__stream_decoder_new, | 827 (void* (*) (void)) FLAC__stream_decoder_new, |
| 710 http_decoder_set_md5_checking, | |
| 711 (FLAC__bool (*) (void *, const char*)) http_decoder_set_url, | 828 (FLAC__bool (*) (void *, const char*)) http_decoder_set_url, |
| 829 (FLAC__bool (*) (void *)) http_decoder_unset_url, | |
| 830 (FLAC__bool (*) (void *, FLAC__bool)) http_decoder_set_md5_checking, | |
| 712 (FLAC__bool (*) (void *)) FLAC__stream_decoder_set_metadata_ignore_all, | 831 (FLAC__bool (*) (void *)) FLAC__stream_decoder_set_metadata_ignore_all, |
| 713 (FLAC__bool (*) (void *, FLAC__MetadataType)) FLAC__stream_decoder_set_metadata_respond, | 832 (FLAC__bool (*) (void *, FLAC__MetadataType)) FLAC__stream_decoder_set_metadata_respond, |
| 714 (FLAC__bool (*) (void *, WriteCallback)) FLAC__stream_decoder_set_write_callback, | 833 (FLAC__bool (*) (void *, WriteCallback)) FLAC__stream_decoder_set_write_callback, |
| 715 (FLAC__bool (*) (void *, MetadataCallback)) FLAC__stream_decoder_set_metadata_callback, | 834 (FLAC__bool (*) (void *, MetadataCallback)) FLAC__stream_decoder_set_metadata_callback, |
| 716 (FLAC__bool (*) (void *, ErrorCallback)) FLAC__stream_decoder_set_error_callback, | 835 (FLAC__bool (*) (void *, ErrorCallback)) FLAC__stream_decoder_set_error_callback, |
| 760 void *decoder = *decoderp; | 879 void *decoder = *decoderp; |
| 761 | 880 |
| 762 decoder = *decoderp; | 881 decoder = *decoderp; |
| 763 fntab = *fntabp; | 882 fntab = *fntabp; |
| 764 | 883 |
| 884 fntab -> set_source(decoder, filename); | |
| 765 fntab -> set_md5_checking(decoder, false); | 885 fntab -> set_md5_checking(decoder, false); |
| 766 fntab -> set_source(decoder, filename); | |
| 767 fntab -> set_metadata_ignore_all(decoder); | 886 fntab -> set_metadata_ignore_all(decoder); |
| 768 fntab -> set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO); | 887 fntab -> set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO); |
| 769 fntab -> set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); | 888 fntab -> set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); |
| 770 fntab -> set_write_callback(decoder, write_callback_); | 889 fntab -> set_write_callback(decoder, write_callback_); |
| 771 fntab -> set_metadata_callback(decoder, metadata_callback_); | 890 fntab -> set_metadata_callback(decoder, metadata_callback_); |
| 772 fntab -> set_error_callback(decoder, error_callback_); | 891 fntab -> set_error_callback(decoder, error_callback_); |
| 773 fntab -> set_client_data(decoder, &file_info_); | 892 fntab -> set_client_data(decoder, &file_info_); |
| 774 if(!fntab -> decoder_init(decoder)) | 893 if(!fntab -> decoder_init(decoder)) |
| 894 { | |
| 895 fntab -> unset_source(decoder); | |
| 775 return false; | 896 return false; |
| 897 } | |
| 776 | 898 |
| 777 if(!fntab -> process_until_end_of_metadata(decoder)) | 899 if(!fntab -> process_until_end_of_metadata(decoder)) |
| 900 { | |
| 901 fntab -> unset_source(decoder); | |
| 778 return false; | 902 return false; |
| 903 } | |
| 779 } | 904 } |
| 780 | 905 |
| 781 return true; | 906 return true; |
| 782 } | 907 } |
| 783 | 908 |
