Skip to content
Snippets Groups Projects
Commit dfe4aca1 authored by François Cartegnie's avatar François Cartegnie :fingers_crossed:
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
No related branches found
No related tags found
No related merge requests found
......@@ -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())
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment