[PATCH] Switch -dumpstream/stream capturing via command away from fopen.
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
participants (1)
-
Reimar Döffinger