summaryrefslogtreecommitdiffstats
path: root/demux/demux.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-09-01 16:06:41 +0200
committerAnton Kindestam <antonki@kth.se>2018-12-06 10:31:10 +0100
commit9d8afcf79e3a4b563800dcf7fc08779355e9d602 (patch)
tree4e7e6e74d02f2b692194b79569d895d3ccbf7652 /demux/demux.c
parent02756c3735f8e7e8ac6b5ca1168b68a6a325122d (diff)
downloadmpv-9d8afcf79e3a4b563800dcf7fc08779355e9d602.tar.bz2
mpv-9d8afcf79e3a4b563800dcf7fc08779355e9d602.tar.xz
demux: add another stream recording feature
--record-file is nice, but only sometimes. If you watch some sort of livestream which you want to record, it's actually much nicer not to record what you're currently "seeing", but anything you're receiving.
Diffstat (limited to 'demux/demux.c')
-rw-r--r--demux/demux.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/demux/demux.c b/demux/demux.c
index b3b18257cf..e9565166ab 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -35,6 +35,7 @@
#include "mpv_talloc.h"
#include "common/msg.h"
#include "common/global.h"
+#include "common/recorder.h"
#include "misc/thread_tools.h"
#include "osdep/atomic.h"
#include "osdep/timer.h"
@@ -97,6 +98,7 @@ struct demux_opts {
int access_references;
int seekable_cache;
int create_ccs;
+ char *record_file;
};
#define OPT_BASE_STRUCT struct demux_opts
@@ -118,6 +120,7 @@ const struct m_sub_options demux_conf = {
OPT_CHOICE("demuxer-seekable-cache", seekable_cache, 0,
({"auto", -1}, {"no", 0}, {"yes", 1})),
OPT_FLAG("sub-create-cc-track", create_ccs, 0),
+ OPT_STRING("stream-record", record_file, 0),
{0}
},
.size = sizeof(struct demux_opts),
@@ -229,6 +232,10 @@ struct demux_internal {
int64_t next_cache_update;
// Updated during init only.
char *stream_base_filename;
+
+ // -- Access from demuxer thread only
+ bool enable_recording;
+ struct mp_recorder *recorder;
};
// A continuous range of cached packets for all enabled streams.
@@ -963,6 +970,11 @@ static void demux_shutdown(struct demux_internal *in)
{
struct demuxer *demuxer = in->d_user;
+ if (in->recorder) {
+ mp_recorder_destroy(in->recorder);
+ in->recorder = NULL;
+ }
+
if (demuxer->desc->close)
demuxer->desc->close(in->d_thread);
demuxer->priv = NULL;
@@ -1509,6 +1521,33 @@ void demux_add_packet(struct sh_stream *stream, demux_packet_t *dp)
}
}
+ // (should preferable be outside of the lock)
+ if (in->enable_recording && !in->recorder &&
+ in->opts->record_file && in->opts->record_file[0])
+ {
+ // Later failures shouldn't make it retry and overwrite the previously
+ // recorded file.
+ in->enable_recording = false;
+
+ in->recorder =
+ mp_recorder_create(in->d_thread->global, in->opts->record_file,
+ in->streams, in->num_streams);
+ if (!in->recorder)
+ MP_ERR(in, "Disabling recording.\n");
+ }
+
+ if (in->recorder) {
+ struct mp_recorder_sink *sink =
+ mp_recorder_get_sink(in->recorder, dp->stream);
+ if (sink) {
+ mp_recorder_feed_packet(sink, dp);
+ } else {
+ MP_ERR(in, "New stream appeared; stopping recording.\n");
+ mp_recorder_destroy(in->recorder);
+ in->recorder = NULL;
+ }
+ }
+
wakeup_ds(ds);
pthread_mutex_unlock(&in->lock);
}
@@ -2338,6 +2377,7 @@ static struct demuxer *open_given_type(struct mpv_global *global,
.highest_av_pts = MP_NOPTS_VALUE,
.seeking_in_progress = MP_NOPTS_VALUE,
.demux_ts = MP_NOPTS_VALUE,
+ .enable_recording = params && params->stream_record,
};
pthread_mutex_init(&in->lock, NULL);
pthread_cond_init(&in->wakeup, NULL);