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
{
public:
static const unsigned UNKNOWN = StreamFormat::UNSUPPORTED + 1; /* will probe */
static const unsigned MPEG2TS = StreamFormat::UNSUPPORTED + 1;
static const unsigned PACKEDAAC = StreamFormat::UNSUPPORTED + 2;
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();
}
static const unsigned MPEG2TS = StreamFormat::UNSUPPORTED + 2;
static const unsigned PACKEDAAC = StreamFormat::UNSUPPORTED + 3;
};
}
......
......@@ -55,10 +55,14 @@ AbstractDemuxer * HLSStream::createDemux(const StreamFormat &format)
AbstractDemuxer *ret = NULL;
switch((unsigned)format)
{
case HLSStreamFormat::PACKEDAAC:
case HLSStreamFormat::UNKNOWN:
ret = new Demuxer(p_realdemux, "any", fakeesout->getEsOut(), demuxersource);
break;
case HLSStreamFormat::PACKEDAAC:
ret = new Demuxer(p_realdemux, "avformat", fakeesout->getEsOut(), demuxersource);
break;
case HLSStreamFormat::MPEG2TS:
ret = new Demuxer(p_realdemux, "ts", fakeesout->getEsOut(), demuxersource);
break;
......
......@@ -52,27 +52,10 @@ HLSSegment::~HLSSegment()
#endif
}
void HLSSegment::checkFormat(block_t *p_block, SegmentChunk *, BaseRepresentation *rep)
{
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)
void HLSSegment::onChunkDownload(block_t **pp_block, SegmentChunk *chunk, BaseRepresentation *)
{
block_t *p_block = *pp_block;
checkFormat(p_block, chunk, rep);
#ifdef HAVE_GCRYPT
if(encryption.method == SegmentEncryption::AES_128)
{
......
......@@ -61,7 +61,6 @@ namespace hls
protected:
virtual void onChunkDownload(block_t **, SegmentChunk *, BaseRepresentation *); /* reimpl */
void checkFormat(block_t *, SegmentChunk *, BaseRepresentation *);
SegmentEncryption encryption;
#ifdef HAVE_GCRYPT
......
......@@ -29,6 +29,7 @@
#include "../adaptative/playlist/SegmentList.h"
#include "../adaptative/tools/Retrieve.hpp"
#include "../adaptative/tools/Helper.h"
#include "../HLSStreamFormat.hpp"
#include "M3U8.hpp"
#include "Tags.hpp"
......@@ -37,6 +38,8 @@
#include <cstdio>
#include <sstream>
#include <map>
#include <cctype>
#include <algorithm>
using namespace adaptative;
using namespace adaptative::playlist;
......@@ -70,6 +73,55 @@ static void releaseTagsList(std::list<Tag *> &list)
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)
{
const Attribute *uriAttr = tag->getAttributeByName("URI");
......@@ -105,22 +157,7 @@ Representation * M3U8Parser::createRepresentation(BaseAdaptationSet *adaptSet, c
rep->setBandwidth(bwAttr->decimal());
if(codecsAttr)
{
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");
setFormatFromCodecs(rep, codecsAttr->quotedString());
if(resAttr)
{
......@@ -219,6 +256,8 @@ void M3U8Parser::parseSegments(vlc_object_t *p_obj, Representation *rep, const s
break;
segment->setSourceUrl(uritag->getValue().value);
if((unsigned)rep->getStreamFormat() == HLSStreamFormat::UNKNOWN)
setFormatFromExtension(rep, uritag->getValue().value);
if(ctx_extinf)
{
......@@ -417,7 +456,7 @@ M3U8 * M3U8Parser::parse(stream_t *p_stream, const std::string &playlisturl)
if(pair.second->getAttributeByName("TYPE")->value != "AUDIO" &&
pair.second->getAttributeByName("TYPE")->value != "VIDEO")
{
rep->setMimeType("application/binary");
rep->streamFormat = StreamFormat(HLSStreamFormat::UNSUPPORTED);
}
if(pair.second->getAttributeByName("LANGUAGE"))
......
......@@ -67,6 +67,8 @@ namespace hls
void createAndFillRepresentation(vlc_object_t *, BaseAdaptationSet *,
const AttributesTag *, 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 *);
};
}
......
......@@ -43,6 +43,7 @@ Representation::Representation ( BaseAdaptationSet *set ) :
b_loaded = false;
switchpolicy = SegmentInformation::SWITCH_SEGMENT_ALIGNED; /* FIXME: based on streamformat */
nextPlaylistupdate = 0;
streamFormat = HLSStreamFormat::UNKNOWN;
}
Representation::~Representation ()
......@@ -51,10 +52,7 @@ Representation::~Representation ()
StreamFormat Representation::getStreamFormat() const
{
if(getMimeType().empty())
return StreamFormat(HLSStreamFormat::UNKNOWN);
else
return HLSStreamFormat::mimeToFormat(getMimeType());
return streamFormat;
}
bool Representation::isLive() const
......
......@@ -23,6 +23,7 @@
#include "../adaptative/playlist/BaseRepresentation.h"
#include "../adaptative/tools/Properties.hpp"
#include "../HLSStreamFormat.hpp"
namespace hls
{
......@@ -52,6 +53,7 @@ namespace hls
virtual void getDurationsRange(mtime_t *, mtime_t *) const; /* reimpl */
private:
StreamFormat streamFormat;
bool b_live;
bool b_loaded;
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