Sophie

Sophie

distrib > Arklinux > devel > i586 > by-pkgid > 9482443bfa78fcd0975e9204e634806b > files > 16

mplayer-1.0-0.svn34182.1ark.src.rpm

--- mplayer/command.c.recorder~	2010-04-06 13:16:58.000000000 +0200
+++ mplayer/command.c	2010-04-06 13:40:22.795706994 +0200
@@ -3006,6 +3006,26 @@ int run_command(MPContext * mpctx, mp_cm
 	    }
 	    break;
 
+	case MP_CMD_RECORD:
+	{
+	    char *file=cmd->args[0].v.s;
+	    int flags=0;
+	    if(file) {
+		while(file[0]=='+' || file[0]=='%' || file[0]=='|' || file[0]=='@') {
+		    if(file[0]=='+')
+			    flags |= 1; /* append */
+		    else if(file[0]=='%')
+			    flags |= 2; /* prepend */
+		    else if(file[0]=='|')
+			    flags |= 4; /* pipe */
+		    else if(file[0]=='@')
+			    flags |= 8; /* wait for data block (e.g. header) */
+		    file++;
+		}
+	    }
+	    recorder_switch(file, flags);
+	    break;
+	}
 	case MP_CMD_VF_CHANGE_RECTANGLE:
             if (!sh_video)
                 break;
--- mplayer/input/input.c.recorder~	2010-04-06 13:40:22.785706791 +0200
+++ mplayer/input/input.c	2010-04-06 13:40:22.795706994 +0200
@@ -166,6 +166,7 @@ static const mp_cmd_t mp_cmds[] = {
   { MP_CMD_VO_ROOTWIN, "vo_rootwin", 0, { {MP_CMD_ARG_INT,{-1}}, {-1,{0}} } },
   { MP_CMD_VO_BORDER, "vo_border", 0, { {MP_CMD_ARG_INT,{-1}}, {-1,{0}} } },
   { MP_CMD_SCREENSHOT, "screenshot", 0, { {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
+  { MP_CMD_RECORD, "record", 0, { {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } },
   { MP_CMD_PANSCAN, "panscan",1,  { {MP_CMD_ARG_FLOAT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
   { MP_CMD_SWITCH_VSYNC, "switch_vsync", 0, { {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
   { MP_CMD_LOADFILE, "loadfile", 1, { {MP_CMD_ARG_STRING, {0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
@@ -426,7 +427,7 @@ static const mp_cmd_bind_t def_cmd_binds
   { { '8', 0 }, "saturation 1" },
   { { 'd', 0 }, "frame_drop" },
   { { 'D', 0 }, "step_property deinterlace" },
-  { { 'r', 0 }, "sub_pos -1" },
+//  { { 'r', 0 }, "sub_pos -1" },
   { { 't', 0 }, "sub_pos +1" },
   { { 'a', 0 }, "sub_alignment" },
   { { 'v', 0 }, "sub_visibility" },
@@ -473,6 +474,7 @@ static const mp_cmd_bind_t def_cmd_binds
   { { 'S', 0 }, "screenshot 1" },
   { { 'w', 0 }, "panscan -0.1" },
   { { 'e', 0 }, "panscan +0.1" },
+  { { 'r', 0 }, "record" },
 
   { { KEY_POWER, 0 }, "quit" },
   { { KEY_MENU, 0 }, "osd" },
@@ -507,7 +509,8 @@ static const mp_cmd_bind_t gui_def_cmd_b
   { { KEY_ENTER, 0 }, "gui_play" },
   { { KEY_ESC, 0 }, "gui_stop" },
   { { 'p', 0 }, "gui_playlist" },
-  { { 'r', 0 }, "gui_preferences" },
+  { { 'r', 0 }, "record" },
+//{ { 'r', 0 }, "gui_preferences" },
   { { 'c', 0 }, "gui_skinbrowser" },
 
   { { 0 }, NULL }
--- mplayer/input/input.h.recorder~	2010-04-06 13:40:22.789040523 +0200
+++ mplayer/input/input.h	2010-04-06 13:40:22.795706994 +0200
@@ -133,6 +133,7 @@ typedef enum {
   MP_CMD_ASS_USE_MARGINS,
   MP_CMD_SWITCH_TITLE,
   MP_CMD_STOP,
+  MP_CMD_RECORD,
 
   /// DVDNAV commands
   MP_CMD_DVDNAV_UP = 1000,
--- mplayer/Makefile.recorder~	2010-04-06 13:40:22.789040523 +0200
+++ mplayer/Makefile	2010-04-06 13:40:22.795706994 +0200
@@ -531,6 +531,7 @@ SRCS_COMMON = asxparser.c \
               stream/stream_mf.c \
               stream/stream_null.c \
               stream/url.c \
+              stream/recorder.c \
               $(SRCS_COMMON-yes)
 
 
--- mplayer/mplayer.c.recorder~	2010-04-06 13:40:22.789040523 +0200
+++ mplayer/mplayer.c	2010-04-06 13:40:22.799040334 +0200
@@ -124,6 +124,9 @@ char *heartbeat_cmd;
 #endif
 #include "stream/cache2.h"
 
+extern void recorder_register_options(m_config_t* cfg);
+extern void recorder_close(void);
+
 //**************************************************************************//
 //             Playtree
 //**************************************************************************//
@@ -679,6 +682,9 @@ void uninit_player(unsigned int mask){
 #endif
   }
 
+  current_module="uninit_recorder";
+  recorder_close();
+
   current_module=NULL;
 }
 
@@ -2647,6 +2653,7 @@ int gui_no_filename=0;
   mconfig = m_config_new();
   m_config_register_options(mconfig,mplayer_opts);
   mp_input_register_options(mconfig);
+  recorder_register_options(mconfig); //HACK
 
   // Preparse the command line
   m_config_preparse_command_line(mconfig,argc,argv);
@@ -2977,6 +2984,8 @@ stream_set_interrupt_callback(mp_input_c
  }
 #endif
 
+setvbuf(stdin, 0, _IONBF, 0);
+
 initialized_flags|=INITIALIZED_INPUT;
 current_module = NULL;
 
--- mplayer/mp_msg.h.recorder~	2010-04-06 13:16:58.000000000 +0200
+++ mplayer/mp_msg.h	2010-04-06 13:40:22.799040334 +0200
@@ -124,6 +124,8 @@ extern int verbose;
 
 #define MSGT_TELETEXT 46       // Teletext decoder
 
+#define MSGT_RECORDER 63
+
 #define MSGT_MAX 64
 
 void mp_msg_init(void);
--- mplayer/stream/cache2.c.recorder~	2010-04-06 13:16:52.000000000 +0200
+++ mplayer/stream/cache2.c	2010-04-06 13:43:46.752147495 +0200
@@ -58,6 +58,8 @@ static void *ThreadProc(void *s);
 #include "cache2.h"
 extern int use_gui;
 
+void recorder_write(unsigned char *buffer, int len);
+
 typedef struct {
   // constats:
   unsigned char *buffer;      // base pointer of the alllocated buffer memory
@@ -334,6 +336,7 @@ static void exit_sighandler(int x){
  */
 int stream_enable_cache(stream_t *stream,int size,int min,int seek_limit){
   int ss = stream->sector_size ? stream->sector_size : STREAM_BUFFER_SIZE;
+  pid_t pid;
   int res = -1;
   cache_vars_t* s;
 
@@ -344,6 +347,7 @@ int stream_enable_cache(stream_t *stream
 
   s=cache_init(size,ss);
   if(s == NULL) return -1;
+  stream->cache_pid=-1;
   stream->cache_data=s;
   s->stream=stream; // callback
   s->seek_limit=seek_limit;
@@ -359,7 +363,9 @@ int stream_enable_cache(stream_t *stream
   }
 
 #if !defined(__MINGW32__) && !defined(PTHREAD_CACHE) && !defined(__OS2__)
-  if((stream->cache_pid=fork())){
+  pid=fork();
+  if(pid){
+    stream->cache_pid = pid;
     if ((pid_t)stream->cache_pid == -1)
       stream->cache_pid = 0;
 #else
@@ -439,7 +445,14 @@ static void ThreadProc( void *s ){
 int cache_stream_fill_buffer(stream_t *s){
   int len;
   if(s->eof){ s->buf_pos=s->buf_len=0; return 0; }
-  if(!s->cache_pid) return stream_fill_buffer(s);
+  if(s->cache_pid <= 0) {
+    len = stream_fill_buffer(s);
+    if(len <= 0)
+      return 0;
+    if(s->cache_pid == 0)
+      recorder_write(s->buffer, len);
+    return len;
+  }
 
 //  cache_stats(s->cache_data);
 
@@ -453,6 +466,7 @@ int cache_stream_fill_buffer(stream_t *s
   s->buf_len=len;
   s->pos+=len;
 //  printf("[%d]",len);fflush(stdout);
+  recorder_write(s->buffer, len);
   return len;
 
 }
@@ -460,7 +474,7 @@ int cache_stream_fill_buffer(stream_t *s
 int cache_stream_seek_long(stream_t *stream,off_t pos){
   cache_vars_t* s;
   off_t newpos;
-  if(!stream->cache_pid) return stream_seek_long(stream,pos);
+  if(stream->cache_pid <= 0) return stream_seek_long(stream,pos);
 
   s=stream->cache_data;
 //  s->seek_lock=1;
--- mplayer/stream/recorder.c.recorder~	2010-04-06 13:40:22.799040334 +0200
+++ mplayer/stream/recorder.c	2010-04-06 13:40:22.799040334 +0200
@@ -0,0 +1,181 @@
+
+/*
+ * A simple (silly) stream recorder by Albeu
+ * Kept up to date and improved by bero <bero@arklinux.org>
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "../m_config.h"
+#include "../m_option.h"
+#include "mp_msg.h"
+
+static int record = 0;
+static char append[2] = { 'w', 0 };
+static void* header = NULL;
+static char* out_file = NULL;
+static char* pipecmd = NULL;
+static unsigned char* waitfor = NULL;
+static unsigned int waitcount = 0;
+static FILE* fd = NULL;
+
+static m_option_t recorder_opts[] = {
+  { "started", &record, CONF_TYPE_FLAG, 0, 0, 1, NULL },
+  { "stopped", &record, CONF_TYPE_FLAG, 0, 1, 0, NULL },
+  { NULL,NULL, 0, 0, 0, 0, NULL}
+};
+
+static m_option_t recorder_conf[] = {
+  { "recorder", &recorder_opts, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
+  { NULL,NULL, 0, 0, 0, 0, NULL}
+};
+
+void recorder_register_options(m_config_t* cfg) {
+  m_config_register_options(cfg,recorder_conf);
+}
+
+void recorder_write(unsigned char* buffer,int len) {
+  int w;
+
+  if(!record)
+    return;
+
+  if (!fd)
+  {
+    if(pipecmd)
+      fd = popen(pipecmd, "w");
+    else if(out_file) {
+      fd = fopen(out_file,append);
+      free(out_file);
+      out_file=NULL;
+    } else
+      fd = fopen("/home/andi/tmp/mplayer_record.stream", append);
+    if(!fd) {
+      mp_msg(MSGT_RECORDER,MSGL_ERR,"Unable to open recorder output file %s (%s)\n",out_file,strerror(errno));
+      return;
+    } else {
+      mp_msg(MSGT_RECORDER,MSGL_V,"Recorder ready, recording in %s\n",out_file);
+      if(header) {
+	char buf[65536];
+	FILE *hdr=fopen(header, "r");
+	while(!feof(hdr) && !ferror(hdr)) {
+          int count=fread(buf, 1, 65536, hdr);
+	  fwrite(buf, 1, count, fd);
+	}
+	fclose(hdr);
+	free(header);
+	header=NULL;
+      }
+    }
+  }
+
+  if(waitcount) {
+    int i;
+    for(i=0; i<len-waitcount; i++) {
+      if(buffer[i]==waitfor[0]) {
+	int found=1, j;
+	for(j=1; j<waitcount; j++) {
+	  if(buffer[i+j] != waitfor[j]) {
+	    found=0;
+	    break;
+	  }
+	}
+	if(found) {
+	  free(waitfor);
+	  waitfor=NULL;
+	  waitcount=0;
+	  buffer += i;
+	  len -= i;
+	  break;
+	}
+      }
+    }
+    if(waitcount)
+      return;
+  }
+  
+  w = fwrite(buffer,len,1,fd);
+  if(w < 1) {
+    mp_msg(MSGT_RECORDER,MSGL_ERR,"Recorder : write error => disabeling the recorder\n");
+    if(pipecmd) {
+      free(pipecmd);
+      pipecmd = NULL;
+      pclose(fd);
+    } else {
+      fclose(fd);
+    }
+    fd = NULL;
+  }
+}
+
+void recorder_close(void) {
+  if(!fd)
+    return;
+  if(waitfor) {
+    free(waitfor);
+    waitfor=0;
+  }
+  if(pipecmd) {
+    if(pclose(fd) != 0)
+      mp_msg(MSGT_RECORDER,MSGL_ERR,"Recorder : close error (%s)\n",strerror(errno));
+    free(pipecmd);
+    pipecmd = NULL;
+  } else {
+    if(fclose(fd) != 0)
+      mp_msg(MSGT_RECORDER,MSGL_ERR,"Recorder : close error (%s)\n",strerror(errno));
+  }
+  fd = NULL;
+}
+
+/*
+ * Flags:
+ * 1 ----> Append to existing file
+ * 2 ----> Prepend existing file
+ * 4 ----> Pipe to command
+ * 8 ----> Wait for specific data before recording
+ */
+void recorder_switch(char *name, int flags) {
+  if(name) {
+    if((flags & 2) && strchr(name, '%')) {
+      header=strdup(name);
+      *strchr(header, '%')=0;
+      strcpy(name, strchr(name, '%')+1);
+    }
+    if((flags & 8) && strchr(name, ':')) {
+      char *tmp=strdup(name);
+      int i;
+      *strchr(tmp, ':')=0;
+      strcpy(name, strchr(name, ':')+1);
+      waitfor=(char*) malloc(strlen(tmp)/2);
+      waitcount=0;
+      for(i=0; i<strlen(tmp); i+=2) {
+	char bytes[3];
+	bytes[0]=tmp[i];
+	bytes[1]=tmp[i+1];
+	bytes[2]=0;
+	waitfor[waitcount++]=strtoul(bytes, NULL, 16);
+      }
+      free(tmp);
+    }
+    if(flags & 4)
+      pipecmd=strdup(name);
+    else
+      out_file=strdup(name);
+  }
+  if(!pipecmd && (flags & 1))
+    append[0]='a';
+  else
+    append[0]='w';
+  record = record ? 0 : 1;
+  if(record) {
+    mp_msg(MSGT_RECORDER,MSGL_INFO,"\nStart recording\n");
+  } else {
+    mp_msg(MSGT_RECORDER,MSGL_INFO,"\nStop recording\n");
+    recorder_close();
+  }
+}
--- mplayer/stream/stream.h.recorder~	2010-04-06 13:16:52.000000000 +0200
+++ mplayer/stream/stream.h	2010-04-06 13:40:22.799040334 +0200
@@ -153,7 +153,7 @@ typedef struct stream_st {
   off_t pos,start_pos,end_pos;
   int eof;
   int mode; //STREAM_READ or STREAM_WRITE
-  unsigned int cache_pid;
+  pid_t cache_pid;
   void* cache_data;
   void* priv; // used for DVD, TV, RTSP etc
   char* url;  // strdup() of filename/url