diff options
Diffstat (limited to 'src/combined/demux_wavpack.c')
-rw-r--r-- | src/combined/demux_wavpack.c | 414 |
1 files changed, 0 insertions, 414 deletions
diff --git a/src/combined/demux_wavpack.c b/src/combined/demux_wavpack.c deleted file mode 100644 index 94a23acdc..000000000 --- a/src/combined/demux_wavpack.c +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright (C) 2006-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * xine interface to libwavpack by Diego Pettenò <flameeyes@gmail.com> - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#define LOG_MODULE "demux_wavpack" -#define LOG_VERBOSE -#define LOG - -#include "xine_internal.h" -#include "xineutils.h" -#include "demux.h" -#include "bswap.h" -#include "attributes.h" - -#include <wavpack/wavpack.h> -#include "combined_wavpack.h" - -typedef struct { - demux_plugin_t demux_plugin; - - xine_stream_t *stream; - fifo_buffer_t *audio_fifo; - input_plugin_t *input; - int status; - - uint32_t current_sample; - uint32_t samples; - uint32_t samplerate; - uint16_t bits_per_sample:6; - uint16_t channels:4; -} demux_wv_t; - -typedef struct { - demux_class_t demux_class; -} demux_wv_class_t; - -static int32_t xine_input_read_bytes(void *const this_gen, void *const data, - const int32_t bcount) { - input_plugin_t *const this = (input_plugin_t*)this_gen; - return this->read(this, data, bcount); -} - -static uint32_t xine_input_get_pos(void *const this_gen) { - input_plugin_t *const this = (input_plugin_t*)this_gen; - return this->get_current_pos(this); -} - -static int xine_input_set_pos_abs(void *const this_gen, const uint32_t pos) { - input_plugin_t *const this = (input_plugin_t*)this_gen; - return this->seek(this, pos, SEEK_SET); -} - -static int xine_input_set_pos_rel(void *const this_gen, const int32_t delta, - const int mode) { - input_plugin_t *const this = (input_plugin_t*)this_gen; - return this->seek(this, delta, mode); -} - -static int xine_input_push_back_byte(void *const this_gen, const int c) { - input_plugin_t *const this = (input_plugin_t*)this_gen; - if ( this->seek(this, -1, SEEK_CUR) ) { - return c; - } else { - lprintf("xine_input_push_back_byte: unable to seek.\n"); - return EOF; - } -} - -static uint32_t xine_input_get_length(void *const this_gen) { - input_plugin_t *const this = (input_plugin_t*)this_gen; - return this->get_length(this); -} - -static int xine_input_can_seek(void *const this_gen) { - input_plugin_t *const this = (input_plugin_t*)this_gen; - return INPUT_IS_SEEKABLE(this); -} - -static int32_t xine_input_write_bytes(__attr_unused void *const id, - __attr_unused void *const data, - __attr_unused const int32_t bcount) { - lprintf("xine_input_write_bytes: acces is read-only.\n"); - return 0; -} - -static WavpackStreamReader wavpack_input_reader = { - .read_bytes = xine_input_read_bytes, - .get_pos = xine_input_get_pos, - .set_pos_abs = xine_input_set_pos_abs, - .set_pos_rel = xine_input_set_pos_rel, - .push_back_byte = xine_input_push_back_byte, - .get_length = xine_input_get_length, - .can_seek = xine_input_can_seek, - .write_bytes = xine_input_write_bytes -}; - -static int open_wv_file(demux_wv_t *const this) { - WavpackContext *ctx = NULL; - char error[256]; /* Current version of wavpack (4.31) does not write more than this */ - wvheader_t header; - uint32_t tmp; - - /* Right now we don't support non-seekable streams */ - if (! INPUT_IS_SEEKABLE(this->input) ) { - lprintf("open_wv_file: non-seekable inputs aren't supported yet.\n"); - return 0; - } - - /* Read the file header */ - if (_x_demux_read_header(this->input, (uint8_t*)(&header), sizeof(wvheader_t)) != sizeof(wvheader_t)) - return 0; - - /* Validate header, we currently support only Wavpack 4 */ - if ( header.idcode != wvpk_signature || (le2me_16(header.wv_version) >> 8) != 4 ) - return 0; - - /* Rewind */ - this->input->seek(this->input, 0, SEEK_SET); - - ctx = WavpackOpenFileInputEx(&wavpack_input_reader, this->input, NULL, error, 0, 0); - if ( ! ctx ) { - lprintf("xine_open_wavpack_input: unable to open the stream: %s\n", error); - return 0; - } - - this->current_sample = 0; - this->samples = WavpackGetNumSamples(ctx); - lprintf("number of samples: %u\n", this->samples); - this->samplerate = WavpackGetSampleRate(ctx); - lprintf("samplerate: %u Hz\n", this->samplerate); - - tmp = WavpackGetBitsPerSample(ctx); _x_assert(tmp <= 32); - lprintf("bits_per_sample: %u\n", tmp); - this->bits_per_sample = tmp; - - tmp = WavpackGetNumChannels(ctx); _x_assert(tmp <= 8); - lprintf("channels: %u\n", tmp); - this->channels = tmp; - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, - wvpk_signature); - _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->samplerate); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, - this->bits_per_sample); - - WavpackCloseFile(ctx); - this->input->seek(this->input, SEEK_SET, 0); - - return 1; -} - -static int demux_wv_send_chunk(demux_plugin_t *const this_gen) { - demux_wv_t *const this = (demux_wv_t *) this_gen; - uint32_t bytes_to_read; uint8_t header_sent = 0; - wvheader_t header; - - lprintf("new frame\n"); - - /* Check if we've finished */ - if (this->current_sample >= this->samples) { - lprintf("all frames read\n"); - this->status = DEMUX_FINISHED; - return this->status; - } - - lprintf("current sample: %u\n", this->current_sample); - - do { - if ( this->input->read(this->input, (uint8_t*)(&header), sizeof(wvheader_t)) != sizeof(wvheader_t) ) { - this->status = DEMUX_FINISHED; - return this->status; - } - - /* The size of the block is «of course» minus 8, and - it also includes the size of the header. - */ - bytes_to_read = le2me_32(header.block_size) + 8 - sizeof(wvheader_t); - - lprintf("demux_wavpack: going to read %u bytes.\n", bytes_to_read); - - while(bytes_to_read) { - off_t bytes_read = 0, bytes_to_read_now, offset = 0; - buf_element_t *buf = NULL; - int64_t input_time_guess; - - /* Get a buffer */ - buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); - buf->type = BUF_AUDIO_WAVPACK; - buf->decoder_flags = 0; - - /* Set normalised position */ - buf->extra_info->input_normpos = - (int) ((double) this->input->get_current_pos(this->input) * 65535 / - this->input->get_length(this->input)); - - buf->pts = (((this->current_sample) / this->samplerate))*90000; - lprintf("Sending buffer with PTS %"PRId64"\n", buf->pts); - - /* Set time */ - input_time_guess = this->samples; - input_time_guess /= this->samplerate; - input_time_guess *= 1000; - input_time_guess *= buf->extra_info->input_normpos; - input_time_guess /= 65535; - buf->extra_info->input_time = input_time_guess; - - if ( ! header_sent ) - offset = sizeof(wvheader_t); - - bytes_to_read_now = ( bytes_to_read+offset > buf->max_size ) ? buf->max_size-offset : bytes_to_read; - if ( ! header_sent ) { - header_sent = 1; - xine_fast_memcpy(buf->content, &header, sizeof(wvheader_t)); - } - - bytes_read = this->input->read(this->input, &buf->content[offset], bytes_to_read_now); - - buf->size = offset + bytes_read; - - bytes_to_read -= bytes_read; - - if ( bytes_to_read <= 0 && (le2me_32(header.flags) & FINAL_BLOCK) == FINAL_BLOCK) - buf->decoder_flags |= BUF_FLAG_FRAME_END; - - this->audio_fifo->put(this->audio_fifo, buf); - } - } while ( (le2me_32(header.flags) & FINAL_BLOCK) != FINAL_BLOCK ); - - this->current_sample += le2me_32(header.samples_count); - - return this->status; -} - -static void demux_wv_send_headers(demux_plugin_t *const this_gen) { - demux_wv_t *const this = (demux_wv_t *) this_gen; - buf_element_t *buf; - - this->audio_fifo = this->stream->audio_fifo; - - this->status = DEMUX_OK; - - /* Send start buffers */ - _x_demux_control_start(this->stream); - - /* Send header to decoder */ - if (this->audio_fifo) { - buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - - buf->type = BUF_AUDIO_WAVPACK; - buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; - buf->decoder_info[0] = this->input->get_length(this->input); - buf->decoder_info[1] = this->samplerate; - 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 int demux_wv_seek (demux_plugin_t *this_gen, - off_t start_pos, int start_time, int playing) { - demux_wv_t *const this = (demux_wv_t *) this_gen; - - /* If thread is not running, initialize demuxer */ - if( !playing ) { - - /* send new pts */ - _x_demux_control_newpts(this->stream, 0, 0); - - this->status = DEMUX_OK; - - } - - return this->status; -} - -static void demux_wv_dispose (demux_plugin_t *const this_gen) { - demux_wv_t *const this = (demux_wv_t *) this_gen; - - free(this); -} - -static int demux_wv_get_status (demux_plugin_t *const this_gen) { - const demux_wv_t *const this = (const demux_wv_t *) this_gen; - - return this->status; -} - -static int demux_wv_get_stream_length (demux_plugin_t *const this_gen) { - const demux_wv_t *const this = (demux_wv_t *) this_gen; - - return (this->samples*1000) / this->samplerate; -} - -static uint32_t demux_wv_get_capabilities(demux_plugin_t *const this_gen) { - return DEMUX_CAP_NOCAP; -} - -static int demux_wv_get_optional_data(demux_plugin_t *const this_gen, - void *data, const int data_type) { - return DEMUX_OPTIONAL_UNSUPPORTED; -} - -static demux_plugin_t *open_plugin (demux_class_t *const class_gen, - xine_stream_t *const stream, - input_plugin_t *const input) { - demux_wv_t *const this = calloc(1, sizeof (demux_wv_t)); - this->stream = stream; - this->input = input; - - this->demux_plugin.send_headers = demux_wv_send_headers; - this->demux_plugin.send_chunk = demux_wv_send_chunk; - this->demux_plugin.seek = demux_wv_seek; - this->demux_plugin.dispose = demux_wv_dispose; - this->demux_plugin.get_status = demux_wv_get_status; - this->demux_plugin.get_stream_length = demux_wv_get_stream_length; - this->demux_plugin.get_capabilities = demux_wv_get_capabilities; - this->demux_plugin.get_optional_data = demux_wv_get_optional_data; - this->demux_plugin.demux_class = class_gen; - - this->status = DEMUX_FINISHED; - switch (stream->content_detection_method) { - - case METHOD_BY_EXTENSION: { - const char *const mrl = input->get_mrl (input); - const char *const extensions = class_gen->get_extensions (class_gen); - - if (!_x_demux_check_extension (mrl, extensions)) { - free (this); - return NULL; - } - } - /* Falling through is intended */ - - case METHOD_BY_CONTENT: - case METHOD_EXPLICIT: - - if (!open_wv_file(this)) { - free (this); - return NULL; - } - - break; - - default: - free (this); - return NULL; - } - - return &this->demux_plugin; -} - -static const char *get_description (demux_class_t *const this_gen) { - return "Wavpack demux plugin"; -} - -static const char *get_identifier (demux_class_t *const this_gen) { - return "Wavpack"; -} - -static const char *get_extensions (demux_class_t *const this_gen) { - return "wv wvp"; -} - -static const char *get_mimetypes (demux_class_t *const this_gen) { - return "audio/x-wavpack: wv,wvp: WavPack audio;"; -} - -static void class_dispose (demux_class_t *const this_gen) { - demux_wv_class_t *const this = (demux_wv_class_t *) this_gen; - - free (this); -} - -void *demux_wv_init_plugin (xine_t *const xine, void *const data) { - demux_wv_class_t *const this = calloc(1, sizeof (demux_wv_class_t)); - - 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; -} |