[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