From aa87c143cb369f1448f8d08086b5ef98998b4436 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 24 May 2014 14:06:13 +0200 Subject: stream: remove chaos related to writeable streams For some reason, we support writeable streams. (Only encoding uses that, and the use of it looks messy enough that I want to replace it with FILE or avio today.) It's a chaos: most streams do not actually check the mode parameter like they should. Simplify it, and let streams signal availability of write mode by setting a flag in the stream info struct. --- stream/stream.c | 10 ++++++++-- stream/stream.h | 3 ++- stream/stream_avdevice.c | 5 +---- stream/stream_bluray.c | 2 +- stream/stream_cdda.c | 6 +----- stream/stream_dvb.c | 6 +----- stream/stream_dvd.c | 6 +++--- stream/stream_dvdnav.c | 2 +- stream/stream_edl.c | 5 +---- stream/stream_file.c | 16 +++++----------- stream/stream_lavf.c | 18 +++++------------- stream/stream_memory.c | 2 +- stream/stream_mf.c | 2 +- stream/stream_null.c | 4 ++-- stream/stream_pvr.c | 5 +---- stream/stream_rar.c | 7 ++----- stream/stream_smb.c | 13 +++---------- stream/stream_tv.c | 2 +- stream/stream_vcd.c | 10 +--------- 19 files changed, 41 insertions(+), 83 deletions(-) (limited to 'stream') diff --git a/stream/stream.c b/stream/stream.c index 3ea4d475b7..baee62221f 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -289,6 +289,13 @@ static int open_internal(const stream_info_t *sinfo, struct stream *underlying, s->path = talloc_strdup(s, path); s->source = underlying; s->allow_caching = true; + s->mode = flags & (STREAM_READ | STREAM_WRITE); + + if ((s->mode & STREAM_WRITE) && !sinfo->can_write) { + MP_ERR(s, "No write access implemented.\n"); + talloc_free(s); + return STREAM_ERROR; + } // Parse options if (sinfo->priv_size) { @@ -306,8 +313,7 @@ static int open_internal(const stream_info_t *sinfo, struct stream *underlying, } } - s->mode = flags & (STREAM_READ | STREAM_WRITE); - int r = sinfo->open(s, s->mode); + int r = sinfo->open(s); if (r != STREAM_OK) { talloc_free(s); return r; diff --git a/stream/stream.h b/stream/stream.h index 5fc4c58579..ec0059e451 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -110,13 +110,14 @@ struct stream; typedef struct stream_info_st { const char *name; // opts is set from ->opts - int (*open)(struct stream *st, int mode); + int (*open)(struct stream *st); const char **protocols; int priv_size; const void *priv_defaults; const struct m_option *options; const char **url_options; bool stream_filter; + bool can_write; } stream_info_t; typedef struct stream { diff --git a/stream/stream_avdevice.c b/stream/stream_avdevice.c index 5e8aefd018..b4983b507a 100644 --- a/stream/stream_avdevice.c +++ b/stream/stream_avdevice.c @@ -20,11 +20,8 @@ #include "stream.h" -static int open_f(stream_t *stream, int mode) +static int open_f(stream_t *stream) { - if (mode != STREAM_READ) - return STREAM_ERROR; - stream->type = STREAMTYPE_AVDEVICE; stream->demuxer = "lavf"; diff --git a/stream/stream_bluray.c b/stream/stream_bluray.c index 0ca87403b4..5ef9fc8c60 100644 --- a/stream/stream_bluray.c +++ b/stream/stream_bluray.c @@ -712,7 +712,7 @@ static void select_initial_angle(stream_t *s) { bd_free_title_info(info); } -static int bluray_stream_open(stream_t *s, int mode) +static int bluray_stream_open(stream_t *s) { struct bluray_priv_s *b = s->priv; diff --git a/stream/stream_cdda.c b/stream/stream_cdda.c index 856c9736d2..f6740c1816 100644 --- a/stream/stream_cdda.c +++ b/stream/stream_cdda.c @@ -283,7 +283,7 @@ static int control(stream_t *stream, int cmd, void *arg) return STREAM_UNSUPPORTED; } -static int open_cdda(stream_t *st, int m) +static int open_cdda(stream_t *st) { cdda_priv *priv = st->priv; cdda_priv *p = priv; @@ -292,10 +292,6 @@ static int open_cdda(stream_t *st, int m) cdrom_drive_t *cdd = NULL; int last_track; - if (m != STREAM_READ) { - return STREAM_UNSUPPORTED; - } - if (!p->device) { if (cdrom_device) p->device = talloc_strdup(NULL, cdrom_device); diff --git a/stream/stream_dvb.c b/stream/stream_dvb.c index ba40c3afc3..cdf282d3ac 100644 --- a/stream/stream_dvb.c +++ b/stream/stream_dvb.c @@ -627,7 +627,7 @@ static int dvb_streaming_start(stream_t *stream, int tuner_type, char *progname) -static int dvb_open(stream_t *stream, int mode) +static int dvb_open(stream_t *stream) { // I don't force the file format bacause, although it's almost always TS, // there are some providers that stream an IP multicast with M$ Mpeg4 inside @@ -637,10 +637,6 @@ static int dvb_open(stream_t *stream, int mode) char *progname; int tuner_type = 0, i; - - if(mode != STREAM_READ) - return STREAM_UNSUPPORTED; - priv->fe_fd = priv->sec_fd = priv->dvr_fd = -1; priv->config = dvb_get_config(stream); if(priv->config == NULL) diff --git a/stream/stream_dvd.c b/stream/stream_dvd.c index c393915ffd..ae3ed09b5e 100644 --- a/stream/stream_dvd.c +++ b/stream/stream_dvd.c @@ -663,7 +663,7 @@ static int control(stream_t *stream,int cmd,void* arg) } -static int open_s(stream_t *stream, int mode) +static int open_s(stream_t *stream) { int k; dvd_priv_t *d = stream->priv; @@ -932,7 +932,7 @@ fail: return STREAM_UNSUPPORTED; } -static int ifo_stream_open (stream_t *stream, int mode) +static int ifo_stream_open (stream_t *stream) { char* filename; dvd_priv_t *priv = talloc_ptrtype(stream, priv); @@ -963,7 +963,7 @@ static int ifo_stream_open (stream_t *stream, int mode) free(filename); stream->url=talloc_strdup(stream, "dvd://"); - return open_s(stream, mode); + return open_s(stream); } const stream_info_t stream_info_dvd = { diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c index fdaf38e640..b438e7205c 100644 --- a/stream/stream_dvdnav.c +++ b/stream/stream_dvdnav.c @@ -664,7 +664,7 @@ static struct priv *new_dvdnav_stream(stream_t *stream, char *filename) return priv; } -static int open_s(stream_t *stream, int mode) +static int open_s(stream_t *stream) { struct priv *priv, *p; priv = p = stream->priv; diff --git a/stream/stream_edl.c b/stream/stream_edl.c index 8f9c5a90af..ac1e1f9406 100644 --- a/stream/stream_edl.c +++ b/stream/stream_edl.c @@ -3,11 +3,8 @@ #include "stream.h" -static int s_open (struct stream *stream, int mode) +static int s_open (struct stream *stream) { - if (mode != STREAM_READ) - return STREAM_ERROR; - stream->type = STREAMTYPE_EDL; stream->demuxer = "edl"; diff --git a/stream/stream_file.c b/stream/stream_file.c index 528cf1a6e3..a0ffc9114f 100644 --- a/stream/stream_file.c +++ b/stream/stream_file.c @@ -204,7 +204,7 @@ static bool check_stream_network(stream_t *stream) } #endif -static int open_f(stream_t *stream, int mode) +static int open_f(stream_t *stream) { int fd; struct priv *priv = talloc_ptrtype(stream, priv); @@ -213,15 +213,8 @@ static int open_f(stream_t *stream, int mode) }; stream->priv = priv; - int m = O_CLOEXEC; - if (mode == STREAM_READ) - m |= O_RDONLY; - else if (mode == STREAM_WRITE) - m |= O_RDWR | O_CREAT | O_TRUNC; - else { - MP_ERR(stream, "Unknown open mode %d\n", mode); - return STREAM_UNSUPPORTED; - } + bool write = stream->mode == STREAM_WRITE; + int m = O_CLOEXEC | (write ? O_RDWR | O_CREAT | O_TRUNC : O_RDONLY); char *filename = mp_file_url_to_filename(stream, bstr0(stream->url)); if (filename) { @@ -231,7 +224,7 @@ static int open_f(stream_t *stream, int mode) } if (!strcmp(filename, "-")) { - if (mode == STREAM_READ) { + if (!write) { MP_INFO(stream, "Reading from stdin...\n"); fd = 0; #if HAVE_SETMODE @@ -301,4 +294,5 @@ const stream_info_t stream_info_file = { .name = "file", .open = open_f, .protocols = (const char*[]){ "file", "", NULL }, + .can_write = true, }; diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c index c8281ea389..b8f90cc9b1 100644 --- a/stream/stream_lavf.c +++ b/stream/stream_lavf.c @@ -32,7 +32,7 @@ #include "bstr/bstr.h" #include "talloc.h" -static int open_f(stream_t *stream, int mode); +static int open_f(stream_t *stream); static char **read_icy(stream_t *stream); static int fill_buffer(stream_t *s, char *buffer, int max_len) @@ -113,7 +113,7 @@ static int control(stream_t *s, int cmd, void *arg) // avio doesn't seem to support this - emulate it by reopening close_f(s); s->priv = NULL; - return open_f(s, STREAM_READ); + return open_f(s); } } return STREAM_UNSUPPORTED; @@ -127,10 +127,9 @@ static int interrupt_cb(void *ctx) static const char * const prefix[] = { "lavf://", "ffmpeg://" }; -static int open_f(stream_t *stream, int mode) +static int open_f(stream_t *stream) { struct MPOpts *opts = stream->opts; - int flags = 0; AVIOContext *avio = NULL; int res = STREAM_ERROR; AVDictionary *dict = NULL; @@ -139,15 +138,7 @@ static int open_f(stream_t *stream, int mode) stream->seek = NULL; stream->seekable = false; - if (mode == STREAM_READ) - flags = AVIO_FLAG_READ; - else if (mode == STREAM_WRITE) - flags = AVIO_FLAG_WRITE; - else { - MP_ERR(stream, "Unknown open mode %d\n", mode); - res = STREAM_UNSUPPORTED; - goto out; - } + int flags = stream->mode == STREAM_WRITE ? AVIO_FLAG_WRITE : AVIO_FLAG_READ; const char *filename = stream->url; if (!filename) { @@ -330,4 +321,5 @@ const stream_info_t stream_info_ffmpeg = { "rtmpt", "rtmpte", "rtmpts", "srtp", "tcp", "udp", "tls", "unix", "sftp", "md5", NULL }, + .can_write = true, }; diff --git a/stream/stream_memory.c b/stream/stream_memory.c index df01d2956e..b748c9264c 100644 --- a/stream/stream_memory.c +++ b/stream/stream_memory.c @@ -55,7 +55,7 @@ static int control(stream_t *s, int cmd, void *arg) return STREAM_UNSUPPORTED; } -static int open_f(stream_t *stream, int mode) +static int open_f(stream_t *stream) { stream->fill_buffer = fill_buffer; stream->seek = seek; diff --git a/stream/stream_mf.c b/stream/stream_mf.c index a42fa29c0a..05c5bb60bd 100644 --- a/stream/stream_mf.c +++ b/stream/stream_mf.c @@ -29,7 +29,7 @@ #include "stream.h" static int -mf_stream_open (stream_t *stream, int mode) +mf_stream_open (stream_t *stream) { stream->type = STREAMTYPE_MF; stream->demuxer = "mf"; diff --git a/stream/stream_null.c b/stream/stream_null.c index c9a0a430e2..8fca1282a5 100644 --- a/stream/stream_null.c +++ b/stream/stream_null.c @@ -25,14 +25,14 @@ #include "stream.h" -static int open_s(stream_t *stream,int mode) +static int open_s(stream_t *stream) { return 1; } - const stream_info_t stream_info_null = { .name = "null", .open = open_s, .protocols = (const char*[]){ "null", NULL }, + .can_write = true, }; diff --git a/stream/stream_pvr.c b/stream/stream_pvr.c index 8b5251cb06..e45c9005a1 100644 --- a/stream/stream_pvr.c +++ b/stream/stream_pvr.c @@ -1510,15 +1510,12 @@ pvr_stream_read (stream_t *stream, char *buffer, int size) } static int -pvr_stream_open (stream_t *stream, int mode) +pvr_stream_open (stream_t *stream) { struct v4l2_capability vcap; struct v4l2_ext_controls ctrls; struct pvr_t *pvr = NULL; - if (mode != STREAM_READ) - return STREAM_UNSUPPORTED; - pvr = pvr_init (); pvr->log = stream->log; diff --git a/stream/stream_rar.c b/stream/stream_rar.c index 24687523e2..d40a8ca545 100644 --- a/stream/stream_rar.c +++ b/stream/stream_rar.c @@ -86,7 +86,7 @@ static int rar_entry_control(stream_t *s, int cmd, void *arg) return STREAM_UNSUPPORTED; } -static int rar_entry_open(stream_t *stream, int mode) +static int rar_entry_open(stream_t *stream) { if (!strchr(stream->path, '|')) return STREAM_ERROR; @@ -158,11 +158,8 @@ static void rar_filter_close(stream_t *s) free_stream(m); } -static int rar_filter_open(stream_t *stream, int mode) +static int rar_filter_open(stream_t *stream) { - if (mode != STREAM_READ) - return STREAM_UNSUPPORTED; - struct stream *rar = stream->source; if (!rar) return STREAM_UNSUPPORTED; diff --git a/stream/stream_smb.c b/stream/stream_smb.c index 6b79d072dd..e39c758fdf 100644 --- a/stream/stream_smb.c +++ b/stream/stream_smb.c @@ -87,10 +87,9 @@ static void close_f(stream_t *s){ smbc_close(p->fd); } -static int open_f (stream_t *stream, int mode) +static int open_f (stream_t *stream) { char *filename; - mode_t m = 0; int64_t len; int fd, err; @@ -99,14 +98,7 @@ static int open_f (stream_t *stream, int mode) filename = stream->url; - if(mode == STREAM_READ) - m = O_RDONLY; - else if (mode == STREAM_WRITE) //who's gonna do that ? - m = O_RDWR|O_CREAT|O_TRUNC; - else { - MP_ERR(stream, "[smb] Unknown open mode %d\n", mode); - return STREAM_UNSUPPORTED; - } + mode_t m = stream->mode == STREAM_WRITE ? O_RDWR|O_CREAT|O_TRUNC : O_RDONLY; if(!filename) { MP_ERR(stream, "[smb] Bad url\n"); @@ -149,4 +141,5 @@ const stream_info_t stream_info_smb = { .name = "smb", .open = open_f, .protocols = (const char*[]){"smb", NULL}, + .can_write = true, //who's gonna do that? }; diff --git a/stream/stream_tv.c b/stream/stream_tv.c index 3bd18c3ffa..e54fe4bded 100644 --- a/stream/stream_tv.c +++ b/stream/stream_tv.c @@ -86,7 +86,7 @@ tv_stream_close (stream_t *stream) { } static int -tv_stream_open (stream_t *stream, int mode) +tv_stream_open (stream_t *stream) { stream->type = STREAMTYPE_TV; diff --git a/stream/stream_vcd.c b/stream/stream_vcd.c index 23b95cf3c6..0ea8f7dabe 100644 --- a/stream/stream_vcd.c +++ b/stream/stream_vcd.c @@ -78,7 +78,7 @@ static void close_s(stream_t *stream) { free(stream->priv); } -static int open_s(stream_t *stream,int mode) +static int open_s(stream_t *stream) { int ret,ret2,f,sect,tmp; mp_vcd_priv_t* vcd; @@ -90,14 +90,6 @@ static int open_s(stream_t *stream,int mode) char device[20] = "\\\\.\\?:"; #endif - if(mode != STREAM_READ -#if defined(__MINGW32__) || defined(__CYGWIN__) - || GetVersion() > 0x80000000 // Win9x -#endif - ) { - return STREAM_UNSUPPORTED; - } - char *dev = stream->url; if (strncmp("vcd://", dev, 6) != 0) return STREAM_UNSUPPORTED; -- cgit v1.2.3