mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
9abb830db0
--HG-- rename : content/media/nsAudioAvailableEventManager.cpp => content/media/AudioAvailableEventManager.cpp rename : content/media/nsAudioAvailableEventManager.h => content/media/AudioAvailableEventManager.h rename : content/media/nsAudioStream.cpp => content/media/AudioStream.cpp rename : content/media/nsAudioStream.h => content/media/AudioStream.h rename : content/media/nsMediaCache.cpp => content/media/MediaCache.cpp rename : content/media/nsMediaCache.h => content/media/MediaCache.h rename : content/media/nsBuiltinDecoder.cpp => content/media/MediaDecoder.cpp rename : content/media/nsBuiltinDecoder.h => content/media/MediaDecoder.h rename : content/media/nsBuiltinDecoderReader.cpp => content/media/MediaDecoderReader.cpp rename : content/media/nsBuiltinDecoderReader.h => content/media/MediaDecoderReader.h rename : content/media/nsBuiltinDecoderStateMachine.cpp => content/media/MediaDecoderStateMachine.cpp rename : content/media/nsBuiltinDecoderStateMachine.h => content/media/MediaDecoderStateMachine.h rename : content/media/dash/nsDASHDecoder.cpp => content/media/dash/DASHDecoder.cpp rename : content/media/dash/nsDASHDecoder.h => content/media/dash/DASHDecoder.h rename : content/media/dash/nsDASHReader.cpp => content/media/dash/DASHReader.cpp rename : content/media/dash/nsDASHReader.h => content/media/dash/DASHReader.h rename : content/media/dash/nsDASHRepDecoder.cpp => content/media/dash/DASHRepDecoder.cpp rename : content/media/dash/nsDASHRepDecoder.h => content/media/dash/DASHRepDecoder.h rename : content/media/gstreamer/nsGStreamerDecoder.cpp => content/media/gstreamer/GStreamerDecoder.cpp rename : content/media/gstreamer/nsGStreamerDecoder.h => content/media/gstreamer/GStreamerDecoder.h rename : content/media/gstreamer/nsGStreamerReader.cpp => content/media/gstreamer/GStreamerReader.cpp rename : content/media/gstreamer/nsGStreamerReader.h => content/media/gstreamer/GStreamerReader.h rename : content/media/ogg/nsOggCodecState.cpp => content/media/ogg/OggCodecState.cpp rename : content/media/ogg/nsOggCodecState.h => content/media/ogg/OggCodecState.h rename : content/media/ogg/nsOggDecoder.cpp => content/media/ogg/OggDecoder.cpp rename : content/media/ogg/nsOggDecoder.h => content/media/ogg/OggDecoder.h rename : content/media/ogg/nsOggReader.cpp => content/media/ogg/OggReader.cpp rename : content/media/ogg/nsOggReader.h => content/media/ogg/OggReader.h rename : content/media/omx/nsMediaOmxDecoder.cpp => content/media/omx/MediaOmxDecoder.cpp rename : content/media/omx/nsMediaOmxDecoder.h => content/media/omx/MediaOmxDecoder.h rename : content/media/omx/nsMediaOmxReader.cpp => content/media/omx/MediaOmxReader.cpp rename : content/media/omx/nsMediaOmxReader.h => content/media/omx/MediaOmxReader.h rename : content/media/plugins/nsMediaPluginDecoder.cpp => content/media/plugins/MediaPluginDecoder.cpp rename : content/media/plugins/nsMediaPluginDecoder.h => content/media/plugins/MediaPluginDecoder.h rename : content/media/plugins/nsMediaPluginHost.cpp => content/media/plugins/MediaPluginHost.cpp rename : content/media/plugins/nsMediaPluginHost.h => content/media/plugins/MediaPluginHost.h rename : content/media/plugins/nsMediaPluginReader.cpp => content/media/plugins/MediaPluginReader.cpp rename : content/media/plugins/nsMediaPluginReader.h => content/media/plugins/MediaPluginReader.h rename : content/media/raw/nsRawDecoder.cpp => content/media/raw/RawDecoder.cpp rename : content/media/raw/nsRawDecoder.h => content/media/raw/RawDecoder.h rename : content/media/raw/nsRawReader.cpp => content/media/raw/RawReader.cpp rename : content/media/raw/nsRawReader.h => content/media/raw/RawReader.h rename : content/media/raw/nsRawStructs.h => content/media/raw/RawStructs.h rename : content/media/wave/nsWaveDecoder.cpp => content/media/wave/WaveDecoder.cpp rename : content/media/wave/nsWaveDecoder.h => content/media/wave/WaveDecoder.h rename : content/media/wave/nsWaveReader.cpp => content/media/wave/WaveReader.cpp rename : content/media/wave/nsWaveReader.h => content/media/wave/WaveReader.h rename : content/media/webm/nsWebMBufferedParser.cpp => content/media/webm/WebMBufferedParser.cpp rename : content/media/webm/nsWebMBufferedParser.h => content/media/webm/WebMBufferedParser.h rename : content/media/webm/nsWebMDecoder.cpp => content/media/webm/WebMDecoder.cpp rename : content/media/webm/nsWebMDecoder.h => content/media/webm/WebMDecoder.h rename : content/media/webm/nsWebMReader.cpp => content/media/webm/WebMReader.cpp rename : content/media/webm/nsWebMReader.h => content/media/webm/WebMReader.h
605 lines
18 KiB
C++
605 lines
18 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=2 et sw=2 tw=80: */
|
|
/*
|
|
* nsDASHWebMODParser.cpp
|
|
*****************************************************************************
|
|
* Copyrigh(C) 2010 - 2012 Klagenfurt University
|
|
*
|
|
* Created on: May 1, 2012
|
|
* Based on IsoffMainParser.cpp by:
|
|
* Christopher Mueller <christopher.mueller@itec.uni-klu.ac.at>
|
|
* Christian Timmerer <christian.timmerer@itec.uni-klu.ac.at>
|
|
* Author:
|
|
* Steve Workman <sworkman@mozilla.com>
|
|
|
|
*
|
|
* This Source Code Form Is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*****************************************************************************/
|
|
|
|
/* DASH - Dynamic Adaptive Streaming over HTTP.
|
|
*
|
|
* DASH is an adaptive bitrate streaming technology where a multimedia file is
|
|
* partitioned into one or more segments and delivered to a client using HTTP.
|
|
*
|
|
* (see DASHDecoder.cpp for info on DASH interaction with the media engine).
|
|
*
|
|
* Media Presentation Description (MPD) Parser for WebM On Demand Profile.
|
|
*
|
|
* Parses DOM built from MPD XML to verify data and populate MPD classes.
|
|
* MPD classes used as a metadata source by WebM On Demand Manager.
|
|
*/
|
|
|
|
#include "nsAutoPtr.h"
|
|
#include "nsTArray.h"
|
|
#include "nsMimeTypes.h"
|
|
#include "nsString.h"
|
|
#include "nsIDOMElement.h"
|
|
#include "prlog.h"
|
|
#include "nsDASHWebMODParser.h"
|
|
|
|
#if defined(PR_LOGGING)
|
|
static PRLogModuleInfo* gnsDASHWebMODParserLog = nullptr;
|
|
#define LOG(msg, ...) \
|
|
PR_LOG(gnsDASHWebMODParserLog, PR_LOG_DEBUG, \
|
|
("%p [nsDASHWebMODParser] " msg, this, __VA_ARGS__))
|
|
#define LOG1(msg) \
|
|
PR_LOG(gnsDASHWebMODParserLog, PR_LOG_DEBUG, \
|
|
("%p [nsDASHWebMODParser] " msg, this))
|
|
#else
|
|
#define LOG(msg, ...)
|
|
#define LOG1(msg)
|
|
#endif
|
|
|
|
namespace mozilla {
|
|
namespace net {
|
|
|
|
nsDASHWebMODParser::nsDASHWebMODParser(nsIDOMElement* aRoot) :
|
|
mRoot(aRoot)
|
|
{
|
|
MOZ_COUNT_CTOR(nsDASHWebMODParser);
|
|
#if defined(PR_LOGGING)
|
|
if(!gnsDASHWebMODParserLog)
|
|
gnsDASHWebMODParserLog = PR_NewLogModule("nsDASHWebMODParser");
|
|
#endif
|
|
LOG1("Created nsDASHWebMODParser");
|
|
}
|
|
|
|
nsDASHWebMODParser::~nsDASHWebMODParser()
|
|
{
|
|
MOZ_COUNT_DTOR(nsDASHWebMODParser);
|
|
}
|
|
|
|
MPD*
|
|
nsDASHWebMODParser::Parse()
|
|
{
|
|
LOG1("Parsing DOM into MPD objects");
|
|
nsAutoPtr<MPD> mpd(new MPD());
|
|
|
|
nsresult rv = VerifyMPDAttributes();
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
|
|
rv = SetMPDBaseUrls(mpd);
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
|
|
rv = SetPeriods(mpd);
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
|
|
return mpd.forget();
|
|
}
|
|
|
|
nsresult
|
|
nsDASHWebMODParser::VerifyMPDAttributes()
|
|
{
|
|
NS_ENSURE_TRUE(mRoot, NS_ERROR_NOT_INITIALIZED);
|
|
|
|
// @|type| should be "static".
|
|
nsAutoString type;
|
|
nsresult rv = GetAttribute(mRoot, NS_LITERAL_STRING("type"), type);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
NS_ENSURE_TRUE(type.EqualsLiteral("static"), NS_ERROR_ILLEGAL_VALUE);
|
|
|
|
// Note: No attributes to be set in MPD object for DASH-WebM OD. This
|
|
// function used for attribute verification only.
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsDASHWebMODParser::SetMPDBaseUrls(MPD* aMpd)
|
|
{
|
|
NS_ENSURE_TRUE(mRoot, NS_ERROR_NOT_INITIALIZED);
|
|
|
|
nsCOMPtr<nsIDOMElement> child, nextChild;
|
|
nsresult rv = mRoot->GetFirstElementChild(getter_AddRefs(child));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
#ifdef PR_LOGGING
|
|
int i = 0;
|
|
#endif
|
|
while (child) {
|
|
nsAutoString tagName;
|
|
rv = child->GetTagName(tagName);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if (tagName.EqualsLiteral("BaseURL")) {
|
|
nsAutoString baseUrlStr;
|
|
rv = child->GetTextContent(baseUrlStr);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
aMpd->AddBaseUrl(baseUrlStr);
|
|
LOG("MPD BaseURL #%d: \"%s\"",
|
|
i++, NS_ConvertUTF16toUTF8(baseUrlStr).get());
|
|
}
|
|
rv = child->GetNextElementSibling(getter_AddRefs(nextChild));
|
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
|
|
child = nextChild;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsDASHWebMODParser::GetTime(nsAString& aTimeStr, double& aTime)
|
|
{
|
|
NS_ENSURE_FALSE(aTimeStr.IsEmpty(), NS_ERROR_NOT_INITIALIZED);
|
|
// Fail if time string is not of the format "PT<time>S".
|
|
NS_NAMED_LITERAL_STRING(prefix, "PT");
|
|
NS_NAMED_LITERAL_STRING(suffix, "S");
|
|
nsAString::const_iterator start, end, prefixStart, prefixEnd,
|
|
suffixStart, suffixEnd;
|
|
|
|
// Search for "PT" at the start.
|
|
aTimeStr.BeginReading(start);
|
|
aTimeStr.EndReading(end);
|
|
prefixStart = start;
|
|
prefixEnd = end;
|
|
NS_ENSURE_TRUE(FindInReadable(prefix, prefixStart, prefixEnd),
|
|
NS_ERROR_ILLEGAL_VALUE);
|
|
NS_ENSURE_TRUE(prefixStart == start, NS_ERROR_ILLEGAL_VALUE);
|
|
|
|
// Search for "S" after "PT".
|
|
suffixStart = prefixEnd;
|
|
suffixEnd = end;
|
|
NS_ENSURE_TRUE(FindInReadable(suffix, suffixStart, suffixEnd),
|
|
NS_ERROR_ILLEGAL_VALUE);
|
|
NS_ENSURE_TRUE(suffixStart != prefixEnd, NS_ERROR_ILLEGAL_VALUE);
|
|
NS_ENSURE_TRUE(suffixEnd == end, NS_ERROR_ILLEGAL_VALUE);
|
|
|
|
// Parse inner substring for time.
|
|
const nsAutoString timeSubString(Substring(prefixEnd, suffixStart));
|
|
LOG("Parsing substring \"%s\" in \"%s\"",
|
|
NS_ConvertUTF16toUTF8(timeSubString).get(),
|
|
NS_ConvertUTF16toUTF8(aTimeStr).get());
|
|
NS_ENSURE_FALSE(timeSubString.IsEmpty(), NS_ERROR_ILLEGAL_VALUE);
|
|
nsresult rv;
|
|
aTime = timeSubString.ToDouble(&rv);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsDASHWebMODParser::SetPeriods(MPD* aMpd)
|
|
{
|
|
NS_ENSURE_TRUE(mRoot, NS_ERROR_NOT_INITIALIZED);
|
|
|
|
nsCOMPtr<nsIDOMElement> child, nextChild;
|
|
nsresult rv = mRoot->GetFirstElementChild(getter_AddRefs(child));
|
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
|
|
|
|
#ifdef PR_LOGGING
|
|
int i = 0;
|
|
#endif
|
|
while (child) {
|
|
nsAutoString tagName;
|
|
rv = child->GetTagName(tagName);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if (tagName.EqualsLiteral("Period")) {
|
|
nsAutoPtr<Period> period(new Period());
|
|
|
|
// Get start time and duration
|
|
nsAutoString value;
|
|
rv = GetAttribute(child, NS_LITERAL_STRING("start"), value);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if (!value.IsEmpty()) {
|
|
double startTime = -1;
|
|
rv = GetTime(value, startTime);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
NS_ENSURE_TRUE(0 <= startTime, NS_ERROR_ILLEGAL_VALUE);
|
|
period->SetStart(startTime);
|
|
}
|
|
|
|
rv = GetAttribute(child, NS_LITERAL_STRING("duration"), value);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if (!value.IsEmpty()) {
|
|
double duration = -1;
|
|
rv = GetTime(value, duration);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
NS_ENSURE_TRUE(0 <= duration, NS_ERROR_ILLEGAL_VALUE);
|
|
period->SetDuration(duration);
|
|
}
|
|
|
|
bool bIgnoreThisPeriod;
|
|
rv = SetAdaptationSets(child, period, bIgnoreThisPeriod);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// |Period| should be ignored if its child elems are invalid
|
|
if (bIgnoreThisPeriod) {
|
|
LOG1("Ignoring period");
|
|
} else {
|
|
aMpd->AddPeriod(period.forget());
|
|
LOG("Period #%d: added to MPD", i++);
|
|
}
|
|
}
|
|
rv = child->GetNextElementSibling(getter_AddRefs(nextChild));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
child = nextChild;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsDASHWebMODParser::ValidateAdaptationSetAttributes(nsIDOMElement* aChild,
|
|
bool &bAttributesValid)
|
|
{
|
|
// Check common attributes first.
|
|
nsAutoString value;
|
|
nsresult rv = GetAttribute(aChild, NS_LITERAL_STRING("subsegmentStartsWithSAP"),
|
|
value);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
bAttributesValid = (!value.IsEmpty() && value.EqualsLiteral("1"));
|
|
|
|
// Now check for video and audio specific attributes.
|
|
nsAutoString mimeType;
|
|
if (bAttributesValid) {
|
|
rv = GetAttribute(aChild, NS_LITERAL_STRING("mimeType"), mimeType);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
bAttributesValid = !mimeType.IsEmpty();
|
|
if (!bAttributesValid)
|
|
LOG1("mimeType not present!");
|
|
}
|
|
// Validate attributes for video.
|
|
if (bAttributesValid && mimeType.EqualsLiteral(VIDEO_WEBM)) {
|
|
// @|segmentAlignment| is optional
|
|
if (bAttributesValid) {
|
|
rv = GetAttribute(aChild, NS_LITERAL_STRING("segmentAlignment"), value);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
bAttributesValid = (value.IsEmpty() || value.EqualsLiteral("true"));
|
|
if (!bAttributesValid)
|
|
LOG1("segmentAlignment not present or invalid!");
|
|
}
|
|
if (bAttributesValid) {
|
|
rv = GetAttribute(aChild, NS_LITERAL_STRING("subsegmentAlignment"),
|
|
value);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
bAttributesValid = (!value.IsEmpty() && value.EqualsLiteral("true"));
|
|
if (!bAttributesValid)
|
|
LOG1("subsegmentAlignment not present or invalid!");
|
|
}
|
|
if (bAttributesValid) {
|
|
rv = GetAttribute(aChild, NS_LITERAL_STRING("bitstreamSwitching"),
|
|
value);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
bAttributesValid = (!value.IsEmpty() && value.EqualsLiteral("true"));
|
|
if (!bAttributesValid)
|
|
LOG1("bitstreamSwitching not present or invalid!");
|
|
}
|
|
} else if (bAttributesValid && mimeType.EqualsLiteral(AUDIO_WEBM)) {
|
|
// Validate attributes for audio.
|
|
} else if (bAttributesValid) {
|
|
// attributes are not valid since mimeType is wrong
|
|
bAttributesValid = false;
|
|
LOG("mimeType is invalid: %s", NS_ConvertUTF16toUTF8(mimeType).get());
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsDASHWebMODParser::SetAdaptationSets(nsIDOMElement* aPeriodElem,
|
|
Period* aPeriod,
|
|
bool &bIgnoreThisPeriod)
|
|
{
|
|
NS_ENSURE_ARG(aPeriodElem);
|
|
NS_ENSURE_ARG(aPeriod);
|
|
|
|
// Assume ok until an error is found.
|
|
bIgnoreThisPeriod = false;
|
|
|
|
nsCOMPtr<nsIDOMElement> child, nextChild;
|
|
nsresult rv = aPeriodElem->GetFirstElementChild(getter_AddRefs(child));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
#ifdef PR_LOGGING
|
|
int i = 0;
|
|
#endif
|
|
while (child) {
|
|
nsAutoString tagName;
|
|
rv = child->GetTagName(tagName);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// If child is invalid, return and ignore this |Period|
|
|
if (tagName.EqualsLiteral("SegmentList")
|
|
|| tagName.EqualsLiteral("SegmentTemplate")) {
|
|
bIgnoreThisPeriod = true;
|
|
return NS_OK;
|
|
}
|
|
|
|
if (tagName.EqualsLiteral("AdaptationSet")) {
|
|
// Ignore this |AdaptationSet| if an attribute is inavlid
|
|
bool bAttributesValid = false;
|
|
rv = ValidateAdaptationSetAttributes(child, bAttributesValid);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// Add |AdaptationSet| to |Period| if attributes and child elems are ok
|
|
if (bAttributesValid) {
|
|
nsAutoPtr<AdaptationSet> adaptationSet(new AdaptationSet());
|
|
|
|
// Attribute check already done; set correct value for this profile
|
|
adaptationSet->EnableBitstreamSwitching(true);
|
|
|
|
nsAutoString mimeType;
|
|
rv = GetAttribute(child, NS_LITERAL_STRING("mimeType"), mimeType);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if (!mimeType.IsEmpty()) {
|
|
adaptationSet->SetMIMEType(mimeType);
|
|
}
|
|
|
|
// TODO width
|
|
|
|
// TODO height
|
|
|
|
// TODO codecs
|
|
|
|
bool bIgnoreThisAdaptSet = false;
|
|
rv = SetRepresentations(child, adaptationSet, bIgnoreThisAdaptSet);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (!bIgnoreThisAdaptSet) {
|
|
LOG("AdaptationSet #%d: mimeType:%s width:%d height:%d codecs:%s",
|
|
i, NS_ConvertUTF16toUTF8(mimeType).get(),
|
|
adaptationSet->GetWidth(), adaptationSet->GetHeight(), "");
|
|
aPeriod->AddAdaptationSet(adaptationSet.forget());
|
|
LOG("AdaptationSet #%d: added to Period", i++);
|
|
}
|
|
}
|
|
}
|
|
rv = child->GetNextElementSibling(getter_AddRefs(nextChild));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
child = nextChild;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsDASHWebMODParser::SetRepresentations(nsIDOMElement* aAdaptSetElem,
|
|
AdaptationSet* aAdaptationSet,
|
|
bool &bIgnoreThisAdaptSet)
|
|
{
|
|
NS_ENSURE_ARG(aAdaptSetElem);
|
|
NS_ENSURE_ARG(aAdaptationSet);
|
|
|
|
// Assume ok until an error is found.
|
|
bIgnoreThisAdaptSet = false;
|
|
|
|
nsCOMPtr<nsIDOMElement> child, nextChild;
|
|
nsresult rv = aAdaptSetElem->GetFirstElementChild(getter_AddRefs(child));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
#ifdef PR_LOGGING
|
|
int i = 0;
|
|
#endif
|
|
bIgnoreThisAdaptSet = false;
|
|
while (child) {
|
|
nsAutoString tagName;
|
|
rv = child->GetTagName(tagName);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// If child is invalid, return and ignore this |Period|
|
|
if (tagName.EqualsLiteral("SegmentList")
|
|
|| tagName.EqualsLiteral("SegmentTemplate")) {
|
|
bIgnoreThisAdaptSet = true;
|
|
return NS_OK;
|
|
}
|
|
|
|
if (tagName.EqualsLiteral("Representation")) {
|
|
|
|
nsAutoPtr<Representation> representation(new Representation());
|
|
|
|
nsAutoString value;
|
|
rv = GetAttribute(child, NS_LITERAL_STRING("width"), value);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if(!value.IsEmpty()) {
|
|
representation->SetWidth(value.ToInteger(&rv));
|
|
}
|
|
|
|
rv = GetAttribute(child, NS_LITERAL_STRING("height"), value);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if(!value.IsEmpty()) {
|
|
representation->SetHeight(value.ToInteger(&rv));
|
|
}
|
|
|
|
rv = GetAttribute(child, NS_LITERAL_STRING("bandwidth"), value);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if(!value.IsEmpty()) {
|
|
representation->SetBitrate(value.ToInteger(&rv));
|
|
}
|
|
|
|
LOG("Representation #%d: width:%d height:%d bitrate:%d",
|
|
i, representation->GetWidth(),
|
|
representation->GetHeight(),
|
|
representation->GetBitrate());
|
|
|
|
// Get |BaseURL| elements
|
|
bool bIgnoreThisRep;
|
|
SetRepresentationBaseUrls(child, representation, bIgnoreThisRep);
|
|
|
|
// Get |SegmentBase| elements
|
|
if (!bIgnoreThisRep)
|
|
SetRepSegmentBase(child, representation, bIgnoreThisRep);
|
|
|
|
if (!bIgnoreThisRep) {
|
|
aAdaptationSet->AddRepresentation(representation.forget());
|
|
LOG("Representation #%d: added to AdaptationSet", i++);
|
|
}
|
|
}
|
|
rv = child->GetNextElementSibling(getter_AddRefs(nextChild));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
child = nextChild;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsDASHWebMODParser::SetRepresentationBaseUrls(nsIDOMElement* aRepElem,
|
|
Representation* aRep,
|
|
bool &bIgnoreThisRep)
|
|
{
|
|
NS_ENSURE_ARG(aRepElem);
|
|
NS_ENSURE_ARG(aRep);
|
|
|
|
nsCOMPtr<nsIDOMElement> child, nextChild;
|
|
nsresult rv = aRepElem->GetFirstElementChild(getter_AddRefs(child));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
#ifdef PR_LOGGING
|
|
int i = 0;
|
|
#endif
|
|
// Ignore if no |BaseURL| elems; assume none exist until discovered.
|
|
bIgnoreThisRep = true;
|
|
while (child) {
|
|
nsAutoString tagName;
|
|
rv = child->GetTagName(tagName);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if (tagName.EqualsLiteral("BaseURL")) {
|
|
bIgnoreThisRep = false;
|
|
nsAutoString baseUrlStr;
|
|
rv = child->GetTextContent(baseUrlStr);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
aRep->AddBaseUrl(baseUrlStr);
|
|
LOG("BaseURL #%d: \"%s\" added to Representation",
|
|
i++, NS_ConvertUTF16toUTF8(baseUrlStr).get());
|
|
}
|
|
rv = child->GetNextElementSibling(getter_AddRefs(nextChild));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
child = nextChild;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsDASHWebMODParser::SetRepSegmentBase(nsIDOMElement* aRepElem,
|
|
Representation* aRep,
|
|
bool &bIgnoreThisRep)
|
|
{
|
|
NS_ENSURE_ARG(aRepElem);
|
|
NS_ENSURE_ARG(aRep);
|
|
|
|
nsCOMPtr<nsIDOMElement> child, nextChild;
|
|
nsresult rv = aRepElem->GetFirstElementChild(getter_AddRefs(child));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
#ifdef PR_LOGGING
|
|
int i = 0;
|
|
#endif
|
|
// Ignore if no |SegmentBase| elems; assume none exist until discovered.
|
|
bIgnoreThisRep = true;
|
|
while (child) {
|
|
nsAutoString tagName;
|
|
rv = child->GetTagName(tagName);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if (tagName.EqualsLiteral("SegmentBase")) {
|
|
bIgnoreThisRep = false;
|
|
bool bIgnoreThisSegBase = false;
|
|
|
|
nsAutoPtr<SegmentBase> segmentBase(new SegmentBase());
|
|
|
|
nsAutoString value;
|
|
rv = GetAttribute(child, NS_LITERAL_STRING("indexRange"), value);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if(!value.IsEmpty()) {
|
|
segmentBase->SetIndexRange(value);
|
|
} else {
|
|
bIgnoreThisRep = true;
|
|
bIgnoreThisSegBase = true;
|
|
}
|
|
|
|
if (!bIgnoreThisSegBase) {
|
|
SetSegmentBaseInit(child, segmentBase, bIgnoreThisSegBase);
|
|
}
|
|
|
|
if (!bIgnoreThisSegBase) {
|
|
aRep->SetSegmentBase(segmentBase.forget());
|
|
LOG("SegmentBase #%d: added to Representation", i++);
|
|
}
|
|
break;
|
|
}
|
|
rv = child->GetNextElementSibling(getter_AddRefs(nextChild));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
child = nextChild;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsDASHWebMODParser::SetSegmentBaseInit(nsIDOMElement* aSegBaseElem,
|
|
SegmentBase* aSegBase,
|
|
bool &bIgnoreThisSegBase)
|
|
{
|
|
NS_ENSURE_ARG(aSegBaseElem);
|
|
NS_ENSURE_ARG(aSegBase);
|
|
|
|
nsCOMPtr<nsIDOMElement> child, nextChild;
|
|
nsresult rv = aSegBaseElem->GetFirstElementChild(getter_AddRefs(child));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
#ifdef PR_LOGGING
|
|
int i = 0;
|
|
#endif
|
|
// Ignore if no |Initialisation| elems; assume none exist until discovered.
|
|
bIgnoreThisSegBase = true;
|
|
while (child) {
|
|
nsAutoString tagName;
|
|
rv = child->GetTagName(tagName);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
// XXX Spec spells with 's'; WebM Project defn spells with 'z': accept both
|
|
if (tagName.EqualsLiteral("Initialisation")
|
|
|| tagName.EqualsLiteral("Initialization")) {
|
|
bIgnoreThisSegBase = false;
|
|
|
|
nsAutoString value;
|
|
rv = GetAttribute(child, NS_LITERAL_STRING("range"), value);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if(!value.IsEmpty()) {
|
|
aSegBase->SetInitRange(value);
|
|
LOG("Initialisation #%d: added to SegmentBase", i++);
|
|
} else {
|
|
bIgnoreThisSegBase = true;
|
|
}
|
|
break;
|
|
}
|
|
rv = child->GetNextElementSibling(getter_AddRefs(nextChild));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
child = nextChild;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsDASHWebMODParser::GetAttribute(nsIDOMElement* aElem,
|
|
const nsAString& aAttribute,
|
|
nsAString& aValue)
|
|
{
|
|
bool bAttributePresent;
|
|
nsresult rv = aElem->HasAttribute(aAttribute, &bAttributePresent);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if (!bAttributePresent)
|
|
aValue.AssignLiteral("");
|
|
else {
|
|
rv = aElem->GetAttribute(aAttribute, aValue);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
}//namespace net
|
|
}//namespace mozilla
|