summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2010-11-02 03:17:41 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2010-11-02 07:48:31 +0200
commit3cb3bbbddc1d09dab1471a3630f1a9aa4392ed50 (patch)
tree4989a29dbae266e0bb83bddca9fcdef1058c4a17
parent2be10f22b24712b959fa2883a4dcfa7caf72ab79 (diff)
downloadmpv-3cb3bbbddc1d09dab1471a3630f1a9aa4392ed50.tar.bz2
mpv-3cb3bbbddc1d09dab1471a3630f1a9aa4392ed50.tar.xz
Add a simple capture feature (-capture)
If a specified key is pressed during playback, the current stream is captured to a file, similar to what -dumpstream achieves. original patch by Pásztor Szilárd, don tricon hu Taken from the following svn commits, but with several fixes and modifications (one obvious user-visible difference is that the default key binding is 'C', not 'c'): git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32524 b3059339-0415-0410-9bf9-f77b7e298cf2 git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32529 b3059339-0415-0410-9bf9-f77b7e298cf2 git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32530 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r--DOCS/man/en/mplayer.117
-rw-r--r--DOCS/tech/slave.txt5
-rw-r--r--cfg-mplayer.h3
-rw-r--r--command.c38
-rw-r--r--input/input.c2
-rw-r--r--input/input.h1
-rw-r--r--options.h1
-rw-r--r--stream/cache2.c2
-rw-r--r--stream/stream.c17
-rw-r--r--stream/stream.h3
10 files changed, 88 insertions, 1 deletions
diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1
index 7d246a6a25..246b212532 100644
--- a/DOCS/man/en/mplayer.1
+++ b/DOCS/man/en/mplayer.1
@@ -273,6 +273,8 @@ Toggle displaying "forced subtitles".
Toggle subtitle alignment: top / middle / bottom.
.IPs "x and z"
Adjust subtitle delay by +/\- 0.1 seconds.
+.IPs "C (\-capture only)"
+Start/stop capturing the primary stream.
.IPs "r and t"
Move subtitles up/down.
.IPs "i (\-edlout mode only)"
@@ -1248,6 +1250,18 @@ from the current position, MPlayer will wait for the cache to be filled to
this position rather than performing a stream seek (default: 50).
.
.TP
+.B \-capture (MPlayer only)
+Allows capturing the primary stream (not additional audio tracks or other
+kind of streams) into the file specified by \-dumpfile or \"stream.dump\"
+by default.
+If this option is given, capturing can be started and stopped by pressing
+the key bound to this function (see section INTERACTIVE CONTROL).
+Same as for \-dumpstream, this will likely not produce usable results for
+anything else than MPEG streams.
+Note that, due to cache latencies, captured data may begin and end
+somewhat delayed compared to what you see displayed.
+.
+.TP
.B \-cdda <option1:option2> (CDDA only)
This option can be used to tune the CD Audio reading feature of MPlayer.
.sp 1
@@ -1379,7 +1393,8 @@ on the command line only the last one will work.
.TP
.B \-dumpfile <filename> (MPlayer only)
Specify which file MPlayer should dump to.
-Should be used together with \-dumpaudio / \-dumpvideo / \-dumpstream.
+Should be used together with \-dumpaudio / \-dumpvideo / \-dumpstream /
+\-capture.
.
.TP
.B \-dumpstream (MPlayer only)
diff --git a/DOCS/tech/slave.txt b/DOCS/tech/slave.txt
index 330534cefe..e923232689 100644
--- a/DOCS/tech/slave.txt
+++ b/DOCS/tech/slave.txt
@@ -76,6 +76,10 @@ audio_delay <value> [abs]
If [abs] is non-zero, parameter is set to <value>.
<value> is in the range [-100, 100].
+capturing [value]
+ Toggle/set capturing the primary stream like -dumpstream.
+ Requires the -capture parameter to be given.
+
change_rectangle <val1> <val2>
Change the position of the rectangle filter rectangle.
<val1>
@@ -538,6 +542,7 @@ channels int X
switch_audio int -2 255 X X X select audio stream
switch_angle int -2 255 X X X select DVD angle
switch_title int -2 255 X X X select DVD title
+capturing flag 0 1 X X X dump primary stream if enabled
fullscreen flag 0 1 X X X
deinterlace flag 0 1 X X X
ontop flag 0 1 X X X
diff --git a/cfg-mplayer.h b/cfg-mplayer.h
index 2c368ff54c..ba2a912ded 100644
--- a/cfg-mplayer.h
+++ b/cfg-mplayer.h
@@ -294,6 +294,9 @@ const m_option_t mplayer_opts[]={
{"dumpjacosub", &stream_dump_type, CONF_TYPE_FLAG, 0, 0, 8, NULL},
{"dumpsami", &stream_dump_type, CONF_TYPE_FLAG, 0, 0, 9, NULL},
+ OPT_FLAG_ON("capture", capture_dump, 0),
+ OPT_FLAG_OFF("nocapture", capture_dump, 0),
+
#ifdef CONFIG_LIRC
{"lircconf", &lirc_configfile, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL},
#endif
diff --git a/command.c b/command.c
index 60d04d4248..e367687c5a 100644
--- a/command.c
+++ b/command.c
@@ -1178,6 +1178,40 @@ static int mp_property_yuv_colorspace(m_option_t *prop, int action,
return M_PROPERTY_NOT_IMPLEMENTED;
}
+static int mp_property_capture(m_option_t *prop, int action,
+ void *arg, MPContext *mpctx)
+{
+ struct MPOpts *opts = &mpctx->opts;
+
+ if (!mpctx->stream)
+ return M_PROPERTY_UNAVAILABLE;
+
+ if (!opts->capture_dump) {
+ mp_tmsg(MSGT_GLOBAL, MSGL_ERR,
+ "Capturing not enabled (forgot -capture parameter?)\n");
+ return M_PROPERTY_ERROR;
+ }
+
+ int capturing = !!mpctx->stream->capture_file;
+
+ int ret = m_property_flag(prop, action, arg, &capturing);
+ if (ret == M_PROPERTY_OK && capturing != !!mpctx->stream->capture_file) {
+ if (capturing) {
+ mpctx->stream->capture_file = fopen(opts->stream_dump_name, "wb");
+ if (!mpctx->stream->capture_file) {
+ mp_tmsg(MSGT_GLOBAL, MSGL_ERR,
+ "Error opening capture file: %s\n", strerror(errno));
+ ret = M_PROPERTY_ERROR;
+ }
+ } else {
+ fclose(mpctx->stream->capture_file);
+ mpctx->stream->capture_file = NULL;
+ }
+ }
+
+ return ret;
+}
+
/// Panscan (RW)
static int mp_property_panscan(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
@@ -2158,6 +2192,8 @@ static const m_option_t mp_properties[] = {
0, 0, 0, NULL },
{ "pause", mp_property_pause, CONF_TYPE_FLAG,
M_OPT_RANGE, 0, 1, NULL },
+ { "capturing", mp_property_capture, CONF_TYPE_FLAG,
+ M_OPT_RANGE, 0, 1, NULL },
// Audio
{ "volume", mp_property_volume, CONF_TYPE_FLOAT,
@@ -2330,6 +2366,7 @@ static struct property_osd_display {
// general
{ "loop", 0, -1, _("Loop: %s") },
{ "chapter", -1, -1, NULL },
+ { "capturing", 0, -1, _("Capturing: %s") },
// audio
{ "volume", OSD_VOLUME, -1, _("Volume") },
{ "mute", 0, -1, _("Mute: %s") },
@@ -2456,6 +2493,7 @@ static struct {
{ "chapter", MP_CMD_SEEK_CHAPTER, 0},
{ "angle", MP_CMD_SWITCH_ANGLE, 0},
{ "pause", MP_CMD_PAUSE, 0},
+ { "capturing", MP_CMD_CAPTURING, 1},
// audio
{ "volume", MP_CMD_VOLUME, 0},
{ "mute", MP_CMD_MUTE, 1},
diff --git a/input/input.c b/input/input.c
index 1e2a6e888e..658e34f4dc 100644
--- a/input/input.c
+++ b/input/input.c
@@ -183,6 +183,7 @@ static const mp_cmd_t mp_cmds[] = {
{ MP_CMD_LOADFILE, "loadfile", 1, { {MP_CMD_ARG_STRING, {0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
{ MP_CMD_LOADLIST, "loadlist", 1, { {MP_CMD_ARG_STRING, {0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
{ MP_CMD_RUN, "run", 1, { {MP_CMD_ARG_STRING,{0}}, {-1,{0}} } },
+ { MP_CMD_CAPTURING, "capturing", 0, { {-1,{0}} } },
{ MP_CMD_VF_CHANGE_RECTANGLE, "change_rectangle", 2, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}}}},
{ MP_CMD_TV_TELETEXT_ADD_DEC, "teletext_add_dec", 1, { {MP_CMD_ARG_STRING,{0}}, {-1,{0}} } },
{ MP_CMD_TV_TELETEXT_GO_LINK, "teletext_go_link", 1, { {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
@@ -475,6 +476,7 @@ static const mp_cmd_bind_t def_cmd_binds[] = {
#endif
{ { 'T', 0 }, "vo_ontop" },
{ { 'f', 0 }, "vo_fullscreen" },
+ { { 'C', 0 }, "step_property_osd capturing" },
{ { 's', 0 }, "screenshot 0" },
{ { 'S', 0 }, "screenshot 1" },
{ { 'w', 0 }, "panscan -0.1" },
diff --git a/input/input.h b/input/input.h
index 51d9f6522e..d922655950 100644
--- a/input/input.h
+++ b/input/input.h
@@ -41,6 +41,7 @@ typedef enum {
MP_CMD_TV_STEP_CHANNEL,
MP_CMD_TV_STEP_NORM,
MP_CMD_TV_STEP_CHANNEL_LIST,
+ MP_CMD_CAPTURING,
MP_CMD_VO_FULLSCREEN,
MP_CMD_SUB_POS,
MP_CMD_DVDNAV,
diff --git a/options.h b/options.h
index 84f843552b..91ea2832d2 100644
--- a/options.h
+++ b/options.h
@@ -28,6 +28,7 @@ typedef struct MPOpts {
int osd_level;
int osd_duration;
char *stream_dump_name;
+ int capture_dump;
int loop_times;
int ordered_chapters;
int chapterrange[2];
diff --git a/stream/cache2.c b/stream/cache2.c
index 3aa24df64d..c4514243e1 100644
--- a/stream/cache2.c
+++ b/stream/cache2.c
@@ -508,6 +508,8 @@ int cache_stream_fill_buffer(stream_t *s){
s->buf_len=len;
s->pos+=len;
// printf("[%d]",len);fflush(stdout);
+ if (s->capture_file)
+ stream_capture_do(s);
return len;
}
diff --git a/stream/stream.c b/stream/stream.c
index 8b325a24d1..ca45f511e5 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -265,6 +265,16 @@ stream_t *open_output_stream(const char *filename, struct MPOpts *options)
//=================== STREAMER =========================
+void stream_capture_do(stream_t *s)
+{
+ 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));
+ fclose(s->capture_file);
+ s->capture_file = NULL;
+ }
+}
+
int stream_fill_buffer(stream_t *s){
int len;
// we will retry even if we already reached EOF previously.
@@ -296,6 +306,8 @@ int stream_fill_buffer(stream_t *s){
s->buf_len=len;
s->pos+=len;
// printf("[%d]",len);fflush(stdout);
+ if (s->capture_file)
+ stream_capture_do(s);
return len;
}
@@ -463,6 +475,11 @@ void free_stream(stream_t *s){
#ifdef CONFIG_STREAM_CACHE
cache_uninit(s);
#endif
+ if (s->capture_file) {
+ fclose(s->capture_file);
+ s->capture_file = NULL;
+ }
+
if(s->close) s->close(s);
if(s->fd>0){
/* on unix we define closesocket to close
diff --git a/stream/stream.h b/stream/stream.h
index bd73f6f954..8e4b260ffb 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -22,6 +22,7 @@
#include "config.h"
#include "mp_msg.h"
#include "url.h"
+#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <sys/types.h>
@@ -168,6 +169,7 @@ typedef struct stream {
streaming_ctrl_t *streaming_ctrl;
#endif
unsigned char buffer[STREAM_BUFFER_SIZE>STREAM_MAX_SECTOR_SIZE?STREAM_BUFFER_SIZE:STREAM_MAX_SECTOR_SIZE];
+ FILE *capture_file;
} stream_t;
#ifdef CONFIG_NETWORKING
@@ -176,6 +178,7 @@ typedef struct stream {
int stream_fill_buffer(stream_t *s);
int stream_seek_long(stream_t *s, off_t pos);
+void stream_capture_do(stream_t *s);
#ifdef CONFIG_STREAM_CACHE
int stream_enable_cache(stream_t *stream,int size,int min,int prefill);