summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-12-10 01:28:20 +0100
committerwm4 <wm4@nowhere>2012-12-11 00:37:54 +0100
commit180944fe282fb57be4d8f986f7fcb0a209f943d5 (patch)
tree0a25fd0b88429c57f54019deb2d9801bf51c0224
parent222a5cf7c0a4de094f368f7154122a72312dbf39 (diff)
downloadmpv-180944fe282fb57be4d8f986f7fcb0a209f943d5.tar.bz2
mpv-180944fe282fb57be4d8f986f7fcb0a209f943d5.tar.xz
stream_lavf/demux_lavf: export/use HTTP MIME type
This is a fix for web radio streams that send raw AAC [1]. libavformat's AAC demuxer probe is picky enough to request hundreds of KBs data, which makes for a slow startup. To speed up stream startup, try use the HTTP MIME type to identify the format. The webstream in question sends an AAC specific MIME type, for which demux_lavf will force the AAC demuxer, without probing anything. ffmpeg/ffplay do the same thing. Note that as of ffmpeg commit 76d851b, av_probe_input_buffer() does the mapping from MIME type to demuxer. The actual mapping is not publicly accessible, and can only be used by calling that function. This will hopefully be rectified, and ideally ffmpeg would provide a function like find_demuxer_from_mime_type(). [1] http://lr2mp0.latvijasradio.lv:8000
-rw-r--r--demux/demux_lavf.c17
-rw-r--r--stream/stream.c18
-rw-r--r--stream/stream.h1
-rw-r--r--stream/stream_lavf.c13
4 files changed, 34 insertions, 15 deletions
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 7fa849f3a1..b3ae1d6315 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -83,8 +83,23 @@ typedef struct lavf_priv {
bool use_dts;
bool seek_by_bytes;
int bitrate;
+ char *mime_type;
} lavf_priv_t;
+static const char *map_demuxer_mime_type[][2] = {
+ {"audio/aacp", "aac"},
+ {0}
+};
+
+static const char *find_demuxer_from_mime_type(char *mime_type)
+{
+ for (int n = 0; map_demuxer_mime_type[n][0]; n++) {
+ if (strcasecmp(map_demuxer_mime_type[n][0], mime_type) == 0)
+ return map_demuxer_mime_type[n][1];
+ }
+ return NULL;
+}
+
static int mp_read(void *opaque, uint8_t *buf, int size)
{
struct demuxer *demuxer = opaque;
@@ -207,6 +222,8 @@ static int lavf_check_file(demuxer_t *demuxer)
format = demuxer->stream->lavf_type;
if (!format)
format = avdevice_format;
+ if (!format && demuxer->stream->mime_type)
+ format = (char *)find_demuxer_from_mime_type(demuxer->stream->mime_type);
if (format) {
if (strcmp(format, "help") == 0) {
list_formats();
diff --git a/stream/stream.c b/stream/stream.c
index 6e0644e59c..d7ab7a751a 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -179,7 +179,7 @@ static stream_t *open_stream_plugin(const stream_info_t *sinfo,
streaming_ctrl_free(s->streaming_ctrl);
#endif
free(s->url);
- free(s);
+ talloc_free(s);
return NULL;
}
@@ -202,6 +202,9 @@ static stream_t *open_stream_plugin(const stream_info_t *sinfo,
mp_msg(MSGT_OPEN,MSGL_V, "STREAM: Author: %s\n", sinfo->author);
mp_msg(MSGT_OPEN,MSGL_V, "STREAM: Comment: %s\n", sinfo->comment);
+ if (s->mime_type)
+ mp_msg(MSGT_OPEN, MSGL_V, "Mime-type: '%s'\n", s->mime_type);
+
return s;
}
@@ -510,8 +513,7 @@ stream_t* new_memory_stream(unsigned char* data,int len){
}
stream_t* new_stream(int fd,int type){
- stream_t *s=calloc(1, sizeof(stream_t));
- if(s==NULL) return NULL;
+ stream_t *s=talloc_zero(NULL, stream_t);
#if HAVE_WINSOCK2_H
{
@@ -523,11 +525,6 @@ stream_t* new_stream(int fd,int type){
s->fd=fd;
s->type=type;
- s->buf_pos=s->buf_len=0;
- s->start_pos=s->end_pos=0;
- s->priv=NULL;
- s->url=NULL;
- s->cache_pid=0;
stream_reset(s);
return s;
}
@@ -551,11 +548,8 @@ void free_stream(stream_t *s){
mp_msg(MSGT_STREAM,MSGL_V,"WINSOCK2 uninit\n");
WSACleanup(); // there might be a better place for this (-> later)
#endif
- // Disabled atm, i don't like that. s->priv can be anything after all
- // streams should destroy their priv on close
- //free(s->priv);
free(s->url);
- free(s);
+ talloc_free(s);
}
stream_t* new_ds_stream(demux_stream_t *ds) {
diff --git a/stream/stream.h b/stream/stream.h
index ebab587f03..43980197e7 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -175,6 +175,7 @@ typedef struct stream {
void* cache_data;
void* priv; // used for DVD, TV, RTSP etc
char* url; // strdup() of filename/url
+ char *mime_type; // when HTTP streaming is used
char *lavf_type; // name of expected demuxer type for lavf
struct MPOpts *opts;
streaming_ctrl_t *streaming_ctrl;
diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c
index a3268c10ae..4dae59c2c0 100644
--- a/stream/stream_lavf.c
+++ b/stream/stream_lavf.c
@@ -16,10 +16,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "config.h"
+#include <libavformat/avformat.h>
+#include <libavformat/avio.h>
+#include <libavutil/opt.h>
-#include "libavformat/avformat.h"
-#include "libavformat/avio.h"
+#include "config.h"
#include "core/mp_msg.h"
#include "stream.h"
#include "core/m_option.h"
@@ -139,6 +140,12 @@ static int open_f(stream_t *stream, int mode, void *opts, int *file_format)
if (avio_open(&avio, filename, flags) < 0)
goto out;
+ if (avio->av_class) {
+ uint8_t *mt = NULL;
+ if (av_opt_get(avio, "mime_type", AV_OPT_SEARCH_CHILDREN, &mt) >= 0)
+ stream->mime_type = talloc_strdup(stream, mt);
+ }
+
char *rtmp[] = {"rtmp:", "rtmpt:", "rtmpe:", "rtmpte:", "rtmps:"};
for (int i = 0; i < FF_ARRAY_ELEMS(rtmp); i++)
if (!strncmp(filename, rtmp[i], strlen(rtmp[i]))) {