[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