[MPlayer-dev-eng] [PATCH] Switch -dumpstream/stream capturing via command away from fopen.

Reimar Döffinger Reimar.Doeffinger at gmx.de
Mon Jan 18 00:59:08 EET 2021


Use our own stream functions which for example have proper
UTF-8 support on Windows.
Would also allow to capture to other stream types than
just files, but this is likely to have problems, e.g.
FFmpeg's AVIO supports appending only via stream-specific
options, so stream_ffmpeg does not support it.
---
 command.c            | 15 ++++++++-------
 mplayer.c            | 22 +++++++++++-----------
 stream/cache2.c      |  2 +-
 stream/stream.c      | 22 ++++++++++++----------
 stream/stream.h      |  5 +++--
 stream/stream_file.c |  2 ++
 6 files changed, 37 insertions(+), 31 deletions(-)

diff --git a/command.c b/command.c
index 0e5c11f7c..4424eadd8 100644
--- a/command.c
+++ b/command.c
@@ -1123,7 +1123,7 @@ static int mp_property_capture(m_option_t *prop, int action,
                                void *arg, MPContext *mpctx)
 {
     int ret;
-    int capturing = mpctx->stream && mpctx->stream->capture_file;
+    int capturing = mpctx->stream && mpctx->stream->capture_stream;

     if (!mpctx->stream)
         return M_PROPERTY_UNAVAILABLE;
@@ -1134,17 +1134,18 @@ static int mp_property_capture(m_option_t *prop, int action,
     }

     ret = m_property_flag(prop, action, arg, &capturing);
-    if (ret == M_PROPERTY_OK && capturing != !!mpctx->stream->capture_file) {
+    if (ret == M_PROPERTY_OK && capturing != !!mpctx->stream->capture_stream) {
         if (capturing) {
-            mpctx->stream->capture_file = fopen(stream_dump_name, "ab");
-            if (!mpctx->stream->capture_file) {
+            int dummy;
+            mpctx->stream->capture_stream = open_stream_full(stream_dump_name, STREAM_APPEND, NULL, &dummy);
+            if (!mpctx->stream->capture_stream) {
                 mp_msg(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;
+            free_stream(mpctx->stream->capture_stream);
+            mpctx->stream->capture_stream = NULL;
         }
     }

@@ -1154,7 +1155,7 @@ static int mp_property_capture(m_option_t *prop, int action,
         break;
     case M_PROPERTY_OK:
         set_osd_msg(OSD_MSG_SPEED, 1, osd_duration, MSGTR_OSDCapturing,
-                    mpctx->stream->capture_file ? MSGTR_Enabled : MSGTR_Disabled);
+                    mpctx->stream->capture_stream ? MSGTR_Enabled : MSGTR_Disabled);
         break;
     default:
         break;
diff --git a/mplayer.c b/mplayer.c
index c0223ab6c..f335299a6 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -3281,12 +3281,12 @@ play_next_file:
     if (stream_dump_type == 5) {
         unsigned char buf[4096];
         int len;
-        FILE *f;
+        stream_t *os;
         current_module = "dumpstream";
         stream_reset(mpctx->stream);
         stream_seek(mpctx->stream, mpctx->stream->start_pos);
-        f = fopen(stream_dump_name, "wb");
-        if (!f) {
+        os = open_output_stream(stream_dump_name, NULL);
+        if (!os) {
             mp_msg(MSGT_CPLAYER, MSGL_FATAL, MSGTR_CantOpenDumpfile);
             exit_player(EXIT_ERROR);
         }
@@ -3303,7 +3303,7 @@ play_next_file:
                 break;
             len = stream_read(mpctx->stream, buf, 4096);
             if (len > 0) {
-                if (fwrite(buf, len, 1, f) != 1) {
+                if (stream_write_buffer(os, buf, len) != len) {
                     mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_ErrorWritingFile, stream_dump_name);
                     exit_player(EXIT_ERROR);
                 }
@@ -3316,7 +3316,7 @@ play_next_file:
                     break;
             }
         }
-        if (fclose(f)) {
+        if (free_stream(os)) {
             mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_ErrorWritingFile, stream_dump_name);
             exit_player(EXIT_ERROR);
         }
@@ -3484,7 +3484,7 @@ goto_enable_cache:

     // DUMP STREAMS:
     if ((stream_dump_type) && (stream_dump_type < 4)) {
-        FILE *f;
+        stream_t *os;
         demux_stream_t *ds = NULL;
         current_module = "dump";
         // select stream to dump
@@ -3513,8 +3513,8 @@ goto_enable_cache:
             mpctx->d_sub->id = -2;
         }
         // let's dump it!
-        f = fopen(stream_dump_name, "wb");
-        if (!f) {
+        os = open_output_stream(stream_dump_name, NULL);
+        if (!os) {
             mp_msg(MSGT_CPLAYER, MSGL_FATAL, MSGTR_CantOpenDumpfile);
             exit_player(EXIT_ERROR);
         }
@@ -3531,9 +3531,9 @@ goto_enable_cache:
                 break;
             if ((mpctx->demuxer->file_format == DEMUXER_TYPE_AVI || mpctx->demuxer->file_format == DEMUXER_TYPE_ASF || mpctx->demuxer->file_format == DEMUXER_TYPE_MOV)
                 && stream_dump_type == 2)
-                fwrite(&in_size, 1, 4, f);
+                stream_write_buffer(os, &in_size, 4);
             if (in_size > 0) {
-                fwrite(start, in_size, 1, f);
+                stream_write_buffer(os, start, in_size);
                 stream_dump_progress(in_size, mpctx->stream);
             }
             if (dvd_last_chapter > 0) {
@@ -3542,7 +3542,7 @@ goto_enable_cache:
                     break;
             }
         }
-        fclose(f);
+        free_stream(os);
         stream_dump_progress_end();
         mp_msg(MSGT_CPLAYER, MSGL_INFO, MSGTR_CoreDumped);
         exit_player_with_rc(EXIT_EOF, 0);
diff --git a/stream/cache2.c b/stream/cache2.c
index d6ed3aee5..f2eb711c2 100644
--- a/stream/cache2.c
+++ b/stream/cache2.c
@@ -578,7 +578,7 @@ int cache_stream_fill_buffer(stream_t *s){
   s->buf_len=len;
   s->pos+=len;
 //  printf("[%d]",len);fflush(stdout);
-  if (s->capture_file)
+  if (s->capture_stream)
     stream_capture_do(s);
   return len;

diff --git a/stream/stream.c b/stream/stream.c
index 6cb7e79b1..0d39df6a7 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -181,7 +181,7 @@ static stream_t* open_stream_plugin(const stream_info_t* sinfo, const char* file
     }
   }
   s = new_stream(-2,-2);
-  s->capture_file = NULL;
+  s->capture_stream = NULL;
   s->url=strdup(filename);
   s->flags |= mode;
   *ret = sinfo->open(s,mode,arg,file_format);
@@ -270,11 +270,11 @@ stream_t* open_output_stream(const char* filename, char** options) {

 void stream_capture_do(stream_t *s)
 {
-  if (fwrite(s->buffer, s->buf_len, 1, s->capture_file) < 1) {
+  if (stream_write_buffer(s->capture_stream, s->buffer, s->buf_len) != s->buf_len) {
     mp_msg(MSGT_GLOBAL, MSGL_ERR, MSGTR_StreamErrorWritingCapture,
            strerror(errno));
-    fclose(s->capture_file);
-    s->capture_file = NULL;
+    free_stream(s->capture_stream);
+    s->capture_stream = NULL;
   }
 }

@@ -370,7 +370,7 @@ int stream_fill_buffer(stream_t *s){
   // definitely not at EOF yet
   s->eof = 0;
 //  printf("[%d]",len);fflush(stdout);
-  if (s->capture_file)
+  if (s->capture_stream)
     stream_capture_do(s);
   return s->buf_len;
 }
@@ -540,14 +540,15 @@ stream_t* new_stream(int fd,int type){
   return s;
 }

-void free_stream(stream_t *s){
+int free_stream(stream_t *s){
+  int res = 0;
 //  printf("\n*** free_stream() called ***\n");
 #ifdef CONFIG_STREAM_CACHE
     cache_uninit(s);
 #endif
-  if (s->capture_file) {
-    fclose(s->capture_file);
-    s->capture_file = NULL;
+  if (s->capture_stream) {
+    res |= free_stream(s->capture_stream);
+    s->capture_stream = NULL;
   }

   if(s->close) s->close(s);
@@ -557,7 +558,7 @@ void free_stream(stream_t *s){
        network socket and file */
     if(s->url && strstr(s->url,"://"))
       closesocket(s->fd);
-    else close(s->fd);
+    else res |= close(s->fd);
   }
 #if HAVE_WINSOCK2_H
   mp_msg(MSGT_STREAM,MSGL_V,"WINSOCK2 uninit\n");
@@ -568,6 +569,7 @@ void free_stream(stream_t *s){
   //free(s->priv);
   free(s->url);
   free(s);
+  return res;
 }

 stream_t* new_ds_stream(demux_stream_t *ds) {
diff --git a/stream/stream.h b/stream/stream.h
index 3063684d0..1e03e0b74 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -64,6 +64,7 @@
 /// streams that use the new api should check the mode at open
 #define STREAM_READ  0
 #define STREAM_WRITE 1
+#define STREAM_APPEND 2
 /// Seek flags, if not mannualy set and s->seek isn't NULL
 /// MP_STREAM_SEEK is automaticly set
 #define MP_STREAM_SEEK_BW  2
@@ -179,7 +180,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;
+  struct stream *capture_stream;
 } stream_t;

 #ifdef CONFIG_NETWORKING
@@ -363,7 +364,7 @@ static inline int stream_skip(stream_t *s, int64_t len)
 void stream_reset(stream_t *s);
 int stream_control(stream_t *s, int cmd, void *arg);
 stream_t* new_stream(int fd,int type);
-void free_stream(stream_t *s);
+int free_stream(stream_t *s);
 stream_t* new_memory_stream(unsigned char* data,int len);
 stream_t* open_stream(const char* filename,char** options,int* file_format);
 stream_t* open_stream_full(const char* filename,int mode, char** options, int* file_format);
diff --git a/stream/stream_file.c b/stream/stream_file.c
index e96a5165a..204e49fde 100644
--- a/stream/stream_file.c
+++ b/stream/stream_file.c
@@ -149,6 +149,8 @@ static int open_f(stream_t *stream,int mode, void* opts, int* file_format) {
     m = O_RDONLY;
   else if(mode == STREAM_WRITE)
     m = O_RDWR|O_CREAT|O_TRUNC;
+  else if (mode == STREAM_APPEND)
+    m = O_RDWR|O_CREAT|O_APPEND;
   else {
     mp_msg(MSGT_OPEN,MSGL_ERR, "[file] Unknown open mode %d\n",mode);
     m_struct_free(&stream_opts,opts);
--
2.30.0



More information about the MPlayer-dev-eng mailing list