summaryrefslogtreecommitdiffstats
path: root/demux/demux.h
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-07-16 22:40:21 +0200
committerwm4 <wm4@nowhere>2014-07-16 23:25:56 +0200
commit1301a907617459237fb0071b4640ad53d0ae491f (patch)
treea3eb637ac01f1f11c53922ac9589e2e826869f2c /demux/demux.h
parent69a8f08f3e7cc0a9121c7fdb3499081fb2e34ddf (diff)
downloadmpv-1301a907617459237fb0071b4640ad53d0ae491f.tar.bz2
mpv-1301a907617459237fb0071b4640ad53d0ae491f.tar.xz
demux: add a demuxer thread
This adds a thread to the demuxer which reads packets asynchronously. It will do so until a configurable minimum packet queue size is reached. (See options.rst additions.) For now, the thread is disabled by default. There are some corner cases that have to be fixed, such as fixing cache behavior with webradios. Note that most interaction with the demuxer is still blocking, so if e.g. network dies, the player will still freeze. But this change will make it possible to remove most causes for freezing. Most of the new code in demux.c actually consists of weird caches to compensate for thread-safety issues (with the previously single-threaded design), or to avoid blocking by having to wait on the demuxer thread. Most of the changes in the player are due to the fact that we must not access the source stream directly. the demuxer thread already accesses it, and the stream stuff is not thread-safe. For timeline stuff (like ordered chapters), we enable the thread for the current segment only. We also clear its packet queue on seek, so that the remaining (unconsumed) readahead buffer doesn't waste memory. Keep in mind that insane subtitles (such as ASS typesetting muxed into mkv files) will practically disable the readahead, because the total queue size is considered when checking whether the minimum queue size was reached.
Diffstat (limited to 'demux/demux.h')
-rw-r--r--demux/demux.h49
1 files changed, 36 insertions, 13 deletions
diff --git a/demux/demux.h b/demux/demux.h
index 58da35c796..4ec259d6dc 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -31,10 +31,15 @@
#include "packet.h"
#include "stheader.h"
-struct MPOpts;
-
-#define MAX_PACKS 4096
-#define MAX_PACK_BYTES 0x8000000 // 128 MiB
+// Maximum total size of packets queued - if larger, no new packets are read,
+// and the demuxer pretends EOF was reached.
+#define MAX_PACKS 16000
+#define MAX_PACK_BYTES (400 * 1024 * 1024)
+// Minimum total size of packets queued - the demuxer thread will read more
+// packets, until either number or total size of the packets exceed the minimum.
+// This can actually be configured with command line options.
+#define MIN_PACKS 64
+#define MIN_PACK_BYTES (5 * 1024 * 1024)
enum demuxer_type {
DEMUXER_TYPE_GENERIC = 0,
@@ -48,14 +53,14 @@ enum demuxer_type {
#define DEMUXER_CTRL_NOTIMPL -1
#define DEMUXER_CTRL_DONTKNOW 0
#define DEMUXER_CTRL_OK 1
-#define DEMUXER_CTRL_GUESS 2
enum demux_ctrl {
DEMUXER_CTRL_SWITCHED_TRACKS = 1,
DEMUXER_CTRL_GET_TIME_LENGTH,
DEMUXER_CTRL_RESYNC,
DEMUXER_CTRL_IDENTIFY_PROGRAM,
- DEMUXER_CTRL_STREAM_CTRL, // stupid workaround for legacy TV code
+ DEMUXER_CTRL_STREAM_CTRL,
+ DEMUXER_CTRL_STREAM_AUTOSELECT,
};
struct demux_ctrl_stream_ctrl {
@@ -87,7 +92,10 @@ enum demux_check {
};
enum demux_event {
- DEMUX_EVENT_METADATA = (1 << 0),
+ DEMUX_EVENT_INIT = 1 << 0, // complete (re-)initialization
+ DEMUX_EVENT_STREAMS = 1 << 1, // a stream was added
+ DEMUX_EVENT_METADATA = 1 << 2, // metadata or stream_metadata changed
+ DEMUX_EVENT_ALL = 0xFFFF,
};
#define MAX_SH_STREAMS 256
@@ -172,15 +180,12 @@ typedef struct demuxer {
const demuxer_desc_t *desc; ///< Demuxer description structure
const char *filetype; // format name when not identified by demuxer (libavformat)
int64_t filepos; // input stream current pos.
- struct stream *stream;
char *filename; // same as stream->url
enum demuxer_type type;
int seekable; // flag
double start_time;
// File format allows PTS resets (even if the current file is without)
bool ts_resets_possible;
- bool warned_queue_overflow;
- bool stream_select_default; // initial selection status of a new stream
// Bitmask of DEMUX_EVENT_*
int events;
@@ -207,13 +212,19 @@ typedef struct demuxer {
struct mp_tags *metadata;
- struct mp_tags *stream_metadata;
-
void *priv; // demuxer-specific internal data
struct MPOpts *opts;
struct mpv_global *global;
struct mp_log *log, *glog;
struct demuxer_params *params;
+
+ struct demux_internal *in; // internal to demux.c
+
+ // Since the demuxer can run in its own thread, and the stream is not
+ // thread-safe, only the demuxer is allowed to access the stream directly.
+ // You can freely use demux_stream_control() to send STREAM_CTRLs, or use
+ // demux_pause() to get exclusive access to the stream.
+ struct stream *stream;
} demuxer_t;
typedef struct {
@@ -238,11 +249,14 @@ struct demuxer *demux_open(struct stream *stream, char *force_format,
struct demuxer_params *params,
struct mpv_global *global);
+void demux_start_thread(struct demuxer *demuxer);
+void demux_stop_thread(struct demuxer *demuxer);
+void demux_set_wakeup_cb(struct demuxer *demuxer, void (*cb)(void *ctx), void *ctx);
+
void demux_flush(struct demuxer *demuxer);
int demux_seek(struct demuxer *demuxer, float rel_seek_secs, int flags);
char *demux_info_get(struct demuxer *demuxer, const char *opt);
-bool demux_info_update(struct demuxer *demuxer);
int demux_control(struct demuxer *demuxer, int cmd, void *arg);
@@ -250,6 +264,7 @@ void demuxer_switch_track(struct demuxer *demuxer, enum stream_type type,
struct sh_stream *stream);
void demuxer_select_track(struct demuxer *demuxer, struct sh_stream *stream,
bool selected);
+void demux_set_stream_autoselect(struct demuxer *demuxer, bool autoselect);
void demuxer_help(struct mp_log *log);
@@ -260,6 +275,14 @@ int demuxer_add_chapter(struct demuxer *demuxer, struct bstr name,
double demuxer_get_time_length(struct demuxer *demuxer);
+int demux_stream_control(demuxer_t *demuxer, int ctrl, void *arg);
+
+void demux_pause(demuxer_t *demuxer);
+void demux_unpause(demuxer_t *demuxer);
+
+void demux_changed(demuxer_t *demuxer, int events);
+void demux_update(demuxer_t *demuxer);
+
struct sh_stream *demuxer_stream_by_demuxer_id(struct demuxer *d,
enum stream_type t, int id);