input_stream: forward-declare the struct
Hide the definition from C code, to prepare the transition to C++.
This commit is contained in:
parent
3203a7dd8c
commit
0273cd44b0
@ -707,7 +707,7 @@ endif
|
||||
libinput_a_SOURCES = \
|
||||
src/InputInit.cxx src/InputInit.hxx \
|
||||
src/InputRegistry.cxx src/InputRegistry.hxx \
|
||||
src/InputStream.cxx \
|
||||
src/InputStream.cxx src/InputStream.hxx \
|
||||
src/InputPlugin.hxx \
|
||||
src/InputInternal.cxx src/InputInternal.hxx \
|
||||
src/input/RewindInputPlugin.cxx src/input/RewindInputPlugin.hxx \
|
||||
|
@ -31,6 +31,7 @@ extern "C" {
|
||||
#include "DecoderControl.hxx"
|
||||
#include "DecoderInternal.hxx"
|
||||
#include "song.h"
|
||||
#include "InputStream.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "MusicBuffer.hxx"
|
||||
#include "MusicChunk.hxx"
|
||||
#include "tag.h"
|
||||
#include "input_stream.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include "fs/Path.hxx"
|
||||
#include "decoder_api.h"
|
||||
#include "tag.h"
|
||||
#include "input_stream.h"
|
||||
#include "InputStream.hxx"
|
||||
|
||||
extern "C" {
|
||||
#include "decoder_list.h"
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "InputInternal.hxx"
|
||||
#include "input_stream.h"
|
||||
#include "InputStream.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "input_stream.h"
|
||||
#include "InputStream.hxx"
|
||||
#include "InputRegistry.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
#include "input/RewindInputPlugin.hxx"
|
||||
@ -118,6 +118,52 @@ input_stream_lock_wait_ready(struct input_stream *is)
|
||||
g_mutex_unlock(is->mutex);
|
||||
}
|
||||
|
||||
const char *
|
||||
input_stream_get_mime_type(const struct input_stream *is)
|
||||
{
|
||||
assert(is != NULL);
|
||||
assert(is->ready);
|
||||
|
||||
return is->mime;
|
||||
}
|
||||
|
||||
void
|
||||
input_stream_override_mime_type(struct input_stream *is, const char *mime)
|
||||
{
|
||||
assert(is != NULL);
|
||||
assert(is->ready);
|
||||
|
||||
g_free(is->mime);
|
||||
is->mime = g_strdup(mime);
|
||||
}
|
||||
|
||||
goffset
|
||||
input_stream_get_size(const struct input_stream *is)
|
||||
{
|
||||
assert(is != NULL);
|
||||
assert(is->ready);
|
||||
|
||||
return is->size;
|
||||
}
|
||||
|
||||
goffset
|
||||
input_stream_get_offset(const struct input_stream *is)
|
||||
{
|
||||
assert(is != NULL);
|
||||
assert(is->ready);
|
||||
|
||||
return is->offset;
|
||||
}
|
||||
|
||||
bool
|
||||
input_stream_is_seekable(const struct input_stream *is)
|
||||
{
|
||||
assert(is != NULL);
|
||||
assert(is->ready);
|
||||
|
||||
return is->seekable;
|
||||
}
|
||||
|
||||
bool
|
||||
input_stream_cheap_seeking(const struct input_stream *is)
|
||||
{
|
||||
|
102
src/InputStream.hxx
Normal file
102
src/InputStream.hxx
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2013 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPD_INPUT_STREAM_HXX
|
||||
#define MPD_INPUT_STREAM_HXX
|
||||
|
||||
#include "input_stream.h"
|
||||
#include "check.h"
|
||||
#include "gcc.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
struct input_stream {
|
||||
/**
|
||||
* the plugin which implements this input stream
|
||||
*/
|
||||
const struct input_plugin *plugin;
|
||||
|
||||
/**
|
||||
* The absolute URI which was used to open this stream. May
|
||||
* be NULL if this is unknown.
|
||||
*/
|
||||
char *uri;
|
||||
|
||||
/**
|
||||
* A mutex that protects the mutable attributes of this object
|
||||
* and its implementation. It must be locked before calling
|
||||
* any of the public methods.
|
||||
*
|
||||
* This object is allocated by the client, and the client is
|
||||
* responsible for freeing it.
|
||||
*/
|
||||
GMutex *mutex;
|
||||
|
||||
/**
|
||||
* A cond that gets signalled when the state of this object
|
||||
* changes from the I/O thread. The client of this object may
|
||||
* wait on it. Optional, may be NULL.
|
||||
*
|
||||
* This object is allocated by the client, and the client is
|
||||
* responsible for freeing it.
|
||||
*/
|
||||
GCond *cond;
|
||||
|
||||
/**
|
||||
* indicates whether the stream is ready for reading and
|
||||
* whether the other attributes in this struct are valid
|
||||
*/
|
||||
bool ready;
|
||||
|
||||
/**
|
||||
* if true, then the stream is fully seekable
|
||||
*/
|
||||
bool seekable;
|
||||
|
||||
/**
|
||||
* the size of the resource, or -1 if unknown
|
||||
*/
|
||||
goffset size;
|
||||
|
||||
/**
|
||||
* the current offset within the stream
|
||||
*/
|
||||
goffset offset;
|
||||
|
||||
/**
|
||||
* the MIME content type of the resource, or NULL if unknown
|
||||
*/
|
||||
char *mime;
|
||||
};
|
||||
|
||||
gcc_nonnull(1)
|
||||
static inline void
|
||||
input_stream_lock(struct input_stream *is)
|
||||
{
|
||||
g_mutex_lock(is->mutex);
|
||||
}
|
||||
|
||||
gcc_nonnull(1)
|
||||
static inline void
|
||||
input_stream_unlock(struct input_stream *is)
|
||||
{
|
||||
g_mutex_unlock(is->mutex);
|
||||
}
|
||||
|
||||
#endif
|
@ -233,19 +233,19 @@ playlist_list_open_stream_mime2(struct input_stream *is, const char *mime)
|
||||
}
|
||||
|
||||
static struct playlist_provider *
|
||||
playlist_list_open_stream_mime(struct input_stream *is)
|
||||
playlist_list_open_stream_mime(struct input_stream *is, const char *full_mime)
|
||||
{
|
||||
assert(is->mime != NULL);
|
||||
assert(full_mime != NULL);
|
||||
|
||||
const char *semicolon = strchr(is->mime, ';');
|
||||
const char *semicolon = strchr(full_mime, ';');
|
||||
if (semicolon == NULL)
|
||||
return playlist_list_open_stream_mime2(is, is->mime);
|
||||
return playlist_list_open_stream_mime2(is, full_mime);
|
||||
|
||||
if (semicolon == is->mime)
|
||||
if (semicolon == full_mime)
|
||||
return NULL;
|
||||
|
||||
/* probe only the portion before the semicolon*/
|
||||
char *mime = g_strndup(is->mime, semicolon - is->mime);
|
||||
char *mime = g_strndup(full_mime, semicolon - full_mime);
|
||||
struct playlist_provider *playlist =
|
||||
playlist_list_open_stream_mime2(is, mime);
|
||||
g_free(mime);
|
||||
@ -285,8 +285,9 @@ playlist_list_open_stream(struct input_stream *is, const char *uri)
|
||||
|
||||
input_stream_lock_wait_ready(is);
|
||||
|
||||
if (is->mime != NULL) {
|
||||
playlist = playlist_list_open_stream_mime(is);
|
||||
const char *const mime = input_stream_get_mime_type(is);
|
||||
if (mime != NULL) {
|
||||
playlist = playlist_list_open_stream_mime(is, mime);
|
||||
if (playlist != NULL)
|
||||
return playlist;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "ArchiveInternal.hxx"
|
||||
#include "ArchivePlugin.hxx"
|
||||
#include "InputInternal.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
#include "refcount.h"
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "ArchiveInternal.hxx"
|
||||
#include "ArchivePlugin.hxx"
|
||||
#include "InputInternal.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
#include "refcount.h"
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "ArchiveInternal.hxx"
|
||||
#include "ArchivePlugin.hxx"
|
||||
#include "InputInternal.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
#include "refcount.h"
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
#define MPD_FLAC_IO_HANDLE_HXX
|
||||
|
||||
#include "gcc.h"
|
||||
#include "input_stream.h"
|
||||
#include "InputStream.hxx"
|
||||
|
||||
#include <FLAC/callback.h>
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "FLACInput.hxx"
|
||||
#include "decoder_api.h"
|
||||
#include "gcc.h"
|
||||
#include "input_stream.h"
|
||||
#include "InputStream.hxx"
|
||||
|
||||
FLAC__StreamDecoderReadStatus
|
||||
FLACInput::Read(FLAC__byte buffer[], size_t *bytes)
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "decoder_api.h"
|
||||
#include "FfmpegMetaData.hxx"
|
||||
#include "tag_handler.h"
|
||||
#include "InputStream.hxx"
|
||||
|
||||
extern "C" {
|
||||
#include "audio_check.h"
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "OggCodec.hxx"
|
||||
#include "audio_check.h"
|
||||
#include "tag_handler.h"
|
||||
#include "InputStream.hxx"
|
||||
|
||||
#include <opus.h>
|
||||
#include <ogg/ogg.h>
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "VorbisDecoderPlugin.h"
|
||||
#include "VorbisComments.hxx"
|
||||
#include "decoder_api.h"
|
||||
#include "InputStream.hxx"
|
||||
#include "OggCodec.hxx"
|
||||
|
||||
extern "C" {
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "config.h"
|
||||
#include "WavpackDecoderPlugin.hxx"
|
||||
#include "decoder_api.h"
|
||||
#include "InputStream.hxx"
|
||||
|
||||
extern "C" {
|
||||
#include "audio_check.h"
|
||||
|
@ -69,14 +69,14 @@ static AFfileoffset
|
||||
audiofile_file_length(AFvirtualfile *vfile)
|
||||
{
|
||||
struct input_stream *is = (struct input_stream *) vfile->closure;
|
||||
return is->size;
|
||||
return input_stream_get_size(is);
|
||||
}
|
||||
|
||||
static AFfileoffset
|
||||
audiofile_file_tell(AFvirtualfile *vfile)
|
||||
{
|
||||
struct input_stream *is = (struct input_stream *) vfile->closure;
|
||||
return is->offset;
|
||||
return input_stream_get_offset(is);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -93,7 +93,7 @@ audiofile_file_seek(AFvirtualfile *vfile, AFfileoffset offset, int is_relative)
|
||||
struct input_stream *is = (struct input_stream *) vfile->closure;
|
||||
int whence = (is_relative ? SEEK_CUR : SEEK_SET);
|
||||
if (input_stream_lock_seek(is, offset, whence, NULL)) {
|
||||
return is->offset;
|
||||
return input_stream_get_offset(is);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@ -166,7 +166,7 @@ audiofile_stream_decode(struct decoder *decoder, struct input_stream *is)
|
||||
char chunk[CHUNK_SIZE];
|
||||
enum decoder_command cmd;
|
||||
|
||||
if (!is->seekable) {
|
||||
if (!input_stream_is_seekable(is)) {
|
||||
g_warning("not seekable");
|
||||
return;
|
||||
}
|
||||
@ -194,7 +194,7 @@ audiofile_stream_decode(struct decoder *decoder, struct input_stream *is)
|
||||
|
||||
total_time = ((float)frame_count / (float)audio_format.sample_rate);
|
||||
|
||||
bit_rate = (uint16_t)(is->size * 8.0 / total_time / 1000.0 + 0.5);
|
||||
bit_rate = (uint16_t)(input_stream_get_size(is) * 8.0 / total_time / 1000.0 + 0.5);
|
||||
|
||||
fs = (int)afGetVirtualFrameSize(af_fp, AF_DEFAULT_TRACK, 1);
|
||||
|
||||
|
@ -128,12 +128,12 @@ dsdiff_read_prop_snd(struct decoder *decoder, struct input_stream *is,
|
||||
goffset end_offset)
|
||||
{
|
||||
struct dsdiff_chunk_header header;
|
||||
while ((goffset)(is->offset + sizeof(header)) <= end_offset) {
|
||||
while ((goffset)(input_stream_get_offset(is) + sizeof(header)) <= end_offset) {
|
||||
if (!dsdiff_read_chunk_header(decoder, is, &header))
|
||||
return false;
|
||||
|
||||
goffset chunk_end_offset =
|
||||
is->offset + dsdiff_chunk_size(&header);
|
||||
goffset chunk_end_offset = input_stream_get_offset(is)
|
||||
+ dsdiff_chunk_size(&header);
|
||||
if (chunk_end_offset > end_offset)
|
||||
return false;
|
||||
|
||||
@ -174,7 +174,7 @@ dsdiff_read_prop_snd(struct decoder *decoder, struct input_stream *is,
|
||||
}
|
||||
}
|
||||
|
||||
return is->offset == end_offset;
|
||||
return input_stream_get_offset(is) == end_offset;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,7 +186,7 @@ dsdiff_read_prop(struct decoder *decoder, struct input_stream *is,
|
||||
const struct dsdiff_chunk_header *prop_header)
|
||||
{
|
||||
uint64_t prop_size = dsdiff_chunk_size(prop_header);
|
||||
goffset end_offset = is->offset + prop_size;
|
||||
goffset end_offset = input_stream_get_offset(is) + prop_size;
|
||||
|
||||
struct dsdlib_id prop_id;
|
||||
if (prop_size < sizeof(prop_id) ||
|
||||
@ -261,8 +261,8 @@ dsdiff_read_metadata_extra(struct decoder *decoder, struct input_stream *is,
|
||||
/* Now process all the remaining chunk headers in the stream
|
||||
and record their position and size */
|
||||
|
||||
while ( is->offset < is->size )
|
||||
{
|
||||
const goffset size = input_stream_get_size(is);
|
||||
while (input_stream_get_offset(is) < size) {
|
||||
uint64_t chunk_size = dsdiff_chunk_size(chunk_header);
|
||||
|
||||
/* DIIN chunk, is directly followed by other chunks */
|
||||
@ -272,19 +272,19 @@ dsdiff_read_metadata_extra(struct decoder *decoder, struct input_stream *is,
|
||||
/* DIAR chunk - DSDIFF native tag for Artist */
|
||||
if (dsdlib_id_equals(&chunk_header->id, "DIAR")) {
|
||||
chunk_size = dsdiff_chunk_size(chunk_header);
|
||||
metadata->diar_offset = is->offset;
|
||||
metadata->diar_offset = input_stream_get_offset(is);
|
||||
}
|
||||
|
||||
/* DITI chunk - DSDIFF native tag for Title */
|
||||
if (dsdlib_id_equals(&chunk_header->id, "DITI")) {
|
||||
chunk_size = dsdiff_chunk_size(chunk_header);
|
||||
metadata->diti_offset = is->offset;
|
||||
metadata->diti_offset = input_stream_get_offset(is);
|
||||
}
|
||||
#ifdef HAVE_ID3TAG
|
||||
/* 'ID3 ' chunk, offspec. Used by sacdextract */
|
||||
if (dsdlib_id_equals(&chunk_header->id, "ID3 ")) {
|
||||
chunk_size = dsdiff_chunk_size(chunk_header);
|
||||
metadata->id3_offset = is->offset;
|
||||
metadata->id3_offset = input_stream_get_offset(is);
|
||||
metadata->id3_size = chunk_size;
|
||||
}
|
||||
#endif
|
||||
@ -293,7 +293,7 @@ dsdiff_read_metadata_extra(struct decoder *decoder, struct input_stream *is,
|
||||
break;
|
||||
}
|
||||
|
||||
if ( is->offset < is->size ) {
|
||||
if (input_stream_get_offset(is) < size) {
|
||||
if (!dsdiff_read_chunk_header(decoder, is, chunk_header))
|
||||
return false;
|
||||
}
|
||||
@ -355,7 +355,8 @@ dsdiff_read_metadata(struct decoder *decoder, struct input_stream *is,
|
||||
/* ignore unknown chunk */
|
||||
uint64_t chunk_size;
|
||||
chunk_size = dsdiff_chunk_size(chunk_header);
|
||||
goffset chunk_end_offset = is->offset + chunk_size;
|
||||
goffset chunk_end_offset = input_stream_get_offset(is)
|
||||
+ chunk_size;
|
||||
|
||||
if (!dsdlib_skip_to(decoder, is, chunk_end_offset))
|
||||
return false;
|
||||
|
@ -64,24 +64,24 @@ bool
|
||||
dsdlib_skip_to(struct decoder *decoder, struct input_stream *is,
|
||||
goffset offset)
|
||||
{
|
||||
if (is->seekable)
|
||||
if (input_stream_is_seekable(is))
|
||||
return input_stream_seek(is, offset, SEEK_SET, NULL);
|
||||
|
||||
if (is->offset > offset)
|
||||
if (input_stream_get_offset(is) > offset)
|
||||
return false;
|
||||
|
||||
char buffer[8192];
|
||||
while (is->offset < offset) {
|
||||
while (input_stream_get_offset(is) < offset) {
|
||||
size_t length = sizeof(buffer);
|
||||
if (offset - is->offset < (goffset)length)
|
||||
length = offset - is->offset;
|
||||
if (offset - input_stream_get_offset(is) < (goffset)length)
|
||||
length = offset - input_stream_get_offset(is);
|
||||
|
||||
size_t nbytes = decoder_read(decoder, is, buffer, length);
|
||||
if (nbytes == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(is->offset == offset);
|
||||
assert(input_stream_get_offset(is) == offset);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ dsdlib_skip(struct decoder *decoder, struct input_stream *is,
|
||||
if (delta == 0)
|
||||
return true;
|
||||
|
||||
if (is->seekable)
|
||||
if (input_stream_is_seekable(is))
|
||||
return input_stream_seek(is, delta, SEEK_CUR, NULL);
|
||||
|
||||
char buffer[8192];
|
||||
@ -139,10 +139,12 @@ dsdlib_tag_id3(struct input_stream *is,
|
||||
id3_length_t count;
|
||||
|
||||
/* Prevent broken files causing problems */
|
||||
if (is->offset >= is->size)
|
||||
const goffset size = input_stream_get_size(is);
|
||||
const goffset offset = input_stream_get_offset(is);
|
||||
if (offset >= size)
|
||||
return;
|
||||
|
||||
count = is->size - is->offset;
|
||||
count = size - offset;
|
||||
|
||||
/* Check and limit id3 tag size to prevent a stack overflow */
|
||||
if (count == 0 || count > 4096)
|
||||
|
@ -165,14 +165,15 @@ dsf_read_metadata(struct decoder *decoder, struct input_stream *is,
|
||||
|
||||
metadata->chunk_size = data_size;
|
||||
/* data_size cannot be bigger or equal to total file size */
|
||||
if (data_size >= (unsigned) is->size)
|
||||
const uint64_t size = (uint64_t)input_stream_get_size(is);
|
||||
if (data_size >= size)
|
||||
return false;
|
||||
|
||||
metadata->channels = (unsigned) dsf_fmt_chunk.channelnum;
|
||||
metadata->sample_rate = samplefreq;
|
||||
#ifdef HAVE_ID3TAG
|
||||
/* metada_offset cannot be bigger then or equal to total file size */
|
||||
if (metadata_offset >= (unsigned) is->size)
|
||||
if (metadata_offset >= size)
|
||||
metadata->id3_offset = 0;
|
||||
else
|
||||
metadata->id3_offset = (goffset) metadata_offset;
|
||||
|
@ -175,7 +175,8 @@ faad_song_duration(struct decoder_buffer *buffer, struct input_stream *is)
|
||||
size_t length;
|
||||
bool success;
|
||||
|
||||
fileread = is->size >= 0 ? is->size : 0;
|
||||
const goffset size = input_stream_get_size(is);
|
||||
fileread = size >= 0 ? size : 0;
|
||||
|
||||
decoder_buffer_fill(buffer);
|
||||
data = decoder_buffer_read(buffer, &length);
|
||||
@ -201,7 +202,7 @@ faad_song_duration(struct decoder_buffer *buffer, struct input_stream *is)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (is->seekable && length >= 2 &&
|
||||
if (input_stream_is_seekable(is) && length >= 2 &&
|
||||
data[0] == 0xFF && ((data[1] & 0xF6) == 0xF0)) {
|
||||
/* obtain the duration from the ADTS header */
|
||||
float song_length = adts_song_duration(buffer);
|
||||
|
@ -755,7 +755,7 @@ mp3_frame_duration(const struct mad_frame *frame)
|
||||
static goffset
|
||||
mp3_this_frame_offset(const struct mp3_data *data)
|
||||
{
|
||||
goffset offset = data->input_stream->offset;
|
||||
goffset offset = input_stream_get_offset(data->input_stream);
|
||||
|
||||
if (data->stream.this_frame != NULL)
|
||||
offset -= data->stream.bufend - data->stream.this_frame;
|
||||
@ -768,7 +768,8 @@ mp3_this_frame_offset(const struct mp3_data *data)
|
||||
static goffset
|
||||
mp3_rest_including_this_frame(const struct mp3_data *data)
|
||||
{
|
||||
return data->input_stream->size - mp3_this_frame_offset(data);
|
||||
return input_stream_get_size(data->input_stream)
|
||||
- mp3_this_frame_offset(data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -841,7 +842,7 @@ mp3_decode_first_frame(struct mp3_data *data, struct tag **tag)
|
||||
|
||||
if (parse_lame(&lame, &ptr, &bitlen)) {
|
||||
if (gapless_playback &&
|
||||
data->input_stream->seekable) {
|
||||
input_stream_is_seekable(data->input_stream)) {
|
||||
data->drop_start_samples = lame.encoder_delay +
|
||||
DECODERDELAY;
|
||||
data->drop_end_samples = lame.encoder_padding;
|
||||
@ -1081,7 +1082,7 @@ mp3_read(struct mp3_data *data)
|
||||
if (cmd == DECODE_COMMAND_SEEK) {
|
||||
unsigned long j;
|
||||
|
||||
assert(data->input_stream->seekable);
|
||||
assert(input_stream_is_seekable(data->input_stream));
|
||||
|
||||
j = mp3_time_to_frame(data,
|
||||
decoder_seek_where(decoder));
|
||||
@ -1163,7 +1164,8 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
|
||||
}
|
||||
|
||||
decoder_initialized(decoder, &audio_format,
|
||||
data.input_stream->seekable, data.total_time);
|
||||
input_stream_is_seekable(input_stream),
|
||||
data.total_time);
|
||||
|
||||
if (tag != NULL) {
|
||||
decoder_tag(decoder, input_stream, tag);
|
||||
|
@ -41,19 +41,21 @@ static GByteArray *mod_loadfile(struct decoder *decoder, struct input_stream *is
|
||||
GByteArray *bdatas;
|
||||
size_t ret;
|
||||
|
||||
if (is->size == 0) {
|
||||
const goffset size = input_stream_get_size(is);
|
||||
|
||||
if (size == 0) {
|
||||
g_warning("file is empty");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (is->size > MODPLUG_FILE_LIMIT) {
|
||||
if (size > MODPLUG_FILE_LIMIT) {
|
||||
g_warning("file too large");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//known/unknown size, preallocate array, lets read in chunks
|
||||
if (is->size > 0) {
|
||||
bdatas = g_byte_array_sized_new(is->size);
|
||||
if (size > 0) {
|
||||
bdatas = g_byte_array_sized_new(size);
|
||||
} else {
|
||||
bdatas = g_byte_array_sized_new(MODPLUG_PREALLOC_BLOCK);
|
||||
}
|
||||
@ -126,7 +128,8 @@ mod_decode(struct decoder *decoder, struct input_stream *is)
|
||||
assert(audio_format_valid(&audio_format));
|
||||
|
||||
decoder_initialized(decoder, &audio_format,
|
||||
is->seekable, ModPlug_GetLength(f) / 1000.0);
|
||||
input_stream_is_seekable(is),
|
||||
ModPlug_GetLength(f) / 1000.0);
|
||||
|
||||
do {
|
||||
ret = ModPlug_Read(f, audio_buffer, MODPLUG_FRAME_SIZE);
|
||||
|
@ -70,7 +70,7 @@ mpc_tell_cb(cb_first_arg)
|
||||
{
|
||||
struct mpc_decoder_data *data = (struct mpc_decoder_data *) cb_data;
|
||||
|
||||
return (long)(data->is->offset);
|
||||
return (long)input_stream_get_offset(data->is);
|
||||
}
|
||||
|
||||
static mpc_bool_t
|
||||
@ -78,7 +78,7 @@ mpc_canseek_cb(cb_first_arg)
|
||||
{
|
||||
struct mpc_decoder_data *data = (struct mpc_decoder_data *) cb_data;
|
||||
|
||||
return data->is->seekable;
|
||||
return input_stream_is_seekable(data->is);
|
||||
}
|
||||
|
||||
static mpc_int32_t
|
||||
@ -86,7 +86,7 @@ mpc_getsize_cb(cb_first_arg)
|
||||
{
|
||||
struct mpc_decoder_data *data = (struct mpc_decoder_data *) cb_data;
|
||||
|
||||
return data->is->size;
|
||||
return input_stream_get_size(data->is);
|
||||
}
|
||||
|
||||
/* this _looks_ performance-critical, don't de-inline -- eric */
|
||||
@ -222,7 +222,7 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
|
||||
decoder_replay_gain(mpd_decoder, &replay_gain_info);
|
||||
|
||||
decoder_initialized(mpd_decoder, &audio_format,
|
||||
is->seekable,
|
||||
input_stream_is_seekable(is),
|
||||
mpc_streaminfo_get_length(&info));
|
||||
|
||||
do {
|
||||
|
@ -38,8 +38,9 @@ pcm_stream_decode(struct decoder *decoder, struct input_stream *is)
|
||||
.channels = 2,
|
||||
};
|
||||
|
||||
const bool reverse_endian = is->mime != NULL &&
|
||||
strcmp(is->mime, "audio/x-mpd-cdda-pcm-reverse") == 0;
|
||||
const char *const mime = input_stream_get_mime_type(is);
|
||||
const bool reverse_endian = mime != NULL &&
|
||||
strcmp(mime, "audio/x-mpd-cdda-pcm-reverse") == 0;
|
||||
|
||||
GError *error = NULL;
|
||||
enum decoder_command cmd;
|
||||
@ -47,10 +48,12 @@ pcm_stream_decode(struct decoder *decoder, struct input_stream *is)
|
||||
double time_to_size = audio_format_time_to_size(&audio_format);
|
||||
|
||||
float total_time = -1;
|
||||
if (is->size >= 0)
|
||||
total_time = is->size / time_to_size;
|
||||
const goffset size = input_stream_get_size(is);
|
||||
if (size >= 0)
|
||||
total_time = size / time_to_size;
|
||||
|
||||
decoder_initialized(decoder, &audio_format, is->seekable, total_time);
|
||||
decoder_initialized(decoder, &audio_format,
|
||||
input_stream_is_seekable(is), total_time);
|
||||
|
||||
do {
|
||||
char buffer[4096];
|
||||
|
@ -32,7 +32,7 @@ sndfile_vio_get_filelen(void *user_data)
|
||||
{
|
||||
const struct input_stream *is = user_data;
|
||||
|
||||
return is->size;
|
||||
return input_stream_get_size(is);
|
||||
}
|
||||
|
||||
static sf_count_t
|
||||
@ -45,7 +45,7 @@ sndfile_vio_seek(sf_count_t offset, int whence, void *user_data)
|
||||
if (!success)
|
||||
return -1;
|
||||
|
||||
return is->offset;
|
||||
return input_stream_get_offset(is);
|
||||
}
|
||||
|
||||
static sf_count_t
|
||||
@ -79,7 +79,7 @@ sndfile_vio_tell(void *user_data)
|
||||
{
|
||||
const struct input_stream *is = user_data;
|
||||
|
||||
return is->offset;
|
||||
return input_stream_get_offset(is);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "config.h"
|
||||
#include "CdioParanoiaInputPlugin.hxx"
|
||||
#include "InputInternal.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
#include "refcount.h"
|
||||
|
||||
|
@ -19,12 +19,13 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "CurlInputPlugin.hxx"
|
||||
#include "InputInternal.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
#include "conf.h"
|
||||
#include "tag.h"
|
||||
#include "IcyMetaDataParser.hxx"
|
||||
#include "event/MultiSocketMonitor.hxx"
|
||||
#include "InputInternal.hxx"
|
||||
#include "event/Loop.hxx"
|
||||
#include "IOThread.hxx"
|
||||
#include "glib_compat.h"
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "DespotifyInputPlugin.hxx"
|
||||
#include "DespotifyUtils.hxx"
|
||||
#include "InputInternal.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
#include "tag.h"
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "config.h"
|
||||
#include "FfmpegInputPlugin.hxx"
|
||||
#include "InputInternal.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
|
||||
extern "C" {
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "config.h" /* must be first for large file support */
|
||||
#include "FileInputPlugin.hxx"
|
||||
#include "InputInternal.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
#include "fd_util.h"
|
||||
#include "open.h"
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "config.h"
|
||||
#include "MmsInputPlugin.hxx"
|
||||
#include "InputInternal.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "config.h"
|
||||
#include "RewindInputPlugin.hxx"
|
||||
#include "InputInternal.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
#include "tag.h"
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "config.h"
|
||||
#include "SoupInputPlugin.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "InputInternal.hxx"
|
||||
#include "IOThread.hxx"
|
||||
#include "event/Loop.hxx"
|
||||
|
@ -29,64 +29,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
struct input_stream {
|
||||
/**
|
||||
* the plugin which implements this input stream
|
||||
*/
|
||||
const struct input_plugin *plugin;
|
||||
|
||||
/**
|
||||
* The absolute URI which was used to open this stream. May
|
||||
* be NULL if this is unknown.
|
||||
*/
|
||||
char *uri;
|
||||
|
||||
/**
|
||||
* A mutex that protects the mutable attributes of this object
|
||||
* and its implementation. It must be locked before calling
|
||||
* any of the public methods.
|
||||
*
|
||||
* This object is allocated by the client, and the client is
|
||||
* responsible for freeing it.
|
||||
*/
|
||||
GMutex *mutex;
|
||||
|
||||
/**
|
||||
* A cond that gets signalled when the state of this object
|
||||
* changes from the I/O thread. The client of this object may
|
||||
* wait on it. Optional, may be NULL.
|
||||
*
|
||||
* This object is allocated by the client, and the client is
|
||||
* responsible for freeing it.
|
||||
*/
|
||||
GCond *cond;
|
||||
|
||||
/**
|
||||
* indicates whether the stream is ready for reading and
|
||||
* whether the other attributes in this struct are valid
|
||||
*/
|
||||
bool ready;
|
||||
|
||||
/**
|
||||
* if true, then the stream is fully seekable
|
||||
*/
|
||||
bool seekable;
|
||||
|
||||
/**
|
||||
* the size of the resource, or -1 if unknown
|
||||
*/
|
||||
goffset size;
|
||||
|
||||
/**
|
||||
* the current offset within the stream
|
||||
*/
|
||||
goffset offset;
|
||||
|
||||
/**
|
||||
* the MIME content type of the resource, or NULL if unknown
|
||||
*/
|
||||
char *mime;
|
||||
};
|
||||
struct input_stream;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -119,20 +62,6 @@ gcc_nonnull(1)
|
||||
void
|
||||
input_stream_close(struct input_stream *is);
|
||||
|
||||
gcc_nonnull(1)
|
||||
static inline void
|
||||
input_stream_lock(struct input_stream *is)
|
||||
{
|
||||
g_mutex_lock(is->mutex);
|
||||
}
|
||||
|
||||
gcc_nonnull(1)
|
||||
static inline void
|
||||
input_stream_unlock(struct input_stream *is)
|
||||
{
|
||||
g_mutex_unlock(is->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for errors that may have occurred in the I/O thread.
|
||||
*
|
||||
@ -167,6 +96,26 @@ gcc_nonnull(1)
|
||||
void
|
||||
input_stream_lock_wait_ready(struct input_stream *is);
|
||||
|
||||
gcc_nonnull_all gcc_pure
|
||||
const char *
|
||||
input_stream_get_mime_type(const struct input_stream *is);
|
||||
|
||||
gcc_nonnull_all
|
||||
void
|
||||
input_stream_override_mime_type(struct input_stream *is, const char *mime);
|
||||
|
||||
gcc_nonnull_all gcc_pure
|
||||
goffset
|
||||
input_stream_get_size(const struct input_stream *is);
|
||||
|
||||
gcc_nonnull_all gcc_pure
|
||||
goffset
|
||||
input_stream_get_offset(const struct input_stream *is);
|
||||
|
||||
gcc_nonnull_all gcc_pure
|
||||
bool
|
||||
input_stream_is_seekable(const struct input_stream *is);
|
||||
|
||||
/**
|
||||
* Determines whether seeking is cheap. This is true for local files.
|
||||
*/
|
||||
|
@ -242,8 +242,7 @@ lastfm_open_uri(const char *uri, GMutex *mutex, GCond *cond)
|
||||
|
||||
/* last.fm does not send a MIME type, we have to fake it here
|
||||
:-( */
|
||||
g_free(playlist->is->mime);
|
||||
playlist->is->mime = g_strdup("application/xspf+xml");
|
||||
input_stream_override_mime_type(playlist->is, "application/xspf+xml");
|
||||
|
||||
g_mutex_unlock(mutex);
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "config.h"
|
||||
#include "IOThread.hxx"
|
||||
#include "InputInit.hxx"
|
||||
#include "input_stream.h"
|
||||
#include "InputStream.hxx"
|
||||
#include "conf.h"
|
||||
#include "stdbin.h"
|
||||
|
||||
|
@ -24,7 +24,7 @@ extern "C" {
|
||||
}
|
||||
#include "decoder_api.h"
|
||||
#include "InputInit.hxx"
|
||||
#include "input_stream.h"
|
||||
#include "InputStream.hxx"
|
||||
#include "audio_format.h"
|
||||
extern "C" {
|
||||
#include "tag_ape.h"
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "tag.h"
|
||||
#include "conf.h"
|
||||
#include "input_stream.h"
|
||||
#include "InputStream.hxx"
|
||||
#include "InputInit.hxx"
|
||||
#include "IOThread.hxx"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user