Commit 0ed098b2 authored by Francois Cartegnie's avatar Francois Cartegnie

demux: hls: hardcode formats depending on codecs/extension

parent 4bb4f670
...@@ -31,24 +31,8 @@ namespace hls ...@@ -31,24 +31,8 @@ namespace hls
{ {
public: public:
static const unsigned UNKNOWN = StreamFormat::UNSUPPORTED + 1; /* will probe */ static const unsigned UNKNOWN = StreamFormat::UNSUPPORTED + 1; /* will probe */
static const unsigned MPEG2TS = StreamFormat::UNSUPPORTED + 1; static const unsigned MPEG2TS = StreamFormat::UNSUPPORTED + 2;
static const unsigned PACKEDAAC = StreamFormat::UNSUPPORTED + 2; static const unsigned PACKEDAAC = StreamFormat::UNSUPPORTED + 3;
static StreamFormat mimeToFormat(const std::string &mime)
{
std::string::size_type pos = mime.find("/");
if(pos != std::string::npos)
{
std::string tail = mime.substr(pos + 1);
if(tail == "aac")
return StreamFormat(HLSStreamFormat::PACKEDAAC);
else if (tail == "mp2t")
return StreamFormat(HLSStreamFormat::MPEG2TS);
else if (tail == "binary")
return StreamFormat(HLSStreamFormat::UNSUPPORTED);
}
return StreamFormat();
}
}; };
} }
......
...@@ -55,10 +55,14 @@ AbstractDemuxer * HLSStream::createDemux(const StreamFormat &format) ...@@ -55,10 +55,14 @@ AbstractDemuxer * HLSStream::createDemux(const StreamFormat &format)
AbstractDemuxer *ret = NULL; AbstractDemuxer *ret = NULL;
switch((unsigned)format) switch((unsigned)format)
{ {
case HLSStreamFormat::PACKEDAAC: case HLSStreamFormat::UNKNOWN:
ret = new Demuxer(p_realdemux, "any", fakeesout->getEsOut(), demuxersource); ret = new Demuxer(p_realdemux, "any", fakeesout->getEsOut(), demuxersource);
break; break;
case HLSStreamFormat::PACKEDAAC:
ret = new Demuxer(p_realdemux, "avformat", fakeesout->getEsOut(), demuxersource);
break;
case HLSStreamFormat::MPEG2TS: case HLSStreamFormat::MPEG2TS:
ret = new Demuxer(p_realdemux, "ts", fakeesout->getEsOut(), demuxersource); ret = new Demuxer(p_realdemux, "ts", fakeesout->getEsOut(), demuxersource);
break; break;
......
...@@ -52,27 +52,10 @@ HLSSegment::~HLSSegment() ...@@ -52,27 +52,10 @@ HLSSegment::~HLSSegment()
#endif #endif
} }
void HLSSegment::checkFormat(block_t *p_block, SegmentChunk *, BaseRepresentation *rep) void HLSSegment::onChunkDownload(block_t **pp_block, SegmentChunk *chunk, BaseRepresentation *)
{
if(rep->getStreamFormat() == StreamFormat(HLSStreamFormat::UNKNOWN))
{
if(p_block->i_buffer > 3 && !memcmp(p_block->p_buffer, "ID3", 3))
{
rep->setMimeType("audio/aac");
}
else
{
rep->setMimeType("video/mp2t");
}
}
}
void HLSSegment::onChunkDownload(block_t **pp_block, SegmentChunk *chunk, BaseRepresentation *rep)
{ {
block_t *p_block = *pp_block; block_t *p_block = *pp_block;
checkFormat(p_block, chunk, rep);
#ifdef HAVE_GCRYPT #ifdef HAVE_GCRYPT
if(encryption.method == SegmentEncryption::AES_128) if(encryption.method == SegmentEncryption::AES_128)
{ {
......
...@@ -61,7 +61,6 @@ namespace hls ...@@ -61,7 +61,6 @@ namespace hls
protected: protected:
virtual void onChunkDownload(block_t **, SegmentChunk *, BaseRepresentation *); /* reimpl */ virtual void onChunkDownload(block_t **, SegmentChunk *, BaseRepresentation *); /* reimpl */
void checkFormat(block_t *, SegmentChunk *, BaseRepresentation *);
SegmentEncryption encryption; SegmentEncryption encryption;
#ifdef HAVE_GCRYPT #ifdef HAVE_GCRYPT
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "../adaptative/playlist/SegmentList.h" #include "../adaptative/playlist/SegmentList.h"
#include "../adaptative/tools/Retrieve.hpp" #include "../adaptative/tools/Retrieve.hpp"
#include "../adaptative/tools/Helper.h" #include "../adaptative/tools/Helper.h"
#include "../HLSStreamFormat.hpp"
#include "M3U8.hpp" #include "M3U8.hpp"
#include "Tags.hpp" #include "Tags.hpp"
...@@ -37,6 +38,8 @@ ...@@ -37,6 +38,8 @@
#include <cstdio> #include <cstdio>
#include <sstream> #include <sstream>
#include <map> #include <map>
#include <cctype>
#include <algorithm>
using namespace adaptative; using namespace adaptative;
using namespace adaptative::playlist; using namespace adaptative::playlist;
...@@ -70,6 +73,55 @@ static void releaseTagsList(std::list<Tag *> &list) ...@@ -70,6 +73,55 @@ static void releaseTagsList(std::list<Tag *> &list)
list.clear(); list.clear();
} }
void M3U8Parser::setFormatFromCodecs(Representation *rep, const std::string codecsstring)
{
std::list<std::string> codecs;
std::list<std::string> tokens = Helper::tokenize(codecsstring, ',');
std::list<std::string>::const_iterator it;
for(it=tokens.begin(); it!=tokens.end(); ++it)
{
/* Truncate init data */
std::size_t pos = (*it).find_first_of('.', 0);
if(pos != std::string::npos)
codecs.push_back((*it).substr(0, pos));
else
codecs.push_back(*it);
}
if(!codecs.empty())
{
if(codecs.size() == 1)
{
std::string codec = codecs.front();
transform(codec.begin(), codec.end(), codec.begin(), (int (*)(int))std::tolower);
if(codec == "mp4a")
rep->streamFormat = StreamFormat(HLSStreamFormat::PACKEDAAC);
}
else
{
rep->streamFormat = StreamFormat(HLSStreamFormat::MPEG2TS);
}
}
}
void M3U8Parser::setFormatFromExtension(Representation *rep, const std::string &filename)
{
std::size_t pos = filename.find_last_of('.');
if(pos != std::string::npos)
{
std::string extension = filename.substr(pos + 1);
transform(extension.begin(), extension.end(), extension.begin(), (int (*)(int))std::tolower);
if(extension == "aac")
{
rep->streamFormat = StreamFormat(HLSStreamFormat::PACKEDAAC);
}
else if(extension == "ts" || extension == "mp2t" || extension == "mpeg")
{
rep->streamFormat = StreamFormat(HLSStreamFormat::MPEG2TS);
}
}
}
Representation * M3U8Parser::createRepresentation(BaseAdaptationSet *adaptSet, const AttributesTag * tag) Representation * M3U8Parser::createRepresentation(BaseAdaptationSet *adaptSet, const AttributesTag * tag)
{ {
const Attribute *uriAttr = tag->getAttributeByName("URI"); const Attribute *uriAttr = tag->getAttributeByName("URI");
...@@ -105,22 +157,7 @@ Representation * M3U8Parser::createRepresentation(BaseAdaptationSet *adaptSet, c ...@@ -105,22 +157,7 @@ Representation * M3U8Parser::createRepresentation(BaseAdaptationSet *adaptSet, c
rep->setBandwidth(bwAttr->decimal()); rep->setBandwidth(bwAttr->decimal());
if(codecsAttr) if(codecsAttr)
{ setFormatFromCodecs(rep, codecsAttr->quotedString());
std::list<std::string> list = Helper::tokenize(codecsAttr->quotedString(), ',');
std::list<std::string>::const_iterator it;
for(it=list.begin(); it!=list.end(); ++it)
{
std::size_t pos = (*it).find_first_of('.', 0);
if(pos != std::string::npos)
rep->addCodec((*it).substr(0, pos));
else
rep->addCodec(*it);
}
}
/* if more than 1 codec, don't probe, can't be packed audio */
if(rep->getCodecs().size() > 1)
rep->setMimeType("video/mp2t");
if(resAttr) if(resAttr)
{ {
...@@ -219,6 +256,8 @@ void M3U8Parser::parseSegments(vlc_object_t *p_obj, Representation *rep, const s ...@@ -219,6 +256,8 @@ void M3U8Parser::parseSegments(vlc_object_t *p_obj, Representation *rep, const s
break; break;
segment->setSourceUrl(uritag->getValue().value); segment->setSourceUrl(uritag->getValue().value);
if((unsigned)rep->getStreamFormat() == HLSStreamFormat::UNKNOWN)
setFormatFromExtension(rep, uritag->getValue().value);
if(ctx_extinf) if(ctx_extinf)
{ {
...@@ -417,7 +456,7 @@ M3U8 * M3U8Parser::parse(stream_t *p_stream, const std::string &playlisturl) ...@@ -417,7 +456,7 @@ M3U8 * M3U8Parser::parse(stream_t *p_stream, const std::string &playlisturl)
if(pair.second->getAttributeByName("TYPE")->value != "AUDIO" && if(pair.second->getAttributeByName("TYPE")->value != "AUDIO" &&
pair.second->getAttributeByName("TYPE")->value != "VIDEO") pair.second->getAttributeByName("TYPE")->value != "VIDEO")
{ {
rep->setMimeType("application/binary"); rep->streamFormat = StreamFormat(HLSStreamFormat::UNSUPPORTED);
} }
if(pair.second->getAttributeByName("LANGUAGE")) if(pair.second->getAttributeByName("LANGUAGE"))
......
...@@ -67,6 +67,8 @@ namespace hls ...@@ -67,6 +67,8 @@ namespace hls
void createAndFillRepresentation(vlc_object_t *, BaseAdaptationSet *, void createAndFillRepresentation(vlc_object_t *, BaseAdaptationSet *,
const AttributesTag *, const std::list<Tag *>&); const AttributesTag *, const std::list<Tag *>&);
void parseSegments(vlc_object_t *, Representation *, const std::list<Tag *>&); void parseSegments(vlc_object_t *, Representation *, const std::list<Tag *>&);
void setFormatFromCodecs(Representation *, const std::string);
void setFormatFromExtension(Representation *rep, const std::string &);
std::list<Tag *> parseEntries(stream_t *); std::list<Tag *> parseEntries(stream_t *);
}; };
} }
......
...@@ -43,6 +43,7 @@ Representation::Representation ( BaseAdaptationSet *set ) : ...@@ -43,6 +43,7 @@ Representation::Representation ( BaseAdaptationSet *set ) :
b_loaded = false; b_loaded = false;
switchpolicy = SegmentInformation::SWITCH_SEGMENT_ALIGNED; /* FIXME: based on streamformat */ switchpolicy = SegmentInformation::SWITCH_SEGMENT_ALIGNED; /* FIXME: based on streamformat */
nextPlaylistupdate = 0; nextPlaylistupdate = 0;
streamFormat = HLSStreamFormat::UNKNOWN;
} }
Representation::~Representation () Representation::~Representation ()
...@@ -51,10 +52,7 @@ Representation::~Representation () ...@@ -51,10 +52,7 @@ Representation::~Representation ()
StreamFormat Representation::getStreamFormat() const StreamFormat Representation::getStreamFormat() const
{ {
if(getMimeType().empty()) return streamFormat;
return StreamFormat(HLSStreamFormat::UNKNOWN);
else
return HLSStreamFormat::mimeToFormat(getMimeType());
} }
bool Representation::isLive() const bool Representation::isLive() const
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "../adaptative/playlist/BaseRepresentation.h" #include "../adaptative/playlist/BaseRepresentation.h"
#include "../adaptative/tools/Properties.hpp" #include "../adaptative/tools/Properties.hpp"
#include "../HLSStreamFormat.hpp"
namespace hls namespace hls
{ {
...@@ -52,6 +53,7 @@ namespace hls ...@@ -52,6 +53,7 @@ namespace hls
virtual void getDurationsRange(mtime_t *, mtime_t *) const; /* reimpl */ virtual void getDurationsRange(mtime_t *, mtime_t *) const; /* reimpl */
private: private:
StreamFormat streamFormat;
bool b_live; bool b_live;
bool b_loaded; bool b_loaded;
mtime_t nextPlaylistupdate; mtime_t nextPlaylistupdate;
......
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