diff options
author | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2009-11-23 01:56:21 +0200 |
---|---|---|
committer | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2009-11-23 01:56:21 +0200 |
commit | 5995bc175aea0417ce7ff7285c1c8fc84ebb5704 (patch) | |
tree | 7fa0b90e03fc5b3a6447b79754b654bc279f5237 /stream | |
parent | 4c552b2e420ba4cb6d888b12360c7bf63e7cd03a (diff) | |
parent | af2988cbcef1b057772d44b9f9752be3f15960b0 (diff) |
Merge svn changes up to r29962
Diffstat (limited to 'stream')
-rw-r--r-- | stream/cache2.c | 3 | ||||
-rw-r--r-- | stream/http.c | 2 | ||||
-rw-r--r-- | stream/stream.c | 25 | ||||
-rw-r--r-- | stream/stream.h | 14 | ||||
-rw-r--r-- | stream/stream_cue.c | 2 | ||||
-rw-r--r-- | stream/stream_dvd.c | 2 | ||||
-rw-r--r-- | stream/stream_dvdnav.c | 2 | ||||
-rw-r--r-- | stream/stream_ffmpeg.c | 140 | ||||
-rw-r--r-- | stream/stream_file.c | 2 | ||||
-rw-r--r-- | stream/stream_live555.c | 1 | ||||
-rw-r--r-- | stream/stream_netstream.c | 2 | ||||
-rw-r--r-- | stream/stream_smb.c | 2 |
12 files changed, 173 insertions, 24 deletions
diff --git a/stream/cache2.c b/stream/cache2.c index 78acdc9845..4c9bdf8aec 100644 --- a/stream/cache2.c +++ b/stream/cache2.c @@ -307,8 +307,7 @@ 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; cache_vars_t* s; - if (stream->type==STREAMTYPE_STREAM && stream->fd < 0) { - // The stream has no 'fd' behind it, so is non-cacheable + if (stream->flags & STREAM_NON_CACHEABLE) { mp_msg(MSGT_CACHE,MSGL_STATUS,"\rThis stream is non-cacheable\n"); return 1; } diff --git a/stream/http.c b/stream/http.c index 498e40473c..3ebfe03d05 100644 --- a/stream/http.c +++ b/stream/http.c @@ -891,7 +891,7 @@ static int fixup_open(stream_t *stream,int seekable) { stream->type = STREAMTYPE_STREAM; if(!is_icy && !is_ultravox && seekable) { - stream->flags |= STREAM_SEEK; + stream->flags |= MP_STREAM_SEEK; stream->seek = http_seek; } stream->streaming_ctrl->bandwidth = network_bandwidth; diff --git a/stream/stream.c b/stream/stream.c index 8570f0b125..713d766d93 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -60,6 +60,7 @@ extern const stream_info_t stream_info_rtsp_sip; extern const stream_info_t stream_info_cue; extern const stream_info_t stream_info_null; extern const stream_info_t stream_info_mf; +extern const stream_info_t stream_info_ffmpeg; extern const stream_info_t stream_info_file; extern const stream_info_t stream_info_ifo; extern const stream_info_t stream_info_dvd; @@ -114,6 +115,9 @@ static const stream_info_t* const auto_open_streams[] = { #ifdef CONFIG_DVDNAV &stream_info_dvdnav, #endif +#ifdef CONFIG_LIBAVFORMAT + &stream_info_ffmpeg, +#endif &stream_info_null, &stream_info_mf, @@ -165,10 +169,10 @@ static stream_t *open_stream_plugin(const stream_info_t *sinfo, char *filename, } if(s->type <= -2) mp_msg(MSGT_OPEN,MSGL_WARN, "Warning streams need a type !!!!\n"); - if(s->flags & STREAM_SEEK && !s->seek) - s->flags &= ~STREAM_SEEK; - if(s->seek && !(s->flags & STREAM_SEEK)) - s->flags |= STREAM_SEEK; + if(s->flags & MP_STREAM_SEEK && !s->seek) + s->flags &= ~MP_STREAM_SEEK; + if(s->seek && !(s->flags & MP_STREAM_SEEK)) + s->flags |= MP_STREAM_SEEK; s->mode = mode; @@ -248,6 +252,9 @@ int stream_fill_buffer(stream_t *s){ len=s->streaming_ctrl->streaming_read(s->fd,s->buffer,STREAM_BUFFER_SIZE, s->streaming_ctrl); } else #endif + if (s->fill_buffer) + len = s->fill_buffer(s, s->buffer, STREAM_BUFFER_SIZE); + else len=read(s->fd,s->buffer,STREAM_BUFFER_SIZE); break; case STREAMTYPE_DS: @@ -322,8 +329,9 @@ if(newpos==0 || newpos!=s->pos){ mp_msg(MSGT_STREAM,MSGL_INFO,"Stream not seekable!\n"); return 1; } + break; } -#else +#endif if(newpos<s->pos){ mp_msg(MSGT_STREAM,MSGL_INFO,"Cannot seek backward in linear streams!\n"); return 1; @@ -331,7 +339,6 @@ if(newpos==0 || newpos!=s->pos){ while(s->pos<newpos){ if(stream_fill_buffer(s)<=0) break; // EOF } -#endif break; default: // This should at the beginning as soon as all streams are converted @@ -387,8 +394,7 @@ stream_t* new_memory_stream(unsigned char* data,int len){ if(len < 0) return NULL; - s=malloc(sizeof(stream_t)+len); - memset(s,0,sizeof(stream_t)); + s=calloc(1, sizeof(stream_t)+len); s->fd=-1; s->type=STREAMTYPE_MEMORY; s->buf_pos=0; s->buf_len=len; @@ -400,9 +406,8 @@ stream_t* new_memory_stream(unsigned char* data,int len){ } stream_t* new_stream(int fd,int type){ - stream_t *s=malloc(sizeof(stream_t)); + stream_t *s=calloc(1, sizeof(stream_t)); if(s==NULL) return NULL; - memset(s,0,sizeof(stream_t)); #if HAVE_WINSOCK2_H { diff --git a/stream/stream.h b/stream/stream.h index 51dbbc925c..b3b5e8f4c3 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -37,10 +37,14 @@ #define STREAM_READ 0 #define STREAM_WRITE 1 /// Seek flags, if not mannualy set and s->seek isn't NULL -/// STREAM_SEEK is automaticly set -#define STREAM_SEEK_BW 2 -#define STREAM_SEEK_FW 4 -#define STREAM_SEEK (STREAM_SEEK_BW|STREAM_SEEK_FW) +/// MP_STREAM_SEEK is automaticly set +#define MP_STREAM_SEEK_BW 2 +#define MP_STREAM_SEEK_FW 4 +#define MP_STREAM_SEEK (MP_STREAM_SEEK_BW|MP_STREAM_SEEK_FW) +/** This is a HACK for live555 that does not respect the + separation between stream an demuxer and thus is not + actually a stream cache can not be used */ +#define STREAM_NON_CACHEABLE 8 //////////// Open return code #define STREAM_REDIRECTED -2 @@ -273,7 +277,7 @@ inline static int stream_seek(stream_t *s,off_t pos){ } inline static int stream_skip(stream_t *s,off_t len){ - if( (len<0 && (s->flags & STREAM_SEEK_BW)) || (len>2*STREAM_BUFFER_SIZE && (s->flags & STREAM_SEEK_FW)) ) { + if( (len<0 && (s->flags & MP_STREAM_SEEK_BW)) || (len>2*STREAM_BUFFER_SIZE && (s->flags & MP_STREAM_SEEK_FW)) ) { // negative or big skip! return stream_seek(s,stream_tell(s)+len); } diff --git a/stream/stream_cue.c b/stream/stream_cue.c index ac1bdfc4f4..fb8b869f76 100644 --- a/stream/stream_cue.c +++ b/stream/stream_cue.c @@ -578,7 +578,7 @@ static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { stream->fd = f; stream->type = STREAMTYPE_VCDBINCUE; stream->sector_size = VCD_SECTOR_DATA; - stream->flags = STREAM_READ | STREAM_SEEK_FW; + stream->flags = STREAM_READ | MP_STREAM_SEEK_FW; stream->start_pos = ret; stream->end_pos = ret2; stream->fill_buffer = cue_vcd_read; diff --git a/stream/stream_dvd.c b/stream/stream_dvd.c index 36a8b07d05..b5894c6c13 100644 --- a/stream/stream_dvd.c +++ b/stream/stream_dvd.c @@ -978,7 +978,7 @@ static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { // return NULL; stream->type = STREAMTYPE_DVD; stream->sector_size = 2048; - stream->flags = STREAM_READ | STREAM_SEEK; + stream->flags = STREAM_READ | MP_STREAM_SEEK; stream->fill_buffer = fill_buffer; stream->seek = seek; stream->control = control; diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c index 3f419dfb65..117b918260 100644 --- a/stream/stream_dvdnav.c +++ b/stream/stream_dvdnav.c @@ -596,7 +596,7 @@ static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { dvdnav_angle_change(priv->dvdnav, dvd_angle); stream->sector_size = 2048; - stream->flags = STREAM_READ | STREAM_SEEK; + stream->flags = STREAM_READ | MP_STREAM_SEEK; stream->fill_buffer = fill_buffer; stream->seek = seek; stream->control = control; diff --git a/stream/stream_ffmpeg.c b/stream/stream_ffmpeg.c new file mode 100644 index 0000000000..c681dc2c88 --- /dev/null +++ b/stream/stream_ffmpeg.c @@ -0,0 +1,140 @@ +#include "config.h" + +#include "libavformat/avformat.h" +#include "libavformat/avio.h" +#include "mp_msg.h" +#include "stream.h" +#include "m_option.h" +#include "m_struct.h" + +static struct stream_priv_s { + char *filename; + char *filename2; +} stream_priv_dflts = { + NULL, NULL +}; + +#define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f) +/// URL definition +static const m_option_t stream_opts_fields[] = { + {"string", ST_OFF(filename), CONF_TYPE_STRING, 0, 0 ,0, NULL}, + {"filename", ST_OFF(filename2), CONF_TYPE_STRING, 0, 0 ,0, NULL}, + {NULL} +}; + +static const struct m_struct_st stream_opts = { + "ffmpeg", + sizeof(struct stream_priv_s), + &stream_priv_dflts, + stream_opts_fields +}; + +static int fill_buffer(stream_t *s, char *buffer, int max_len) +{ + int r = url_read_complete(s->priv, buffer, max_len); + return (r <= 0) ? -1 : r; +} + +static int write_buffer(stream_t *s, char *buffer, int len) +{ + int r = url_write(s->priv, buffer, len); + return (r <= 0) ? -1 : r; +} + +static int seek(stream_t *s, off_t newpos) +{ + s->pos = newpos; + if (url_seek(s->priv, s->pos, SEEK_SET) < 0) { + s->eof = 1; + return 0; + } + return 1; +} + +static int control(stream_t *s, int cmd, void *arg) +{ + int64_t size; + switch(cmd) { + case STREAM_CTRL_GET_SIZE: + size = url_filesize(s->priv); + if(size >= 0) { + *(off_t *)arg = size; + return 1; + } + } + return STREAM_UNSUPPORTED; +} + +static void close_f(stream_t *stream) +{ + url_close(stream->priv); +} + +static const char prefix[] = "ffmpeg://"; + +static int open_f(stream_t *stream, int mode, void *opts, int *file_format) +{ + int flags = 0; + const char *filename; + struct stream_priv_s *p = opts; + URLContext *ctx = NULL; + int res = STREAM_ERROR; + int64_t size; + + av_register_all(); + if (mode == STREAM_READ) + flags = URL_RDONLY; + else if (mode == STREAM_WRITE) + flags = URL_WRONLY; + else { + mp_msg(MSGT_OPEN, MSGL_ERR, "[ffmpeg] Unknown open mode %d\n", mode); + res = STREAM_UNSUPPORTED; + goto out; + } + + if (p->filename) + filename = p->filename; + else if (p->filename2) + filename = p->filename2; + else { + mp_msg(MSGT_OPEN, MSGL_ERR, "[ffmpeg] No URL\n"); + goto out; + } + if (!strncmp(filename, prefix, strlen(prefix))) + filename += strlen(prefix); + mp_msg(MSGT_OPEN, MSGL_V, "[ffmpeg] Opening %s\n", filename); + + if (url_open(&ctx, filename, flags) < 0) + goto out; + + stream->priv = ctx; + size = url_filesize(ctx); + if (size >= 0) + stream->end_pos = size; + stream->type = STREAMTYPE_FILE; + stream->seek = seek; + if (ctx->is_streamed) { + stream->type = STREAMTYPE_STREAM; + stream->seek = NULL; + } + stream->fill_buffer = fill_buffer; + stream->write_buffer = write_buffer; + stream->control = control; + stream->close = close_f; + res = STREAM_OK; + +out: + m_struct_free(&stream_opts,opts); + return res; +} + +const stream_info_t stream_info_ffmpeg = { + "FFmpeg", + "ffmpeg", + "", + "", + open_f, + { "ffmpeg", NULL }, + &stream_opts, + 1 // Urls are an option string +}; diff --git a/stream/stream_file.c b/stream/stream_file.c index 9514204a3b..e0b7780c5f 100644 --- a/stream/stream_file.c +++ b/stream/stream_file.c @@ -159,7 +159,7 @@ static int open_f(stream_t *stream,int mode, void* opts, int* file_format) { #endif if(mode == STREAM_READ) stream->seek = seek_forward; stream->type = STREAMTYPE_STREAM; // Must be move to STREAMTYPE_FILE - stream->flags |= STREAM_SEEK_FW; + stream->flags |= MP_STREAM_SEEK_FW; } else if(len >= 0) { stream->seek = seek; stream->end_pos = len; diff --git a/stream/stream_live555.c b/stream/stream_live555.c index 8d92134f5e..c3b61de5d4 100644 --- a/stream/stream_live555.c +++ b/stream/stream_live555.c @@ -44,6 +44,7 @@ static int open_live_rtsp_sip(stream_t *stream,int mode, void* opts, int* file_f *file_format = DEMUXER_TYPE_RTP; stream->type = STREAMTYPE_STREAM; + stream->flags = STREAM_NON_CACHEABLE; return STREAM_OK; fail: diff --git a/stream/stream_netstream.c b/stream/stream_netstream.c index 0d35462aaa..47d1baad89 100644 --- a/stream/stream_netstream.c +++ b/stream/stream_netstream.c @@ -279,7 +279,7 @@ static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { stream->fill_buffer = fill_buffer; stream->control = control; - if(stream->flags & STREAM_SEEK) + if(stream->flags & MP_STREAM_SEEK) stream->seek = seek; stream->close = close_s; diff --git a/stream/stream_smb.c b/stream/stream_smb.c index f1b11f8d9b..027640f921 100644 --- a/stream/stream_smb.c +++ b/stream/stream_smb.c @@ -138,7 +138,7 @@ static int open_f (stream_t *stream, int mode, void *opts, int* file_format) { smbc_lseek (fd, 0, SEEK_SET); } if(len > 0 || mode == STREAM_WRITE) { - stream->flags |= STREAM_SEEK; + stream->flags |= MP_STREAM_SEEK; stream->seek = seek; if(mode == STREAM_READ) stream->end_pos = len; } |