summaryrefslogtreecommitdiff
path: root/src/combined/demux_wavpack.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/combined/demux_wavpack.c')
-rw-r--r--src/combined/demux_wavpack.c414
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;
-}