Commit dfe4aca1 authored by François Cartegnie's avatar François Cartegnie 🤞
Browse files

demux: hls: probe content

Solves issues when the server does not sends proper MIME
and the file does not match known extension.
parent d0c6bbb5
......@@ -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()
{
......
......@@ -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;
......
......@@ -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())
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment