summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-05-11 22:19:33 +0200
committerwm4 <wm4@nowhere>2013-05-12 21:51:57 +0200
commitfaad40aad92d51290ef2fc4d94277eca89863873 (patch)
tree48979e16495ec04765f8e684610750821b80332a
parente6e5a7b221ef2fcdd5a1982d6fdcb627100447d2 (diff)
downloadmpv-faad40aad92d51290ef2fc4d94277eca89863873.tar.bz2
mpv-faad40aad92d51290ef2fc4d94277eca89863873.tar.xz
core: add --stream-capture
This is a partial revert of commit 7059c15, and basically re-adds --capture, just with different option names and slightly different semantics.
-rw-r--r--DOCS/man/en/input.rst1
-rw-r--r--DOCS/man/en/options.rst9
-rw-r--r--core/cfg-mplayer.h2
-rw-r--r--core/command.c15
-rw-r--r--core/mplayer.c2
-rw-r--r--core/options.h1
-rw-r--r--stream/cache2.c1
-rw-r--r--stream/stream.c34
-rw-r--r--stream/stream.h6
9 files changed, 71 insertions, 0 deletions
diff --git a/DOCS/man/en/input.rst b/DOCS/man/en/input.rst
index 638172289c..5ae78ca06d 100644
--- a/DOCS/man/en/input.rst
+++ b/DOCS/man/en/input.rst
@@ -341,6 +341,7 @@ sub-scale x subtitle font size multiplicator
ass-use-margins x see ``--ass-use-margins``
ass-vsfilter-aspect-compat x see ``--ass-vsfilter-aspect-compat``
ass-style-override x see ``--ass-style-override``
+stream-capture x a filename, see ``--capture``
tv-brightness x
tv-contrast x
tv-saturation x
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst
index cd1b4ab90a..2f3e5bf38d 100644
--- a/DOCS/man/en/options.rst
+++ b/DOCS/man/en/options.rst
@@ -1528,6 +1528,15 @@
Print out a custom string during playback instead of the standard status
line. Expands properties. See ``--playing-msg``.
+--stream-capture=<filename>
+ Allows capturing the primary stream (not additional audio tracks or other
+ kind of streams) into the given file. Capturing can also be started and
+ stopped changing the filename with the ``stream-capture`` slave property.
+ Generally this will not produce usable results for anything else than MPEG
+ or raw streams, unless capturing includes the file headers and is not
+ interrupted. Note that, due to cache latencies, captured data may begin and
+ end somewhat delayed compared to what you see displayed.
+
--playlist=<filename>
Play files according to a playlist file (ASX, Winamp, SMIL, or
one-file-per-line format).
diff --git a/core/cfg-mplayer.h b/core/cfg-mplayer.h
index baf0820f48..9feb82f9cd 100644
--- a/core/cfg-mplayer.h
+++ b/core/cfg-mplayer.h
@@ -634,6 +634,8 @@ const m_option_t mplayer_opts[]={
OPT_FLAG("untimed", untimed, 0),
+ OPT_STRING("stream-capture", stream_capture, 0),
+
#ifdef CONFIG_LIRC
{"lircconf", &lirc_configfile, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL},
#endif
diff --git a/core/command.c b/core/command.c
index d8a8882c26..e9d3d0d679 100644
--- a/core/command.c
+++ b/core/command.c
@@ -197,6 +197,20 @@ static int mp_property_stream_path(m_option_t *prop, int action, void *arg,
return m_property_strdup_ro(prop, action, arg, stream->url);
}
+static int mp_property_stream_capture(m_option_t *prop, int action,
+ void *arg, MPContext *mpctx)
+{
+ if (!mpctx->stream)
+ return M_PROPERTY_UNAVAILABLE;
+
+ if (action == M_PROPERTY_SET) {
+ char *filename = *(char **)arg;
+ stream_set_capture_file(mpctx->stream, filename);
+ // fall through to mp_property_generic_option
+ }
+ return mp_property_generic_option(prop, action, arg, mpctx);
+}
+
/// Demuxer name (RO)
static int mp_property_demuxer(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
@@ -1357,6 +1371,7 @@ static const m_option_t mp_properties[] = {
0, 0, 0, NULL },
{ "stream-path", mp_property_stream_path, CONF_TYPE_STRING,
0, 0, 0, NULL },
+ M_OPTION_PROPERTY_CUSTOM("stream-capture", mp_property_stream_capture),
{ "demuxer", mp_property_demuxer, CONF_TYPE_STRING,
0, 0, 0, NULL },
{ "stream-pos", mp_property_stream_pos, CONF_TYPE_INT64,
diff --git a/core/mplayer.c b/core/mplayer.c
index 361d3d5466..ed8de9eb36 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -4233,6 +4233,8 @@ goto_enable_cache: ;
if (demux_was_interrupted(mpctx))
goto terminate_playback;
+ stream_set_capture_file(mpctx->stream, opts->stream_capture);
+
//============ Open DEMUXERS --- DETECT file type =======================
mpctx->audio_delay = opts->audio_delay;
diff --git a/core/options.h b/core/options.h
index 11286bf883..09cf20c852 100644
--- a/core/options.h
+++ b/core/options.h
@@ -85,6 +85,7 @@ typedef struct MPOpts {
int osd_fractions;
char *vobsub_name;
int untimed;
+ char *stream_capture;
int loop_times;
int ordered_chapters;
int chapter_merge_threshold;
diff --git a/stream/cache2.c b/stream/cache2.c
index 38c57d0af9..1337e44e37 100644
--- a/stream/cache2.c
+++ b/stream/cache2.c
@@ -593,6 +593,7 @@ int cache_stream_fill_buffer(stream_t *s){
s->buf_len=len;
s->pos+=len;
// printf("[%d]",len);fflush(stdout);
+ stream_capture_write(s);
return len;
}
diff --git a/stream/stream.c b/stream/stream.c
index 36594d8556..caf78851c3 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -41,6 +41,7 @@
#include <winsock2.h>
#endif
+#include "core/bstr.h"
#include "core/mp_msg.h"
#include "osdep/shmem.h"
#include "osdep/timer.h"
@@ -312,6 +313,37 @@ static int stream_reconnect(stream_t *s)
return 0;
}
+void stream_set_capture_file(stream_t *s, const char *filename)
+{
+ if (!bstr_equals(bstr0(s->capture_filename), bstr0(filename))) {
+ if (s->capture_file)
+ fclose(s->capture_file);
+ talloc_free(s->capture_filename);
+ s->capture_file = NULL;
+ s->capture_filename = NULL;
+ if (filename) {
+ s->capture_file = fopen(filename, "wb");
+ if (s->capture_file) {
+ s->capture_filename = talloc_strdup(NULL, filename);
+ } else {
+ mp_tmsg(MSGT_GLOBAL, MSGL_ERR,
+ "Error opening capture file: %s\n", strerror(errno));
+ }
+ }
+ }
+}
+
+void stream_capture_write(stream_t *s)
+{
+ if (s->capture_file) {
+ if (fwrite(s->buffer, s->buf_len, 1, s->capture_file) < 1) {
+ mp_tmsg(MSGT_GLOBAL, MSGL_ERR, "Error writing capture file: %s\n",
+ strerror(errno));
+ stream_set_capture_file(s, NULL);
+ }
+ }
+}
+
int stream_read_internal(stream_t *s, void *buf, int len)
{
int orig_len = len;
@@ -367,6 +399,7 @@ int stream_fill_buffer(stream_t *s)
s->buf_pos = 0;
s->buf_len = len;
// printf("[%d]",len);fflush(stdout);
+ stream_capture_write(s);
return len;
}
@@ -566,6 +599,7 @@ void free_stream(stream_t *s)
#ifdef CONFIG_STREAM_CACHE
cache_uninit(s);
#endif
+ stream_set_capture_file(s, NULL);
if (s->close)
s->close(s);
diff --git a/stream/stream.h b/stream/stream.h
index df4188ed94..ad2d7dd19a 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -188,6 +188,9 @@ typedef struct stream {
unsigned char buffer[STREAM_BUFFER_SIZE >
STREAM_MAX_SECTOR_SIZE ? STREAM_BUFFER_SIZE :
STREAM_MAX_SECTOR_SIZE];
+
+ FILE *capture_file;
+ char *capture_filename;
} stream_t;
#ifdef CONFIG_NETWORKING
@@ -197,6 +200,9 @@ typedef struct stream {
int stream_fill_buffer(stream_t *s);
int stream_seek_long(stream_t *s, int64_t pos);
+void stream_set_capture_file(stream_t *s, const char *filename);
+void stream_capture_write(stream_t *s);
+
#ifdef CONFIG_STREAM_CACHE
int stream_enable_cache_percent(stream_t *stream, int64_t stream_cache_size,
float stream_cache_min_percent,