2016-12-26 13:30:29 -05:00
|
|
|
|
|
|
|
#ifndef __INPUT_H__
|
|
|
|
#define __INPUT_H__
|
|
|
|
|
2016-12-28 18:39:23 -05:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
2016-12-26 13:30:29 -05:00
|
|
|
#include <event2/buffer.h>
|
2019-02-16 13:34:36 -05:00
|
|
|
#include "db.h"
|
2019-02-08 13:03:09 -05:00
|
|
|
#include "misc.h"
|
2016-12-26 13:30:29 -05:00
|
|
|
|
|
|
|
// Must be in sync with inputs[] in input.c
|
|
|
|
enum input_types
|
|
|
|
{
|
|
|
|
INPUT_TYPE_FILE,
|
|
|
|
INPUT_TYPE_HTTP,
|
2017-01-14 17:35:19 -05:00
|
|
|
INPUT_TYPE_PIPE,
|
2016-12-28 18:39:23 -05:00
|
|
|
#ifdef HAVE_SPOTIFY_H
|
|
|
|
INPUT_TYPE_SPOTIFY,
|
|
|
|
#endif
|
2016-12-26 13:30:29 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
enum input_flags
|
|
|
|
{
|
2019-02-16 13:34:36 -05:00
|
|
|
// Flags that input is closing current source
|
|
|
|
INPUT_FLAG_START_NEXT = (1 << 0),
|
2016-12-26 13:30:29 -05:00
|
|
|
// Flags end of file
|
2019-02-16 13:34:36 -05:00
|
|
|
INPUT_FLAG_EOF = (1 << 1),
|
2017-03-11 13:23:49 -05:00
|
|
|
// Flags error reading file
|
2019-02-16 13:34:36 -05:00
|
|
|
INPUT_FLAG_ERROR = (1 << 2),
|
2016-12-26 13:30:29 -05:00
|
|
|
// Flags possible new stream metadata
|
2019-02-16 13:34:36 -05:00
|
|
|
INPUT_FLAG_METADATA = (1 << 3),
|
2019-01-13 18:17:02 -05:00
|
|
|
// Flags new stream quality
|
2019-02-16 13:34:36 -05:00
|
|
|
INPUT_FLAG_QUALITY = (1 << 4),
|
2016-12-26 13:30:29 -05:00
|
|
|
};
|
|
|
|
|
2019-02-16 13:34:36 -05:00
|
|
|
struct input_source
|
2016-12-26 13:30:29 -05:00
|
|
|
{
|
2019-02-16 13:34:36 -05:00
|
|
|
// Type of input
|
|
|
|
enum input_types type;
|
2016-12-26 13:30:29 -05:00
|
|
|
|
2019-02-16 13:34:36 -05:00
|
|
|
// Item-Id of the file/item in the queue
|
2016-12-26 13:30:29 -05:00
|
|
|
uint32_t item_id;
|
|
|
|
|
2019-02-16 13:34:36 -05:00
|
|
|
// Id of the file/item in the files database
|
|
|
|
uint32_t id;
|
|
|
|
|
|
|
|
// Length of the file/item in milliseconds
|
2016-12-26 13:30:29 -05:00
|
|
|
uint32_t len_ms;
|
|
|
|
|
|
|
|
enum data_kind data_kind;
|
|
|
|
enum media_kind media_kind;
|
|
|
|
char *path;
|
|
|
|
|
2019-02-16 13:34:36 -05:00
|
|
|
// Flags that the input has been opened (i.e. needs to be closed)
|
|
|
|
bool open;
|
2016-12-26 13:30:29 -05:00
|
|
|
|
2019-02-16 13:34:36 -05:00
|
|
|
// The below is private data for the input backend. It is optional for the
|
|
|
|
// backend to use, so nothing in the input or player should depend on it!
|
|
|
|
//
|
|
|
|
// Opaque pointer to data that the input backend sets up when start() is
|
|
|
|
// called, and that is cleaned up by the backend when stop() is called
|
|
|
|
void *input_ctx;
|
|
|
|
// Private evbuf. Alloc'ed by backend at start() and free'd at stop()
|
|
|
|
struct evbuffer *evbuf;
|
|
|
|
// Private source quality storage
|
|
|
|
struct media_quality quality;
|
2016-12-26 13:30:29 -05:00
|
|
|
};
|
|
|
|
|
2017-01-15 17:25:00 -05:00
|
|
|
typedef int (*input_cb)(void);
|
|
|
|
|
2017-01-22 17:16:15 -05:00
|
|
|
struct input_metadata
|
|
|
|
{
|
2019-03-18 17:57:18 -04:00
|
|
|
// queue_item id
|
2017-01-22 17:16:15 -05:00
|
|
|
uint32_t item_id;
|
|
|
|
|
2019-03-18 17:57:18 -04:00
|
|
|
// Input can override the default player progress by setting this
|
|
|
|
// FIXME only implemented for Airplay speakers currently
|
|
|
|
uint32_t pos_ms;
|
2017-01-22 17:16:15 -05:00
|
|
|
|
2019-03-18 17:57:18 -04:00
|
|
|
// Sets new song length (input will also update queue_item)
|
|
|
|
uint32_t len_ms;
|
2017-01-27 05:05:24 -05:00
|
|
|
|
2019-03-18 17:57:18 -04:00
|
|
|
// Input can update queue_item with the below
|
2017-01-22 17:16:15 -05:00
|
|
|
char *artist;
|
|
|
|
char *title;
|
|
|
|
char *album;
|
2017-01-27 05:05:24 -05:00
|
|
|
char *genre;
|
2017-01-22 17:16:15 -05:00
|
|
|
char *artwork_url;
|
2019-03-18 17:57:18 -04:00
|
|
|
|
|
|
|
// Indicates whether we are starting playback. Just passed on to output.
|
|
|
|
int startup;
|
2017-01-22 17:16:15 -05:00
|
|
|
};
|
|
|
|
|
2016-12-26 13:30:29 -05:00
|
|
|
struct input_definition
|
|
|
|
{
|
|
|
|
// Name of the input
|
|
|
|
const char *name;
|
|
|
|
|
|
|
|
// Type of input
|
|
|
|
enum input_types type;
|
|
|
|
|
|
|
|
// Set to 1 if the input initialization failed
|
|
|
|
char disabled;
|
|
|
|
|
|
|
|
// Prepare a playback session
|
2019-02-16 13:34:36 -05:00
|
|
|
int (*setup)(struct input_source *source);
|
2016-12-26 13:30:29 -05:00
|
|
|
|
2019-02-16 13:34:36 -05:00
|
|
|
// One iteration of the playback loop (= a read operation from source)
|
|
|
|
int (*play)(struct input_source *source);
|
2016-12-26 13:30:29 -05:00
|
|
|
|
2019-02-16 13:34:36 -05:00
|
|
|
// Cleans up (only required when stopping source before it ends itself)
|
|
|
|
int (*stop)(struct input_source *source);
|
2016-12-26 13:30:29 -05:00
|
|
|
|
|
|
|
// Changes the playback position
|
2019-02-16 13:34:36 -05:00
|
|
|
int (*seek)(struct input_source *source, int seek_ms);
|
2016-12-26 13:30:29 -05:00
|
|
|
|
2017-01-22 17:16:15 -05:00
|
|
|
// Return metadata
|
2019-02-16 13:34:36 -05:00
|
|
|
int (*metadata_get)(struct input_metadata *metadata, struct input_source *source);
|
2017-01-22 17:16:15 -05:00
|
|
|
|
2016-12-26 13:30:29 -05:00
|
|
|
// Initialization function called during startup
|
|
|
|
int (*init)(void);
|
|
|
|
|
|
|
|
// Deinitialization function called at shutdown
|
|
|
|
void (*deinit)(void);
|
|
|
|
};
|
|
|
|
|
2019-02-16 13:34:36 -05:00
|
|
|
|
|
|
|
/* ---------------------- Interface towards input backends ------------------ */
|
|
|
|
/* Thread: input and spotify */
|
2016-12-26 13:30:29 -05:00
|
|
|
|
|
|
|
/*
|
2019-01-11 13:34:36 -05:00
|
|
|
* Transfer stream data to the player's input buffer. Data must be PCM-LE
|
|
|
|
* samples. The input evbuf will be drained on succesful write. This is to avoid
|
2019-02-16 13:34:36 -05:00
|
|
|
* copying memory.
|
2016-12-26 13:30:29 -05:00
|
|
|
*
|
2019-01-11 13:34:36 -05:00
|
|
|
* @in evbuf Raw PCM_LE audio data to write
|
2019-01-13 18:17:02 -05:00
|
|
|
* @in evbuf Quality of the PCM (sample rate etc.)
|
2016-12-26 13:30:29 -05:00
|
|
|
* @in flags One or more INPUT_FLAG_*
|
2019-02-16 13:34:36 -05:00
|
|
|
* @return 0 on success, EAGAIN if buffer was full, -1 on error
|
2016-12-26 13:30:29 -05:00
|
|
|
*/
|
|
|
|
int
|
2019-02-08 13:03:09 -05:00
|
|
|
input_write(struct evbuffer *evbuf, struct media_quality *quality, short flags);
|
2016-12-26 13:30:29 -05:00
|
|
|
|
2016-12-28 18:39:23 -05:00
|
|
|
/*
|
2019-02-16 13:34:36 -05:00
|
|
|
* Input modules can use this to wait for the input_buffer to be ready for
|
|
|
|
* writing. The wait is max INPUT_LOOP_TIMEOUT, which allows the event base to
|
|
|
|
* loop and process pending commands once in a while.
|
2016-12-28 18:39:23 -05:00
|
|
|
*/
|
2019-02-16 13:34:36 -05:00
|
|
|
int
|
2016-12-28 18:39:23 -05:00
|
|
|
input_wait(void);
|
|
|
|
|
2019-02-16 13:34:36 -05:00
|
|
|
/*
|
|
|
|
* Async switch to the next song in the queue. Mostly for internal use, but
|
|
|
|
* might be relevant some day externally?
|
|
|
|
*/
|
|
|
|
//void
|
|
|
|
//input_next(void);
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------------------- Interface towards player thread ------------------- */
|
|
|
|
/* Thread: player */
|
|
|
|
|
2016-12-26 13:30:29 -05:00
|
|
|
/*
|
|
|
|
* Move a chunk of stream data from the player's input buffer to an output
|
|
|
|
* buffer. Should only be called by the player thread. Will not block.
|
|
|
|
*
|
2017-01-13 18:43:03 -05:00
|
|
|
* @in data Output buffer
|
|
|
|
* @in size How much data to move to the output buffer
|
2019-03-18 17:57:18 -04:00
|
|
|
* @out flag Flag INPUT_FLAG_*
|
|
|
|
* @out flagdata Data associated with the flag, e.g. quality or metadata struct
|
2017-01-13 18:43:03 -05:00
|
|
|
* @return Number of bytes moved, -1 on error
|
2016-12-26 13:30:29 -05:00
|
|
|
*/
|
|
|
|
int
|
2019-03-18 17:57:18 -04:00
|
|
|
input_read(void *data, size_t size, short *flag, void **flagdata);
|
2016-12-26 13:30:29 -05:00
|
|
|
|
2017-01-15 17:25:00 -05:00
|
|
|
/*
|
|
|
|
* Player can set this to get a callback from the input when the input buffer
|
|
|
|
* is full. The player may use this to resume playback after an underrun.
|
|
|
|
*
|
|
|
|
* @in cb The callback
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
input_buffer_full_cb(input_cb cb);
|
|
|
|
|
2016-12-26 13:30:29 -05:00
|
|
|
/*
|
2019-02-16 13:34:36 -05:00
|
|
|
* Tells the input to start, i.e. after calling this function the input buffer
|
|
|
|
* will begin to fill up, and should be read periodically with input_read(). If
|
|
|
|
* called while another item is still open, it will be closed and the input
|
|
|
|
* buffer will be flushed. This operation blocks.
|
|
|
|
*
|
|
|
|
* @in item_id Queue item id to start playing
|
|
|
|
* @in seek_ms Position to start playing
|
|
|
|
* @return Actual seek position if seekable, 0 otherwise, -1 on error
|
2016-12-26 13:30:29 -05:00
|
|
|
*/
|
|
|
|
int
|
2019-02-16 13:34:36 -05:00
|
|
|
input_seek(uint32_t item_id, int seek_ms);
|
2016-12-26 13:30:29 -05:00
|
|
|
|
|
|
|
/*
|
2019-02-16 13:34:36 -05:00
|
|
|
* Same as input_seek(), just non-blocking and does not offer seek.
|
|
|
|
*
|
|
|
|
* @in item_id Queue item id to start playing
|
2016-12-26 13:30:29 -05:00
|
|
|
*/
|
2019-02-16 13:34:36 -05:00
|
|
|
void
|
|
|
|
input_start(uint32_t item_id);
|
2016-12-26 13:30:29 -05:00
|
|
|
|
|
|
|
/*
|
2019-02-16 13:34:36 -05:00
|
|
|
* Stops the input and clears everything. Flushes the input buffer.
|
2016-12-26 13:30:29 -05:00
|
|
|
*/
|
2019-02-16 13:34:36 -05:00
|
|
|
void
|
|
|
|
input_stop(void);
|
2016-12-26 13:30:29 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Flush input buffer. Output flags will be the same as input_read().
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
input_flush(short *flags);
|
|
|
|
|
2017-01-22 17:16:15 -05:00
|
|
|
/*
|
|
|
|
* Free the entire struct
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
input_metadata_free(struct input_metadata *metadata, int content_only);
|
|
|
|
|
2017-01-13 18:43:03 -05:00
|
|
|
/*
|
|
|
|
* Called by player_init (so will run in main thread)
|
|
|
|
*/
|
2016-12-26 13:30:29 -05:00
|
|
|
int
|
|
|
|
input_init(void);
|
|
|
|
|
2017-01-13 18:43:03 -05:00
|
|
|
/*
|
|
|
|
* Called by player_deinit (so will run in main thread)
|
|
|
|
*/
|
2016-12-26 13:30:29 -05:00
|
|
|
void
|
|
|
|
input_deinit(void);
|
|
|
|
|
|
|
|
#endif /* !__INPUT_H__ */
|