[vlc-commits] demux: hls: probe content
Francois Cartegnie
git at videolan.org
Thu May 9 17:41:08 CEST 2019
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Apr 23 14:34:37 2019 +0200| [dfe4aca1f22265115e07c501a77c870cfea4cd52] | committer: Francois Cartegnie
demux: hls: probe content
Solves issues when the server does not sends proper MIME
and the file does not match known extension.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=dfe4aca1f22265115e07c501a77c870cfea4cd52
---
modules/demux/adaptive/StreamFormat.cpp | 22 +++++++++++++++++++++-
modules/demux/adaptive/StreamFormat.hpp | 2 ++
modules/demux/adaptive/plumbing/Demuxer.cpp | 15 +++++++++++++--
3 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/modules/demux/adaptive/StreamFormat.cpp b/modules/demux/adaptive/StreamFormat.cpp
index c5f027df59..9a695c3c34 100644
--- a/modules/demux/adaptive/StreamFormat.cpp
+++ b/modules/demux/adaptive/StreamFormat.cpp
@@ -23,6 +23,8 @@
#endif
#include "StreamFormat.hpp"
+
+#include <vlc_common.h>
#include <algorithm>
using namespace adaptive;
@@ -66,7 +68,7 @@ StreamFormat::StreamFormat( const std::string &mimetype )
std::string mime = mimetype;
std::transform(mime.begin(), mime.end(), mime.begin(), ::tolower);
std::string::size_type pos = mime.find("/");
- formatid = UNSUPPORTED;
+ formatid = UNKNOWN;
if(pos != std::string::npos)
{
std::string tail = mime.substr(pos + 1);
@@ -83,6 +85,24 @@ StreamFormat::StreamFormat( const std::string &mimetype )
}
}
+StreamFormat::StreamFormat(const void *data_, size_t sz)
+{
+ const uint8_t *data = reinterpret_cast<const uint8_t *>(data_);
+ formatid = UNKNOWN;
+ const char moov[] = "ftypmoovmoof";
+ if(sz > 188 && data[0] == 0x47 && data[188] == 0x47)
+ formatid = StreamFormat::MPEG2TS;
+ else if(sz > 4 && (!memcmp(&moov, data, 4) ||
+ !memcmp(&moov[4], data, 4) ||
+ !memcmp(&moov[8], data, 4)))
+ formatid = StreamFormat::MP4;
+ else if(sz > 7 && !memcmp("WEBVTT", data, 6) &&
+ std::isspace(static_cast<unsigned char>(data[7])))
+ formatid = StreamFormat::WEBVTT;
+ else if(sz > 4 && !memcmp(".Eߣ", data, 4))
+ formatid = StreamFormat::WEBM;
+}
+
StreamFormat::~StreamFormat()
{
diff --git a/modules/demux/adaptive/StreamFormat.hpp b/modules/demux/adaptive/StreamFormat.hpp
index 62b4865a38..db70a53753 100644
--- a/modules/demux/adaptive/StreamFormat.hpp
+++ b/modules/demux/adaptive/StreamFormat.hpp
@@ -36,9 +36,11 @@ namespace adaptive
static const unsigned PACKEDAAC = 5;
static const unsigned WEBM = 6;
static const unsigned UNKNOWN = 0xFF; /* will probe */
+ static const unsigned PEEK_SIZE = 189;
StreamFormat( unsigned = UNSUPPORTED );
explicit StreamFormat( const std::string &mime );
+ StreamFormat( const void *, size_t );
~StreamFormat();
operator unsigned() const;
std::string str() const;
diff --git a/modules/demux/adaptive/plumbing/Demuxer.cpp b/modules/demux/adaptive/plumbing/Demuxer.cpp
index 3b6772e233..346d79f79a 100644
--- a/modules/demux/adaptive/plumbing/Demuxer.cpp
+++ b/modules/demux/adaptive/plumbing/Demuxer.cpp
@@ -100,13 +100,24 @@ bool MimeDemuxer::create()
if(!p_newstream)
return false;
+ StreamFormat format;
char *type = stream_ContentType(p_newstream);
if(type)
{
- demuxer = factory->newDemux( p_realdemux, StreamFormat(std::string(type)),
- p_es_out, sourcestream );
+ format = StreamFormat(std::string(type));
free(type);
}
+ /* Try to probe */
+ if(format == StreamFormat(StreamFormat::UNKNOWN))
+ {
+ const uint8_t *p_peek;
+ size_t i_peek = sourcestream->Peek(&p_peek, StreamFormat::PEEK_SIZE);
+ format = StreamFormat(reinterpret_cast<const void *>(p_peek), i_peek);
+ }
+
+ if(format != StreamFormat(StreamFormat::UNKNOWN))
+ demuxer = factory->newDemux(p_realdemux, format, p_es_out, sourcestream);
+
vlc_stream_Delete(p_newstream);
if(!demuxer || !demuxer->create())
More information about the vlc-commits
mailing list