From 0e0d536d4d4c3c354fdebd7ee8b1c70a2a9edc0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 4 Apr 2007 20:47:46 +0200 Subject: Move the flac plugins sources into the combined directory, like wavpack. --HG-- rename : src/libflac/decoder_flac.c => src/combined/decoder_flac.c rename : src/libflac/demux_flac.c => src/combined/demux_flac.c rename : src/libflac/demux_flac.h => src/combined/demux_flac.h --- configure.ac | 1 - src/Makefile.am | 1 - src/combined/Makefile.am | 11 +- src/combined/decoder_flac.c | 435 +++++++++++++++++++++++++ src/combined/demux_flac.c | 766 ++++++++++++++++++++++++++++++++++++++++++++ src/combined/demux_flac.h | 28 ++ src/libflac/Makefile.am | 14 - src/libflac/decoder_flac.c | 435 ------------------------- src/libflac/demux_flac.c | 766 -------------------------------------------- src/libflac/demux_flac.h | 28 -- 10 files changed, 1239 insertions(+), 1246 deletions(-) create mode 100644 src/combined/decoder_flac.c create mode 100644 src/combined/demux_flac.c create mode 100644 src/combined/demux_flac.h delete mode 100644 src/libflac/Makefile.am delete mode 100644 src/libflac/decoder_flac.c delete mode 100644 src/libflac/demux_flac.c delete mode 100644 src/libflac/demux_flac.h diff --git a/configure.ac b/configure.ac index 316635480..17d477d5d 100644 --- a/configure.ac +++ b/configure.ac @@ -2638,7 +2638,6 @@ src/libffmpeg/libavcodec/ppc/Makefile src/libffmpeg/libavcodec/sparc/Makefile src/libffmpeg/libavcodec/libpostproc/Makefile src/libffmpeg/libavutil/Makefile -src/libflac/Makefile src/liblpcm/Makefile src/libmad/Makefile src/libmpeg2/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index 0d5621593..df8e2d462 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,7 +28,6 @@ SUBDIRS = \ libspeex \ libreal \ libfaad \ - libflac \ libmusepack \ post \ combined diff --git a/src/combined/Makefile.am b/src/combined/Makefile.am index 0d27f71c0..884fcf0cc 100644 --- a/src/combined/Makefile.am +++ b/src/combined/Makefile.am @@ -4,9 +4,18 @@ if HAVE_WAVPACK xineplug_wavpack = xineplug_wavpack.la endif -xineplug_LTLIBRARIES = $(xineplug_wavpack) +if HAVE_LIBFLAC +xineplug_flac = xineplug_flac.la +endif + +xineplug_LTLIBRARIES = $(xineplug_wavpack) $(xineplug_flac) xineplug_wavpack_la_SOURCES = demux_wavpack.c decoder_wavpack.c combined_wavpack.c combined_wavpack.h xineplug_wavpack_la_CFLAGS = $(VISIBILITY_FLAG) $(WAVPACK_CFLAGS) -I$(srcdir)/../demuxers xineplug_wavpack_la_LIBADD = $(XINE_LIB) $(WAVPACK_LIBS) xineplug_wavpack_la_LDFLAGS = $(xineplug_ldflags) + +xineplug_flac_la_SOURCES = demux_flac.c decoder_flac.c demux_flac.h +xineplug_flac_la_CFLAGS = $(VISIBILITY_FLAG) $(LIBFLAC_CFLAGS) +xineplug_flac_la_LIBADD = $(XINE_LIB) $(LIBFLAC_LIBS) +xineplug_flac_la_LDFLAGS = $(xineplug_ldflags) diff --git a/src/combined/decoder_flac.c b/src/combined/decoder_flac.c new file mode 100644 index 000000000..9b77cc27d --- /dev/null +++ b/src/combined/decoder_flac.c @@ -0,0 +1,435 @@ +/* + * Copyright (C) 2000-2003 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * John McCutchan 2003 + * FLAC Decoder (http://flac.sf.net) + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include + +#if !defined FLAC_API_VERSION_CURRENT || FLAC_API_VERSION_CURRENT < 8 +#include +#define LEGACY_FLAC +#else +#undef LEGACY_FLAC +#endif + +#define LOG_MODULE "flac_decoder" +#define LOG_VERBOSE + +/* +#define LOG +*/ + +#include "xine_internal.h" +#include "audio_out.h" +#include "buffer.h" + +#include "demux_flac.h" + +typedef struct { + audio_decoder_class_t decoder_class; +} flac_class_t; + +typedef struct flac_decoder_s { + audio_decoder_t audio_decoder; + + int64_t pts; + + int output_sampling_rate; + int output_open; + int output_mode; + + xine_stream_t *stream; + + FLAC__StreamDecoder *flac_decoder; + + int sample_rate; + int bits_per_sample; + int channels; + + unsigned char *buf; + int buf_size; + int buf_pos; + int min_size; + +} flac_decoder_t; + +/* + * FLAC callback functions + */ + +static FLAC__StreamDecoderReadStatus +flac_read_callback (const FLAC__StreamDecoder *decoder, + FLAC__byte buffer[], + unsigned *bytes, + void *client_data) +{ + flac_decoder_t *this = (flac_decoder_t *)client_data; + int number_of_bytes_to_copy; + + lprintf("flac_read_callback: %d\n", *bytes); + + if (this->buf_pos > *bytes) + number_of_bytes_to_copy = *bytes; + else + number_of_bytes_to_copy = this->buf_pos; + + lprintf("number_of_bytes_to_copy: %d\n", number_of_bytes_to_copy); + + *bytes = number_of_bytes_to_copy; + + xine_fast_memcpy (buffer, this->buf, number_of_bytes_to_copy); + + this->buf_pos -= number_of_bytes_to_copy; + memmove(this->buf, &this->buf[number_of_bytes_to_copy], this->buf_pos ); + + if(number_of_bytes_to_copy) + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; + else + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; +} + +static FLAC__StreamDecoderWriteStatus +flac_write_callback (const FLAC__StreamDecoder *decoder, + const FLAC__Frame *frame, + const FLAC__int32 *const buffer[], + void *client_data) +{ + flac_decoder_t *this = (flac_decoder_t *)client_data; + audio_buffer_t *audio_buffer = NULL; + int samples_left = frame->header.blocksize; + int bytes_per_sample = (frame->header.bits_per_sample == 8)?1:2; + int buf_samples; + int8_t *data8; + int16_t *data16; + int i,j; + + lprintf("flac_write_callback\n"); + + while( samples_left ) { + + audio_buffer = this->stream->audio_out->get_buffer(this->stream->audio_out); + + if( audio_buffer->mem_size < samples_left * frame->header.channels * bytes_per_sample ) + buf_samples = audio_buffer->mem_size / (frame->header.channels * bytes_per_sample); + else + buf_samples = samples_left; + + + if( frame->header.bits_per_sample == 8 ) { + data8 = (int8_t *)audio_buffer->mem; + + for( j=0; j < buf_samples; j++ ) + for( i=0; i < frame->header.channels; i++ ) + *data8++ = buffer[i][j]; + + } else { + + data16 = (int16_t *)audio_buffer->mem; + + for( j=0; j < buf_samples; j++ ) + for( i=0; i < frame->header.channels; i++ ) + *data16++ = buffer[i][j]; + } + + audio_buffer->num_frames = buf_samples; + audio_buffer->vpts = this->pts; + this->pts = 0; + this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); + + samples_left -= buf_samples; + } + return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; +} + +static void +flac_metadata_callback (const FLAC__StreamDecoder *decoder, + const FLAC__StreamMetadata *metadata, + void *client_data) +{ + /* flac_decoder_t *this = (flac_decoder_t *)client_data; */ + + lprintf("Metadata callback called!\n"); + +#ifdef LOG + if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { + printf("libflac: min_blocksize = %d\n", metadata->data.stream_info.min_blocksize); + printf("libflac: max_blocksize = %d\n", metadata->data.stream_info.max_blocksize); + printf("libflac: min_framesize = %d\n", metadata->data.stream_info.min_framesize); + printf("libflac: max_framesize = %d\n", metadata->data.stream_info.max_framesize); + /* does not work well: + this->min_size = 2 * metadata->data.stream_info.max_blocksize; */ + } +#endif + + return; +} + +static void +flac_error_callback (const FLAC__StreamDecoder *decoder, + FLAC__StreamDecoderErrorStatus status, + void *client_data) +{ + /* This will be called if there is an error in the flac stream */ + lprintf("flac_error_callback\n"); + +#ifdef LOG + if (status == FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC) + printf("libflac: Decoder lost synchronization.\n"); + else if (status == FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER) + printf("libflac: Decoder encounted a corrupted frame header.\n"); + else if (status == FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH) + printf("libflac: Frame's data did not match the CRC in the footer.\n"); + else + printf("libflac: unknown error.\n"); +#endif + + return; +} + + +/* + * FLAC plugin decoder + */ + +static void +flac_reset (audio_decoder_t *this_gen) +{ + flac_decoder_t *this = (flac_decoder_t *) this_gen; + + this->buf_pos = 0; + + if( FLAC__stream_decoder_get_state(this->flac_decoder) != + FLAC__STREAM_DECODER_SEARCH_FOR_METADATA ) + FLAC__stream_decoder_flush (this->flac_decoder); +} + +static void +flac_discontinuity (audio_decoder_t *this_gen) +{ + flac_decoder_t *this = (flac_decoder_t *) this_gen; + + this->pts = 0; + + lprintf("Discontinuity!\n"); +} + +static void +flac_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) +{ + flac_decoder_t *this = (flac_decoder_t *) this_gen; + int ret = 1; + + /* We are getting the stream header, open up the audio + * device, and collect information about the stream + */ + if (buf->decoder_flags & BUF_FLAG_STDHEADER) + { + int mode = AO_CAP_MODE_MONO; + + this->sample_rate = buf->decoder_info[1]; + this->bits_per_sample = buf->decoder_info[2]; + this->channels = buf->decoder_info[3]; + + mode = _x_ao_channels2mode(this->channels); + + if (!this->output_open) + { + this->output_open = this->stream->audio_out->open ( + this->stream->audio_out, + this->stream, + this->bits_per_sample, + this->sample_rate, + mode); + + + } + this->buf_pos = 0; + } else if (this->output_open) + { + /* This isn't a header frame and we have opened the output device */ + + + /* What we have buffered so far, and what is coming in + * is larger than our buffer + */ + if (this->buf_pos + buf->size > this->buf_size) + { + this->buf_size += 2 * buf->size; + this->buf = realloc (this->buf, this->buf_size); + lprintf("reallocating buffer to %d\n", this->buf_size); + } + + xine_fast_memcpy (&this->buf[this->buf_pos], buf->content, buf->size); + this->buf_pos += buf->size; + + if (buf->pts) + this->pts = buf->pts; + + /* We have enough to decode a frame */ + while( ret && this->buf_pos > this->min_size ) { + + FLAC__StreamDecoderState state = FLAC__stream_decoder_get_state(this->flac_decoder); + + if( state == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA ) { + lprintf("process_until_end_of_metadata\n"); + ret = FLAC__stream_decoder_process_until_end_of_metadata (this->flac_decoder); + } else if ( state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC || + state == FLAC__STREAM_DECODER_READ_FRAME ) { + lprintf("process_single\n"); + ret = FLAC__stream_decoder_process_single (this->flac_decoder); + } else { + lprintf("aborted.\n"); + FLAC__stream_decoder_flush (this->flac_decoder); + break; + } + } + } else + return; + + +} + +static void +flac_dispose (audio_decoder_t *this_gen) { + flac_decoder_t *this = (flac_decoder_t *) this_gen; + + FLAC__stream_decoder_finish (this->flac_decoder); + + FLAC__stream_decoder_delete (this->flac_decoder); + + if (this->output_open) + this->stream->audio_out->close (this->stream->audio_out, this->stream); + + if (this->buf) + free(this->buf); + + free (this_gen); +} + +static audio_decoder_t * +open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { + flac_decoder_t *this ; + + this = (flac_decoder_t *) xine_xmalloc (sizeof (flac_decoder_t)); + + this->audio_decoder.decode_data = flac_decode_data; + this->audio_decoder.reset = flac_reset; + this->audio_decoder.discontinuity = flac_discontinuity; + this->audio_decoder.dispose = flac_dispose; + this->stream = stream; + + this->output_open = 0; + this->buf = NULL; + this->buf_size = 0; + this->min_size = 65536; + this->pts = 0; + + this->flac_decoder = FLAC__stream_decoder_new(); + +#ifdef LEGACY_FLAC + FLAC__stream_decoder_set_read_callback (this->flac_decoder, + flac_read_callback); + FLAC__stream_decoder_set_write_callback (this->flac_decoder, + flac_write_callback); + FLAC__stream_decoder_set_metadata_callback (this->flac_decoder, + flac_metadata_callback); + FLAC__stream_decoder_set_error_callback (this->flac_decoder, + flac_error_callback); + + FLAC__stream_decoder_set_client_data (this->flac_decoder, this); + + if (FLAC__stream_decoder_init (this->flac_decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) { + free (this); + return NULL; + } +#else + if ( FLAC__stream_decoder_init_stream (this->flac_decoder, + flac_read_callback, + NULL, /* seek */ + NULL, /* tell */ + NULL, /* length */ + NULL, /* eof */ + flac_write_callback, + NULL, /* metadata */ + flac_error_callback, + this + ) != FLAC__STREAM_DECODER_INIT_STATUS_OK ) { + free (this); + return NULL; + } +#endif + + return (audio_decoder_t *) this; +} + +/* + * flac plugin class + */ + +static char *get_identifier (audio_decoder_class_t *this) { + return "flacdec"; +} + +static char *get_description (audio_decoder_class_t *this) { + return "flac audio decoder plugin"; +} + +static void dispose_class (audio_decoder_class_t *this) { + free (this); +} + +static void * +init_plugin (xine_t *xine, void *data) { + flac_class_t *this; + + this = (flac_class_t *) xine_xmalloc (sizeof (flac_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.get_identifier = get_identifier; + this->decoder_class.get_description = get_description; + this->decoder_class.dispose = dispose_class; + + + return this; +} + +static uint32_t audio_types[] = { + BUF_AUDIO_FLAC, 0 + }; + +static const decoder_info_t dec_info_audio = { + audio_types, /* supported types */ + 5 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_DEMUX, 26, "flac", XINE_VERSION_CODE, NULL, demux_flac_init_class }, + { PLUGIN_AUDIO_DECODER, 15, "flacdec", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/combined/demux_flac.c b/src/combined/demux_flac.c new file mode 100644 index 000000000..43ee17d5c --- /dev/null +++ b/src/combined/demux_flac.c @@ -0,0 +1,766 @@ +/* + * Copyright (C) 2000-2006 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * + * John McCutchan + * FLAC demuxer (http://flac.sf.net) + * + * TODO: Skip id3v2 tags. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#if !defined FLAC_API_VERSION_CURRENT || FLAC_API_VERSION_CURRENT < 8 +#include +#define LEGACY_FLAC +#else +#undef LEGACY_FLAC +#endif + +#define LOG_MODULE "demux_flac" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include "xine_internal.h" +#include "xineutils.h" +#include "../demuxers/demux.h" + +#include "demux_flac.h" + +#ifndef LEGACY_FLAC +# define FLAC__SeekableStreamDecoder FLAC__StreamDecoder +#endif + +/* FLAC Demuxer plugin */ +typedef struct demux_flac_s { + demux_plugin_t demux_plugin; + + xine_stream_t *stream; + + fifo_buffer_t *audio_fifo; + fifo_buffer_t *video_fifo; + + input_plugin_t *input; + + int status; + + int seek_flag; + + off_t data_start; + off_t data_size; + + /* FLAC Stuff */ + FLAC__SeekableStreamDecoder *flac_decoder; + + uint64_t total_samples; + uint64_t bits_per_sample; + uint64_t channels; + uint64_t sample_rate; + uint64_t length_in_msec; +} demux_flac_t ; + + +/* FLAC Demuxer class */ +typedef struct demux_flac_class_s { + demux_class_t demux_class; + + xine_t *xine; + config_values_t *config; + +} demux_flac_class_t; + +/* FLAC Callbacks */ +static +#ifdef LEGACY_FLAC +FLAC__SeekableStreamDecoderReadStatus +#else +FLAC__StreamDecoderReadStatus +#endif +flac_read_callback (const FLAC__SeekableStreamDecoder *decoder, + FLAC__byte buffer[], + unsigned *bytes, + void *client_data) +{ + demux_flac_t *this = (demux_flac_t *)client_data; + input_plugin_t *input = this->input; + off_t offset = *bytes; + + lprintf("flac_read_callback\n"); + + /* This should only be called when flac is reading the metadata + * of the flac stream. + */ + + offset = input->read (input, buffer, offset); + + lprintf("Read %lld / %u bytes into buffer\n", offset, *bytes); + + /* This is the way to detect EOF with xine input plugins */ + if ( offset <= 0 && *bytes != 0 ) + { + *bytes = offset; + lprintf("Marking EOF\n"); + + this->status = DEMUX_FINISHED; +#ifdef LEGACY_FLAC + return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; +#else + return FLAC__STREAM_DECODER_READ_STATUS_ABORT; +#endif + } + else + { + *bytes = offset; + lprintf("Read was perfect\n"); + +#ifdef LEGACY_FLAC + return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK; +#else + return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; +#endif + } +} + +static +#ifdef LEGACY_FLAC +FLAC__SeekableStreamDecoderSeekStatus +#else +FLAC__StreamDecoderSeekStatus +#endif +flac_seek_callback (const FLAC__SeekableStreamDecoder *decoder, + FLAC__uint64 absolute_byte_offset, + void *client_data) +{ + input_plugin_t *input = ((demux_flac_t *)client_data)->input; + off_t offset; + + lprintf("flac_seek_callback\n"); + + offset = input->seek (input, absolute_byte_offset, SEEK_SET); + + if (offset == -1) +#ifdef LEGACY_FLAC + return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR; +#else + return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; +#endif + else +#ifdef LEGACY_FLAC + return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK; +#else + return FLAC__STREAM_DECODER_SEEK_STATUS_OK; +#endif +} + +static +#ifdef LEGACY_FLAC +FLAC__SeekableStreamDecoderTellStatus +#else +FLAC__StreamDecoderTellStatus +#endif +flac_tell_callback (const FLAC__SeekableStreamDecoder *decoder, + FLAC__uint64 *absolute_byte_offset, + void *client_data) +{ + input_plugin_t *input = ((demux_flac_t *)client_data)->input; + off_t offset; + + lprintf("flac_tell_callback\n"); + + offset = input->get_current_pos (input); + + *absolute_byte_offset = offset; + +#ifdef LEGACY_FLAC + return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK; +#else + return FLAC__STREAM_DECODER_TELL_STATUS_OK; +#endif +} + +static +#ifdef LEGACY_FLAC +FLAC__SeekableStreamDecoderLengthStatus +#else +FLAC__StreamDecoderLengthStatus +#endif +flac_length_callback (const FLAC__SeekableStreamDecoder *decoder, + FLAC__uint64 *stream_length, + void *client_data) +{ + input_plugin_t *input = ((demux_flac_t *)client_data)->input; + off_t offset; + + lprintf("flac_length_callback\n"); + + offset = input->get_length (input); + + /* FIXME, can flac handle -1 as offset ? */ +#ifdef LEGACY_FLAC + return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK; +#else + return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; +#endif +} + +static FLAC__bool +flac_eof_callback (const FLAC__SeekableStreamDecoder *decoder, + void *client_data) +{ + demux_flac_t *this = (demux_flac_t *)client_data; + + lprintf("flac_eof_callback\n"); + + if (this->status == DEMUX_FINISHED) + { + lprintf("flac_eof_callback: True!\n"); + + return true; + } + else + { + lprintf("flac_eof_callback: False!\n"); + + return false; + } +} + +static FLAC__StreamDecoderWriteStatus +flac_write_callback (const FLAC__SeekableStreamDecoder *decoder, + const FLAC__Frame *frame, + const FLAC__int32 * const buffer[], + void *client_data) +{ + /* This should never be called, all we use flac for in this demuxer + * is seeking. We do the decoding in the decoder + */ + + lprintf("Error: Write callback was called!\n"); + + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; +} + +static void +flac_metadata_callback (const FLAC__SeekableStreamDecoder *decoder, + const FLAC__StreamMetadata *metadata, + void *client_data) +{ + demux_flac_t *this = (demux_flac_t *)client_data; + + lprintf("IN: Metadata callback\n"); + + /* This should be called when we first look at a flac stream, + * We get information about the stream here. + */ + if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { + lprintf("Got METADATA!\n"); + + this->total_samples = metadata->data.stream_info.total_samples; + this->bits_per_sample = metadata->data.stream_info.bits_per_sample; + this->channels = metadata->data.stream_info.channels; + this->sample_rate = metadata->data.stream_info.sample_rate; + this->length_in_msec = (this->total_samples * 1000) / + this->sample_rate; + } + return; +} + +static void +flac_error_callback (const FLAC__SeekableStreamDecoder *decoder, + FLAC__StreamDecoderErrorStatus status, + void *client_data) +{ + demux_flac_t *this = (demux_flac_t *)client_data; + /* This will be called if there is an error when flac is seeking + * in the stream. + */ + + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_flac: flac_error_callback\n"); + + if (status == FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC) + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "demux_flac: Decoder lost synchronization.\n"); + else if (status == FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER) + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "demux_flac: Decoder encounted a corrupted frame header.\n"); + else if (status == FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH) + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "demux_flac: Frame's data did not match the CRC in the footer.\n"); + else + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_flac: unknown error.\n"); + + this->status = DEMUX_FINISHED; + + return; +} + +/* FLAC Demuxer plugin */ +static int +demux_flac_send_chunk (demux_plugin_t *this_gen) { + demux_flac_t *this = (demux_flac_t *) this_gen; + buf_element_t *buf = NULL; + off_t current_file_pos, file_size = 0; + int64_t current_pts; + unsigned int remaining_sample_bytes = 0; + + remaining_sample_bytes = 2048; + + current_file_pos = this->input->get_current_pos (this->input) + - this->data_start; + if( (this->data_size - this->data_start) > 0 ) + file_size = (this->data_size - this->data_start); + + current_pts = current_file_pos; + current_pts *= this->length_in_msec * 90; + if( file_size ) + current_pts /= file_size; + + if (this->seek_flag) { +#ifdef USE_ESTIMATED_PTS + _x_demux_control_newpts (this->stream, current_pts, BUF_FLAG_SEEK); +#else + _x_demux_control_newpts (this->stream, 0, BUF_FLAG_SEEK); +#endif + this->seek_flag = 0; + } + + + while (remaining_sample_bytes) + { + if(!this->audio_fifo) { + this->status = DEMUX_FINISHED; + break; + } + + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = BUF_AUDIO_FLAC; + if( file_size ) + buf->extra_info->input_normpos = (int) ((double)current_file_pos * 65535 / file_size); + buf->extra_info->input_time = current_pts / 90; +#ifdef USE_ESTIMATED_PTS + buf->pts = current_pts; +#else + buf->pts = 0; +#endif + + if (remaining_sample_bytes > buf->max_size) + buf->size = buf->max_size; + else + buf->size = remaining_sample_bytes; + + remaining_sample_bytes -= buf->size; + + if (this->input->read (this->input,buf->content,buf->size)!=buf->size) { + lprintf("buf->size != input->read()\n"); + + buf->free_buffer (buf); + this->status = DEMUX_FINISHED; + break; + } + + /* + if (!remaining_sample_bytes) + { + buf->decoder_flags |= BUF_FLAG_FRAME_END; + }*/ + + this->audio_fifo->put (this->audio_fifo, buf); + } + + return this->status; +} + +static void +demux_flac_send_headers (demux_plugin_t *this_gen) { + demux_flac_t *this = (demux_flac_t *) this_gen; + + buf_element_t *buf; + + lprintf("demux_flac_send_headers\n"); + + this->video_fifo = this->stream->video_fifo; + this->audio_fifo = this->stream->audio_fifo; + + this->status = DEMUX_OK; + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->channels); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->sample_rate); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->bits_per_sample); + + _x_demux_control_start (this->stream); + + if (this->audio_fifo) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = BUF_AUDIO_FLAC; + buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; + buf->decoder_info[0] = 0; + buf->decoder_info[1] = this->sample_rate; + buf->decoder_info[2] = this->bits_per_sample; + buf->decoder_info[3] = this->channels; + buf->size = 0; + this->audio_fifo->put (this->audio_fifo, buf); + } +} + +static void +demux_flac_dispose (demux_plugin_t *this_gen) { + demux_flac_t *this = (demux_flac_t *) this_gen; + + lprintf("demux_flac_dispose\n"); + + if (this->flac_decoder) +#ifdef LEGACY_FLAC + FLAC__seekable_stream_decoder_delete (this->flac_decoder); +#else + FLAC__stream_decoder_delete (this->flac_decoder); +#endif + + free(this); + return; +} + +static int +demux_flac_get_status (demux_plugin_t *this_gen) { + demux_flac_t *this = (demux_flac_t *) this_gen; + + lprintf("demux_flac_get_status\n"); + + return this->status; +} + + +static int +demux_flac_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { + demux_flac_t *this = (demux_flac_t *) this_gen; + + lprintf("demux_flac_seek\n"); + + start_pos = (off_t) ( (double) start_pos / 65535 * + this->input->get_length (this->input) ); + + if (!start_pos && start_time) { + double distance = (double)start_time; + + if (this->length_in_msec != 0) + { + distance /= (double)this->length_in_msec; + } + start_pos = (uint64_t)(distance * (this->data_size - this->data_start)); + } + + if (start_pos || !start_time) { + + start_pos += this->data_start; + this->input->seek (this->input, start_pos, SEEK_SET); + lprintf ("Seek to position: %lld\n", start_pos); + + } else { + + double distance = (double)start_time; + uint64_t target_sample; + FLAC__bool s = false; + + if (this->length_in_msec != 0) + { + distance /= (double)this->length_in_msec; + } + target_sample = (uint64_t)(distance * this->total_samples); + +#ifdef LEGACY_FLAC + s = FLAC__seekable_stream_decoder_seek_absolute (this->flac_decoder, + target_sample); +#else + s = FLAC__stream_decoder_seek_absolute (this->flac_decoder, + target_sample); +#endif + + if (s) { + lprintf ("Seek to: %d successfull!\n", start_time); + } else + this->status = DEMUX_FINISHED; + } + + _x_demux_flush_engine (this->stream); + this->seek_flag = 1; + + return this->status; +} + +static int +demux_flac_get_stream_length (demux_plugin_t *this_gen) { + demux_flac_t *this = (demux_flac_t *) this_gen; + + lprintf("demux_flac_get_stream_length\n"); + + if (this->flac_decoder) + return this->length_in_msec; + else + return 0; +} + +static uint32_t +demux_flac_get_capabilities (demux_plugin_t *this_gen) { + lprintf("demux_flac_get_capabilities\n"); + + return DEMUX_CAP_NOCAP; +} + +static int +demux_flac_get_optional_data (demux_plugin_t *this_gen, void *data, int dtype) { + lprintf("demux_flac_get_optional_data\n"); + + return DEMUX_OPTIONAL_UNSUPPORTED; +} + +static demux_plugin_t * +open_plugin (demux_class_t *class_gen, + xine_stream_t *stream, + input_plugin_t *input) { + demux_flac_t *this; + + lprintf("open_plugin\n"); + + switch (stream->content_detection_method) { + case METHOD_BY_CONTENT: + { + uint8_t buf[MAX_PREVIEW_SIZE]; + int len; + + /* + * try to get a preview of the data + */ + len = input->get_optional_data (input, buf, INPUT_OPTIONAL_DATA_PREVIEW); + if (len == INPUT_OPTIONAL_UNSUPPORTED) { + + if (input->get_capabilities (input) & INPUT_CAP_SEEKABLE) { + + input->seek (input, 0, SEEK_SET); + if ( (len=input->read (input, buf, 1024)) <= 0) + return NULL; + input->seek (input, 0, SEEK_SET); + + } else + return NULL; + } + + /* FIXME: Skip id3v2 tag */ + /* Look for fLaC tag at the beginning of file */ + if ( (buf[0] != 'f') || (buf[1] != 'L') || + (buf[2] != 'a') || (buf[3] != 'C') ) + return NULL; + } + break; + case METHOD_BY_EXTENSION: { + char *ending, *mrl; + + mrl = input->get_mrl (input); + + ending = strrchr (mrl, '.'); + + if (!ending || (strlen (ending) < 5)) + return NULL; + + if (strncasecmp (ending, ".flac", 5)) + return NULL; + } + break; + case METHOD_EXPLICIT: + break; + default: + return NULL; + break; + } + + /* + * if we reach this point, the input has been accepted. + */ + + this = xine_xmalloc (sizeof (demux_flac_t)); + this->stream = stream; + this->input = input; + + this->demux_plugin.send_headers = demux_flac_send_headers; + this->demux_plugin.send_chunk = demux_flac_send_chunk; + this->demux_plugin.seek = demux_flac_seek; + this->demux_plugin.dispose = demux_flac_dispose; + this->demux_plugin.get_status = demux_flac_get_status; + this->demux_plugin.get_stream_length = demux_flac_get_stream_length; + this->demux_plugin.get_capabilities = demux_flac_get_capabilities; + this->demux_plugin.get_optional_data = demux_flac_get_optional_data; + this->demux_plugin.demux_class = class_gen; + + this->seek_flag = 0; + + + /* Get a new FLAC decoder and hook up callbacks */ +#ifdef LEGACY_FLAC + this->flac_decoder = FLAC__seekable_stream_decoder_new(); + lprintf("this->flac_decoder: %p\n", this->flac_decoder); + + FLAC__seekable_stream_decoder_set_md5_checking (this->flac_decoder, false); + FLAC__seekable_stream_decoder_set_read_callback (this->flac_decoder, + flac_read_callback); + FLAC__seekable_stream_decoder_set_seek_callback (this->flac_decoder, + flac_seek_callback); + FLAC__seekable_stream_decoder_set_tell_callback (this->flac_decoder, + flac_tell_callback); + FLAC__seekable_stream_decoder_set_length_callback (this->flac_decoder, + flac_length_callback); + FLAC__seekable_stream_decoder_set_eof_callback (this->flac_decoder, + flac_eof_callback); + FLAC__seekable_stream_decoder_set_metadata_callback (this->flac_decoder, + flac_metadata_callback); + FLAC__seekable_stream_decoder_set_write_callback (this->flac_decoder, + flac_write_callback); + FLAC__seekable_stream_decoder_set_error_callback (this->flac_decoder, + flac_error_callback); + FLAC__seekable_stream_decoder_set_client_data (this->flac_decoder, + this); + + FLAC__seekable_stream_decoder_init (this->flac_decoder); +#else + this->flac_decoder = FLAC__stream_decoder_new(); + lprintf("this->flac_decoder: %p\n", this->flac_decoder); + + if ( ! this->flac_decoder ) { + free(this); + return NULL; + } + + FLAC__stream_decoder_set_md5_checking (this->flac_decoder, false); + + if ( FLAC__stream_decoder_init_stream(this->flac_decoder, + flac_read_callback, + flac_seek_callback, + flac_tell_callback, + flac_length_callback, + flac_eof_callback, + flac_write_callback, + flac_metadata_callback, + flac_error_callback, + this + ) != FLAC__STREAM_DECODER_INIT_STATUS_OK ) { +#ifdef LEGACY_FLAC + FLAC__seekable_stream_decoder_delete (this->flac_decoder); +#else + FLAC__stream_decoder_delete (this->flac_decoder); +#endif + free(this); + return NULL; + } +#endif + + /* Get some stream info */ + this->data_size = this->input->get_length (this->input); + this->data_start = this->input->get_current_pos (this->input); + + /* This will cause FLAC to give us the rest of the information on + * this flac stream + */ + this->status = DEMUX_OK; +#ifdef LEGACY_FLAC + FLAC__seekable_stream_decoder_process_until_end_of_metadata (this->flac_decoder); +#else + FLAC__stream_decoder_process_until_end_of_metadata (this->flac_decoder); +#endif + + lprintf("Processed file until end of metadata: %s\n", + this->status == DEMUX_OK ? "success" : "failure"); + + if (this->status != DEMUX_OK) { +#ifdef LEGACY_FLAC + FLAC__seekable_stream_decoder_delete (this->flac_decoder); +#else + FLAC__stream_decoder_delete (this->flac_decoder); +#endif + free (this); + return NULL; + } + + return &this->demux_plugin; +} + + +/* FLAC Demuxer class */ + +static char * +get_description (demux_class_t *this_gen) { + return "FLAC demux plugin"; +} + +static char * +get_identifier (demux_class_t *this_gen) { + return "FLAC"; +} + +static char * +get_extensions (demux_class_t *this_gen) { + return "flac"; +} + +static char * +get_mimetypes (demux_class_t *this_gen) { + return "application/x-flac: flac: FLAC Audio;"; +} + +static void +class_dispose (demux_class_t *this_gen) { + demux_flac_class_t *this = (demux_flac_class_t *) this_gen; + + lprintf("class_dispose\n"); + + free (this); +} + +void * +demux_flac_init_class (xine_t *xine, void *data) { + + demux_flac_class_t *this; + + lprintf("demux_flac_init_class\n"); + + this = xine_xmalloc (sizeof (demux_flac_class_t)); + this->config = xine->config; + this->xine = xine; + + this->demux_class.open_plugin = open_plugin; + this->demux_class.get_description = get_description; + this->demux_class.get_identifier = get_identifier; + this->demux_class.get_mimetypes = get_mimetypes; + this->demux_class.get_extensions = get_extensions; + this->demux_class.dispose = class_dispose; + + return this; +} diff --git a/src/combined/demux_flac.h b/src/combined/demux_flac.h new file mode 100644 index 000000000..6086781d1 --- /dev/null +++ b/src/combined/demux_flac.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2000-2003 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: demux_flac.h,v 1.2 2003/12/09 00:02:32 f1rmb Exp $ + */ + +#ifndef HAVE_DEMUX_FLAC_H +#define HAVE_DEMUX_FLAC_H + +void *demux_flac_init_class (xine_t *xine, void *data); + +#endif diff --git a/src/libflac/Makefile.am b/src/libflac/Makefile.am deleted file mode 100644 index 6449820bc..000000000 --- a/src/libflac/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -include $(top_srcdir)/misc/Makefile.common - -libdir = $(XINE_PLUGINDIR) - -if HAVE_LIBFLAC -lib_LTLIBRARIES = xineplug_flac.la -endif - -xineplug_flac_la_SOURCES = demux_flac.c decoder_flac.c -xineplug_flac_la_LIBADD = $(LIBFLAC_LIBS) $(XINE_LIB) -xineplug_flac_la_CFLAGS = $(LIBFLAC_CFLAGS) $(VISIBILITY_FLAG) -xineplug_flac_la_LDFLAGS = -avoid-version -module - -noinst_HEADERS = demux_flac.h diff --git a/src/libflac/decoder_flac.c b/src/libflac/decoder_flac.c deleted file mode 100644 index 9b77cc27d..000000000 --- a/src/libflac/decoder_flac.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Copyright (C) 2000-2003 the xine project - * - * This file is part of xine, a free video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * John McCutchan 2003 - * FLAC Decoder (http://flac.sf.net) - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include - -#if !defined FLAC_API_VERSION_CURRENT || FLAC_API_VERSION_CURRENT < 8 -#include -#define LEGACY_FLAC -#else -#undef LEGACY_FLAC -#endif - -#define LOG_MODULE "flac_decoder" -#define LOG_VERBOSE - -/* -#define LOG -*/ - -#include "xine_internal.h" -#include "audio_out.h" -#include "buffer.h" - -#include "demux_flac.h" - -typedef struct { - audio_decoder_class_t decoder_class; -} flac_class_t; - -typedef struct flac_decoder_s { - audio_decoder_t audio_decoder; - - int64_t pts; - - int output_sampling_rate; - int output_open; - int output_mode; - - xine_stream_t *stream; - - FLAC__StreamDecoder *flac_decoder; - - int sample_rate; - int bits_per_sample; - int channels; - - unsigned char *buf; - int buf_size; - int buf_pos; - int min_size; - -} flac_decoder_t; - -/* - * FLAC callback functions - */ - -static FLAC__StreamDecoderReadStatus -flac_read_callback (const FLAC__StreamDecoder *decoder, - FLAC__byte buffer[], - unsigned *bytes, - void *client_data) -{ - flac_decoder_t *this = (flac_decoder_t *)client_data; - int number_of_bytes_to_copy; - - lprintf("flac_read_callback: %d\n", *bytes); - - if (this->buf_pos > *bytes) - number_of_bytes_to_copy = *bytes; - else - number_of_bytes_to_copy = this->buf_pos; - - lprintf("number_of_bytes_to_copy: %d\n", number_of_bytes_to_copy); - - *bytes = number_of_bytes_to_copy; - - xine_fast_memcpy (buffer, this->buf, number_of_bytes_to_copy); - - this->buf_pos -= number_of_bytes_to_copy; - memmove(this->buf, &this->buf[number_of_bytes_to_copy], this->buf_pos ); - - if(number_of_bytes_to_copy) - return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; - else - return FLAC__STREAM_DECODER_READ_STATUS_ABORT; -} - -static FLAC__StreamDecoderWriteStatus -flac_write_callback (const FLAC__StreamDecoder *decoder, - const FLAC__Frame *frame, - const FLAC__int32 *const buffer[], - void *client_data) -{ - flac_decoder_t *this = (flac_decoder_t *)client_data; - audio_buffer_t *audio_buffer = NULL; - int samples_left = frame->header.blocksize; - int bytes_per_sample = (frame->header.bits_per_sample == 8)?1:2; - int buf_samples; - int8_t *data8; - int16_t *data16; - int i,j; - - lprintf("flac_write_callback\n"); - - while( samples_left ) { - - audio_buffer = this->stream->audio_out->get_buffer(this->stream->audio_out); - - if( audio_buffer->mem_size < samples_left * frame->header.channels * bytes_per_sample ) - buf_samples = audio_buffer->mem_size / (frame->header.channels * bytes_per_sample); - else - buf_samples = samples_left; - - - if( frame->header.bits_per_sample == 8 ) { - data8 = (int8_t *)audio_buffer->mem; - - for( j=0; j < buf_samples; j++ ) - for( i=0; i < frame->header.channels; i++ ) - *data8++ = buffer[i][j]; - - } else { - - data16 = (int16_t *)audio_buffer->mem; - - for( j=0; j < buf_samples; j++ ) - for( i=0; i < frame->header.channels; i++ ) - *data16++ = buffer[i][j]; - } - - audio_buffer->num_frames = buf_samples; - audio_buffer->vpts = this->pts; - this->pts = 0; - this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); - - samples_left -= buf_samples; - } - return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; -} - -static void -flac_metadata_callback (const FLAC__StreamDecoder *decoder, - const FLAC__StreamMetadata *metadata, - void *client_data) -{ - /* flac_decoder_t *this = (flac_decoder_t *)client_data; */ - - lprintf("Metadata callback called!\n"); - -#ifdef LOG - if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { - printf("libflac: min_blocksize = %d\n", metadata->data.stream_info.min_blocksize); - printf("libflac: max_blocksize = %d\n", metadata->data.stream_info.max_blocksize); - printf("libflac: min_framesize = %d\n", metadata->data.stream_info.min_framesize); - printf("libflac: max_framesize = %d\n", metadata->data.stream_info.max_framesize); - /* does not work well: - this->min_size = 2 * metadata->data.stream_info.max_blocksize; */ - } -#endif - - return; -} - -static void -flac_error_callback (const FLAC__StreamDecoder *decoder, - FLAC__StreamDecoderErrorStatus status, - void *client_data) -{ - /* This will be called if there is an error in the flac stream */ - lprintf("flac_error_callback\n"); - -#ifdef LOG - if (status == FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC) - printf("libflac: Decoder lost synchronization.\n"); - else if (status == FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER) - printf("libflac: Decoder encounted a corrupted frame header.\n"); - else if (status == FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH) - printf("libflac: Frame's data did not match the CRC in the footer.\n"); - else - printf("libflac: unknown error.\n"); -#endif - - return; -} - - -/* - * FLAC plugin decoder - */ - -static void -flac_reset (audio_decoder_t *this_gen) -{ - flac_decoder_t *this = (flac_decoder_t *) this_gen; - - this->buf_pos = 0; - - if( FLAC__stream_decoder_get_state(this->flac_decoder) != - FLAC__STREAM_DECODER_SEARCH_FOR_METADATA ) - FLAC__stream_decoder_flush (this->flac_decoder); -} - -static void -flac_discontinuity (audio_decoder_t *this_gen) -{ - flac_decoder_t *this = (flac_decoder_t *) this_gen; - - this->pts = 0; - - lprintf("Discontinuity!\n"); -} - -static void -flac_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) -{ - flac_decoder_t *this = (flac_decoder_t *) this_gen; - int ret = 1; - - /* We are getting the stream header, open up the audio - * device, and collect information about the stream - */ - if (buf->decoder_flags & BUF_FLAG_STDHEADER) - { - int mode = AO_CAP_MODE_MONO; - - this->sample_rate = buf->decoder_info[1]; - this->bits_per_sample = buf->decoder_info[2]; - this->channels = buf->decoder_info[3]; - - mode = _x_ao_channels2mode(this->channels); - - if (!this->output_open) - { - this->output_open = this->stream->audio_out->open ( - this->stream->audio_out, - this->stream, - this->bits_per_sample, - this->sample_rate, - mode); - - - } - this->buf_pos = 0; - } else if (this->output_open) - { - /* This isn't a header frame and we have opened the output device */ - - - /* What we have buffered so far, and what is coming in - * is larger than our buffer - */ - if (this->buf_pos + buf->size > this->buf_size) - { - this->buf_size += 2 * buf->size; - this->buf = realloc (this->buf, this->buf_size); - lprintf("reallocating buffer to %d\n", this->buf_size); - } - - xine_fast_memcpy (&this->buf[this->buf_pos], buf->content, buf->size); - this->buf_pos += buf->size; - - if (buf->pts) - this->pts = buf->pts; - - /* We have enough to decode a frame */ - while( ret && this->buf_pos > this->min_size ) { - - FLAC__StreamDecoderState state = FLAC__stream_decoder_get_state(this->flac_decoder); - - if( state == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA ) { - lprintf("process_until_end_of_metadata\n"); - ret = FLAC__stream_decoder_process_until_end_of_metadata (this->flac_decoder); - } else if ( state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC || - state == FLAC__STREAM_DECODER_READ_FRAME ) { - lprintf("process_single\n"); - ret = FLAC__stream_decoder_process_single (this->flac_decoder); - } else { - lprintf("aborted.\n"); - FLAC__stream_decoder_flush (this->flac_decoder); - break; - } - } - } else - return; - - -} - -static void -flac_dispose (audio_decoder_t *this_gen) { - flac_decoder_t *this = (flac_decoder_t *) this_gen; - - FLAC__stream_decoder_finish (this->flac_decoder); - - FLAC__stream_decoder_delete (this->flac_decoder); - - if (this->output_open) - this->stream->audio_out->close (this->stream->audio_out, this->stream); - - if (this->buf) - free(this->buf); - - free (this_gen); -} - -static audio_decoder_t * -open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { - flac_decoder_t *this ; - - this = (flac_decoder_t *) xine_xmalloc (sizeof (flac_decoder_t)); - - this->audio_decoder.decode_data = flac_decode_data; - this->audio_decoder.reset = flac_reset; - this->audio_decoder.discontinuity = flac_discontinuity; - this->audio_decoder.dispose = flac_dispose; - this->stream = stream; - - this->output_open = 0; - this->buf = NULL; - this->buf_size = 0; - this->min_size = 65536; - this->pts = 0; - - this->flac_decoder = FLAC__stream_decoder_new(); - -#ifdef LEGACY_FLAC - FLAC__stream_decoder_set_read_callback (this->flac_decoder, - flac_read_callback); - FLAC__stream_decoder_set_write_callback (this->flac_decoder, - flac_write_callback); - FLAC__stream_decoder_set_metadata_callback (this->flac_decoder, - flac_metadata_callback); - FLAC__stream_decoder_set_error_callback (this->flac_decoder, - flac_error_callback); - - FLAC__stream_decoder_set_client_data (this->flac_decoder, this); - - if (FLAC__stream_decoder_init (this->flac_decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) { - free (this); - return NULL; - } -#else - if ( FLAC__stream_decoder_init_stream (this->flac_decoder, - flac_read_callback, - NULL, /* seek */ - NULL, /* tell */ - NULL, /* length */ - NULL, /* eof */ - flac_write_callback, - NULL, /* metadata */ - flac_error_callback, - this - ) != FLAC__STREAM_DECODER_INIT_STATUS_OK ) { - free (this); - return NULL; - } -#endif - - return (audio_decoder_t *) this; -} - -/* - * flac plugin class - */ - -static char *get_identifier (audio_decoder_class_t *this) { - return "flacdec"; -} - -static char *get_description (audio_decoder_class_t *this) { - return "flac audio decoder plugin"; -} - -static void dispose_class (audio_decoder_class_t *this) { - free (this); -} - -static void * -init_plugin (xine_t *xine, void *data) { - flac_class_t *this; - - this = (flac_class_t *) xine_xmalloc (sizeof (flac_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.get_identifier = get_identifier; - this->decoder_class.get_description = get_description; - this->decoder_class.dispose = dispose_class; - - - return this; -} - -static uint32_t audio_types[] = { - BUF_AUDIO_FLAC, 0 - }; - -static const decoder_info_t dec_info_audio = { - audio_types, /* supported types */ - 5 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_DEMUX, 26, "flac", XINE_VERSION_CODE, NULL, demux_flac_init_class }, - { PLUGIN_AUDIO_DECODER, 15, "flacdec", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libflac/demux_flac.c b/src/libflac/demux_flac.c deleted file mode 100644 index 43ee17d5c..000000000 --- a/src/libflac/demux_flac.c +++ /dev/null @@ -1,766 +0,0 @@ -/* - * Copyright (C) 2000-2006 the xine project - * - * This file is part of xine, a free video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * - * John McCutchan - * FLAC demuxer (http://flac.sf.net) - * - * TODO: Skip id3v2 tags. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include - -#include - -#if !defined FLAC_API_VERSION_CURRENT || FLAC_API_VERSION_CURRENT < 8 -#include -#define LEGACY_FLAC -#else -#undef LEGACY_FLAC -#endif - -#define LOG_MODULE "demux_flac" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include "xine_internal.h" -#include "xineutils.h" -#include "../demuxers/demux.h" - -#include "demux_flac.h" - -#ifndef LEGACY_FLAC -# define FLAC__SeekableStreamDecoder FLAC__StreamDecoder -#endif - -/* FLAC Demuxer plugin */ -typedef struct demux_flac_s { - demux_plugin_t demux_plugin; - - xine_stream_t *stream; - - fifo_buffer_t *audio_fifo; - fifo_buffer_t *video_fifo; - - input_plugin_t *input; - - int status; - - int seek_flag; - - off_t data_start; - off_t data_size; - - /* FLAC Stuff */ - FLAC__SeekableStreamDecoder *flac_decoder; - - uint64_t total_samples; - uint64_t bits_per_sample; - uint64_t channels; - uint64_t sample_rate; - uint64_t length_in_msec; -} demux_flac_t ; - - -/* FLAC Demuxer class */ -typedef struct demux_flac_class_s { - demux_class_t demux_class; - - xine_t *xine; - config_values_t *config; - -} demux_flac_class_t; - -/* FLAC Callbacks */ -static -#ifdef LEGACY_FLAC -FLAC__SeekableStreamDecoderReadStatus -#else -FLAC__StreamDecoderReadStatus -#endif -flac_read_callback (const FLAC__SeekableStreamDecoder *decoder, - FLAC__byte buffer[], - unsigned *bytes, - void *client_data) -{ - demux_flac_t *this = (demux_flac_t *)client_data; - input_plugin_t *input = this->input; - off_t offset = *bytes; - - lprintf("flac_read_callback\n"); - - /* This should only be called when flac is reading the metadata - * of the flac stream. - */ - - offset = input->read (input, buffer, offset); - - lprintf("Read %lld / %u bytes into buffer\n", offset, *bytes); - - /* This is the way to detect EOF with xine input plugins */ - if ( offset <= 0 && *bytes != 0 ) - { - *bytes = offset; - lprintf("Marking EOF\n"); - - this->status = DEMUX_FINISHED; -#ifdef LEGACY_FLAC - return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; -#else - return FLAC__STREAM_DECODER_READ_STATUS_ABORT; -#endif - } - else - { - *bytes = offset; - lprintf("Read was perfect\n"); - -#ifdef LEGACY_FLAC - return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK; -#else - return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; -#endif - } -} - -static -#ifdef LEGACY_FLAC -FLAC__SeekableStreamDecoderSeekStatus -#else -FLAC__StreamDecoderSeekStatus -#endif -flac_seek_callback (const FLAC__SeekableStreamDecoder *decoder, - FLAC__uint64 absolute_byte_offset, - void *client_data) -{ - input_plugin_t *input = ((demux_flac_t *)client_data)->input; - off_t offset; - - lprintf("flac_seek_callback\n"); - - offset = input->seek (input, absolute_byte_offset, SEEK_SET); - - if (offset == -1) -#ifdef LEGACY_FLAC - return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR; -#else - return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; -#endif - else -#ifdef LEGACY_FLAC - return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK; -#else - return FLAC__STREAM_DECODER_SEEK_STATUS_OK; -#endif -} - -static -#ifdef LEGACY_FLAC -FLAC__SeekableStreamDecoderTellStatus -#else -FLAC__StreamDecoderTellStatus -#endif -flac_tell_callback (const FLAC__SeekableStreamDecoder *decoder, - FLAC__uint64 *absolute_byte_offset, - void *client_data) -{ - input_plugin_t *input = ((demux_flac_t *)client_data)->input; - off_t offset; - - lprintf("flac_tell_callback\n"); - - offset = input->get_current_pos (input); - - *absolute_byte_offset = offset; - -#ifdef LEGACY_FLAC - return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK; -#else - return FLAC__STREAM_DECODER_TELL_STATUS_OK; -#endif -} - -static -#ifdef LEGACY_FLAC -FLAC__SeekableStreamDecoderLengthStatus -#else -FLAC__StreamDecoderLengthStatus -#endif -flac_length_callback (const FLAC__SeekableStreamDecoder *decoder, - FLAC__uint64 *stream_length, - void *client_data) -{ - input_plugin_t *input = ((demux_flac_t *)client_data)->input; - off_t offset; - - lprintf("flac_length_callback\n"); - - offset = input->get_length (input); - - /* FIXME, can flac handle -1 as offset ? */ -#ifdef LEGACY_FLAC - return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK; -#else - return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; -#endif -} - -static FLAC__bool -flac_eof_callback (const FLAC__SeekableStreamDecoder *decoder, - void *client_data) -{ - demux_flac_t *this = (demux_flac_t *)client_data; - - lprintf("flac_eof_callback\n"); - - if (this->status == DEMUX_FINISHED) - { - lprintf("flac_eof_callback: True!\n"); - - return true; - } - else - { - lprintf("flac_eof_callback: False!\n"); - - return false; - } -} - -static FLAC__StreamDecoderWriteStatus -flac_write_callback (const FLAC__SeekableStreamDecoder *decoder, - const FLAC__Frame *frame, - const FLAC__int32 * const buffer[], - void *client_data) -{ - /* This should never be called, all we use flac for in this demuxer - * is seeking. We do the decoding in the decoder - */ - - lprintf("Error: Write callback was called!\n"); - - return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; -} - -static void -flac_metadata_callback (const FLAC__SeekableStreamDecoder *decoder, - const FLAC__StreamMetadata *metadata, - void *client_data) -{ - demux_flac_t *this = (demux_flac_t *)client_data; - - lprintf("IN: Metadata callback\n"); - - /* This should be called when we first look at a flac stream, - * We get information about the stream here. - */ - if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { - lprintf("Got METADATA!\n"); - - this->total_samples = metadata->data.stream_info.total_samples; - this->bits_per_sample = metadata->data.stream_info.bits_per_sample; - this->channels = metadata->data.stream_info.channels; - this->sample_rate = metadata->data.stream_info.sample_rate; - this->length_in_msec = (this->total_samples * 1000) / - this->sample_rate; - } - return; -} - -static void -flac_error_callback (const FLAC__SeekableStreamDecoder *decoder, - FLAC__StreamDecoderErrorStatus status, - void *client_data) -{ - demux_flac_t *this = (demux_flac_t *)client_data; - /* This will be called if there is an error when flac is seeking - * in the stream. - */ - - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_flac: flac_error_callback\n"); - - if (status == FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC) - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "demux_flac: Decoder lost synchronization.\n"); - else if (status == FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER) - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "demux_flac: Decoder encounted a corrupted frame header.\n"); - else if (status == FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH) - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "demux_flac: Frame's data did not match the CRC in the footer.\n"); - else - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_flac: unknown error.\n"); - - this->status = DEMUX_FINISHED; - - return; -} - -/* FLAC Demuxer plugin */ -static int -demux_flac_send_chunk (demux_plugin_t *this_gen) { - demux_flac_t *this = (demux_flac_t *) this_gen; - buf_element_t *buf = NULL; - off_t current_file_pos, file_size = 0; - int64_t current_pts; - unsigned int remaining_sample_bytes = 0; - - remaining_sample_bytes = 2048; - - current_file_pos = this->input->get_current_pos (this->input) - - this->data_start; - if( (this->data_size - this->data_start) > 0 ) - file_size = (this->data_size - this->data_start); - - current_pts = current_file_pos; - current_pts *= this->length_in_msec * 90; - if( file_size ) - current_pts /= file_size; - - if (this->seek_flag) { -#ifdef USE_ESTIMATED_PTS - _x_demux_control_newpts (this->stream, current_pts, BUF_FLAG_SEEK); -#else - _x_demux_control_newpts (this->stream, 0, BUF_FLAG_SEEK); -#endif - this->seek_flag = 0; - } - - - while (remaining_sample_bytes) - { - if(!this->audio_fifo) { - this->status = DEMUX_FINISHED; - break; - } - - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = BUF_AUDIO_FLAC; - if( file_size ) - buf->extra_info->input_normpos = (int) ((double)current_file_pos * 65535 / file_size); - buf->extra_info->input_time = current_pts / 90; -#ifdef USE_ESTIMATED_PTS - buf->pts = current_pts; -#else - buf->pts = 0; -#endif - - if (remaining_sample_bytes > buf->max_size) - buf->size = buf->max_size; - else - buf->size = remaining_sample_bytes; - - remaining_sample_bytes -= buf->size; - - if (this->input->read (this->input,buf->content,buf->size)!=buf->size) { - lprintf("buf->size != input->read()\n"); - - buf->free_buffer (buf); - this->status = DEMUX_FINISHED; - break; - } - - /* - if (!remaining_sample_bytes) - { - buf->decoder_flags |= BUF_FLAG_FRAME_END; - }*/ - - this->audio_fifo->put (this->audio_fifo, buf); - } - - return this->status; -} - -static void -demux_flac_send_headers (demux_plugin_t *this_gen) { - demux_flac_t *this = (demux_flac_t *) this_gen; - - buf_element_t *buf; - - lprintf("demux_flac_send_headers\n"); - - this->video_fifo = this->stream->video_fifo; - this->audio_fifo = this->stream->audio_fifo; - - this->status = DEMUX_OK; - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->channels); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->sample_rate); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->bits_per_sample); - - _x_demux_control_start (this->stream); - - if (this->audio_fifo) { - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = BUF_AUDIO_FLAC; - buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; - buf->decoder_info[0] = 0; - buf->decoder_info[1] = this->sample_rate; - buf->decoder_info[2] = this->bits_per_sample; - buf->decoder_info[3] = this->channels; - buf->size = 0; - this->audio_fifo->put (this->audio_fifo, buf); - } -} - -static void -demux_flac_dispose (demux_plugin_t *this_gen) { - demux_flac_t *this = (demux_flac_t *) this_gen; - - lprintf("demux_flac_dispose\n"); - - if (this->flac_decoder) -#ifdef LEGACY_FLAC - FLAC__seekable_stream_decoder_delete (this->flac_decoder); -#else - FLAC__stream_decoder_delete (this->flac_decoder); -#endif - - free(this); - return; -} - -static int -demux_flac_get_status (demux_plugin_t *this_gen) { - demux_flac_t *this = (demux_flac_t *) this_gen; - - lprintf("demux_flac_get_status\n"); - - return this->status; -} - - -static int -demux_flac_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { - demux_flac_t *this = (demux_flac_t *) this_gen; - - lprintf("demux_flac_seek\n"); - - start_pos = (off_t) ( (double) start_pos / 65535 * - this->input->get_length (this->input) ); - - if (!start_pos && start_time) { - double distance = (double)start_time; - - if (this->length_in_msec != 0) - { - distance /= (double)this->length_in_msec; - } - start_pos = (uint64_t)(distance * (this->data_size - this->data_start)); - } - - if (start_pos || !start_time) { - - start_pos += this->data_start; - this->input->seek (this->input, start_pos, SEEK_SET); - lprintf ("Seek to position: %lld\n", start_pos); - - } else { - - double distance = (double)start_time; - uint64_t target_sample; - FLAC__bool s = false; - - if (this->length_in_msec != 0) - { - distance /= (double)this->length_in_msec; - } - target_sample = (uint64_t)(distance * this->total_samples); - -#ifdef LEGACY_FLAC - s = FLAC__seekable_stream_decoder_seek_absolute (this->flac_decoder, - target_sample); -#else - s = FLAC__stream_decoder_seek_absolute (this->flac_decoder, - target_sample); -#endif - - if (s) { - lprintf ("Seek to: %d successfull!\n", start_time); - } else - this->status = DEMUX_FINISHED; - } - - _x_demux_flush_engine (this->stream); - this->seek_flag = 1; - - return this->status; -} - -static int -demux_flac_get_stream_length (demux_plugin_t *this_gen) { - demux_flac_t *this = (demux_flac_t *) this_gen; - - lprintf("demux_flac_get_stream_length\n"); - - if (this->flac_decoder) - return this->length_in_msec; - else - return 0; -} - -static uint32_t -demux_flac_get_capabilities (demux_plugin_t *this_gen) { - lprintf("demux_flac_get_capabilities\n"); - - return DEMUX_CAP_NOCAP; -} - -static int -demux_flac_get_optional_data (demux_plugin_t *this_gen, void *data, int dtype) { - lprintf("demux_flac_get_optional_data\n"); - - return DEMUX_OPTIONAL_UNSUPPORTED; -} - -static demux_plugin_t * -open_plugin (demux_class_t *class_gen, - xine_stream_t *stream, - input_plugin_t *input) { - demux_flac_t *this; - - lprintf("open_plugin\n"); - - switch (stream->content_detection_method) { - case METHOD_BY_CONTENT: - { - uint8_t buf[MAX_PREVIEW_SIZE]; - int len; - - /* - * try to get a preview of the data - */ - len = input->get_optional_data (input, buf, INPUT_OPTIONAL_DATA_PREVIEW); - if (len == INPUT_OPTIONAL_UNSUPPORTED) { - - if (input->get_capabilities (input) & INPUT_CAP_SEEKABLE) { - - input->seek (input, 0, SEEK_SET); - if ( (len=input->read (input, buf, 1024)) <= 0) - return NULL; - input->seek (input, 0, SEEK_SET); - - } else - return NULL; - } - - /* FIXME: Skip id3v2 tag */ - /* Look for fLaC tag at the beginning of file */ - if ( (buf[0] != 'f') || (buf[1] != 'L') || - (buf[2] != 'a') || (buf[3] != 'C') ) - return NULL; - } - break; - case METHOD_BY_EXTENSION: { - char *ending, *mrl; - - mrl = input->get_mrl (input); - - ending = strrchr (mrl, '.'); - - if (!ending || (strlen (ending) < 5)) - return NULL; - - if (strncasecmp (ending, ".flac", 5)) - return NULL; - } - break; - case METHOD_EXPLICIT: - break; - default: - return NULL; - break; - } - - /* - * if we reach this point, the input has been accepted. - */ - - this = xine_xmalloc (sizeof (demux_flac_t)); - this->stream = stream; - this->input = input; - - this->demux_plugin.send_headers = demux_flac_send_headers; - this->demux_plugin.send_chunk = demux_flac_send_chunk; - this->demux_plugin.seek = demux_flac_seek; - this->demux_plugin.dispose = demux_flac_dispose; - this->demux_plugin.get_status = demux_flac_get_status; - this->demux_plugin.get_stream_length = demux_flac_get_stream_length; - this->demux_plugin.get_capabilities = demux_flac_get_capabilities; - this->demux_plugin.get_optional_data = demux_flac_get_optional_data; - this->demux_plugin.demux_class = class_gen; - - this->seek_flag = 0; - - - /* Get a new FLAC decoder and hook up callbacks */ -#ifdef LEGACY_FLAC - this->flac_decoder = FLAC__seekable_stream_decoder_new(); - lprintf("this->flac_decoder: %p\n", this->flac_decoder); - - FLAC__seekable_stream_decoder_set_md5_checking (this->flac_decoder, false); - FLAC__seekable_stream_decoder_set_read_callback (this->flac_decoder, - flac_read_callback); - FLAC__seekable_stream_decoder_set_seek_callback (this->flac_decoder, - flac_seek_callback); - FLAC__seekable_stream_decoder_set_tell_callback (this->flac_decoder, - flac_tell_callback); - FLAC__seekable_stream_decoder_set_length_callback (this->flac_decoder, - flac_length_callback); - FLAC__seekable_stream_decoder_set_eof_callback (this->flac_decoder, - flac_eof_callback); - FLAC__seekable_stream_decoder_set_metadata_callback (this->flac_decoder, - flac_metadata_callback); - FLAC__seekable_stream_decoder_set_write_callback (this->flac_decoder, - flac_write_callback); - FLAC__seekable_stream_decoder_set_error_callback (this->flac_decoder, - flac_error_callback); - FLAC__seekable_stream_decoder_set_client_data (this->flac_decoder, - this); - - FLAC__seekable_stream_decoder_init (this->flac_decoder); -#else - this->flac_decoder = FLAC__stream_decoder_new(); - lprintf("this->flac_decoder: %p\n", this->flac_decoder); - - if ( ! this->flac_decoder ) { - free(this); - return NULL; - } - - FLAC__stream_decoder_set_md5_checking (this->flac_decoder, false); - - if ( FLAC__stream_decoder_init_stream(this->flac_decoder, - flac_read_callback, - flac_seek_callback, - flac_tell_callback, - flac_length_callback, - flac_eof_callback, - flac_write_callback, - flac_metadata_callback, - flac_error_callback, - this - ) != FLAC__STREAM_DECODER_INIT_STATUS_OK ) { -#ifdef LEGACY_FLAC - FLAC__seekable_stream_decoder_delete (this->flac_decoder); -#else - FLAC__stream_decoder_delete (this->flac_decoder); -#endif - free(this); - return NULL; - } -#endif - - /* Get some stream info */ - this->data_size = this->input->get_length (this->input); - this->data_start = this->input->get_current_pos (this->input); - - /* This will cause FLAC to give us the rest of the information on - * this flac stream - */ - this->status = DEMUX_OK; -#ifdef LEGACY_FLAC - FLAC__seekable_stream_decoder_process_until_end_of_metadata (this->flac_decoder); -#else - FLAC__stream_decoder_process_until_end_of_metadata (this->flac_decoder); -#endif - - lprintf("Processed file until end of metadata: %s\n", - this->status == DEMUX_OK ? "success" : "failure"); - - if (this->status != DEMUX_OK) { -#ifdef LEGACY_FLAC - FLAC__seekable_stream_decoder_delete (this->flac_decoder); -#else - FLAC__stream_decoder_delete (this->flac_decoder); -#endif - free (this); - return NULL; - } - - return &this->demux_plugin; -} - - -/* FLAC Demuxer class */ - -static char * -get_description (demux_class_t *this_gen) { - return "FLAC demux plugin"; -} - -static char * -get_identifier (demux_class_t *this_gen) { - return "FLAC"; -} - -static char * -get_extensions (demux_class_t *this_gen) { - return "flac"; -} - -static char * -get_mimetypes (demux_class_t *this_gen) { - return "application/x-flac: flac: FLAC Audio;"; -} - -static void -class_dispose (demux_class_t *this_gen) { - demux_flac_class_t *this = (demux_flac_class_t *) this_gen; - - lprintf("class_dispose\n"); - - free (this); -} - -void * -demux_flac_init_class (xine_t *xine, void *data) { - - demux_flac_class_t *this; - - lprintf("demux_flac_init_class\n"); - - this = xine_xmalloc (sizeof (demux_flac_class_t)); - this->config = xine->config; - this->xine = xine; - - this->demux_class.open_plugin = open_plugin; - this->demux_class.get_description = get_description; - this->demux_class.get_identifier = get_identifier; - this->demux_class.get_mimetypes = get_mimetypes; - this->demux_class.get_extensions = get_extensions; - this->demux_class.dispose = class_dispose; - - return this; -} diff --git a/src/libflac/demux_flac.h b/src/libflac/demux_flac.h deleted file mode 100644 index 6086781d1..000000000 --- a/src/libflac/demux_flac.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2000-2003 the xine project - * - * This file is part of xine, a free video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: demux_flac.h,v 1.2 2003/12/09 00:02:32 f1rmb Exp $ - */ - -#ifndef HAVE_DEMUX_FLAC_H -#define HAVE_DEMUX_FLAC_H - -void *demux_flac_init_class (xine_t *xine, void *data); - -#endif -- cgit v1.2.3