[MPlayer-dev-eng] [PATCH] Capture feature

Pásztor Szilárd bartosteka at freemail.hu
Thu Sep 9 13:08:36 CEST 2010


Reimar Döffinger:
> Uh, about 1/3 the amount of code, plus it actually supports more actions
> and it will profit from extensions/fixes to the generic flag handling code.
> But call it "more maintainable" if that does not fit your definition of
>"complex".

Attached with the additional manpage entry.
-------------- next part --------------
diff -NurpabB mplayer-export-2010-09-09/cfg-mplayer.h mplayer-export-2010-09-09-capture/cfg-mplayer.h
--- mplayer-export-2010-09-09/cfg-mplayer.h	2010-09-08 07:29:05.000000000 +0200
+++ mplayer-export-2010-09-09-capture/cfg-mplayer.h	2010-09-09 12:40:21.697250536 +0200
@@ -296,6 +296,8 @@ 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},
 
+    {"capturefile", &capture_dump_name, CONF_TYPE_STRING, 0, 0, 0, NULL},
+
 #ifdef CONFIG_LIRC
     {"lircconf", &lirc_configfile, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL},
 #endif
diff -NurpabB mplayer-export-2010-09-09/command.c mplayer-export-2010-09-09-capture/command.c
--- mplayer-export-2010-09-09/command.c	2010-09-04 01:49:35.000000000 +0200
+++ mplayer-export-2010-09-09-capture/command.c	2010-09-09 12:40:21.700249775 +0200
@@ -71,6 +71,7 @@
 #define ROUND(x) ((int)((x)<0 ? (x)-0.5 : (x)+0.5))
 
 extern int use_menu;
+char *capture_dump_name=NULL;
 
 static void rescale_input_coordinates(int ix, int iy, double *dx, double *dy)
 {
@@ -1110,6 +1111,68 @@ static int mp_property_deinterlace(m_opt
     return M_PROPERTY_NOT_IMPLEMENTED;
 }
 
+static int mp_property_capture(m_option_t *prop, int action,
+                                   void *arg, MPContext *mpctx)
+{
+    int capturing = -1;
+    int ret = M_PROPERTY_NOT_IMPLEMENTED;
+
+    if (!mpctx->stream)
+        return M_PROPERTY_UNAVAILABLE;
+
+    switch (action) {
+    case M_PROPERTY_GET:
+        if (arg) {
+	    *(int *)arg = !!mpctx->stream->capture_file;
+	    return M_PROPERTY_OK;
+	} else
+            return M_PROPERTY_ERROR;
+    case M_PROPERTY_SET:
+        if (!arg) {
+            ret = M_PROPERTY_ERROR;
+	    break;
+	}
+	M_PROPERTY_CLAMP(prop, *(int *) arg);
+	capturing = *(int *)arg;
+	// fall through
+    case M_PROPERTY_STEP_UP:
+    case M_PROPERTY_STEP_DOWN:
+	if (capturing < 0)
+	    capturing = !mpctx->stream->capture_file;
+
+	if (capturing) {
+	    if (capture_dump_name && !mpctx->stream->capture_file &&
+		!(mpctx->stream->capture_file = fopen(capture_dump_name, "wb"))) {
+		mp_msg(MSGT_GLOBAL, MSGL_ERR, "Error opening capture file: %s\n", strerror(errno));
+		ret = M_PROPERTY_ERROR;
+	    } else
+		ret = M_PROPERTY_OK;
+	} else {
+	    if (mpctx->stream->capture_file) {
+		fclose(mpctx->stream->capture_file);
+		mpctx->stream->capture_file = NULL;
+		ret = M_PROPERTY_OK;
+	    }
+	    else
+		return M_PROPERTY_OK;
+	}
+    }
+
+    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)
@@ -2098,6 +2161,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,
@@ -2287,6 +2352,7 @@ static struct {
     { "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 },
diff -NurpabB mplayer-export-2010-09-09/DOCS/man/en/mplayer.1 mplayer-export-2010-09-09-capture/DOCS/man/en/mplayer.1
--- mplayer-export-2010-09-09/DOCS/man/en/mplayer.1	2010-09-08 07:29:05.000000000 +0200
+++ mplayer-export-2010-09-09-capture/DOCS/man/en/mplayer.1	2010-09-09 13:00:56.751499206 +0200
@@ -281,6 +281,8 @@ Toggle displaying "forced subtitles".
 Toggle subtitle alignment: top / middle / bottom.
 .IPs "x and z"
 Adjust subtitle delay by +/\- 0.1 seconds.
+.IPs "c (\-capturefile only)"
+Start/stop capturing the primary stream.
 .IPs "r and t"
 Move subtitles up/down.
 .IPs "i (\-edlout mode only)"
@@ -1340,6 +1342,16 @@ from the current position, MPlayer will 
 this position rather than performing a stream seek (default: 50).
 .
 .TP
+.B \-capturefile <filename> (MPlayer only)
+Allows capturing the primary stream (e.g. not additional audio or others)
+into the specified file. If this option is given, capturing can be started
+and stopped by pressing the key bound to this function (see section
+INTERACTIVE CONTROL). The capture file produced by this function is the same
+as that of -dumpstream and will probably be useless for anything else than
+MPEG streams. Note that, due to cache latencies, captured data may start
+and stop 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
diff -NurpabB mplayer-export-2010-09-09/help/help_mp-en.h mplayer-export-2010-09-09-capture/help/help_mp-en.h
--- mplayer-export-2010-09-09/help/help_mp-en.h	2010-09-08 07:29:05.000000000 +0200
+++ mplayer-export-2010-09-09-capture/help/help_mp-en.h	2010-09-09 12:40:21.703249592 +0200
@@ -213,6 +213,8 @@ static const char help_text[]=
 #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"
diff -NurpabB mplayer-export-2010-09-09/help/help_mp-hu.h mplayer-export-2010-09-09-capture/help/help_mp-hu.h
--- mplayer-export-2010-09-09/help/help_mp-hu.h	2010-07-27 23:23:19.000000000 +0200
+++ mplayer-export-2010-09-09-capture/help/help_mp-hu.h	2010-09-09 12:40:21.706249268 +0200
@@ -209,6 +209,8 @@ static const char help_text[]=
 #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"
diff -NurpabB mplayer-export-2010-09-09/help/help_mp-it.h mplayer-export-2010-09-09-capture/help/help_mp-it.h
--- mplayer-export-2010-09-09/help/help_mp-it.h	2010-08-18 19:23:21.000000000 +0200
+++ mplayer-export-2010-09-09-capture/help/help_mp-it.h	2010-09-09 12:40:21.710249757 +0200
@@ -208,6 +208,8 @@ static const char help_text[]=
 #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"
diff -NurpabB mplayer-export-2010-09-09/input/input.c mplayer-export-2010-09-09-capture/input/input.c
--- mplayer-export-2010-09-09/input/input.c	2010-09-03 20:50:03.000000000 +0200
+++ mplayer-export-2010-09-09-capture/input/input.c	2010-09-09 12:40:21.711250020 +0200
@@ -173,6 +173,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}} } },
@@ -461,6 +462,7 @@ static const mp_cmd_bind_t def_cmd_binds
 #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" },
diff -NurpabB mplayer-export-2010-09-09/input/input.h mplayer-export-2010-09-09-capture/input/input.h
--- mplayer-export-2010-09-09/input/input.h	2010-09-03 20:50:03.000000000 +0200
+++ mplayer-export-2010-09-09-capture/input/input.h	2010-09-09 12:40:21.712249336 +0200
@@ -43,6 +43,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 -NurpabB mplayer-export-2010-09-09/mplayer.c mplayer-export-2010-09-09-capture/mplayer.c
--- mplayer-export-2010-09-09/mplayer.c	2010-09-08 21:35:02.000000000 +0200
+++ mplayer-export-2010-09-09-capture/mplayer.c	2010-09-09 12:40:21.715249419 +0200
@@ -4140,6 +4140,11 @@ goto_next_file:  // don't jump here afte
 
 mp_msg(MSGT_CPLAYER,MSGL_INFO,"\n");
 
+if (mpctx->stream && mpctx->stream->capture_file) {
+    fclose(mpctx->stream->capture_file);
+    mpctx->stream->capture_file = NULL;
+}
+
 if(benchmark){
     double tot=video_time_usage+vout_time_usage+audio_time_usage;
     double total_time_usage;
diff -NurpabB mplayer-export-2010-09-09/mplayer.h mplayer-export-2010-09-09-capture/mplayer.h
--- mplayer-export-2010-09-09/mplayer.h	2010-09-03 20:50:03.000000000 +0200
+++ mplayer-export-2010-09-09-capture/mplayer.h	2010-09-09 12:40:21.716249256 +0200
@@ -42,6 +42,8 @@ extern int    sub_auto;
 
 extern char * filename;
 
+extern char *capture_dump_name;
+
 extern int stream_cache_size;
 extern int autosync;
 extern double start_pts;
diff -NurpabB mplayer-export-2010-09-09/stream/cache2.c mplayer-export-2010-09-09-capture/stream/cache2.c
--- mplayer-export-2010-09-09/stream/cache2.c	2010-08-26 23:06:24.000000000 +0200
+++ mplayer-export-2010-09-09-capture/stream/cache2.c	2010-09-09 12:40:21.717250178 +0200
@@ -520,6 +520,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 -NurpabB mplayer-export-2010-09-09/stream/stream.c mplayer-export-2010-09-09-capture/stream/stream.c
--- mplayer-export-2010-09-09/stream/stream.c	2010-08-21 12:08:29.000000000 +0200
+++ mplayer-export-2010-09-09-capture/stream/stream.c	2010-09-09 12:40:21.718250038 +0200
@@ -179,6 +179,7 @@ static stream_t* open_stream_plugin(cons
     }
   }
   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,14 @@ stream_t* open_output_stream(const char*
 
 //=================== 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 +309,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;
 }
 
diff -NurpabB mplayer-export-2010-09-09/stream/stream.h mplayer-export-2010-09-09-capture/stream/stream.h
--- mplayer-export-2010-09-09/stream/stream.h	2010-08-03 18:26:50.000000000 +0200
+++ mplayer-export-2010-09-09-capture/stream/stream.h	2010-09-09 12:40:21.718250038 +0200
@@ -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 @@ 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
@@ -173,6 +175,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);


More information about the MPlayer-dev-eng mailing list