Mercurial > mplayer.hg
changeset 32438:faefba58f413
Implement a basic capture feature, available through -capture.
If a specified key is pressed during playback, the current stream is
captured to a file, similar to what -dumpstream achieves.
patch by PŹ«ˇsztor SzilŹ«ˇrd, don tricon hu
author | diego |
---|---|
date | Thu, 21 Oct 2010 18:19:30 +0000 |
parents | 8d6bd95d0009 |
children | 2f1ccd169a7f |
files | DOCS/man/en/mplayer.1 DOCS/tech/slave.txt cfg-mplayer.h command.c help/help_mp-en.h help/help_mp-hu.h help/help_mp-it.h input/input.c input/input.h mplayer.c mplayer.h stream/cache2.c stream/stream.c stream/stream.h |
diffstat | 14 files changed, 106 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/DOCS/man/en/mplayer.1 Thu Oct 21 17:35:56 2010 +0000 +++ b/DOCS/man/en/mplayer.1 Thu Oct 21 18:19:30 2010 +0000 @@ -281,6 +281,8 @@ 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)" @@ -1340,6 +1342,18 @@ 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 @@ -1465,7 +1479,8 @@ .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)
--- a/DOCS/tech/slave.txt Thu Oct 21 17:35:56 2010 +0000 +++ b/DOCS/tech/slave.txt Thu Oct 21 18:19:30 2010 +0000 @@ -76,6 +76,10 @@ 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> @@ -537,6 +541,7 @@ 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
--- a/cfg-mplayer.h Thu Oct 21 17:35:56 2010 +0000 +++ b/cfg-mplayer.h Thu Oct 21 18:19:30 2010 +0000 @@ -292,6 +292,8 @@ {"dumpjacosub", &stream_dump_type, CONF_TYPE_FLAG, 0, 0, 8, NULL}, {"dumpsami", &stream_dump_type, CONF_TYPE_FLAG, 0, 0, 9, NULL}, + {"capture", &capture_dump, CONF_TYPE_FLAG, 0, 0, 1, NULL}, + #ifdef CONFIG_LIRC {"lircconf", &lirc_configfile, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL}, #endif
--- a/command.c Thu Oct 21 17:35:56 2010 +0000 +++ b/command.c Thu Oct 21 18:19:30 2010 +0000 @@ -1109,6 +1109,48 @@ return M_PROPERTY_NOT_IMPLEMENTED; } +static int mp_property_capture(m_option_t *prop, int action, + void *arg, MPContext *mpctx) +{ + int ret; + int capturing = !!mpctx->stream->capture_file; + + if (!mpctx->stream) + return M_PROPERTY_UNAVAILABLE; + + ret = m_property_flag(prop, action, arg, &capturing); + if (ret == M_PROPERTY_OK && capturing != !!mpctx->stream->capture_file) { + if (capturing) { + if (capture_dump && !(mpctx->stream->capture_file = fopen(stream_dump_name, "wb"))) { + mp_msg(MSGT_GLOBAL, MSGL_ERR, + "Error opening capture file: %s\n", strerror(errno)); + ret = M_PROPERTY_ERROR; + } else { + mp_msg(MSGT_GLOBAL, MSGL_ERR, + "Capturing not enabled (forgot -capture parameter?)\n"); + ret = M_PROPERTY_ERROR; + } + } else { + fclose(mpctx->stream->capture_file); + mpctx->stream->capture_file = NULL; + } + } + + switch (ret) { + case M_PROPERTY_ERROR: + set_osd_msg(OSD_MSG_SPEED, 1, osd_duration, MSGTR_OSDCapturingFailure); + break; + case M_PROPERTY_OK: + set_osd_msg(OSD_MSG_SPEED, 1, osd_duration, MSGTR_OSDCapturing, + mpctx->stream->capture_file ? MSGTR_Enabled : MSGTR_Disabled); + break; + default: + break; + } + + return ret; +} + /// Panscan (RW) static int mp_property_panscan(m_option_t *prop, int action, void *arg, MPContext *mpctx) @@ -2097,6 +2139,8 @@ 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, @@ -2286,6 +2330,7 @@ { "loop", MP_CMD_LOOP, 0, 0, -1, MSGTR_LoopStatus }, { "chapter", MP_CMD_SEEK_CHAPTER, 0, 0, -1, NULL }, { "angle", MP_CMD_SWITCH_ANGLE, 0, 0, -1, NULL }, + { "capturing", MP_CMD_CAPTURING, 1, 0, -1, NULL }, // audio { "volume", MP_CMD_VOLUME, 0, OSD_VOLUME, -1, MSGTR_Volume }, { "mute", MP_CMD_MUTE, 1, 0, -1, MSGTR_MuteStatus },
--- a/help/help_mp-en.h Thu Oct 21 17:35:56 2010 +0000 +++ b/help/help_mp-en.h Thu Oct 21 18:19:30 2010 +0000 @@ -213,6 +213,8 @@ #define MSGTR_OSDChapter "Chapter: (%d) %s" #define MSGTR_OSDAngle "Angle: %d/%d" #define MSGTR_OSDDeinterlace "Deinterlace: %s" +#define MSGTR_OSDCapturing "Capturing: %s" +#define MSGTR_OSDCapturingFailure "Capturing failed" // property values #define MSGTR_Enabled "enabled"
--- a/help/help_mp-hu.h Thu Oct 21 17:35:56 2010 +0000 +++ b/help/help_mp-hu.h Thu Oct 21 18:19:30 2010 +0000 @@ -213,6 +213,8 @@ #define MSGTR_OSDChapter "Fejezet: (%d) %s" #define MSGTR_OSDAngle "Szög: %d/%d" #define MSGTR_OSDDeinterlace "Deinterlace: %s" +#define MSGTR_OSDCapturing "Mentés: %s" +#define MSGTR_OSDCapturingFailure "Mentés sikertelen" // property values #define MSGTR_Enabled "bekapcsolva"
--- a/help/help_mp-it.h Thu Oct 21 17:35:56 2010 +0000 +++ b/help/help_mp-it.h Thu Oct 21 18:19:30 2010 +0000 @@ -211,6 +211,8 @@ #define MSGTR_OSDChapter "Capitolo: (%d) %s" #define MSGTR_OSDAngle "Angolazione: %d/%d" #define MSGTR_OSDDeinterlace "Deinterlacciamento: %s" +#define MSGTR_OSDCapturing "Registrazione: %s" +#define MSGTR_OSDCapturingFailure "Registrazione fallito" // property values #define MSGTR_Enabled "abilitat"
--- a/input/input.c Thu Oct 21 17:35:56 2010 +0000 +++ b/input/input.c Thu Oct 21 18:19:30 2010 +0000 @@ -173,6 +173,7 @@ { 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}} } }, @@ -464,6 +465,7 @@ #endif { { 'T', 0 }, "vo_ontop" }, { { 'f', 0 }, "vo_fullscreen" }, + { { 'c', 0 }, "capturing" }, { { 's', 0 }, "screenshot 0" }, { { 'S', 0 }, "screenshot 1" }, { { 'w', 0 }, "panscan -0.1" },
--- a/input/input.h Thu Oct 21 17:35:56 2010 +0000 +++ b/input/input.h Thu Oct 21 18:19:30 2010 +0000 @@ -43,6 +43,7 @@ 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,
--- a/mplayer.c Thu Oct 21 17:35:56 2010 +0000 +++ b/mplayer.c Thu Oct 21 18:19:30 2010 +0000 @@ -263,8 +263,9 @@ #endif // dump: -static char *stream_dump_name="stream.dump"; - int stream_dump_type=0; +char *stream_dump_name = "stream.dump"; +int stream_dump_type = 0; +int capture_dump = 0; // A-V sync: static float default_max_pts_correction=-1;
--- a/mplayer.h Thu Oct 21 17:35:56 2010 +0000 +++ b/mplayer.h Thu Oct 21 18:19:30 2010 +0000 @@ -39,7 +39,10 @@ /* for the GUI */ extern int auto_quality; extern int disable_gui_conf; + +extern int capture_dump; extern int stream_dump_type; +extern char *stream_dump_name; void update_set_of_subtitles(void);
--- a/stream/cache2.c Thu Oct 21 17:35:56 2010 +0000 +++ b/stream/cache2.c Thu Oct 21 18:19:30 2010 +0000 @@ -510,6 +510,8 @@ s->buf_len=len; s->pos+=len; // printf("[%d]",len);fflush(stdout); + if (s->capture_file) + stream_capture_do(s); return len; }
--- a/stream/stream.c Thu Oct 21 17:35:56 2010 +0000 +++ b/stream/stream.c Thu Oct 21 18:19:30 2010 +0000 @@ -179,6 +179,7 @@ } } s = new_stream(-2,-2); + s->capture_file = NULL; s->url=strdup(filename); s->flags |= mode; *ret = sinfo->open(s,mode,arg,file_format); @@ -269,6 +270,16 @@ //=================== STREAMER ========================= +void stream_capture_do(stream_t *s) +{ + if (fwrite(s->buffer, s->buf_len, 1, s->capture_file) < 1) { + mp_msg(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. @@ -300,6 +311,8 @@ s->buf_len=len; s->pos+=len; // printf("[%d]",len);fflush(stdout); + if (s->capture_file) + stream_capture_do(s); return len; } @@ -463,6 +476,11 @@ #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
--- a/stream/stream.h Thu Oct 21 17:35:56 2010 +0000 +++ b/stream/stream.h Thu Oct 21 18:19:30 2010 +0000 @@ -23,6 +23,7 @@ #include "m_option.h" #include "mp_msg.h" #include "url.h" +#include <stdio.h> #include <string.h> #include <inttypes.h> #include <sys/types.h> @@ -165,6 +166,7 @@ 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 @@ -173,6 +175,7 @@ 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);