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);