author | Wes Kocher <wkocher@mozilla.com> |
Mon, 23 Mar 2015 16:40:59 -0700 | |
changeset 235176 | e642ae3c0496b4a3b177d060fe0d43b85dd3fd1e |
parent 235175 | 9cee181014eb6302296b9b9f1552ab9019c9c32b (current diff) |
parent 235093 | 84f7fa96af4fa19b0ce10f2d13f7f1b08f1abfe3 (diff) |
child 235179 | 235a9cb26548a76b85a67af8845746ac27ca2e7a |
push id | 57353 |
push user | kwierso@gmail.com |
push date | Mon, 23 Mar 2015 23:51:33 +0000 |
treeherder | mozilla-inbound@7f5abc27fd53 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 39.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/accessible/html/HTMLTableAccessible.cpp +++ b/accessible/html/HTMLTableAccessible.cpp @@ -294,25 +294,28 @@ HTMLTableHeaderCellAccessible:: //////////////////////////////////////////////////////////////////////////////// // HTMLTableHeaderCellAccessible: Accessible implementation role HTMLTableHeaderCellAccessible::NativeRole() { // Check value of @scope attribute. static nsIContent::AttrValuesArray scopeValues[] = - {&nsGkAtoms::col, &nsGkAtoms::row, nullptr}; + { &nsGkAtoms::col, &nsGkAtoms::colgroup, + &nsGkAtoms::row, &nsGkAtoms::rowgroup, nullptr }; int32_t valueIdx = mContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::scope, scopeValues, eCaseMatters); switch (valueIdx) { case 0: + case 1: return roles::COLUMNHEADER; - case 1: + case 2: + case 3: return roles::ROWHEADER; } // Assume it's columnheader if there are headers in siblings, otherwise // rowheader. // This should iterate the flattened tree nsIContent* parentContent = mContent->GetParent(); if (!parentContent) {
--- a/accessible/tests/mochitest/table/test_headers_table.html +++ b/accessible/tests/mochitest/table/test_headers_table.html @@ -151,16 +151,152 @@ cell: "table6_cell", rowHeaderCells: [ "table6_rh" ], columnHeaderCells: [ "table6_ch" ] } ]; testHeaderCells(headerInfoMap); + ////////////////////////////////////////////////////////////////////////// + // @scope="rowgroup" and @scope="row" + + headerInfoMap = [ + { + cell: "t7_r1c1", + rowHeaderCells: [ "t7_Females", "t7_Mary" ], + columnHeaderCells: [ "t7_1km" ] + }, + { + cell: "t7_r1c2", + rowHeaderCells: [ "t7_Females", "t7_Mary" ], + columnHeaderCells: [ "t7_5km" ] + }, + { + cell: "t7_r1c3", + rowHeaderCells: [ "t7_Females", "t7_Mary" ], + columnHeaderCells: [ "t7_10km" ] + }, + { + cell: "t7_r2c1", + rowHeaderCells: [ "t7_Females", "t7_Betsy" ], + columnHeaderCells: [ "t7_1km" ] + }, + { + cell: "t7_r2c2", + rowHeaderCells: [ "t7_Females", "t7_Betsy" ], + columnHeaderCells: [ "t7_5km" ] + }, + { + cell: "t7_r2c3", + rowHeaderCells: [ "t7_Females", "t7_Betsy" ], + columnHeaderCells: [ "t7_10km" ] + }, + { + cell: "t7_r3c1", + rowHeaderCells: [ "t7_Males", "t7_Matt" ], + columnHeaderCells: [ "t7_1km" ] + }, + { + cell: "t7_r3c2", + rowHeaderCells: [ "t7_Males", "t7_Matt" ], + columnHeaderCells: [ "t7_5km" ] + }, + { + cell: "t7_r3c3", + rowHeaderCells: [ "t7_Males", "t7_Matt" ], + columnHeaderCells: [ "t7_10km" ] + }, + { + cell: "t7_r4c1", + rowHeaderCells: [ "t7_Males", "t7_Todd" ], + columnHeaderCells: [ "t7_1km" ] + }, + { + cell: "t7_r4c2", + rowHeaderCells: [ "t7_Males", "t7_Todd" ], + columnHeaderCells: [ "t7_5km" ] + }, + { + cell: "t7_r4c3", + rowHeaderCells: [ "t7_Males", "t7_Todd" ], + columnHeaderCells: [ "t7_10km" ] + } + ]; + + testHeaderCells(headerInfoMap); + + ////////////////////////////////////////////////////////////////////////// + // @scope="colgroup" and @scope="col" + + headerInfoMap = [ + { + cell: "t8_r1c1", + rowHeaderCells: [ "t8_1km" ], + columnHeaderCells: [ "t7_Females", "t7_Mary" ] + }, + { + cell: "t8_r1c2", + rowHeaderCells: [ "t8_5km" ], + columnHeaderCells: [ "t8_Females", "t8_Mary" ] + }, + { + cell: "t8_r1c3", + rowHeaderCells: [ "t8_10km" ], + columnHeaderCells: [ "t8_Females", "t8_Mary" ] + }, + { + cell: "t8_r1c4", + rowHeaderCells: [ "t8_1km" ], + columnHeaderCells: [ "t8_Females", "t8_Betsy" ] + }, + { + cell: "t8_r2c1", + rowHeaderCells: [ "t8_5km" ], + columnHeaderCells: [ "t8_Females", "t8_Betsy" ] + }, + { + cell: "t8_r2c2", + rowHeaderCells: [ "t8_10km" ], + columnHeaderCells: [ "t8_Females", "t8_Betsy" ] + }, + { + cell: "t8_r2c3", + rowHeaderCells: [ "t8_1km" ], + columnHeaderCells: [ "t8_Males", "t8_Matt" ] + }, + { + cell: "t8_r2c4", + rowHeaderCells: [ "t8_5km" ], + columnHeaderCells: [ "t8_Males", "t8_Matt" ] + }, + { + cell: "t8_r3c1", + rowHeaderCells: [ "t8_10km" ], + columnHeaderCells: [ "t8_Males", "t8_Matt" ] + }, + { + cell: "t8_r3c2", + rowHeaderCells: [ "t8_1km" ], + columnHeaderCells: [ "t8_Males", "t8_Todd" ] + }, + { + cell: "t8_r3c3", + rowHeaderCells: [ "t8_5km" ], + columnHeaderCells: [ "t8_Males", "t8_Todd" ] + }, + { + cell: "t8_r3c4", + rowHeaderCells: [ "t8_10km" ], + columnHeaderCells: [ "t8_Males", "t8_Todd" ] + } + ]; + + testHeaderCells(headerInfoMap); + SimpleTest.finish(); } SimpleTest.waitForExplicitFinish(); addA11yLoadEvent(doTest); </script> </head> @@ -170,16 +306,21 @@ href="https://bugzilla.mozilla.org/show_bug.cgi?id=512424"> Bug 512424 </a> <a target="_blank" title="Table headers not associated when header is a td element with no scope" href="https://bugzilla.mozilla.org/show_bug.cgi?id=704465"> Bug 704465 </a> + <a target="_blank" + title="Support rowgroup and colgroup HTML scope" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=1141978"> + Bug 1141978 + </a> <p id="display"></p> <div id="content" style="display: none"></div> <pre id="test"> </pre> <table id="table1" border="1"> <thead> @@ -270,10 +411,92 @@ <td>empty cell</th> <td id="table6_ch">colheader</td> </tr> <tr> <td id="table6_rh">rowheader</th> <td id="table6_cell" headers="table6_ch table6_rh">cell</td> </tr> </table> + + <table id="table7" class="data complex" border="1"> + <caption>Version 1 with rowgroup</caption> + <thead> + <tr> + <td colspan="2"> </td> + <th id="t7_1km" scope="col">1 km</th> + <th id="t7_5km" scope="col">5 km</th> + <th id="t7_10km" scope="col">10 km</th> + </tr> + </thead> + <tbody> + <tr> + <th id="t7_Females" rowspan="2" scope="rowgroup">Females</th> + <th id="t7_Mary" scope="row">Mary</th> + <td id="t7_r1c1">8:32</td> + <td id="t7_r1c2">28:04</td> + <td id="t7_r1c3">1:01:16</td> + </tr> + <tr> + <th id="t7_Betsy" scope="row">Betsy</th> + <td id="t7_r2c1">7:43</td> + <td id="t7_r2c2">26:47</td> + <td id="t7_r2c3">55:38</td> + </tr> + <tr> + <th id="t7_Males" rowspan="2" scope="rowgroup">Males</th> + <th id="t7_Matt" scope="row">Matt</th> + <td id="t7_r3c1">7:55</td> + <td id="t7_r3c2">27:29</td> + <td id="t7_r3c3">57:04</td> + </tr> + <tr> + <th id="t7_Todd" scope="row">Todd</th> + <td id="t7_r4c1">7:01</td> + <td id="t7_r4c2">24:21</td> + <td id="t7_r4c3">50:35</td> + </tr> + </tbody> + </table> + + <table id="table8" class="data complex" border="1"> + <caption>Version 2 with colgroup</caption> + <thead> + <tr> + <td rowspan="2"> </td> + <th id="t8_Females" colspan="2" scope="colgroup">Females</th> + <th id="t8_Males" colspan="2" scope="colgroup">Males</th> + </tr> + <tr> + <th id="t8_Mary" scope="col">Mary</th> + <th id="t8_Betsy" scope="col">Betsy</th> + <th id="t8_Matt" scope="col">Matt</th> + <th id="t8_Todd" scope="col">Todd</th> + </tr> + </thead> + <tbody> + <tr> + <th id="t8_1km" scope="row">1 km</th> + <td id="t8_r1c1">8:32</td> + <td id="t8_r1c2">7:43</td> + <td id="t8_r1c3">7:55</td> + <td id="t8_r1c4">7:01</td> + </tr> + <tr> + <th id="t8_5km" scope="row">5 km</th> + <td id="t8_r2c1">28:04</td> + <td id="t8_r2c2">26:47</td> + <td id="t8_r2c3">27:27</td> + <td id="t8_r2c4">24:21</td> + </tr> + <tr> + <th id="t8_10km" scope="row">10 km</th> + <td id="t8_r3c1">1:01:16</td> + <td id="t8_r3c2">55:38</td> + <td id="t8_r3c3">57:04</td> + <td id="t8_r3c4">50:35</td> + </tr> + + </tbody> + </table> + </body> </html>
--- a/dom/base/nsDOMAttributeMap.cpp +++ b/dom/base/nsDOMAttributeMap.cpp @@ -46,27 +46,23 @@ RemoveMapRef(nsAttrHashKey::KeyType aKey { aData->SetMap(nullptr); return PL_DHASH_REMOVE; } nsDOMAttributeMap::~nsDOMAttributeMap() { - if (mAttributeCache) { - mAttributeCache->Enumerate(RemoveMapRef, nullptr); - } + mAttributeCache.Enumerate(RemoveMapRef, nullptr); } void nsDOMAttributeMap::DropReference() { - if (mAttributeCache) { - mAttributeCache->Enumerate(RemoveMapRef, nullptr); - } + mAttributeCache.Enumerate(RemoveMapRef, nullptr); mContent = nullptr; } NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMAttributeMap) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMAttributeMap) tmp->DropReference(); NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER @@ -82,19 +78,17 @@ TraverseMapEntry(nsAttrHashKey::KeyType static_cast<nsCycleCollectionTraversalCallback*>(aUserArg); cb->NoteXPCOMChild(static_cast<nsINode*>(aData.get())); return PL_DHASH_NEXT; } NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMAttributeMap) - if (tmp->mAttributeCache) { - tmp->mAttributeCache->Enumerate(TraverseMapEntry, &cb); - } + tmp->mAttributeCache.Enumerate(TraverseMapEntry, &cb); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContent) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsDOMAttributeMap) NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsDOMAttributeMap) if (tmp->IsBlack()) { @@ -138,79 +132,76 @@ SetOwnerDocumentFunc(nsAttrHashKey::KeyT nsresult rv = aData->SetOwnerDocument(static_cast<nsIDocument*>(aUserArg)); return NS_FAILED(rv) ? PL_DHASH_STOP : PL_DHASH_NEXT; } nsresult nsDOMAttributeMap::SetOwnerDocument(nsIDocument* aDocument) { - if (mAttributeCache) { - uint32_t n = mAttributeCache->Enumerate(SetOwnerDocumentFunc, aDocument); - NS_ENSURE_TRUE(n == mAttributeCache->Count(), NS_ERROR_FAILURE); - } + uint32_t n = mAttributeCache.Enumerate(SetOwnerDocumentFunc, aDocument); + NS_ENSURE_TRUE(n == mAttributeCache.Count(), NS_ERROR_FAILURE); + return NS_OK; } void nsDOMAttributeMap::DropAttribute(int32_t aNamespaceID, nsIAtom* aLocalName) { nsAttrKey attr(aNamespaceID, aLocalName); - if (mAttributeCache) { - Attr *node = mAttributeCache->GetWeak(attr); - if (node) { - // Break link to map - node->SetMap(nullptr); + Attr *node = mAttributeCache.GetWeak(attr); + if (node) { + // Break link to map + node->SetMap(nullptr); - // Remove from cache - mAttributeCache->Remove(attr); - } + // Remove from cache + mAttributeCache.Remove(attr); } } already_AddRefed<Attr> nsDOMAttributeMap::RemoveAttribute(mozilla::dom::NodeInfo* aNodeInfo) { NS_ASSERTION(aNodeInfo, "RemoveAttribute() called with aNodeInfo == nullptr!"); nsAttrKey attr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom()); nsRefPtr<Attr> node; - if (mAttributeCache && mAttributeCache->Get(attr, getter_AddRefs(node))) { - // Break link to map - node->SetMap(nullptr); - - // Remove from cache - mAttributeCache->Remove(attr); - } else { + if (!mAttributeCache.Get(attr, getter_AddRefs(node))) { nsAutoString value; // As we are removing the attribute we need to set the current value in // the attribute node. mContent->GetAttr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom(), value); nsRefPtr<mozilla::dom::NodeInfo> ni = aNodeInfo; node = new Attr(nullptr, ni.forget(), value, true); } + else { + // Break link to map + node->SetMap(nullptr); + + // Remove from cache + mAttributeCache.Remove(attr); + } return node.forget(); } Attr* nsDOMAttributeMap::GetAttribute(mozilla::dom::NodeInfo* aNodeInfo, bool aNsAware) { NS_ASSERTION(aNodeInfo, "GetAttribute() called with aNodeInfo == nullptr!"); nsAttrKey attr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom()); - EnsureAttributeCache(); - Attr* node = mAttributeCache->GetWeak(attr); + Attr* node = mAttributeCache.GetWeak(attr); if (!node) { nsRefPtr<mozilla::dom::NodeInfo> ni = aNodeInfo; nsRefPtr<Attr> newAttr = new Attr(this, ni.forget(), EmptyString(), aNsAware); - mAttributeCache->Put(attr, newAttr); + mAttributeCache.Put(attr, newAttr); node = newAttr; } return node; } Attr* nsDOMAttributeMap::NamedGetter(const nsAString& aAttrName, bool& aFound) @@ -246,24 +237,16 @@ nsDOMAttributeMap::GetNamedItem(const ns { NS_ENSURE_ARG_POINTER(aAttribute); NS_IF_ADDREF(*aAttribute = GetNamedItem(aAttrName)); return NS_OK; } -void -nsDOMAttributeMap::EnsureAttributeCache() -{ - if (!mAttributeCache) { - mAttributeCache = MakeUnique<AttrCache>(); - } -} - NS_IMETHODIMP nsDOMAttributeMap::SetNamedItem(nsIDOMAttr* aAttr, nsIDOMAttr** aReturn) { Attr* attribute = static_cast<Attr*>(aAttr); NS_ENSURE_ARG(attribute); ErrorResult rv; *aReturn = SetNamedItem(*attribute, rv).take(); @@ -360,18 +343,17 @@ nsDOMAttributeMap::SetNamedItemInternal( nsAutoString value; aAttr.GetValue(value); nsRefPtr<NodeInfo> ni = aAttr.NodeInfo(); // Add the new attribute to the attribute map before updating // its value in the element. @see bug 364413. nsAttrKey attrkey(ni->NamespaceID(), ni->NameAtom()); - EnsureAttributeCache(); - mAttributeCache->Put(attrkey, &aAttr); + mAttributeCache.Put(attrkey, &aAttr); aAttr.SetMap(this); rv = mContent->SetAttr(ni->NamespaceID(), ni->NameAtom(), ni->GetPrefixAtom(), value, true); if (NS_FAILED(rv)) { aError.Throw(rv); DropAttribute(ni->NamespaceID(), ni->NameAtom()); } @@ -549,43 +531,41 @@ nsDOMAttributeMap::RemoveNamedItemNS(con } return RemoveNamedItem(ni, aError); } uint32_t nsDOMAttributeMap::Count() const { - return mAttributeCache ? mAttributeCache->Count() : 0; + return mAttributeCache.Count(); } uint32_t nsDOMAttributeMap::Enumerate(AttrCache::EnumReadFunction aFunc, void *aUserArg) const { - return mAttributeCache ? mAttributeCache->EnumerateRead(aFunc, aUserArg) : 0; + return mAttributeCache.EnumerateRead(aFunc, aUserArg); } size_t AttrCacheSizeEnumerator(const nsAttrKey& aKey, const nsRefPtr<Attr>& aValue, MallocSizeOf aMallocSizeOf, void* aUserArg) { return aMallocSizeOf(aValue.get()); } size_t nsDOMAttributeMap::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { size_t n = aMallocSizeOf(this); - n += mAttributeCache - ? mAttributeCache->SizeOfExcludingThis(AttrCacheSizeEnumerator, - aMallocSizeOf) - : 0; + n += mAttributeCache.SizeOfExcludingThis(AttrCacheSizeEnumerator, + aMallocSizeOf); // NB: mContent is non-owning and thus not counted. return n; } /* virtual */ JSObject* nsDOMAttributeMap::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
--- a/dom/base/nsDOMAttributeMap.h +++ b/dom/base/nsDOMAttributeMap.h @@ -6,17 +6,16 @@ /* * Implementation of the |attributes| property of DOM Core's Element object. */ #ifndef nsDOMAttributeMap_h #define nsDOMAttributeMap_h #include "mozilla/MemoryReporting.h" -#include "mozilla/UniquePtr.h" #include "mozilla/dom/Attr.h" #include "mozilla/ErrorResult.h" #include "nsCycleCollectionParticipant.h" #include "nsIDOMMozNamedAttrMap.h" #include "nsRefPtrHashtable.h" #include "nsString.h" #include "nsWrapperCache.h" @@ -181,21 +180,19 @@ public: protected: virtual ~nsDOMAttributeMap(); private: nsCOMPtr<Element> mContent; /** - * Cache of Attrs. It's usually empty, and thus initialized lazily. + * Cache of Attrs. */ - mozilla::UniquePtr<AttrCache> mAttributeCache; - - void EnsureAttributeCache(); + AttrCache mAttributeCache; /** * SetNamedItem() (aWithNS = false) and SetNamedItemNS() (aWithNS = * true) implementation. */ already_AddRefed<Attr> SetNamedItemInternal(Attr& aNode, bool aWithNS, ErrorResult& aError);
--- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -3279,17 +3279,19 @@ class CGWrapWithCacheMethod(CGAbstractMe Argument('JS::MutableHandle<JSObject*>', 'aReflector')] CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args) self.properties = properties def definition_body(self): return fill( """ $*{assertInheritance} - MOZ_ASSERT_IF(aGivenProto, !aCache->GetWrapper()); + MOZ_ASSERT(!aCache->GetWrapper(), + "You should probably not be using Wrap() directly; use " + "GetOrCreateDOMReflector instead"); MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache), "nsISupports must be on our primary inheritance chain"); JS::Rooted<JSObject*> parent(aCx, WrapNativeParent(aCx, aObject->GetParentObject())); if (!parent) { return false; }
--- a/dom/canvas/WebGL1Context.h +++ b/dom/canvas/WebGL1Context.h @@ -29,13 +29,15 @@ public: // nsWrapperCache virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override; private: virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) override; virtual bool ValidateBufferTarget(GLenum target, const char* info) override; virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) override; virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info) override; + + virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) override; }; } // namespace mozilla #endif // WEBGL_1_CONTEXT_H_
--- a/dom/canvas/WebGL1ContextUniforms.cpp +++ b/dom/canvas/WebGL1ContextUniforms.cpp @@ -1,16 +1,16 @@ /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* 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/. */ #include "WebGL1Context.h" -using namespace mozilla; +namespace mozilla { bool WebGL1Context::ValidateAttribPointerType(bool /*integerMode*/, GLenum type, GLsizei* out_alignment, const char* info) { MOZ_ASSERT(out_alignment); if (!out_alignment) return false; @@ -28,8 +28,22 @@ WebGL1Context::ValidateAttribPointerType case LOCAL_GL_FLOAT: *out_alignment = 4; return true; } ErrorInvalidEnumInfo(info, type); return false; } + +bool +WebGL1Context::ValidateUniformMatrixTranspose(bool transpose, const char* info) +{ + if (transpose) { + ErrorInvalidValue("%s: transpose must be FALSE as per the " + "OpenGL ES 2.0 spec", info); + return false; + } + + return true; +} + +} // namespace mozilla
--- a/dom/canvas/WebGL2Context.h +++ b/dom/canvas/WebGL2Context.h @@ -103,36 +103,106 @@ public: // Programs and shaders - WebGL2ContextPrograms.cpp GLint GetFragDataLocation(WebGLProgram* program, const nsAString& name); // ------------------------------------------------------------------------- // Uniforms and attributes - WebGL2ContextUniforms.cpp void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); + // GL 3.0 & ES 3.0 void Uniform1ui(WebGLUniformLocation* location, GLuint v0); void Uniform2ui(WebGLUniformLocation* location, GLuint v0, GLuint v1); void Uniform3ui(WebGLUniformLocation* location, GLuint v0, GLuint v1, GLuint v2); void Uniform4ui(WebGLUniformLocation* location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); - void Uniform1uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value); - void Uniform2uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value); - void Uniform3uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value); - void Uniform4uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value); - void UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value); - void UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value); - void UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value); - void UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value); - void UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value); - void UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value); - void UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value); - void UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value); - void UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value); - void UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value); - void UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value); - void UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value); + +private: + void Uniform1uiv_base(WebGLUniformLocation* loc, size_t arrayLength, const GLuint* data); + void Uniform2uiv_base(WebGLUniformLocation* loc, size_t arrayLength, const GLuint* data); + void Uniform3uiv_base(WebGLUniformLocation* loc, size_t arrayLength, const GLuint* data); + void Uniform4uiv_base(WebGLUniformLocation* loc, size_t arrayLength, const GLuint* data); + +public: + void Uniform1uiv(WebGLUniformLocation* loc, const dom::Sequence<GLuint>& arr) { + Uniform1uiv_base(loc,arr.Length(), arr.Elements()); + } + void Uniform2uiv(WebGLUniformLocation* loc, const dom::Sequence<GLuint>& arr) { + Uniform2uiv_base(loc,arr.Length(), arr.Elements()); + } + void Uniform3uiv(WebGLUniformLocation* loc, const dom::Sequence<GLuint>& arr) { + Uniform3uiv_base(loc,arr.Length(), arr.Elements()); + } + void Uniform4uiv(WebGLUniformLocation* loc, const dom::Sequence<GLuint>& arr) { + Uniform4uiv_base(loc,arr.Length(), arr.Elements()); + } + +private: + void UniformMatrix2x3fv_base(WebGLUniformLocation* loc, bool transpose, + size_t arrayLength, const GLfloat* data); + void UniformMatrix3x2fv_base(WebGLUniformLocation* loc, bool transpose, + size_t arrayLength, const GLfloat* data); + void UniformMatrix2x4fv_base(WebGLUniformLocation* loc, bool transpose, + size_t arrayLength, const GLfloat* data); + void UniformMatrix4x2fv_base(WebGLUniformLocation* loc, bool transpose, + size_t arrayLength, const GLfloat* data); + void UniformMatrix3x4fv_base(WebGLUniformLocation* loc, bool transpose, + size_t arrayLength, const GLfloat* data); + void UniformMatrix4x3fv_base(WebGLUniformLocation* loc, bool transpose, + size_t arrayLength, const GLfloat* data); + +public: + // GL 2.1 & ES 3.0 + void UniformMatrix2x3fv(WebGLUniformLocation* loc, bool transpose, const dom::Sequence<GLfloat>& value){ + UniformMatrix2x3fv_base(loc, transpose, value.Length(), value.Elements()); + } + void UniformMatrix2x4fv(WebGLUniformLocation* loc, bool transpose, const dom::Sequence<GLfloat>& value){ + UniformMatrix2x4fv_base(loc, transpose, value.Length(), value.Elements()); + } + void UniformMatrix3x2fv(WebGLUniformLocation* loc, bool transpose, const dom::Sequence<GLfloat>& value){ + UniformMatrix3x2fv_base(loc, transpose, value.Length(), value.Elements()); + } + void UniformMatrix3x4fv(WebGLUniformLocation* loc, bool transpose, const dom::Sequence<GLfloat>& value){ + UniformMatrix3x4fv_base(loc, transpose, value.Length(), value.Elements()); + } + void UniformMatrix4x2fv(WebGLUniformLocation* loc, bool transpose, const dom::Sequence<GLfloat>& value){ + UniformMatrix4x2fv_base(loc, transpose, value.Length(), value.Elements()); + } + void UniformMatrix4x3fv(WebGLUniformLocation* loc, bool transpose, const dom::Sequence<GLfloat>& value){ + UniformMatrix4x3fv_base(loc, transpose, value.Length(), value.Elements()); + } + + void UniformMatrix2x3fv(WebGLUniformLocation* loc, bool transpose, const dom::Float32Array& value){ + value.ComputeLengthAndData(); + UniformMatrix2x3fv_base(loc, transpose, value.Length(), value.Data()); + } + + void UniformMatrix2x4fv(WebGLUniformLocation* loc, bool transpose, const dom::Float32Array& value){ + value.ComputeLengthAndData(); + UniformMatrix2x4fv_base(loc, transpose, value.Length(), value.Data()); + } + + void UniformMatrix3x2fv(WebGLUniformLocation* loc, bool transpose, const dom::Float32Array& value){ + value.ComputeLengthAndData(); + UniformMatrix3x2fv_base(loc, transpose, value.Length(), value.Data()); + } + + void UniformMatrix3x4fv(WebGLUniformLocation* loc, bool transpose, const dom::Float32Array& value){ + value.ComputeLengthAndData(); + UniformMatrix3x4fv_base(loc, transpose, value.Length(), value.Data()); + } + + void UniformMatrix4x2fv(WebGLUniformLocation* loc, bool transpose, const dom::Float32Array& value){ + value.ComputeLengthAndData(); + UniformMatrix4x2fv_base(loc, transpose, value.Length(), value.Data()); + } + + void UniformMatrix4x3fv(WebGLUniformLocation* loc, bool transpose, const dom::Float32Array& value){ + value.ComputeLengthAndData(); + UniformMatrix4x3fv_base(loc, transpose, value.Length(), value.Data()); + } private: void VertexAttribI4iv(GLuint index, size_t length, const GLint* v); void VertexAttribI4uiv(GLuint index, size_t length, const GLuint* v); public: // GL 3.0 & ES 3.0 void VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w); @@ -273,13 +343,15 @@ private: bool ValidateTexStorage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, const char* info); virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) override; virtual bool ValidateBufferTarget(GLenum target, const char* info) override; virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) override; virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info) override; + + virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) override; }; } // namespace mozilla #endif
--- a/dom/canvas/WebGL2ContextSync.cpp +++ b/dom/canvas/WebGL2ContextSync.cpp @@ -1,52 +1,133 @@ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* 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/. */ #include "WebGL2Context.h" + #include "GLContext.h" +#include "WebGLSync.h" using namespace mozilla; using namespace mozilla::dom; // ------------------------------------------------------------------------- // Sync objects already_AddRefed<WebGLSync> WebGL2Context::FenceSync(GLenum condition, GLbitfield flags) { - MOZ_CRASH("Not Implemented."); - return nullptr; + if (IsContextLost()) + return nullptr; + + if (condition != LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE) { + ErrorInvalidEnum("fenceSync: condition must be SYNC_GPU_COMMANDS_COMPLETE"); + return nullptr; + } + + if (flags != 0) { + ErrorInvalidValue("fenceSync: flags must be 0"); + return nullptr; + } + + MakeContextCurrent(); + nsRefPtr<WebGLSync> globj = new WebGLSync(this, condition, flags); + return globj.forget(); } bool WebGL2Context::IsSync(WebGLSync* sync) { - MOZ_CRASH("Not Implemented."); - return false; + if (IsContextLost()) + return false; + + return ValidateObjectAllowDeleted("isSync", sync) && !sync->IsDeleted(); } void WebGL2Context::DeleteSync(WebGLSync* sync) { - MOZ_CRASH("Not Implemented."); + if (IsContextLost()) + return; + + if (!ValidateObjectAllowDeletedOrNull("deleteSync", sync)) + return; + + if (!sync || sync->IsDeleted()) + return; + + sync->RequestDelete(); } GLenum WebGL2Context::ClientWaitSync(WebGLSync* sync, GLbitfield flags, GLuint64 timeout) { - MOZ_CRASH("Not Implemented."); - return LOCAL_GL_FALSE; + if (IsContextLost()) + return LOCAL_GL_WAIT_FAILED; + + if (!sync || sync->IsDeleted()) { + ErrorInvalidValue("clientWaitSync: sync is not a sync object."); + return LOCAL_GL_WAIT_FAILED; + } + + if (flags != 0 && flags != LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT) { + ErrorInvalidValue("clientWaitSync: flag must be SYNC_FLUSH_COMMANDS_BIT or 0"); + return LOCAL_GL_WAIT_FAILED; + } + + MakeContextCurrent(); + return gl->fClientWaitSync(sync->mGLName, flags, timeout); } void WebGL2Context::WaitSync(WebGLSync* sync, GLbitfield flags, GLuint64 timeout) { - MOZ_CRASH("Not Implemented."); + if (IsContextLost()) + return; + + if (!sync || sync->IsDeleted()) { + ErrorInvalidValue("waitSync: sync is not a sync object."); + return; + } + + if (flags != 0) { + ErrorInvalidValue("waitSync: flags must be 0"); + return; + } + + if (timeout != LOCAL_GL_TIMEOUT_IGNORED) { + ErrorInvalidValue("waitSync: timeout must be TIMEOUT_IGNORED"); + return; + } + + MakeContextCurrent(); + gl->fWaitSync(sync->mGLName, flags, timeout); } void WebGL2Context::GetSyncParameter(JSContext*, WebGLSync* sync, GLenum pname, JS::MutableHandleValue retval) { - MOZ_CRASH("Not Implemented."); + if (IsContextLost()) + return; + + if (!sync || sync->IsDeleted()) { + ErrorInvalidValue("getSyncParameter: sync is not a sync object."); + return; + } + + retval.set(JS::NullValue()); + + GLint result = 0; + switch (pname) { + case LOCAL_GL_OBJECT_TYPE: + case LOCAL_GL_SYNC_STATUS: + case LOCAL_GL_SYNC_CONDITION: + case LOCAL_GL_SYNC_FLAGS: + MakeContextCurrent(); + gl->fGetSynciv(sync->mGLName, pname, 1, nullptr, &result); + retval.set(JS::Int32Value(result)); + break; + } + + ErrorInvalidEnum("getSyncParameter: Invalid pname 0x%04x", pname); }
--- a/dom/canvas/WebGL2ContextUniforms.cpp +++ b/dom/canvas/WebGL2ContextUniforms.cpp @@ -69,16 +69,22 @@ WebGL2Context::ValidateAttribPointerType return true; } } ErrorInvalidEnum("%s: invalid enum value 0x%x", info, type); return false; } +bool +WebGL2Context::ValidateUniformMatrixTranspose(bool /*transpose*/, const char* /*info*/) +{ + return true; +} + // ------------------------------------------------------------------------- // Uniforms and attributes void WebGL2Context::VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset) { if (IsContextLost()) @@ -108,150 +114,232 @@ WebGL2Context::VertexAttribIPointer(GLui vd.normalized = false; vd.integer = true; MakeContextCurrent(); gl->fVertexAttribIPointer(index, size, type, stride, reinterpret_cast<void*>(offset)); } void -WebGL2Context::Uniform1ui(WebGLUniformLocation* location, GLuint v0) +WebGL2Context::Uniform1ui(WebGLUniformLocation* loc, GLuint v0) { - MOZ_CRASH("Not Implemented."); -} + GLuint rawLoc; + if (!ValidateUniformSetter(loc, 1, LOCAL_GL_UNSIGNED_INT, "uniform1ui", &rawLoc)) + return; -void -WebGL2Context::Uniform2ui(WebGLUniformLocation* location, GLuint v0, GLuint v1) -{ - MOZ_CRASH("Not Implemented."); + MakeContextCurrent(); + gl->fUniform1ui(rawLoc, v0); } void -WebGL2Context::Uniform3ui(WebGLUniformLocation* location, GLuint v0, GLuint v1, GLuint v2) +WebGL2Context::Uniform2ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1) { - MOZ_CRASH("Not Implemented."); + GLuint rawLoc; + if (!ValidateUniformSetter(loc, 2, LOCAL_GL_UNSIGNED_INT, "uniform2ui", &rawLoc)) + return; + + MakeContextCurrent(); + gl->fUniform2ui(rawLoc, v0, v1); } void -WebGL2Context::Uniform4ui(WebGLUniformLocation* location, GLuint v0, GLuint v1, - GLuint v2, GLuint v3) +WebGL2Context::Uniform3ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1, GLuint v2) { - MOZ_CRASH("Not Implemented."); + GLuint rawLoc; + if (!ValidateUniformSetter(loc, 3, LOCAL_GL_UNSIGNED_INT, "uniform3ui", &rawLoc)) + return; + + MakeContextCurrent(); + gl->fUniform3ui(rawLoc, v0, v1, v2); } void -WebGL2Context::Uniform1uiv(WebGLUniformLocation* location, - const dom::Sequence<GLuint>& value) +WebGL2Context::Uniform4ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1, GLuint v2, GLuint v3) { - MOZ_CRASH("Not Implemented."); + GLuint rawLoc; + if (!ValidateUniformSetter(loc, 4, LOCAL_GL_UNSIGNED_INT, "uniform4ui", &rawLoc)) + return; + + MakeContextCurrent(); + gl->fUniform4ui(rawLoc, v0, v1, v2, v3); } void -WebGL2Context::Uniform2uiv(WebGLUniformLocation* location, - const dom::Sequence<GLuint>& value) +WebGL2Context::Uniform1uiv_base(WebGLUniformLocation* loc, size_t arrayLength, + const GLuint* data) { - MOZ_CRASH("Not Implemented."); -} + GLuint rawLoc; + GLsizei numElementsToUpload; -void -WebGL2Context::Uniform3uiv(WebGLUniformLocation* location, - const dom::Sequence<GLuint>& value) -{ - MOZ_CRASH("Not Implemented."); + if (!ValidateUniformArraySetter(loc, 1, LOCAL_GL_UNSIGNED_INT, arrayLength, + "uniform1uiv", &rawLoc, &numElementsToUpload)) + { + return; + } + + MakeContextCurrent(); + gl->fUniform1uiv(rawLoc, numElementsToUpload, data); } void -WebGL2Context::Uniform4uiv(WebGLUniformLocation* location, - const dom::Sequence<GLuint>& value) +WebGL2Context::Uniform2uiv_base(WebGLUniformLocation* loc, size_t arrayLength, + const GLuint* data) { - MOZ_CRASH("Not Implemented."); + GLuint rawLoc; + GLsizei numElementsToUpload; + + if (!ValidateUniformArraySetter(loc, 2, LOCAL_GL_UNSIGNED_INT, arrayLength, + "uniform2uiv", &rawLoc, &numElementsToUpload)) + { + return; + } + + MakeContextCurrent(); + gl->fUniform2uiv(rawLoc, numElementsToUpload, data); } void -WebGL2Context::UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose, - const dom::Float32Array& value) +WebGL2Context::Uniform3uiv_base(WebGLUniformLocation* loc, size_t arrayLength, + const GLuint* data) { - MOZ_CRASH("Not Implemented."); -} + GLuint rawLoc; + GLsizei numElementsToUpload; -void -WebGL2Context::UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose, - const dom::Sequence<GLfloat>& value) -{ - MOZ_CRASH("Not Implemented."); + if (!ValidateUniformArraySetter(loc, 3, LOCAL_GL_UNSIGNED_INT, arrayLength, + "uniform3uiv", &rawLoc, &numElementsToUpload)) + { + return; + } + + MakeContextCurrent(); + gl->fUniform1uiv(rawLoc, numElementsToUpload, data); } void -WebGL2Context::UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose, - const dom::Float32Array& value) +WebGL2Context::Uniform4uiv_base(WebGLUniformLocation* loc, size_t arrayLength, + const GLuint* data) { - MOZ_CRASH("Not Implemented."); + GLuint rawLoc; + GLsizei numElementsToUpload; + + if (!ValidateUniformArraySetter(loc, 4, LOCAL_GL_UNSIGNED_INT, arrayLength, + "uniform4uiv", &rawLoc, &numElementsToUpload)) { + return; + } + + MakeContextCurrent(); + gl->fUniform4uiv(rawLoc, numElementsToUpload, data); } void -WebGL2Context::UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose, - const dom::Sequence<GLfloat>& value) +WebGL2Context::UniformMatrix2x3fv_base(WebGLUniformLocation* loc, bool transpose, + size_t arrayLength, const GLfloat* data) { - MOZ_CRASH("Not Implemented."); + GLuint rawLoc; + GLsizei numElementsToUpload; + + if (!ValidateUniformMatrixArraySetter(loc, 2, 3, LOCAL_GL_FLOAT, arrayLength, + transpose, "uniformMatrix2x3fv", + &rawLoc, &numElementsToUpload)) + { + return; + } + + MakeContextCurrent(); + gl->fUniformMatrix2x3fv(rawLoc, numElementsToUpload, transpose, data); } void -WebGL2Context::UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose, - const dom::Float32Array& value) +WebGL2Context::UniformMatrix2x4fv_base(WebGLUniformLocation* loc, bool transpose, + size_t arrayLength, const GLfloat* data) { - MOZ_CRASH("Not Implemented."); -} + GLuint rawLoc; + GLsizei numElementsToUpload; -void -WebGL2Context::UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose, - const dom::Sequence<GLfloat>& value) -{ - MOZ_CRASH("Not Implemented."); + if (!ValidateUniformMatrixArraySetter(loc, 2, 4, LOCAL_GL_FLOAT, arrayLength, + transpose, "uniformMatrix2x4fv", + &rawLoc, &numElementsToUpload)) + { + return; + } + + MakeContextCurrent(); + gl->fUniformMatrix2x4fv(rawLoc, numElementsToUpload, transpose, data); } void -WebGL2Context::UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose, - const dom::Float32Array& value) +WebGL2Context::UniformMatrix3x2fv_base(WebGLUniformLocation* loc, bool transpose, + size_t arrayLength, const GLfloat* data) { - MOZ_CRASH("Not Implemented."); -} + GLuint rawLoc; + GLsizei numElementsToUpload; -void -WebGL2Context::UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose, - const dom::Sequence<GLfloat>& value) -{ - MOZ_CRASH("Not Implemented."); + if (!ValidateUniformMatrixArraySetter(loc, 3, 2, LOCAL_GL_FLOAT, arrayLength, + transpose, "uniformMatrix3x2fv", + &rawLoc, &numElementsToUpload)) + { + return; + } + + MakeContextCurrent(); + gl->fUniformMatrix3x2fv(rawLoc, numElementsToUpload, transpose, data); } void -WebGL2Context::UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose, - const dom::Float32Array& value) +WebGL2Context::UniformMatrix3x4fv_base(WebGLUniformLocation* loc, bool transpose, + size_t arrayLength, const GLfloat* data) { - MOZ_CRASH("Not Implemented."); + GLuint rawLoc; + GLsizei numElementsToUpload; + + if (!ValidateUniformMatrixArraySetter(loc, 3, 4, LOCAL_GL_FLOAT, arrayLength, + transpose, "uniformMatrix3x4fv", + &rawLoc, &numElementsToUpload)) + { + return; + } + + MakeContextCurrent(); + gl->fUniformMatrix3x4fv(rawLoc, numElementsToUpload, transpose, data); } void -WebGL2Context::UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose, - const dom::Sequence<GLfloat>& value) +WebGL2Context::UniformMatrix4x2fv_base(WebGLUniformLocation* loc, bool transpose, + size_t arrayLength, const GLfloat* data) { - MOZ_CRASH("Not Implemented."); + GLuint rawLoc; + GLsizei numElementsToUpload; + + if (!ValidateUniformMatrixArraySetter(loc, 4, 2, LOCAL_GL_FLOAT, arrayLength, + transpose, "uniformMatrix4x2fv", + &rawLoc, &numElementsToUpload)) + { + return; + } + + MakeContextCurrent(); + gl->fUniformMatrix4x2fv(rawLoc, numElementsToUpload, transpose, data); } void -WebGL2Context::UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose, - const dom::Float32Array& value) +WebGL2Context::UniformMatrix4x3fv_base(WebGLUniformLocation* loc, bool transpose, + size_t arrayLength, const GLfloat* data) { - MOZ_CRASH("Not Implemented."); -} + GLuint rawLoc; + GLsizei numElementsToUpload; -void -WebGL2Context::UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose, - const dom::Sequence<GLfloat>& value) -{ - MOZ_CRASH("Not Implemented."); + if (!ValidateUniformMatrixArraySetter(loc, 4, 3, LOCAL_GL_FLOAT, arrayLength, + transpose, "uniformMatrix4x3fv", + &rawLoc, &numElementsToUpload)) + { + return; + } + + MakeContextCurrent(); + gl->fUniformMatrix4x3fv(rawLoc, numElementsToUpload, transpose, data); } void WebGL2Context::VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) { if (IsContextLost()) return;
--- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -810,69 +810,69 @@ public: UniformMatrix2fv_base(loc, transpose, value.Length(), value.Data()); } void UniformMatrix2fv(WebGLUniformLocation* loc, WebGLboolean transpose, const dom::Sequence<float>& value) { UniformMatrix2fv_base(loc, transpose, value.Length(), value.Elements()); } - void UniformMatrix2fv_base(WebGLUniformLocation* loc, - WebGLboolean transpose, size_t arrayLength, - const float* data); + void UniformMatrix2fv_base(WebGLUniformLocation* loc, bool transpose, + size_t arrayLength, const float* data); void UniformMatrix3fv(WebGLUniformLocation* loc, WebGLboolean transpose, const dom::Float32Array& value) { value.ComputeLengthAndData(); UniformMatrix3fv_base(loc, transpose, value.Length(), value.Data()); } void UniformMatrix3fv(WebGLUniformLocation* loc, WebGLboolean transpose, const dom::Sequence<float>& value) { UniformMatrix3fv_base(loc, transpose, value.Length(), value.Elements()); } - void UniformMatrix3fv_base(WebGLUniformLocation* loc, - WebGLboolean transpose, size_t arrayLength, - const float* data); + void UniformMatrix3fv_base(WebGLUniformLocation* loc, bool transpose, + size_t arrayLength, const float* data); void UniformMatrix4fv(WebGLUniformLocation* loc, WebGLboolean transpose, const dom::Float32Array& value) { value.ComputeLengthAndData(); UniformMatrix4fv_base(loc, transpose, value.Length(), value.Data()); } - void UniformMatrix4fv(WebGLUniformLocation* loc, WebGLboolean transpose, + void UniformMatrix4fv(WebGLUniformLocation* loc, bool transpose, const dom::Sequence<float>& value) { UniformMatrix4fv_base(loc, transpose, value.Length(), value.Elements()); } - void UniformMatrix4fv_base(WebGLUniformLocation* loc, - WebGLboolean transpose, size_t arrayLength, - const float* data); + void UniformMatrix4fv_base(WebGLUniformLocation* loc, bool transpose, + size_t arrayLength, const float* data); void UseProgram(WebGLProgram* prog); bool ValidateAttribArraySetter(const char* name, uint32_t count, uint32_t arrayLength); bool ValidateUniformLocation(WebGLUniformLocation* loc, const char* funcName); bool ValidateUniformSetter(WebGLUniformLocation* loc, uint8_t setterSize, GLenum setterType, const char* info, GLuint* out_rawLoc); bool ValidateUniformArraySetter(WebGLUniformLocation* loc, uint8_t setterElemSize, GLenum setterType, size_t setterArraySize, const char* info, GLuint* out_rawLoc, GLsizei* out_numElementsToUpload); bool ValidateUniformMatrixArraySetter(WebGLUniformLocation* loc, - uint8_t setterDims, GLenum setterType, + uint8_t setterCols, + uint8_t setterRows, + GLenum setterType, size_t setterArraySize, bool setterTranspose, - const char* info, GLuint* out_rawLoc, + const char* info, + GLuint* out_rawLoc, GLsizei* out_numElementsToUpload); void ValidateProgram(WebGLProgram* prog); bool ValidateUniformLocation(const char* info, WebGLUniformLocation* loc); bool ValidateSamplerUniformSetter(const char* info, WebGLUniformLocation* loc, GLint value); void Viewport(GLint x, GLint y, GLsizei width, GLsizei height); // ----------------------------------------------------------------------------- // WEBGL_lose_context @@ -1384,16 +1384,17 @@ private: private: // ------------------------------------------------------------------------- // Context customization points virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) = 0; virtual bool ValidateBufferTarget(GLenum target, const char* info) = 0; virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) = 0; virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info) = 0; + virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) = 0; protected: int32_t MaxTextureSizeForTarget(TexTarget target) const { return (target == LOCAL_GL_TEXTURE_2D) ? mGLMaxTextureSize : mGLMaxCubeMapTextureSize; } int32_t @@ -1586,16 +1587,17 @@ public: friend class WebGLTexture; friend class WebGLFramebuffer; friend class WebGLRenderbuffer; friend class WebGLProgram; friend class WebGLQuery; friend class WebGLBuffer; friend class WebGLSampler; friend class WebGLShader; + friend class WebGLSync; friend class WebGLTransformFeedback; friend class WebGLUniformLocation; friend class WebGLVertexArray; friend class WebGLVertexArrayFake; friend class WebGLVertexArrayGL; }; // used by DOM bindings in conjunction with GetParentObject
--- a/dom/canvas/WebGLContextGL.cpp +++ b/dom/canvas/WebGLContextGL.cpp @@ -2799,51 +2799,51 @@ WebGLContext::Uniform4fv_base(WebGLUnifo // Matrix void WebGLContext::UniformMatrix2fv_base(WebGLUniformLocation* loc, bool transpose, size_t arrayLength, const float* data) { GLuint rawLoc; GLsizei numElementsToUpload; - if (!ValidateUniformMatrixArraySetter(loc, 2, LOCAL_GL_FLOAT, arrayLength, + if (!ValidateUniformMatrixArraySetter(loc, 2, 2, LOCAL_GL_FLOAT, arrayLength, transpose, "uniformMatrix2fv", &rawLoc, &numElementsToUpload)) { return; } MakeContextCurrent(); gl->fUniformMatrix2fv(rawLoc, numElementsToUpload, false, data); } void WebGLContext::UniformMatrix3fv_base(WebGLUniformLocation* loc, bool transpose, size_t arrayLength, const float* data) { GLuint rawLoc; GLsizei numElementsToUpload; - if (!ValidateUniformMatrixArraySetter(loc, 3, LOCAL_GL_FLOAT, arrayLength, + if (!ValidateUniformMatrixArraySetter(loc, 3, 3, LOCAL_GL_FLOAT, arrayLength, transpose, "uniformMatrix3fv", &rawLoc, &numElementsToUpload)) { return; } MakeContextCurrent(); gl->fUniformMatrix3fv(rawLoc, numElementsToUpload, false, data); } void WebGLContext::UniformMatrix4fv_base(WebGLUniformLocation* loc, bool transpose, size_t arrayLength, const float* data) { GLuint rawLoc; GLsizei numElementsToUpload; - if (!ValidateUniformMatrixArraySetter(loc, 4, LOCAL_GL_FLOAT, arrayLength, + if (!ValidateUniformMatrixArraySetter(loc, 4, 4, LOCAL_GL_FLOAT, arrayLength, transpose, "uniformMatrix4fv", &rawLoc, &numElementsToUpload)) { return; } MakeContextCurrent(); gl->fUniformMatrix4fv(rawLoc, numElementsToUpload, false, data);
--- a/dom/canvas/WebGLContextValidate.cpp +++ b/dom/canvas/WebGLContextValidate.cpp @@ -1534,42 +1534,41 @@ WebGLContext::ValidateUniformArraySetter *out_rawLoc = loc->mLoc; *out_numElementsToUpload = std::min((size_t)loc->mActiveInfo->mElemCount, setterArraySize / setterElemSize); return true; } bool WebGLContext::ValidateUniformMatrixArraySetter(WebGLUniformLocation* loc, - uint8_t setterDims, + uint8_t setterCols, + uint8_t setterRows, GLenum setterType, size_t setterArraySize, bool setterTranspose, const char* funcName, GLuint* const out_rawLoc, GLsizei* const out_numElementsToUpload) { - uint8_t setterElemSize = setterDims * setterDims; + uint8_t setterElemSize = setterCols * setterRows; if (IsContextLost()) return false; if (!ValidateUniformLocation(loc, funcName)) return false; if (!loc->ValidateSizeAndType(setterElemSize, setterType, this, funcName)) return false; if (!loc->ValidateArrayLength(setterElemSize, setterArraySize, this, funcName)) return false; - if (setterTranspose) { - ErrorInvalidValue("%s: `transpose` must be false.", funcName); + if (!ValidateUniformMatrixTranspose(setterTranspose, funcName)) return false; - } *out_rawLoc = loc->mLoc; *out_numElementsToUpload = std::min((size_t)loc->mActiveInfo->mElemCount, setterArraySize / setterElemSize); return true; } bool
--- a/dom/canvas/WebGLRenderbuffer.cpp +++ b/dom/canvas/WebGLRenderbuffer.cpp @@ -174,16 +174,18 @@ RenderbufferStorageMaybeMultisample(gl:: height); } } void WebGLRenderbuffer::RenderbufferStorage(GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height) const { + MOZ_ASSERT(mContext->mBoundRenderbuffer == this); + gl::GLContext* gl = mContext->gl; MOZ_ASSERT(samples >= 0 && samples <= 256); // Sanity check. GLenum primaryFormat = internalFormat; GLenum secondaryFormat = 0; if (NeedsDepthStencilEmu(mContext->gl, primaryFormat)) { primaryFormat = DepthStencilDepthFormat(gl);
--- a/dom/canvas/WebGLSync.cpp +++ b/dom/canvas/WebGLSync.cpp @@ -4,36 +4,40 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "WebGLSync.h" #include "mozilla/dom/WebGL2RenderingContextBinding.h" namespace mozilla { -WebGLSync::WebGLSync(WebGLContext* webgl): - WebGLContextBoundObject(webgl) +WebGLSync::WebGLSync(WebGLContext* webgl, GLenum condition, GLbitfield flags) + : WebGLContextBoundObject(webgl) { - MOZ_CRASH("Not Implemented."); + mGLName = mContext->gl->fFenceSync(condition, flags); } WebGLSync::~WebGLSync() -{} +{ + DeleteOnce(); +} void WebGLSync::Delete() { - MOZ_CRASH("Not Implemented."); + mContext->MakeContextCurrent(); + mContext->gl->fDeleteSync(mGLName); + mGLName = 0; + LinkedListElement<WebGLSync>::remove(); } WebGLContext* WebGLSync::GetParentObject() const { - MOZ_CRASH("Not Implemented."); - return nullptr; + return Context(); } // ------------------------------------------------------------------------- // IMPLEMENT NS JSObject* WebGLSync::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) { return dom::WebGLSyncBinding::Wrap(cx, this, aGivenProto);
--- a/dom/canvas/WebGLSync.h +++ b/dom/canvas/WebGLSync.h @@ -16,25 +16,27 @@ class WebGLSync final : public nsWrapperCache , public WebGLRefCountedObject<WebGLSync> , public LinkedListElement<WebGLSync> , public WebGLContextBoundObject { friend class WebGL2Context; public: - explicit WebGLSync(WebGLContext* webgl); + WebGLSync(WebGLContext* webgl, GLenum condition, GLbitfield flags); void Delete(); WebGLContext* GetParentObject() const; virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override; NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSync) NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSync) private: ~WebGLSync(); + + GLsync mGLName; }; } // namespace mozilla #endif // WEBGL_SYNC_H_
--- a/dom/canvas/WebGLTexture.cpp +++ b/dom/canvas/WebGLTexture.cpp @@ -594,20 +594,20 @@ ClearWithTempFB(WebGLContext* webgl, GLu if (mask & LOCAL_GL_COLOR_BUFFER_BIT) { // Nope, it already had one. return false; } gl::ScopedRenderbuffer rb(gl); { - gl::ScopedBindRenderbuffer(gl, rb.RB()); - gl->fRenderbufferStorage(LOCAL_GL_RENDERBUFFER, - LOCAL_GL_RGBA4, - width, height); + // Only GLES guarantees RGBA4. + GLenum format = gl->IsGLES() ? LOCAL_GL_RGBA4 : LOCAL_GL_RGBA8; + gl::ScopedBindRenderbuffer rbBinding(gl, rb.RB()); + gl->fRenderbufferStorage(LOCAL_GL_RENDERBUFFER, format, width, height); } gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0, LOCAL_GL_RENDERBUFFER, rb.RB()); mask |= LOCAL_GL_COLOR_BUFFER_BIT; // Last chance! return ClearByMask(webgl, mask);
--- a/dom/canvas/WebGLUniformLocation.cpp +++ b/dom/canvas/WebGLUniformLocation.cpp @@ -45,59 +45,77 @@ WebGLUniformLocation::ValidateForProgram } return true; } static bool IsUniformSetterTypeValid(GLenum setterType, GLenum uniformType) { + // The order in this switch matches table 2.10 from OpenGL ES + // 3.0.4 (Aug 27, 2014) es_spec_3.0.4.pdf switch (uniformType) { + case LOCAL_GL_FLOAT: + case LOCAL_GL_FLOAT_VEC2: + case LOCAL_GL_FLOAT_VEC3: + case LOCAL_GL_FLOAT_VEC4: + return setterType == LOCAL_GL_FLOAT; + + case LOCAL_GL_INT: + case LOCAL_GL_INT_VEC2: + case LOCAL_GL_INT_VEC3: + case LOCAL_GL_INT_VEC4: + return setterType == LOCAL_GL_INT; + + case LOCAL_GL_UNSIGNED_INT: + case LOCAL_GL_UNSIGNED_INT_VEC2: + case LOCAL_GL_UNSIGNED_INT_VEC3: + case LOCAL_GL_UNSIGNED_INT_VEC4: + return setterType == LOCAL_GL_UNSIGNED_INT; + + /* bool can be set via any function: 0, 0.0f -> FALSE, _ -> TRUE */ case LOCAL_GL_BOOL: case LOCAL_GL_BOOL_VEC2: case LOCAL_GL_BOOL_VEC3: case LOCAL_GL_BOOL_VEC4: - return setterType == LOCAL_GL_INT || - setterType == LOCAL_GL_FLOAT; // GLfloat(0.0) sets a bool to false. + return (setterType == LOCAL_GL_INT || + setterType == LOCAL_GL_FLOAT || + setterType == LOCAL_GL_UNSIGNED_INT); - case LOCAL_GL_INT: - case LOCAL_GL_INT_SAMPLER_2D: - case LOCAL_GL_INT_SAMPLER_2D_ARRAY: - case LOCAL_GL_INT_SAMPLER_3D: - case LOCAL_GL_INT_SAMPLER_CUBE: - case LOCAL_GL_INT_VEC2: - case LOCAL_GL_INT_VEC3: - case LOCAL_GL_INT_VEC4: + case LOCAL_GL_FLOAT_MAT2: + case LOCAL_GL_FLOAT_MAT3: + case LOCAL_GL_FLOAT_MAT4: + case LOCAL_GL_FLOAT_MAT2x3: + case LOCAL_GL_FLOAT_MAT2x4: + case LOCAL_GL_FLOAT_MAT3x2: + case LOCAL_GL_FLOAT_MAT3x4: + case LOCAL_GL_FLOAT_MAT4x2: + case LOCAL_GL_FLOAT_MAT4x3: + return setterType == LOCAL_GL_FLOAT; + + /* Samplers can only be set via Uniform1i */ case LOCAL_GL_SAMPLER_2D: + case LOCAL_GL_SAMPLER_3D: + case LOCAL_GL_SAMPLER_CUBE: + case LOCAL_GL_SAMPLER_2D_SHADOW: case LOCAL_GL_SAMPLER_2D_ARRAY: case LOCAL_GL_SAMPLER_2D_ARRAY_SHADOW: - case LOCAL_GL_SAMPLER_2D_SHADOW: - case LOCAL_GL_SAMPLER_CUBE: case LOCAL_GL_SAMPLER_CUBE_SHADOW: + + case LOCAL_GL_INT_SAMPLER_2D: + case LOCAL_GL_INT_SAMPLER_3D: + case LOCAL_GL_INT_SAMPLER_CUBE: + case LOCAL_GL_INT_SAMPLER_2D_ARRAY: + case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D: - case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: case LOCAL_GL_UNSIGNED_INT_SAMPLER_3D: case LOCAL_GL_UNSIGNED_INT_SAMPLER_CUBE: + case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: return setterType == LOCAL_GL_INT; - case LOCAL_GL_FLOAT: - case LOCAL_GL_FLOAT_MAT2: - case LOCAL_GL_FLOAT_MAT2x3: - case LOCAL_GL_FLOAT_MAT2x4: - case LOCAL_GL_FLOAT_MAT3: - case LOCAL_GL_FLOAT_MAT3x2: - case LOCAL_GL_FLOAT_MAT3x4: - case LOCAL_GL_FLOAT_MAT4: - case LOCAL_GL_FLOAT_MAT4x2: - case LOCAL_GL_FLOAT_MAT4x3: - case LOCAL_GL_FLOAT_VEC2: - case LOCAL_GL_FLOAT_VEC3: - case LOCAL_GL_FLOAT_VEC4: - return setterType == LOCAL_GL_FLOAT; - default: MOZ_CRASH("Bad `uniformType`."); } } bool WebGLUniformLocation::ValidateSizeAndType(uint8_t setterElemSize, GLenum setterType, WebGLContext* webgl, const char* funcName) const
--- a/dom/datastore/DataStoreService.cpp +++ b/dom/datastore/DataStoreService.cpp @@ -1015,20 +1015,22 @@ DataStoreService::GetDataStoresResolve(n nsRefPtr<DataStore> exposedStore = new DataStore(aWindow); ErrorResult error; exposedStore->SetDataStoreImpl(*dataStoreObj, error); if (error.Failed()) { return; } - JS::Rooted<JSObject*> obj(cx, exposedStore->WrapObject(cx, JS::NullPtr())); - MOZ_ASSERT(obj); + JS::Rooted<JS::Value> exposedObject(cx); + if (!GetOrCreateDOMReflector(cx, exposedStore, &exposedObject)) { + JS_ClearPendingException(cx); + return; + } - JS::Rooted<JS::Value> exposedObject(cx, JS::ObjectValue(*obj)); dataStore->SetExposedObject(exposedObject); counter->AppendDataStore(cx, exposedStore, dataStore); } } // Thie method populates 'aStores' with the list of DataStores with 'aName' as // name and available for this 'aAppId'.
--- a/dom/html/HTMLAudioElement.cpp +++ b/dom/html/HTMLAudioElement.cpp @@ -38,17 +38,18 @@ HTMLAudioElement::HTMLAudioElement(alrea HTMLAudioElement::~HTMLAudioElement() { } bool HTMLAudioElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const { - return HasAttr(kNameSpaceID_None, nsGkAtoms::controls); + return HasAttr(kNameSpaceID_None, nsGkAtoms::controls) || + HTMLMediaElement::IsInteractiveHTMLContent(aIgnoreTabindex); } already_AddRefed<HTMLAudioElement> HTMLAudioElement::Audio(const GlobalObject& aGlobal, const Optional<nsAString>& aSrc, ErrorResult& aRv) { nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aGlobal.GetAsSupports());
--- a/dom/html/HTMLImageElement.cpp +++ b/dom/html/HTMLImageElement.cpp @@ -146,17 +146,18 @@ NS_IMPL_STRING_ATTR(HTMLImageElement, Lo NS_IMPL_URI_ATTR(HTMLImageElement, Src, src) NS_IMPL_STRING_ATTR(HTMLImageElement, Srcset, srcset) NS_IMPL_STRING_ATTR(HTMLImageElement, UseMap, usemap) NS_IMPL_INT_ATTR(HTMLImageElement, Vspace, vspace) bool HTMLImageElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const { - return HasAttr(kNameSpaceID_None, nsGkAtoms::usemap); + return HasAttr(kNameSpaceID_None, nsGkAtoms::usemap) || + nsGenericHTMLElement::IsInteractiveHTMLContent(aIgnoreTabindex); } bool HTMLImageElement::IsSrcsetEnabled() { return Preferences::GetBool(kPrefSrcsetEnabled, false); }
--- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -3219,17 +3219,18 @@ HTMLInputElement::Focus(ErrorResult& aEr } return; } bool HTMLInputElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const { - return mType != NS_FORM_INPUT_HIDDEN; + return mType != NS_FORM_INPUT_HIDDEN || + nsGenericHTMLFormElementWithState::IsInteractiveHTMLContent(aIgnoreTabindex); } NS_IMETHODIMP HTMLInputElement::Select() { if (mType == NS_FORM_INPUT_NUMBER) { nsNumberControlFrame* numberControlFrame = do_QueryFrame(GetPrimaryFrame());
--- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -3231,23 +3231,23 @@ void HTMLMediaElement::PlaybackEnded() void HTMLMediaElement::SeekStarted() { DispatchAsyncEvent(NS_LITERAL_STRING("seeking")); // Set the Variable if the Seekstarted while active playing if(mPlayingThroughTheAudioChannel) { mPlayingThroughTheAudioChannelBeforeSeek = true; } - FireTimeUpdate(false); } void HTMLMediaElement::SeekCompleted() { mPlayingBeforeSeek = false; SetPlayedOrSeeked(true); + FireTimeUpdate(false); DispatchAsyncEvent(NS_LITERAL_STRING("seeked")); // We changed whether we're seeking so we need to AddRemoveSelfReference AddRemoveSelfReference(); if (mTextTrackManager) { mTextTrackManager->DidSeek(); } if (mCurrentPlayRangeStart == -1.0) { mCurrentPlayRangeStart = CurrentTime();
--- a/dom/html/HTMLObjectElement.cpp +++ b/dom/html/HTMLObjectElement.cpp @@ -47,17 +47,18 @@ HTMLObjectElement::~HTMLObjectElement() { UnregisterActivityObserver(); DestroyImageLoadingContent(); } bool HTMLObjectElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const { - return HasAttr(kNameSpaceID_None, nsGkAtoms::usemap); + return HasAttr(kNameSpaceID_None, nsGkAtoms::usemap) || + nsGenericHTMLFormElement::IsInteractiveHTMLContent(aIgnoreTabindex); } bool HTMLObjectElement::IsDoneAddingChildren() { return mIsDoneAddingChildren; }
--- a/dom/html/HTMLVideoElement.cpp +++ b/dom/html/HTMLVideoElement.cpp @@ -124,17 +124,18 @@ nsresult HTMLVideoElement::SetAcceptHead return aChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"), value, false); } bool HTMLVideoElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const { - return HasAttr(kNameSpaceID_None, nsGkAtoms::controls); + return HasAttr(kNameSpaceID_None, nsGkAtoms::controls) || + HTMLMediaElement::IsInteractiveHTMLContent(aIgnoreTabindex); } uint32_t HTMLVideoElement::MozParsedFrames() const { MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread."); if (!sVideoStatsEnabled) { return 0; }
--- a/dom/html/test/forms/test_interactive_content_in_label.html +++ b/dom/html/test/forms/test_interactive_content_in_label.html @@ -13,71 +13,54 @@ https://bugzilla.mozilla.org/show_bug.cg <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=229925">Mozilla Bug 229925</a> <p id="display"></p> <form action="#"> <label> <span id="text">label</span> <input type="button" id="target" value="target"> - <a id="yes1" href="#">a</a> - <audio id="yes2" controls></audio> - <button id="yes3">button</button> - <details id="yes4">details</details> - <embed id="yes5">embed</embed> - <iframe id="yes6" src="data:text/plain," style="width: 16px; height: 16px;"></iframe> - <img id="yes7" src="data:image/png," usemap="#map"> - <input id="yes8" type="text" size="4"> - <keygen id="yes9"> - <label id="yes10">label</label> - <object id="yes11" usemap="#map">object</object> - <select id="yes12"><option>select</option></select> - <textarea id="yes13" cols="1" rows="1"></textarea> - <video id="yes14" controls></video> + <a class="yes" href="#">a</a> + <audio class="yes" controls></audio> + <button class="yes">button</button> + <details class="yes">details</details> + <embed class="yes">embed</embed> + <iframe class="yes" src="data:text/plain," style="width: 16px; height: 16px;"></iframe> + <img class="yes" src="data:image/png," usemap="#map"> + <input class="yes" type="text" size="4"> + <keygen class="yes"> + <label class="yes">label</label> + <object class="yes" usemap="#map">object</object> + <select class="yes"><option>select</option></select> + <textarea class="yes" cols="1" rows="1"></textarea> + <video class="yes" controls></video> - <audio id="no1"></audio> - <img id="no2" src="data:image/png,"> - <input id="no3" type="hidden"> - <object id="no4">object</object> - <video id="no5"></video> - <span id="no6" tabindex="1">tabindex</span> + <audio class="no"></audio> + <img class="no" src="data:image/png,"> + <input class="no" type="hidden"> + <object class="no">object</object> + <video class="no"></video> + + <span class="no" tabindex="1">tabindex</span> + <audio class="no" tabindex="1"></audio> + <img class="no" src="data:image/png," tabindex="1"> + <input class="no" type="hidden" tabindex="1"> + <object class="no" tabindex="1">object</object> + <video class="no" tabindex="1"></video> </label> </form> <script class="testbody" type="text/javascript"> /** Test for Bug 229925 **/ var target = document.getElementById("target"); -var yes_nodes = [ - document.getElementById("yes1"), - document.getElementById("yes2"), - document.getElementById("yes3"), - document.getElementById("yes4"), - document.getElementById("yes5"), - document.getElementById("yes6"), - document.getElementById("yes7"), - document.getElementById("yes8"), - document.getElementById("yes9"), - document.getElementById("yes10"), - document.getElementById("yes11"), - document.getElementById("yes12"), - document.getElementById("yes13"), - document.getElementById("yes14"), -]; +var yes_nodes = Array.from(document.getElementsByClassName("yes")); -var no_nodes = [ - document.getElementById("text"), - document.getElementById("no1"), - document.getElementById("no2"), - document.getElementById("no3"), - document.getElementById("no4"), - document.getElementById("no5"), - document.getElementById("no6"), -]; +var no_nodes = Array.from(document.getElementsByClassName("no")); var target_clicked = false; target.addEventListener("click", function() { target_clicked = true; }); var node; for (node of yes_nodes) {
--- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -2527,17 +2527,17 @@ MediaDecoderStateMachine::SeekCompleted( mPlayDuration = newCurrentTime - mStartTime; mDecoder->StartProgressUpdates(); // Change state to DECODING or COMPLETED now. SeekingStopped will // call MediaDecoderStateMachine::Seek to reset our state to SEEKING // if we need to seek again. - bool isLiveStream = mDecoder->GetResource()->GetLength() == -1; + bool isLiveStream = mDecoder->GetResource()->IsLiveStream(); if (mPendingSeek.Exists()) { // A new seek target came in while we were processing the old one. No rest // for the seeking. DECODER_LOG("A new seek came along while we were finishing the old one - staying in SEEKING"); SetState(DECODER_STATE_SEEKING); } else if (GetMediaTime() == mEndTime && !isLiveStream) { // Seeked to end of media, move to COMPLETED state. Note we don't do // this if we're playing a live stream, since the end of media will advance @@ -2735,17 +2735,17 @@ nsresult MediaDecoderStateMachine::RunSt TimeStamp now = TimeStamp::Now(); NS_ASSERTION(!mBufferingStart.IsNull(), "Must know buffering start time."); // With buffering heuristics we will remain in the buffering state if // we've not decoded enough data to begin playback, or if we've not // downloaded a reasonable amount of data inside our buffering time. if (mReader->UseBufferingHeuristics()) { TimeDuration elapsed = now - mBufferingStart; - bool isLiveStream = resource->GetLength() == -1; + bool isLiveStream = resource->IsLiveStream(); if ((isLiveStream || !mDecoder->CanPlayThrough()) && elapsed < TimeDuration::FromSeconds(mBufferingWait * mPlaybackRate) && (mQuickBuffering ? HasLowDecodedData(mQuickBufferingLowDataThresholdUsecs) : HasLowUndecodedData(mBufferingWait * USECS_PER_S)) && mDecoder->IsExpectingMoreData()) { DECODER_LOG("Buffering: wait %ds, timeout in %.3lfs %s", mBufferingWait, mBufferingWait - elapsed.ToSeconds(),
--- a/dom/media/MediaResource.h +++ b/dom/media/MediaResource.h @@ -408,16 +408,22 @@ public: return nullptr; } // Return true if the stream is a live stream virtual bool IsRealTime() { return false; } + // Returns true if the resource is a live stream. + virtual bool IsLiveStream() + { + return GetLength() == -1; + } + virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { return 0; } virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); }
--- a/dom/media/fmp4/apple/AppleATDecoder.cpp +++ b/dom/media/fmp4/apple/AppleATDecoder.cpp @@ -150,18 +150,16 @@ static OSStatus void* aUserData) { PassthroughUserData* userData = (PassthroughUserData*)aUserData; if (!userData->mDataSize) { *aNumDataPackets = 0; return kNoMoreDataErr; } - LOG("AudioConverter wants %u packets of audio data\n", *aNumDataPackets); - if (aPacketDesc) { userData->mPacket.mStartOffset = 0; userData->mPacket.mVariableFramesInPacket = 0; userData->mPacket.mDataByteSize = userData->mDataSize; *aPacketDesc = &userData->mPacket; } aData->mBuffers[0].mNumberChannels = userData->mChannels; @@ -248,40 +246,40 @@ AppleATDecoder::DecodeSample(mp4_demuxer if (rv && rv != kNoMoreDataErr) { LOG("Error decoding audio stream: %d\n", rv); return NS_ERROR_FAILURE; } if (numFrames) { outputData.AppendElements(decoded.get(), numFrames * channels); - LOG("%d frames decoded", numFrames); } if (rv == kNoMoreDataErr) { - LOG("done processing compressed packet"); break; } } while (true); if (outputData.IsEmpty()) { return NS_OK; } size_t numFrames = outputData.Length() / channels; int rate = mOutputFormat.mSampleRate; CheckedInt<Microseconds> duration = FramesToUsecs(numFrames, rate); if (!duration.isValid()) { NS_WARNING("Invalid count of accumulated audio samples"); return NS_ERROR_FAILURE; } +#ifdef LOG_SAMPLE_DECODE LOG("pushed audio at time %lfs; duration %lfs\n", (double)aSample->composition_timestamp / USECS_PER_S, (double)duration.value() / USECS_PER_S); +#endif nsAutoArrayPtr<AudioDataValue> data(new AudioDataValue[outputData.Length()]); PodCopy(data.get(), &outputData[0], outputData.Length()); nsRefPtr<AudioData> audio = new AudioData(aSample->byte_offset, aSample->composition_timestamp, duration.value(), numFrames, data.forget(),
--- a/dom/media/mediasource/MediaSource.cpp +++ b/dom/media/mediasource/MediaSource.cpp @@ -292,25 +292,24 @@ MediaSource::EndOfStream(const Optional< if (mReadyState != MediaSourceReadyState::Open || mSourceBuffers->AnyUpdating()) { aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } SetReadyState(MediaSourceReadyState::Ended); mSourceBuffers->Ended(); - mDecoder->Ended(); if (!aError.WasPassed()) { mDecoder->SetMediaSourceDuration(mSourceBuffers->GetHighestBufferedEndTime(), MSRangeRemovalAction::SKIP); if (aRv.Failed()) { return; } - // TODO: - // Notify media element that all data is now available. + // Notify reader that all data is now available. + mDecoder->Ended(true); return; } switch (aError.Value()) { case MediaSourceEndOfStreamError::Network: // TODO: If media element has a readyState of: // HAVE_NOTHING -> run resource fetch algorithm // > HAVE_NOTHING -> run "interrupted" steps of resource fetch break; @@ -451,16 +450,20 @@ MediaSource::SetReadyState(MediaSourceRe MediaSourceReadyState oldState = mReadyState; mReadyState = aState; if (mReadyState == MediaSourceReadyState::Open && (oldState == MediaSourceReadyState::Closed || oldState == MediaSourceReadyState::Ended)) { QueueAsyncSimpleEvent("sourceopen"); + if (oldState == MediaSourceReadyState::Ended) { + // Notify reader that more data may come. + mDecoder->Ended(false); + } return; } if (mReadyState == MediaSourceReadyState::Ended && oldState == MediaSourceReadyState::Open) { QueueAsyncSimpleEvent("sourceended"); return; }
--- a/dom/media/mediasource/MediaSourceDecoder.cpp +++ b/dom/media/mediasource/MediaSourceDecoder.cpp @@ -151,20 +151,21 @@ MediaSourceDecoder::RemoveTrackBuffer(Tr void MediaSourceDecoder::OnTrackBufferConfigured(TrackBuffer* aTrackBuffer, const MediaInfo& aInfo) { MOZ_ASSERT(mReader); mReader->OnTrackBufferConfigured(aTrackBuffer, aInfo); } void -MediaSourceDecoder::Ended() +MediaSourceDecoder::Ended(bool aEnded) { ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); - mReader->Ended(); + static_cast<MediaSourceResource*>(GetResource())->SetEnded(aEnded); + mReader->Ended(aEnded); mon.NotifyAll(); } bool MediaSourceDecoder::IsExpectingMoreData() { ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); return !mReader->IsEnded();
--- a/dom/media/mediasource/MediaSourceDecoder.h +++ b/dom/media/mediasource/MediaSourceDecoder.h @@ -48,17 +48,17 @@ public: void DetachMediaSource(); already_AddRefed<SourceBufferDecoder> CreateSubDecoder(const nsACString& aType, int64_t aTimestampOffset /* microseconds */); void AddTrackBuffer(TrackBuffer* aTrackBuffer); void RemoveTrackBuffer(TrackBuffer* aTrackBuffer); void OnTrackBufferConfigured(TrackBuffer* aTrackBuffer, const MediaInfo& aInfo); - void Ended(); + void Ended(bool aEnded); bool IsExpectingMoreData() override; // Return the duration of the video in seconds. virtual double GetDuration() override; void SetInitialDuration(int64_t aDuration); void SetMediaSourceDuration(double aDuration, MSRangeRemovalAction aAction); double GetMediaSourceDuration();
--- a/dom/media/mediasource/MediaSourceReader.cpp +++ b/dom/media/mediasource/MediaSourceReader.cpp @@ -34,32 +34,27 @@ extern PRLogModuleInfo* GetMediaSourceLo // When a stream hits EOS it needs to decide what other stream to switch to. Due // to inaccuracies is determining buffer end frames (Bug 1065207) and rounding // issues we use a fuzz factor to determine the end time of this stream for // switching to the new stream. This value is based on the end of frame // default value used in Blink, kDefaultBufferDurationInMs. #define EOS_FUZZ_US 125000 -// Audio and video source buffers often have a slight duration -// discrepency. We want to handle the case where a source buffer is smaller than -// another by more than EOS_FUZZ_US so we can properly detect EOS in IsNearEnd(). -// This value was chosen at random, to cater for most streams seen in the wild. -#define DURATION_DIFFERENCE_FUZZ 300000 - using mozilla::dom::TimeRanges; namespace mozilla { MediaSourceReader::MediaSourceReader(MediaSourceDecoder* aDecoder) : MediaDecoderReader(aDecoder) , mLastAudioTime(0) , mLastVideoTime(0) , mPendingSeekTime(-1) , mWaitingForSeekData(false) + , mSeekToEnd(false) , mTimeThreshold(0) , mDropAudioBeforeThreshold(false) , mDropVideoBeforeThreshold(false) , mAudioDiscontinuity(false) , mVideoDiscontinuity(false) , mEnded(false) , mMediaSourceDuration(0) , mHasEssentialTrackBuffers(false) @@ -786,16 +781,18 @@ void MediaSourceReader::NotifyTimeRangesChanged() { ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); if (mWaitingForSeekData) { //post a task to the decode queue to try to complete the pending seek. RefPtr<nsIRunnable> task(NS_NewRunnableMethod( this, &MediaSourceReader::AttemptSeek)); GetTaskQueue()->Dispatch(task.forget()); + } else { + MaybeNotifyHaveData(); } } nsRefPtr<MediaDecoderReader::SeekPromise> MediaSourceReader::Seek(int64_t aTime, int64_t aIgnored /* Used only for ogg which is non-MSE */) { MSE_DEBUG("Seek(aTime=%lld, aEnd=%lld, aCurrent=%lld)", aTime); @@ -887,24 +884,28 @@ MediaSourceReader::OnVideoSeekFailed(nsr mVideoSeekRequest.Complete(); mPendingSeekTime = -1; mSeekPromise.Reject(aResult, __func__); } void MediaSourceReader::DoAudioSeek() { - if (SwitchAudioSource(&mPendingSeekTime) == SOURCE_NONE) { + int64_t seekTime = mPendingSeekTime; + if (mSeekToEnd) { + seekTime = LastSampleTime(MediaData::AUDIO_DATA); + } + if (SwitchAudioSource(&seekTime) == SOURCE_NONE) { // Data we need got evicted since the last time we checked for data // availability. Abort current seek attempt. mWaitingForSeekData = true; return; } GetAudioReader()->ResetDecode(); - mAudioSeekRequest.Begin(GetAudioReader()->Seek(GetReaderAudioTime(mPendingSeekTime), 0) + mAudioSeekRequest.Begin(GetAudioReader()->Seek(GetReaderAudioTime(seekTime), 0) ->RefableThen(GetTaskQueue(), __func__, this, &MediaSourceReader::OnAudioSeekCompleted, &MediaSourceReader::OnAudioSeekFailed)); MSE_DEBUG("reader=%p", GetAudioReader()); } void MediaSourceReader::OnAudioSeekCompleted(int64_t aTime) @@ -929,17 +930,19 @@ MediaSourceReader::AttemptSeek() { // Make sure we don't hold the monitor while calling into the reader // Seek methods since it can deadlock. { ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); if (!mWaitingForSeekData) { return; } - if (!TrackBuffersContainTime(mPendingSeekTime)) { + + mSeekToEnd = IsEnded() && mPendingSeekTime >= mMediaSourceDuration * USECS_PER_S; + if (!mSeekToEnd && !TrackBuffersContainTime(mPendingSeekTime)) { mVideoSourceDecoder = nullptr; mAudioSourceDecoder = nullptr; return; } mWaitingForSeekData = false; } // Decoding discontinuity upon seek, reset last times to seek target. @@ -953,24 +956,28 @@ MediaSourceReader::AttemptSeek() } else { MOZ_CRASH(); } } void MediaSourceReader::DoVideoSeek() { - if (SwitchVideoSource(&mPendingSeekTime) == SOURCE_NONE) { + int64_t seekTime = mPendingSeekTime; + if (mSeekToEnd) { + seekTime = LastSampleTime(MediaData::VIDEO_DATA); + } + if (SwitchVideoSource(&seekTime) == SOURCE_NONE) { // Data we need got evicted since the last time we checked for data // availability. Abort current seek attempt. mWaitingForSeekData = true; return; } GetVideoReader()->ResetDecode(); - mVideoSeekRequest.Begin(GetVideoReader()->Seek(GetReaderVideoTime(mPendingSeekTime), 0) + mVideoSeekRequest.Begin(GetVideoReader()->Seek(GetReaderVideoTime(seekTime), 0) ->RefableThen(GetTaskQueue(), __func__, this, &MediaSourceReader::OnVideoSeekCompleted, &MediaSourceReader::OnVideoSeekFailed)); MSE_DEBUG("reader=%p", GetVideoReader()); } nsresult MediaSourceReader::GetBuffered(dom::TimeRanges* aBuffered) @@ -1022,26 +1029,34 @@ MediaSourceReader::WaitForData(MediaData return p; } void MediaSourceReader::MaybeNotifyHaveData() { ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); bool haveAudio = false, haveVideo = false; - if (!IsSeeking() && mAudioTrack && HaveData(mLastAudioTime, MediaData::AUDIO_DATA)) { - haveAudio = true; - WaitPromise(MediaData::AUDIO_DATA).ResolveIfExists(MediaData::AUDIO_DATA, __func__); + bool ended = IsEnded(); + // If we are in ended mode, we will resolve any pending wait promises. + // The next Request*Data will handle END_OF_STREAM or going back into waiting + // mode. + if (!IsSeeking() && mAudioTrack) { + haveAudio = HaveData(mLastAudioTime, MediaData::AUDIO_DATA); + if (ended || haveAudio) { + WaitPromise(MediaData::AUDIO_DATA).ResolveIfExists(MediaData::AUDIO_DATA, __func__); + } } - if (!IsSeeking() && mVideoTrack && HaveData(mLastVideoTime, MediaData::VIDEO_DATA)) { - haveVideo = true; - WaitPromise(MediaData::VIDEO_DATA).ResolveIfExists(MediaData::VIDEO_DATA, __func__); + if (!IsSeeking() && mVideoTrack) { + haveVideo = HaveData(mLastVideoTime, MediaData::VIDEO_DATA); + if (ended || haveVideo) { + WaitPromise(MediaData::VIDEO_DATA).ResolveIfExists(MediaData::VIDEO_DATA, __func__); + } } - MSE_DEBUG("isSeeking=%d haveAudio=%d, haveVideo=%d", - IsSeeking(), haveAudio, haveVideo); + MSE_DEBUG("isSeeking=%d haveAudio=%d, haveVideo=%d ended=%d", + IsSeeking(), haveAudio, haveVideo, ended); } static void CombineEncryptionData(EncryptionInfo& aTo, const EncryptionInfo& aFrom) { if (!aFrom.mIsEncrypted) { return; } @@ -1122,51 +1137,60 @@ MediaSourceReader::ReadUpdatedMetadata(M const MediaInfo& info = GetVideoReader()->GetMediaInfo(); MOZ_ASSERT(info.HasVideo()); mInfo.mVideo = info.mVideo; } *aInfo = mInfo; } void -MediaSourceReader::Ended() +MediaSourceReader::Ended(bool aEnded) { mDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); - mEnded = true; + mEnded = aEnded; + if (aEnded) { + // post a task to the decode queue to try to complete any pending + // seek or wait + RefPtr<nsIRunnable> task(NS_NewRunnableMethod( + this, &MediaSourceReader::NotifyTimeRangesChanged)); + GetTaskQueue()->Dispatch(task.forget()); + } } bool MediaSourceReader::IsEnded() { ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); return mEnded; } bool MediaSourceReader::IsNearEnd(MediaData::Type aType, int64_t aTime) { ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); if (!mEnded) { return false; } - if (aTime >= (mMediaSourceDuration * USECS_PER_S - EOS_FUZZ_US)) { - return true; - } - // We may have discrepencies between the mediasource duration and the - // sourcebuffer end time (mMediaSourceDuration == max(audio.EndTime, video.EndTime) - // If the sourcebuffer duration is close enough to the mediasource duration, - // then use it instead to determine if we're near the end. TrackBuffer* trackBuffer = aType == MediaData::AUDIO_DATA ? mAudioTrack : mVideoTrack; nsRefPtr<dom::TimeRanges> buffered = new dom::TimeRanges(); trackBuffer->Buffered(buffered); - if ((mMediaSourceDuration - buffered->GetEndTime()) * USECS_PER_S <= DURATION_DIFFERENCE_FUZZ) { - return aTime >= std::floor(buffered->GetEndTime() * USECS_PER_S); - } - return false; + return aTime >= (buffered->GetEndTime() * USECS_PER_S - EOS_FUZZ_US); +} + +int64_t +MediaSourceReader::LastSampleTime(MediaData::Type aType) +{ + ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); + + TrackBuffer* trackBuffer = + aType == MediaData::AUDIO_DATA ? mAudioTrack : mVideoTrack; + nsRefPtr<dom::TimeRanges> buffered = new dom::TimeRanges(); + trackBuffer->Buffered(buffered); + return buffered->GetEndTime() * USECS_PER_S - 1; } void MediaSourceReader::SetMediaSourceDuration(double aDuration) { ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); mMediaSourceDuration = aDuration; }
--- a/dom/media/mediasource/MediaSourceReader.h +++ b/dom/media/mediasource/MediaSourceReader.h @@ -130,21 +130,21 @@ public: ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor()); return mDecoder->IsShutdown(); } // Return true if all of the active tracks contain data for the specified time. bool TrackBuffersContainTime(int64_t aTime); // Mark the reader to indicate that EndOfStream has been called on our MediaSource - void Ended(); - - // Return true if the Ended method has been called + // and that the media element has all the media data. + // If called with true, the reader will come out of ended mode. + void Ended(bool aEnded); + // Return true if reader has all of the media data. bool IsEnded(); - bool IsNearEnd(MediaData::Type aType, int64_t aTime /* microseconds */); // Set the duration of the attached mediasource element. void SetMediaSourceDuration(double aDuration /* seconds */); #ifdef MOZ_EME nsresult SetCDMProxy(CDMProxy* aProxy); #endif @@ -222,16 +222,19 @@ private: already_AddRefed<SourceBufferDecoder> SelectDecoder(int64_t aTarget /* microseconds */, int64_t aTolerance /* microseconds */, const nsTArray<nsRefPtr<SourceBufferDecoder>>& aTrackDecoders); bool HaveData(int64_t aTarget, MediaData::Type aType); void AttemptSeek(); bool IsSeeking() { return mPendingSeekTime != -1; } + bool IsNearEnd(MediaData::Type aType, int64_t aTime /* microseconds */); + int64_t LastSampleTime(MediaData::Type aType); + nsRefPtr<SourceBufferDecoder> mAudioSourceDecoder; nsRefPtr<SourceBufferDecoder> mVideoSourceDecoder; nsTArray<nsRefPtr<TrackBuffer>> mTrackBuffers; nsTArray<nsRefPtr<TrackBuffer>> mShutdownTrackBuffers; nsTArray<nsRefPtr<TrackBuffer>> mEssentialTrackBuffers; nsRefPtr<TrackBuffer> mAudioTrack; nsRefPtr<TrackBuffer> mVideoTrack; @@ -260,16 +263,17 @@ private: MediaPromiseConsumerHolder<SeekPromise> mAudioSeekRequest; MediaPromiseConsumerHolder<SeekPromise> mVideoSeekRequest; MediaPromiseHolder<SeekPromise> mSeekPromise; // Temporary seek information while we wait for the data // to be added to the track buffer. int64_t mPendingSeekTime; bool mWaitingForSeekData; + bool mSeekToEnd; int64_t mTimeThreshold; bool mDropAudioBeforeThreshold; bool mDropVideoBeforeThreshold; bool mAudioDiscontinuity; bool mVideoDiscontinuity;
--- a/dom/media/mediasource/MediaSourceResource.h +++ b/dom/media/mediasource/MediaSourceResource.h @@ -3,16 +3,17 @@ /* 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/. */ #ifndef MOZILLA_MEDIASOURCERESOURCE_H_ #define MOZILLA_MEDIASOURCERESOURCE_H_ #include "MediaResource.h" +#include "mozilla/Monitor.h" #include "prlog.h" #ifdef PR_LOGGING extern PRLogModuleInfo* GetMediaSourceLog(); #define MSE_DEBUG(arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("MediaSourceResource(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__)) #else #define MSE_DEBUG(...) @@ -21,17 +22,20 @@ extern PRLogModuleInfo* GetMediaSourceLo #define UNIMPLEMENTED() MSE_DEBUG("UNIMPLEMENTED FUNCTION at %s:%d", __FILE__, __LINE__) namespace mozilla { class MediaSourceResource final : public MediaResource { public: explicit MediaSourceResource(nsIPrincipal* aPrincipal = nullptr) - : mPrincipal(aPrincipal) {} + : mPrincipal(aPrincipal) + , mMonitor("MediaSourceResource") + , mEnded(false) + {} virtual nsresult Close() override { return NS_OK; } virtual void Suspend(bool aCloseImmediately) override { UNIMPLEMENTED(); } virtual void Resume() override { UNIMPLEMENTED(); } virtual bool CanClone() override { UNIMPLEMENTED(); return false; } virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder) override { UNIMPLEMENTED(); return nullptr; } virtual void SetReadMode(MediaCacheStream::ReadMode aMode) override { UNIMPLEMENTED(); } virtual void SetPlaybackRate(uint32_t aBytesPerSecond) override { UNIMPLEMENTED(); } @@ -61,32 +65,45 @@ public: UNIMPLEMENTED(); aRanges.AppendElement(MediaByteRange(0, GetLength())); return NS_OK; } virtual bool IsTransportSeekable() override { return true; } virtual const nsCString& GetContentType() const override { return mType; } + virtual bool IsLiveStream() override + { + MonitorAutoLock mon(mMonitor); + return !mEnded; + } + void SetEnded(bool aEnded) + { + MonitorAutoLock mon(mMonitor); + mEnded = aEnded; + } + private: virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override { size_t size = MediaResource::SizeOfExcludingThis(aMallocSizeOf); size += mType.SizeOfExcludingThisIfUnshared(aMallocSizeOf); return size; } virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override { return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); } nsRefPtr<nsIPrincipal> mPrincipal; const nsCString mType; + Monitor mMonitor; + bool mEnded; // protected by mMonitor }; } // namespace mozilla #undef MSE_DEBUG #undef UNIMPLEMENTED #endif /* MOZILLA_MEDIASOURCERESOURCE_H_ */
--- a/dom/media/tests/mochitest/mochitest.ini +++ b/dom/media/tests/mochitest/mochitest.ini @@ -141,22 +141,26 @@ skip-if = toolkit == 'gonk' # b2g (Bug 1 skip-if = toolkit == 'gonk' # b2g (Bug 1059867) [test_peerConnection_throwInCallbacks.html] skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g) [test_peerConnection_toJSON.html] skip-if = toolkit == 'gonk' # b2g (Bug 1059867) [test_peerConnection_twoAudioStreams.html] skip-if = toolkit == 'gonk' # b2g (Bug 1059867) +[test_peerConnection_twoAudioTracksInOneStream.html] +skip-if = toolkit == 'gonk' # b2g (Bug 1059867) [test_peerConnection_twoAudioVideoStreams.html] skip-if = (toolkit == 'gonk' || (e10s && debug)) # b2g (Bug 1059867) or fd exhaustion on e10s debug intermittent (Bug 1126078) [test_peerConnection_twoAudioVideoStreamsCombined.html] skip-if = (toolkit == 'gonk' || (e10s && debug)) # b2g (Bug 1059867) or fd exhaustion on e10s debug intermittent (Bug 1126078) [test_peerConnection_twoVideoStreams.html] skip-if = (toolkit == 'gonk' || (e10s && debug)) # b2g (Bug 1059867) or fd exhaustion on e10s debug intermittent (Bug 1126078) +[test_peerConnection_twoVideoTracksInOneStream.html] +skip-if = (toolkit == 'gonk' || (e10s && debug)) # b2g (Bug 1059867) or fd exhaustion on e10s debug intermittent (Bug 1126078) [test_peerConnection_addSecondAudioStream.html] skip-if = toolkit == 'gonk' # b2g (Bug 1059867) [test_peerConnection_answererAddSecondAudioStream.html] skip-if = toolkit == 'gonk' # b2g (Bug 1059867) [test_peerConnection_removeAudioTrack.html] skip-if = toolkit == 'gonk' # b2g (Bug 1059867) [test_peerConnection_removeThenAddAudioTrack.html] skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
new file mode 100644 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_twoAudioTracksInOneStream.html @@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<html> +<head> + <script type="application/javascript" src="pc.js"></script> +</head> +<body> +<pre id="test"> +<script type="application/javascript"> + createHTML({ + bug: "1145407", + title: "Multistream: Two audio tracks in one stream" + }); + + var test; + runNetworkTest(function (options) { + test = new PeerConnectionTest(options); + test.chain.insertAfter("PC_REMOTE_GET_OFFER", [ + function PC_REMOTE_OVERRIDE_STREAM_IDS_IN_OFFER(test) { + test._local_offer.sdp = test._local_offer.sdp.replace( + /a=msid:[^\s]*/g, + "a=msid:foo"); + }, + function PC_REMOTE_OVERRIDE_EXPECTED_STREAM_IDS(test) { + Object.keys( + test.pcRemote.expectedRemoteTrackInfoById).forEach(trackId => { + test.pcRemote.expectedRemoteTrackInfoById[trackId].streamId = "foo"; + }); + } + ]); + test.chain.insertAfter("PC_LOCAL_GET_ANSWER", [ + function PC_LOCAL_OVERRIDE_STREAM_IDS_IN_ANSWER(test) { + test._remote_answer.sdp = test._remote_answer.sdp.replace( + /a=msid:[^\s]*/g, + "a=msid:foo"); + }, + function PC_LOCAL_OVERRIDE_EXPECTED_STREAM_IDS(test) { + Object.keys( + test.pcLocal.expectedRemoteTrackInfoById).forEach(trackId => { + test.pcLocal.expectedRemoteTrackInfoById[trackId].streamId = "foo"; + }); + } + ]); + test.setMediaConstraints([{audio: true}, {audio: true}], + [{audio: true}, {audio: true}]); + test.run(); + }); +</script> +</pre> +</body> +</html>
new file mode 100644 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_twoVideoTracksInOneStream.html @@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<html> +<head> + <script type="application/javascript" src="pc.js"></script> +</head> +<body> +<pre id="test"> +<script type="application/javascript"> + createHTML({ + bug: "1145407", + title: "Multistream: Two video tracks in offerer stream" + }); + + var test; + runNetworkTest(function (options) { + test = new PeerConnectionTest(options); + test.chain.insertAfter("PC_REMOTE_GET_OFFER", [ + function PC_REMOTE_OVERRIDE_STREAM_IDS_IN_OFFER(test) { + test._local_offer.sdp = test._local_offer.sdp.replace( + /a=msid:[^\s]*/g, + "a=msid:foo"); + }, + function PC_REMOTE_OVERRIDE_EXPECTED_STREAM_IDS(test) { + Object.keys( + test.pcRemote.expectedRemoteTrackInfoById).forEach(trackId => { + test.pcRemote.expectedRemoteTrackInfoById[trackId].streamId = "foo"; + }); + } + ]); + test.chain.insertAfter("PC_LOCAL_GET_ANSWER", [ + function PC_LOCAL_OVERRIDE_STREAM_IDS_IN_ANSWER(test) { + test._remote_answer.sdp = test._remote_answer.sdp.replace( + /a=msid:[^\s]*/g, + "a=msid:foo"); + }, + function PC_LOCAL_OVERRIDE_EXPECTED_STREAM_IDS(test) { + Object.keys( + test.pcLocal.expectedRemoteTrackInfoById).forEach(trackId => { + test.pcLocal.expectedRemoteTrackInfoById[trackId].streamId = "foo"; + }); + } + ]); + test.setMediaConstraints([{video: true}, {video: true}], + [{video: true}, {video: true}]); + test.run(); + }); +</script> +</pre> +</body> +</html>
--- a/dom/network/tests/test_udpsocket.html +++ b/dom/network/tests/test_udpsocket.html @@ -307,23 +307,23 @@ function testCloseBeforeOpened() { return socket.close().then(function() { ok(true, 'expected closedPromise to be resolved'); }).then(socket.opened); } function testOpenWithoutClose() { info('test for open without close'); - let opened = []; + let closed = []; for (let i = 0; i < 50; i++) { let socket = new UDPSocket(); - opened.push(socket.opened); + closed.push(socket.closed); } - return Promise.all(opened); + return Promise.all(closed); } function testBFCache() { info('test for bfcache behavior'); let socket = new UDPSocket(); return socket.opened.then(function() { @@ -372,16 +372,20 @@ function runTest() { .then(testOpenFailed) .then(testSendBeforeOpen) .then(testCloseBeforeOpened) .then(testOpenWithoutClose) .then(testBFCache) .then(function() { info('test finished'); SimpleTest.finish(); + }) + .catch(function(err) { + ok(false, 'test failed due to: ' + err); + SimpleTest.finish(); }); } window.addEventListener('load', function () { SpecialPowers.pushPermissions([ {type: 'udp-socket', allow: true, context: document}], function() { SpecialPowers.pushPrefEnv({ 'set': [
--- a/dom/plugins/test/mochitest/cocoa_focus.html +++ b/dom/plugins/test/mochitest/cocoa_focus.html @@ -10,17 +10,16 @@ window.opener.SimpleTest.is(aLeft, aRight, aMessage); } function ok(aValue, aMessage) { window.opener.SimpleTest.ok(aValue, aMessage); } function runTests() { - netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); var utils = SpecialPowers.DOMWindowUtils; var scale = utils.screenPixelsPerCSSPixel; var plugin1 = document.getElementById("plugin1"); // What we're testing. var plugin2 = document.getElementById("plugin2"); // Dummy. var plugin1Bounds = plugin1.getBoundingClientRect(); var plugin2Bounds = plugin2.getBoundingClientRect(); @@ -62,17 +61,17 @@ is(plugin1.getFocusState(), true, "(1) Plugin should have focus."); is(plugin1.getFocusEventCount(), expectedEventCount, "Focus event count should be " + expectedEventCount); // Make sure window activation state changes don't spontaneously // change plugin focus. // Blur the window. - window.blur(); + SpecialPowers.focus(opener); is(plugin1.getFocusState(), true, "(2) Plugin should still have focus."); is(plugin1.getFocusEventCount(), expectedEventCount, "Focus event count should be " + expectedEventCount); // Focus the window. window.focus(); is(plugin1.getFocusState(), true, "(3) Plugin should still have focus."); @@ -90,26 +89,26 @@ // changes that took place while the window was inactive. // Give the plugin focus (the window is already focused). utils.sendNativeMouseEvent(plugin1X * scale, plugin1Y * scale, NSLeftMouseDown, 0, plugin1); utils.sendNativeMouseEvent(plugin1X * scale, plugin1Y * scale, NSLeftMouseUp, 0, plugin1); expectedEventCount++; // Blur the window. - window.blur(); + SpecialPowers.focus(opener); // Take focus from the plugin while the window is blurred. plugin2.focus(); is(plugin1.getFocusState(), true, "(5) Plugin should still have focus."); is(plugin1.getFocusEventCount(), expectedEventCount, "Focus event count should be " + expectedEventCount); // Focus the window. - window.focus(); + SpecialPowers.focus(window); expectedEventCount++; is(plugin1.getFocusState(), false, "(6) Plugin should not have focus."); is(plugin1.getFocusEventCount(), expectedEventCount, "Focus event count should be " + expectedEventCount); window.opener.testsFinished(); }
--- a/dom/plugins/test/mochitest/cocoa_window_focus.html +++ b/dom/plugins/test/mochitest/cocoa_window_focus.html @@ -48,33 +48,30 @@ is(plugin1.getTopLevelWindowActivationEventCount(), expectedEventCount, "Window focus event count should be " + expectedEventCount); is(plugin2.getTopLevelWindowActivationState(), true, "Activation state should be: activated"); is(plugin2.getTopLevelWindowActivationEventCount(), expectedEventCount, "Window focus event count should be " + expectedEventCount); } catch (e) { ok(false, "Plugin does not know its initial top-level window activation state!"); } - netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); - var fm = SpecialPowers.Cc["@mozilla.org/focus-manager;1"]. - getService(SpecialPowers.Ci.nsIFocusManager); + var fm = SpecialPowers.Services.focus; waitForFocus(function() { // Make sure the plugin handled the focus event before checking. executeSoon(function() { expectedEventCount++; is(plugin1.getTopLevelWindowActivationState(), false, "Activation state should be: deactivated"); is(plugin1.getTopLevelWindowActivationEventCount(), expectedEventCount, "Window focus event count should be " + expectedEventCount); is(plugin2.getTopLevelWindowActivationState(), false, "Activation state should be: deactivated"); is(plugin2.getTopLevelWindowActivationEventCount(), expectedEventCount, "Window focus event count should be " + expectedEventCount); // Bring our window back to the front and make sure plugins were properly notified. - netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); fm.focusedWindow = window; waitForFocus(function() { // Make sure the plugin handled the focus event before checking. executeSoon(function() { expectedEventCount++; is(plugin1.getTopLevelWindowActivationState(), true, "Activation state should be: activated"); @@ -86,14 +83,13 @@ window.opener.testsFinished(); }); }, window); }); }, window.opener); // Send our window to the back and make sure plugins were properly notified. // Calling window.blur() is not allowed. - netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); fm.focusedWindow = window.opener; } </script> </body> </html>
--- a/dom/plugins/test/mochitest/test_cocoa_focus.html +++ b/dom/plugins/test/mochitest/test_cocoa_focus.html @@ -1,13 +1,14 @@ <html> <head> <title>NPCocoaEventFocusChanged Tests</title> <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <script type="application/javascript" src="utils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> </head> <body onload="runTests()"> <script class="testbody" type="application/javascript"> SimpleTest.waitForExplicitFinish(); setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED); var gOtherWindow;
--- a/dom/plugins/test/mochitest/test_cocoa_window_focus.html +++ b/dom/plugins/test/mochitest/test_cocoa_window_focus.html @@ -1,13 +1,14 @@ <html> <head> <title>NPCocoaEventWindowFocusChanged Tests</title> <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <script type="application/javascript" src="utils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> </head> <body onload="runTests()"> <script class="testbody" type="application/javascript"> SimpleTest.waitForExplicitFinish(); setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED); var gOtherWindow;
--- a/gfx/layers/LayersLogging.h +++ b/gfx/layers/LayersLogging.h @@ -181,23 +181,25 @@ AppendToString(std::stringstream& aStrea aStream << sfx; } template<class src, class dst> void AppendToString(std::stringstream& aStream, const mozilla::gfx::ScaleFactors2D<src, dst>& scale, const char* pfx="", const char* sfx="") { + aStream << pfx; std::streamsize oldPrecision = aStream.precision(3); if (scale.AreScalesSame()) { aStream << scale.xScale; } else { aStream << '(' << scale.xScale << ',' << scale.yScale << ')'; } aStream.precision(oldPrecision); + aStream << sfx; } void AppendToString(std::stringstream& aStream, const mozilla::gfx::Matrix4x4& m, const char* pfx="", const char* sfx=""); void AppendToString(std::stringstream& aStream, const mozilla::gfx::Matrix5x4& m,
--- a/gfx/layers/TiledLayerBuffer.h +++ b/gfx/layers/TiledLayerBuffer.h @@ -3,20 +3,22 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef GFX_TILEDLAYERBUFFER_H #define GFX_TILEDLAYERBUFFER_H // Debug defines //#define GFX_TILEDLAYER_DEBUG_OVERLAY //#define GFX_TILEDLAYER_PREF_WARNINGS +//#define GFX_TILEDLAYER_RETAINING_LOG #include <stdint.h> // for uint16_t, uint32_t #include <sys/types.h> // for int32_t #include "gfxPlatform.h" // for GetTileWidth/GetTileHeight +#include "LayersLogging.h" // for print_stderr #include "mozilla/gfx/Logging.h" // for gfxCriticalError #include "nsDebug.h" // for NS_ASSERTION #include "nsPoint.h" // for nsIntPoint #include "nsRect.h" // for nsIntRect #include "nsRegion.h" // for nsIntRegion #include "nsTArray.h" // for nsTArray #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 @@ -109,26 +111,16 @@ public: Tile GetTile(const nsIntPoint& aTileOrigin) const; // Given a tile x, y relative to the top left of the layer, this function // will return the tile for // (x*GetScaledTileSize().width, y*GetScaledTileSize().height, // GetScaledTileSize().width, GetScaledTileSize().height) Tile GetTile(int x, int y) const; - // This operates the same as GetTile(aTileOrigin), but will also replace the - // specified tile with the placeholder tile. This does not call ReleaseTile - // on the removed tile. - bool RemoveTile(const nsIntPoint& aTileOrigin, Tile& aRemovedTile); - - // This operates the same as GetTile(x, y), but will also replace the - // specified tile with the placeholder tile. This does not call ReleaseTile - // on the removed tile. - bool RemoveTile(int x, int y, Tile& aRemovedTile); - const gfx::IntSize& GetTileSize() const { return mTileSize; } gfx::IntSize GetScaledTileSize() const { return RoundedToInt(gfx::Size(mTileSize) / mResolution); } unsigned int GetTileCount() const { return mRetainedTiles.Length(); } const nsIntRegion& GetValidRegion() const { return mValidRegion; } const nsIntRegion& GetPaintedRegion() const { return mPaintedRegion; } @@ -280,41 +272,16 @@ TiledLayerBuffer<Derived, Tile>::GetTile template<typename Derived, typename Tile> Tile TiledLayerBuffer<Derived, Tile>::GetTile(int x, int y) const { int index = x * mRetainedHeight + y; return mRetainedTiles.SafeElementAt(index, AsDerived().GetPlaceholderTile()); } -template<typename Derived, typename Tile> bool -TiledLayerBuffer<Derived, Tile>::RemoveTile(const nsIntPoint& aTileOrigin, - Tile& aRemovedTile) -{ - gfx::IntSize scaledTileSize = GetScaledTileSize(); - int firstTileX = floor_div(mValidRegion.GetBounds().x, scaledTileSize.width); - int firstTileY = floor_div(mValidRegion.GetBounds().y, scaledTileSize.height); - return RemoveTile(floor_div(aTileOrigin.x, scaledTileSize.width) - firstTileX, - floor_div(aTileOrigin.y, scaledTileSize.height) - firstTileY, - aRemovedTile); -} - -template<typename Derived, typename Tile> bool -TiledLayerBuffer<Derived, Tile>::RemoveTile(int x, int y, Tile& aRemovedTile) -{ - int index = x * mRetainedHeight + y; - const Tile& tileToRemove = mRetainedTiles.SafeElementAt(index, AsDerived().GetPlaceholderTile()); - if (!tileToRemove.IsPlaceholderTile()) { - aRemovedTile = tileToRemove; - mRetainedTiles[index] = AsDerived().GetPlaceholderTile(); - return true; - } - return false; -} - template<typename Derived, typename Tile> void TiledLayerBuffer<Derived, Tile>::Dump(std::stringstream& aStream, const char* aPrefix, bool aDumpHtml) { nsIntRect visibleRect = GetValidRegion().GetBounds(); gfx::IntSize scaledTileSize = GetScaledTileSize(); for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) { @@ -357,16 +324,32 @@ TiledLayerBuffer<Derived, Tile>::Update( const nsIntPoint newBufferOrigin(RoundDownToTileEdge(newBound.x, scaledTileSize.width), RoundDownToTileEdge(newBound.y, scaledTileSize.height)); // This is the reason we break the style guide with newValidRegion instead // of aNewValidRegion - so that the names match better and code easier to read const nsIntRegion& oldValidRegion = mValidRegion; const int oldRetainedHeight = mRetainedHeight; +#ifdef GFX_TILEDLAYER_RETAINING_LOG + { // scope ss + std::stringstream ss; + ss << "TiledLayerBuffer " << this << " starting update" + << " on bounds "; + AppendToString(ss, newBound); + ss << " with mResolution=" << mResolution << "\n"; + for (size_t i = 0; i < mRetainedTiles.Length(); i++) { + ss << "mRetainedTiles[" << i << "] = "; + mRetainedTiles[i].Dump(ss); + ss << "\n"; + } + print_stderr(ss); + } +#endif + // Pass 1: Recycle valid content from the old buffer // Recycle tiles from the old buffer that contain valid regions. // Insert placeholders tiles if we have no valid area for that tile // which we will allocate in pass 2. // TODO: Add a tile pool to reduce new allocation int tileX = 0; int tileY = 0; int tilesMissing = 0; @@ -426,16 +409,31 @@ TiledLayerBuffer<Derived, Tile>::Update( x += width; } // Keep track of the number of horizontal/vertical tiles // in the buffer so that we can easily look up a tile. mRetainedWidth = tileX; mRetainedHeight = tileY; +#ifdef GFX_TILEDLAYER_RETAINING_LOG + { // scope ss + std::stringstream ss; + ss << "TiledLayerBuffer " << this << " finished pass 1 of update;" + << " tilesMissing=" << tilesMissing << "\n"; + for (size_t i = 0; i < oldRetainedTiles.Length(); i++) { + ss << "oldRetainedTiles[" << i << "] = "; + oldRetainedTiles[i].Dump(ss); + ss << "\n"; + } + print_stderr(ss); + } +#endif + + // Pass 1.5: Release excess tiles in oldRetainedTiles // Tiles in oldRetainedTiles that aren't in newRetainedTiles will be recycled // before creating new ones, but there could still be excess unnecessary // tiles. As tiles may not have a fixed memory cost (for example, due to // double-buffering), we should release these excess tiles first. int oldTileCount = 0; for (size_t i = 0; i < oldRetainedTiles.Length(); i++) { Tile oldTile = oldRetainedTiles[i]; @@ -466,16 +464,34 @@ TiledLayerBuffer<Derived, Tile>::Update( << " old valid " << oldValidRegion.ToString().get() << " old painted " << oldAndPainted.ToString().get() << " new valid " << newValidRegion.ToString().get(); } #endif nsIntRegion regionToPaint(aPaintRegion); +#ifdef GFX_TILEDLAYER_RETAINING_LOG + { // scope ss + std::stringstream ss; + ss << "TiledLayerBuffer " << this << " finished pass 1.5 of update\n"; + for (size_t i = 0; i < oldRetainedTiles.Length(); i++) { + ss << "oldRetainedTiles[" << i << "] = "; + oldRetainedTiles[i].Dump(ss); + ss << "\n"; + } + for (size_t i = 0; i < newRetainedTiles.Length(); i++) { + ss << "newRetainedTiles[" << i << "] = "; + newRetainedTiles[i].Dump(ss); + ss << "\n"; + } + print_stderr(ss); + } +#endif + // Pass 2: Validate // We know at this point that any tile in the new buffer that had valid content // from the previous buffer is placed correctly in the new buffer. // We know that any tile in the old buffer that isn't a place holder is // of no use and can be recycled. // We also know that any place holder tile in the new buffer must be // allocated. tileX = 0; @@ -560,16 +576,35 @@ TiledLayerBuffer<Derived, Tile>::Update( x += width; } AsDerived().PostValidate(aPaintRegion); for (unsigned int i = 0; i < newRetainedTiles.Length(); ++i) { AsDerived().UnlockTile(newRetainedTiles[i]); } +#ifdef GFX_TILEDLAYER_RETAINING_LOG + { // scope ss + std::stringstream ss; + ss << "TiledLayerBuffer " << this << " finished pass 2 of update;" + << " oldTileCount=" << oldTileCount << "\n"; + for (size_t i = 0; i < oldRetainedTiles.Length(); i++) { + ss << "oldRetainedTiles[" << i << "] = "; + oldRetainedTiles[i].Dump(ss); + ss << "\n"; + } + for (size_t i = 0; i < newRetainedTiles.Length(); i++) { + ss << "newRetainedTiles[" << i << "] = "; + newRetainedTiles[i].Dump(ss); + ss << "\n"; + } + print_stderr(ss); + } +#endif + // At this point, oldTileCount should be zero MOZ_ASSERT(oldTileCount == 0, "Failed to release old tiles"); mRetainedTiles = newRetainedTiles; mValidRegion = newValidRegion; mPaintedRegion.Or(mPaintedRegion, aPaintRegion); }
--- a/gfx/layers/client/TextureClientPool.cpp +++ b/gfx/layers/client/TextureClientPool.cpp @@ -6,16 +6,19 @@ #include "TextureClientPool.h" #include "CompositableClient.h" #include "mozilla/layers/ISurfaceAllocator.h" #include "gfxPrefs.h" #include "nsComponentManagerUtils.h" +#define TCP_LOG(...) +//#define TCP_LOG(...) printf_stderr(__VA_ARGS__); + namespace mozilla { namespace layers { static void ShrinkCallback(nsITimer *aTimer, void *aClosure) { static_cast<TextureClientPool*>(aClosure)->ShrinkToMinimumSize(); } @@ -27,16 +30,18 @@ TextureClientPool::TextureClientPool(gfx ISurfaceAllocator *aAllocator) : mFormat(aFormat) , mSize(aSize) , mMaxTextureClients(aMaxTextureClients) , mShrinkTimeoutMsec(aShrinkTimeoutMsec) , mOutstandingClients(0) , mSurfaceAllocator(aAllocator) { + TCP_LOG("TexturePool %p created with max size %u and timeout %u\n", + this, mMaxTextureClients, aShrinkTimeoutMsec); mTimer = do_CreateInstance("@mozilla.org/timer;1"); if (aFormat == gfx::SurfaceFormat::UNKNOWN) { gfxWarning() << "Creating texture pool for SurfaceFormat::UNKNOWN format"; } } TextureClientPool::~TextureClientPool() { @@ -84,16 +89,18 @@ TextureClientPool::GetTextureClient() if (mTextureClients.size()) { mOutstandingClients++; textureClient = mTextureClients.top(); mTextureClients.pop(); #ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL DebugOnly<bool> ok = TestClientPool("fetch", textureClient, this); MOZ_ASSERT(ok); #endif + TCP_LOG("TexturePool %p giving %p from pool; size %u outstanding %u\n", + this, textureClient.get(), mTextureClients.size(), mOutstandingClients); return textureClient; } // We're increasing the number of outstanding TextureClients without reusing a // client, we may need to free a deferred-return TextureClient. ShrinkToMaximumSize(); // No unused clients in the pool, create one @@ -108,16 +115,18 @@ TextureClientPool::GetTextureClient() } mOutstandingClients++; #ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL if (textureClient) { textureClient->mPoolTracker = this; } #endif + TCP_LOG("TexturePool %p giving new %p; size %u outstanding %u\n", + this, textureClient.get(), mTextureClients.size(), mOutstandingClients); return textureClient; } void TextureClientPool::ReturnTextureClient(TextureClient *aClient) { if (!aClient) { return; @@ -125,105 +134,138 @@ TextureClientPool::ReturnTextureClient(T #ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL DebugOnly<bool> ok = TestClientPool("return", aClient, this); MOZ_ASSERT(ok); #endif // Add the client to the pool: MOZ_ASSERT(mOutstandingClients > mTextureClientsDeferred.size()); mOutstandingClients--; mTextureClients.push(aClient); + TCP_LOG("TexturePool %p had client %p returned; size %u outstanding %u\n", + this, aClient, mTextureClients.size(), mOutstandingClients); // Shrink down if we're beyond our maximum size ShrinkToMaximumSize(); // Kick off the pool shrinking timer if there are still more unused texture // clients than our desired minimum cache size. if (mTextureClients.size() > sMinCacheSize) { + TCP_LOG("TexturePool %p scheduling a shrink-to-min-size\n", this); mTimer->InitWithFuncCallback(ShrinkCallback, this, mShrinkTimeoutMsec, nsITimer::TYPE_ONE_SHOT); } } void TextureClientPool::ReturnTextureClientDeferred(TextureClient *aClient) { if (!aClient) { return; } #ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL DebugOnly<bool> ok = TestClientPool("defer", aClient, this); MOZ_ASSERT(ok); #endif mTextureClientsDeferred.push(aClient); + TCP_LOG("TexturePool %p had client %p defer-returned, size %u outstanding %u\n", + this, aClient, mTextureClientsDeferred.size(), mOutstandingClients); ShrinkToMaximumSize(); } void TextureClientPool::ShrinkToMaximumSize() { uint32_t totalClientsOutstanding = mTextureClients.size() + mOutstandingClients; + TCP_LOG("TexturePool %p shrinking to max size %u; total outstanding %u\n", + this, mMaxTextureClients, totalClientsOutstanding); // We're over our desired maximum size, immediately shrink down to the // maximum, or zero if we have too many outstanding texture clients. // We cull from the deferred TextureClients first, as we can't reuse those // until they get returned. while (totalClientsOutstanding > mMaxTextureClients) { if (mTextureClientsDeferred.size()) { MOZ_ASSERT(mOutstandingClients > 0); mOutstandingClients--; + TCP_LOG("TexturePool %p dropped deferred client %p; %u remaining\n", + this, mTextureClientsDeferred.top().get(), + mTextureClientsDeferred.size() - 1); mTextureClientsDeferred.pop(); } else { if (!mTextureClients.size()) { // Getting here means we're over our desired number of TextureClients // with none in the pool. This can happen for pathological cases, or // it could mean that mMaxTextureClients needs adjusting for whatever // device we're running on. + TCP_LOG("TexturePool %p encountering pathological case!\n", this); break; } + TCP_LOG("TexturePool %p dropped non-deferred client %p; %u remaining\n", + this, mTextureClients.top().get(), mTextureClients.size() - 1); mTextureClients.pop(); } totalClientsOutstanding--; } } void TextureClientPool::ShrinkToMinimumSize() { + TCP_LOG("TexturePool %p shrinking to minimum size %u\n", this, sMinCacheSize); while (mTextureClients.size() > sMinCacheSize) { + TCP_LOG("TexturePool %p popped %p; shrunk to %u\n", + this, mTextureClients.top().get(), mTextureClients.size() - 1); mTextureClients.pop(); } } void TextureClientPool::ReturnDeferredClients() { + TCP_LOG("TexturePool %p returning %u deferred clients to pool\n", + this, mTextureClientsDeferred.size()); while (!mTextureClientsDeferred.empty()) { mTextureClients.push(mTextureClientsDeferred.top()); mTextureClientsDeferred.pop(); MOZ_ASSERT(mOutstandingClients > 0); mOutstandingClients--; } ShrinkToMaximumSize(); // Kick off the pool shrinking timer if there are still more unused texture // clients than our desired minimum cache size. if (mTextureClients.size() > sMinCacheSize) { + TCP_LOG("TexturePool %p kicking off shrink-to-min timer\n", this); mTimer->InitWithFuncCallback(ShrinkCallback, this, mShrinkTimeoutMsec, nsITimer::TYPE_ONE_SHOT); } } void +TextureClientPool::ReportClientLost() +{ + MOZ_ASSERT(mOutstandingClients > mTextureClientsDeferred.size()); + mOutstandingClients--; + TCP_LOG("TexturePool %p getting report client lost; down to %u outstanding\n", + this, mOutstandingClients); +} + +void TextureClientPool::Clear() { + TCP_LOG("TexturePool %p getting cleared\n", this); while (!mTextureClients.empty()) { + TCP_LOG("TexturePool %p releasing client %p\n", + this, mTextureClients.top().get()); mTextureClients.pop(); } while (!mTextureClientsDeferred.empty()) { MOZ_ASSERT(mOutstandingClients > 0); mOutstandingClients--; + TCP_LOG("TexturePool %p releasing deferred client %p\n", + this, mTextureClientsDeferred.top().get()); mTextureClientsDeferred.pop(); } } } }
--- a/gfx/layers/client/TextureClientPool.h +++ b/gfx/layers/client/TextureClientPool.h @@ -70,20 +70,17 @@ public: * ReturnTextureClientDeferred. */ void ReturnDeferredClients(); /** * Report that a client retrieved via GetTextureClient() has become * unusable, so that it will no longer be tracked. */ - void ReportClientLost() { - MOZ_ASSERT(mOutstandingClients > mTextureClientsDeferred.size()); - mOutstandingClients--; - } + void ReportClientLost(); /** * Calling this will cause the pool to attempt to relinquish any unused * clients. */ void Clear(); gfx::SurfaceFormat GetFormat() { return mFormat; }
--- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -535,16 +535,28 @@ TileClient::operator=(const TileClient& mLastUpdate = o.mLastUpdate; #endif mManager = o.mManager; mInvalidFront = o.mInvalidFront; mInvalidBack = o.mInvalidBack; return *this; } +void +TileClient::Dump(std::stringstream& aStream) +{ + aStream << "TileClient(bb=" << (TextureClient*)mBackBuffer << " fb=" << mFrontBuffer.get(); + if (mBackBufferOnWhite) { + aStream << " bbow=" << mBackBufferOnWhite.get(); + } + if (mFrontBufferOnWhite) { + aStream << " fbow=" << mFrontBufferOnWhite.get(); + } + aStream << ")"; +} void TileClient::Flip() { #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 if (mFrontBuffer && mFrontBuffer->GetIPDLActor() && mCompositableClient && mCompositableClient->GetIPDLActor()) { // remove old buffer from CompositableHost
--- a/gfx/layers/client/TiledContentClient.h +++ b/gfx/layers/client/TiledContentClient.h @@ -209,16 +209,21 @@ struct TileClient DiscardBackBuffer(); } nsExpirationState *GetExpirationState() { return &mExpirationState; } TileDescriptor GetTileDescriptor(); /** + * For debugging. + */ + void Dump(std::stringstream& aStream); + + /** * Swaps the front and back buffers. */ void Flip(); void DumpTexture(std::stringstream& aStream) { // TODO We should combine the OnWhite/OnBlack here an just output a single image. CompositableClient::DumpTextureClient(aStream, mFrontBuffer); }
--- a/gfx/layers/composite/TiledContentHost.h +++ b/gfx/layers/composite/TiledContentHost.h @@ -101,16 +101,20 @@ public: bool IsPlaceholderTile() const { return mTextureHost == nullptr; } void ReadUnlock() { if (mSharedLock) { mSharedLock->ReadUnlock(); } } + void Dump(std::stringstream& aStream) { + aStream << "TileHost(...)"; // fill in as needed + } + void DumpTexture(std::stringstream& aStream) { // TODO We should combine the OnWhite/OnBlack here an just output a single image. CompositableHost::DumpTextureHost(aStream, mTextureHost); } RefPtr<gfxSharedReadLock> mSharedLock; CompositableTextureHostRef mTextureHost; CompositableTextureHostRef mTextureHostOnWhite;
--- a/gfx/thebes/gfxTextRun.cpp +++ b/gfx/thebes/gfxTextRun.cpp @@ -1226,23 +1226,26 @@ gfxTextRun::CopyGlyphDataFrom(gfxTextRun } } dstGlyphs[i] = g; } // Copy glyph runs GlyphRunIterator iter(aSource, aStart, aLength); #ifdef DEBUG - gfxFont *lastFont = nullptr; + GlyphRun *prevRun = nullptr; #endif while (iter.NextRun()) { gfxFont *font = iter.GetGlyphRun()->mFont; - NS_ASSERTION(font != lastFont, "Glyphruns not coalesced?"); + NS_ASSERTION(!prevRun || prevRun->mFont != iter.GetGlyphRun()->mFont || + prevRun->mMatchType != iter.GetGlyphRun()->mMatchType || + prevRun->mOrientation != iter.GetGlyphRun()->mOrientation, + "Glyphruns not coalesced?"); #ifdef DEBUG - lastFont = font; + prevRun = iter.GetGlyphRun(); uint32_t end = iter.GetStringEnd(); #endif uint32_t start = iter.GetStringStart(); // These used to be NS_ASSERTION()s, but WARNING is more appropriate. // Although it's unusual (and not desirable), it's possible for us to assign // different fonts to a base character and a following diacritic. // Example on OSX 10.5/10.6 with default fonts installed:
--- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -2435,16 +2435,33 @@ DumpStringRepresentation(JSContext *cx, str->dumpRepresentation(stderr, 0); args.rval().setUndefined(); return true; } #endif +static bool +SetLazyParsingEnabled(JSContext *cx, unsigned argc, Value *vp) +{ + CallArgs args = CallArgsFromVp(argc, vp); + + if (argc < 1) { + JS_ReportError(cx, "setLazyParsingEnabled: need an argument"); + return false; + } + + bool arg = ToBoolean(args.get(0)); + JS::CompartmentOptionsRef(cx->compartment()).setDiscardSource(!arg); + + args.rval().setUndefined(); + return true; +} + static const JSFunctionSpecWithHelp TestingFunctions[] = { JS_FN_HELP("gc", ::GC, 0, 0, "gc([obj] | 'compartment' [, 'shrinking'])", " Run the garbage collector. When obj is given, GC only its compartment.\n" " If 'compartment' is given, GC any compartments that were scheduled for\n" " GC via schedulegc.\n" " If 'shrinking' is passed as the optional second argument, perform a\n" " shrinking GC rather than a normal GC."), @@ -2817,16 +2834,20 @@ gc::ZealModeHelpText), " because the object is a revoked proxy)."), #ifdef DEBUG JS_FN_HELP("dumpStringRepresentation", DumpStringRepresentation, 1, 0, "dumpStringRepresentation(str)", " Print a human-readable description of how the string |str| is represented.\n"), #endif + JS_FN_HELP("setLazyParsingEnabled", SetLazyParsingEnabled, 1, 0, +"setLazyParsingEnabled(bool)", +" Enable or disable lazy parsing in the current compartment. The default is enabled."), + JS_FS_HELP_END }; static const JSPropertySpec TestingProperties[] = { JS_PSG("timesAccessed", TimesAccessed, 0), JS_PS_END };
--- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -150,18 +150,17 @@ CanLazilyParse(ExclusiveContext *cx, con !options.hasPollutedGlobalScope && !cx->compartment()->options().discardSource() && !options.sourceIsLazy; } static void MarkFunctionsWithinEvalScript(JSScript *script) { - // Mark top level functions in an eval script as being within an eval and, - // if applicable, inside a with statement. + // Mark top level functions in an eval script as being within an eval. if (!script->hasObjects()) return; ObjectArray *objects = script->objects(); size_t start = script->innerObjectsStart(); for (size_t i = start; i < objects->length; i++) { @@ -287,27 +286,24 @@ frontend::CompileScript(ExclusiveContext bool savedCallerFun = evalCaller && evalCaller->functionOrCallerFunction(); Rooted<JSScript*> script(cx, JSScript::Create(cx, evalStaticScope, savedCallerFun, options, staticLevel, sourceObject, 0, srcBuf.length())); if (!script) return nullptr; - // We can specialize a bit for the given scope chain if that scope chain is the global object. - JSObject *globalScope = - scopeChain && scopeChain == &scopeChain->global() ? (JSObject*) scopeChain : nullptr; - MOZ_ASSERT_IF(globalScope, globalScope->isNative()); - MOZ_ASSERT_IF(globalScope, JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(globalScope->getClass())); - + bool insideNonGlobalEval = + evalStaticScope && evalStaticScope->enclosingScopeForStaticScopeIter(); BytecodeEmitter::EmitterMode emitterMode = options.selfHostingMode ? BytecodeEmitter::SelfHosting : BytecodeEmitter::Normal; BytecodeEmitter bce(/* parent = */ nullptr, &parser, &globalsc, script, /* lazyScript = */ js::NullPtr(), options.forEval, - evalCaller, evalStaticScope, !!globalScope, options.lineno, emitterMode); + evalCaller, evalStaticScope, insideNonGlobalEval, + options.lineno, emitterMode); if (!bce.init()) return nullptr; // Syntax parsing may cause us to restart processing of top level // statements in the script. Use Maybe<> so that the parse context can be // reset when this occurs. Maybe<ParseContext<FullParseHandler> > pc; @@ -511,33 +507,40 @@ frontend::CompileLazyFunction(JSContext if (lazy->directlyInsideEval()) script->setDirectlyInsideEval(); if (lazy->usesArgumentsApplyAndThis()) script->setUsesArgumentsApplyAndThis(); if (lazy->hasBeenCloned()) script->setHasBeenCloned(); + /* + * We just pass false for insideNonGlobalEval and insideEval, because we + * don't actually know whether we are or not. The only consumer of those + * booleans is TryConvertFreeName, and it has special machinery to avoid + * doing bad things when a lazy function is inside eval. + */ + MOZ_ASSERT(!options.forEval); BytecodeEmitter bce(/* parent = */ nullptr, &parser, pn->pn_funbox, script, lazy, - options.forEval, /* evalCaller = */ js::NullPtr(), + /* insideEval = */ false, /* evalCaller = */ js::NullPtr(), /* evalStaticScope = */ js::NullPtr(), - /* hasGlobalScope = */ true, options.lineno, + /* insideNonGlobalEval = */ false, options.lineno, BytecodeEmitter::LazyFunction); if (!bce.init()) return false; return EmitFunctionScript(cx, &bce, pn->pn_body); } // Compile a JS function body, which might appear as the value of an event // handler attribute in an HTML <INPUT> tag, or in a Function() constructor. static bool CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, const ReadOnlyCompileOptions &options, const AutoNameVector &formals, SourceBufferHolder &srcBuf, - HandleObject enclosingScope, GeneratorKind generatorKind) + HandleObject enclosingStaticScope, GeneratorKind generatorKind) { js::TraceLoggerThread *logger = js::TraceLoggerForMainThread(cx->runtime()); js::TraceLoggerEvent event(logger, TraceLogger_AnnotateScripts, options); js::AutoTraceLog scriptLogger(logger, event); js::AutoTraceLog typeLogger(logger, TraceLogger_ParserCompileFunction); // FIXME: make Function pass in two strings and parse them as arguments and // ProgramElements respectively. @@ -628,37 +631,29 @@ CompileFunctionBody(JSContext *cx, Mutab return false; if (!SetSourceMap(cx, parser.tokenStream, ss)) return false; if (fn->pn_funbox->function()->isInterpreted()) { MOZ_ASSERT(fun == fn->pn_funbox->function()); - Rooted<JSScript*> script(cx, JSScript::Create(cx, enclosingScope, false, options, + Rooted<JSScript*> script(cx, JSScript::Create(cx, enclosingStaticScope, false, options, /* staticLevel = */ 0, sourceObject, /* sourceStart = */ 0, srcBuf.length())); if (!script) return false; script->bindings = fn->pn_funbox->bindings; - /* - * The reason for checking fun->environment() below is that certain - * consumers of JS::CompileFunction, namely - * EventListenerManager::CompileEventHandlerInternal, passes in a - * nullptr environment. This compiled function is never used, but - * instead is cloned immediately onto the right scope chain. - */ BytecodeEmitter funbce(/* parent = */ nullptr, &parser, fn->pn_funbox, script, /* lazyScript = */ js::NullPtr(), /* insideEval = */ false, /* evalCaller = */ js::NullPtr(), /* evalStaticScope = */ js::NullPtr(), - fun->environment() && fun->environment()->is<GlobalObject>(), - options.lineno); + /* insideNonGlobalEval = */ false, options.lineno); if (!funbce.init()) return false; if (!EmitFunctionScript(cx, &funbce, fn->pn_body)) return false; } else { fun.set(fn->pn_funbox->function()); MOZ_ASSERT(IsAsmJSModuleNative(fun->native()));
--- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -106,17 +106,18 @@ struct LoopStmtInfo : public StmtInfoBCE } // anonymous namespace BytecodeEmitter::BytecodeEmitter(BytecodeEmitter *parent, Parser<FullParseHandler> *parser, SharedContext *sc, HandleScript script, Handle<LazyScript *> lazyScript, bool insideEval, HandleScript evalCaller, Handle<StaticEvalObject *> staticEvalScope, - bool hasGlobalScope, uint32_t lineNum, EmitterMode emitterMode) + bool insideNonGlobalEval, uint32_t lineNum, + EmitterMode emitterMode) : sc(sc), cx(sc->context), parent(parent), script(cx, script), lazyScript(cx, lazyScript), prolog(cx, lineNum), main(cx, lineNum), current(&main), @@ -137,17 +138,17 @@ BytecodeEmitter::BytecodeEmitter(Bytecod blockScopeList(cx), yieldOffsetList(cx), typesetCount(0), hasSingletons(false), hasTryFinally(false), emittingForInit(false), emittingRunOnceLambda(false), insideEval(insideEval), - hasGlobalScope(hasGlobalScope), + insideNonGlobalEval(insideNonGlobalEval), emitterMode(emitterMode) { MOZ_ASSERT_IF(evalCaller, insideEval); MOZ_ASSERT_IF(emitterMode == LazyFunction, lazyScript); // Function scripts are never eval scripts. MOZ_ASSERT_IF(evalStaticScope, !sc->isFunctionBox()); } @@ -1582,24 +1583,34 @@ TryConvertFreeName(BytecodeEmitter *bce, pn->setOp(op); JS_ALWAYS_TRUE(pn->pn_cookie.set(bce->parser->tokenStream, hops, slot)); return true; } hops++; } + // If this walk up and check for directlyInsideEval is ever removed, + // we'll need to adjust CompileLazyFunction to better communicate + // whether we're inside eval to the BytecodeEmitter. For now, this + // walk is why CompileLazyFunction can claim that it's never inside + // eval. if (script->funHasExtensibleScope() || script->directlyInsideEval()) return false; } } // Unbound names aren't recognizable global-property references if the - // script isn't running against its global object. - if (!bce->script->compileAndGo() || !bce->hasGlobalScope) + // script is inside a non-global eval call. + if (bce->insideNonGlobalEval) + return false; + + // Skip trying to use GNAME ops if we know our script has a polluted + // global scope, since they'll just get treated as NAME ops anyway. + if (bce->script->hasPollutedGlobalScope()) return false; // Deoptimized names also aren't necessarily globals. if (pn->isDeoptimized()) return false; if (bce->sc->isFunctionBox()) { // Unbound names in function code may not be globals if new locals can @@ -1618,16 +1629,20 @@ TryConvertFreeName(BytecodeEmitter *bce, // 'var x; ' + // 'eval("print(x)");'); // "undefined", not "GLOBAL" // // Given the enclosing eval code's strictness and its bindings (neither is // readily available now), we could exactly check global-ness, but it's not // worth the trouble for doubly-nested eval code. So we conservatively // approximate. If the outer eval code is strict, then this eval code will // be: thus, don't optimize if we're compiling strict code inside an eval. + // + // Though actually, we don't even need an inner eval. We could just as well + // have a lambda inside that outer strict mode eval and it would run into + // the same issue. if (bce->insideEval && bce->sc->strict()) return false; JSOp op; switch (pn->getOp()) { case JSOP_GETNAME: op = JSOP_GETGNAME; break; case JSOP_SETNAME: op = StrictifySetNameOp(JSOP_SETGNAME, bce); break; case JSOP_SETCONST: @@ -2289,17 +2304,17 @@ BytecodeEmitter::emitNameOp(ParseNode *p } else { if (!emitAtomOp(pn, op)) return false; } } /* Need to provide |this| value for call */ if (callContext) { - if (op == JSOP_GETNAME) { + if (op == JSOP_GETNAME || op == JSOP_GETGNAME) { JSOp thisOp = needsImplicitThis() ? JSOP_IMPLICITTHIS : JSOP_GIMPLICITTHIS; if (!emitAtomOp(pn, thisOp)) return false; } else { if (!emit1(JSOP_UNDEFINED)) return false; } } @@ -5305,17 +5320,17 @@ EmitFunc(ExclusiveContext *cx, BytecodeE return false; script->bindings = funbox->bindings; uint32_t lineNum = bce->parser->tokenStream.srcCoords.lineNum(pn->pn_pos.begin); BytecodeEmitter bce2(bce, bce->parser, funbox, script, /* lazyScript = */ js::NullPtr(), bce->insideEval, bce->evalCaller, /* evalStaticScope = */ js::NullPtr(), - bce->hasGlobalScope, lineNum, bce->emitterMode); + bce->insideNonGlobalEval, lineNum, bce->emitterMode); if (!bce2.init()) return false; /* We measured the max scope depth when we parsed the function. */ if (!EmitFunctionScript(cx, &bce2, pn->pn_body)) return false; if (funbox->usesArguments && funbox->usesApply && funbox->usesThis) @@ -6778,17 +6793,17 @@ BytecodeEmitter::emitLexicalInitializati if (!bindNameToSlot(pn)) return false; jsatomid atomIndex; if (!maybeEmitVarDecl(globalDefOp, pn, &atomIndex)) return false; if (pn->getOp() != JSOP_INITLEXICAL) { - bool global = js_CodeSpec[pn->getOp()].format & JOF_GNAME; + bool global = IsGlobalOp(pn->getOp()); if (!emitIndex32(global ? JSOP_BINDGNAME : JSOP_BINDNAME, atomIndex)) return false; if (!emit1(JSOP_SWAP)) return false; } if (!pn->pn_cookie.isFree()) { if (!emitVarOp(pn, pn->getOp()))
--- a/js/src/frontend/BytecodeEmitter.h +++ b/js/src/frontend/BytecodeEmitter.h @@ -185,18 +185,18 @@ struct BytecodeEmitter bool emittingRunOnceLambda:1; /* true while emitting a lambda which is only expected to run once. */ bool isRunOnceLambda(); bool insideEval:1; /* True if compiling an eval-expression or a function nested inside an eval. */ - const bool hasGlobalScope:1; /* frontend::CompileScript's scope chain is the - global object */ + const bool insideNonGlobalEval:1; /* True if this is a direct eval + call in some non-global scope. */ enum EmitterMode { Normal, /* * Emit JSOP_GETINTRINSIC instead of JSOP_GETNAME and assert that * JSOP_GETNAME and JSOP_*GNAME don't ever get emitted. See the comment * for the field |selfHostingMode| in Parser.h for details. @@ -216,17 +216,17 @@ struct BytecodeEmitter * Note that BytecodeEmitters are magic: they own the arena "top-of-stack" * space above their tempMark points. This means that you cannot alloc from * tempLifoAlloc and save the pointer beyond the next BytecodeEmitter * destruction. */ BytecodeEmitter(BytecodeEmitter *parent, Parser<FullParseHandler> *parser, SharedContext *sc, HandleScript script, Handle<LazyScript *> lazyScript, bool insideEval, HandleScript evalCaller, - Handle<StaticEvalObject *> evalStaticScope, bool hasGlobalScope, + Handle<StaticEvalObject *> evalStaticScope, bool insideNonGlobalEval, uint32_t lineNum, EmitterMode emitterMode = Normal); bool init(); bool updateLocalsToFrameSlots(); bool isAliasedName(ParseNode *pn); MOZ_ALWAYS_INLINE bool makeAtomIndex(JSAtom *atom, jsatomid *indexp) {
--- a/js/src/gc/Memory.cpp +++ b/js/src/gc/Memory.cpp @@ -98,16 +98,18 @@ InitMemorySubsystem() if (pageSize == 0) { SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); pageSize = sysinfo.dwPageSize; allocGranularity = sysinfo.dwAllocationGranularity; } } +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + static inline void * MapMemoryAt(void *desired, size_t length, int flags, int prot = PAGE_READWRITE) { return VirtualAlloc(desired, length, flags, prot); } static inline void * MapMemory(size_t length, int flags, int prot = PAGE_READWRITE) @@ -274,16 +276,67 @@ size_t GetPageFaultCount() { PROCESS_MEMORY_COUNTERS pmc; if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) return 0; return pmc.PageFaultCount; } +# else // Various APIs are unavailable. + +void * +MapAlignedPages(size_t size, size_t alignment) +{ + MOZ_ASSERT(size >= alignment); + MOZ_ASSERT(size % alignment == 0); + MOZ_ASSERT(size % pageSize == 0); + MOZ_ASSERT(alignment % allocGranularity == 0); + + void *p = _aligned_malloc(size, alignment); + + MOZ_ASSERT(OffsetFromAligned(p, alignment) == 0); + return p; +} + +static void * +MapAlignedPagesLastDitch(size_t size, size_t alignment) +{ + return nullptr; +} + +void +UnmapPages(void *p, size_t size) +{ + _aligned_free(p); +} + +bool +MarkPagesUnused(void *p, size_t size) +{ + MOZ_ASSERT(OffsetFromAligned(p, pageSize) == 0); + return true; +} + +bool +MarkPagesInUse(void *p, size_t size) +{ + MOZ_ASSERT(OffsetFromAligned(p, pageSize) == 0); + return true; +} + +size_t +GetPageFaultCount() +{ + // GetProcessMemoryInfo is unavailable. + return 0; +} + +# endif + void * AllocateMappedContent(int fd, size_t offset, size_t length, size_t alignment) { // TODO: Bug 988813 - Support memory mapped array buffer for Windows platform. return nullptr; } // Deallocate mapped memory for object. @@ -318,16 +371,22 @@ MapAlignedPages(size_t size, size_t alig int flags = MAP_PRIVATE | MAP_ANON | MAP_ALIGN | MAP_NOSYNC; void *p = mmap((caddr_t)alignment, size, prot, flags, -1, 0); if (p == MAP_FAILED) return nullptr; return p; } +static void * +MapAlignedPagesLastDitch(size_t size, size_t alignment) +{ + return nullptr; +} + void UnmapPages(void *p, size_t size) { MOZ_ALWAYS_TRUE(0 == munmap((caddr_t)p, size)); } bool MarkPagesUnused(void *p, size_t size)
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug1106982-2.js @@ -0,0 +1,20 @@ +var x = "wrong"; +var t = {x: "x"}; +var hits = 0; +var p = new Proxy(t, { + has(t, id) { + var found = id in t; + if (++hits == 2) + delete t[id]; + return found; + }, + get(t, id) { return t[id]; } +}); +evaluate(`function testFunc() { + x += " x"; +}`, { compileAndGo: false }); + +var cloneFunc = clone(testFunc, p); +cloneFunc(); +assertEq(hits, 2); +assertEq(t.x, "undefined x");
--- a/js/src/jit-test/tests/basic/bug1106982.js +++ b/js/src/jit-test/tests/basic/bug1106982.js @@ -7,10 +7,13 @@ var p = new Proxy(t, { if (++hits == 2) delete t[id]; return found; }, get(t, id) { return t[id]; } }); with (p) x += " x"; +// If you change this testcase (e.g. because we fix the number of +// has() calls we end up making to match spec better), don't forget to +// update bug1106982-2.js too. See also bug 1145641. assertEq(hits, 2); assertEq(t.x, "undefined x");
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/basic/eval-scopes.js @@ -0,0 +1,135 @@ +function bytecode(f) { + if (typeof disassemble !== "function") + return "unavailable"; + var d = disassemble(f); + return d.slice(d.indexOf("main:"), d.indexOf("\n\n")); +} + +function hasGname(f, v, hasIt = true) { + // Do a try-catch that prints the full stack, so we can tell + // _which_ part of this test failed. + try { + var b = bytecode(f); + if (b != "unavailable") { + assertEq(b.contains(`getgname "${v}"`), hasIt); + assertEq(b.contains(`getname "${v}"`), !hasIt); + } + } catch (e) { + print(e.stack); + throw e; + } +} + +var x = "outer"; + +setLazyParsingEnabled(false); +{ + let x = "inner"; + eval("function g() { assertEq(x, 'inner');} g()"); + eval("function g2() { (function nest() { assertEq(x, 'inner'); })(); } g2()"); +} +eval(` + function g3() { + assertEq(x, 'outer'); + } + g3(); + hasGname(g3, 'x'); + `); +eval(` + function g4() { + function nest() { assertEq(x, 'outer'); } + nest(); + return nest; + } + hasGname(g4(), 'x'); + `); +setLazyParsingEnabled(true); + +{ + let x = "inner"; + eval("function h() { assertEq(x, 'inner');} h()"); + eval("function h2() { (function nest() { assertEq(x, 'inner'); })(); } h2()"); +} +// It sure would be nice if we could run the h3/h4 tests below, but it turns out +// that lazy functions and eval don't play together all that well. See bug +// 1146080. For now, assert we have no gname, so people will notice if they +// accidentally fix it and adjust this test accordingly. +eval(` + function h3() { + assertEq(x, 'outer'); + } + h3(); + hasGname(h3, 'x', false); + `); +eval(` + function h4() { + function nest() { assertEq(x, 'outer'); } + nest(); + return nest; + } + hasGname(h4(), 'x', false); + `); + +setLazyParsingEnabled(false); +with ({}) { + let x = "inner"; + eval("function i() { assertEq(x, 'inner');} i()"); + eval("function i2() { (function nest() { assertEq(x, 'inner'); })(); } i2()"); +} +setLazyParsingEnabled(true); + +with ({}) { + let x = "inner"; + eval("function j() { assertEq(x, 'inner');} j()"); + eval("function j2() { (function nest() { assertEq(x, 'inner'); })(); } j2()"); +} + +setLazyParsingEnabled(false); +(function () { + var x = "inner"; + eval("function k() { assertEq(x, 'inner');} k()"); + eval("function k2() { (function nest() { assertEq(x, 'inner'); })(); } k2()"); +})(); +setLazyParsingEnabled(true); + +(function () { + let x = "inner"; + eval("function l() { assertEq(x, 'inner');} l()"); + eval("function l2() { (function nest() { assertEq(x, 'inner'); })(); } l2()"); +})(); + +var y1 = 5; +eval(` + 'use strict'; + var y1 = 6; + assertEq(y1, 6); + (function() { assertEq(y1, 6); })() + `); +assertEq(y1, 5); + +eval(` + 'use strict'; + var y2 = 6; + assertEq(y2, 6); + (function() { assertEq(y2, 6); })() + `); + +setLazyParsingEnabled(false); + +var y3 = 5; +eval(` + 'use strict'; + var y3 = 6; + assertEq(y3, 6); + (function() { assertEq(y3, 6); })() + `); +assertEq(y3, 5); + +eval(` + 'use strict'; + var y4 = 6; + assertEq(y4, 6); + (function() { assertEq(y4, 6); })() + `); + +setLazyParsingEnabled(true);
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/basic/function-gname.js @@ -0,0 +1,49 @@ +function bytecode(f) { + if (typeof disassemble !== "function") + return "unavailable"; + var d = disassemble(f); + return d.slice(d.indexOf("main:"), d.indexOf("\n\n")); +} + +function hasGname(f, v) { + // Do a try-catch that prints the full stack, so we can tell + // _which_ part of this test failed. + try { + var b = bytecode(f); + if (b != "unavailable") { + assertEq(b.contains(`getgname "${v}"`), true); + assertEq(b.contains(`getname "${v}"`), false); + } + } catch (e) { + print(e.stack); + throw e; + } +} + +var x = "outer"; + +var f1 = new Function("assertEq(x, 'outer')"); +f1(); +hasGname(f1, 'x'); + +setLazyParsingEnabled(false); +var f2 = new Function("assertEq(x, 'outer')"); +f2(); +hasGname(f2, 'x'); +setLazyParsingEnabled(true); + +{ + let x = "inner"; + var f3 = new Function("assertEq(x, 'outer')"); + f3(); + hasGname(f3, 'x'); +} + +setLazyParsingEnabled(false); +{ + let x = "inner"; + var f4 = new Function("assertEq(x, 'outer')"); + f4(); + hasGname(f4, 'x'); +} +setLazyParsingEnabled(true);
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/basic/weird-scopechains.js @@ -0,0 +1,36 @@ +function checkNameLookup() { + return "global"; +} + +function assertWithMessage(got, expected, message) { + assertEq(message + ": " + got, message + ": " + expected); +} + +// Create our test func via "evaluate" so it won't be compileAndGo and +// we can clone it. +evaluate(`function testFunc() { + assertWithMessage(checkNameLookup(), "local", "nameLookup"); + assertWithMessage(checkThisBinding(), "local", "thisBinding"); + + // Important: lambda needs to close over "reason", so it won't just get the + // scope of testFunc as its scope. Instead it'll get the Call object + // "reason" lives in. + var reason = " in lambda in Call"; + (function() { + assertWithMessage(checkNameLookup(), "local", "nameLookup" + reason); + assertWithMessage(checkThisBinding(), "local", "thisBinding" + reason); + })(); +}`, { compileAndGo: false }); + +var obj = { + checkNameLookup: function() { + return "local"; + }, + + checkThisBinding: function() { + return this.checkNameLookup(); + }, +}; + +var cloneFunc = clone(testFunc, obj); +cloneFunc();
--- a/js/src/jit/BaselineBailouts.cpp +++ b/js/src/jit/BaselineBailouts.cpp @@ -700,23 +700,23 @@ InitFromBailout(JSContext *cx, HandleScr // not resume into baseline code, but instead into // HandleExceptionBaseline, so *do* set the scope chain here. if (iter.pcOffset() != 0 || iter.resumeAfter() || (excInfo && excInfo->propagatingIonExceptionForDebugMode())) { scopeChain = fun->environment(); } } else { - // For global, compile-and-go scripts the scope chain is the - // script's global (Ion does not compile non-compile-and-go - // scripts). Also note that it's invalid to resume into the - // prologue in this case because the prologue expects the scope - // chain in R1 for eval and global scripts. + // For global scripts without a polluted global scope the scope + // chain is the script's global (Ion does not compile scripts + // with a polluted global scope). Also note that it's invalid to + // resume into the prologue in this case because the prologue + // expects the scope chain in R1 for eval and global scripts. MOZ_ASSERT(!script->isForEval()); - MOZ_ASSERT(script->compileAndGo()); + MOZ_ASSERT(!script->hasPollutedGlobalScope()); scopeChain = &(script->global()); } } // Make sure to add HAS_RVAL to flags here because setFlags() below // will clobber it. returnValue = iter.read(); flags |= BaselineFrame::HAS_RVAL;
--- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -2051,16 +2051,19 @@ BaselineCompiler::emit_JSOP_IN() frame.push(R0); return true; } bool BaselineCompiler::emit_JSOP_GETGNAME() { + if (script->hasPollutedGlobalScope()) + return emit_JSOP_GETNAME(); + RootedPropertyName name(cx, script->getName(pc)); if (name == cx->names().undefined) { frame.push(UndefinedValue()); return true; } if (name == cx->names().NaN) { frame.push(cx->runtime()->NaNValue); @@ -2083,18 +2086,22 @@ BaselineCompiler::emit_JSOP_GETGNAME() // Mark R0 as pushed stack value. frame.push(R0); return true; } bool BaselineCompiler::emit_JSOP_BINDGNAME() { - frame.push(ObjectValue(script->global())); - return true; + if (!script->hasPollutedGlobalScope()) { + frame.push(ObjectValue(script->global())); + return true; + } + + return emit_JSOP_BINDNAME(); } bool BaselineCompiler::emit_JSOP_SETPROP() { // Keep lhs in R0, rhs in R1. frame.popRegsAndSync(2);
--- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -6056,16 +6056,18 @@ DoGetNameFallback(JSContext *cx, Baselin jsbytecode *pc = stub->icEntry()->pc(script); mozilla::DebugOnly<JSOp> op = JSOp(*pc); FallbackICSpew(cx, stub, "GetName(%s)", js_CodeName[JSOp(*pc)]); MOZ_ASSERT(op == JSOP_GETNAME || op == JSOP_GETGNAME); RootedPropertyName name(cx, script->getName(pc)); + static_assert(JSOP_GETGNAME_LENGTH == JSOP_GETNAME_LENGTH, + "Otherwise our check for JSOP_TYPEOF isn't ok"); if (JSOp(pc[JSOP_GETGNAME_LENGTH]) == JSOP_TYPEOF) { if (!GetScopeNameForTypeOf(cx, scopeChain, name, res)) return false; } else { if (!GetScopeName(cx, scopeChain, name, res)) return false; } @@ -6082,17 +6084,17 @@ DoGetNameFallback(JSContext *cx, Baselin // Attach new stub. if (stub->numOptimizedStubs() >= ICGetName_Fallback::MAX_OPTIMIZED_STUBS) { // TODO: Discard all stubs in this IC and replace with generic stub. return true; } bool attached = false; bool isTemporarilyUnoptimizable = false; - if (js_CodeSpec[*pc].format & JOF_GNAME) { + if (IsGlobalOp(JSOp(*pc)) && !script->hasPollutedGlobalScope()) { Handle<GlobalObject*> global = scopeChain.as<GlobalObject>(); if (!TryAttachGlobalNameStub(cx, script, pc, stub, global, name, &attached, &isTemporarilyUnoptimizable)) { return false; } } else { if (!TryAttachScopeNameStub(cx, script, stub, scopeChain, name, &attached)) @@ -6197,17 +6199,17 @@ ICGetName_Scope<NumHops>::Compiler::gene static bool DoBindNameFallback(JSContext *cx, BaselineFrame *frame, ICBindName_Fallback *stub, HandleObject scopeChain, MutableHandleValue res) { jsbytecode *pc = stub->icEntry()->pc(frame->script()); mozilla::DebugOnly<JSOp> op = JSOp(*pc); FallbackICSpew(cx, stub, "BindName(%s)", js_CodeName[JSOp(*pc)]); - MOZ_ASSERT(op == JSOP_BINDNAME); + MOZ_ASSERT(op == JSOP_BINDNAME || op == JSOP_BINDGNAME); RootedPropertyName name(cx, frame->script()->getName(pc)); RootedObject scope(cx); if (!LookupNameUnqualified(cx, name, scopeChain, &scope)) return false; res.setObject(*scope);
--- a/js/src/jit/BytecodeAnalysis.cpp +++ b/js/src/jit/BytecodeAnalysis.cpp @@ -146,28 +146,36 @@ BytecodeAnalysis::init(TempAllocator &al if (catchFinallyRanges[i].contains(offset)) infos_[offset].loopEntryInCatchOrFinally = true; } break; case JSOP_GETNAME: case JSOP_BINDNAME: case JSOP_SETNAME: + case JSOP_STRICTSETNAME: case JSOP_DELNAME: case JSOP_GETALIASEDVAR: case JSOP_SETALIASEDVAR: case JSOP_LAMBDA: case JSOP_LAMBDA_ARROW: case JSOP_DEFFUN: case JSOP_DEFVAR: case JSOP_DEFCONST: case JSOP_SETCONST: usesScopeChain_ = true; break; + case JSOP_GETGNAME: + case JSOP_SETGNAME: + case JSOP_STRICTSETGNAME: + if (script_->hasPollutedGlobalScope()) + usesScopeChain_ = true; + break; + case JSOP_FINALLY: hasTryFinally_ = true; break; case JSOP_SETARG: hasSetArg_ = true; break;
--- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -3485,22 +3485,22 @@ CodeGenerator::visitCallDirectEvalV(LCal pushArg(ToValue(lir, LCallDirectEvalV::Argument)); pushArg(ToValue(lir, LCallDirectEvalV::ThisValue)); pushArg(ImmGCPtr(gen->info().script())); pushArg(scopeChain); callVM(DirectEvalValueInfo, lir); } -// Registers safe for use before generatePrologue(). -static const uint32_t EntryTempMask = Registers::TempMask & ~(1 << OsrFrameReg.code()); - void CodeGenerator::generateArgumentsChecks(bool bailout) { + // Registers safe for use before generatePrologue(). + static const uint32_t EntryTempMask = Registers::TempMask & ~(1 << OsrFrameReg.code()); + // This function can be used the normal way to check the argument types, // before entering the function and bailout when arguments don't match. // For debug purpose, this is can also be used to force/check that the // arguments are correct. Upon fail it will hit a breakpoint. MIRGraph &mir = gen->graph(); MResumePoint *rp = mir.entryResumePoint();
--- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -2030,21 +2030,22 @@ CheckScript(JSContext *cx, JSScript *scr return false; } if (script->isGenerator()) { TrackAndSpewIonAbort(cx, script, "generator script"); return false; } - if (!script->compileAndGo() && !script->functionNonDelazifying()) { - // Support non-CNG functions but not other scripts. For global scripts, - // IonBuilder currently uses the global object as scope chain, this is - // not valid for non-CNG code. - TrackAndSpewIonAbort(cx, script, "not compile-and-go"); + if (script->hasPollutedGlobalScope() && !script->functionNonDelazifying()) { + // Support functions with a polluted global scope but not other + // scripts. For global scripts, IonBuilder currently uses the global + // object as scope chain, this is not valid when the script has a + // polluted global scope. + TrackAndSpewIonAbort(cx, script, "has polluted global scope"); return false; } return true; } static MethodStatus CheckScriptSize(JSContext *cx, JSScript* script)
--- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -1195,18 +1195,20 @@ IonBuilder::initScopeChain(MDefinition * return false; } scope = createCallObject(callee, scope); if (!scope) return false; } } else { - // For CNG global scripts, the scope chain is the global object. - MOZ_ASSERT(script()->compileAndGo()); + // For global scripts without a polluted global scope, the scope chain + // is the global object. + MOZ_ASSERT(!script()->isForEval()); + MOZ_ASSERT(!script()->hasPollutedGlobalScope()); scope = constant(ObjectValue(script()->global())); } current->setScopeChain(scope); return true; } bool @@ -1811,42 +1813,47 @@ IonBuilder::inspectOpcode(JSOp op) return pushConstant(Int32Value(GET_INT8(pc))); case JSOP_UINT16: return pushConstant(Int32Value(GET_UINT16(pc))); case JSOP_GETGNAME: { PropertyName *name = info().getAtom(pc)->asPropertyName(); - return jsop_getgname(name); + if (!script()->hasPollutedGlobalScope()) + return jsop_getgname(name); + return jsop_getname(name); } - case JSOP_BINDGNAME: - return pushConstant(ObjectValue(script()->global())); - case JSOP_SETGNAME: case JSOP_STRICTSETGNAME: { PropertyName *name = info().getAtom(pc)->asPropertyName(); + if (script()->hasPollutedGlobalScope()) + return jsop_setprop(name); JSObject *obj = &script()->global(); return setStaticName(obj, name); } case JSOP_GETNAME: { PropertyName *name = info().getAtom(pc)->asPropertyName(); return jsop_getname(name); } case JSOP_GETINTRINSIC: { PropertyName *name = info().getAtom(pc)->asPropertyName(); return jsop_intrinsic(name); } + case JSOP_BINDGNAME: + if (!script()->hasPollutedGlobalScope()) + return pushConstant(ObjectValue(script()->global())); + // Fall through to JSOP_BINDNAME case JSOP_BINDNAME: return jsop_bindname(info().getName(pc)); case JSOP_DUP: current->pushSlot(current->stackDepth() - 1); return true; case JSOP_DUP2: @@ -7563,17 +7570,17 @@ IonBuilder::jsop_getgname(PropertyName * return jsop_getname(name); } bool IonBuilder::jsop_getname(PropertyName *name) { MDefinition *object; - if (js_CodeSpec[*pc].format & JOF_GNAME) { + if (IsGlobalOp(JSOp(*pc)) && !script()->hasPollutedGlobalScope()) { MInstruction *global = constant(ObjectValue(script()->global())); object = global; } else { current->push(current->scopeChain()); object = current->pop(); } MGetNameCache *ins;
--- a/js/src/jit/JitFrames.cpp +++ b/js/src/jit/JitFrames.cpp @@ -2491,19 +2491,20 @@ InlineFrameIterator::computeScopeChain(V } // Note we can hit this case even for heavyweight functions, in case we // are walking the frame during the function prologue, before the scope // chain has been initialized. if (isFunctionFrame()) return callee(fallback)->environment(); - // Ion does not handle scripts that are not compile-and-go. + // Ion does not handle non-function scripts that have anything other than + // the global on their scope chain. MOZ_ASSERT(!script()->isForEval()); - MOZ_ASSERT(script()->compileAndGo()); + MOZ_ASSERT(!script()->hasPollutedGlobalScope()); return &script()->global(); } bool InlineFrameIterator::isFunctionFrame() const { return !!calleeTemplate_; }
--- a/js/src/jit/none/Architecture-none.h +++ b/js/src/jit/none/Architecture-none.h @@ -106,16 +106,17 @@ struct FloatRegister bool isDouble() const { MOZ_CRASH(); } bool isInt32x4() const { MOZ_CRASH(); } bool isFloat32x4() const { MOZ_CRASH(); } FloatRegister asSingle() const { MOZ_CRASH(); } FloatRegister asDouble() const { MOZ_CRASH(); } FloatRegister asInt32x4() const { MOZ_CRASH(); } FloatRegister asFloat32x4() const { MOZ_CRASH(); } Code code() const { MOZ_CRASH(); } + Encoding encoding() const { MOZ_CRASH(); } const char *name() const { MOZ_CRASH(); } bool volatile_() const { MOZ_CRASH(); } bool operator != (FloatRegister) const { MOZ_CRASH(); } bool operator == (FloatRegister) const { MOZ_CRASH(); } bool aliases(FloatRegister) const { MOZ_CRASH(); } uint32_t numAliased() const { MOZ_CRASH(); } void aliased(uint32_t, FloatRegister *) { MOZ_CRASH(); } bool equiv(FloatRegister) const { MOZ_CRASH(); }
--- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -127,16 +127,22 @@ class Assembler : public AssemblerShared static void PatchInstructionImmediate(uint8_t *, PatchedImmPtr) { MOZ_CRASH(); } static int32_t ExtractCodeLabelOffset(uint8_t *) { MOZ_CRASH(); } static void ToggleToJmp(CodeLocationLabel) { MOZ_CRASH(); } static void ToggleToCmp(CodeLocationLabel) { MOZ_CRASH(); } static void ToggleCall(CodeLocationLabel, bool) { MOZ_CRASH(); } static uintptr_t GetPointer(uint8_t *) { MOZ_CRASH(); } + + void verifyHeapAccessDisassembly(uint32_t begin, uint32_t end, + const Disassembler::HeapAccess &heapAccess) + { + MOZ_CRASH(); + } }; class Operand { public: Operand (const Address &) { MOZ_CRASH();} };
--- a/js/src/jsapi-tests/testGCAllocator.cpp +++ b/js/src/jsapi-tests/testGCAllocator.cpp @@ -25,24 +25,29 @@ #include <sys/types.h> #include <unistd.h> #else #error "Memory mapping functions are not defined for your OS." #endif BEGIN_TEST(testGCAllocator) { + size_t PageSize = 0; #if defined(XP_WIN) +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); - const size_t PageSize = sysinfo.dwPageSize; + PageSize = sysinfo.dwPageSize; +# else // Various APIs are unavailable. This test is disabled. + return true; +# endif #elif defined(SOLARIS) return true; #elif defined(XP_UNIX) - const size_t PageSize = size_t(sysconf(_SC_PAGESIZE)); + PageSize = size_t(sysconf(_SC_PAGESIZE)); #else return true; #endif /* Finish any ongoing background free activity. */ js::gc::AutoFinishGC finishGC(rt); bool growUp; @@ -264,16 +269,17 @@ positionIsCorrect(const char *str, void if (result != desired) { while (--tempChunks >= 0) js::gc::UnmapPages(chunkPool[tempChunks], 2 * Chunk); } return result == desired; } #if defined(XP_WIN) +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) void * mapMemoryAt(void *desired, size_t length) { return VirtualAlloc(desired, length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); } void * @@ -283,18 +289,29 @@ mapMemory(size_t length) } void unmapPages(void *p, size_t size) { MOZ_ALWAYS_TRUE(VirtualFree(p, 0, MEM_RELEASE)); } -#elif defined(SOLARIS) -// This test doesn't apply to Solaris. +# else // Various APIs are unavailable. This test is disabled. + +void *mapMemoryAt(void *desired, size_t length) { return nullptr; } +void *mapMemory(size_t length) { return nullptr; } +void unmapPages(void *p, size_t size) { } + +# endif +#elif defined(SOLARIS) // This test doesn't apply to Solaris. + +void *mapMemoryAt(void *desired, size_t length) { return nullptr; } +void *mapMemory(size_t length) { return nullptr; } +void unmapPages(void *p, size_t size) { } + #elif defined(XP_UNIX) void * mapMemoryAt(void *desired, size_t length) { #if defined(__ia64__) || (defined(__sparc64__) && defined(__NetBSD__)) MOZ_RELEASE_ASSERT(0xffff800000000000ULL & (uintptr_t(desired) + length - 1) == 0); #endif
--- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -638,17 +638,18 @@ js::XDRInterpretedFunction(XDRState<mode template bool js::XDRInterpretedFunction(XDRState<XDR_ENCODE> *, HandleObject, HandleScript, MutableHandleFunction); template bool js::XDRInterpretedFunction(XDRState<XDR_DECODE> *, HandleObject, HandleScript, MutableHandleFunction); JSObject * -js::CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction srcFun) +js::CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction srcFun, + PollutedGlobalScopeOption polluted) { /* NB: Keep this in sync with XDRInterpretedFunction. */ RootedObject cloneProto(cx); if (srcFun->isStarGenerator()) { cloneProto = GlobalObject::getOrCreateStarGeneratorFunctionPrototype(cx, cx->global()); if (!cloneProto) return nullptr; } @@ -660,17 +661,17 @@ js::CloneFunctionAndScript(JSContext *cx JSFunction::INTERPRETED, NullPtr(), NullPtr(), cloneProto, allocKind, TenuredObject)); if (!clone) return nullptr; RootedScript srcScript(cx, srcFun->getOrCreateScript(cx)); if (!srcScript) return nullptr; - RootedScript clonedScript(cx, CloneScript(cx, enclosingScope, clone, srcScript)); + RootedScript clonedScript(cx, CloneScript(cx, enclosingScope, clone, srcScript, polluted)); if (!clonedScript) return nullptr; clone->setArgCount(srcFun->nargs()); clone->setFlags(srcFun->flags()); clone->initAtom(srcFun->displayAtom()); clone->initScript(clonedScript); clonedScript->setFunction(clone);
--- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -649,17 +649,18 @@ namespace js { JSString *FunctionToString(JSContext *cx, HandleFunction fun, bool bodyOnly, bool lambdaParen); template<XDRMode mode> bool XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enclosingScript, MutableHandleFunction objp); extern JSObject * -CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun); +CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, + PollutedGlobalScopeOption polluted); /* * Report an error that call.thisv is not compatible with the specified class, * assuming that the method (clasp->name).prototype.<name of callee function> * is what was called. */ extern void ReportIncompatibleMethod(JSContext *cx, CallReceiver call, const Class *clasp);
--- a/js/src/jsnativestack.cpp +++ b/js/src/jsnativestack.cpp @@ -42,16 +42,20 @@ js::GetNativeStackBaseImpl() MOV pTib, EAX } return static_cast<void*>(pTib->StackBase); # elif defined(_M_X64) PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb()); return reinterpret_cast<void*>(pTib->StackBase); +# elif defined(_M_ARM) + PNT_TIB pTib = reinterpret_cast<PNT_TIB>(NtCurrentTeb()); + return static_cast<void*>(pTib->StackBase); + # elif defined(_WIN32) && defined(__GNUC__) NT_TIB* pTib; asm ("movl %%fs:0x18, %0\n" : "=r" (pTib)); return static_cast<void*>(pTib->StackBase); # endif }
--- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -3026,17 +3026,17 @@ js::CloneScript(JSContext *cx, HandleObj RootedObject enclosingScope(cx); if (ssi.done() || ssi.type() == StaticScopeIter<CanGC>::Function) enclosingScope = fun; else if (ssi.type() == StaticScopeIter<CanGC>::Block) enclosingScope = objects[FindScopeObjectIndex(src, ssi.block())]; else enclosingScope = objects[FindScopeObjectIndex(src, ssi.staticWith())]; - clone = CloneFunctionAndScript(cx, enclosingScope, innerFun); + clone = CloneFunctionAndScript(cx, enclosingScope, innerFun, polluted); } } else { /* * Clone object literals emitted for the JSOP_NEWOBJECT opcode. We only emit that * instead of the less-optimized JSOP_NEWINIT for self-hosted code or code compiled * with JSOPTION_COMPILE_N_GO set. As we don't clone the latter type of code, this * case should only ever be hit when cloning objects from self-hosted code. */
--- a/js/src/tests/jstests.py +++ b/js/src/tests/jstests.py @@ -105,16 +105,18 @@ def parse_args(): help='Run under JS debugger.') harness_og.add_option('--passthrough', action='store_true', help='Run tests with stdin/stdout attached to' ' caller.') harness_og.add_option('--valgrind', action='store_true', help='Run tests in valgrind.') harness_og.add_option('--valgrind-args', default='', help='Extra args to pass to valgrind.') + harness_og.add_option('--rr', action='store_true', + help='Run tests under RR record-and-replay debugger.') op.add_option_group(harness_og) input_og = OptionGroup(op, "Inputs", "Change what tests are run.") input_og.add_option('-f', '--file', dest='test_file', action='append', help='Get tests from the given file.') input_og.add_option('-x', '--exclude-file', action='append', help='Exclude tests from the given file.') input_og.add_option('-d', '--exclude-random', dest='random', @@ -169,27 +171,29 @@ def parse_args(): if len(args) > 0: options.js_shell = abspath(args[0]) requested_paths |= set(args[1:]) # If we do not have a shell, we must be in a special mode. if options.js_shell is None and not options.make_manifests: op.error('missing JS_SHELL argument') - # Valgrind and gdb are mutually exclusive. - if options.valgrind and options.debug: - op.error("--valgrind and --debug are mutually exclusive.") + # Valgrind, gdb, and rr are mutually exclusive. + if sum(map(lambda e: 1 if e else 0, [options.valgrind, options.debug, options.rr])) > 1: + op.error("--valgrind, --debug, and --rr are mutually exclusive.") # Fill the debugger field, as needed. prefix = options.debugger.split() if options.debug else [] if options.valgrind: prefix = ['valgrind'] + options.valgrind_args.split() if os.uname()[0] == 'Darwin': prefix.append('--dsymutil=yes') options.show_output = True + if options.rr: + prefix = ['rr', 'record'] js_cmd_args = options.shell_args.split() if options.jorendb: options.passthrough = True options.hide_progress = True options.worker_count = 1 debugger_path = realpath(os.path.join( abspath(dirname(abspath(__file__))),
--- a/js/src/vm/Interpreter-inl.h +++ b/js/src/vm/Interpreter-inl.h @@ -298,18 +298,20 @@ SetAliasedVarOperation(JSContext *cx, JS inline bool SetNameOperation(JSContext *cx, JSScript *script, jsbytecode *pc, HandleObject scope, HandleValue val) { MOZ_ASSERT(*pc == JSOP_SETNAME || *pc == JSOP_STRICTSETNAME || *pc == JSOP_SETGNAME || *pc == JSOP_STRICTSETGNAME); - MOZ_ASSERT_IF(*pc == JSOP_SETGNAME, scope == cx->global()); - MOZ_ASSERT_IF(*pc == JSOP_STRICTSETGNAME, scope == cx->global()); + MOZ_ASSERT_IF(*pc == JSOP_SETGNAME && !script->hasPollutedGlobalScope(), + scope == cx->global()); + MOZ_ASSERT_IF(*pc == JSOP_STRICTSETGNAME && !script->hasPollutedGlobalScope(), + scope == cx->global()); bool strict = *pc == JSOP_STRICTSETNAME || *pc == JSOP_STRICTSETGNAME; RootedPropertyName name(cx, script->getName(pc)); RootedValue valCopy(cx, val); // In strict mode, assigning to an undeclared global variable is an // error. To detect this, we call NativeSetProperty directly and pass // Unqualified. It stores the error, if any, in |result|.
--- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -283,17 +283,17 @@ GetNameOperation(JSContext *cx, Interpre * Skip along the scope chain to the enclosing global object. This is * used for GNAME opcodes where the bytecode emitter has determined a * name access must be on the global. It also insulates us from bugs * in the emitter: type inference will assume that GNAME opcodes are * accessing the global object, and the inferred behavior should match * the actual behavior even if the id could be found on the scope chain * before the global object. */ - if (IsGlobalOp(JSOp(*pc))) + if (IsGlobalOp(JSOp(*pc)) && !fp->script()->hasPollutedGlobalScope()) obj = &obj->global(); Shape *shape = nullptr; JSObject *scope = nullptr, *pobj = nullptr; if (LookupNameNoGC(cx, name, obj, &scope, &pobj, &shape)) { if (FetchNameNoGC(pobj, shape, vp)) return CheckUninitializedLexical(cx, name, vp); } @@ -2034,38 +2034,43 @@ CASE(JSOP_SETCONST) RootedObject &obj = rootObject0; obj = ®S.fp()->varObj(); if (!SetConstOperation(cx, obj, name, rval)) goto error; } END_CASE(JSOP_SETCONST) -CASE(JSOP_BINDGNAME) - PUSH_OBJECT(REGS.fp()->global()); -END_CASE(JSOP_BINDGNAME) - CASE(JSOP_BINDINTRINSIC) PUSH_OBJECT(*cx->global()->intrinsicsHolder()); END_CASE(JSOP_BINDINTRINSIC) +CASE(JSOP_BINDGNAME) CASE(JSOP_BINDNAME) { - RootedObject &scopeChain = rootObject0; - scopeChain = REGS.fp()->scopeChain(); - - RootedPropertyName &name = rootName0; - name = script->getName(REGS.pc); - - /* Assigning to an undeclared name adds a property to the global object. */ - RootedObject &scope = rootObject1; - if (!LookupNameUnqualified(cx, name, scopeChain, &scope)) - goto error; - - PUSH_OBJECT(*scope); + JSOp op = JSOp(*REGS.pc); + if (op == JSOP_BINDNAME || script->hasPollutedGlobalScope()) { + RootedObject &scopeChain = rootObject0; + scopeChain = REGS.fp()->scopeChain(); + + RootedPropertyName &name = rootName0; + name = script->getName(REGS.pc); + + /* Assigning to an undeclared name adds a property to the global object. */ + RootedObject &scope = rootObject1; + if (!LookupNameUnqualified(cx, name, scopeChain, &scope)) + goto error; + + PUSH_OBJECT(*scope); + } else { + PUSH_OBJECT(REGS.fp()->global()); + } + + static_assert(JSOP_BINDNAME_LENGTH == JSOP_BINDGNAME_LENGTH, + "We're sharing the END_CASE so the lengths better match"); } END_CASE(JSOP_BINDNAME) #define BITWISE_OP(OP) \ JS_BEGIN_MACRO \ int32_t i, j; \ if (!ToInt32(cx, REGS.stackHandleAt(-2), &i)) \ goto error; \ @@ -2462,16 +2467,19 @@ CASE(JSOP_SETGNAME) CASE(JSOP_STRICTSETGNAME) CASE(JSOP_SETNAME) CASE(JSOP_STRICTSETNAME) { static_assert(JSOP_SETNAME_LENGTH == JSOP_STRICTSETNAME_LENGTH, "setname and strictsetname must be the same size"); static_assert(JSOP_SETGNAME_LENGTH == JSOP_STRICTSETGNAME_LENGTH, "setganem adn strictsetgname must be the same size"); + static_assert(JSOP_SETNAME_LENGTH == JSOP_SETGNAME_LENGTH, + "We're sharing the END_CASE so the lengths better match"); + RootedObject &scope = rootObject0; scope = ®S.sp[-2].toObject(); HandleValue value = REGS.stackHandleAt(-1); if (!SetNameOperation(cx, script, REGS.pc, scope, value)) goto error; REGS.sp[-2] = REGS.sp[-1]; @@ -2717,29 +2725,33 @@ CASE(JSOP_GIMPLICITTHIS) RootedValue &v = rootValue0; if (!ComputeImplicitThis(cx, scope, &v)) goto error; PUSH_COPY(v); } else { // Treat it like JSOP_UNDEFINED. PUSH_UNDEFINED(); } + static_assert(JSOP_IMPLICITTHIS_LENGTH == JSOP_GIMPLICITTHIS_LENGTH, + "We're sharing the END_CASE so the lengths better match"); } END_CASE(JSOP_IMPLICITTHIS) CASE(JSOP_GETGNAME) CASE(JSOP_GETNAME) { RootedValue &rval = rootValue0; if (!GetNameOperation(cx, REGS.fp(), REGS.pc, &rval)) goto error; PUSH_COPY(rval); TypeScript::Monitor(cx, script, REGS.pc, rval); + static_assert(JSOP_GETNAME_LENGTH == JSOP_GETGNAME_LENGTH, + "We're sharing the END_CASE so the lengths better match"); } END_CASE(JSOP_GETNAME) CASE(JSOP_GETINTRINSIC) { RootedValue &rval = rootValue0; if (!GetIntrinsicOperation(cx, REGS.pc, &rval))
--- a/js/src/vm/Opcodes.h +++ b/js/src/vm/Opcodes.h @@ -1494,44 +1494,48 @@ 1234567890123456789012345678901234567890 * Category: Statements * Type: Function * Operands: * Stack: => */ \ macro(JSOP_RETRVAL, 153,"retrval", NULL, 1, 0, 0, JOF_BYTE) \ \ /* - * Looks up name on global scope and pushes its value onto the stack. + * Looks up name on global scope and pushes its value onto the stack, unless + * the script has a polluted global, in which case it acts just like + * JSOP_NAME. * * Free variable references that must either be found on the global or a * ReferenceError. * Category: Variables and Scopes * Type: Free Variables * Operands: uint32_t nameIndex * Stack: => val */ \ macro(JSOP_GETGNAME, 154,"getgname", NULL, 5, 0, 1, JOF_ATOM|JOF_NAME|JOF_TYPESET|JOF_GNAME) \ /* * Pops the top two values on the stack as 'val' and 'scope', sets property * of 'scope' as 'val' and pushes 'val' back on the stack. * - * 'scope' should be the global scope. + * 'scope' should be the global scope unless the script has a polluted + * global scope, in which case acts like JSOP_SETNAME. * Category: Variables and Scopes * Type: Free Variables * Operands: uint32_t nameIndex * Stack: scope, val => val */ \ macro(JSOP_SETGNAME, 155,"setgname", NULL, 5, 2, 1, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING|JOF_GNAME|JOF_CHECKSLOPPY) \ \ /* * Pops the top two values on the stack as 'val' and 'scope', sets property * of 'scope' as 'val' and pushes 'val' back on the stack. Throws a * TypeError if the set fails, per strict mode semantics. * - * 'scope' should be the global scope. + * 'scope' should be the global scope unless the script has a polluted + * global scope, in which case acts like JSOP_STRICTSETNAME. * Category: Variables and Scopes * Type: Free Variables * Operands: uint32_t nameIndex * Stack: scope, val => val */ \ macro(JSOP_STRICTSETGNAME, 156, "strict-setgname", NULL, 5, 2, 1, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING|JOF_GNAME|JOF_CHECKSTRICT) \ /* * Pushes the implicit 'this' value for calls to the associated name onto @@ -1764,19 +1768,20 @@ 1234567890123456789012345678901234567890 */ \ macro(JSOP_DEBUGAFTERYIELD, 208, "debugafteryield", NULL, 1, 0, 0, JOF_BYTE) \ macro(JSOP_UNUSED209, 209, "unused209", NULL, 1, 0, 0, JOF_BYTE) \ macro(JSOP_UNUSED210, 210, "unused210", NULL, 1, 0, 0, JOF_BYTE) \ macro(JSOP_UNUSED211, 211, "unused211", NULL, 1, 0, 0, JOF_BYTE) \ macro(JSOP_UNUSED212, 212, "unused212", NULL, 1, 0, 0, JOF_BYTE) \ macro(JSOP_UNUSED213, 213, "unused213", NULL, 1, 0, 0, JOF_BYTE) \ /* - * Pushes the global scope onto the stack. + * Pushes the global scope onto the stack if the script doesn't have a + * polluted global scope. Otherwise will act like JSOP_BINDNAME. * - * 'nameIndex' is not used. + * 'nameIndex' is only used when acting like JSOP_BINDNAME. * Category: Variables and Scopes * Type: Free Variables * Operands: uint32_t nameIndex * Stack: => global */ \ macro(JSOP_BINDGNAME, 214, "bindgname", NULL, 5, 0, 1, JOF_ATOM|JOF_NAME|JOF_SET|JOF_GNAME) \ \ /*
--- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -2563,19 +2563,29 @@ RemoveReferencedNames(JSContext *cx, Han // care about entraining variables unnecessarily. for (jsbytecode *pc = script->code(); pc != script->codeEnd(); pc += GetBytecodeLength(pc)) { PropertyName *name; switch (JSOp(*pc)) { case JSOP_GETNAME: case JSOP_SETNAME: + case JSOP_STRICTSETNAME: name = script->getName(pc); break; + case JSOP_GETGNAME: + case JSOP_SETGNAME: + case JSOP_STRICTSETGNAME: + if (script->hasPollutedGlobalScope()) + name = script->getName(pc); + else + name = nullptr; + break; + case JSOP_GETALIASEDVAR: case JSOP_SETALIASEDVAR: name = ScopeCoordinateName(cx->runtime()->scopeCoordinateNameCache, script, pc); break; default: name = nullptr; break;
--- a/js/src/vm/UnboxedObject.cpp +++ b/js/src/vm/UnboxedObject.cpp @@ -171,18 +171,20 @@ UnboxedLayout::makeConstructorCode(JSCon HeapTypeSet *types = group->maybeGetProperty(IdToTypeId(NameToId(property.name))); Label notObject; masm.branchTestObject(Assembler::NotEqual, valueOperand, types->mightBeMIRType(MIRType_Null) ? ¬Object : &failureStoreObject); Register payloadReg = masm.extractObject(valueOperand, scratch1); - if (!types->hasType(TypeSet::AnyObjectType())) - masm.guardObjectType(payloadReg, types, scratch2, &failureStoreObject); + if (!types->hasType(TypeSet::AnyObjectType())) { + Register scratch = (payloadReg == scratch1) ? scratch2 : scratch1; + masm.guardObjectType(payloadReg, types, scratch, &failureStoreObject); + } masm.storeUnboxedProperty(targetAddress, JSVAL_TYPE_OBJECT, TypedOrValueRegister(MIRType_Object, AnyRegister(payloadReg)), nullptr); if (notObject.used()) { Label done; masm.jump(&done); @@ -202,17 +204,17 @@ UnboxedLayout::makeConstructorCode(JSCon if (object != ReturnReg) masm.movePtr(object, ReturnReg); // Restore non-volatile registers which were saved on entry. for (GeneralRegisterBackwardIterator iter(savedNonVolatileRegisters); iter.more(); ++iter) masm.Pop(*iter); - masm.ret(); + masm.abiret(); masm.bind(&failureStoreOther); // There was a failure while storing a value which cannot be stored at all // in the unboxed object. Initialize the object so it is safe for GC and // return null. masm.initUnboxedObjectContents(object, templateObject); @@ -236,17 +238,17 @@ UnboxedLayout::makeConstructorCode(JSCon // Initialize the object so it is safe for GC. masm.initUnboxedObjectContents(object, templateObject); masm.movePtr(ImmWord(CLEAR_CONSTRUCTOR_CODE_TOKEN), object); masm.jump(&done); Linker linker(masm); - AutoFlushICache afc("RegExp"); + AutoFlushICache afc("UnboxedObject"); JitCode *code = linker.newCode<NoGC>(cx, OTHER_CODE); if (!code) return false; layout.setConstructorCode(code); return true; }
--- a/js/src/vm/Xdr.h +++ b/js/src/vm/Xdr.h @@ -24,17 +24,17 @@ namespace js { * versions. If deserialization fails, the data should be invalidated if * possible. * * When you change this, run make_opcode_doc.py and copy the new output into * this wiki page: * * https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode */ -static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 265; +static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 267; static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND); static_assert(JSErr_Limit == 388, "GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or " "removed MSG_DEFs from js.msg, you should increment " "XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's " "expected JSErr_Limit value.");
--- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -444,17 +444,17 @@ public: protected: typedef nsTArray<RuleValue> RuleValueList; void AppendRuleToTable(PLDHashTable* aTable, const void* aKey, const RuleSelectorPair& aRuleInfo); void AppendUniversalRule(const RuleSelectorPair& aRuleInfo); int32_t mRuleCount; - // The hashtables are lazily initialized. + PLDHashTable mIdTable; PLDHashTable mClassTable; PLDHashTable mTagTable; PLDHashTable mNameSpaceTable; RuleValueList mUniversalRules; struct EnumData { const RuleValue* mCurValue; @@ -503,16 +503,30 @@ RuleHash::RuleHash(bool aQuirksMode) mElementUniversalCalls(0), mElementNameSpaceCalls(0), mElementTagCalls(0), mElementClassCalls(0), mElementIdCalls(0) #endif { MOZ_COUNT_CTOR(RuleHash); + + PL_DHashTableInit(&mIdTable, aQuirksMode ? &RuleHash_IdTable_CIOps.ops + : &RuleHash_IdTable_CSOps.ops, + sizeof(RuleHashTableEntry)); + + PL_DHashTableInit(&mClassTable, aQuirksMode ? &RuleHash_ClassTable_CIOps.ops + : &RuleHash_ClassTable_CSOps.ops, + sizeof(RuleHashTableEntry)); + + PL_DHashTableInit(&mTagTable, &RuleHash_TagTable_Ops, + sizeof(RuleHashTagTableEntry)); + + PL_DHashTableInit(&mNameSpaceTable, &RuleHash_NameSpaceTable_Ops, + sizeof(RuleHashTableEntry)); } RuleHash::~RuleHash() { MOZ_COUNT_DTOR(RuleHash); #ifdef RULE_HASH_STATS printf( "RuleHash(%p):\n" @@ -545,28 +559,20 @@ RuleHash::~RuleHash() #endif // RULE_HASH_STATS // Rule Values are arena allocated no need to delete them. Their destructor // isn't doing any cleanup. So we dont even bother to enumerate through // the hash tables and call their destructors. if (nullptr != mEnumList) { delete [] mEnumList; } // delete arena for strings and small objects - if (mIdTable.IsInitialized()) { - PL_DHashTableFinish(&mIdTable); - } - if (mClassTable.IsInitialized()) { - PL_DHashTableFinish(&mClassTable); - } - if (mTagTable.IsInitialized()) { - PL_DHashTableFinish(&mTagTable); - } - if (mNameSpaceTable.IsInitialized()) { - PL_DHashTableFinish(&mNameSpaceTable); - } + PL_DHashTableFinish(&mIdTable); + PL_DHashTableFinish(&mClassTable); + PL_DHashTableFinish(&mTagTable); + PL_DHashTableFinish(&mNameSpaceTable); } void RuleHash::AppendRuleToTable(PLDHashTable* aTable, const void* aKey, const RuleSelectorPair& aRuleInfo) { // Get a new or existing entry. RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*> (PL_DHashTableAdd(aTable, aKey, fallible)); @@ -595,54 +601,34 @@ void RuleHash::AppendUniversalRule(const void RuleHash::AppendRule(const RuleSelectorPair& aRuleInfo) { nsCSSSelector *selector = aRuleInfo.mSelector; if (selector->IsPseudoElement()) { selector = selector->mNext; } if (nullptr != selector->mIDList) { - if (!mIdTable.IsInitialized()) { - PL_DHashTableInit(&mIdTable, - mQuirksMode ? &RuleHash_IdTable_CIOps.ops - : &RuleHash_IdTable_CSOps.ops, - sizeof(RuleHashTableEntry)); - } AppendRuleToTable(&mIdTable, selector->mIDList->mAtom, aRuleInfo); RULE_HASH_STAT_INCREMENT(mIdSelectors); } else if (nullptr != selector->mClassList) { - if (!mClassTable.IsInitialized()) { - PL_DHashTableInit(&mClassTable, - mQuirksMode ? &RuleHash_ClassTable_CIOps.ops - : &RuleHash_ClassTable_CSOps.ops, - sizeof(RuleHashTableEntry)); - } AppendRuleToTable(&mClassTable, selector->mClassList->mAtom, aRuleInfo); RULE_HASH_STAT_INCREMENT(mClassSelectors); } else if (selector->mLowercaseTag) { RuleValue ruleValue(aRuleInfo, mRuleCount++, mQuirksMode); - if (!mTagTable.IsInitialized()) { - PL_DHashTableInit(&mTagTable, &RuleHash_TagTable_Ops, - sizeof(RuleHashTagTableEntry)); - } AppendRuleToTagTable(&mTagTable, selector->mLowercaseTag, ruleValue); RULE_HASH_STAT_INCREMENT(mTagSelectors); if (selector->mCasedTag && selector->mCasedTag != selector->mLowercaseTag) { AppendRuleToTagTable(&mTagTable, selector->mCasedTag, ruleValue); RULE_HASH_STAT_INCREMENT(mTagSelectors); } } else if (kNameSpaceID_Unknown != selector->mNameSpace) { - if (!mNameSpaceTable.IsInitialized()) { - PL_DHashTableInit(&mNameSpaceTable, &RuleHash_NameSpaceTable_Ops, - sizeof(RuleHashTableEntry)); - } AppendRuleToTable(&mNameSpaceTable, NS_INT32_TO_PTR(selector->mNameSpace), aRuleInfo); RULE_HASH_STAT_INCREMENT(mNameSpaceSelectors); } else { // universal tag selector AppendUniversalRule(aRuleInfo); RULE_HASH_STAT_INCREMENT(mUniversalSelectors); } @@ -689,41 +675,41 @@ void RuleHash::EnumerateAllRules(Element int32_t valueCount = 0; RULE_HASH_STAT_INCREMENT(mElementsMatched); if (mUniversalRules.Length() != 0) { // universal rules mEnumList[valueCount++] = ToEnumData(mUniversalRules); RULE_HASH_STAT_INCREMENT_LIST_COUNT(mUniversalRules, mElementUniversalCalls); } // universal rules within the namespace - if (kNameSpaceID_Unknown != nameSpace && mNameSpaceTable.IsInitialized()) { + if (kNameSpaceID_Unknown != nameSpace && mNameSpaceTable.EntryCount() > 0) { RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*> (PL_DHashTableSearch(&mNameSpaceTable, NS_INT32_TO_PTR(nameSpace))); if (entry) { mEnumList[valueCount++] = ToEnumData(entry->mRules); RULE_HASH_STAT_INCREMENT_LIST_COUNT(entry->mRules, mElementNameSpaceCalls); } } - if (mTagTable.IsInitialized()) { + if (mTagTable.EntryCount() > 0) { RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*> (PL_DHashTableSearch(&mTagTable, tag)); if (entry) { mEnumList[valueCount++] = ToEnumData(entry->mRules); RULE_HASH_STAT_INCREMENT_LIST_COUNT(entry->mRules, mElementTagCalls); } } - if (id && mIdTable.IsInitialized()) { + if (id && mIdTable.EntryCount() > 0) { RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*> (PL_DHashTableSearch(&mIdTable, id)); if (entry) { mEnumList[valueCount++] = ToEnumData(entry->mRules); RULE_HASH_STAT_INCREMENT_LIST_COUNT(entry->mRules, mElementIdCalls); } } - if (mClassTable.IsInitialized()) { + if (mClassTable.EntryCount() > 0) { for (int32_t index = 0; index < classCount; ++index) { RuleHashTableEntry *entry = static_cast<RuleHashTableEntry*> (PL_DHashTableSearch(&mClassTable, classList->AtomAt(index))); if (entry) { mEnumList[valueCount++] = ToEnumData(entry->mRules); RULE_HASH_STAT_INCREMENT_LIST_COUNT(entry->mRules, mElementClassCalls); } } @@ -776,39 +762,31 @@ SizeOfRuleHashTableEntry(PLDHashEntryHdr return entry->mRules.SizeOfExcludingThis(aMallocSizeOf); } size_t RuleHash::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { size_t n = 0; - if (mIdTable.IsInitialized()) { - n += PL_DHashTableSizeOfExcludingThis(&mIdTable, - SizeOfRuleHashTableEntry, - aMallocSizeOf); - } - - if (mClassTable.IsInitialized()) { - n += PL_DHashTableSizeOfExcludingThis(&mClassTable, - SizeOfRuleHashTableEntry, - aMallocSizeOf); - } - - if (mTagTable.IsInitialized()) { - n += PL_DHashTableSizeOfExcludingThis(&mTagTable, - SizeOfRuleHashTableEntry, - aMallocSizeOf); - } - - if (mNameSpaceTable.IsInitialized()) { - n += PL_DHashTableSizeOfExcludingThis(&mNameSpaceTable, - SizeOfRuleHashTableEntry, - aMallocSizeOf); - } + n += PL_DHashTableSizeOfExcludingThis(&mIdTable, + SizeOfRuleHashTableEntry, + aMallocSizeOf); + + n += PL_DHashTableSizeOfExcludingThis(&mClassTable, + SizeOfRuleHashTableEntry, + aMallocSizeOf); + + n += PL_DHashTableSizeOfExcludingThis(&mTagTable, + SizeOfRuleHashTableEntry, + aMallocSizeOf); + + n += PL_DHashTableSizeOfExcludingThis(&mNameSpaceTable, + SizeOfRuleHashTableEntry, + aMallocSizeOf); n += mUniversalRules.SizeOfExcludingThis(aMallocSizeOf); return n; } size_t RuleHash::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
--- a/media/libopus/moz.build +++ b/media/libopus/moz.build @@ -65,33 +65,34 @@ LOCAL_INCLUDES += [ 'silk', 'src', ] # sources.mozbuild is generated from gen-sources.py when a new libopus is # imported. include('sources.mozbuild') -SOURCES += celt_sources -SOURCES += silk_sources -SOURCES += opus_sources +UNIFIED_SOURCES += celt_sources +SOURCES += celt_nonunified_sources +UNIFIED_SOURCES += silk_sources +UNIFIED_SOURCES += opus_sources if CONFIG['MOZ_SAMPLE_TYPE_FLOAT32']: LOCAL_INCLUDES += [ 'silk/float', ] - SOURCES += silk_sources_float - SOURCES += opus_sources_float + UNIFIED_SOURCES += silk_sources_float + UNIFIED_SOURCES += opus_sources_float else: LOCAL_INCLUDES += [ 'silk/fixed', ] - SOURCES += silk_sources_fixed + UNIFIED_SOURCES += silk_sources_fixed # for webrtc - SOURCES += opus_sources_float + UNIFIED_SOURCES += opus_sources_float if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_AS']: SOURCES += celt_sources_arm GENERATED_SOURCES += [ '%s.%s' % (f, CONFIG['ASM_SUFFIX']) for f in [ 'celt_pitch_xcorr_arm-gnu', ]] # -Os is significantly slower, enable -O3 unless optimization is disabled if CONFIG['MOZ_OPTIMIZE']:
--- a/media/libopus/sources.mozbuild +++ b/media/libopus/sources.mozbuild @@ -1,30 +1,35 @@ # THIS FILE WAS AUTOMATICALLY GENERATED BY gen-sources.py. DO NOT EDIT. celt_sources = [ 'celt/bands.c', 'celt/celt.c', - 'celt/celt_decoder.c', - 'celt/celt_encoder.c', 'celt/celt_lpc.c', 'celt/cwrs.c', 'celt/entcode.c', 'celt/entdec.c', 'celt/entenc.c', 'celt/kiss_fft.c', 'celt/laplace.c', 'celt/mathops.c', 'celt/mdct.c', 'celt/modes.c', 'celt/pitch.c', 'celt/quant_bands.c', 'celt/rate.c', 'celt/vq.c', ] +celt_nonunified_sources = [ + # Disabled because of name clash of opus_custom_encoder_get_size. + 'celt/celt_decoder.c', + # Disabled because of name clash of opus_custom_encoder_get_size. + 'celt/celt_encoder.c', +] + celt_sources_arm = [ 'celt/arm/arm_celt_map.c', 'celt/arm/armcpu.c', ] celt_sources_arm_asm = [ 'celt/arm/celt_pitch_xcorr_arm.s', ]
--- a/media/webrtc/moz.build +++ b/media/webrtc/moz.build @@ -62,17 +62,16 @@ if CONFIG['MOZ_WEBRTC_SIGNALING']: 'signaling/src/mediapipeline/MediaPipelineFilter.cpp', 'signaling/src/mediapipeline/SrtpFlow.cpp', 'signaling/src/peerconnection/MediaPipelineFactory.cpp', 'signaling/src/peerconnection/MediaStreamList.cpp', 'signaling/src/peerconnection/PeerConnectionCtx.cpp', 'signaling/src/peerconnection/PeerConnectionImpl.cpp', 'signaling/src/peerconnection/PeerConnectionMedia.cpp', 'signaling/src/peerconnection/WebrtcGlobalInformation.cpp', - 'signaling/src/sdp/sipcc/ccsdp.c', 'signaling/src/sdp/sipcc/cpr_string.c', 'signaling/src/sdp/sipcc/sdp_access.c', 'signaling/src/sdp/sipcc/sdp_attr.c', 'signaling/src/sdp/sipcc/sdp_attr_access.c', 'signaling/src/sdp/sipcc/sdp_base64.c', 'signaling/src/sdp/sipcc/sdp_config.c', 'signaling/src/sdp/sipcc/sdp_main.c', 'signaling/src/sdp/sipcc/sdp_services_unix.c',
--- a/media/webrtc/signaling/src/jsep/JsepCodecDescription.h +++ b/media/webrtc/signaling/src/jsep/JsepCodecDescription.h @@ -33,20 +33,19 @@ struct JsepCodecDescription { mEnabled(enabled) { } virtual ~JsepCodecDescription() {} virtual JsepCodecDescription* Clone() const = 0; virtual void AddFmtps(SdpFmtpAttributeList& fmtp) const = 0; virtual void AddRtcpFbs(SdpRtcpFbAttributeList& rtcpfb) const = 0; - virtual bool LoadFmtps(const SdpFmtpAttributeList::Parameters& params) = 0; - virtual bool LoadRtcpFbs( - const SdpRtcpFbAttributeList::Feedback& feedback) = 0; + // TODO(bug 1142105): This probably should be a helper function in + // /sdp static bool GetPtAsInt(const std::string& ptString, uint16_t* ptOutparam) { char* end; unsigned long pt = strtoul(ptString.c_str(), &end, 10); size_t length = static_cast<size_t>(end - ptString.c_str()); if ((pt > UINT16_MAX) || (length != ptString.size())) { return false; @@ -75,27 +74,50 @@ struct JsepCodecDescription { } const SdpRtpmapAttributeList::Rtpmap& entry = rtpmap.GetEntry(fmt); if (mType == remoteMsection.GetMediaType() && (mName == entry.name) && (mClock == entry.clock) && (mChannels == entry.channels)) { - return ParametersMatch(FindParameters(entry.pt, remoteMsection)); + return ParametersMatch(entry.pt, remoteMsection); } return false; } virtual bool - ParametersMatch(const SdpFmtpAttributeList::Parameters* fmtp) const + ParametersMatch(const std::string& fmt, + const SdpMediaSection& remoteMsection) const { return true; } + UniquePtr<JsepCodecDescription> + MakeNegotiatedCodec(const std::string& pt, + const SdpMediaSection& remoteMsection) const + { + UniquePtr<JsepCodecDescription> negotiated(Clone()); + + if (!negotiated->Negotiate(pt, remoteMsection)) { + negotiated.reset(); + } + + return negotiated; + } + + virtual bool + Negotiate(const std::string& pt, const SdpMediaSection& remoteMsection) + { + mDefaultPt = pt; + return true; + } + + // TODO(bug 1142105): This probably should be a helper function in + // /sdp static const SdpFmtpAttributeList::Parameters* FindParameters(const std::string& pt, const mozilla::SdpMediaSection& remoteMsection) { const SdpAttributeList& attrs = remoteMsection.GetAttributeList(); if (attrs.HasAttribute(SdpAttribute::kFmtpAttribute)) { const SdpFmtpAttributeList& fmtps = attrs.GetFmtp(); @@ -103,50 +125,56 @@ struct JsepCodecDescription { if (i->format == pt && i->parameters) { return i->parameters.get(); } } } return nullptr; } - virtual JsepCodecDescription* - MakeNegotiatedCodec(const mozilla::SdpMediaSection& remoteMsection, - const std::string& pt, - bool sending) const + UniquePtr<JsepCodecDescription> + MakeSendCodec(const mozilla::SdpMediaSection& remoteMsection, + const std::string& pt) const { - UniquePtr<JsepCodecDescription> negotiated(Clone()); - negotiated->mDefaultPt = pt; - - const SdpAttributeList& attrs = remoteMsection.GetAttributeList(); + UniquePtr<JsepCodecDescription> sendCodec(Clone()); + sendCodec->mDefaultPt = pt; - if (sending) { - auto* parameters = FindParameters(negotiated->mDefaultPt, remoteMsection); - if (parameters) { - if (!negotiated->LoadFmtps(*parameters)) { - // Remote parameters were invalid - return nullptr; - } - } - } else { - // If a receive track, we need to pay attention to remote end's rtcp-fb - if (attrs.HasAttribute(SdpAttribute::kRtcpFbAttribute)) { - auto& rtcpfbs = attrs.GetRtcpFb().mFeedbacks; - for (auto i = rtcpfbs.begin(); i != rtcpfbs.end(); ++i) { - if (i->pt == negotiated->mDefaultPt || i->pt == "*") { - if (!negotiated->LoadRtcpFbs(*i)) { - // Remote parameters were invalid - return nullptr; - } - } - } - } + if (!sendCodec->LoadSendParameters(remoteMsection, pt)) { + sendCodec.reset(); } - return negotiated.release(); + return sendCodec; + } + + UniquePtr<JsepCodecDescription> + MakeRecvCodec(const mozilla::SdpMediaSection& remoteMsection, + const std::string& pt) const + { + UniquePtr<JsepCodecDescription> recvCodec(Clone()); + recvCodec->mDefaultPt = pt; + + if (!recvCodec->LoadRecvParameters(remoteMsection, pt)) { + recvCodec.reset(); + } + + return recvCodec; + } + + virtual bool LoadSendParameters( + const mozilla::SdpMediaSection& remoteMsection, + const std::string& pt) + { + return true; + } + + virtual bool LoadRecvParameters( + const mozilla::SdpMediaSection& remoteMsection, + const std::string& pt) + { + return true; } virtual void AddToMediaSection(SdpMediaSection& msection) const { if (mEnabled && msection.GetMediaType() == mType) { if (mType == SdpMediaSection::kApplication) { // Hack: using mChannels for number of streams @@ -229,30 +257,16 @@ struct JsepAudioCodecDescription : publi } virtual void AddRtcpFbs(SdpRtcpFbAttributeList& rtcpfb) const override { // TODO: Do we want to add anything? } - virtual bool - LoadFmtps(const SdpFmtpAttributeList::Parameters& params) override - { - // TODO - return true; - } - - virtual bool - LoadRtcpFbs(const SdpRtcpFbAttributeList::Feedback& feedback) override - { - // Nothing to do - return true; - } - JSEP_CODEC_CLONE(JsepAudioCodecDescription) uint32_t mPacketSize; uint32_t mBitrate; }; struct JsepVideoCodecDescription : public JsepCodecDescription { JsepVideoCodecDescription(const std::string& defaultPt, @@ -311,57 +325,195 @@ struct JsepVideoCodecDescription : publi // Just hard code for now rtcpfb.PushEntry(mDefaultPt, SdpRtcpFbAttributeList::kNack); rtcpfb.PushEntry( mDefaultPt, SdpRtcpFbAttributeList::kNack, SdpRtcpFbAttributeList::pli); rtcpfb.PushEntry( mDefaultPt, SdpRtcpFbAttributeList::kCcm, SdpRtcpFbAttributeList::fir); } + SdpFmtpAttributeList::H264Parameters + GetH264Parameters(const std::string& pt, + const SdpMediaSection& msection) const + { + // Will contain defaults if nothing else + SdpFmtpAttributeList::H264Parameters result; + auto* params = FindParameters(pt, msection); + + if (params && params->codec_type == SdpRtpmapAttributeList::kH264) { + result = + static_cast<const SdpFmtpAttributeList::H264Parameters&>(*params); + } + + return result; + } + + SdpFmtpAttributeList::VP8Parameters + GetVP8Parameters(const std::string& pt, + const SdpMediaSection& msection) const + { + SdpRtpmapAttributeList::CodecType expectedType( + mName == "VP8" ? + SdpRtpmapAttributeList::kVP8 : + SdpRtpmapAttributeList::kVP9); + + // Will contain defaults if nothing else + SdpFmtpAttributeList::VP8Parameters result(expectedType); + auto* params = FindParameters(pt, msection); + + if (params && params->codec_type == expectedType) { + result = + static_cast<const SdpFmtpAttributeList::VP8Parameters&>(*params); + } + + return result; + } + virtual bool - LoadFmtps(const SdpFmtpAttributeList::Parameters& params) override + Negotiate(const std::string& pt, + const SdpMediaSection& remoteMsection) override + { + if (mName == "H264") { + SdpFmtpAttributeList::H264Parameters h264Params( + GetH264Parameters(pt, remoteMsection)); + if (!h264Params.level_asymmetry_allowed) { + SetSaneH264Level(std::min(GetSaneH264Level(h264Params.profile_level_id), + GetSaneH264Level(mProfileLevelId)), + &mProfileLevelId); + } + + // TODO(bug 1143709): max-recv-level support + } + + return JsepCodecDescription::Negotiate(pt, remoteMsection); + } + + // Maps the not-so-sane encoding of H264 level into something that is + // ordered in the way one would expect + // 1b is 0xAB, everything else is the level left-shifted one half-byte + // (eg; 1.0 is 0xA0, 1.1 is 0xB0, 3.1 is 0x1F0) + static uint32_t + GetSaneH264Level(uint32_t profileLevelId) { - switch (params.codec_type) { - case SdpRtpmapAttributeList::kH264: - LoadH264Parameters(params); - break; - case SdpRtpmapAttributeList::kVP9: - // VP8 and VP9 share the same SDP parameters thus far - case SdpRtpmapAttributeList::kVP8: - LoadVP8Parameters(params); - break; - case SdpRtpmapAttributeList::kiLBC: - case SdpRtpmapAttributeList::kiSAC: - case SdpRtpmapAttributeList::kOpus: - case SdpRtpmapAttributeList::kG722: - case SdpRtpmapAttributeList::kPCMU: - case SdpRtpmapAttributeList::kPCMA: - case SdpRtpmapAttributeList::kOtherCodec: - MOZ_ASSERT(false, "Invalid codec type for video"); + uint32_t profileIdc = (profileLevelId >> 16); + + if (profileIdc == 0x42 || profileIdc == 0x4D || profileIdc == 0x58) { + if ((profileLevelId & 0x10FF) == 0x100B) { + // Level 1b + return 0xAB; + } + } + + uint32_t level = profileLevelId & 0xFF; + + if (level == 0x09) { + // Another way to encode level 1b + return 0xAB; + } + + return level << 4; + } + + static void + SetSaneH264Level(uint32_t level, uint32_t* profileLevelId) + { + uint32_t profileIdc = (*profileLevelId >> 16); + uint32_t levelMask = 0xFF; + + if (profileIdc == 0x42 || profileIdc == 0x4d || profileIdc == 0x58) { + levelMask = 0x10FF; + if (level == 0xAB) { + // Level 1b + level = 0x100B; + } else { + // Not 1b, just shift + level = level >> 4; + } + } else if (level == 0xAB) { + // Another way to encode 1b + level = 0x09; + } else { + // Not 1b, just shift + level = level >> 4; + } + + *profileLevelId = (*profileLevelId & ~levelMask) | level; + } + + virtual bool + LoadSendParameters(const mozilla::SdpMediaSection& remoteMsection, + const std::string& pt) override + { + + if (mName == "H264") { + SdpFmtpAttributeList::H264Parameters h264Params( + GetH264Parameters(pt, remoteMsection)); + + if (!h264Params.level_asymmetry_allowed) { + SetSaneH264Level(std::min(GetSaneH264Level(h264Params.profile_level_id), + GetSaneH264Level(mProfileLevelId)), + &mProfileLevelId); + } else { + SetSaneH264Level(GetSaneH264Level(h264Params.profile_level_id), + &mProfileLevelId); + } + + mMaxFs = h264Params.max_fs; + mMaxMbps = h264Params.max_mbps; + mMaxCpb = h264Params.max_cpb; + mMaxDpb = h264Params.max_dpb; + mMaxBr = h264Params.max_br; + mSpropParameterSets = h264Params.sprop_parameter_sets; + } else if (mName == "VP8" || mName == "VP9") { + SdpFmtpAttributeList::VP8Parameters vp8Params( + GetVP8Parameters(pt, remoteMsection)); + + mMaxFs = vp8Params.max_fs; + mMaxFr = vp8Params.max_fr; } return true; } virtual bool - LoadRtcpFbs(const SdpRtcpFbAttributeList::Feedback& feedback) override + LoadRecvParameters(const mozilla::SdpMediaSection& remoteMsection, + const std::string& pt) override { - switch (feedback.type) { - case SdpRtcpFbAttributeList::kAck: - mAckFbTypes.push_back(feedback.parameter); - break; - case SdpRtcpFbAttributeList::kCcm: - mCcmFbTypes.push_back(feedback.parameter); - break; - case SdpRtcpFbAttributeList::kNack: - mNackFbTypes.push_back(feedback.parameter); - break; - case SdpRtcpFbAttributeList::kApp: - case SdpRtcpFbAttributeList::kTrrInt: - // We don't support these, ignore. - {} + const SdpAttributeList& attrs(remoteMsection.GetAttributeList()); + + if (attrs.HasAttribute(SdpAttribute::kRtcpFbAttribute)) { + auto& rtcpfbs = attrs.GetRtcpFb().mFeedbacks; + for (auto i = rtcpfbs.begin(); i != rtcpfbs.end(); ++i) { + if (i->pt == mDefaultPt || i->pt == "*") { + switch (i->type) { + case SdpRtcpFbAttributeList::kAck: + mAckFbTypes.push_back(i->parameter); + break; + case SdpRtcpFbAttributeList::kCcm: + mCcmFbTypes.push_back(i->parameter); + break; + case SdpRtcpFbAttributeList::kNack: + mNackFbTypes.push_back(i->parameter); + break; + case SdpRtcpFbAttributeList::kApp: + case SdpRtcpFbAttributeList::kTrrInt: + // We don't support these, ignore. + {} + } + } + } + } + + if (mName == "H264") { + SdpFmtpAttributeList::H264Parameters h264Params( + GetH264Parameters(pt, remoteMsection)); + if (!h264Params.level_asymmetry_allowed) { + SetSaneH264Level(std::min(GetSaneH264Level(h264Params.profile_level_id), + GetSaneH264Level(mProfileLevelId)), + &mProfileLevelId); + } } return true; } enum Subprofile { kH264ConstrainedBaseline, kH264Baseline, kH264Main, @@ -480,70 +632,36 @@ struct JsepVideoCodecDescription : publi if ((profileLevelId & 0xFFFF00) == 0x2C1000) { return kH264CALVC44; } return kH264UnknownSubprofile; } virtual bool - ParametersMatch(const SdpFmtpAttributeList::Parameters* fmtp) const - override + ParametersMatch(const std::string& fmt, + const SdpMediaSection& remoteMsection) const override { if (mName == "H264") { - if (!fmtp) { - // No fmtp means that we cannot assume level asymmetry is allowed, - // and since we have no way of knowing the profile-level-id, we can't - // say that we match. + SdpFmtpAttributeList::H264Parameters h264Params( + GetH264Parameters(fmt, remoteMsection)); + + if (h264Params.packetization_mode != mPacketizationMode) { return false; } - auto* h264Params = - static_cast<const SdpFmtpAttributeList::H264Parameters*>(fmtp); - - if (!h264Params->level_asymmetry_allowed) { - if (GetSubprofile(h264Params->profile_level_id) != - GetSubprofile(mProfileLevelId)) { - return false; - } - } - - if (h264Params->packetization_mode != mPacketizationMode) { + if (GetSubprofile(h264Params.profile_level_id) != + GetSubprofile(mProfileLevelId)) { return false; } } + return true; } - void - LoadH264Parameters(const SdpFmtpAttributeList::Parameters& params) - { - const SdpFmtpAttributeList::H264Parameters& h264Params = - static_cast<const SdpFmtpAttributeList::H264Parameters&>(params); - - mMaxFs = h264Params.max_fs; - mProfileLevelId = h264Params.profile_level_id; - mPacketizationMode = h264Params.packetization_mode; - mMaxMbps = h264Params.max_mbps; - mMaxCpb = h264Params.max_cpb; - mMaxDpb = h264Params.max_dpb; - mMaxBr = h264Params.max_br; - mSpropParameterSets = h264Params.sprop_parameter_sets; - } - - void - LoadVP8Parameters(const SdpFmtpAttributeList::Parameters& params) - { - const SdpFmtpAttributeList::VP8Parameters& vp8Params = - static_cast<const SdpFmtpAttributeList::VP8Parameters&>(params); - - mMaxFs = vp8Params.max_fs; - mMaxFr = vp8Params.max_fr; - } - JSEP_CODEC_CLONE(JsepVideoCodecDescription) std::vector<std::string> mAckFbTypes; std::vector<std::string> mNackFbTypes; std::vector<std::string> mCcmFbTypes; uint32_t mMaxFs; @@ -575,30 +693,16 @@ struct JsepApplicationCodecDescription : } virtual void AddRtcpFbs(SdpRtcpFbAttributeList& rtcpfb) const override { // Nothing to do here. } - virtual bool - LoadFmtps(const SdpFmtpAttributeList::Parameters& params) override - { - // TODO: Is there anything to do here? - return true; - } - - virtual bool - LoadRtcpFbs(const SdpRtcpFbAttributeList::Feedback& feedback) override - { - // Nothing to do - return true; - } - JSEP_CODEC_CLONE(JsepApplicationCodecDescription) // Override, uses sctpmap instead of rtpmap virtual bool Matches(const std::string& fmt, const SdpMediaSection& remoteMsection) const override { auto& attrs = remoteMsection.GetAttributeList();
--- a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp +++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp @@ -911,18 +911,22 @@ void JsepSessionImpl::AddCommonCodecs(const SdpMediaSection& remoteMsection, SdpMediaSection* msection) { const std::vector<std::string>& formats = remoteMsection.GetFormats(); for (auto fmt = formats.begin(); fmt != formats.end(); ++fmt) { JsepCodecDescription* codec = FindMatchingCodec(*fmt, remoteMsection); if (codec) { - codec->mDefaultPt = *fmt; // Reflect the other side's PT - codec->AddToMediaSection(*msection); + UniquePtr<JsepCodecDescription> negotiated( + codec->MakeNegotiatedCodec(*fmt, remoteMsection)); + if (negotiated) { + negotiated->AddToMediaSection(*msection); + codec->mDefaultPt = *fmt; // Remember the other side's PT + } // TODO(bug 1099351): Once bug 1073475 is fixed on all supported // versions, we can remove this limitation. break; } } } void @@ -1676,40 +1680,51 @@ JsepSessionImpl::NegotiateTrack(const Sd JsepCodecDescription* codec = FindMatchingCodec(*fmt, remoteMsection); if (!codec) { continue; } bool sending = (direction == JsepTrack::kJsepTrackSending); - // We need to take the remote side's parameters into account so we can - // configure our send media. - // |codec| is assumed to have the necessary state about our own config - // in order to negotiate. - JsepCodecDescription* negotiated = - codec->MakeNegotiatedCodec(remoteMsection, *fmt, sending); - - if (!negotiated) { + // Everywhere else in JsepSessionImpl, a JsepCodecDescription describes + // what one side puts in its SDP. However, we don't want that here; we want + // a JsepCodecDescription that instead encapsulates all the parameters + // that deal with sending (or receiving). For sending, some of these + // parameters will come from the local codec config (eg; rtcp-fb), others + // will come from the remote SDP (eg; max-fps), and still others can only be + // determined by inspecting both local config and remote SDP (eg; + // profile-level-id when level-asymmetry-allowed is 0). + UniquePtr<JsepCodecDescription> sendOrReceiveCodec; + + if (sending) { + sendOrReceiveCodec = + Move(codec->MakeSendCodec(remoteMsection, *fmt)); + } else { + sendOrReceiveCodec = + Move(codec->MakeRecvCodec(remoteMsection, *fmt)); + } + + if (!sendOrReceiveCodec) { continue; } if (remoteMsection.GetMediaType() == SdpMediaSection::kAudio || remoteMsection.GetMediaType() == SdpMediaSection::kVideo) { // Sanity-check that payload type can work with RTP uint16_t payloadType; - if (!negotiated->GetPtAsInt(&payloadType) || + if (!sendOrReceiveCodec->GetPtAsInt(&payloadType) || payloadType > UINT8_MAX) { JSEP_SET_ERROR("audio/video payload type is not an 8 bit unsigned int: " << *fmt); return NS_ERROR_INVALID_ARG; } } - negotiatedDetails->mCodecs.push_back(negotiated); + negotiatedDetails->mCodecs.push_back(sendOrReceiveCodec.release()); break; } if (negotiatedDetails->mCodecs.empty()) { JSEP_SET_ERROR("Failed to negotiate codec details for all codecs"); return NS_ERROR_INVALID_ARG; }
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp +++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp @@ -1,19 +1,16 @@ /* 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/. */ #include "CSFLog.h" #include "nspr.h" #include "plstr.h" -// For rtcp-fb constants -#include "ccsdp.h" - #include "VideoConduit.h" #include "AudioConduit.h" #include "nsThreadUtils.h" #include "LoadManager.h" #include "YuvStamper.h" #include "nsServiceManagerUtils.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" @@ -22,16 +19,23 @@ #include "webrtc/common_video/interface/native_handle.h" #include "webrtc/video_engine/include/vie_errors.h" #include "browser_logging/WebRtcLog.h" #ifdef MOZ_WIDGET_ANDROID #include "AndroidJNIWrapper.h" #endif +// for ntohs +#ifdef _MSC_VER +#include "Winsock2.h" +#else +#include <netinet/in.h> +#endif + #include <algorithm> #include <math.h> #define DEFAULT_VIDEO_MAX_FRAMERATE 30 namespace mozilla { static const char* logTag ="WebrtcVideoSessionConduit";
--- a/media/webrtc/signaling/src/sdp/SdpAttribute.h +++ b/media/webrtc/signaling/src/sdp/SdpAttribute.h @@ -938,21 +938,23 @@ public: virtual void Serialize(std::ostream& os) const = 0; SdpRtpmapAttributeList::CodecType codec_type; }; class H264Parameters : public Parameters { public: + static const uint32_t kDefaultProfileLevelId = 0x420010; + H264Parameters() : Parameters(SdpRtpmapAttributeList::kH264), packetization_mode(0), level_asymmetry_allowed(false), - profile_level_id(0), + profile_level_id(kDefaultProfileLevelId), max_mbps(0), max_fs(0), max_cpb(0), max_dpb(0), max_br(0) { memset(sprop_parameter_sets, 0, sizeof(sprop_parameter_sets)); }
deleted file mode 100644 --- a/media/webrtc/signaling/src/sdp/sipcc/ccsdp.c +++ /dev/null @@ -1,335 +0,0 @@ -/* 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/. */ - -#include "sdp.h" -#include "ccapi.h" - -int ccsdpAttrGetFmtpInst(void *sdp_ptr, uint16_t level, uint16_t payload_num) -{ - cc_sdp_t *sdpp = sdp_ptr; - if ( sdpp->dest_sdp == NULL ) { - return 0; - } - return sdp_find_fmtp_inst(sdpp->dest_sdp, level, payload_num); -} - -const char* ccsdpAttrGetFmtpParamSets(void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return NULL; - } - return sdp_attr_get_fmtp_param_sets(sdpp->dest_sdp, level, cap_num, inst_num); -} - -sdp_result_e ccsdpAttrGetFmtpPackMode(void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t *val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_get_fmtp_pack_mode(sdpp->dest_sdp, level, cap_num, inst_num, val); -} - -sdp_result_e ccsdpAttrGetFmtpLevelAsymmetryAllowed(void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t *val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_get_fmtp_level_asymmetry_allowed(sdpp->dest_sdp, level, cap_num, inst_num, val); -} - -const char* ccsdpAttrGetFmtpProfileLevelId (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return NULL; - } - return sdp_attr_get_fmtp_profile_id(sdpp->dest_sdp, level, cap_num, inst_num); -} - - - -sdp_result_e ccsdpAttrGetFmtpMaxMbps (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t *val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_get_fmtp_max_mbps(sdpp->dest_sdp, level, cap_num, inst_num, val); -} - -sdp_result_e ccsdpAttrGetFmtpMaxFs (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t *val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_get_fmtp_max_fs(sdpp->dest_sdp, level, cap_num, inst_num, val); -} - -sdp_result_e ccsdpAttrGetFmtpMaxCpb (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t *val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_get_fmtp_max_cpb(sdpp->dest_sdp, level, cap_num, inst_num, val); -} - -sdp_result_e ccsdpAttrGetFmtpMaxBr (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t* val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_get_fmtp_max_br(sdpp->dest_sdp, level, cap_num, inst_num, val); -} - -int ccsdpGetBandwidthValue (void *sdp_ptr, uint16_t level, uint16_t inst_num) - -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_get_bw_value(sdpp->dest_sdp, level, inst_num); -} - -sdp_result_e ccsdpAttrGetFmtpMaxDpb (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t *val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->dest_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_get_fmtp_max_dpb(sdpp->dest_sdp, level, cap_num, inst_num, val); -} - -sdp_result_e ccsdpAddNewAttr (void *sdp_ptr, uint16_t level, uint8_t cap_num, - sdp_attr_e attr_type, uint16_t *inst_num) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_add_new_attr(sdpp->src_sdp, level, cap_num, attr_type, inst_num); -} - -sdp_result_e ccsdpAttrSetFmtpPayloadType (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t payload_num) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_payload_type(sdpp->src_sdp, level, cap_num, inst_num, payload_num); -} - - -sdp_result_e ccsdpAttrSetFmtpPackMode (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t pack_mode) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_pack_mode(sdpp->src_sdp, level, cap_num, inst_num, pack_mode); -} - -sdp_result_e ccsdpAttrSetFmtpLevelAsymmetryAllowed (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t asym_allowed) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_level_asymmetry_allowed(sdpp->src_sdp, level, cap_num, inst_num, asym_allowed); -} - - -sdp_result_e ccsdpAttrSetFmtpProfileLevelId (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, const char *profile_level_id) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_profile_level_id(sdpp->src_sdp, level, cap_num, inst_num, profile_level_id); -} - - -sdp_result_e ccsdpAttrSetFmtpParameterSets (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, const char *parameter_sets) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_parameter_sets(sdpp->src_sdp, level, cap_num, inst_num, parameter_sets); -} - - - -sdp_result_e ccsdpAttrSetFmtpMaxBr (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t max_br) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_max_br(sdpp->src_sdp, level, cap_num, inst_num, max_br); -} - - -sdp_result_e ccsdpAttrSetFmtpMaxMbps (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t max_mbps) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_max_mbps(sdpp->src_sdp, level, cap_num, inst_num, max_mbps); -} - -sdp_result_e ccsdpAttrSetFmtpMaxFs (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t max_fs) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_max_fs(sdpp->src_sdp, level, cap_num, inst_num, max_fs); -} - -sdp_result_e ccsdpAttrSetFmtpMaxCpb (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t max_cpb) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_max_cpb(sdpp->src_sdp, level, cap_num, inst_num, max_cpb); -} - -sdp_result_e ccsdpAttrSetFmtpMaxDbp (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t max_dpb) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_max_dpb(sdpp->src_sdp, level, cap_num, inst_num, max_dpb); -} - - -sdp_result_e ccsdpAttrSetFmtpQcif (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t qcif) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_qcif(sdpp->src_sdp, level, cap_num, inst_num, qcif); -} - -sdp_result_e ccsdpAttrSetFmtpSqcif (void *sdp_ptr, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t sqcif) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_attr_set_fmtp_sqcif(sdpp->src_sdp, level, cap_num, inst_num, sqcif); -} - -sdp_result_e ccsdpAddNewBandwidthLine (void *sdp_ptr, uint16_t level, sdp_bw_modifier_e bw_modifier, uint16_t *inst_num) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_add_new_bw_line(sdpp->src_sdp, level, bw_modifier, inst_num); -} - - -sdp_result_e ccsdpSetBandwidth (void *sdp_ptr, uint16_t level, uint16_t inst_num, - sdp_bw_modifier_e bw_modifier, uint32_t bw_val) -{ - cc_sdp_t *sdpp = sdp_ptr; - - if ( sdpp->src_sdp == NULL ) { - return SDP_INVALID_PARAMETER; - } - return sdp_set_bw(sdpp->src_sdp, level, inst_num, bw_modifier, bw_val); -} - -const char * ccsdpCodecName(rtp_ptype ptype) -{ - switch (ptype) - { - case RTP_NONE: return "NONE"; - case RTP_PCMU: return "PCMU"; - case RTP_CELP: return "CELP"; - case RTP_G726: return "G726"; - case RTP_GSM: return "GSM"; - case RTP_G723: return "G723"; - case RTP_DVI4: return "DVI4"; - case RTP_DVI4_II: return "DVI4_II"; - case RTP_LPC: return "LPC"; - case RTP_PCMA: return "PCMA"; - case RTP_G722: return "G722"; - case RTP_G728: return "G728"; - case RTP_G729: return "G729"; - case RTP_JPEG: return "JPEG"; - case RTP_NV: return "NV"; - case RTP_H261: return "H261"; - case RTP_H264_P0: return "H264_P0"; - case RTP_H264_P1: return "H264_P1"; - case RTP_AVT: return "AVT"; - case RTP_L16: return "L16"; - case RTP_H263: return "H263"; - case RTP_ILBC: return "iLBC"; - case RTP_OPUS: return "OPUS"; - case RTP_VP8: return "VP8"; - case RTP_VP9: return "VP9"; - case RTP_I420: return "I420"; - /* case RTP_ISAC: return "ISAC"; */ - } - return "UNKNOWN"; -} -
--- a/media/webrtc/signaling/src/sdp/sipcc/ccsdp.h +++ b/media/webrtc/signaling/src/sdp/sipcc/ccsdp.h @@ -1,53 +1,12 @@ /* 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/. */ -/** - * Skip this file if not doing video on the device. - * - * The ccsdp_xxx api's provide a means to query and populate the SDP attributes - * for video m lines. These Api are not needed if we are not supporting video on - * the platform. For audio the stack will populate the appropriate attributes - * - * - * These API's can be invoked from the vcmCheckAttrs() and vcmPopulateAttrs() - * methods to populate or extract the value of specific attributes in the video SDP. - * These api require an handle to the SDP that is passed in the above methods. - * <pre> - * sdp_handle The SDP handle - * level The level the attribute is defined. Can be either - * SDP_SESSION_LEVEL or 0-n specifying a media line level. - * inst_num The instance number of the attribute. Multiple instances - * of a particular attribute may exist at each level and so - * the inst_num determines the particular attribute at that - * level that should be accessed. Note that this is the - * instance number of the specified type of attribute, not the - * overall attribute number at the level. Also note that the - * instance number is 1-based. For example: - * v=0 - * o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4 - * s=SDP Seminar - * c=IN IP4 10.1.0.2 - * t=0 0 - * m=audio 1234 RTP/AVP 0 101 102 - * a=foo 1 - * a=foo 2 - * a=bar 1 # This is instance 1 of attribute bar. - * a=foo 3 # This is instance 3 of attribute foo. - * cap_num Almost all of the attributes may be defined as X-cpar - * parameters (with the exception of X-sqn, X-cap, and X-cpar). - * If the cap_num is set to zero, then the attribute is not - * an X-cpar parameter attribute. If the cap_num is any other - * value, it specifies the capability number that the X-cpar - * attribute is specified for. - * </pre> - */ - #ifndef __CCSDP_H__ #define __CCSDP_H__ #include "cpr_types.h" #include "ccsdp_rtcp_fb.h" #define SIPSDP_ILBC_MODE20 20 @@ -80,48 +39,16 @@ typedef enum rtp_ptype_ RTP_ILBC = 116, /* used only to make an offer */ RTP_OPUS = 109, RTP_VP8 = 120, RTP_VP9 = 121, RTP_I420 = 124, RTP_ISAC = 124 } rtp_ptype; -/** - * IANA-registered static payload types for the RTP/AVP profile. - * See http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xml - */ -typedef enum static_rtp_ptype_ -{ - STATIC_RTP_AVP_PCMU_8000_1 = 0, - STATIC_RTP_AVP_GSM_8000_1 = 3, - STATIC_RTP_AVP_G723_8000_1 = 4, - STATIC_RTP_AVP_DVI4_8000_1 = 5, - STATIC_RTP_AVP_DVI4_16000_1 = 6, - STATIC_RTP_AVP_LPC_8000_1 = 7, - STATIC_RTP_AVP_PCMA_8000_1 = 8, - STATIC_RTP_AVP_G722_8000_1 = 9, - STATIC_RTP_AVP_L16_44100_2 = 10, - STATIC_RTP_AVP_L16_44100_1 = 11, - STATIC_RTP_AVP_QCELP_8000_1 = 12, - STATIC_RTP_AVP_CN_8000_1 = 13, - STATIC_RTP_AVP_MPA_90000_1 = 14, - STATIC_RTP_AVP_G728_8000_1 = 15, - STATIC_RTP_AVP_DVI4_11025_1 = 16, - STATIC_RTP_AVP_DVI4_22050_1 = 17, - STATIC_RTP_AVP_G729_8000_1 = 18, - STATIC_RTP_AVP_CELB_90000_1 = 25, - STATIC_RTP_AVP_JPEG_90000_1 = 26, - STATIC_RTP_AVP_NV_90000_1 = 28, - STATIC_RTP_AVP_H261_90000_1 = 31, - STATIC_RTP_AVP_MPV_90000_1 = 32, - STATIC_RTP_AVP_MP2T_90000_1 = 33, - STATIC_RTP_AVP_H263_90000_1 = 34 -} static_rtp_ptype; - typedef struct { const char *name; int value; } ccsdp_key_table_entry_t; typedef enum max_coded_audio_bandwidth_ { opus_nb = 0, /* Narrowband */ opus_mb = 1, /* Mediumband */ @@ -255,442 +182,20 @@ typedef enum { SDP_ATTR_MSID_SEMANTIC, SDP_ATTR_BUNDLE_ONLY, SDP_ATTR_END_OF_CANDIDATES, SDP_ATTR_ICE_OPTIONS, SDP_ATTR_SSRC, SDP_MAX_ATTR_TYPES, SDP_ATTR_INVALID } sdp_attr_e; -/* This is here so that it can be used in the VcmSIPCCBinding interface */ + typedef enum { SDP_SETUP_NOT_FOUND = -1, SDP_SETUP_ACTIVE = 0, SDP_SETUP_PASSIVE, SDP_SETUP_ACTPASS, SDP_SETUP_HOLDCONN, SDP_MAX_SETUP, SDP_SETUP_UNKNOWN } sdp_setup_type_e; -/** - * Returns the inst_num value for the specified FTMP attr - * - * @param[in] sdp_handle The SDP handle - * @param[in] level The level to check for the attribute. - * - * @return inst_num The attribute instance number to check, or -1 for failure - */ - -int ccsdpAttrGetFmtpInst(void *sdp_handle, uint16_t level, uint16_t payload_num); - -/** - * Gets the value of the fmtp attribute- parameter-sets parameter for H.264 codec - * - * @param[in] sdp_handle The SDP handle - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * - * @return parameter-sets value. - */ - -const char* ccsdpAttrGetFmtpParamSets(void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num); - -/** - * Gets the value of the fmtp attribute- packetization-mode parameter for H.264 codec - * - * @param[in] sdp_handle The SDP handle - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[out] *val packetization-mode value in the range 0 - 2. - * - * @return sdp_result_e SDP_SUCCESS = SUCCESS - */ -sdp_result_e ccsdpAttrGetFmtpPackMode(void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t *val); -/** - * Gets the value of the fmtp attribute- level asymmetry allowed parameter for H.264 codec - * - * @param[in] sdp_handle The SDP handle - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[out] *val level-asymmetry-allowed param value in the range 0 - 1. - * - * @return sdp_result_e SDP_SUCCESS = SUCCESS - */ -sdp_result_e ccsdpAttrGetFmtpLevelAsymmetryAllowed(void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t *val); - - -/** - * Gets the value of the fmtp attribute- profile-level-id parameter for H.264 codec - * - * @param[in] sdp_handle The SDP handle returned by sdp_init_description. - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * - * @return char * profile-level-id value. - */ -const char* ccsdpAttrGetFmtpProfileLevelId (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num); - -/** - * Gets the value of the fmtp attribute- max-mbps parameter for H.264 codec - * - * @param[in] sdp_handle The SDP handle - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[out] *val max-mbps value. - * - * @return sdp_result_e SDP_SUCCESS - */ - -sdp_result_e ccsdpAttrGetFmtpMaxMbps (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t *val); - -/** - * Gets the value of the fmtp attribute- max-fs parameter for H.264 codec - * - * @param[in] sdp_handle The SDP handle - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[out] *val max-fs value. - * - * @return sdp_result_e SDP_SUCCESS - */ -sdp_result_e ccsdpAttrGetFmtpMaxFs (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t *val); - -/** - * Gets the value of the fmtp attribute- max-cpb parameter for H.264 codec - * @param[in] sdp_handle The SDP handle - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param [out] *val max-cpb value. - * - * @return sdp_result_e SDP_SUCCESS - */ -sdp_result_e ccsdpAttrGetFmtpMaxCpb (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t *val); - -/** - * Gets the value of the fmtp attribute- max-br parameter for H.264 codec - * - * @param[in] sdp_handle The SDP handle - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param [out] *val max-br value. - * - * @return sdp_result_e SDP_SUCCESS - */ -sdp_result_e ccsdpAttrGetFmtpMaxBr (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t* val); - -/** - * Returns the bandwidth value parameter from the b= line. - * - * @param[in] sdp_handle The SDP handle - * @param[in] level The level from which to get the bw value. - * @param[in] inst_num instance number of bw line at the level. The first - * instance has a inst_num of 1 and so on. - * - * @return A valid numerical bw value or SDP_INVALID_VALUE(-2). - */ -int ccsdpGetBandwidthValue (void *sdp_handle, uint16_t level, uint16_t inst_num); - -/** - * Add a new attribute of the specified type at the given level and capability - * level or base attribute if cap_num is zero. - * - * @param[in] sdp_handle The SDP handle - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] attr_type The type of attribute to add. - * @param[in] inst_num Pointer to a uint16_t in which to return the instance number of the newly added attribute. - * - * @return sdp_result_e - * SDP_SUCCESS Attribute was added successfully. - * SDP_NO_RESOURCE No memory avail for new attribute. - * SDP_INVALID_PARAMETER Specified media line is not defined. - */ -sdp_result_e ccsdpAddNewAttr (void *sdp_handle, uint16_t level, uint8_t cap_num, - sdp_attr_e attr_type, uint16_t *inst_num); - -/** - * Gets the value of the fmtp attribute- max-dpb parameter for H.264 codec - * - * @param[in] sdp_handle The SDP handle - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[out] *val max-dpb value. - * - * @return sdp_result_e - * SDP_SUCCESS Attribute was added successfully. - */ - -sdp_result_e ccsdpAttrGetFmtpMaxDpb (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t *val); - - -/** - * Sets the value of the fmtp attribute payload type parameter for the given attribute. - * - * @param[in] sdp_handle The SDP handle - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[in] payload_num New payload type value. - * - * @return SDP_SUCCESS Attribute was added successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e ccsdpAttrSetFmtpPayloadType (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t payload_num); - -/** - * Sets the value of the packetization mode attribute parameter for the given attribute. - * - * @param[in] sdp_handle The SDP handle returned by sdp_init_description. - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[in] pack_mode Packetization mode value - * - * @return SDP_SUCCESS Attribute was added successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e ccsdpAttrSetFmtpPackMode (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t pack_mode); -/** - * Sets the value of the level-asymmetry-allowed attribute parameter for the given attribute. - * - * @param[in] sdp_handle The SDP handle returned by sdp_init_description. - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[in] level_asymmetry_allowed level asymmetry allowed value (0 or 1). - * - * @return SDP_SUCCESS Attribute was added successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e ccsdpAttrSetFmtpLevelAsymmetryAllowed (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t level_asymmetry_allowed); - -/** - * Sets the value of the profile-level-id parameter for the given attribute. - * - * @param[in] sdp_handle The SDP handle returned by sdp_init_description. - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[in] profile_level_id profile_level_id to be set - * - * @return SDP_SUCCESS Attribute was added successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e ccsdpAttrSetFmtpProfileLevelId (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, const char *profile_level_id); - -/** - * Sets the value of the profile-level-id parameter for the given attribute. - * - * @param[in] sdp_handle The SDP handle returned by sdp_init_description. - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[in] parameter_sets parameter_sets to be set - * - * @return SDP_SUCCESS Attribute was added successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e ccsdpAttrSetFmtpParameterSets (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, const char *parameter_sets); - -/** - * Sets the value of the max-br parameter for the given attribute. - * - * @param[in] sdp_handle The SDP handle returned by sdp_init_description. - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[in] max_br max_br value to be set - * - * @return SDP_SUCCESS Attribute was added successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - - -sdp_result_e ccsdpAttrSetFmtpMaxBr (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t max_br); - -/** - * Sets the value of the fmtp attribute- max-mbps parameter for H.264 codec - * - * @param[in] sdp_handle The SDP handle returned by sdp_init_description. - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[in] max_mbps value of max_mbps to be set - * - * @return SDP_SUCCESS Attribute was added successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e ccsdpAttrSetFmtpMaxMbps (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t max_mbps); - -/** - * Sets the value of the fmtp attribute- max-fs parameter for H.264 codec - * @param[in] sdp_handle The SDP handle returned by sdp_init_description. - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[in] max_fs max_fs value to be set - * - * @return SDP_SUCCESS Attribute was added successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e ccsdpAttrSetFmtpMaxFs (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t max_fs); -/** - * Sets the value of the fmtp attribute- max-cbp parameter for H.264 codec - * @param[in] sdp_handle The SDP handle returned by sdp_init_description. - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[in] max_cpb max_cbp value to be set - * - * @return SDP_SUCCESS Attribute was added successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e ccsdpAttrSetFmtpMaxCpb (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t max_cpb); -/** - * Sets the value of the fmtp attribute- max-dbp parameter for H.264 codec - * @param[in] sdp_handle The SDP handle returned by sdp_init_description. - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[in] max_dpb max_dbp value to be set - * - * @return SDP_SUCCESS Attribute was added successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ - -sdp_result_e ccsdpAttrSetFmtpMaxDbp (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t max_dpb); - - -/** - * Sets the value of the fmtp attribute qcif parameter for the given attribute. - * @param[in] sdp_handle The SDP handle returned by sdp_init_description. - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[in] qcif Sets the QCIF value for a video codec - * - * @return SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e ccsdpAttrSetFmtpQcif (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t qcif); - -/** - * Sets the value of the fmtp attribute sqcif parameter for the given attribute. - * - * @param[in] sdp_handle The SDP handle returned by sdp_init_description. - * @param[in] level The level to check for the attribute. - * @param[in] cap_num The capability number associated with the attribute if any. If none, should be zero. - * @param[in] inst_num The attribute instance number to check. - * @param[in] sqcif Sets the SQCIF value for a video codec - * - * @return SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e ccsdpAttrSetFmtpSqcif (void *sdp_handle, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t sqcif); - -/** - * - * To specify bandwidth parameters at any level, a bw line must first be - * added at that level using this function. This function returns the instance - * number of an existing bw_line that matches bw_modifier type, or of a newly - * created bw_line of type bw_modifier. After this addition, you can set the - * properties of the added bw line by using sdp_set_bw(). - * - * Note carefully though, that since there can be multiple instances of bw - * lines at any level, you must specify the instance number when setting - * or getting the properties of a bw line at any level. - * - * This function returns the inst_num variable, the instance number - * of the created bw_line at that level. The instance number is 1 based. - * <pre> - * For example: - * v=0 :Session Level - * o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4 - * s=SDP Seminar - * c=IN IP4 10.1.0.2 - * t=0 0 - * b=AS:60 : instance number 1 - * b=TIAS:50780 : instance number 2 - * m=audio 1234 RTP/AVP 0 101 102 : 1st Media level - * b=AS:12 : instance number 1 - * b=TIAS:8480 : instance number 2 - * m=audio 1234 RTP/AVP 0 101 102 : 2nd Media level - * b=AS:20 : instance number 1 - * </pre> - * @param[in] sdp_handle The SDP handle returned by sdp_init_description. - * @param[in] level The level to create the bw line. - * @param[in] bw_modifier The Type of bandwidth, CT, AS or TIAS. - * @param[out] inst_num This memory is set with the instance number of the newly created bw line instance. - * - * @return SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e ccsdpAddNewBandwidthLine (void *sdp_handle, uint16_t level, sdp_bw_modifier_e bw_modifier, uint16_t *inst_num); - - -/** - * Once a bandwidth line is added under a level, this function can be used to - * set the properties of that bandwidth line. - * - * @param[in] sdp_handle The SDP handle returned by sdp_init_description. - * @param[in] level The level to at which the bw line resides. - * @param[in] inst_num The instance number of the bw line that is to be set. - * @param[in] bw_modifier The Type of bandwidth, CT, AS or TIAS. - * @param[in] bw_val Numerical bandwidth value. - * - * @note Before calling this function to set the bw line, the bw line must - * be added using sdp_add_new_bw_line at the required level. - * - * @return SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e ccsdpSetBandwidth (void *sdp_handle, uint16_t level, uint16_t inst_num, - sdp_bw_modifier_e bw_modifier, uint32_t bw_val); - -/** - * Returns a string representation of a codec's name. - * - * @param[in] rtp_ptype The value taken from the rtp_ptype enumeration - * - * @return A string representing the name of the codec - */ -const char * ccsdpCodecName(rtp_ptype ptype); - #endif
--- a/media/webrtc/signaling/src/sdp/sipcc/sdp.h +++ b/media/webrtc/signaling/src/sdp/sipcc/sdp.h @@ -1185,20 +1185,16 @@ extern tinybool sdp_timespec_valid(sdp_t extern const char *sdp_get_time_start(sdp_t *sdp_ptr); extern const char *sdp_get_time_stop(sdp_t *sdp_ptr); sdp_result_e sdp_set_time_start(sdp_t *sdp_p, const char *start_time); sdp_result_e sdp_set_time_stop(sdp_t *sdp_p, const char *stop_time); extern tinybool sdp_encryption_valid(sdp_t *sdp_p, uint16_t level); extern sdp_encrypt_type_e sdp_get_encryption_method(sdp_t *sdp_p, uint16_t level); extern const char *sdp_get_encryption_key(sdp_t *sdp_p, uint16_t level); -extern sdp_result_e sdp_set_encryption_method(sdp_t *sdp_p, uint16_t level, - sdp_encrypt_type_e method); -extern sdp_result_e sdp_set_encryption_key(sdp_t *sdp_p, uint16_t level, - const char *key); extern tinybool sdp_connection_valid(sdp_t *sdp_p, uint16_t level); extern tinybool sdp_bw_line_exists(sdp_t *sdp_p, uint16_t level, uint16_t inst_num); extern tinybool sdp_bandwidth_valid(sdp_t *sdp_p, uint16_t level, uint16_t inst_num); extern sdp_nettype_e sdp_get_conn_nettype(sdp_t *sdp_p, uint16_t level); extern sdp_addrtype_e sdp_get_conn_addrtype(sdp_t *sdp_p, uint16_t level); extern const char *sdp_get_conn_address(sdp_t *sdp_p, uint16_t level); @@ -1207,18 +1203,16 @@ extern int32_t sdp_get_mcast_ttl(sdp_t * extern int32_t sdp_get_mcast_num_of_addresses(sdp_t *sdp_p, uint16_t level); extern sdp_result_e sdp_set_conn_nettype(sdp_t *sdp_p, uint16_t level, sdp_nettype_e nettype); extern sdp_result_e sdp_set_conn_addrtype(sdp_t *sdp_p, uint16_t level, sdp_addrtype_e addrtype); extern sdp_result_e sdp_set_conn_address(sdp_t *sdp_p, uint16_t level, const char *address); -extern sdp_result_e sdp_set_mcast_addr_fields(sdp_t *sdp_p, uint16_t level, - uint16_t ttl, uint16_t num_addr); extern tinybool sdp_media_line_valid(sdp_t *sdp_p, uint16_t level); extern uint16_t sdp_get_num_media_lines(sdp_t *sdp_ptr); extern sdp_media_e sdp_get_media_type(sdp_t *sdp_p, uint16_t level); extern uint32_t sdp_get_media_line_number(sdp_t *sdp_p, uint16_t level); extern sdp_port_format_e sdp_get_media_port_format(sdp_t *sdp_p, uint16_t level); extern int32_t sdp_get_media_portnum(sdp_t *sdp_p, uint16_t level); extern int32_t sdp_get_media_portcount(sdp_t *sdp_p, uint16_t level); @@ -1236,30 +1230,21 @@ extern uint16_t sdp_get_media_profile_nu extern rtp_ptype sdp_get_known_payload_type(sdp_t *sdp_p, uint16_t level, uint16_t payload_type_raw); extern uint32_t sdp_get_media_payload_type(sdp_t *sdp_p, uint16_t level, uint16_t payload_num, sdp_payload_ind_e *indicator); extern uint32_t sdp_get_media_profile_payload_type(sdp_t *sdp_p, uint16_t level, uint16_t prof_num, uint16_t payload_num, sdp_payload_ind_e *indicator); extern sdp_result_e sdp_insert_media_line(sdp_t *sdp_p, uint16_t level); -extern void sdp_delete_media_line(sdp_t *sdp_p, uint16_t level); extern sdp_result_e sdp_set_media_type(sdp_t *sdp_p, uint16_t level, sdp_media_e media); -extern sdp_result_e sdp_set_media_port_format(sdp_t *sdp_p, uint16_t level, - sdp_port_format_e port_format); extern sdp_result_e sdp_set_media_portnum(sdp_t *sdp_p, uint16_t level, int32_t portnum, int32_t sctpport); extern int32_t sdp_get_media_sctp_port(sdp_t *sdp_p, uint16_t level); -extern sdp_result_e sdp_set_media_portcount(sdp_t *sdp_p, uint16_t level, - int32_t num_ports); -extern sdp_result_e sdp_set_media_vpi(sdp_t *sdp_p, uint16_t level, int32_t vpi); -extern sdp_result_e sdp_set_media_vci(sdp_t *sdp_p, uint16_t level, uint32_t vci); -extern sdp_result_e sdp_set_media_vcci(sdp_t *sdp_p, uint16_t level, int32_t vcci); -extern sdp_result_e sdp_set_media_cid(sdp_t *sdp_p, uint16_t level, int32_t cid); extern sdp_result_e sdp_set_media_transport(sdp_t *sdp_p, uint16_t level, sdp_transport_e transport); extern sdp_result_e sdp_add_media_profile(sdp_t *sdp_p, uint16_t level, sdp_transport_e profile); extern sdp_result_e sdp_add_media_payload_type(sdp_t *sdp_p, uint16_t level, uint16_t payload_type, sdp_payload_ind_e indicator); extern sdp_result_e sdp_add_media_profile_payload_type(sdp_t *sdp_p, uint16_t level, uint16_t prof_num, uint16_t payload_type, @@ -1275,361 +1260,112 @@ extern sdp_result_e sdp_add_new_attr(sdp extern sdp_result_e sdp_attr_num_instances(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, sdp_attr_e attr_type, uint16_t *num_attr_inst); extern tinybool sdp_attr_valid(sdp_t *sdp_p, sdp_attr_e attr_type, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern uint32_t sdp_attr_line_number(sdp_t *sdp_p, sdp_attr_e attr_type, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern const char *sdp_attr_get_simple_string(sdp_t *sdp_p, sdp_attr_e attr_type, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e sdp_attr_set_simple_string(sdp_t *sdp_p, - sdp_attr_e attr_type, uint16_t level, - uint8_t cap_num, uint16_t inst_num, const char *string_parm); extern uint32_t sdp_attr_get_simple_u32(sdp_t *sdp_p, sdp_attr_e attr_type, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e sdp_attr_set_simple_u32(sdp_t *sdp_p, - sdp_attr_e attr_type, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t num_parm); extern tinybool sdp_attr_get_simple_boolean(sdp_t *sdp_p, sdp_attr_e attr_type, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e sdp_attr_set_simple_boolean(sdp_t *sdp_p, - sdp_attr_e attr_type, uint16_t level, uint8_t cap_num, - uint16_t inst_num, uint32_t bool_parm); extern tinybool sdp_attr_is_present (sdp_t *sdp_p, sdp_attr_e attr_type, uint16_t level, uint8_t cap_num); extern const char* sdp_attr_get_maxprate(sdp_t *sdp_p, uint16_t level, uint16_t inst_num); -extern sdp_result_e sdp_attr_set_maxprate(sdp_t *sdp_p, uint16_t level, - uint16_t inst_num, const char *string_parm); extern sdp_t38_ratemgmt_e sdp_attr_get_t38ratemgmt(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e sdp_attr_set_t38ratemgmt(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - sdp_t38_ratemgmt_e t38ratemgmt); extern sdp_t38_udpec_e sdp_attr_get_t38udpec(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e sdp_attr_set_t38udpec(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - sdp_t38_udpec_e t38udpec); extern sdp_direction_e sdp_get_media_direction(sdp_t *sdp_p, uint16_t level, uint8_t cap_num); extern sdp_qos_strength_e sdp_attr_get_qos_strength(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num); extern sdp_qos_status_types_e sdp_attr_get_qos_status_type (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num); extern sdp_qos_dir_e sdp_attr_get_qos_direction(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num); extern tinybool sdp_attr_get_qos_confirm(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num); extern sdp_curr_type_e sdp_attr_get_curr_type (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num); extern sdp_des_type_e sdp_attr_get_des_type (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num); extern sdp_conf_type_e sdp_attr_get_conf_type (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num); -extern sdp_result_e sdp_attr_set_conf_type (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num, - sdp_conf_type_e conf_type); -extern sdp_result_e sdp_attr_set_des_type (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num, - sdp_des_type_e des_type); -extern sdp_result_e sdp_attr_set_curr_type (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num, - sdp_curr_type_e curr_type); -extern sdp_result_e sdp_attr_set_qos_strength(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num, - sdp_qos_strength_e strength); -extern sdp_result_e sdp_attr_set_qos_direction(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num, - sdp_qos_dir_e direction); -extern sdp_result_e sdp_attr_set_qos_status_type(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num, - sdp_qos_status_types_e status_type); -extern sdp_result_e sdp_attr_set_qos_confirm(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num, - tinybool confirm); extern sdp_nettype_e sdp_attr_get_subnet_nettype(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern sdp_addrtype_e sdp_attr_get_subnet_addrtype(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern const char *sdp_attr_get_subnet_addr(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern int32_t sdp_attr_get_subnet_prefix(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e sdp_attr_set_subnet_nettype(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - sdp_nettype_e nettype); -extern sdp_result_e sdp_attr_set_subnet_addrtype(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - sdp_addrtype_e addrtype); -extern sdp_result_e sdp_attr_set_subnet_addr(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - const char *addr); -extern sdp_result_e sdp_attr_set_subnet_prefix(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - int32_t prefix); extern rtp_ptype sdp_attr_get_rtpmap_known_codec(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern tinybool sdp_attr_rtpmap_payload_valid(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t *inst_num, uint16_t payload_type); extern uint16_t sdp_attr_get_rtpmap_payload_type(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern const char *sdp_attr_get_rtpmap_encname(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern uint32_t sdp_attr_get_rtpmap_clockrate(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern uint16_t sdp_attr_get_rtpmap_num_chan(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e sdp_attr_set_rtpmap_payload_type(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t payload_num); -extern sdp_result_e sdp_attr_set_rtpmap_encname(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, const char *encname); -extern sdp_result_e sdp_attr_set_rtpmap_clockrate(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint32_t clockrate); -extern sdp_result_e sdp_attr_set_rtpmap_num_chan(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t num_chan); extern tinybool sdp_attr_sprtmap_payload_valid(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t *inst_num, uint16_t payload_type); extern uint16_t sdp_attr_get_sprtmap_payload_type(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern const char *sdp_attr_get_sprtmap_encname(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern uint32_t sdp_attr_get_sprtmap_clockrate(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern uint16_t sdp_attr_get_sprtmap_num_chan(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e sdp_attr_set_sprtmap_payload_type(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t payload_num); -extern sdp_result_e sdp_attr_set_sprtmap_encname(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, const char *encname); -extern sdp_result_e sdp_attr_set_sprtmap_clockrate(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t clockrate); -extern sdp_result_e sdp_attr_set_sprtmap_num_chan(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint16_t num_chan); extern tinybool sdp_attr_fmtp_payload_valid(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t *inst_num, uint16_t payload_type); extern uint16_t sdp_attr_get_fmtp_payload_type(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern sdp_ne_res_e sdp_attr_fmtp_is_range_set(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, uint8_t low_val, uint8_t high_val); extern tinybool sdp_attr_fmtp_valid(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, uint16_t appl_maxval, uint32_t* evt_array); extern sdp_result_e sdp_attr_set_fmtp_payload_type(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, uint16_t payload_num); extern sdp_result_e sdp_attr_get_fmtp_range(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, uint32_t *bmap); -extern sdp_result_e sdp_attr_set_fmtp_range(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint8_t low_val, uint8_t high_val); -extern sdp_result_e sdp_attr_set_fmtp_bitmap(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t *bmap, uint32_t maxval); extern sdp_result_e sdp_attr_clear_fmtp_range(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, uint8_t low_val, uint8_t high_val); extern sdp_ne_res_e sdp_attr_compare_fmtp_ranges(sdp_t *src_sdp_ptr, sdp_t *dst_sdp_ptr, uint16_t src_level, uint16_t dst_level, uint8_t src_cap_num, uint8_t dst_cap_num, uint16_t src_inst_num, uint16_t dst_inst_num); extern sdp_result_e sdp_attr_copy_fmtp_ranges(sdp_t *src_sdp_ptr, sdp_t *dst_sdp_ptr, uint16_t src_level, uint16_t dst_level, uint8_t src_cap_num, uint8_t dst_cap_num, uint16_t src_inst_num, uint16_t dst_inst_num); -extern sdp_result_e sdp_attr_set_fmtp_annexa (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - tinybool annexa); -extern sdp_result_e sdp_attr_set_fmtp_mode(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint32_t mode); extern uint32_t sdp_attr_get_fmtp_mode_for_payload_type (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint32_t payload_type); -extern sdp_result_e sdp_attr_set_fmtp_annexb (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - tinybool annexb); - -extern sdp_result_e sdp_attr_set_fmtp_bitrate_type (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint32_t bitrate); -extern sdp_result_e sdp_attr_set_fmtp_cif (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t cif); -extern sdp_result_e sdp_attr_set_fmtp_qcif (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t qcif); -extern sdp_result_e sdp_attr_set_fmtp_sqcif (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t sqcif); -extern sdp_result_e sdp_attr_set_fmtp_cif4 (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t cif4); -extern sdp_result_e sdp_attr_set_fmtp_cif16 (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t cif16); -extern sdp_result_e sdp_attr_set_fmtp_maxbr (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t maxbr); -extern sdp_result_e sdp_attr_set_fmtp_max_average_bitrate (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint32_t maxaveragebitrate); -extern sdp_result_e sdp_attr_set_fmtp_usedtx (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - tinybool usedtx); -extern sdp_result_e sdp_attr_set_fmtp_stereo (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - tinybool stereo); -extern sdp_result_e sdp_attr_set_fmtp_useinbandfec (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - tinybool useinbandfec); -extern sdp_result_e sdp_attr_set_fmtp_maxcodedaudiobandwidth (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - const char *maxcodedaudiobandwidth); -extern sdp_result_e sdp_attr_set_fmtp_cbr (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - tinybool cbr); -extern sdp_result_e sdp_attr_set_fmtp_custom (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t custom_x, uint16_t custom_y, - uint16_t custom_mpi); -extern sdp_result_e sdp_attr_set_fmtp_par (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t par_width, uint16_t par_height); -extern sdp_result_e sdp_attr_set_fmtp_bpp (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t bpp); -extern sdp_result_e sdp_attr_set_fmtp_hrd (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t hrd); - -extern sdp_result_e sdp_attr_set_fmtp_h263_num_params (sdp_t *sdp_p, - int16_t level, - uint8_t cap_num, - uint16_t inst_num, - int16_t profile, - uint16_t h263_level, - tinybool interlace); - -extern sdp_result_e sdp_attr_set_fmtp_profile_level_id (sdp_t *sdp_p, - uint16_t level, - uint8_t cap_num, - uint16_t inst_num, - const char *prof_id); - -extern sdp_result_e sdp_attr_set_fmtp_parameter_sets (sdp_t *sdp_p, - uint16_t level, - uint8_t cap_num, - uint16_t inst_num, - const char *parameter_sets); - -extern sdp_result_e sdp_attr_set_fmtp_deint_buf_req (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint32_t deint_buf_req); - -extern sdp_result_e sdp_attr_set_fmtp_init_buf_time (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint32_t init_buf_time); - -extern sdp_result_e sdp_attr_set_fmtp_max_don_diff (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint32_t max_don_diff); - -extern sdp_result_e sdp_attr_set_fmtp_interleaving_depth (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t interleaving_depth); - -extern sdp_result_e sdp_attr_set_fmtp_pack_mode (sdp_t *sdp_p, - uint16_t level, - uint8_t cap_num, - uint16_t inst_num, - uint16_t pack_mode); - -extern sdp_result_e sdp_attr_set_fmtp_level_asymmetry_allowed (sdp_t *sdp_p, - uint16_t level, - uint8_t cap_num, - uint16_t inst_num, - uint16_t level_asymmetry_allowed); - -extern sdp_result_e sdp_attr_set_fmtp_redundant_pic_cap (sdp_t *sdp_p, - uint16_t level, - uint8_t cap_num, - uint16_t inst_num, - tinybool redundant_pic_cap); - -extern sdp_result_e sdp_attr_set_fmtp_max_mbps (sdp_t *sdp_p, - uint16_t level, - uint8_t cap_num, - uint16_t inst_num, - uint32_t max_mbps); - extern sdp_result_e sdp_attr_set_fmtp_max_fs (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, uint32_t max_fs); extern sdp_result_e sdp_attr_set_fmtp_max_fr (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, uint32_t max_fr); -extern sdp_result_e sdp_attr_set_fmtp_max_cpb (sdp_t *sdp_p, - uint16_t level, - uint8_t cap_num, - uint16_t inst_num, - uint32_t max_cpb); - -extern sdp_result_e sdp_attr_set_fmtp_max_dpb (sdp_t *sdp_p, - uint16_t level, - uint8_t cap_num, - uint16_t inst_num, - uint32_t max_dpb); - -extern sdp_result_e sdp_attr_set_fmtp_max_br (sdp_t *sdp_p, - uint16_t level, - uint8_t cap_num, - uint16_t inst_num, - uint32_t max_br); - -extern sdp_result_e sdp_attr_set_fmtp_max_rcmd_nalu_size (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint32_t max_rcmd_nalu_size); - -extern sdp_result_e sdp_attr_set_fmtp_deint_buf_cap (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint32_t deint_buf_cap); - -extern sdp_result_e sdp_attr_set_fmtp_h264_parameter_add (sdp_t *sdp_p, - uint16_t level, - uint8_t cap_num, - uint16_t inst_num, - uint16_t parameter_add); - -extern sdp_result_e sdp_attr_set_fmtp_h261_annex_params (sdp_t *sdp_p, - uint16_t level, - uint8_t cap_num, - uint16_t inst_num, - tinybool annex_d); - -extern sdp_result_e sdp_attr_set_fmtp_h263_annex_params (sdp_t *sdp_p, - uint16_t level, - uint8_t cap_num, - uint16_t inst_num, - tinybool annex_f, - tinybool annex_i, - tinybool annex_j, - tinybool annex_t, - uint16_t annex_k_val, - uint16_t annex_n_val, - uint16_t annex_p_val_picture_resize, - uint16_t annex_p_val_warp); - - /* get routines */ extern int32_t sdp_attr_get_fmtp_bitrate_type (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern int32_t sdp_attr_get_fmtp_cif (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern int32_t sdp_attr_get_fmtp_qcif (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); @@ -1691,26 +1427,18 @@ extern int32_t sdp_attr_get_fmtp_annex_n extern int32_t sdp_attr_get_fmtp_annex_p_picture_resize (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern int32_t sdp_attr_get_fmtp_annex_p_warp (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); /* sctpmap params */ extern uint16_t sdp_attr_get_sctpmap_port(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e sdp_attr_set_sctpmap_port(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t port); extern sdp_result_e sdp_attr_get_sctpmap_protocol (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, char* protocol); -extern sdp_result_e sdp_attr_set_sctpmap_protocol (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - const char *protocol); -extern sdp_result_e sdp_attr_set_sctpmap_streams (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, uint32_t streams); extern sdp_result_e sdp_attr_get_sctpmap_streams (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, uint32_t* val); extern const char *sdp_attr_get_msid_identifier(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern const char *sdp_attr_get_msid_appdata(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); @@ -1792,46 +1520,36 @@ extern sdp_media_e sdp_attr_get_xcap_med uint16_t inst_num); extern sdp_transport_e sdp_attr_get_xcap_transport_type(sdp_t *sdp_p, uint16_t level, uint16_t inst_num); extern uint16_t sdp_attr_get_xcap_num_payload_types(sdp_t *sdp_p, uint16_t level, uint16_t inst_num); extern uint16_t sdp_attr_get_xcap_payload_type(sdp_t *sdp_p, uint16_t level, uint16_t inst_num, uint16_t payload_num, sdp_payload_ind_e *indicator); -extern sdp_result_e sdp_attr_set_xcap_media_type(sdp_t *sdp_p, uint16_t level, - uint16_t inst_num, sdp_media_e media); -extern sdp_result_e sdp_attr_set_xcap_transport_type(sdp_t *sdp_p, uint16_t level, - uint16_t inst_num, sdp_transport_e transport); extern sdp_result_e sdp_attr_add_xcap_payload_type(sdp_t *sdp_p, uint16_t level, uint16_t inst_num, uint16_t payload_type, sdp_payload_ind_e indicator); extern uint16_t sdp_attr_get_cdsc_first_cap_num(sdp_t *sdp_p, uint16_t level, uint16_t inst_num); extern sdp_media_e sdp_attr_get_cdsc_media_type(sdp_t *sdp_p, uint16_t level, uint16_t inst_num); extern sdp_transport_e sdp_attr_get_cdsc_transport_type(sdp_t *sdp_p, uint16_t level, uint16_t inst_num); extern uint16_t sdp_attr_get_cdsc_num_payload_types(sdp_t *sdp_p, uint16_t level, uint16_t inst_num); extern uint16_t sdp_attr_get_cdsc_payload_type(sdp_t *sdp_p, uint16_t level, uint16_t inst_num, uint16_t payload_num, sdp_payload_ind_e *indicator); -extern sdp_result_e sdp_attr_set_cdsc_media_type(sdp_t *sdp_p, uint16_t level, - uint16_t inst_num, sdp_media_e media); -extern sdp_result_e sdp_attr_set_cdsc_transport_type(sdp_t *sdp_p, uint16_t level, - uint16_t inst_num, sdp_transport_e transport); extern sdp_result_e sdp_attr_add_cdsc_payload_type(sdp_t *sdp_p, uint16_t level, uint16_t inst_num, uint16_t payload_type, sdp_payload_ind_e indicator); extern tinybool sdp_media_dynamic_payload_valid (sdp_t *sdp_p, uint16_t payload_type, uint16_t m_line); -extern sdp_result_e sdp_attr_set_rtr_confirm (sdp_t *, uint16_t , \ - uint8_t ,uint16_t ,tinybool ); extern tinybool sdp_attr_get_rtr_confirm (sdp_t *, uint16_t, uint8_t, uint16_t); extern tinybool sdp_attr_get_silencesupp_enabled(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern uint16_t sdp_attr_get_silencesupp_timer(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, tinybool *null_ind); extern sdp_silencesupp_pref_e sdp_attr_get_silencesupp_pref(sdp_t *sdp_p, @@ -1840,120 +1558,59 @@ extern sdp_silencesupp_pref_e sdp_attr_g uint16_t inst_num); extern sdp_silencesupp_siduse_e sdp_attr_get_silencesupp_siduse(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern uint8_t sdp_attr_get_silencesupp_fxnslevel(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, tinybool *null_ind); -extern sdp_result_e sdp_attr_set_silencesupp_enabled(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - tinybool enable); -extern sdp_result_e sdp_attr_set_silencesupp_timer(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t value, - tinybool null_ind); -extern sdp_result_e sdp_attr_set_silencesupp_pref(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - sdp_silencesupp_pref_e pref); -extern sdp_result_e sdp_attr_set_silencesupp_siduse(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - sdp_silencesupp_siduse_e siduse); -extern sdp_result_e sdp_attr_set_silencesupp_fxnslevel(sdp_t *sdp_p, - uint16_t level, - uint8_t cap_num, - uint16_t inst_num, - uint16_t value, - tinybool null_ind); - extern sdp_mediadir_role_e sdp_attr_get_comediadir_role(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e sdp_attr_set_comediadir_role(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - sdp_mediadir_role_e role); - -extern sdp_result_e sdp_delete_all_media_direction_attrs (sdp_t *sdp_p, - uint16_t level); extern uint16_t sdp_attr_get_mptime_num_intervals( sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern uint16_t sdp_attr_get_mptime_interval( sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, uint16_t interval_num); extern sdp_result_e sdp_attr_add_mptime_interval( sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, uint16_t interval); -extern sdp_result_e sdp_delete_bw_line (sdp_t *sdp_p, uint16_t level, uint16_t inst_num); extern sdp_result_e sdp_copy_all_bw_lines(sdp_t *src_sdp_ptr, sdp_t *dst_sdp_ptr, uint16_t src_level, uint16_t dst_level); extern sdp_bw_modifier_e sdp_get_bw_modifier(sdp_t *sdp_p, uint16_t level, uint16_t inst_num); extern const char *sdp_get_bw_modifier_name(sdp_bw_modifier_e bw_modifier); extern int32_t sdp_get_bw_value(sdp_t *sdp_p, uint16_t level, uint16_t inst_num); extern int32_t sdp_get_num_bw_lines (sdp_t *sdp_p, uint16_t level); extern sdp_result_e sdp_add_new_bw_line(sdp_t *sdp_p, uint16_t level, sdp_bw_modifier_e bw_modifier, uint16_t *inst_num); -extern sdp_result_e sdp_set_bw(sdp_t *sdp_p, uint16_t level, uint16_t inst_num, - sdp_bw_modifier_e value, uint32_t bw_val); extern sdp_group_attr_e sdp_get_group_attr(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e sdp_set_group_attr(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - sdp_group_attr_e value); extern const char* sdp_attr_get_x_sidout (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e sdp_attr_set_x_sidout (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - const char *sidout); extern const char* sdp_attr_get_x_sidin (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e sdp_attr_set_x_sidin (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - const char *sidin); - extern const char* sdp_attr_get_x_confid (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e sdp_attr_set_x_confid (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - const char *confid); - -extern sdp_result_e sdp_attr_set_ice_candidate(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, const char *ice_candidate); - extern uint16_t sdp_get_group_num_id(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e sdp_set_group_num_id(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t group_num_id); extern const char* sdp_get_group_id(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, uint16_t id_num); -extern sdp_result_e sdp_set_group_id (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, char* group_id); - extern int32_t sdp_get_mid_value(sdp_t *sdp_p, uint16_t level); -extern sdp_result_e sdp_set_mid_value(sdp_t *sdp_p, uint16_t level, uint32_t mid_val); - -extern sdp_result_e sdp_set_source_filter(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - sdp_src_filter_mode_e mode, - sdp_nettype_e nettype, - sdp_addrtype_e addrtype, - const char *dest_addr, - const char *src_addr); extern sdp_result_e sdp_include_new_filter_src_addr(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, const char *src_addr); extern sdp_src_filter_mode_e sdp_get_source_filter_mode(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern sdp_result_e sdp_get_filter_destination_attributes(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, @@ -1963,19 +1620,16 @@ extern sdp_result_e sdp_get_filter_desti char *dest_addr); extern int32_t sdp_get_filter_source_address_count(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); extern sdp_result_e sdp_get_filter_source_address (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, uint16_t src_addr_id, char *src_addr); -extern sdp_result_e sdp_set_rtcp_unicast_mode(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - sdp_rtcp_unicast_mode_e mode); extern sdp_rtcp_unicast_mode_e sdp_get_rtcp_unicast_mode(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); void sdp_crypto_debug(char *buffer, ulong length_bytes); char * sdp_debug_msg_filter(char *buffer, ulong length_bytes); extern int32_t @@ -2035,104 +1689,39 @@ sdp_attr_get_sdescriptions_salt_size(sdp uint16_t inst_num); extern unsigned long sdp_attr_get_srtp_crypto_selection_flags(sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num); -extern sdp_result_e -sdp_attr_set_sdescriptions_tag(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - int32_t tag_num); - -extern sdp_result_e -sdp_attr_set_sdescriptions_crypto_suite(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - sdp_srtp_crypto_suite_t crypto_suite); - -extern sdp_result_e -sdp_attr_set_sdescriptions_key(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - char *key); - -extern sdp_result_e -sdp_attr_set_sdescriptions_salt(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - char *salt); - -extern sdp_result_e -sdp_attr_set_sdescriptions_lifetime(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - char *lifetime); - -extern sdp_result_e -sdp_attr_set_sdescriptions_mki(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - char *mki_value, - uint16_t mki_length); - -extern sdp_result_e -sdp_attr_set_sdescriptions_key_size(sdp_t *sdp_p, - uint16_t level, - uint8_t cap_num, - uint16_t inst_num, - unsigned char key_size); - -extern sdp_result_e -sdp_attr_set_sdescriptions_salt_size(sdp_t *sdp_p, - uint16_t level, - uint8_t cap_num, - uint16_t inst_num, - unsigned char salt_size); - sdp_result_e sdp_attr_get_ice_attribute (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, sdp_attr_e sdp_attr, uint16_t inst_num, char **out); -sdp_result_e -sdp_attr_set_ice_attribute(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, sdp_attr_e sdp_attr, uint16_t inst_num, const char *ice_attrib); sdp_result_e sdp_attr_get_rtcp_mux_attribute (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, sdp_attr_e sdp_attr, uint16_t inst_num, tinybool *rtcp_mux); sdp_result_e -sdp_attr_set_rtcp_mux_attribute(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, sdp_attr_e sdp_attr, uint16_t inst_num, const tinybool rtcp_mux); - - -sdp_result_e sdp_attr_get_setup_attribute (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, sdp_setup_type_e *setup_type); sdp_result_e -sdp_attr_set_setup_attribute(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, sdp_setup_type_e setup_type); - -sdp_result_e sdp_attr_get_connection_attribute (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, uint16_t inst_num, sdp_connection_type_e *connection_type); sdp_result_e -sdp_attr_set_connection_attribute(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, sdp_connection_type_e connection_type); - -sdp_result_e sdp_attr_get_dtls_fingerprint_attribute (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, sdp_attr_e sdp_attr, uint16_t inst_num, char **out); -sdp_result_e -sdp_attr_set_dtls_fingerprint_attribute(sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, sdp_attr_e sdp_attr, uint16_t inst_num, const char *dtls_fingerprint); - sdp_rtcp_fb_ack_type_e sdp_attr_get_rtcp_fb_ack(sdp_t *sdp_p, uint16_t level, uint16_t payload_type, uint16_t inst); sdp_rtcp_fb_nack_type_e sdp_attr_get_rtcp_fb_nack(sdp_t *sdp_p, uint16_t level, uint16_t payload_type, uint16_t inst); uint32_t sdp_attr_get_rtcp_fb_trr_int(sdp_t *sdp_p, uint16_t level, uint16_t payload_type,
--- a/media/webrtc/signaling/src/sdp/sipcc/sdp_access.c +++ b/media/webrtc/signaling/src/sdp/sipcc/sdp_access.c @@ -503,79 +503,16 @@ const char *sdp_get_encryption_key (sdp_ return (NULL); } encrypt_p = &(mca_p->encrypt); } return (encrypt_p->encrypt_key); } -/* Function: sdp_set_encryption_method - * Description: Sets the value of the encryption method param for the k= - * encryption token line. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the k= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * type The encryption type. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_encryption_method (sdp_t *sdp_p, uint16_t level, - sdp_encrypt_type_e type) -{ - sdp_encryptspec_t *encrypt_p; - sdp_mca_t *mca_p; - - if (level == SDP_SESSION_LEVEL) { - encrypt_p = &(sdp_p->encrypt); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - encrypt_p = &(mca_p->encrypt); - } - - encrypt_p->encrypt_type = type; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_encryption_key - * Description: Sets the value of the encryption key parameter for the k= - * encryption token line. The string is copied into the - * SDP structure so application memory will not be - * referenced by the SDP lib. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the k= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * key Ptr to the encryption key string. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_encryption_key (sdp_t *sdp_p, uint16_t level, const char *key) -{ - sdp_encryptspec_t *encrypt_p; - sdp_mca_t *mca_p; - - if (level == SDP_SESSION_LEVEL) { - encrypt_p = &(sdp_p->encrypt); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - encrypt_p = &(mca_p->encrypt); - } - - sstrncpy(encrypt_p->encrypt_key, key, sizeof(encrypt_p->encrypt_key)); - return (SDP_SUCCESS); -} - /* Function: sdp_connection_valid * Description: Returns true or false depending on whether the connection c= * token line has been defined for this SDP at the given level. * Parameters: sdp_p The SDP handle returned by sdp_init_description. * level The level to check for the c= line. Will be * either SDP_SESSION_LEVEL or 1-n specifying a * media line level. * Returns: TRUE or FALSE. @@ -937,58 +874,16 @@ sdp_result_e sdp_set_conn_address (sdp_t } conn_p = &(mca_p->conn); } sstrncpy(conn_p->conn_addr, address, sizeof(conn_p->conn_addr)); return (SDP_SUCCESS); } -/* Function: sdp_set_mcast_addr_fields - * Description: Sets the value of the ttl and num of addresses for - * a multicast address. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the c= line. Will be - * either SDP_SESSION_LEVEL or 1-n specifying a - * media line level. - * ttl Time to live (ttl) value. - * num_of_addresses number of addresses - . - * Returns: SDP_SUCCESS - */ -sdp_result_e sdp_set_mcast_addr_fields(sdp_t *sdp_p, uint16_t level, - uint16_t ttl, uint16_t num_of_addresses) -{ - sdp_conn_t *conn_p; - sdp_mca_t *mca_p; - - if (level == SDP_SESSION_LEVEL) { - conn_p = &(sdp_p->default_conn); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - conn_p = &(mca_p->conn); - } - - if (conn_p) { - conn_p->is_multicast = TRUE; - if ((conn_p->ttl >0) && (conn_p->ttl <= SDP_MAX_TTL_VALUE)) { - conn_p->ttl = ttl; - } - conn_p->num_of_addresses = num_of_addresses; - } else { - return (SDP_FAILURE); - } - return (SDP_SUCCESS); -} - - /* Function: sdp_media_line_valid * Description: Returns true or false depending on whether the specified * media line m= has been defined for this SDP. The * SDP_SESSION_LEVEL level is not valid for this check since, * by definition, this is a media level. * Parameters: sdp_p The SDP handle returned by sdp_init_description. * level The level to check for the c= line. Will be * 1-n specifying a media line level. @@ -1618,76 +1513,16 @@ sdp_result_e sdp_insert_media_line (sdp_ new_mca_p->next_p = mca_p->next_p; mca_p->next_p = new_mca_p; } sdp_p->mca_count++; return (SDP_SUCCESS); } -/* Function: sdp_delete_media_line - * Description: Delete the media line at the level specified for the - * given SDP. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The media level to delete. Will be 1-n. - * Returns: SDP_SUCCESS, SDP_NO_RESOURCE, or SDP_INVALID_PARAMETER - */ -void sdp_delete_media_line (sdp_t *sdp_p, uint16_t level) -{ - sdp_mca_t *mca_p; - sdp_mca_t *prev_mca_p = NULL; - sdp_attr_t *attr_p; - sdp_attr_t *next_attr_p; - sdp_bw_t *bw_p; - sdp_bw_data_t *bw_data_p; - - /* If we're not deleting media line 1, then we need a pointer - * to the previous media line so we can relink. */ - if (level == 1) { - mca_p = sdp_find_media_level(sdp_p, level); - } else { - prev_mca_p = sdp_find_media_level(sdp_p, (uint16_t)(level-1)); - if (prev_mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return; - } - mca_p = prev_mca_p->next_p; - } - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return; - } - - /* Delete all attributes from this level. */ - for (attr_p = mca_p->media_attrs_p; attr_p != NULL;) { - next_attr_p = attr_p->next_p; - sdp_free_attr(attr_p); - attr_p = next_attr_p; - } - - /* Delete bw line */ - bw_p = &(mca_p->bw); - bw_data_p = bw_p->bw_data_list; - while (bw_data_p != NULL) { - bw_p->bw_data_list = bw_data_p->next_p; - SDP_FREE(bw_data_p); - bw_data_p = bw_p->bw_data_list; - } - - /* Now relink the media levels and delete the specified one. */ - if (prev_mca_p == NULL) { - sdp_p->mca_p = mca_p->next_p; - } else { - prev_mca_p->next_p = mca_p->next_p; - } - SDP_FREE(mca_p); - sdp_p->mca_count--; - return; -} - /* Function: sdp_set_media_type * Description: Sets the value of the media type parameter for the m= * media token line. * Parameters: sdp_p The SDP handle returned by sdp_init_description. * level The media level to set the param. Will be 1-n. * media Media type for the media line. * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER */ @@ -1700,42 +1535,16 @@ sdp_result_e sdp_set_media_type (sdp_t * sdp_p->conf_p->num_invalid_param++; return (SDP_INVALID_PARAMETER); } mca_p->media = media; return (SDP_SUCCESS); } -/* Function: sdp_set_media_port_format - * Description: Sets the value of the port format parameter for the m= - * media token line. Note that this parameter must be set - * before any of the port type specific parameters. If a - * parameter is not valid according to the port format - * specified, an attempt to set the parameter will fail. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The media level to set the param. Will be 1-n. - * port_format Media type for the media line. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_media_port_format (sdp_t *sdp_p, uint16_t level, - sdp_port_format_e port_format) -{ - sdp_mca_t *mca_p; - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->port_format = port_format; - return (SDP_SUCCESS); -} - /* Function: sdp_set_media_portnum * Description: Sets the value of the port number parameter for the m= * media token line. If the port number is not valid with the * port format specified for the media line, this call will * fail. * Parameters: sdp_p The SDP handle returned by sdp_init_description. * level The media level to set the param. Will be 1-n. * portnum Port number to set. @@ -1772,137 +1581,16 @@ int32_t sdp_get_media_sctp_port(sdp_t *s if (!mca_p) { sdp_p->conf_p->num_invalid_param++; return -1; } return mca_p->sctpport; } -/* Function: sdp_set_media_portcount - * Description: Sets the value of the port count parameter for the m= - * media token line. If the port count is not valid with the - * port format specified for the media line, this call will - * fail. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The media level to set the param. Will be 1-n. - * num_ports Port count to set. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_media_portcount (sdp_t *sdp_p, uint16_t level, - int32_t num_ports) -{ - sdp_mca_t *mca_p; - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->num_ports = num_ports; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_media_vpi - * Description: Sets the value of the VPI parameter for the m= - * media token line. If the VPI is not valid with the - * port format specified for the media line, this call will - * fail. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The media level to set the param. Will be 1-n. - * vpi The VPI value to set. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_media_vpi (sdp_t *sdp_p, uint16_t level, int32_t vpi) -{ - sdp_mca_t *mca_p; - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->vpi = vpi; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_media_vci - * Description: Sets the value of the VCI parameter for the m= - * media token line. If the VCI is not valid with the - * port format specified for the media line, this call will - * fail. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The media level to set the param. Will be 1-n. - * vci The VCI value to set. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_media_vci (sdp_t *sdp_p, uint16_t level, uint32_t vci) -{ - sdp_mca_t *mca_p; - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->vci = vci; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_media_vcci - * Description: Sets the value of the VCCI parameter for the m= - * media token line. If the VCCI is not valid with the - * port format specified for the media line, this call will - * fail. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The media level to set the param. Will be 1-n. - * vcci The VCCI value to set. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_media_vcci (sdp_t *sdp_p, uint16_t level, int32_t vcci) -{ - sdp_mca_t *mca_p; - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->vcci = vcci; - return (SDP_SUCCESS); -} - -/* Function: sdp_set_media_cid - * Description: Sets the value of the CID parameter for the m= - * media token line. If the CID is not valid with the - * port format specified for the media line, this call will - * fail. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The media level to set the param. Will be 1-n. - * cid The CID value to set. - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER - */ -sdp_result_e sdp_set_media_cid (sdp_t *sdp_p, uint16_t level, int32_t cid) -{ - sdp_mca_t *mca_p; - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - mca_p->cid = cid; - return (SDP_SUCCESS); -} - /* Function: sdp_set_media_transport * Description: Sets the value of the transport type parameter for the m= * media token line. * Parameters: sdp_p The SDP handle returned by sdp_init_description. * level The media level to set the param. Will be 1-n. * transport The transport type to set. * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER */ @@ -2358,121 +2046,16 @@ sdp_result_e sdp_add_new_bw_line (sdp_t bw_data_p->next_p = new_bw_data_p; } *inst_num = ++bw_p->bw_data_count; return (SDP_SUCCESS); } -/* - * sdp_delete_bw_line - * - * Deletes the bw line instance at the specified level. - * - * sdp_p The SDP handle returned by sdp_init_description. - * level The level to delete the bw line. - * inst_num The instance of the bw line to delete. - */ -sdp_result_e sdp_delete_bw_line (sdp_t *sdp_p, uint16_t level, uint16_t inst_num) -{ - sdp_bw_t *bw_p; - sdp_mca_t *mca_p; - sdp_bw_data_t *bw_data_p = NULL; - sdp_bw_data_t *prev_bw_data_p = NULL; - int bw_data_count = 0; - - if (level == SDP_SESSION_LEVEL) { - bw_p = &(sdp_p->bw); - } else { - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - bw_p = &(mca_p->bw); - } - - bw_data_p = bw_p->bw_data_list; - while (bw_data_p != NULL) { - bw_data_count++; - if (bw_data_count == inst_num) { - break; - } - - prev_bw_data_p = bw_data_p; - bw_data_p = bw_data_p->next_p; - } - - if (bw_data_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s bw line instance %u not found.", - sdp_p->debug_str, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - if (prev_bw_data_p == NULL) { - bw_p->bw_data_list = bw_data_p->next_p; - } else { - prev_bw_data_p->next_p = bw_data_p->next_p; - } - bw_p->bw_data_count--; - - SDP_FREE(bw_data_p); - return (SDP_SUCCESS); -} - -/* - * sdp_set_bw - * - * Once a bandwidth line is added under a level, this function can be used to - * set the properties of that bandwidth line. - * - * Parameters: - * sdp_p The SDP handle returned by sdp_init_description. - * level The level to at which the bw line resides. - * inst_num The instance number of the bw line that is to be set. - * bw_modifier The Type of bandwidth, CT, AS or TIAS. - * bw_val Numerical bandwidth value. - * - * NOTE: Before calling this function to set the bw line, the bw line must - * be added using sdp_add_new_bw_line at the required level. - */ -sdp_result_e sdp_set_bw (sdp_t *sdp_p, uint16_t level, uint16_t inst_num, - sdp_bw_modifier_e bw_modifier, uint32_t bw_val) -{ - sdp_bw_data_t *bw_data_p; - - if ((bw_modifier < SDP_BW_MODIFIER_AS) || - (bw_modifier >= SDP_MAX_BW_MODIFIER_VAL)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Invalid bw modifier type: %d.", - sdp_p->debug_str, bw_modifier); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - bw_data_p = sdp_find_bw_line(sdp_p, level, inst_num); - if (bw_data_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s The %u instance of a b= line was not found at level %u.", - sdp_p->debug_str, (unsigned)inst_num, (unsigned)level); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - bw_data_p->bw_modifier = bw_modifier; - bw_data_p->bw_val = bw_val; - - return (SDP_SUCCESS); -} - /* Function: sdp_get_mid_value * Description: Returns the mid value parameter from the a= mid: line. * Parameters: sdp_p The SDP handle returned by sdp_init_description. * level SDP_MEDIA_LEVEL * Returns: mid value. */ int32_t sdp_get_mid_value (sdp_t *sdp_p, uint16_t level) { @@ -2481,28 +2064,8 @@ int32_t sdp_get_mid_value (sdp_t *sdp_p, mca_p = sdp_find_media_level(sdp_p, level); if (mca_p == NULL) { sdp_p->conf_p->num_invalid_param++; return (SDP_INVALID_VALUE); } return (mca_p->mid); } -/* Function: sdp_set_mid_value - * Description: Sets the value of the mid value for the - * a= mid:<val> line. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level SDP_MEDIA_LEVEL - * mid_val mid value . - * Returns: SDP_SUCCESS or SDP_INVALID_PARAMETER -*/ -sdp_result_e sdp_set_mid_value (sdp_t *sdp_p, uint16_t level, uint32_t mid_val) -{ - sdp_mca_t *mca_p; - - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - mca_p->mid = mid_val; - return (SDP_SUCCESS); -}
--- a/media/webrtc/signaling/src/sdp/sipcc/sdp_attr_access.c +++ b/media/webrtc/signaling/src/sdp/sipcc/sdp_attr_access.c @@ -495,17 +495,17 @@ int sdp_find_fmtp_inst (sdp_t *sdp_p, ui * Description: Find the specified attribute in an SDP structure. * Note: This is not an API for the application but an internal * routine used by the SDP library. * Parameters: sdp_p The SDP handle returned by sdp_init_description. * level The level to check for the attribute. * cap_num The capability number associated with the * attribute if any. If none, should be zero. * attr_type The type of attribute to find. - * inst_num The instance num of the attribute to delete. + * inst_num The instance num of the attribute to find. * Range should be (1 - max num insts of this * particular type of attribute at this level). * Returns: Pointer to the attribute or NULL if not found. */ sdp_attr_t *sdp_find_attr (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, sdp_attr_e attr_type, uint16_t inst_num) { uint16_t attr_count=0; @@ -728,66 +728,16 @@ const char *sdp_attr_get_simple_string ( } sdp_p->conf_p->num_invalid_param++; return (NULL); } else { return (attr_p->attr.string_val); } } -/* Function: sdp_attr_set_simple_string - * Description: Sets the value of a string attribute parameter. This - * routine can only be called for attributes that have just - * one string parameter. The string is copied into the SDP - * structure so application memory will not be referenced by - * the SDP library. - * Attributes with a simple string parameter currently include: - * bearer, called, connection_type, dialed, dialing, and - * framing. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * attr_type The simple string attribute type. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * string_parm Ptr to new string value. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_simple_string (sdp_t *sdp_p, sdp_attr_e attr_type, - uint16_t level, uint8_t cap_num, - uint16_t inst_num, const char *string_parm) -{ - sdp_attr_t *attr_p; - - if (!sdp_attr_is_simple_string(attr_type)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute type is not a simple string (%s)", - sdp_p->debug_str, sdp_get_attr_name(attr_type)); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute %s, level %u instance %u not found.", - sdp_p->debug_str, sdp_get_attr_name(attr_type), - (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - sstrncpy(attr_p->attr.string_val, string_parm, - sizeof(attr_p->attr.string_val)); - return (SDP_SUCCESS); - } -} - static boolean sdp_attr_is_simple_u32(sdp_attr_e attr_type) { if ((attr_type != SDP_ATTR_EECID) && (attr_type != SDP_ATTR_PTIME) && (attr_type != SDP_ATTR_MAXPTIME) && (attr_type != SDP_ATTR_T38_VERSION) && (attr_type != SDP_ATTR_T38_MAXBITRATE) && (attr_type != SDP_ATTR_T38_MAXBUFFER) && (attr_type != SDP_ATTR_T38_MAXDGRAM) && @@ -847,64 +797,16 @@ uint32_t sdp_attr_get_simple_u32 (sdp_t } sdp_p->conf_p->num_invalid_param++; return (0); } else { return (attr_p->attr.u32_val); } } -/* Function: sdp_attr_set_simple_u32 - * Description: Sets the value of an unsigned 32-bit attribute parameter. - * This routine can only be called for attributes that have just - * one uint32_t parameter. - * Attributes with a simple uint32_t parameter currently include: - * eecid, ptime, T38FaxVersion, T38maxBitRate, T38FaxMaxBuffer, - * T38FaxMaxDatagram, X-sqn, TC1PayloadBytes, TC1WindowSize, - * TC2PayloadBytes, TC2WindowSize, rtcp. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * attr_type The simple uint32_t attribute type. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * num_parm New uint32_t parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_simple_u32 (sdp_t *sdp_p, sdp_attr_e attr_type, - uint16_t level, uint8_t cap_num, uint16_t inst_num, uint32_t num_parm) -{ - sdp_attr_t *attr_p; - - if (!sdp_attr_is_simple_u32(attr_type)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute type is not a simple uint32_t (%s)", - sdp_p->debug_str, sdp_get_attr_name(attr_type)); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute %s, level %u instance %u not found.", - sdp_p->debug_str, sdp_get_attr_name(attr_type), - (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.u32_val = num_parm; - return (SDP_SUCCESS); - } -} - - /* Function: sdp_attr_get_simple_boolean * Description: Returns a boolean attribute parameter. This * routine can only be called for attributes that have just * one boolean parameter. If the given attribute is not defined, * FALSE will be returned. There is no way for the application * to determine if FALSE is the actual value or the attribute * wasn't defined, so the application must use the * sdp_attr_valid function to determine this. @@ -945,66 +847,16 @@ tinybool sdp_attr_get_simple_boolean (sd } sdp_p->conf_p->num_invalid_param++; return (FALSE); } else { return (attr_p->attr.boolean_val); } } -/* Function: sdp_attr_set_simple_boolean - * Description: Sets the value of a boolean attribute parameter. - * This routine can only be called for attributes that have just - * one boolean parameter. - * Attributes with a simple boolean parameter currently include: - * T38FaxFillBitRemoval, T38FaxTranscodingMMR, - * T38FaxTranscodingJBIG, and TMRGwXid. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * attr_type The simple boolean attribute type. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * bool_parm New boolean parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_simple_boolean (sdp_t *sdp_p, sdp_attr_e attr_type, - uint16_t level, uint8_t cap_num, - uint16_t inst_num, uint32_t bool_parm) -{ - sdp_attr_t *attr_p; - - if ((attr_type != SDP_ATTR_T38_FILLBITREMOVAL) && - (attr_type != SDP_ATTR_T38_TRANSCODINGMMR) && - (attr_type != SDP_ATTR_T38_TRANSCODINGJBIG) && - (attr_type != SDP_ATTR_TMRGWXID)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute type is not a simple boolean (%s)", - sdp_p->debug_str, sdp_get_attr_name(attr_type)); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - attr_p = sdp_find_attr(sdp_p, level, cap_num, attr_type, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute %s, level %u instance %u not found.", - sdp_p->debug_str, sdp_get_attr_name(attr_type), - (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.boolean_val = (tinybool)bool_parm; - return (SDP_SUCCESS); - } -} - /* * sdp_attr_get_maxprate * * This function is used by the application layer to get the packet-rate * within the maxprate attribute. * * Parameters: sdp_p The SDP handle returned by sdp_init_description. * level The level to check for the attribute. @@ -1027,78 +879,16 @@ sdp_attr_get_maxprate (sdp_t *sdp_p, uin } sdp_p->conf_p->num_invalid_param++; return (NULL); } else { return (attr_p->attr.string_val); } } -/* - * sdp_attr_set_maxprate - * - * This function is used by the application layer to set the packet rate of - * the maxprate attribute line appropriately. The maxprate attribute is - * defined as follows: - * - * max-p-rate-def = "a" "=" "maxprate" ":" packet-rate CRLF - * packet-rate = 1*DIGIT ["." 1*DIGIT] - * - * - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * inst_num The attribute instance number to set. - * string_parm A string that contains the value of packet-rate - * that needs to be advertised. - * - * Note that we use a string to set the packet-rate, so the application layer - * must format a string, as per the packet-rate format and pass it to this - * function. - * - * The decision to use a string to communicate the packet-rate was - * made because some operating systems do not support floating point - * operations. - * - * Returns: - * SDP_INVALID_SDP_PTR - If an invalid sdp handle is passed in. - * SDP_INVALID_PARAMETER - If the maxprate attribute is not defined at the - * specified level OR if the packet-rate is not - * formatted correctly in string_parm. - * SDP_SUCCESS - If we are successfully able to set the maxprate attribute. - */ -sdp_result_e -sdp_attr_set_maxprate (sdp_t *sdp_p, uint16_t level, uint16_t inst_num, - const char *string_parm) -{ - sdp_attr_t *attr_p; - - attr_p = sdp_find_attr(sdp_p, level, 0, SDP_ATTR_MAXPRATE, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Attribute %s, level %u instance %u not found.", - sdp_p->debug_str, sdp_get_attr_name(SDP_ATTR_MAXPRATE), - (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - if (!sdp_validate_maxprate(string_parm)) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s is not a valid maxprate value.", string_parm); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - - sstrncpy(attr_p->attr.string_val, string_parm, - sizeof(attr_p->attr.string_val)); - return (SDP_SUCCESS); - } -} - /* Function: sdp_attr_get_t38ratemgmt * Description: Returns the value of the t38ratemgmt attribute * parameter specified for the given attribute. If the given * attribute is not defined, SDP_T38_UNKNOWN_RATE is returned. * Parameters: sdp_p The SDP handle returned by sdp_init_description. * level The level to check for the attribute. * cap_num The capability number associated with the * attribute if any. If none, should be zero. @@ -1119,50 +909,16 @@ sdp_t38_ratemgmt_e sdp_attr_get_t38ratem } sdp_p->conf_p->num_invalid_param++; return (SDP_T38_UNKNOWN_RATE); } else { return (attr_p->attr.t38ratemgmt); } } -/* Function: sdp_attr_set_t38ratemgmt - * Description: Sets the value of the t38ratemgmt attribute parameter - * for the given attribute. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * t38ratemgmt New t38ratemgmt parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_t38ratemgmt (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - sdp_t38_ratemgmt_e t38ratemgmt) -{ - sdp_attr_t *attr_p; - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_T38_RATEMGMT, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s t38ratemgmt attribute, level %u instance %u " - "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.t38ratemgmt = t38ratemgmt; - return (SDP_SUCCESS); - } -} - - /* Function: sdp_attr_get_t38udpec * Description: Returns the value of the t38udpec attribute * parameter specified for the given attribute. If the given * attribute is not defined, SDP_T38_UDPEC_UNKNOWN is returned. * Parameters: sdp_p The SDP handle returned by sdp_init_description. * level The level to check for the attribute. * cap_num The capability number associated with the * attribute if any. If none, should be zero. @@ -1183,50 +939,16 @@ sdp_t38_udpec_e sdp_attr_get_t38udpec (s } sdp_p->conf_p->num_invalid_param++; return (SDP_T38_UDPEC_UNKNOWN); } else { return (attr_p->attr.t38udpec); } } -/* Function: sdp_attr_set_t38udpec - * Description: Sets the value of the t38ratemgmt attribute parameter - * for the given attribute. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * t38udpec New t38udpec parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_t38udpec (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - sdp_t38_udpec_e t38udpec) -{ - sdp_attr_t *attr_p; - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_T38_UDPEC, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s t38udpec attribute, level %u instance %u " - "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.t38udpec = t38udpec; - return (SDP_SUCCESS); - } -} - - /* Function: sdp_get_media_direction * Description: Determines the direction defined for a given level. The * direction will be inactive, sendonly, recvonly, or sendrecv * as determined by the last of these attributes specified at * the given level. If none of these attributes are specified, * the direction will be sendrecv by default. * Parameters: sdp_p The SDP handle returned by sdp_init_description. * level The level to check for the attribute. @@ -1270,95 +992,16 @@ sdp_direction_e sdp_get_media_direction CSFLogDebug(logTag, "%s Warning: Invalid cap_num for media direction.", sdp_p->debug_str); } } return (direction); } -/* - * sdp_delete_all_media_direction_attrs - * - * Deletes all the media direction attributes from a given SDP level. - * Media direction attributes include: - * a=sendonly - * a=recvonly - * a=sendrecv - * a=inactive - * - * This function can be used in conjunction with sdp_add_new_attr, to ensure - * that there is only one direction attribute per level. - * It can also be used to delete all attributes when the client wants to - * advertise the default direction, i.e. a=sendrecv. - */ -sdp_result_e sdp_delete_all_media_direction_attrs (sdp_t *sdp_p, uint16_t level) -{ - sdp_mca_t *mca_p; - sdp_attr_t *attr_p; - sdp_attr_t *prev_attr_p = NULL; - sdp_attr_t *tmp_attr_p = NULL; - - /* Find the pointer to the attr list for this level. */ - if (level == SDP_SESSION_LEVEL) { - attr_p = sdp_p->sess_attrs_p; - while (attr_p != NULL) { - if ((attr_p->type == SDP_ATTR_INACTIVE) || - (attr_p->type == SDP_ATTR_SENDONLY) || - (attr_p->type == SDP_ATTR_RECVONLY) || - (attr_p->type == SDP_ATTR_SENDRECV)) { - - tmp_attr_p = attr_p; - - if (prev_attr_p == NULL) { - sdp_p->sess_attrs_p = attr_p->next_p; - } else { - prev_attr_p->next_p = attr_p->next_p; - } - attr_p = attr_p->next_p; - - sdp_free_attr(tmp_attr_p); - } else { - prev_attr_p = attr_p; - attr_p = attr_p->next_p; - } - } - } else { /* Attr is at a media level */ - mca_p = sdp_find_media_level(sdp_p, level); - if (mca_p == NULL) { - return (SDP_INVALID_MEDIA_LEVEL); - } - - attr_p = mca_p->media_attrs_p; - while (attr_p != NULL) { - if ((attr_p->type == SDP_ATTR_INACTIVE) || - (attr_p->type == SDP_ATTR_SENDONLY) || - (attr_p->type == SDP_ATTR_RECVONLY) || - (attr_p->type == SDP_ATTR_SENDRECV)) { - - tmp_attr_p = attr_p; - - if (prev_attr_p == NULL) { - mca_p->media_attrs_p = attr_p->next_p; - } else { - prev_attr_p->next_p = attr_p->next_p; - } - attr_p = attr_p->next_p; - - sdp_free_attr(tmp_attr_p); - } else { - prev_attr_p = attr_p; - attr_p = attr_p->next_p; - } - } - } - - return (SDP_SUCCESS); -} - /* Since there are four different attribute names which all have the same * qos parameters, all of these attributes are accessed through this same * set of APIs. To distinguish between specific attributes, the application * must also pass the attribute type. The attribute must be one of: * SDP_ATTR_QOS, SDP_ATTR_SECURE, SDP_ATTR_X_PC_QOS, and SDP_ATTR_X_QOS. */ tinybool sdp_validate_qos_attr (sdp_attr_e qos_attr) { @@ -1559,66 +1202,16 @@ tinybool sdp_attr_get_qos_confirm (sdp_t } sdp_p->conf_p->num_invalid_param++; return (FALSE); } else { return (attr_p->attr.qos.confirm); } } -/* Function: sdp_attr_set_qos_strength - * Description: Sets the qos strength value for the specified qos attribute. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * strength New qos strength parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_qos_strength (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, - sdp_attr_e qos_attr, uint16_t inst_num, - sdp_qos_strength_e strength) -{ - sdp_attr_t *attr_p; - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid QOS attribute specified " - "for set qos strength.", sdp_p->debug_str); - } - return (SDP_FAILURE); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - switch (qos_attr) { - case SDP_ATTR_QOS: - attr_p->attr.qos.strength = strength; - return (SDP_SUCCESS); - case SDP_ATTR_DES: - attr_p->attr.des.strength = strength; - return (SDP_SUCCESS); - default: - return (SDP_FAILURE); - - } - } -} - /* Function: sdp_attr_get_curr_type * Description: Returns the value of the curr attribute status_type * parameter specified for the given attribute. If the given * attribute is not defined, SDP_CURR_UNKNOWN_TYPE is * returned. * Parameters: sdp_p The SDP handle returned by sdp_init_description. * level The level to check for the attribute. * cap_num The capability number associated with the @@ -1708,300 +1301,16 @@ sdp_conf_type_e sdp_attr_get_conf_type ( } sdp_p->conf_p->num_invalid_param++; return (SDP_CONF_UNKNOWN_TYPE); } else { return (attr_p->attr.conf.type); } } -/* Function: sdp_attr_set_curr_type - * Description: Returns the value of the curr attribute status_type - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_CURR_UNKNOWN_TYPE is - * returned. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_curr_type (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num, - sdp_curr_type_e curr_type) -{ - sdp_attr_t *attr_p; - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid curr attribute specified " - "for set curr type.", sdp_p->debug_str); - } - return (SDP_FAILURE); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.curr.type = curr_type; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_des_type - * Description: Sets the value of the des attribute type - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_DES_UNKNOWN_TYPE is - * returned. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_des_type (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num, - sdp_des_type_e des_type) -{ - sdp_attr_t *attr_p; - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid des attribute specified " - "for set des type.", sdp_p->debug_str); - } - return (SDP_FAILURE); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.des.type = des_type; - return (SDP_SUCCESS); - } -} - - -/* Function: sdp_attr_set_conf_type - * Description: Sets the value of the conf attribute type - * parameter specified for the given attribute. If the given - * attribute is not defined, SDP_CONF_UNKNOWN_TYPE is - * returned. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_conf_type (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, sdp_attr_e qos_attr, uint16_t inst_num, - sdp_conf_type_e conf_type) -{ - sdp_attr_t *attr_p; - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid conf attribute specified " - "for set conf type.", sdp_p->debug_str); - } - return (SDP_FAILURE); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.conf.type = conf_type; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_qos_direction - * Description: Sets the qos direction value for the specified qos attribute. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * direction New qos direction parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_qos_direction (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, - sdp_attr_e qos_attr, uint16_t inst_num, - sdp_qos_dir_e direction) -{ - sdp_attr_t *attr_p; - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid QOS attribute specified " - "for set qos direction.", sdp_p->debug_str); - } - return (SDP_FAILURE); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - switch (qos_attr) { - case SDP_ATTR_QOS: - attr_p->attr.qos.direction = direction; - return (SDP_SUCCESS); - case SDP_ATTR_CURR: - attr_p->attr.curr.direction = direction; - return (SDP_SUCCESS); - case SDP_ATTR_DES: - attr_p->attr.des.direction = direction; - return (SDP_SUCCESS); - case SDP_ATTR_CONF: - attr_p->attr.conf.direction = direction; - return (SDP_SUCCESS); - default: - return (SDP_FAILURE); - - } - } -} - -/* Function: sdp_attr_set_qos_status_type - * Description: Sets the qos status_type value for the specified qos attribute. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * direction New qos direction parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_qos_status_type (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, - sdp_attr_e qos_attr, uint16_t inst_num, - sdp_qos_status_types_e status_type) -{ - sdp_attr_t *attr_p; - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid QOS attribute specified " - "for set qos status_type.", sdp_p->debug_str); - } - return (SDP_FAILURE); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - switch (qos_attr) { - case SDP_ATTR_CURR: - attr_p->attr.curr.status_type = status_type; - return (SDP_SUCCESS); - case SDP_ATTR_DES: - attr_p->attr.des.status_type = status_type; - return (SDP_SUCCESS); - case SDP_ATTR_CONF: - attr_p->attr.conf.status_type = status_type; - return (SDP_SUCCESS); - default: - return (SDP_FAILURE); - - } - } -} - -/* Function: sdp_attr_set_qos_confirm - * Description: Sets the qos confirm value for the specified qos attribute. - * If this parameter is TRUE, the confirm parameter will be - * specified when the SDP description is built. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * qos_attr The specific type of qos attribute. May be - * qos, secure, X-pc-qos, or X-qos. - * inst_num The attribute instance number to check. - * confirm New qos confirm parameter. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_qos_confirm (sdp_t *sdp_p, uint16_t level, uint8_t cap_num, - sdp_attr_e qos_attr, uint16_t inst_num, - tinybool qos_confirm) -{ - sdp_attr_t *attr_p; - - if (sdp_validate_qos_attr(qos_attr) == FALSE) { - if (sdp_p->debug_flag[SDP_DEBUG_WARNINGS]) { - CSFLogDebug(logTag, "%s Warning: Invalid QOS attribute specified " - "for set qos confirm.", sdp_p->debug_str); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } - attr_p = sdp_find_attr(sdp_p, level, cap_num, qos_attr, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s %s attribute, level %u instance %u " - "not found.", sdp_p->debug_str, - sdp_get_attr_name(qos_attr), (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.qos.confirm = qos_confirm; - return (SDP_SUCCESS); - } -} - - /* Function: sdp_attr_get_subnet_nettype * Description: Returns the value of the subnet attribute network type * parameter specified for the given attribute. If the given * attribute is not defined, SDP_NT_INVALID is returned. * Parameters: sdp_p The SDP handle returned by sdp_init_description. * level The level to check for the attribute. * cap_num The capability number associated with the * attribute if any. If none, should be zero. @@ -2116,152 +1425,16 @@ int32_t sdp_attr_get_subnet_prefix (sdp_ } sdp_p->conf_p->num_invalid_param++; return (SDP_INVALID_VALUE); } else { return (attr_p->attr.subnet.prefix); } } -/* Function: sdp_attr_set_subnet_nettype - * Description: Sets the value of the subnet attribute nettype parameter - * for the given attribute. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * nettype The network type for the attribute. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_subnet_nettype (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - sdp_nettype_e nettype) -{ - sdp_attr_t *attr_p; - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SUBNET, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Subnet attribute, level %u instance %u " - "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.subnet.nettype = nettype; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_subnet_addrtype - * Description: Sets the value of the subnet attribute addrtype parameter - * for the given attribute. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * addrtype The address type for the attribute. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_subnet_addrtype (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - sdp_addrtype_e sdp_addrtype) -{ - sdp_attr_t *attr_p; - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SUBNET, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Subnet attribute, level %u instance %u " - "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.subnet.addrtype = sdp_addrtype; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_subnet_addr - * Description: Sets the value of the subnet attribute addr parameter - * for the given attribute. The address is copied into the - * SDP structure so application memory will not be - * referenced by the SDP lib. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * addr Ptr to the address string for the attribute. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_subnet_addr (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - const char *addr) -{ - sdp_attr_t *attr_p; - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SUBNET, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Subnet attribute, level %u instance %u " - "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - sstrncpy(attr_p->attr.subnet.addr, addr, - sizeof(attr_p->attr.subnet.addr)) ; - return (SDP_SUCCESS); - } -} - -/* Function: sdp_attr_set_subnet_prefix - * Description: Sets the value of the subnet attribute prefix parameter - * for the given attribute. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * prefix Prefix value for the attribute. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_subnet_prefix (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - int32_t prefix) -{ - sdp_attr_t *attr_p; - - attr_p = sdp_find_attr(sdp_p, level, cap_num, - SDP_ATTR_SUBNET, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s Subnet attribute, level %u instance %u " - "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else { - attr_p->attr.subnet.prefix = prefix; - return (SDP_SUCCESS); - } -} - - /* Function: sdp_attr_rtpmap_payload_valid * Description: Returns true or false depending on whether an rtpmap * attribute was specified with the given payload value * at the given level. If it was, the instance number of * that attribute is returned. * Parameters: sdp_p The SDP handle returned by sdp_init_description. * level The level to check for the attribute. * cap_num The capability number associated with the @@ -2415,82 +1588,16 @@ uint16_t sdp_attr_get_rtpmap_num_chan (s } sdp_p->conf_p->num_invalid_param++; return (0); } else { return (attr_p->attr.transport_map.num_chan); } } -/* Function: sdp_attr_set_rtpmap_payload_type - * Description: Sets the value of the rtpmap attribute payload type parameter - * for the given attribute. - * Parameters: sdp_p The SDP handle returned by sdp_init_description. - * level The level to check for the attribute. - * cap_num The capability number associated with the - * attribute if any. If none, should be zero. - * inst_num The attribute instance number to check. - * payload_num New payload type value. - * Returns: SDP_SUCCESS Attribute param was set successfully. - * SDP_INVALID_PARAMETER Specified attribute is not defined. - */ -sdp_result_e sdp_attr_set_rtpmap_payload_type (sdp_t *sdp_p, uint16_t level, - uint8_t cap_num, uint16_t inst_num, - uint16_t payload_num) -{ - sdp_attr_t *attr_p; - - attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_RTPMAP, inst_num); - if (attr_p == NULL) { - if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { - CSFLogError(logTag, "%s rtpmap attribute, level %u instance %u " - "not found.", sdp_p->debug_str, (unsigned)level, (unsigned)inst_num); - } - sdp_p->conf_p->num_invalid_param++; - return (SDP_INVALID_PARAMETER); - } else {