From 58301405824924a8e81017c144338d86ca28eba4 Mon Sep 17 00:00:00 2001 From: reimar Date: Tue, 17 Nov 2009 16:09:17 +0000 Subject: Add preliminary support for streaming via FFmpeg's URProtocol functions. Basic playback tested for file and http protocols. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29923 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/stream.c | 4 ++ stream/stream_ffmpeg.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 stream/stream_ffmpeg.c (limited to 'stream') diff --git a/stream/stream.c b/stream/stream.c index 6a3dd2bc87..c498eb3624 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -58,6 +58,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; @@ -112,6 +113,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, diff --git a/stream/stream_ffmpeg.c b/stream/stream_ffmpeg.c new file mode 100644 index 0000000000..c7a4dde541 --- /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; + if (ctx->is_streamed) { + stream->type = STREAMTYPE_STREAM; + stream->flags |= STREAM_SEEK_FW; + } + stream->seek = seek; + 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 +}; -- cgit v1.2.3 From 00ef6412f47ebe1e841633134982fe2c9f5ff2f1 Mon Sep 17 00:00:00 2001 From: reimar Date: Tue, 17 Nov 2009 18:05:54 +0000 Subject: Use fill_buffer if available also for STREAMTYPE_STREAM git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29925 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/stream.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'stream') diff --git a/stream/stream.c b/stream/stream.c index c498eb3624..7fc7ca2315 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -254,6 +254,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: -- cgit v1.2.3 From dc19e32d67d04703798755b403fe9e642783e29b Mon Sep 17 00:00:00 2001 From: reimar Date: Tue, 17 Nov 2009 18:08:18 +0000 Subject: Enable the read-based forward seek fallback also when CONFIG_NETWORK is enabled. Enabling network support should not have side-effects on code not really related to networking. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29926 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/stream.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'stream') diff --git a/stream/stream.c b/stream/stream.c index 7fc7ca2315..4ee7f8b316 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -331,8 +331,9 @@ if(newpos==0 || newpos!=s->pos){ mp_msg(MSGT_STREAM,MSGL_INFO,"Stream not seekable!\n"); return 1; } + break; } -#else +#endif if(newpospos){ mp_msg(MSGT_STREAM,MSGL_INFO,"Cannot seek backward in linear streams!\n"); return 1; @@ -340,7 +341,6 @@ if(newpos==0 || newpos!=s->pos){ while(s->pos Date: Tue, 17 Nov 2009 18:30:33 +0000 Subject: Fall back to read-based seeking for ffmpeg:// URLs when is_streamed is set (i.e. it is not possible to use url_fseek). git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29928 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/stream_ffmpeg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'stream') diff --git a/stream/stream_ffmpeg.c b/stream/stream_ffmpeg.c index c7a4dde541..c681dc2c88 100644 --- a/stream/stream_ffmpeg.c +++ b/stream/stream_ffmpeg.c @@ -112,11 +112,11 @@ static int open_f(stream_t *stream, int mode, void *opts, int *file_format) if (size >= 0) stream->end_pos = size; stream->type = STREAMTYPE_FILE; + stream->seek = seek; if (ctx->is_streamed) { stream->type = STREAMTYPE_STREAM; - stream->flags |= STREAM_SEEK_FW; + stream->seek = NULL; } - stream->seek = seek; stream->fill_buffer = fill_buffer; stream->write_buffer = write_buffer; stream->control = control; -- cgit v1.2.3 From a81e043f98d79f1e0a47210a0f82062e8b5dbcca Mon Sep 17 00:00:00 2001 From: reimar Date: Tue, 17 Nov 2009 19:14:42 +0000 Subject: Merge malloc+memset -> calloc git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29929 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/stream.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'stream') diff --git a/stream/stream.c b/stream/stream.c index 4ee7f8b316..072e9d0a89 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -396,8 +396,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; @@ -409,9 +408,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 { -- cgit v1.2.3 From e02a2e7f08a87f2147a149a9a66992965e219fce Mon Sep 17 00:00:00 2001 From: reimar Date: Tue, 17 Nov 2009 19:23:55 +0000 Subject: Deobfuscate the special hack to disable cache for live555. Cache can not be used for it, since it does not provide any data stream, the data is provided to the demuxer "behind MPlayer's back". git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29930 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/cache2.c | 3 +-- stream/stream.h | 4 ++++ stream/stream_live555.c | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) (limited to 'stream') diff --git a/stream/cache2.c b/stream/cache2.c index acdb111f0b..5d2e69d82f 100644 --- a/stream/cache2.c +++ b/stream/cache2.c @@ -311,8 +311,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/stream.h b/stream/stream.h index 2bbe443757..4aed24526a 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -41,6 +41,10 @@ #define STREAM_SEEK_BW 2 #define STREAM_SEEK_FW 4 #define STREAM_SEEK (STREAM_SEEK_BW|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 diff --git a/stream/stream_live555.c b/stream/stream_live555.c index 619a8d90af..c36c9ff33a 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_NONCACHEABLE; return STREAM_OK; fail: -- cgit v1.2.3 From e775bdd70d274834780b02548f2d525f71116f98 Mon Sep 17 00:00:00 2001 From: cehoyos Date: Wed, 18 Nov 2009 09:13:09 +0000 Subject: 10l to Reimar: Fix typo. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29931 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/stream_live555.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'stream') diff --git a/stream/stream_live555.c b/stream/stream_live555.c index c36c9ff33a..8165899e94 100644 --- a/stream/stream_live555.c +++ b/stream/stream_live555.c @@ -44,7 +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_NONCACHEABLE; + stream->flags = STREAM_NON_CACHEABLE; return STREAM_OK; fail: -- cgit v1.2.3 From af2988cbcef1b057772d44b9f9752be3f15960b0 Mon Sep 17 00:00:00 2001 From: reimar Date: Sun, 22 Nov 2009 15:18:21 +0000 Subject: Finally rename the STREAM_SEEK define to MP_STREAM_SEEK, there are just too many name clashes, in particular with Windows headers (which define STREAM_SEEK as an enum type). git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29962 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/http.c | 2 +- stream/stream.c | 8 ++++---- stream/stream.h | 10 +++++----- stream/stream_cue.c | 2 +- stream/stream_dvd.c | 2 +- stream/stream_dvdnav.c | 2 +- stream/stream_file.c | 2 +- stream/stream_netstream.c | 2 +- stream/stream_smb.c | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) (limited to 'stream') 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 072e9d0a89..ed41b3e93a 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -174,10 +174,10 @@ stream_t* open_stream_plugin(const stream_info_t* sinfo,char* filename,int mode, } 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; diff --git a/stream/stream.h b/stream/stream.h index 4aed24526a..4da8a1ae43 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -37,10 +37,10 @@ #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 */ @@ -276,7 +276,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 ea9337afb1..53cb01299b 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 46e7100ec1..a9b377a340 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 9962c0606f..1d74504fa5 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_file.c b/stream/stream_file.c index e113e6788e..9a4d7a3500 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_netstream.c b/stream/stream_netstream.c index ea410c41e7..c0a80689df 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 17ba027687..86bb3f84b0 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; } -- cgit v1.2.3