summaryrefslogtreecommitdiffstats
path: root/demux/demux_lavf.c
diff options
context:
space:
mode:
Diffstat (limited to 'demux/demux_lavf.c')
-rw-r--r--demux/demux_lavf.c70
1 files changed, 45 insertions, 25 deletions
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index ad4f521052..9cf36207a3 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -64,6 +64,7 @@ const m_option_t lavfdopts_conf[] = {
#define BIO_BUFFER_SIZE 32768
typedef struct lavf_priv {
+ char *filename;
AVInputFormat *avif;
AVFormatContext *avfc;
AVIOContext *pb;
@@ -151,6 +152,19 @@ static void list_formats(void)
mp_msg(MSGT_DEMUX, MSGL_INFO, "%15s : %s\n", fmt->name, fmt->long_name);
}
+static char *remove_prefix(char *s, const char **prefixes)
+{
+ for (int n = 0; prefixes[n]; n++) {
+ int len = strlen(prefixes[n]);
+ if (strncmp(s, prefixes[n], len) == 0)
+ return s + len;
+ }
+ return s;
+}
+
+static const char *prefixes[] =
+ {"ffmpeg://", "lavf://", "avdevice://", "av://", NULL};
+
static int lavf_check_file(demuxer_t *demuxer)
{
struct MPOpts *opts = demuxer->opts;
@@ -162,13 +176,37 @@ static int lavf_check_file(demuxer_t *demuxer)
int score;
if (!demuxer->priv)
- demuxer->priv = calloc(sizeof(lavf_priv_t), 1);
+ demuxer->priv = talloc_zero(NULL, lavf_priv_t);
priv = demuxer->priv;
priv->autoselect_sub = -1;
+ priv->filename = demuxer->stream->url;
+ if (!priv->filename) {
+ priv->filename = "mp:unknown";
+ mp_msg(MSGT_DEMUX, MSGL_WARN, "Stream url is not set!\n");
+ }
+
+ priv->filename = remove_prefix(priv->filename, prefixes);
+
+ char *avdevice_format = NULL;
+ if (demuxer->stream->type == STREAMTYPE_AVDEVICE) {
+ // always require filename in the form "format:filename"
+ char *sep = strchr(priv->filename, ':');
+ if (!sep) {
+ mp_msg(MSGT_DEMUX, MSGL_FATAL,
+ "Must specify filename in 'format:filename' form\n");
+ return 0;
+ }
+ avdevice_format = talloc_strndup(priv, priv->filename,
+ sep - priv->filename);
+ priv->filename = sep + 1;
+ }
+
char *format = lavfdopts->format;
if (!format)
format = demuxer->stream->lavf_type;
+ if (!format)
+ format = avdevice_format;
if (format) {
if (strcmp(format, "help") == 0) {
list_formats();
@@ -194,14 +232,7 @@ static int lavf_check_file(demuxer_t *demuxer)
return 0;
}
probe_data_size += read_size;
- avpd.filename = demuxer->stream->url;
- if (!avpd.filename) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "Stream url is not set!\n");
- avpd.filename = "";
- }
- if (!strncmp(avpd.filename, "ffmpeg://", 9) ||
- !strncmp(avpd.filename, "lavf://", 7))
- avpd.filename += 9;
+ avpd.filename = priv->filename;
avpd.buf_size = probe_data_size;
score = 0;
@@ -619,20 +650,9 @@ static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
}
}
- char *filename = demuxer->stream->url;
-
- if (filename) {
- if (demuxer->stream->lavf_type && !strcmp(demuxer->stream->lavf_type,
- "rtsp")) {
- // Remove possible leading ffmpeg:// or lavf://
- char *name = strstr(filename, "rtsp:");
- if (name)
- filename = name;
- }
- } else
- filename = "mp:unknown";
-
- if (!(priv->avif->flags & AVFMT_NOFILE)) {
+ if (!(priv->avif->flags & AVFMT_NOFILE) &&
+ demuxer->stream->type != STREAMTYPE_AVDEVICE)
+ {
priv->pb = avio_alloc_context(priv->buffer, BIO_BUFFER_SIZE, 0,
demuxer, mp_read, NULL, mp_seek);
priv->pb->read_seek = mp_read_seek;
@@ -642,7 +662,7 @@ static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
avfc->pb = priv->pb;
}
- if (avformat_open_input(&avfc, filename, priv->avif, NULL) < 0) {
+ if (avformat_open_input(&avfc, priv->filename, priv->avif, NULL) < 0) {
mp_msg(MSGT_HEADER, MSGL_ERR,
"LAVF_header: avformat_open_input() failed\n");
return NULL;
@@ -1047,7 +1067,7 @@ static void demux_close_lavf(demuxer_t *demuxer)
avformat_close_input(&priv->avfc);
}
av_freep(&priv->pb);
- free(priv);
+ talloc_free(priv);
demuxer->priv = NULL;
}
}