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 --- Makefile | 4 +- stream/stream.c | 4 ++ stream/stream_ffmpeg.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 stream/stream_ffmpeg.c diff --git a/Makefile b/Makefile index f87017e2f5..438e0bddec 100644 --- a/Makefile +++ b/Makefile @@ -144,7 +144,9 @@ SRCS_COMMON-$(LIBAVCODEC_A) += libaf/af_lavcac3enc.c \ libmpcodecs/vf_spp.c \ libmpcodecs/vf_uspp.c \ -SRCS_COMMON-$(LIBAVFORMAT) += libmpdemux/demux_lavf.c +SRCS_COMMON-$(LIBAVFORMAT) += libmpdemux/demux_lavf.c \ + stream/stream_ffmpeg.c \ + SRCS_COMMON-$(LIBBS2B) += libaf/af_bs2b.c SRCS_COMMON-$(LIBDCA) += libmpcodecs/ad_libdca.c SRCS_COMMON-$(LIBDV) += libmpcodecs/ad_libdv.c \ 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