From 9dff5bab8a86075ae79cf737ba36378c5a2cc0d7 Mon Sep 17 00:00:00 2001 From: Eric Faust Date: Mon, 23 Sep 2013 15:24:58 -0700 Subject: [PATCH 001/160] Bug 918593 - Part 0: Remove unused name parameter from GenerateReadSlot(). (r=djvj) --- js/src/jit/IonCaches.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index ab844cb2e801..d5712735b02a 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -714,8 +714,8 @@ GenerateDOMProxyChecks(JSContext *cx, MacroAssembler &masm, JSObject *obj, static void GenerateReadSlot(JSContext *cx, IonScript *ion, MacroAssembler &masm, - IonCache::StubAttacher &attacher, JSObject *obj, PropertyName *name, - JSObject *holder, Shape *shape, Register object, TypedOrValueRegister output, + IonCache::StubAttacher &attacher, JSObject *obj, JSObject *holder, + Shape *shape, Register object, TypedOrValueRegister output, Label *failures = NULL) { JS_ASSERT(obj->isNative()); @@ -1222,7 +1222,7 @@ GetPropertyIC::tryAttachNative(JSContext *cx, IonScript *ion, HandleObject obj, switch (type) { case CanAttachReadSlot: - GenerateReadSlot(cx, ion, masm, attacher, obj, name, holder, + GenerateReadSlot(cx, ion, masm, attacher, obj, holder, shape, object(), output()); attachKind = idempotent() ? "idempotent reading" : "non idempotent reading"; @@ -1825,7 +1825,7 @@ GetPropertyParIC::attachReadSlot(LockedJSContext &cx, IonScript *ion, JSObject * // Ready to generate the read slot stub. DispatchStubPrepender attacher(*this); MacroAssembler masm(cx); - GenerateReadSlot(cx, ion, masm, attacher, obj, name(), holder, shape, object(), output()); + GenerateReadSlot(cx, ion, masm, attacher, obj, holder, shape, object(), output()); return linkAndAttachStub(cx, masm, attacher, ion, "parallel reading"); } @@ -2839,7 +2839,7 @@ GetElementIC::attachGetProp(JSContext *cx, IonScript *ion, HandleObject obj, masm.branchTestValue(Assembler::NotEqual, val, idval, &failures); RepatchStubAppender attacher(*this); - GenerateReadSlot(cx, ion, masm, attacher, obj, name, holder, shape, object(), output(), + GenerateReadSlot(cx, ion, masm, attacher, obj, holder, shape, object(), output(), &failures); return linkAndAttachStub(cx, masm, attacher, ion, "property"); @@ -3514,7 +3514,7 @@ GetElementParIC::attachReadSlot(LockedJSContext &cx, IonScript *ion, JSObject *o ValueOperand val = index().reg().valueReg(); masm.branchTestValue(Assembler::NotEqual, val, idval, &failures); - GenerateReadSlot(cx, ion, masm, attacher, obj, name, holder, shape, object(), output(), + GenerateReadSlot(cx, ion, masm, attacher, obj, holder, shape, object(), output(), &failures); return linkAndAttachStub(cx, masm, attacher, ion, "parallel getelem reading"); From 525b3811acaf1eb6e27e1685c4d91eb5bd2b9204 Mon Sep 17 00:00:00 2001 From: Eric Faust Date: Mon, 23 Sep 2013 15:36:19 -0700 Subject: [PATCH 002/160] Bug 918593 - Part 1: Allow caching of global object prototypal name sets in NameIC. (r=djvj) --- js/src/jit/IonCaches.cpp | 40 +++++++++++++++++----------------------- js/src/jit/IonCaches.h | 4 ++-- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index d5712735b02a..b72aa93fcf4a 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -3660,7 +3660,7 @@ GenerateScopeChainGuard(MacroAssembler &masm, JSObject *scopeObj, static void GenerateScopeChainGuards(MacroAssembler &masm, JSObject *scopeChain, JSObject *holder, - Register outputReg, Label *failures) + Register outputReg, Label *failures, bool skipLastGuard = false) { JSObject *tobj = scopeChain; @@ -3669,7 +3669,11 @@ GenerateScopeChainGuards(MacroAssembler &masm, JSObject *scopeChain, JSObject *h while (true) { JS_ASSERT(IsCacheableNonGlobalScope(tobj) || tobj->is()); + if (skipLastGuard && tobj == holder) + break; + GenerateScopeChainGuard(masm, tobj, outputReg, NULL, failures); + if (tobj == holder) break; @@ -3773,7 +3777,8 @@ BindNameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain) } bool -NameIC::attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain, HandleObject holder, +NameIC::attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain, + HandleObject holderBase, HandleObject holder, HandleShape shape) { MacroAssembler masm(cx); @@ -3782,26 +3787,16 @@ NameIC::attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain, H Register scratchReg = outputReg().valueReg().scratchReg(); + // Don't guard the base of the proto chain the name was found on. It will be guarded + // by GenerateReadSlot(). masm.mov(scopeChainReg(), scratchReg); - GenerateScopeChainGuards(masm, scopeChain, holder, scratchReg, &failures); + GenerateScopeChainGuards(masm, scopeChain, holderBase, scratchReg, &failures, + /* skipLastGuard = */true); - unsigned slot = shape->slot(); - if (holder->isFixedSlot(slot)) { - Address addr(scratchReg, JSObject::getFixedSlotOffset(slot)); - masm.loadTypedOrValue(addr, outputReg()); - } else { - masm.loadPtr(Address(scratchReg, JSObject::offsetOfSlots()), scratchReg); - - Address addr(scratchReg, holder->dynamicSlotIndex(slot) * sizeof(Value)); - masm.loadTypedOrValue(addr, outputReg()); - } - - attacher.jumpRejoin(masm); - - if (failures.used()) { - masm.bind(&failures); - attacher.jumpNextStub(masm); - } + // GenerateScopeChain leaves the last scope chain in scrachReg, even though it + // doesn't generate the extra guard. + GenerateReadSlot(cx, ion, masm, attacher, holderBase, holder, shape, scratchReg, + outputReg(), failures.used() ? &failures : NULL); return linkAndAttachStub(cx, masm, attacher, ion, "generic"); } @@ -3815,8 +3810,6 @@ IsCacheableNameReadSlot(JSContext *cx, HandleObject scopeChain, HandleObject obj return false; if (!obj->isNative()) return false; - if (obj != holder) - return false; if (obj->is()) { // Support only simple property lookups. @@ -3824,6 +3817,7 @@ IsCacheableNameReadSlot(JSContext *cx, HandleObject scopeChain, HandleObject obj !IsCacheableNoProperty(obj, holder, shape, pc, output)) return false; } else if (obj->is()) { + JS_ASSERT(obj == holder); if (!shape->hasDefaultGetter()) return false; } else { @@ -3904,7 +3898,7 @@ NameIC::update(JSContext *cx, size_t cacheIndex, HandleObject scopeChain, if (cache.canAttachStub()) { if (IsCacheableNameReadSlot(cx, scopeChain, obj, holder, shape, pc, cache.outputReg())) { - if (!cache.attachReadSlot(cx, ion, scopeChain, obj, shape)) + if (!cache.attachReadSlot(cx, ion, scopeChain, obj, holder, shape)) return false; } else if (IsCacheableNameCallGetter(scopeChain, obj, holder, shape)) { if (!cache.attachCallGetter(cx, ion, obj, holder, shape, returnAddr)) diff --git a/js/src/jit/IonCaches.h b/js/src/jit/IonCaches.h index 7e3423fb16e6..826f917e19e3 100644 --- a/js/src/jit/IonCaches.h +++ b/js/src/jit/IonCaches.h @@ -932,8 +932,8 @@ class NameIC : public RepatchIonCache return typeOf_; } - bool attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain, HandleObject obj, - HandleShape shape); + bool attachReadSlot(JSContext *cx, IonScript *ion, HandleObject scopeChain, + HandleObject holderBase, HandleObject holder, HandleShape shape); bool attachCallGetter(JSContext *cx, IonScript *ion, JSObject *obj, JSObject *holder, HandleShape shape, void *returnAddr); From abd5b28be15714dd35713aa615ca072543de5bbc Mon Sep 17 00:00:00 2001 From: Nicholas Cameron Date: Tue, 24 Sep 2013 10:59:26 +1200 Subject: [PATCH 003/160] Bug 915940. Memory reporter for memory image surfaces. r=njn,mattwoodrow --- gfx/layers/client/TextureClient.cpp | 4 +++- gfx/layers/composite/TextureHost.cpp | 3 +++ gfx/layers/ipc/ISurfaceAllocator.cpp | 6 ++++- gfx/layers/ipc/ISurfaceAllocator.h | 36 ++++++++++++++++++++++++++++ gfx/thebes/gfxPlatform.cpp | 3 +++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index c93d4c1de042..6e1048248354 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -211,6 +211,7 @@ MemoryTextureClient::Allocate(uint32_t aSize) { MOZ_ASSERT(!mBuffer); mBuffer = new uint8_t[aSize]; + GfxHeapTexturesReporter::OnAlloc(mBuffer); mBufSize = aSize; return true; } @@ -228,9 +229,10 @@ MemoryTextureClient::MemoryTextureClient(CompositableClient* aCompositable, MemoryTextureClient::~MemoryTextureClient() { MOZ_COUNT_DTOR(MemoryTextureClient); - if (ShouldDeallocateInDestructor()) { + if (ShouldDeallocateInDestructor() && mBuffer) { // if the buffer has never been shared we must deallocate it or ir would // leak. + GfxHeapTexturesReporter::OnFree(mBuffer); delete mBuffer; } } diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp index 9e06d00ed160..afb43eca5662 100644 --- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -535,6 +535,9 @@ MemoryTextureHost::~MemoryTextureHost() void MemoryTextureHost::DeallocateSharedData() { + if (mBuffer) { + GfxHeapTexturesReporter::OnFree(mBuffer); + } delete[] mBuffer; } diff --git a/gfx/layers/ipc/ISurfaceAllocator.cpp b/gfx/layers/ipc/ISurfaceAllocator.cpp index 4202983b80f5..00c572f22cfd 100644 --- a/gfx/layers/ipc/ISurfaceAllocator.cpp +++ b/gfx/layers/ipc/ISurfaceAllocator.cpp @@ -27,6 +27,8 @@ using namespace mozilla::ipc; namespace mozilla { namespace layers { +mozilla::Atomic GfxHeapTexturesReporter::sAmount; + SharedMemory::SharedMemoryType OptimalShmemType() { return SharedMemory::TYPE_BASIC; @@ -88,6 +90,7 @@ ISurfaceAllocator::AllocSurfaceDescriptorWithCaps(const gfxIntSize& aSize, if (!data) { return false; } + GfxHeapTexturesReporter::OnAlloc(data); #ifdef XP_MACOSX // Workaround a bug in Quartz where drawing an a8 surface to another a8 // surface with OPERATOR_SOURCE still requires the destination to be clear. @@ -134,7 +137,8 @@ ISurfaceAllocator::DestroySharedSurface(SurfaceDescriptor* aSurface) case SurfaceDescriptor::TSurfaceDescriptorD3D10: break; case SurfaceDescriptor::TMemoryImage: - delete [] (unsigned char *)aSurface->get_MemoryImage().data(); + GfxHeapTexturesReporter::OnFree((uint8_t*)aSurface->get_MemoryImage().data()); + delete [] (uint8_t*)aSurface->get_MemoryImage().data(); break; case SurfaceDescriptor::Tnull_t: case SurfaceDescriptor::T__None: diff --git a/gfx/layers/ipc/ISurfaceAllocator.h b/gfx/layers/ipc/ISurfaceAllocator.h index 6dfeee646c55..56352184202e 100644 --- a/gfx/layers/ipc/ISurfaceAllocator.h +++ b/gfx/layers/ipc/ISurfaceAllocator.h @@ -11,6 +11,8 @@ #include "gfxASurface.h" // for gfxASurface, etc #include "gfxPoint.h" // for gfxIntSize #include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc +#include "nsIMemoryReporter.h" // for MemoryUniReporter +#include "mozilla/Atomics.h" // for Atomic /* * FIXME [bjacob] *** PURE CRAZYNESS WARNING *** @@ -25,6 +27,8 @@ class gfxASurface; class gfxSharedImageSurface; +class MemoryTextureClient; +class MemoryTextureHost; namespace base { class Thread; @@ -133,6 +137,38 @@ protected: ~ISurfaceAllocator() {} }; +class GfxHeapTexturesReporter MOZ_FINAL : public mozilla::MemoryUniReporter +{ +public: + GfxHeapTexturesReporter() + : MemoryUniReporter("explicit/gfx/heap-textures", KIND_HEAP, UNITS_BYTES, + "Heap memory shared between threads by texture clients and hosts.") + { +#ifdef DEBUG + // There must be only one instance of this class, due to |sAmount| + // being static. + static bool hasRun = false; + MOZ_ASSERT(!hasRun); + hasRun = true; +#endif + } + + static void OnAlloc(void* aPointer) + { + sAmount += MallocSizeOfOnAlloc(aPointer); + } + + static void OnFree(void* aPointer) + { + sAmount -= MallocSizeOfOnFree(aPointer); + } + +private: + int64_t Amount() MOZ_OVERRIDE { return sAmount; } + + static mozilla::Atomic sAmount; +}; + } // namespace } // namespace diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index 306381514fb7..99ea0b3f54ba 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -10,6 +10,7 @@ #include "mozilla/layers/CompositorChild.h" #include "mozilla/layers/CompositorParent.h" #include "mozilla/layers/ImageBridgeChild.h" +#include "mozilla/layers/ISurfaceAllocator.h" // for GfxHeapTexturesReporter #include "prlog.h" #include "prenv.h" @@ -441,6 +442,8 @@ gfxPlatform::Init() false); CreateCMSOutputProfile(); + + NS_RegisterMemoryReporter(new GfxHeapTexturesReporter()); } void From c2fe69d31672fa2029df5851cb5f711621fce4d2 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 24 Sep 2013 09:04:53 +0900 Subject: [PATCH 004/160] Bug 919045 - Only traverse test directories when tests are enabled with pseudo-derecurse. r=gps --- python/mozbuild/mozbuild/backend/recursivemake.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py index 6145a11dcb23..d09b6ce512c7 100644 --- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -669,8 +669,9 @@ class RecursiveMakeBackend(CommonBackend): if obj.test_dirs: fh.write('TEST_DIRS := %s\n' % ' '.join(obj.test_dirs)) - self._traversal.add(backend_file.relobjdir, - tests=relativize(obj.test_dirs)) + if self.environment.substs.get('ENABLE_TESTS', False): + self._traversal.add(backend_file.relobjdir, + tests=relativize(obj.test_dirs)) if obj.test_tool_dirs and \ self.environment.substs.get('ENABLE_TESTS', False): From a5640bf8f5d8231f0920e9984d91dbf2cda52f0f Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Mon, 23 Sep 2013 17:05:27 -0700 Subject: [PATCH 005/160] Bug 919825: Annotate class nsSecurityConsoleMessage as MOZ_FINAL to fix -Wdelete-non-virtual-dtor GCC build warning. rs=ehsan --- xpcom/base/nsSecurityConsoleMessage.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xpcom/base/nsSecurityConsoleMessage.h b/xpcom/base/nsSecurityConsoleMessage.h index 828fe5b720ad..1b8c03165e28 100644 --- a/xpcom/base/nsSecurityConsoleMessage.h +++ b/xpcom/base/nsSecurityConsoleMessage.h @@ -7,7 +7,7 @@ #include "nsISecurityConsoleMessage.h" #include "nsString.h" -class nsSecurityConsoleMessage : public nsISecurityConsoleMessage +class nsSecurityConsoleMessage MOZ_FINAL : public nsISecurityConsoleMessage { public: NS_DECL_ISUPPORTS From 48946a9621b7304cc021e124aa940f4ead415254 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 23 Sep 2013 20:25:17 -0400 Subject: [PATCH 006/160] Bug 862627 part 1. Switch EventListener to WebIDL codegen. r=smaug --- content/base/public/nsINode.h | 2 +- content/base/src/nsINode.cpp | 2 +- content/events/public/EventTarget.h | 4 ++-- content/events/src/EventTarget.cpp | 2 +- content/events/src/nsDOMEventTargetHelper.cpp | 2 +- content/events/src/nsDOMEventTargetHelper.h | 2 +- dom/base/nsGlobalWindow.cpp | 2 +- dom/base/nsGlobalWindow.h | 2 +- dom/base/nsWindowRoot.cpp | 2 +- dom/base/nsWindowRoot.h | 2 +- dom/bindings/Bindings.conf | 3 --- dom/bindings/Codegen.py | 13 +++---------- dom/devicestorage/DeviceStorage.h | 4 ++-- dom/devicestorage/nsDeviceStorage.cpp | 4 ++-- 14 files changed, 18 insertions(+), 28 deletions(-) diff --git a/content/base/public/nsINode.h b/content/base/public/nsINode.h index 1224705c13cc..55489d6e7e3c 100644 --- a/content/base/public/nsINode.h +++ b/content/base/public/nsINode.h @@ -802,7 +802,7 @@ public: using mozilla::dom::EventTarget::RemoveEventListener; using nsIDOMEventTarget::AddEventListener; virtual void AddEventListener(const nsAString& aType, - nsIDOMEventListener* aListener, + mozilla::dom::EventListener* aListener, bool aUseCapture, const mozilla::dom::Nullable& aWantsUntrusted, mozilla::ErrorResult& aRv) MOZ_OVERRIDE; diff --git a/content/base/src/nsINode.cpp b/content/base/src/nsINode.cpp index f1254d749065..34239d05f986 100644 --- a/content/base/src/nsINode.cpp +++ b/content/base/src/nsINode.cpp @@ -1048,7 +1048,7 @@ nsINode::AddEventListener(const nsAString& aType, void nsINode::AddEventListener(const nsAString& aType, - nsIDOMEventListener* aListener, + EventListener* aListener, bool aUseCapture, const Nullable& aWantsUntrusted, ErrorResult& aRv) diff --git a/content/events/public/EventTarget.h b/content/events/public/EventTarget.h index 722656b43a51..579948b94461 100644 --- a/content/events/public/EventTarget.h +++ b/content/events/public/EventTarget.h @@ -40,12 +40,12 @@ public: using nsIDOMEventTarget::RemoveEventListener; using nsIDOMEventTarget::DispatchEvent; virtual void AddEventListener(const nsAString& aType, - nsIDOMEventListener* aCallback, + EventListener* aCallback, bool aCapture, const Nullable& aWantsUntrusted, ErrorResult& aRv) = 0; virtual void RemoveEventListener(const nsAString& aType, - nsIDOMEventListener* aCallback, + EventListener* aCallback, bool aCapture, ErrorResult& aRv); bool DispatchEvent(nsDOMEvent& aEvent, ErrorResult& aRv); diff --git a/content/events/src/EventTarget.cpp b/content/events/src/EventTarget.cpp index e2fea9a84054..cb5441982389 100644 --- a/content/events/src/EventTarget.cpp +++ b/content/events/src/EventTarget.cpp @@ -12,7 +12,7 @@ namespace dom { void EventTarget::RemoveEventListener(const nsAString& aType, - nsIDOMEventListener* aListener, + EventListener* aListener, bool aUseCapture, ErrorResult& aRv) { diff --git a/content/events/src/nsDOMEventTargetHelper.cpp b/content/events/src/nsDOMEventTargetHelper.cpp index 8807e20211d7..4056db3c978d 100644 --- a/content/events/src/nsDOMEventTargetHelper.cpp +++ b/content/events/src/nsDOMEventTargetHelper.cpp @@ -189,7 +189,7 @@ nsDOMEventTargetHelper::AddEventListener(const nsAString& aType, void nsDOMEventTargetHelper::AddEventListener(const nsAString& aType, - nsIDOMEventListener* aListener, + EventListener* aListener, bool aUseCapture, const Nullable& aWantsUntrusted, ErrorResult& aRv) diff --git a/content/events/src/nsDOMEventTargetHelper.h b/content/events/src/nsDOMEventTargetHelper.h index 7d39550b7400..0288082584da 100644 --- a/content/events/src/nsDOMEventTargetHelper.h +++ b/content/events/src/nsDOMEventTargetHelper.h @@ -46,7 +46,7 @@ public: NS_DECL_NSIDOMEVENTTARGET using mozilla::dom::EventTarget::RemoveEventListener; virtual void AddEventListener(const nsAString& aType, - nsIDOMEventListener* aListener, + mozilla::dom::EventListener* aListener, bool aCapture, const mozilla::dom::Nullable& aWantsUntrusted, mozilla::ErrorResult& aRv) MOZ_OVERRIDE; diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index c40b41283d40..c5242d2bc62f 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -8097,7 +8097,7 @@ nsGlobalWindow::AddEventListener(const nsAString& aType, void nsGlobalWindow::AddEventListener(const nsAString& aType, - nsIDOMEventListener* aListener, + EventListener* aListener, bool aUseCapture, const Nullable& aWantsUntrusted, ErrorResult& aRv) diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index be732b87a375..1fb301e6598f 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -373,7 +373,7 @@ public: NS_DECL_NSIDOMEVENTTARGET using mozilla::dom::EventTarget::RemoveEventListener; virtual void AddEventListener(const nsAString& aType, - nsIDOMEventListener* aListener, + mozilla::dom::EventListener* aListener, bool aUseCapture, const mozilla::dom::Nullable& aWantsUntrusted, mozilla::ErrorResult& aRv) MOZ_OVERRIDE; diff --git a/dom/base/nsWindowRoot.cpp b/dom/base/nsWindowRoot.cpp index ae3e91bbfe3f..3d1d56018b3f 100644 --- a/dom/base/nsWindowRoot.cpp +++ b/dom/base/nsWindowRoot.cpp @@ -113,7 +113,7 @@ nsWindowRoot::AddEventListener(const nsAString& aType, void nsWindowRoot::AddEventListener(const nsAString& aType, - nsIDOMEventListener* aListener, + EventListener* aListener, bool aUseCapture, const Nullable& aWantsUntrusted, ErrorResult& aRv) diff --git a/dom/base/nsWindowRoot.h b/dom/base/nsWindowRoot.h index 7db60e867ae4..444335619647 100644 --- a/dom/base/nsWindowRoot.h +++ b/dom/base/nsWindowRoot.h @@ -30,7 +30,7 @@ public: NS_DECL_NSIDOMEVENTTARGET using mozilla::dom::EventTarget::RemoveEventListener; virtual void AddEventListener(const nsAString& aType, - nsIDOMEventListener* aListener, + mozilla::dom::EventListener* aListener, bool aUseCapture, const mozilla::dom::Nullable& aWantsUntrusted, mozilla::ErrorResult& aRv) MOZ_OVERRIDE; diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index acf7775cf2b7..f4df93ae3968 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -378,9 +378,6 @@ DOMInterfaces = { }], 'EventListener': [ -{ - 'nativeType': 'nsIDOMEventListener' -}, { 'workers': True, }], diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 465770f0e17a..bfa724035dbc 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -3157,9 +3157,7 @@ for (uint32_t i = 0; i < length; ++i) { return handleJSObjectType(type, isMember, isInOwningUnion, failureCode) - if (descriptor.interface.isCallback() and - (descriptor.interface.identifier.name != "EventListener" or - descriptorProvider.workers)): + if descriptor.interface.isCallback(): name = descriptor.interface.identifier.name if type.nullable() or isCallbackReturnValue: declType = CGGeneric("nsRefPtr<%s>" % name); @@ -4115,10 +4113,7 @@ if (!returnArray) { CGIndenter(exceptionCodeIndented, 4).define())) + setValue("JS::ObjectValue(*returnArray)"), False) - if (type.isGeckoInterface() and - (not type.isCallbackInterface() or - (type.unroll().inner.identifier.name == "EventListener" and - not descriptorProvider.workers))): + if type.isGeckoInterface() and not type.isCallbackInterface(): descriptor = descriptorProvider.getDescriptor(type.unroll().inner.identifier.name) if type.nullable(): wrappingCode = ("if (!%s) {\n" % (result) + @@ -9224,9 +9219,7 @@ class CGNativeMember(ClassMethod): type = type.inner return str(type), True, True - if (type.isGeckoInterface() and - (not type.isCallbackInterface() or - type.unroll().inner.identifier.name == "EventListener")): + if type.isGeckoInterface() and not type.isCallbackInterface(): iface = type.unroll().inner argIsPointer = type.nullable() or iface.isExternal() forceOwningType = iface.isCallback() or isMember diff --git a/dom/devicestorage/DeviceStorage.h b/dom/devicestorage/DeviceStorage.h index eece1d7d40a9..4695b9a155e3 100644 --- a/dom/devicestorage/DeviceStorage.h +++ b/dom/devicestorage/DeviceStorage.h @@ -159,13 +159,13 @@ public: virtual void AddEventListener(const nsAString& aType, - nsIDOMEventListener* aListener, + mozilla::dom::EventListener* aListener, bool aUseCapture, const mozilla::dom::Nullable& aWantsUntrusted, ErrorResult& aRv) MOZ_OVERRIDE; virtual void RemoveEventListener(const nsAString& aType, - nsIDOMEventListener* aListener, + mozilla::dom::EventListener* aListener, bool aUseCapture, ErrorResult& aRv) MOZ_OVERRIDE; diff --git a/dom/devicestorage/nsDeviceStorage.cpp b/dom/devicestorage/nsDeviceStorage.cpp index 8a1d981a0162..8af7df08d0fb 100644 --- a/dom/devicestorage/nsDeviceStorage.cpp +++ b/dom/devicestorage/nsDeviceStorage.cpp @@ -3351,7 +3351,7 @@ nsDOMDeviceStorage::AddEventListener(const nsAString & aType, void nsDOMDeviceStorage::AddEventListener(const nsAString & aType, - nsIDOMEventListener *aListener, + EventListener *aListener, bool aUseCapture, const Nullable& aWantsUntrusted, ErrorResult& aRv) @@ -3407,7 +3407,7 @@ nsDOMDeviceStorage::RemoveEventListener(const nsAString & aType, void nsDOMDeviceStorage::RemoveEventListener(const nsAString& aType, - nsIDOMEventListener* aListener, + EventListener* aListener, bool aCapture, ErrorResult& aRv) { From 2e9b983c1d430fed0685339274bf883dafecb0ac Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 23 Sep 2013 20:25:17 -0400 Subject: [PATCH 007/160] Bug 862627 part 2. Rip out some now-dead codegen code. r=smaug --- dom/bindings/Codegen.py | 71 +---------------------------------------- 1 file changed, 1 insertion(+), 70 deletions(-) diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index bfa724035dbc..a762e6833229 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -2429,61 +2429,6 @@ class FailureFatalCastableObjectUnwrapper(CastableObjectUnwrapper): exceptionCode, isCallbackReturnValue) -class CallbackObjectUnwrapper: - """ - A class for unwrapping objects implemented in JS. - - |source| is the JSObject we want to use in native code. - |target| is an nsCOMPtr of the appropriate type in which we store the result. - """ - def __init__(self, descriptor, source, target, exceptionCode, - sourceDescription, codeOnFailure=None): - if codeOnFailure is None: - codeOnFailure = ( - 'ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "%s", "%s");\n' - '%s' % (sourceDescription, descriptor.interface.identifier.name, - exceptionCode)) - self.descriptor = descriptor - self.substitution = { "nativeType" : descriptor.nativeType, - "source" : source, - "target" : target, - "codeOnFailure" : CGIndenter(CGGeneric(codeOnFailure)).define() } - - def __str__(self): - checkObjectType = CGIfWrapper( - CGGeneric(self.substitution["codeOnFailure"]), - "!IsConvertibleToCallbackInterface(cx, %(source)s)" % - self.substitution).define() + "\n\n" - if self.descriptor.workers: - return checkObjectType + string.Template( - "${target} = ${source};" - ).substitute(self.substitution) - - return checkObjectType + string.Template( - """nsISupports* supp = nullptr; -if (XPCConvert::GetISupportsFromJSObject(${source}, &supp)) { - nsCOMPtr xpcwn = do_QueryInterface(supp); - if (xpcwn) { - supp = xpcwn->Native(); - } -} - -const nsIID& iid = NS_GET_IID(${nativeType}); -nsRefPtr wrappedJS; -nsresult rv = nsXPCWrappedJS::GetNewOrUsed(${source}, iid, - supp, getter_AddRefs(wrappedJS)); -if (NS_FAILED(rv) || !wrappedJS) { -${codeOnFailure} -} - -// Use a temp nsCOMPtr for the null-check, because ${target} might be -// OwningNonNull, not an nsCOMPtr. -nsCOMPtr<${nativeType}> tmp = do_QueryObject(wrappedJS.get()); -if (!tmp) { -${codeOnFailure} -} -${target} = tmp.forget();""").substitute(self.substitution) - class JSToNativeConversionInfo(): """ An object representing information about a JS-to-native conversion. @@ -3217,21 +3162,7 @@ for (uint32_t i = 0; i < length; ++i) { declType = "NonNull<" + typeName + ">" templateBody = "" - if descriptor.interface.isCallback(): - # NOTE: This is only used for EventListener at this point - callbackConversion = str(CallbackObjectUnwrapper( - descriptor, - "callbackObj", - "${declName}", - exceptionCode, - firstCap(sourceDescription), - codeOnFailure=failureCode)) - templateBody += ( - "{ // Scope for callbackObj\n" - " JS::Rooted callbackObj(cx, &${val}.toObject());\n" + - CGIndenter(CGGeneric(callbackConversion)).define() + - "\n}") - elif not descriptor.skipGen and not descriptor.interface.isConsequential() and not descriptor.interface.isExternal(): + if not descriptor.skipGen and not descriptor.interface.isConsequential() and not descriptor.interface.isExternal(): if failureCode is not None: templateBody += str(CastableObjectUnwrapper( descriptor, From 26abc3b5f2c20412e314087928731b5a01a6e7bd Mon Sep 17 00:00:00 2001 From: Ralph Giles Date: Mon, 16 Sep 2013 14:48:00 -0700 Subject: [PATCH 008/160] Bug 916807 - Update opus to 1.1 prerelease. r=derf Update our opus implementation to a prerelease of 1.1. This brings many performance and encoder improvements and we believe it is stable enough to switch. This import does not enable any of the new assembly optimizations. The imported code is https://git.xiph.org/opus.git master commit f2446c25c6519bae190152f7a579310b83dc43fd. --- media/libopus/COPYING | 19 +- media/libopus/Makefile.in | 5 +- media/libopus/README_MOZILLA | 2 +- media/libopus/bug776661.patch | 26 - media/libopus/celt/_kiss_fft_guts.h | 24 +- media/libopus/celt/arch.h | 26 +- media/libopus/celt/arm/armcpu.c | 166 + media/libopus/celt/arm/armcpu.h | 35 + media/libopus/celt/arm/fixed_armv4.h | 76 + media/libopus/celt/arm/fixed_armv5e.h | 116 + media/libopus/celt/arm/kiss_fft_armv4.h | 121 + media/libopus/celt/arm/kiss_fft_armv5e.h | 118 + media/libopus/celt/bands.c | 1244 ++++---- media/libopus/celt/bands.h | 47 +- media/libopus/celt/celt.c | 2762 +---------------- media/libopus/celt/celt.h | 118 +- media/libopus/celt/celt_decoder.c | 1195 +++++++ media/libopus/celt/celt_encoder.c | 2287 ++++++++++++++ media/libopus/celt/celt_lpc.c | 205 +- media/libopus/celt/celt_lpc.h | 13 +- media/libopus/celt/cpu_support.h | 51 + media/libopus/celt/cwrs.c | 679 ++-- media/libopus/celt/cwrs.h | 14 +- media/libopus/celt/ecintrin.h | 15 +- media/libopus/celt/entcode.c | 16 +- media/libopus/celt/entcode.h | 13 +- media/libopus/celt/entdec.c | 15 +- media/libopus/celt/entdec.h | 13 +- media/libopus/celt/entenc.c | 13 +- media/libopus/celt/entenc.h | 13 +- media/libopus/celt/fixed_debug.h | 355 ++- media/libopus/celt/fixed_generic.h | 23 +- media/libopus/celt/float_cast.h | 17 +- media/libopus/celt/kiss_fft.c | 28 +- media/libopus/celt/kiss_fft.h | 15 +- media/libopus/celt/laplace.c | 15 +- media/libopus/celt/laplace.h | 12 +- media/libopus/celt/mathops.c | 29 +- media/libopus/celt/mathops.h | 69 +- media/libopus/celt/mdct.c | 333 +- media/libopus/celt/mdct.h | 23 +- media/libopus/celt/mfrngcod.h | 13 +- media/libopus/celt/modes.c | 22 +- media/libopus/celt/modes.h | 14 +- media/libopus/celt/os_support.h | 11 +- media/libopus/celt/pitch.c | 241 +- media/libopus/celt/pitch.h | 113 +- media/libopus/celt/quant_bands.c | 69 +- media/libopus/celt/quant_bands.h | 20 +- media/libopus/celt/rate.c | 40 +- media/libopus/celt/rate.h | 18 +- media/libopus/celt/stack_alloc.h | 39 +- media/libopus/celt/static_modes_fixed.h | 37 - media/libopus/celt/static_modes_float.h | 36 - media/libopus/celt/vq.c | 14 +- media/libopus/celt/vq.h | 19 +- media/libopus/celt/x86/pitch_sse.h | 156 + media/libopus/celt_sources.mk | 38 +- media/libopus/include/opus.h | 645 +++- media/libopus/include/opus_custom.h | 392 ++- media/libopus/include/opus_defines.h | 496 ++- media/libopus/include/opus_multistream.h | 699 ++++- media/libopus/include/opus_types.h | 11 +- media/libopus/mingw.patch | 28 - media/libopus/opus_sources.mk | 40 +- media/libopus/padding.patch | 40 - media/libopus/silk/A2NLSF.c | 8 +- media/libopus/silk/API.h | 20 +- media/libopus/silk/CNG.c | 17 +- media/libopus/silk/HP_variable_cutoff.c | 8 +- media/libopus/silk/Inlines.h | 10 +- media/libopus/silk/LPC_analysis_filter.c | 31 +- media/libopus/silk/LPC_inv_pred_gain.c | 10 +- media/libopus/silk/LP_variable_cutoff.c | 12 +- media/libopus/silk/MacroCount.h | 11 +- media/libopus/silk/MacroDebug.h | 717 ++++- media/libopus/silk/NLSF2A.c | 8 +- media/libopus/silk/NLSF_VQ.c | 8 +- media/libopus/silk/NLSF_VQ_weights_laroia.c | 18 +- media/libopus/silk/NLSF_decode.c | 10 +- media/libopus/silk/NLSF_del_dec_quant.c | 14 +- media/libopus/silk/NLSF_encode.c | 24 +- media/libopus/silk/NLSF_stabilize.c | 10 +- media/libopus/silk/NLSF_unpack.c | 8 +- media/libopus/silk/NSQ.c | 25 +- media/libopus/silk/NSQ_del_dec.c | 40 +- media/libopus/silk/PLC.c | 33 +- media/libopus/silk/PLC.h | 9 +- media/libopus/silk/SigProc_FIX.h | 33 +- media/libopus/silk/VAD.c | 64 +- media/libopus/silk/VQ_WMat_EC.c | 8 +- media/libopus/silk/ana_filt_bank_1.c | 8 +- media/libopus/silk/arm/SigProc_FIX_armv4.h | 47 + media/libopus/silk/arm/SigProc_FIX_armv5e.h | 61 + media/libopus/silk/arm/macros_armv4.h | 103 + media/libopus/silk/arm/macros_armv5e.h | 213 ++ media/libopus/silk/biquad_alt.c | 8 +- media/libopus/silk/bwexpander.c | 8 +- media/libopus/silk/bwexpander_32.c | 8 +- media/libopus/silk/check_control_input.c | 8 +- media/libopus/silk/code_signs.c | 8 +- media/libopus/silk/control.h | 8 +- media/libopus/silk/control_SNR.c | 8 +- media/libopus/silk/control_audio_bandwidth.c | 15 +- media/libopus/silk/control_codec.c | 61 +- media/libopus/silk/debug.c | 8 +- media/libopus/silk/debug.h | 16 +- media/libopus/silk/dec_API.c | 38 +- media/libopus/silk/decode_core.c | 28 +- media/libopus/silk/decode_frame.c | 35 +- media/libopus/silk/decode_indices.c | 8 +- media/libopus/silk/decode_parameters.c | 8 +- media/libopus/silk/decode_pitch.c | 8 +- media/libopus/silk/decode_pulses.c | 8 +- media/libopus/silk/decoder_set_fs.c | 10 +- media/libopus/silk/define.h | 13 +- media/libopus/silk/enc_API.c | 51 +- media/libopus/silk/encode_indices.c | 8 +- media/libopus/silk/encode_pulses.c | 21 +- media/libopus/silk/errors.h | 8 +- .../silk/fixed/LTP_analysis_filter_FIX.c | 12 +- media/libopus/silk/fixed/LTP_scale_ctrl_FIX.c | 8 +- .../silk/fixed/apply_sine_window_FIX.c | 20 +- media/libopus/silk/fixed/autocorr_FIX.c | 43 +- media/libopus/silk/fixed/burg_modified_FIX.c | 33 +- media/libopus/silk/fixed/corrMatrix_FIX.c | 8 +- media/libopus/silk/fixed/encode_frame_FIX.c | 37 +- media/libopus/silk/fixed/find_LPC_FIX.c | 16 +- media/libopus/silk/fixed/find_LTP_FIX.c | 10 +- .../libopus/silk/fixed/find_pitch_lags_FIX.c | 36 +- .../libopus/silk/fixed/find_pred_coefs_FIX.c | 32 +- media/libopus/silk/fixed/k2a_FIX.c | 8 +- media/libopus/silk/fixed/k2a_Q16_FIX.c | 8 +- media/libopus/silk/fixed/main_FIX.h | 14 +- .../silk/fixed/noise_shape_analysis_FIX.c | 29 +- .../silk/fixed/pitch_analysis_core_FIX.c | 432 ++- media/libopus/silk/fixed/prefilter_FIX.c | 23 +- media/libopus/silk/fixed/process_gains_FIX.c | 8 +- .../silk/fixed/regularize_correlations_FIX.c | 8 +- .../silk/fixed/residual_energy16_FIX.c | 8 +- .../libopus/silk/fixed/residual_energy_FIX.c | 20 +- media/libopus/silk/fixed/schur64_FIX.c | 25 +- media/libopus/silk/fixed/schur_FIX.c | 24 +- media/libopus/silk/fixed/solve_LS_FIX.c | 16 +- media/libopus/silk/fixed/structs_FIX.h | 8 +- media/libopus/silk/fixed/vector_ops_FIX.c | 39 +- .../silk/fixed/warped_autocorrelation_FIX.c | 8 +- .../silk/float/LPC_analysis_filter_FLP.c | 8 +- .../silk/float/LPC_inv_pred_gain_FLP.c | 8 +- .../silk/float/LTP_analysis_filter_FLP.c | 12 +- media/libopus/silk/float/LTP_scale_ctrl_FLP.c | 8 +- media/libopus/silk/float/SigProc_FLP.h | 13 +- .../silk/float/apply_sine_window_FLP.c | 8 +- .../libopus/silk/float/autocorrelation_FLP.c | 8 +- media/libopus/silk/float/burg_modified_FLP.c | 12 +- media/libopus/silk/float/bwexpander_FLP.c | 8 +- media/libopus/silk/float/corrMatrix_FLP.c | 8 +- media/libopus/silk/float/encode_frame_FLP.c | 8 +- media/libopus/silk/float/energy_FLP.c | 8 +- media/libopus/silk/float/find_LPC_FLP.c | 10 +- media/libopus/silk/float/find_LTP_FLP.c | 8 +- .../libopus/silk/float/find_pitch_lags_FLP.c | 12 +- .../libopus/silk/float/find_pred_coefs_FLP.c | 10 +- media/libopus/silk/float/inner_product_FLP.c | 8 +- media/libopus/silk/float/k2a_FLP.c | 8 +- media/libopus/silk/float/levinsondurbin_FLP.c | 8 +- media/libopus/silk/float/main_FLP.h | 14 +- .../silk/float/noise_shape_analysis_FLP.c | 10 +- .../silk/float/pitch_analysis_core_FLP.c | 126 +- media/libopus/silk/float/prefilter_FLP.c | 10 +- media/libopus/silk/float/process_gains_FLP.c | 8 +- .../silk/float/regularize_correlations_FLP.c | 8 +- .../libopus/silk/float/residual_energy_FLP.c | 10 +- .../silk/float/scale_copy_vector_FLP.c | 8 +- media/libopus/silk/float/scale_vector_FLP.c | 8 +- media/libopus/silk/float/schur_FLP.c | 8 +- media/libopus/silk/float/solve_LS_FLP.c | 8 +- media/libopus/silk/float/sort_FLP.c | 8 +- media/libopus/silk/float/structs_FLP.h | 8 +- .../silk/float/warped_autocorrelation_FLP.c | 8 +- media/libopus/silk/float/wrappers_FLP.c | 10 +- media/libopus/silk/gain_quant.c | 8 +- media/libopus/silk/init_decoder.c | 8 +- media/libopus/silk/init_encoder.c | 8 +- media/libopus/silk/inner_prod_aligned.c | 8 +- media/libopus/silk/interpolate.c | 8 +- media/libopus/silk/lin2log.c | 8 +- media/libopus/silk/log2lin.c | 12 +- media/libopus/silk/macros.h | 72 +- media/libopus/silk/main.h | 10 +- media/libopus/silk/pitch_est_defines.h | 12 +- media/libopus/silk/pitch_est_tables.c | 8 +- media/libopus/silk/process_NLSFs.c | 10 +- media/libopus/silk/quant_LTP_gains.c | 8 +- media/libopus/silk/resampler.c | 8 +- media/libopus/silk/resampler_down2.c | 12 +- media/libopus/silk/resampler_down2_3.c | 15 +- media/libopus/silk/resampler_private.h | 8 +- media/libopus/silk/resampler_private_AR2.c | 8 +- .../libopus/silk/resampler_private_IIR_FIR.c | 22 +- .../libopus/silk/resampler_private_down_FIR.c | 19 +- media/libopus/silk/resampler_private_up2_HQ.c | 8 +- media/libopus/silk/resampler_rom.c | 18 +- media/libopus/silk/resampler_rom.h | 16 +- media/libopus/silk/resampler_structs.h | 13 +- media/libopus/silk/shell_coder.c | 8 +- media/libopus/silk/sigm_Q15.c | 8 +- media/libopus/silk/sort.c | 8 +- media/libopus/silk/stereo_LR_to_MS.c | 26 +- media/libopus/silk/stereo_MS_to_LR.c | 10 +- media/libopus/silk/stereo_decode_pred.c | 8 +- media/libopus/silk/stereo_encode_pred.c | 8 +- media/libopus/silk/stereo_find_predictor.c | 8 +- media/libopus/silk/stereo_quant_pred.c | 8 +- media/libopus/silk/structs.h | 8 +- media/libopus/silk/sum_sqr_shift.c | 8 +- media/libopus/silk/table_LSF_cos.c | 8 +- media/libopus/silk/tables.h | 8 +- media/libopus/silk/tables_LTP.c | 26 +- media/libopus/silk/tables_NLSF_CB_NB_MB.c | 22 +- media/libopus/silk/tables_NLSF_CB_WB.c | 22 +- media/libopus/silk/tables_gain.c | 8 +- media/libopus/silk/tables_other.c | 12 +- media/libopus/silk/tables_pitch_lag.c | 8 +- media/libopus/silk/tables_pulses_per_block.c | 8 +- media/libopus/silk/tuning_parameters.h | 10 +- media/libopus/silk/typedef.h | 39 +- media/libopus/silk_sources.mk | 33 - media/libopus/src/analysis.c | 654 ++++ media/libopus/src/analysis.h | 90 + media/libopus/src/mlp.c | 111 + media/libopus/src/mlp.h | 41 + media/libopus/src/mlp_data.c | 105 + media/libopus/src/opus.c | 110 +- media/libopus/src/opus_decoder.c | 327 +- media/libopus/src/opus_encoder.c | 1111 ++++++- media/libopus/src/opus_multistream.c | 780 +---- media/libopus/src/opus_multistream_decoder.c | 499 +++ media/libopus/src/opus_multistream_encoder.c | 1054 +++++++ media/libopus/src/opus_private.h | 52 +- media/libopus/src/repacketizer.c | 15 +- media/libopus/src/tansig_table.h | 45 + media/libopus/update.sh | 11 +- 243 files changed, 14647 insertions(+), 7960 deletions(-) delete mode 100644 media/libopus/bug776661.patch create mode 100644 media/libopus/celt/arm/armcpu.c create mode 100644 media/libopus/celt/arm/armcpu.h create mode 100644 media/libopus/celt/arm/fixed_armv4.h create mode 100644 media/libopus/celt/arm/fixed_armv5e.h create mode 100644 media/libopus/celt/arm/kiss_fft_armv4.h create mode 100644 media/libopus/celt/arm/kiss_fft_armv5e.h create mode 100644 media/libopus/celt/celt_decoder.c create mode 100644 media/libopus/celt/celt_encoder.c create mode 100644 media/libopus/celt/cpu_support.h create mode 100644 media/libopus/celt/x86/pitch_sse.h delete mode 100644 media/libopus/mingw.patch delete mode 100644 media/libopus/padding.patch create mode 100644 media/libopus/silk/arm/SigProc_FIX_armv4.h create mode 100644 media/libopus/silk/arm/SigProc_FIX_armv5e.h create mode 100644 media/libopus/silk/arm/macros_armv4.h create mode 100644 media/libopus/silk/arm/macros_armv5e.h create mode 100644 media/libopus/src/analysis.c create mode 100644 media/libopus/src/analysis.h create mode 100644 media/libopus/src/mlp.c create mode 100644 media/libopus/src/mlp.h create mode 100644 media/libopus/src/mlp_data.c create mode 100644 media/libopus/src/opus_multistream_decoder.c create mode 100644 media/libopus/src/opus_multistream_encoder.c create mode 100644 media/libopus/src/tansig_table.h diff --git a/media/libopus/COPYING b/media/libopus/COPYING index 5db750ca413e..9c739c34a3a9 100644 --- a/media/libopus/COPYING +++ b/media/libopus/COPYING @@ -1,10 +1,7 @@ -Copyright 1994-2011 IETF Trust, Xiph.Org, Skype Limited, Octasic, +Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic, Jean-Marc Valin, Timothy B. Terriberry, CSIRO, Gregory Maxwell, Mark Borgerding, - Erik de Castro Lopo. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. + Erik de Castro Lopo Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -33,3 +30,15 @@ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Opus is subject to the royalty-free patent licenses which are +specified at: + +Xiph.Org Foundation: +https://datatracker.ietf.org/ipr/1524/ + +Microsoft Corporation: +https://datatracker.ietf.org/ipr/1914/ + +Broadcom Corporation: +https://datatracker.ietf.org/ipr/1526/ diff --git a/media/libopus/Makefile.in b/media/libopus/Makefile.in index e23955f70797..3f7e6768e878 100644 --- a/media/libopus/Makefile.in +++ b/media/libopus/Makefile.in @@ -6,7 +6,7 @@ FORCE_STATIC_LIB= 1 DEFINES += \ -DOPUS_BUILD \ - -DOPUS_VERSION='"draft-11-mozilla"' \ + -DOPUS_VERSION='"v1.1-beta-23-gf2446c2-mozilla"' \ -DUSE_ALLOCA \ -Drestrict= \ $(NULL) @@ -62,5 +62,6 @@ CSRCS += $(notdir $(SILK_SOURCES_FIXED)) else LOCAL_INCLUDES += -I$(srcdir)/silk/float VPATH += $(srcdir)/silk/float -CSRCS += $(notdir $(SILK_SOURCES_FLOAT)) +CSRCS += $(notdir $(SILK_SOURCES_FLOAT)) \ + $(notdir $(OPUS_SOURCES_FLOAT)) endif diff --git a/media/libopus/README_MOZILLA b/media/libopus/README_MOZILLA index 148e726df73e..af4c54d074dd 100644 --- a/media/libopus/README_MOZILLA +++ b/media/libopus/README_MOZILLA @@ -8,4 +8,4 @@ files after the copy step. The upstream repository is https://git.xiph.org/opus.git -The git tag/revision used was v1.0.0. +The git tag/revision used was v1.1-beta-23-gf2446c2. diff --git a/media/libopus/bug776661.patch b/media/libopus/bug776661.patch deleted file mode 100644 index 215289e7be53..000000000000 --- a/media/libopus/bug776661.patch +++ /dev/null @@ -1,26 +0,0 @@ -# HG changeset patch -# Parent bfb616effc20e449c553b492876a9731352496f0 -Bug 776661 - Initialize all of the bytes in the incoming data structure in silk_get_TOC; r=rillian - -diff --git a/media/libopus/silk/dec_API.c b/media/libopus/silk/dec_API.c ---- a/media/libopus/silk/dec_API.c -+++ b/media/libopus/silk/dec_API.c -@@ -352,17 +352,17 @@ opus_int silk_get_TOC( - - if( nBytesIn < 1 ) { - return -1; - } - if( nFramesPerPayload < 0 || nFramesPerPayload > 3 ) { - return -1; - } - -- silk_memset( Silk_TOC, 0, sizeof( Silk_TOC ) ); -+ silk_memset( Silk_TOC, 0, sizeof( *Silk_TOC ) ); - - /* For stereo, extract the flags for the mid channel */ - flags = silk_RSHIFT( payload[ 0 ], 7 - nFramesPerPayload ) & ( silk_LSHIFT( 1, nFramesPerPayload + 1 ) - 1 ); - - Silk_TOC->inbandFECFlag = flags & 1; - for( i = nFramesPerPayload - 1; i >= 0 ; i-- ) { - flags = silk_RSHIFT( flags, 1 ); - Silk_TOC->VADFlags[ i ] = flags & 1; diff --git a/media/libopus/celt/_kiss_fft_guts.h b/media/libopus/celt/_kiss_fft_guts.h index 1b97fa48224a..f0c6976e5eb6 100644 --- a/media/libopus/celt/_kiss_fft_guts.h +++ b/media/libopus/celt/_kiss_fft_guts.h @@ -1,8 +1,6 @@ -/*Copyright (c) 2003-2012 IETF Trust, Mark Borgerding. All rights reserved. +/*Copyright (c) 2003-2004, Mark Borgerding - - This file is extracted from RFC6716. Please see that RFC for additional - information. + All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -13,11 +11,6 @@ this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -55,7 +48,6 @@ #include "arch.h" -# define SAMPPROD long long #define SAMP_MAX 2147483647 #define TWID_MAX 32767 #define TRIG_UPSCALE 1 @@ -74,8 +66,8 @@ (m).i = SUB32(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0) # define C_MUL4(m,a,b) \ - do{ (m).r = SHR(SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)),2); \ - (m).i = SHR(ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)),2); }while(0) + do{ (m).r = SHR32(SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)),2); \ + (m).i = SHR32(ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)),2); }while(0) # define C_MULBYSCALAR( c, s ) \ do{ (c).r = S_MUL( (c).r , s ) ;\ @@ -102,6 +94,14 @@ do {(res).r = ADD32((res).r,(a).r); (res).i = SUB32((res).i,(a).i); \ }while(0) +#if defined(ARMv4_ASM) +#include "arm/kiss_fft_armv4.h" +#endif + +#if defined(ARMv5E_ASM) +#include "arm/kiss_fft_armv5e.h" +#endif + #else /* not FIXED_POINT*/ # define S_MUL(a,b) ( (a)*(b) ) diff --git a/media/libopus/celt/arch.h b/media/libopus/celt/arch.h index 23f33a20e7f7..78e2635f006f 100644 --- a/media/libopus/celt/arch.h +++ b/media/libopus/celt/arch.h @@ -1,15 +1,12 @@ -/* Copyright (c) 2003-2012 IETF Trust, Jean-Marc Valin, CSIRO, - Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2003-2008 Jean-Marc Valin + Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /** @file arch.h @brief Various architecture definitions for CELT */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -21,11 +18,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -108,6 +100,7 @@ typedef opus_val32 celt_ener; #define DB_SHIFT 10 #define EPSILON 1 +#define VERY_SMALL 0 #define VERY_LARGE16 ((opus_val16)32767) #define Q15_ONE ((opus_val16)32767) @@ -120,10 +113,10 @@ typedef opus_val32 celt_ener; #include "fixed_generic.h" -#ifdef ARM5E_ASM -#include "fixed_arm5e.h" -#elif defined (ARM4_ASM) -#include "fixed_arm4.h" +#ifdef ARMv5E_ASM +#include "arm/fixed_armv5e.h" +#elif defined (ARMv4_ASM) +#include "arm/fixed_armv4.h" #elif defined (BFIN_ASM) #include "fixed_bfin.h" #elif defined (TI_C5X_ASM) @@ -148,6 +141,7 @@ typedef float celt_ener; #define NORM_SCALING 1.f #define EPSILON 1e-15f +#define VERY_SMALL 1e-30f #define VERY_LARGE16 1e15f #define Q15_ONE ((opus_val16)1.f) @@ -169,6 +163,7 @@ typedef float celt_ener; #define SHR(a,shift) (a) #define SHL(a,shift) (a) #define SATURATE(x,a) (x) +#define SATURATE16(x) (x) #define ROUND16(a,shift) (a) #define HALF16(x) (.5f*(x)) @@ -196,6 +191,7 @@ typedef float celt_ener; #define MULT16_16_P15(a,b) ((a)*(b)) #define MULT16_16_P13(a,b) ((a)*(b)) #define MULT16_16_P14(a,b) ((a)*(b)) +#define MULT16_32_P16(a,b) ((a)*(b)) #define DIV32_16(a,b) (((opus_val32)(a))/(opus_val16)(b)) #define DIV32(a,b) (((opus_val32)(a))/(opus_val32)(b)) diff --git a/media/libopus/celt/arm/armcpu.c b/media/libopus/celt/arm/armcpu.c new file mode 100644 index 000000000000..aabcc716f7d5 --- /dev/null +++ b/media/libopus/celt/arm/armcpu.c @@ -0,0 +1,166 @@ +/* Copyright (c) 2010 Xiph.Org Foundation + * Copyright (c) 2013 Parrot */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* Original code from libtheora modified to suit to Opus */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef OPUS_HAVE_RTCD + +#include "armcpu.h" +#include "cpu_support.h" +#include "os_support.h" +#include "opus_types.h" + +#define OPUS_CPU_ARM_V4 (1) +#define OPUS_CPU_ARM_EDSP (1<<1) +#define OPUS_CPU_ARM_MEDIA (1<<2) +#define OPUS_CPU_ARM_NEON (1<<3) + +#if defined(_MSC_VER) +/*For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.*/ +# define WIN32_LEAN_AND_MEAN +# define WIN32_EXTRA_LEAN +# include + +static inline opus_uint32 opus_cpu_capabilities(void){ + opus_uint32 flags; + flags=0; + /* MSVC has no inline __asm support for ARM, but it does let you __emit + * instructions via their assembled hex code. + * All of these instructions should be essentially nops. */ +# if defined(ARMv5E_ASM) + __try{ + /*PLD [r13]*/ + __emit(0xF5DDF000); + flags|=OPUS_CPU_ARM_EDSP; + } + __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ + /*Ignore exception.*/ + } +# if defined(ARMv6E_ASM) + __try{ + /*SHADD8 r3,r3,r3*/ + __emit(0xE6333F93); + flags|=OPUS_CPU_ARM_MEDIA; + } + __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ + /*Ignore exception.*/ + } +# if defined(ARM_HAVE_NEON) + __try{ + /*VORR q0,q0,q0*/ + __emit(0xF2200150); + flags|=OPUS_CPU_ARM_NEON; + } + __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ + /*Ignore exception.*/ + } +# endif +# endif +# endif + return flags; +} + +#elif defined(__linux__) +/* Linux based */ +opus_uint32 opus_cpu_capabilities(void) +{ + opus_uint32 flags = 0; + FILE *cpuinfo; + + /* Reading /proc/self/auxv would be easier, but that doesn't work reliably on + * Android */ + cpuinfo = fopen("/proc/cpuinfo", "r"); + + if(cpuinfo != NULL) + { + /* 512 should be enough for anybody (it's even enough for all the flags that + * x86 has accumulated... so far). */ + char buf[512]; + + while(fgets(buf, 512, cpuinfo) != NULL) + { + /* Search for edsp and neon flag */ + if(memcmp(buf, "Features", 8) == 0) + { + char *p; + p = strstr(buf, " edsp"); + if(p != NULL && (p[5] == ' ' || p[5] == '\n')) + flags |= OPUS_CPU_ARM_EDSP; + + p = strstr(buf, " neon"); + if(p != NULL && (p[5] == ' ' || p[5] == '\n')) + flags |= OPUS_CPU_ARM_NEON; + } + + /* Search for media capabilities (>= ARMv6) */ + if(memcmp(buf, "CPU architecture:", 17) == 0) + { + int version; + version = atoi(buf+17); + + if(version >= 6) + flags |= OPUS_CPU_ARM_MEDIA; + } + } + + fclose(cpuinfo); + } + return flags; +} +#else +/* The feature registers which can tell us what the processor supports are + * accessible in priveleged modes only, so we can't have a general user-space + * detection method like on x86.*/ +# error "Configured to use ARM asm but no CPU detection method available for " \ + "your platform. Reconfigure with --disable-rtcd (or send patches)." +#endif + +int opus_select_arch(void) +{ + opus_uint32 flags = opus_cpu_capabilities(); + int arch = 0; + + if(!(flags & OPUS_CPU_ARM_EDSP)) + return arch; + arch++; + + if(!(flags & OPUS_CPU_ARM_MEDIA)) + return arch; + arch++; + + if(!(flags & OPUS_CPU_ARM_NEON)) + return arch; + arch++; + + return arch; +} + +#endif diff --git a/media/libopus/celt/arm/armcpu.h b/media/libopus/celt/arm/armcpu.h new file mode 100644 index 000000000000..68d80fe22256 --- /dev/null +++ b/media/libopus/celt/arm/armcpu.h @@ -0,0 +1,35 @@ +/* Copyright (c) 2010 Xiph.Org Foundation + * Copyright (c) 2013 Parrot */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* Original code from libtheora modified to suit to Opus */ + +#ifndef ARMCPU_H +#define ARMCPU_H + +int opus_select_arch(void); + +#endif diff --git a/media/libopus/celt/arm/fixed_armv4.h b/media/libopus/celt/arm/fixed_armv4.h new file mode 100644 index 000000000000..bcacc343e8e2 --- /dev/null +++ b/media/libopus/celt/arm/fixed_armv4.h @@ -0,0 +1,76 @@ +/* Copyright (C) 2013 Xiph.Org Foundation and contributors */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_ARMv4_H +#define FIXED_ARMv4_H + +/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ +#undef MULT16_32_Q16 +static inline opus_val32 MULT16_32_Q16_armv4(opus_val16 a, opus_val32 b) +{ + unsigned rd_lo; + int rd_hi; + __asm__( + "#MULT16_32_Q16\n\t" + "smull %0, %1, %2, %3\n\t" + : "=&r"(rd_lo), "=&r"(rd_hi) + : "%r"(b),"r"(a<<16) + ); + return rd_hi; +} +#define MULT16_32_Q16(a, b) (MULT16_32_Q16_armv4(a, b)) + + +/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */ +#undef MULT16_32_Q15 +static inline opus_val32 MULT16_32_Q15_armv4(opus_val16 a, opus_val32 b) +{ + unsigned rd_lo; + int rd_hi; + __asm__( + "#MULT16_32_Q15\n\t" + "smull %0, %1, %2, %3\n\t" + : "=&r"(rd_lo), "=&r"(rd_hi) + : "%r"(b), "r"(a<<16) + ); + /*We intentionally don't OR in the high bit of rd_lo for speed.*/ + return rd_hi<<1; +} +#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv4(a, b)) + + +/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add. + b must fit in 31 bits. + Result fits in 32 bits. */ +#undef MAC16_32_Q15 +#define MAC16_32_Q15(c, a, b) ADD32(c, MULT16_32_Q15(a, b)) + + +/** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */ +#undef MULT32_32_Q31 +#define MULT32_32_Q31(a,b) (opus_val32)((((opus_int64)(a)) * ((opus_int64)(b)))>>31) + +#endif diff --git a/media/libopus/celt/arm/fixed_armv5e.h b/media/libopus/celt/arm/fixed_armv5e.h new file mode 100644 index 000000000000..80632c4a949d --- /dev/null +++ b/media/libopus/celt/arm/fixed_armv5e.h @@ -0,0 +1,116 @@ +/* Copyright (C) 2007-2009 Xiph.Org Foundation + Copyright (C) 2003-2008 Jean-Marc Valin + Copyright (C) 2007-2008 CSIRO + Copyright (C) 2013 Parrot */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_ARMv5E_H +#define FIXED_ARMv5E_H + +#include "fixed_armv4.h" + +/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ +#undef MULT16_32_Q16 +static inline opus_val32 MULT16_32_Q16_armv5e(opus_val16 a, opus_val32 b) +{ + int res; + __asm__( + "#MULT16_32_Q16\n\t" + "smulwb %0, %1, %2\n\t" + : "=r"(res) + : "r"(b),"r"(a) + ); + return res; +} +#define MULT16_32_Q16(a, b) (MULT16_32_Q16_armv5e(a, b)) + + +/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */ +#undef MULT16_32_Q15 +static inline opus_val32 MULT16_32_Q15_armv5e(opus_val16 a, opus_val32 b) +{ + int res; + __asm__( + "#MULT16_32_Q15\n\t" + "smulwb %0, %1, %2\n\t" + : "=r"(res) + : "r"(b), "r"(a) + ); + return res<<1; +} +#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv5e(a, b)) + + +/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add. + b must fit in 31 bits. + Result fits in 32 bits. */ +#undef MAC16_32_Q15 +static inline opus_val32 MAC16_32_Q15_armv5e(opus_val32 c, opus_val16 a, + opus_val32 b) +{ + int res; + __asm__( + "#MAC16_32_Q15\n\t" + "smlawb %0, %1, %2, %3;\n" + : "=r"(res) + : "r"(b<<1), "r"(a), "r"(c) + ); + return res; +} +#define MAC16_32_Q15(c, a, b) (MAC16_32_Q15_armv5e(c, a, b)) + +/** 16x16 multiply-add where the result fits in 32 bits */ +#undef MAC16_16 +static inline opus_val32 MAC16_16_armv5e(opus_val32 c, opus_val16 a, + opus_val16 b) +{ + int res; + __asm__( + "#MAC16_16\n\t" + "smlabb %0, %1, %2, %3;\n" + : "=r"(res) + : "r"(a), "r"(b), "r"(c) + ); + return res; +} +#define MAC16_16(c, a, b) (MAC16_16_armv5e(c, a, b)) + +/** 16x16 multiplication where the result fits in 32 bits */ +#undef MULT16_16 +static inline opus_val32 MULT16_16_armv5e(opus_val16 a, opus_val16 b) +{ + int res; + __asm__( + "#MULT16_16\n\t" + "smulbb %0, %1, %2;\n" + : "=r"(res) + : "r"(a), "r"(b) + ); + return res; +} +#define MULT16_16(a, b) (MULT16_16_armv5e(a, b)) + +#endif diff --git a/media/libopus/celt/arm/kiss_fft_armv4.h b/media/libopus/celt/arm/kiss_fft_armv4.h new file mode 100644 index 000000000000..e4faad6f2b98 --- /dev/null +++ b/media/libopus/celt/arm/kiss_fft_armv4.h @@ -0,0 +1,121 @@ +/*Copyright (c) 2013, Xiph.Org Foundation and contributors. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.*/ + +#ifndef KISS_FFT_ARMv4_H +#define KISS_FFT_ARMv4_H + +#if !defined(KISS_FFT_GUTS_H) +#error "This file should only be included from _kiss_fft_guts.h" +#endif + +#ifdef FIXED_POINT + +#undef C_MUL +#define C_MUL(m,a,b) \ + do{ \ + int br__; \ + int bi__; \ + int tt__; \ + __asm__ __volatile__( \ + "#C_MUL\n\t" \ + "ldrsh %[br], [%[bp], #0]\n\t" \ + "ldm %[ap], {r0,r1}\n\t" \ + "ldrsh %[bi], [%[bp], #2]\n\t" \ + "smull %[tt], %[mi], r1, %[br]\n\t" \ + "smlal %[tt], %[mi], r0, %[bi]\n\t" \ + "rsb %[bi], %[bi], #0\n\t" \ + "smull %[br], %[mr], r0, %[br]\n\t" \ + "mov %[tt], %[tt], lsr #15\n\t" \ + "smlal %[br], %[mr], r1, %[bi]\n\t" \ + "orr %[mi], %[tt], %[mi], lsl #17\n\t" \ + "mov %[br], %[br], lsr #15\n\t" \ + "orr %[mr], %[br], %[mr], lsl #17\n\t" \ + : [mr]"=r"((m).r), [mi]"=r"((m).i), \ + [br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \ + : [ap]"r"(&(a)), [bp]"r"(&(b)) \ + : "r0", "r1" \ + ); \ + } \ + while(0) + +#undef C_MUL4 +#define C_MUL4(m,a,b) \ + do{ \ + int br__; \ + int bi__; \ + int tt__; \ + __asm__ __volatile__( \ + "#C_MUL4\n\t" \ + "ldrsh %[br], [%[bp], #0]\n\t" \ + "ldm %[ap], {r0,r1}\n\t" \ + "ldrsh %[bi], [%[bp], #2]\n\t" \ + "smull %[tt], %[mi], r1, %[br]\n\t" \ + "smlal %[tt], %[mi], r0, %[bi]\n\t" \ + "rsb %[bi], %[bi], #0\n\t" \ + "smull %[br], %[mr], r0, %[br]\n\t" \ + "mov %[tt], %[tt], lsr #17\n\t" \ + "smlal %[br], %[mr], r1, %[bi]\n\t" \ + "orr %[mi], %[tt], %[mi], lsl #15\n\t" \ + "mov %[br], %[br], lsr #17\n\t" \ + "orr %[mr], %[br], %[mr], lsl #15\n\t" \ + : [mr]"=r"((m).r), [mi]"=r"((m).i), \ + [br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \ + : [ap]"r"(&(a)), [bp]"r"(&(b)) \ + : "r0", "r1" \ + ); \ + } \ + while(0) + +#undef C_MULC +#define C_MULC(m,a,b) \ + do{ \ + int br__; \ + int bi__; \ + int tt__; \ + __asm__ __volatile__( \ + "#C_MULC\n\t" \ + "ldrsh %[br], [%[bp], #0]\n\t" \ + "ldm %[ap], {r0,r1}\n\t" \ + "ldrsh %[bi], [%[bp], #2]\n\t" \ + "smull %[tt], %[mr], r0, %[br]\n\t" \ + "smlal %[tt], %[mr], r1, %[bi]\n\t" \ + "rsb %[bi], %[bi], #0\n\t" \ + "smull %[br], %[mi], r1, %[br]\n\t" \ + "mov %[tt], %[tt], lsr #15\n\t" \ + "smlal %[br], %[mi], r0, %[bi]\n\t" \ + "orr %[mr], %[tt], %[mr], lsl #17\n\t" \ + "mov %[br], %[br], lsr #15\n\t" \ + "orr %[mi], %[br], %[mi], lsl #17\n\t" \ + : [mr]"=r"((m).r), [mi]"=r"((m).i), \ + [br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \ + : [ap]"r"(&(a)), [bp]"r"(&(b)) \ + : "r0", "r1" \ + ); \ + } \ + while(0) + +#endif /* FIXED_POINT */ + +#endif /* KISS_FFT_ARMv4_H */ diff --git a/media/libopus/celt/arm/kiss_fft_armv5e.h b/media/libopus/celt/arm/kiss_fft_armv5e.h new file mode 100644 index 000000000000..9eca183d77d6 --- /dev/null +++ b/media/libopus/celt/arm/kiss_fft_armv5e.h @@ -0,0 +1,118 @@ +/*Copyright (c) 2013, Xiph.Org Foundation and contributors. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.*/ + +#ifndef KISS_FFT_ARMv5E_H +#define KISS_FFT_ARMv5E_H + +#if !defined(KISS_FFT_GUTS_H) +#error "This file should only be included from _kiss_fft_guts.h" +#endif + +#ifdef FIXED_POINT + +#if defined(__thumb__)||defined(__thumb2__) +#define LDRD_CONS "Q" +#else +#define LDRD_CONS "Uq" +#endif + +#undef C_MUL +#define C_MUL(m,a,b) \ + do{ \ + int mr1__; \ + int mr2__; \ + int mi__; \ + long long aval__; \ + int bval__; \ + __asm__( \ + "#C_MUL\n\t" \ + "ldrd %[aval], %H[aval], %[ap]\n\t" \ + "ldr %[bval], %[bp]\n\t" \ + "smulwb %[mi], %H[aval], %[bval]\n\t" \ + "smulwb %[mr1], %[aval], %[bval]\n\t" \ + "smulwt %[mr2], %H[aval], %[bval]\n\t" \ + "smlawt %[mi], %[aval], %[bval], %[mi]\n\t" \ + : [mr1]"=r"(mr1__), [mr2]"=r"(mr2__), [mi]"=r"(mi__), \ + [aval]"=&r"(aval__), [bval]"=r"(bval__) \ + : [ap]LDRD_CONS(a), [bp]"m"(b) \ + ); \ + (m).r = SHL32(SUB32(mr1__, mr2__), 1); \ + (m).i = SHL32(mi__, 1); \ + } \ + while(0) + +#undef C_MUL4 +#define C_MUL4(m,a,b) \ + do{ \ + int mr1__; \ + int mr2__; \ + int mi__; \ + long long aval__; \ + int bval__; \ + __asm__( \ + "#C_MUL4\n\t" \ + "ldrd %[aval], %H[aval], %[ap]\n\t" \ + "ldr %[bval], %[bp]\n\t" \ + "smulwb %[mi], %H[aval], %[bval]\n\t" \ + "smulwb %[mr1], %[aval], %[bval]\n\t" \ + "smulwt %[mr2], %H[aval], %[bval]\n\t" \ + "smlawt %[mi], %[aval], %[bval], %[mi]\n\t" \ + : [mr1]"=r"(mr1__), [mr2]"=r"(mr2__), [mi]"=r"(mi__), \ + [aval]"=&r"(aval__), [bval]"=r"(bval__) \ + : [ap]LDRD_CONS(a), [bp]"m"(b) \ + ); \ + (m).r = SHR32(SUB32(mr1__, mr2__), 1); \ + (m).i = SHR32(mi__, 1); \ + } \ + while(0) + +#undef C_MULC +#define C_MULC(m,a,b) \ + do{ \ + int mr__; \ + int mi1__; \ + int mi2__; \ + long long aval__; \ + int bval__; \ + __asm__( \ + "#C_MULC\n\t" \ + "ldrd %[aval], %H[aval], %[ap]\n\t" \ + "ldr %[bval], %[bp]\n\t" \ + "smulwb %[mr], %[aval], %[bval]\n\t" \ + "smulwb %[mi1], %H[aval], %[bval]\n\t" \ + "smulwt %[mi2], %[aval], %[bval]\n\t" \ + "smlawt %[mr], %H[aval], %[bval], %[mr]\n\t" \ + : [mr]"=r"(mr__), [mi1]"=r"(mi1__), [mi2]"=r"(mi2__), \ + [aval]"=&r"(aval__), [bval]"=r"(bval__) \ + : [ap]LDRD_CONS(a), [bp]"m"(b) \ + ); \ + (m).r = SHL32(mr__, 1); \ + (m).i = SHL32(SUB32(mi1__, mi2__), 1); \ + } \ + while(0) + +#endif /* FIXED_POINT */ + +#endif /* KISS_FFT_GUTS_H */ diff --git a/media/libopus/celt/bands.c b/media/libopus/celt/bands.c index 6962587b9d61..93bd0bc7220a 100644 --- a/media/libopus/celt/bands.c +++ b/media/libopus/celt/bands.c @@ -1,11 +1,8 @@ -/* Copyright (c) 2007-2012 IETF Trust, CSIRO, Xiph.Org Foundation, - Gregory Maxwell. All rights reserved. +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2008-2009 Gregory Maxwell Written by Jean-Marc Valin and Gregory Maxwell */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -17,11 +14,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -48,6 +40,23 @@ #include "os_support.h" #include "mathops.h" #include "rate.h" +#include "quant_bands.h" +#include "pitch.h" + +int hysteresis_decision(opus_val16 val, const opus_val16 *thresholds, const opus_val16 *hysteresis, int N, int prev) +{ + int i; + for (i=0;iprev && val < thresholds[prev]+hysteresis[prev]) + i=prev; + if (i thresholds[prev-1]-hysteresis[prev-1]) + i=prev; + return i; +} opus_uint32 celt_lcg_rand(opus_uint32 seed) { @@ -119,7 +128,7 @@ void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *band } /* Normalise each band such that the energy is one. */ -void normalise_bands(const CELTMode *m, const celt_sig * restrict freq, celt_norm * restrict X, const celt_ener *bandE, int end, int C, int M) +void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M) { int i, c, N; const opus_int16 *eBands = m->eBands; @@ -161,7 +170,7 @@ void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *band } /* Normalise each band such that the energy is one. */ -void normalise_bands(const CELTMode *m, const celt_sig * restrict freq, celt_norm * restrict X, const celt_ener *bandE, int end, int C, int M) +void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M) { int i, c, N; const opus_int16 *eBands = m->eBands; @@ -180,28 +189,50 @@ void normalise_bands(const CELTMode *m, const celt_sig * restrict freq, celt_nor #endif /* FIXED_POINT */ /* De-normalise the energy to produce the synthesis from the unit-energy bands */ -void denormalise_bands(const CELTMode *m, const celt_norm * restrict X, celt_sig * restrict freq, const celt_ener *bandE, int end, int C, int M) +void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X, + celt_sig * OPUS_RESTRICT freq, const opus_val16 *bandLogE, int start, int end, int C, int M) { int i, c, N; const opus_int16 *eBands = m->eBands; N = M*m->shortMdctSize; celt_assert2(C<=2, "denormalise_bands() not implemented for >2 channels"); c=0; do { - celt_sig * restrict f; - const celt_norm * restrict x; + celt_sig * OPUS_RESTRICT f; + const celt_norm * OPUS_RESTRICT x; f = freq+c*N; - x = X+c*N; - for (i=0;inbEBands],1); + opus_val16 g; + opus_val16 lg; +#ifdef FIXED_POINT + int shift; +#endif j=M*eBands[i]; band_end = M*eBands[i+1]; + lg = ADD16(bandLogE[i+c*m->nbEBands], SHL16((opus_val16)eMeans[i],6)); +#ifdef FIXED_POINT + /* Handle the integer part of the log energy */ + shift = 16-(lg>>DB_SHIFT); + if (shift>31) + { + shift=0; + g=0; + } else { + /* Handle the fractional part. */ + g = celt_exp2_frac(lg&((1<eBands[i+1]-m->eBands[i]; @@ -227,7 +259,8 @@ void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_mas depth = (1+pulses[i])/((m->eBands[i+1]-m->eBands[i])<nbEBands+i]); } Ediff = EXTEND32(logE[c*m->nbEBands+i])-EXTEND32(MIN16(prev1,prev2)); - Ediff = MAX16(0, Ediff); + Ediff = MAX32(0, Ediff); #ifdef FIXED_POINT if (Ediff < 16384) - r = 2*MIN16(16383,SHR32(celt_exp2(-EXTRACT16(Ediff)),1)); - else + { + opus_val32 r32 = SHR32(celt_exp2(-EXTRACT16(Ediff)),1); + r = 2*MIN16(16383,r32); + } else { r = 0; + } if (LM==3) r = MULT16_16_Q14(23170, MIN32(23169, r)); r = SHR16(MIN16(thresh, r),1); @@ -348,11 +384,7 @@ static void stereo_merge(celt_norm *X, celt_norm *Y, opus_val16 mid, int N) opus_val32 t, lgain, rgain; /* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */ - for (j=0;jeBands; + const opus_int16 * OPUS_RESTRICT eBands = m->eBands; int decision; int hf_sum=0; @@ -415,7 +447,7 @@ int spreading_decision(const CELTMode *m, celt_norm *X, int *average, { int j, N, tmp=0; int tcount[3] = {0,0,0}; - celt_norm * restrict x = X+M*eBands[i]+c*N0; + celt_norm * OPUS_RESTRICT x = X+M*eBands[i]+c*N0; N = M*(eBands[i+1]-eBands[i]); if (N<=8) continue; @@ -486,50 +518,6 @@ int spreading_decision(const CELTMode *m, celt_norm *X, int *average, return decision; } -#ifdef MEASURE_NORM_MSE - -float MSE[30] = {0}; -int nbMSEBands = 0; -int MSECount[30] = {0}; - -void dump_norm_mse(void) -{ - int i; - for (i=0;inbEBands;i++) - { - int j; - int c; - float g; - if (bandE0[i]<10 || (C==2 && bandE0[i+m->nbEBands]<1)) - continue; - c=0; do { - g = bandE[i+c*m->nbEBands]/(1e-15+bandE0[i+c*m->nbEBands]); - for (j=M*m->eBands[i];jeBands[i+1];j++) - MSE[i] += (g*X[j+c*N]-X0[j+c*N])*(g*X[j+c*N]-X0[j+c*N]); - } while (++cnbEBands; -} - -#endif - /* Indexing table for converting from natural Hadamard to ordery Hadamard This is essentially a bit-reversed Gray, on top of which we've added an inversion of the order because we want the DC at the end rather than @@ -632,289 +620,304 @@ static int compute_qn(int N, int b, int offset, int pulse_cap, int stereo) return qn; } -/* This function is responsible for encoding and decoding a band for both - the mono and stereo case. Even in the mono case, it can split the band - in two and transmit the energy difference with the two half-bands. It - can be called recursively so bands can end up being split in 8 parts. */ -static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_norm *Y, - int N, int b, int spread, int B, int intensity, int tf_change, celt_norm *lowband, ec_ctx *ec, - opus_int32 *remaining_bits, int LM, celt_norm *lowband_out, const celt_ener *bandE, int level, - opus_uint32 *seed, opus_val16 gain, celt_norm *lowband_scratch, int fill) +struct band_ctx { + int encode; + const CELTMode *m; + int i; + int intensity; + int spread; + int tf_change; + ec_ctx *ec; + opus_int32 remaining_bits; + const celt_ener *bandE; + opus_uint32 seed; +}; + +struct split_ctx { + int inv; + int imid; + int iside; + int delta; + int itheta; + int qalloc; +}; + +static void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx, + celt_norm *X, celt_norm *Y, int N, int *b, int B, int B0, + int LM, + int stereo, int *fill) +{ + int qn; + int itheta=0; + int delta; + int imid, iside; + int qalloc; + int pulse_cap; + int offset; + opus_int32 tell; + int inv=0; + int encode; + const CELTMode *m; + int i; + int intensity; + ec_ctx *ec; + const celt_ener *bandE; + + encode = ctx->encode; + m = ctx->m; + i = ctx->i; + intensity = ctx->intensity; + ec = ctx->ec; + bandE = ctx->bandE; + + /* Decide on the resolution to give to the split parameter theta */ + pulse_cap = m->logN[i]+LM*(1<>1) - (stereo&&N==2 ? QTHETA_OFFSET_TWOPHASE : QTHETA_OFFSET); + qn = compute_qn(N, *b, offset, pulse_cap, stereo); + if (stereo && i>=intensity) + qn = 1; + if (encode) + { + /* theta is the atan() of the ratio between the (normalized) + side and mid. With just that parameter, we can re-scale both + mid and side because we know that 1) they have unit norm and + 2) they are orthogonal. */ + itheta = stereo_itheta(X, Y, stereo, N); + } + tell = ec_tell_frac(ec); + if (qn!=1) + { + if (encode) + itheta = (itheta*qn+8192)>>14; + + /* Entropy coding of the angle. We use a uniform pdf for the + time split, a step for stereo, and a triangular one for the rest. */ + if (stereo && N>2) + { + int p0 = 3; + int x = itheta; + int x0 = qn/2; + int ft = p0*(x0+1) + x0; + /* Use a probability of p0 up to itheta=8192 and then use 1 after */ + if (encode) + { + ec_encode(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft); + } else { + int fs; + fs=ec_decode(ec,ft); + if (fs<(x0+1)*p0) + x=fs/p0; + else + x=x0+1+(fs-(x0+1)*p0); + ec_dec_update(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft); + itheta = x; + } + } else if (B0>1 || stereo) { + /* Uniform pdf */ + if (encode) + ec_enc_uint(ec, itheta, qn+1); + else + itheta = ec_dec_uint(ec, qn+1); + } else { + int fs=1, ft; + ft = ((qn>>1)+1)*((qn>>1)+1); + if (encode) + { + int fl; + + fs = itheta <= (qn>>1) ? itheta + 1 : qn + 1 - itheta; + fl = itheta <= (qn>>1) ? itheta*(itheta + 1)>>1 : + ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1); + + ec_encode(ec, fl, fl+fs, ft); + } else { + /* Triangular pdf */ + int fl=0; + int fm; + fm = ec_decode(ec, ft); + + if (fm < ((qn>>1)*((qn>>1) + 1)>>1)) + { + itheta = (isqrt32(8*(opus_uint32)fm + 1) - 1)>>1; + fs = itheta + 1; + fl = itheta*(itheta + 1)>>1; + } + else + { + itheta = (2*(qn + 1) + - isqrt32(8*(opus_uint32)(ft - fm - 1) + 1))>>1; + fs = qn + 1 - itheta; + fl = ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1); + } + + ec_dec_update(ec, fl, fl+fs, ft); + } + } + itheta = (opus_int32)itheta*16384/qn; + if (encode && stereo) + { + if (itheta==0) + intensity_stereo(m, X, Y, bandE, i, N); + else + stereo_split(X, Y, N); + } + /* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate. + Let's do that at higher complexity */ + } else if (stereo) { + if (encode) + { + inv = itheta > 8192; + if (inv) + { + int j; + for (j=0;j2<remaining_bits > 2<inv = inv; + sctx->imid = imid; + sctx->iside = iside; + sctx->delta = delta; + sctx->itheta = itheta; + sctx->qalloc = qalloc; +} +static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, int b, + celt_norm *lowband_out) +{ +#ifdef RESYNTH + int resynth = 1; +#else + int resynth = !ctx->encode; +#endif + int c; + int stereo; + celt_norm *x = X; + int encode; + ec_ctx *ec; + + encode = ctx->encode; + ec = ctx->ec; + + stereo = Y != NULL; + c=0; do { + int sign=0; + if (ctx->remaining_bits>=1<remaining_bits -= 1<encode; #endif + celt_norm *Y=NULL; + int encode; + const CELTMode *m; + int i; + int spread; + ec_ctx *ec; - longBlocks = B0==1; + encode = ctx->encode; + m = ctx->m; + i = ctx->i; + spread = ctx->spread; + ec = ctx->ec; N_B /= B; - N_B0 = N_B; - - split = stereo = Y != NULL; - - /* Special case for one sample */ - if (N==1) - { - int c; - celt_norm *x = X; - c=0; do { - int sign=0; - if (*remaining_bits>=1<0) - recombine = tf_change; - /* Band recombining to increase frequency resolution */ - - if (lowband && (recombine || ((N_B&1) == 0 && tf_change<0) || B0>1)) - { - int j; - for (j=0;j>k, 1<>k, 1<>4]<<2; - } - B>>=recombine; - N_B<<=recombine; - - /* Increasing the time resolution */ - while ((N_B&1) == 0 && tf_change<0) - { - if (encode) - haar1(X, N_B, B); - if (lowband) - haar1(lowband, N_B, B); - fill |= fill<>= 1; - time_divide++; - tf_change++; - } - B0=B; - N_B0 = N_B; - - /* Reorganize the samples in time order instead of frequency order */ - if (B0>1) - { - if (encode) - deinterleave_hadamard(X, N_B>>recombine, B0<>recombine, B0<cache.bits + m->cache.index[(LM+1)*m->nbEBands+i]; - if (!stereo && LM != -1 && b > cache[cache[0]]+12 && N>2) + if (LM != -1 && b > cache[cache[0]]+12 && N>2) { + int mbits, sbits, delta; + int itheta; + int qalloc; + struct split_ctx sctx; + celt_norm *next_lowband2=NULL; + opus_int32 rebalance; + N >>= 1; Y = X+N; - split = 1; LM -= 1; if (B==1) fill = (fill&1)|(fill<<1); B = (B+1)>>1; - } - - if (split) - { - int qn; - int itheta=0; - int mbits, sbits, delta; - int qalloc; - int pulse_cap; - int offset; - int orig_fill; - opus_int32 tell; - - /* Decide on the resolution to give to the split parameter theta */ - pulse_cap = m->logN[i]+LM*(1<>1) - (stereo&&N==2 ? QTHETA_OFFSET_TWOPHASE : QTHETA_OFFSET); - qn = compute_qn(N, b, offset, pulse_cap, stereo); - if (stereo && i>=intensity) - qn = 1; - if (encode) - { - /* theta is the atan() of the ratio between the (normalized) - side and mid. With just that parameter, we can re-scale both - mid and side because we know that 1) they have unit norm and - 2) they are orthogonal. */ - itheta = stereo_itheta(X, Y, stereo, N); - } - tell = ec_tell_frac(ec); - if (qn!=1) - { - if (encode) - itheta = (itheta*qn+8192)>>14; - - /* Entropy coding of the angle. We use a uniform pdf for the - time split, a step for stereo, and a triangular one for the rest. */ - if (stereo && N>2) - { - int p0 = 3; - int x = itheta; - int x0 = qn/2; - int ft = p0*(x0+1) + x0; - /* Use a probability of p0 up to itheta=8192 and then use 1 after */ - if (encode) - { - ec_encode(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft); - } else { - int fs; - fs=ec_decode(ec,ft); - if (fs<(x0+1)*p0) - x=fs/p0; - else - x=x0+1+(fs-(x0+1)*p0); - ec_dec_update(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft); - itheta = x; - } - } else if (B0>1 || stereo) { - /* Uniform pdf */ - if (encode) - ec_enc_uint(ec, itheta, qn+1); - else - itheta = ec_dec_uint(ec, qn+1); - } else { - int fs=1, ft; - ft = ((qn>>1)+1)*((qn>>1)+1); - if (encode) - { - int fl; - - fs = itheta <= (qn>>1) ? itheta + 1 : qn + 1 - itheta; - fl = itheta <= (qn>>1) ? itheta*(itheta + 1)>>1 : - ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1); - - ec_encode(ec, fl, fl+fs, ft); - } else { - /* Triangular pdf */ - int fl=0; - int fm; - fm = ec_decode(ec, ft); - - if (fm < ((qn>>1)*((qn>>1) + 1)>>1)) - { - itheta = (isqrt32(8*(opus_uint32)fm + 1) - 1)>>1; - fs = itheta + 1; - fl = itheta*(itheta + 1)>>1; - } - else - { - itheta = (2*(qn + 1) - - isqrt32(8*(opus_uint32)(ft - fm - 1) + 1))>>1; - fs = qn + 1 - itheta; - fl = ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1); - } - - ec_dec_update(ec, fl, fl+fs, ft); - } - } - itheta = (opus_int32)itheta*16384/qn; - if (encode && stereo) - { - if (itheta==0) - intensity_stereo(m, X, Y, bandE, i, N); - else - stereo_split(X, Y, N); - } - /* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate. - Let's do that at higher complexity */ - } else if (stereo) { - if (encode) - { - inv = itheta > 8192; - if (inv) - { - int j; - for (j=0;j2< 2<1 && (itheta&0x3fff)) { - int c; - int sign=0; - celt_norm *x2, *y2; - mbits = b; - sbits = 0; - /* Only need one bit for the side */ - if (itheta != 0 && itheta != 16384) - sbits = 1< 8192; - *remaining_bits -= qalloc+sbits; - - x2 = c ? Y : X; - y2 = c ? X : Y; - if (sbits) - { - if (encode) - { - /* Here we only need to encode a sign for the side */ - sign = x2[0]*y2[1] - x2[1]*y2[0] < 0; - ec_enc_bits(ec, sign, 1); - } else { - sign = ec_dec_bits(ec, 1); - } - } - sign = 1-2*sign; - /* We use orig_fill here because we want to fold the side, but if - itheta==16384, we'll have cleared the low bits of fill. */ - cm = quant_band(encode, m, i, x2, NULL, N, mbits, spread, B, intensity, tf_change, lowband, ec, remaining_bits, LM, lowband_out, NULL, level, seed, gain, lowband_scratch, orig_fill); - /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse), - and there's no need to worry about mixing with the other channel. */ - y2[0] = -sign*x2[1]; - y2[1] = sign*x2[0]; - if (resynth) - { - celt_norm tmp; - X[0] = MULT16_16_Q15(mid, X[0]); - X[1] = MULT16_16_Q15(mid, X[1]); - Y[0] = MULT16_16_Q15(side, Y[0]); - Y[1] = MULT16_16_Q15(side, Y[1]); - tmp = X[0]; - X[0] = SUB16(tmp,Y[0]); - Y[0] = ADD16(tmp,Y[0]); - tmp = X[1]; - X[1] = SUB16(tmp,Y[1]); - Y[1] = ADD16(tmp,Y[1]); - } - } else { - /* "Normal" split code */ - celt_norm *next_lowband2=NULL; - celt_norm *next_lowband_out1=NULL; - int next_level=0; - opus_int32 rebalance; - - /* Give more bits to low-energy MDCTs than they would otherwise deserve */ - if (B0>1 && !stereo && (itheta&0x3fff)) - { - if (itheta > 8192) - /* Rough approximation for pre-echo masking */ - delta -= delta>>(4-LM); - else - /* Corresponds to a forward-masking slope of 1.5 dB per 10 ms */ - delta = IMIN(0, delta + (N<>(5-LM))); - } - mbits = IMAX(0, IMIN(b, (b-delta)/2)); - sbits = b-mbits; - *remaining_bits -= qalloc; - - if (lowband && !stereo) - next_lowband2 = lowband+N; /* >32-bit split case */ - - /* Only stereo needs to pass on lowband_out. Otherwise, it's - handled at the end */ - if (stereo) - next_lowband_out1 = lowband_out; + if (itheta > 8192) + /* Rough approximation for pre-echo masking */ + delta -= delta>>(4-LM); else - next_level = level+1; - - rebalance = *remaining_bits; - if (mbits >= sbits) - { - /* In stereo mode, we do not apply a scaling to the mid because we need the normalized - mid for folding later */ - cm = quant_band(encode, m, i, X, NULL, N, mbits, spread, B, intensity, tf_change, - lowband, ec, remaining_bits, LM, next_lowband_out1, - NULL, next_level, seed, stereo ? Q15ONE : MULT16_16_P15(gain,mid), lowband_scratch, fill); - rebalance = mbits - (rebalance-*remaining_bits); - if (rebalance > 3<>B)<<((B0>>1)&(stereo-1)); - } else { - /* For a stereo split, the high bits of fill are always zero, so no - folding will be done to the side. */ - cm = quant_band(encode, m, i, Y, NULL, N, sbits, spread, B, intensity, tf_change, - next_lowband2, ec, remaining_bits, LM, NULL, - NULL, next_level, seed, MULT16_16_P15(gain,side), NULL, fill>>B)<<((B0>>1)&(stereo-1)); - rebalance = sbits - (rebalance-*remaining_bits); - if (rebalance > 3<>(5-LM))); } + mbits = IMAX(0, IMIN(b, (b-delta)/2)); + sbits = b-mbits; + ctx->remaining_bits -= qalloc; + if (lowband) + next_lowband2 = lowband+N; /* >32-bit split case */ + + rebalance = ctx->remaining_bits; + if (mbits >= sbits) + { + cm = quant_partition(ctx, X, N, mbits, B, + lowband, LM, + MULT16_16_P15(gain,mid), fill); + rebalance = mbits - (rebalance-ctx->remaining_bits); + if (rebalance > 3<>B)<<(B0>>1); + } else { + cm = quant_partition(ctx, Y, N, sbits, B, + next_lowband2, LM, + MULT16_16_P15(gain,side), fill>>B)<<(B0>>1); + rebalance = sbits - (rebalance-ctx->remaining_bits); + if (rebalance > 3<remaining_bits -= curr_bits; /* Ensures we can never bust the budget */ - while (*remaining_bits < 0 && q > 0) + while (ctx->remaining_bits < 0 && q > 0) { - *remaining_bits += curr_bits; + ctx->remaining_bits += curr_bits; q--; curr_bits = pulses2bits(m, i, LM, q); - *remaining_bits -= curr_bits; + ctx->remaining_bits -= curr_bits; } if (q!=0) @@ -1076,7 +1002,7 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c if (resynth) { unsigned cm_mask; - /*B can be as large as 16, so this shift might overflow an int on a + /* B can be as large as 16, so this shift might overflow an int on a 16-bit platform; use a long to get defined behavior.*/ cm_mask = (unsigned)(1UL<>20); + ctx->seed = celt_lcg_rand(ctx->seed); + X[j] = (celt_norm)((opus_int32)ctx->seed>>20); } cm = cm_mask; } else { @@ -1099,10 +1025,10 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c for (j=0;jseed = celt_lcg_rand(ctx->seed); /* About 48 dB below the "normal" folding level */ tmp = QCONST16(1.0f/256, 10); - tmp = (*seed)&0x8000 ? tmp : -tmp; + tmp = (ctx->seed)&0x8000 ? tmp : -tmp; X[j] = lowband[j]+tmp; } cm = fill; @@ -1113,64 +1039,307 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c } } + return cm; +} + + +/* This function is responsible for encoding and decoding a band for the mono case. */ +static unsigned quant_band(struct band_ctx *ctx, celt_norm *X, + int N, int b, int B, celt_norm *lowband, + int LM, celt_norm *lowband_out, + opus_val16 gain, celt_norm *lowband_scratch, int fill) +{ + int N0=N; + int N_B=N; + int N_B0; + int B0=B; + int time_divide=0; + int recombine=0; + int longBlocks; + unsigned cm=0; +#ifdef RESYNTH + int resynth = 1; +#else + int resynth = !ctx->encode; +#endif + int k; + int encode; + int tf_change; + + encode = ctx->encode; + tf_change = ctx->tf_change; + + longBlocks = B0==1; + + N_B /= B; + N_B0 = N_B; + + /* Special case for one sample */ + if (N==1) + { + return quant_band_n1(ctx, X, NULL, b, lowband_out); + } + + if (tf_change>0) + recombine = tf_change; + /* Band recombining to increase frequency resolution */ + + if (lowband_scratch && lowband && (recombine || ((N_B&1) == 0 && tf_change<0) || B0>1)) + { + int j; + for (j=0;j>k, 1<>k, 1<>4]<<2; + } + B>>=recombine; + N_B<<=recombine; + + /* Increasing the time resolution */ + while ((N_B&1) == 0 && tf_change<0) + { + if (encode) + haar1(X, N_B, B); + if (lowband) + haar1(lowband, N_B, B); + fill |= fill<>= 1; + time_divide++; + tf_change++; + } + B0=B; + N_B0 = N_B; + + /* Reorganize the samples in time order instead of frequency order */ + if (B0>1) + { + if (encode) + deinterleave_hadamard(X, N_B>>recombine, B0<>recombine, B0<1) + interleave_hadamard(X, N_B>>recombine, B0<>= 1; + N_B <<= 1; + cm |= cm>>B; + haar1(X, N_B, B); + } + + for (k=0;k>k, 1<1) - interleave_hadamard(X, N_B>>recombine, B0<encode; +#endif + int mbits, sbits, delta; + int itheta; + int qalloc; + struct split_ctx sctx; + int orig_fill; + int encode; + ec_ctx *ec; + + encode = ctx->encode; + ec = ctx->ec; + + /* Special case for one sample */ + if (N==1) + { + return quant_band_n1(ctx, X, Y, b, lowband_out); + } + + orig_fill = fill; + + compute_theta(ctx, &sctx, X, Y, N, &b, B, B, + LM, 1, &fill); + inv = sctx.inv; + imid = sctx.imid; + iside = sctx.iside; + delta = sctx.delta; + itheta = sctx.itheta; + qalloc = sctx.qalloc; +#ifdef FIXED_POINT + mid = imid; + side = iside; +#else + mid = (1.f/32768)*imid; + side = (1.f/32768)*iside; +#endif + + /* This is a special case for N=2 that only works for stereo and takes + advantage of the fact that mid and side are orthogonal to encode + the side with just one bit. */ + if (N==2) + { + int c; + int sign=0; + celt_norm *x2, *y2; + mbits = b; + sbits = 0; + /* Only need one bit for the side. */ + if (itheta != 0 && itheta != 16384) + sbits = 1< 8192; + ctx->remaining_bits -= qalloc+sbits; + + x2 = c ? Y : X; + y2 = c ? X : Y; + if (sbits) + { + if (encode) { - B >>= 1; - N_B <<= 1; - cm |= cm>>B; - haar1(X, N_B, B); + /* Here we only need to encode a sign for the side. */ + sign = x2[0]*y2[1] - x2[1]*y2[0] < 0; + ec_enc_bits(ec, sign, 1); + } else { + sign = ec_dec_bits(ec, 1); } + } + sign = 1-2*sign; + /* We use orig_fill here because we want to fold the side, but if + itheta==16384, we'll have cleared the low bits of fill. */ + cm = quant_band(ctx, x2, N, mbits, B, lowband, + LM, lowband_out, Q15ONE, lowband_scratch, orig_fill); + /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse), + and there's no need to worry about mixing with the other channel. */ + y2[0] = -sign*x2[1]; + y2[1] = sign*x2[0]; + if (resynth) + { + celt_norm tmp; + X[0] = MULT16_16_Q15(mid, X[0]); + X[1] = MULT16_16_Q15(mid, X[1]); + Y[0] = MULT16_16_Q15(side, Y[0]); + Y[1] = MULT16_16_Q15(side, Y[1]); + tmp = X[0]; + X[0] = SUB16(tmp,Y[0]); + Y[0] = ADD16(tmp,Y[0]); + tmp = X[1]; + X[1] = SUB16(tmp,Y[1]); + Y[1] = ADD16(tmp,Y[1]); + } + } else { + /* "Normal" split code */ + opus_int32 rebalance; - for (k=0;k>k, 1<remaining_bits -= qalloc; - /* Scale output for later folding */ - if (lowband_out) - { - int j; - opus_val16 n; - n = celt_sqrt(SHL32(EXTEND32(N0),22)); - for (j=0;jremaining_bits; + if (mbits >= sbits) + { + /* In stereo mode, we do not apply a scaling to the mid because we need the normalized + mid for folding later. */ + cm = quant_band(ctx, X, N, mbits, B, + lowband, LM, lowband_out, + Q15ONE, lowband_scratch, fill); + rebalance = mbits - (rebalance-ctx->remaining_bits); + if (rebalance > 3<>B); + } else { + /* For a stereo split, the high bits of fill are always zero, so no + folding will be done to the side. */ + cm = quant_band(ctx, Y, N, sbits, B, + NULL, LM, NULL, + side, NULL, fill>>B); + rebalance = sbits - (rebalance-ctx->remaining_bits); + if (rebalance > 3<eBands; - celt_norm * restrict norm, * restrict norm2; + const opus_int16 * OPUS_RESTRICT eBands = m->eBands; + celt_norm * OPUS_RESTRICT norm, * OPUS_RESTRICT norm2; VARDECL(celt_norm, _norm); - VARDECL(celt_norm, lowband_scratch); + celt_norm *lowband_scratch; int B; int M; int lowband_offset; int update_lowband = 1; int C = Y_ != NULL ? 2 : 1; + int norm_offset; #ifdef RESYNTH int resynth = 1; #else int resynth = !encode; #endif + struct band_ctx ctx; SAVE_STACK; M = 1<nbEBands], celt_norm); - ALLOC(lowband_scratch, M*(eBands[m->nbEBands]-eBands[m->nbEBands-1]), celt_norm); + norm_offset = M*eBands[start]; + /* No need to allocate norm for the last band because we don't need an + output in that band. */ + ALLOC(_norm, C*(M*eBands[m->nbEBands-1]-norm_offset), celt_norm); norm = _norm; - norm2 = norm + M*eBands[m->nbEBands]; + norm2 = norm + M*eBands[m->nbEBands-1]-norm_offset; + /* We can use the last band as scratch space because we don't need that + scratch space for the last band. */ + lowband_scratch = X_+M*eBands[m->nbEBands-1]; lowband_offset = 0; + ctx.bandE = bandE; + ctx.ec = ec; + ctx.encode = encode; + ctx.intensity = intensity; + ctx.m = m; + ctx.seed = *seed; + ctx.spread = spread; for (i=start;i=m->effEBands) { X=norm; if (Y_!=NULL) Y = norm; + lowband_scratch = NULL; } + if (i==end-1) + lowband_scratch = NULL; /* Get a conservative estimate of the collapse_mask's for the bands we're - going to be folding from. */ + going to be folding from. */ if (lowband_offset != 0 && (spread!=SPREAD_AGGRESSIVE || B>1 || tf_change<0)) { int fold_start; int fold_end; int fold_i; /* This ensures we never repeat spectral content within one band */ - effective_lowband = IMAX(M*eBands[start], M*eBands[lowband_offset]-N); + effective_lowband = IMAX(0, M*eBands[lowband_offset]-norm_offset-N); fold_start = lowband_offset; - while(M*eBands[--fold_start] > effective_lowband); + while(M*eBands[--fold_start] > effective_lowband+norm_offset); fold_end = lowband_offset-1; - while(M*eBands[++fold_end] < effective_lowband+N); + while(M*eBands[++fold_end] < effective_lowband+norm_offset+N); x_cm = y_cm = 0; fold_i = fold_start; do { x_cm |= collapse_masks[fold_i*C+0]; @@ -1265,7 +1457,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end, } while (++fold_i(N<>3]; - if (ret == 0) - return -1; - else - return ret|(c&0x7); -} - -static inline int fromOpus(unsigned char c) -{ - if (c<0x80) - return -1; - else - return fromOpusTable[(c>>3)-16] | (c&0x7); -} -#endif /* CUSTOM_MODES */ - -#define COMBFILTER_MAXPERIOD 1024 -#define COMBFILTER_MINPERIOD 15 - -static int resampling_factor(opus_int32 rate) +int resampling_factor(opus_int32 rate) { int ret; switch (rate) @@ -143,647 +85,101 @@ static int resampling_factor(opus_int32 rate) return ret; } -/** Encoder state - @brief Encoder state - */ -struct OpusCustomEncoder { - const OpusCustomMode *mode; /**< Mode used by the encoder */ - int overlap; - int channels; - int stream_channels; - - int force_intra; - int clip; - int disable_pf; - int complexity; - int upsample; - int start, end; - - opus_int32 bitrate; - int vbr; - int signalling; - int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */ - int loss_rate; - - /* Everything beyond this point gets cleared on a reset */ -#define ENCODER_RESET_START rng - - opus_uint32 rng; - int spread_decision; - opus_val32 delayedIntra; - int tonal_average; - int lastCodedBands; - int hf_average; - int tapset_decision; - - int prefilter_period; - opus_val16 prefilter_gain; - int prefilter_tapset; -#ifdef RESYNTH - int prefilter_period_old; - opus_val16 prefilter_gain_old; - int prefilter_tapset_old; -#endif - int consec_transient; - - opus_val32 preemph_memE[2]; - opus_val32 preemph_memD[2]; - - /* VBR-related parameters */ - opus_int32 vbr_reservoir; - opus_int32 vbr_drift; - opus_int32 vbr_offset; - opus_int32 vbr_count; - -#ifdef RESYNTH - celt_sig syn_mem[2][2*MAX_PERIOD]; -#endif - - celt_sig in_mem[1]; /* Size = channels*mode->overlap */ - /* celt_sig prefilter_mem[], Size = channels*COMBFILTER_PERIOD */ - /* celt_sig overlap_mem[], Size = channels*mode->overlap */ - /* opus_val16 oldEBands[], Size = 2*channels*mode->nbEBands */ -}; - -int celt_encoder_get_size(int channels) -{ - CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); - return opus_custom_encoder_get_size(mode, channels); -} - -OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_get_size(const CELTMode *mode, int channels) -{ - int size = sizeof(struct CELTEncoder) - + (2*channels*mode->overlap-1)*sizeof(celt_sig) - + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig) - + 3*channels*mode->nbEBands*sizeof(opus_val16); - return size; -} - -#ifdef CUSTOM_MODES -CELTEncoder *opus_custom_encoder_create(const CELTMode *mode, int channels, int *error) -{ - int ret; - CELTEncoder *st = (CELTEncoder *)opus_alloc(opus_custom_encoder_get_size(mode, channels)); - /* init will handle the NULL case */ - ret = opus_custom_encoder_init(st, mode, channels); - if (ret != OPUS_OK) - { - opus_custom_encoder_destroy(st); - st = NULL; - } - if (error) - *error = ret; - return st; -} -#endif /* CUSTOM_MODES */ - -int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels) -{ - int ret; - ret = opus_custom_encoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels); - if (ret != OPUS_OK) - return ret; - st->upsample = resampling_factor(sampling_rate); - return OPUS_OK; -} - -OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels) -{ - if (channels < 0 || channels > 2) - return OPUS_BAD_ARG; - - if (st==NULL || mode==NULL) - return OPUS_ALLOC_FAIL; - - OPUS_CLEAR((char*)st, opus_custom_encoder_get_size(mode, channels)); - - st->mode = mode; - st->overlap = mode->overlap; - st->stream_channels = st->channels = channels; - - st->upsample = 1; - st->start = 0; - st->end = st->mode->effEBands; - st->signalling = 1; - - st->constrained_vbr = 1; - st->clip = 1; - - st->bitrate = OPUS_BITRATE_MAX; - st->vbr = 0; - st->force_intra = 0; - st->complexity = 5; - - opus_custom_encoder_ctl(st, OPUS_RESET_STATE); - - return OPUS_OK; -} - -#ifdef CUSTOM_MODES -void opus_custom_encoder_destroy(CELTEncoder *st) -{ - opus_free(st); -} -#endif /* CUSTOM_MODES */ - -static inline opus_val16 SIG2WORD16(celt_sig x) -{ -#ifdef FIXED_POINT - x = PSHR32(x, SIG_SHIFT); - x = MAX32(x, -32768); - x = MIN32(x, 32767); - return EXTRACT16(x); -#else - return (opus_val16)x; -#endif -} - -static int transient_analysis(const opus_val32 * restrict in, int len, int C, - int overlap) +#ifndef OVERRIDE_COMB_FILTER_CONST +static void comb_filter_const(opus_val32 *y, opus_val32 *x, int T, int N, + opus_val16 g10, opus_val16 g11, opus_val16 g12) { + opus_val32 x0, x1, x2, x3, x4; int i; - VARDECL(opus_val16, tmp); - opus_val32 mem0=0,mem1=0; - int is_transient = 0; - int block; - int N; - VARDECL(opus_val16, bins); - SAVE_STACK; - ALLOC(tmp, len, opus_val16); - - block = overlap/2; - N=len/block; - ALLOC(bins, N, opus_val16); - if (C==1) - { - for (i=0;i=3) - is_transient=1; - conseq = 0; - for (j=i+1;j=7) - is_transient=1; - } - RESTORE_STACK; -#ifdef FUZZING - is_transient = rand()&0x1; +} #endif - return is_transient; -} -/** Apply window and compute the MDCT for all sub-frames and - all channels in a frame */ -static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * restrict in, celt_sig * restrict out, int C, int LM) -{ - if (C==1 && !shortBlocks) - { - const int overlap = OVERLAP(mode); - clt_mdct_forward(&mode->mdct, in, out, mode->window, overlap, mode->maxLM-LM, 1); - } else { - const int overlap = OVERLAP(mode); - int N = mode->shortMdctSize<shortMdctSize; - B = shortBlocks; - } - c=0; do { - for (b=0;bmdct, in+c*(B*N+overlap)+b*N, &out[b+c*N*B], mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM, B); - } - } while (++cshortMdctSize<shortMdctSize; - B = shortBlocks; - } - /* Prevents problems from the imdct doing the overlap-add */ - OPUS_CLEAR(x, overlap); - - for (b=0;bmdct, &X[b+c*N2*B], x+N2*b, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM, B); - } - - for (j=0;j>LM;j++) - L2 = MAC16_16(L2, tmp[(j<eBands[len]-m->eBands[len-1])<eBands[i+1]-m->eBands[i])<eBands[i]<eBands[i]<>LM); - best_L1 = L1; - /*printf ("%f ", L1);*/ - for (k=0;k>(LM-k), 1<<(LM-k)); - else - haar1(tmp, N>>k, 1<>LM); - - if (L1 < best_L1) - { - best_L1 = L1; - best_level = k+1; - } - } - /*printf ("%d ", isTransient ? LM-best_level : best_level);*/ - if (isTransient) - metric[i] = best_level; - else - metric[i] = -best_level; - *tf_sum += metric[i]; - } - /*printf("\n");*/ - /* NOTE: Future optimized implementations could detect extreme transients and set - tf_select = 1 but so far we have not found a reliable way of making this useful */ - tf_select = 0; - - cost0 = 0; - cost1 = isTransient ? 0 : lambda; - /* Viterbi forward pass */ - for (i=1;i=0;i--) - { - if (tf_res[i+1] == 1) - tf_res[i] = path1[i+1]; - else - tf_res[i] = path0[i+1]; - } - RESTORE_STACK; -#ifdef FUZZING - tf_select = rand()&0x1; - tf_res[0] = rand()&0x1; - for (i=1;istorage*8; - tell = ec_tell(enc); - logp = isTransient ? 2 : 4; - /* Reserve space to code the tf_select decision. */ - tf_select_rsv = LM>0 && tell+logp+1 <= budget; - budget -= tf_select_rsv; - curr = tf_changed = 0; - for (i=start;istorage*8; - tell = ec_tell(dec); - logp = isTransient ? 2 : 4; - tf_select_rsv = LM>0 && tell+logp+1<=budget; - budget -= tf_select_rsv; - tf_changed = curr = 0; - for (i=start;inbEBands;i++) @@ -794,2042 +190,11 @@ static void init_caps(const CELTMode *m,int *cap,int LM,int C) } } -static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X, - const opus_val16 *bandLogE, int end, int LM, int C, int N0) -{ - int i; - opus_val32 diff=0; - int c; - int trim_index = 5; - if (C==2) - { - opus_val16 sum = 0; /* Q10 */ - /* Compute inter-channel correlation for low frequencies */ - for (i=0;i<8;i++) - { - int j; - opus_val32 partial = 0; - for (j=m->eBands[i]<eBands[i+1]< QCONST16(.995f,10)) - trim_index-=4; - else if (sum > QCONST16(.92f,10)) - trim_index-=3; - else if (sum > QCONST16(.85f,10)) - trim_index-=2; - else if (sum > QCONST16(.8f,10)) - trim_index-=1; - } - - /* Estimate spectral tilt */ - c=0; do { - for (i=0;inbEBands]*(opus_int32)(2+2*i-m->nbEBands); - } - } while (++c QCONST16(2.f, DB_SHIFT)) - trim_index--; - if (diff > QCONST16(8.f, DB_SHIFT)) - trim_index--; - if (diff < -QCONST16(4.f, DB_SHIFT)) - trim_index++; - if (diff < -QCONST16(10.f, DB_SHIFT)) - trim_index++; - - if (trim_index<0) - trim_index = 0; - if (trim_index>10) - trim_index = 10; -#ifdef FUZZING - trim_index = rand()%11; -#endif - return trim_index; -} - -static int stereo_analysis(const CELTMode *m, const celt_norm *X, - int LM, int N0) -{ - int i; - int thetas; - opus_val32 sumLR = EPSILON, sumMS = EPSILON; - - /* Use the L1 norm to model the entropy of the L/R signal vs the M/S signal */ - for (i=0;i<13;i++) - { - int j; - for (j=m->eBands[i]<eBands[i+1]<eBands[13]<<(LM+1))+thetas, sumMS) - > MULT16_32_Q15(m->eBands[13]<<(LM+1), sumLR); -} - -int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc) -{ - int i, c, N; - opus_int32 bits; - ec_enc _enc; - VARDECL(celt_sig, in); - VARDECL(celt_sig, freq); - VARDECL(celt_norm, X); - VARDECL(celt_ener, bandE); - VARDECL(opus_val16, bandLogE); - VARDECL(int, fine_quant); - VARDECL(opus_val16, error); - VARDECL(int, pulses); - VARDECL(int, cap); - VARDECL(int, offsets); - VARDECL(int, fine_priority); - VARDECL(int, tf_res); - VARDECL(unsigned char, collapse_masks); - celt_sig *prefilter_mem; - opus_val16 *oldBandE, *oldLogE, *oldLogE2; - int shortBlocks=0; - int isTransient=0; - const int CC = st->channels; - const int C = st->stream_channels; - int LM, M; - int tf_select; - int nbFilledBytes, nbAvailableBytes; - int effEnd; - int codedBands; - int tf_sum; - int alloc_trim; - int pitch_index=COMBFILTER_MINPERIOD; - opus_val16 gain1 = 0; - int intensity=0; - int dual_stereo=0; - int effectiveBytes; - opus_val16 pf_threshold; - int dynalloc_logp; - opus_int32 vbr_rate; - opus_int32 total_bits; - opus_int32 total_boost; - opus_int32 balance; - opus_int32 tell; - int prefilter_tapset=0; - int pf_on; - int anti_collapse_rsv; - int anti_collapse_on=0; - int silence=0; - ALLOC_STACK; - - if (nbCompressedBytes<2 || pcm==NULL) - return OPUS_BAD_ARG; - - frame_size *= st->upsample; - for (LM=0;LM<=st->mode->maxLM;LM++) - if (st->mode->shortMdctSize<st->mode->maxLM) - return OPUS_BAD_ARG; - M=1<mode->shortMdctSize; - - prefilter_mem = st->in_mem+CC*(st->overlap); - oldBandE = (opus_val16*)(st->in_mem+CC*(2*st->overlap+COMBFILTER_MAXPERIOD)); - oldLogE = oldBandE + CC*st->mode->nbEBands; - oldLogE2 = oldLogE + CC*st->mode->nbEBands; - - if (enc==NULL) - { - tell=1; - nbFilledBytes=0; - } else { - tell=ec_tell(enc); - nbFilledBytes=(tell+4)>>3; - } - -#ifdef CUSTOM_MODES - if (st->signalling && enc==NULL) - { - int tmp = (st->mode->effEBands-st->end)>>1; - st->end = IMAX(1, st->mode->effEBands-tmp); - compressed[0] = tmp<<5; - compressed[0] |= LM<<3; - compressed[0] |= (C==2)<<2; - /* Convert "standard mode" to Opus header */ - if (st->mode->Fs==48000 && st->mode->shortMdctSize==120) - { - int c0 = toOpus(compressed[0]); - if (c0<0) - return OPUS_BAD_ARG; - compressed[0] = c0; - } - compressed++; - nbCompressedBytes--; - } -#else - celt_assert(st->signalling==0); -#endif - - /* Can't produce more than 1275 output bytes */ - nbCompressedBytes = IMIN(nbCompressedBytes,1275); - nbAvailableBytes = nbCompressedBytes - nbFilledBytes; - - if (st->vbr && st->bitrate!=OPUS_BITRATE_MAX) - { - opus_int32 den=st->mode->Fs>>BITRES; - vbr_rate=(st->bitrate*frame_size+(den>>1))/den; -#ifdef CUSTOM_MODES - if (st->signalling) - vbr_rate -= 8<>(3+BITRES); - } else { - opus_int32 tmp; - vbr_rate = 0; - tmp = st->bitrate*frame_size; - if (tell>1) - tmp += tell; - if (st->bitrate!=OPUS_BITRATE_MAX) - nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes, - (tmp+4*st->mode->Fs)/(8*st->mode->Fs)-!!st->signalling)); - effectiveBytes = nbCompressedBytes; - } - - if (enc==NULL) - { - ec_enc_init(&_enc, compressed, nbCompressedBytes); - enc = &_enc; - } - - if (vbr_rate>0) - { - /* Computes the max bit-rate allowed in VBR mode to avoid violating the - target rate and buffering. - We must do this up front so that bust-prevention logic triggers - correctly if we don't have enough bits. */ - if (st->constrained_vbr) - { - opus_int32 vbr_bound; - opus_int32 max_allowed; - /* We could use any multiple of vbr_rate as bound (depending on the - delay). - This is clamped to ensure we use at least two bytes if the encoder - was entirely empty, but to allow 0 in hybrid mode. */ - vbr_bound = vbr_rate; - max_allowed = IMIN(IMAX(tell==1?2:0, - (vbr_rate+vbr_bound-st->vbr_reservoir)>>(BITRES+3)), - nbAvailableBytes); - if(max_allowed < nbAvailableBytes) - { - nbCompressedBytes = nbFilledBytes+max_allowed; - nbAvailableBytes = max_allowed; - ec_enc_shrink(enc, nbCompressedBytes); - } - } - } - total_bits = nbCompressedBytes*8; - - effEnd = st->end; - if (effEnd > st->mode->effEBands) - effEnd = st->mode->effEBands; - - ALLOC(in, CC*(N+st->overlap), celt_sig); - - /* Find pitch period and gain */ - { - VARDECL(celt_sig, _pre); - celt_sig *pre[2]; - SAVE_STACK; - ALLOC(_pre, CC*(N+COMBFILTER_MAXPERIOD), celt_sig); - - pre[0] = _pre; - pre[1] = _pre + (N+COMBFILTER_MAXPERIOD); - - silence = 1; - c=0; do { - int count = 0; - const opus_val16 * restrict pcmp = pcm+c; - celt_sig * restrict inp = in+c*(N+st->overlap)+st->overlap; - - for (i=0;iclip) - x = MAX32(-65536.f, MIN32(65536.f,x)); -#endif - if (++count==st->upsample) - { - count=0; - pcmp+=CC; - } else { - x = 0; - } - /* Apply pre-emphasis */ - tmp = MULT16_16(st->mode->preemph[2], x); - *inp = tmp + st->preemph_memE[c]; - st->preemph_memE[c] = MULT16_32_Q15(st->mode->preemph[1], *inp) - - MULT16_32_Q15(st->mode->preemph[0], tmp); - silence = silence && *inp == 0; - inp++; - } - OPUS_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD); - OPUS_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+st->overlap)+st->overlap, N); - } while (++c0) - { - effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2); - total_bits=nbCompressedBytes*8; - nbAvailableBytes=2; - ec_enc_shrink(enc, nbCompressedBytes); - } - /* Pretend we've filled all the remaining bits with zeros - (that's what the initialiser did anyway) */ - tell = nbCompressedBytes*8; - enc->nbits_total+=tell-ec_tell(enc); - } - if (nbAvailableBytes>12*C && st->start==0 && !silence && !st->disable_pf && st->complexity >= 5) - { - VARDECL(opus_val16, pitch_buf); - ALLOC(pitch_buf, (COMBFILTER_MAXPERIOD+N)>>1, opus_val16); - - pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC); - pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N, - COMBFILTER_MAXPERIOD-COMBFILTER_MINPERIOD, &pitch_index); - pitch_index = COMBFILTER_MAXPERIOD-pitch_index; - - gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD, - N, &pitch_index, st->prefilter_period, st->prefilter_gain); - if (pitch_index > COMBFILTER_MAXPERIOD-2) - pitch_index = COMBFILTER_MAXPERIOD-2; - gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1); - if (st->loss_rate>2) - gain1 = HALF32(gain1); - if (st->loss_rate>4) - gain1 = HALF32(gain1); - if (st->loss_rate>8) - gain1 = 0; - prefilter_tapset = st->tapset_decision; - } else { - gain1 = 0; - } - - /* Gain threshold for enabling the prefilter/postfilter */ - pf_threshold = QCONST16(.2f,15); - - /* Adjusting the threshold based on rate and continuity */ - if (abs(pitch_index-st->prefilter_period)*10>pitch_index) - pf_threshold += QCONST16(.2f,15); - if (nbAvailableBytes<25) - pf_threshold += QCONST16(.1f,15); - if (nbAvailableBytes<35) - pf_threshold += QCONST16(.1f,15); - if (st->prefilter_gain > QCONST16(.4f,15)) - pf_threshold -= QCONST16(.1f,15); - if (st->prefilter_gain > QCONST16(.55f,15)) - pf_threshold -= QCONST16(.1f,15); - - /* Hard threshold at 0.2 */ - pf_threshold = MAX16(pf_threshold, QCONST16(.2f,15)); - if (gain1start==0 && tell+16<=total_bits) - ec_enc_bit_logp(enc, 0, 1); - gain1 = 0; - pf_on = 0; - } else { - /*This block is not gated by a total bits check only because - of the nbAvailableBytes check above.*/ - int qg; - int octave; - - if (ABS16(gain1-st->prefilter_gain)prefilter_gain; - -#ifdef FIXED_POINT - qg = ((gain1+1536)>>10)/3-1; -#else - qg = (int)floor(.5f+gain1*32/3)-1; -#endif - qg = IMAX(0, IMIN(7, qg)); - ec_enc_bit_logp(enc, 1, 1); - pitch_index += 1; - octave = EC_ILOG(pitch_index)-5; - ec_enc_uint(enc, octave, 6); - ec_enc_bits(enc, pitch_index-(16<mode->shortMdctSize-st->mode->overlap; - st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); - OPUS_COPY(in+c*(N+st->overlap), st->in_mem+c*(st->overlap), st->overlap); - if (offset) - comb_filter(in+c*(N+st->overlap)+st->overlap, pre[c]+COMBFILTER_MAXPERIOD, - st->prefilter_period, st->prefilter_period, offset, -st->prefilter_gain, -st->prefilter_gain, - st->prefilter_tapset, st->prefilter_tapset, NULL, 0); - - comb_filter(in+c*(N+st->overlap)+st->overlap+offset, pre[c]+COMBFILTER_MAXPERIOD+offset, - st->prefilter_period, pitch_index, N-offset, -st->prefilter_gain, -gain1, - st->prefilter_tapset, prefilter_tapset, st->mode->window, st->mode->overlap); - OPUS_COPY(st->in_mem+c*(st->overlap), in+c*(N+st->overlap)+N, st->overlap); - - if (N>COMBFILTER_MAXPERIOD) - { - OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD); - } else { - OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, prefilter_mem+c*COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD-N); - OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N); - } - } while (++c0 && ec_tell(enc)+3<=total_bits) - { - if (st->complexity > 1) - { - isTransient = transient_analysis(in, N+st->overlap, CC, - st->overlap); - if (isTransient) - shortBlocks = M; - } - ec_enc_bit_logp(enc, isTransient, 3); - } - - ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */ - ALLOC(bandE,st->mode->nbEBands*CC, celt_ener); - ALLOC(bandLogE,st->mode->nbEBands*CC, opus_val16); - /* Compute MDCTs */ - compute_mdcts(st->mode, shortBlocks, in, freq, CC, LM); - - if (CC==2&&C==1) - { - for (i=0;iupsample != 1) - { - c=0; do - { - int bound = N/st->upsample; - for (i=0;iupsample; - for (;imode, freq, bandE, effEnd, C, M); - - amp2Log2(st->mode, effEnd, st->end, bandE, bandLogE, C); - - /* Band normalisation */ - normalise_bands(st->mode, freq, X, bandE, effEnd, C, M); - - ALLOC(tf_res, st->mode->nbEBands, int); - tf_select = tf_analysis(st->mode, effEnd, C, isTransient, tf_res, effectiveBytes, X, N, LM, &tf_sum); - for (i=effEnd;iend;i++) - tf_res[i] = tf_res[effEnd-1]; - - ALLOC(error, C*st->mode->nbEBands, opus_val16); - quant_coarse_energy(st->mode, st->start, st->end, effEnd, bandLogE, - oldBandE, total_bits, error, enc, - C, LM, nbAvailableBytes, st->force_intra, - &st->delayedIntra, st->complexity >= 4, st->loss_rate); - - tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc); - - st->spread_decision = SPREAD_NORMAL; - if (ec_tell(enc)+4<=total_bits) - { - if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C) - { - if (st->complexity == 0) - st->spread_decision = SPREAD_NONE; - } else { - st->spread_decision = spreading_decision(st->mode, X, - &st->tonal_average, st->spread_decision, &st->hf_average, - &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M); - } - ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5); - } - - ALLOC(cap, st->mode->nbEBands, int); - ALLOC(offsets, st->mode->nbEBands, int); - - init_caps(st->mode,cap,LM,C); - for (i=0;imode->nbEBands;i++) - offsets[i] = 0; - /* Dynamic allocation code */ - /* Make sure that dynamic allocation can't make us bust the budget */ - if (effectiveBytes > 50 && LM>=1) - { - int t1, t2; - if (LM <= 1) - { - t1 = 3; - t2 = 5; - } else { - t1 = 2; - t2 = 4; - } - for (i=st->start+1;iend-1;i++) - { - opus_val32 d2; - d2 = 2*bandLogE[i]-bandLogE[i-1]-bandLogE[i+1]; - if (C==2) - d2 = HALF32(d2 + 2*bandLogE[i+st->mode->nbEBands]- - bandLogE[i-1+st->mode->nbEBands]-bandLogE[i+1+st->mode->nbEBands]); -#ifdef FUZZING - if((rand()&0xF)==0) - { - offsets[i] += 1; - if((rand()&0x3)==0) - offsets[i] += 1+(rand()&0x3); - } -#else - if (d2 > SHL16(t1,DB_SHIFT)) - offsets[i] += 1; - if (d2 > SHL16(t2,DB_SHIFT)) - offsets[i] += 1; -#endif - } - } - dynalloc_logp = 6; - total_bits<<=BITRES; - total_boost = 0; - tell = ec_tell_frac(enc); - for (i=st->start;iend;i++) - { - int width, quanta; - int dynalloc_loop_logp; - int boost; - int j; - width = C*(st->mode->eBands[i+1]-st->mode->eBands[i])<mode, X, bandLogE, - st->end, LM, C, N); - ec_enc_icdf(enc, alloc_trim, trim_icdf, 7); - tell = ec_tell_frac(enc); - } - - /* Variable bitrate */ - if (vbr_rate>0) - { - opus_val16 alpha; - opus_int32 delta; - /* The target rate in 8th bits per frame */ - opus_int32 target; - opus_int32 min_allowed; - int lm_diff = st->mode->maxLM - LM; - - target = vbr_rate + (st->vbr_offset>>lm_diff) - ((40*C+20)<end-st->start)) - target = 7*target/4; - else if (tf_sum < -(st->end-st->start)) - target = 3*target/2; - else if (M > 1) - target-=(target+14)/28; - - /* The current offset is removed from the target and the space used - so far is added*/ - target=target+tell; - - /* In VBR mode the frame size must not be reduced so much that it would - result in the encoder running out of bits. - The margin of 2 bytes ensures that none of the bust-prevention logic - in the decoder will have triggered so far. */ - min_allowed = ((tell+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3)) + 2 - nbFilledBytes; - - nbAvailableBytes = (target+(1<<(BITRES+2)))>>(BITRES+3); - nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes); - nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes) - nbFilledBytes; - - /* By how much did we "miss" the target on that frame */ - delta = target - vbr_rate; - - target=nbAvailableBytes<<(BITRES+3); - - /*If the frame is silent we don't adjust our drift, otherwise - the encoder will shoot to very high rates after hitting a - span of silence, but we do allow the bitres to refill. - This means that we'll undershoot our target in CVBR/VBR modes - on files with lots of silence. */ - if(silence) - { - nbAvailableBytes = 2; - target = 2*8<vbr_count < 970) - { - st->vbr_count++; - alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+20),16)); - } else - alpha = QCONST16(.001f,15); - /* How many bits have we used in excess of what we're allowed */ - if (st->constrained_vbr) - st->vbr_reservoir += target - vbr_rate; - /*printf ("%d\n", st->vbr_reservoir);*/ - - /* Compute the offset we need to apply in order to reach the target */ - st->vbr_drift += (opus_int32)MULT16_32_Q15(alpha,(delta*(1<vbr_offset-st->vbr_drift); - st->vbr_offset = -st->vbr_drift; - /*printf ("%d\n", st->vbr_drift);*/ - - if (st->constrained_vbr && st->vbr_reservoir < 0) - { - /* We're under the min value -- increase rate */ - int adjust = (-st->vbr_reservoir)/(8<vbr_reservoir = 0; - /*printf ("+%d\n", adjust);*/ - } - nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes); - /* This moves the raw bits to take into account the new compressed size */ - ec_enc_shrink(enc, nbCompressedBytes); - } - if (C==2) - { - int effectiveRate; - - /* Always use MS for 2.5 ms frames until we can do a better analysis */ - if (LM!=0) - dual_stereo = stereo_analysis(st->mode, X, LM, N); - - /* Account for coarse energy */ - effectiveRate = (8*effectiveBytes - 80)>>LM; - - /* effectiveRate in kb/s */ - effectiveRate = 2*effectiveRate/5; - if (effectiveRate<35) - intensity = 8; - else if (effectiveRate<50) - intensity = 12; - else if (effectiveRate<68) - intensity = 16; - else if (effectiveRate<84) - intensity = 18; - else if (effectiveRate<102) - intensity = 19; - else if (effectiveRate<130) - intensity = 20; - else - intensity = 100; - intensity = IMIN(st->end,IMAX(st->start, intensity)); - } - - /* Bit allocation */ - ALLOC(fine_quant, st->mode->nbEBands, int); - ALLOC(pulses, st->mode->nbEBands, int); - ALLOC(fine_priority, st->mode->nbEBands, int); - - /* bits = packet size - where we are - safety*/ - bits = (((opus_int32)nbCompressedBytes*8)<=2&&bits>=((LM+2)<mode, st->start, st->end, offsets, cap, - alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses, - fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands); - st->lastCodedBands = codedBands; - - quant_fine_energy(st->mode, st->start, st->end, oldBandE, error, fine_quant, enc, C); - -#ifdef MEASURE_NORM_MSE - float X0[3000]; - float bandE0[60]; - c=0; do - for (i=0;imode->nbEBands;i++) - bandE0[i] = bandE[i]; -#endif - - /* Residual quantisation */ - ALLOC(collapse_masks, C*st->mode->nbEBands, unsigned char); - quant_all_bands(1, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks, - bandE, pulses, shortBlocks, st->spread_decision, dual_stereo, intensity, tf_res, - nbCompressedBytes*(8<rng); - - if (anti_collapse_rsv > 0) - { - anti_collapse_on = st->consec_transient<2; -#ifdef FUZZING - anti_collapse_on = rand()&0x1; -#endif - ec_enc_bits(enc, anti_collapse_on, 1); - } - quant_energy_finalise(st->mode, st->start, st->end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C); - - if (silence) - { - for (i=0;imode->nbEBands;i++) - oldBandE[i] = -QCONST16(28.f,DB_SHIFT); - } - -#ifdef RESYNTH - /* Re-synthesis of the coded audio if required */ - { - celt_sig *out_mem[2]; - celt_sig *overlap_mem[2]; - - log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C); - if (silence) - { - for (i=0;imode->nbEBands;i++) - bandE[i] = 0; - } - -#ifdef MEASURE_NORM_MSE - measure_norm_mse(st->mode, X, X0, bandE, bandE0, M, N, C); -#endif - if (anti_collapse_on) - { - anti_collapse(st->mode, X, collapse_masks, LM, C, N, - st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng); - } - - /* Synthesis */ - denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M); - - OPUS_MOVE(st->syn_mem[0], st->syn_mem[0]+N, MAX_PERIOD); - if (CC==2) - OPUS_MOVE(st->syn_mem[1], st->syn_mem[1]+N, MAX_PERIOD); - - c=0; do - for (i=0;imode->eBands[st->start];i++) - freq[c*N+i] = 0; - while (++cmode->eBands[st->end];isyn_mem[0]+MAX_PERIOD; - if (CC==2) - out_mem[1] = st->syn_mem[1]+MAX_PERIOD; - - overlap_mem[0] = prefilter_mem+CC*COMBFILTER_MAXPERIOD; - if (CC==2) - overlap_mem[1] = overlap_mem[0] + st->overlap; - - compute_inv_mdcts(st->mode, shortBlocks, freq, out_mem, overlap_mem, CC, LM); - - c=0; do { - st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); - st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD); - comb_filter(out_mem[c], out_mem[c], st->prefilter_period_old, st->prefilter_period, st->mode->shortMdctSize, - st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset, - st->mode->window, st->overlap); - if (LM!=0) - comb_filter(out_mem[c]+st->mode->shortMdctSize, out_mem[c]+st->mode->shortMdctSize, st->prefilter_period, pitch_index, N-st->mode->shortMdctSize, - st->prefilter_gain, gain1, st->prefilter_tapset, prefilter_tapset, - st->mode->window, st->mode->overlap); - } while (++cupsample, st->mode->preemph, st->preemph_memD); - st->prefilter_period_old = st->prefilter_period; - st->prefilter_gain_old = st->prefilter_gain; - st->prefilter_tapset_old = st->prefilter_tapset; - } -#endif - - st->prefilter_period = pitch_index; - st->prefilter_gain = gain1; - st->prefilter_tapset = prefilter_tapset; -#ifdef RESYNTH - if (LM!=0) - { - st->prefilter_period_old = st->prefilter_period; - st->prefilter_gain_old = st->prefilter_gain; - st->prefilter_tapset_old = st->prefilter_tapset; - } -#endif - - if (CC==2&&C==1) { - for (i=0;imode->nbEBands;i++) - oldBandE[st->mode->nbEBands+i]=oldBandE[i]; - } - - if (!isTransient) - { - for (i=0;imode->nbEBands;i++) - oldLogE2[i] = oldLogE[i]; - for (i=0;imode->nbEBands;i++) - oldLogE[i] = oldBandE[i]; - } else { - for (i=0;imode->nbEBands;i++) - oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]); - } - /* In case start or end were to change */ - c=0; do - { - for (i=0;istart;i++) - { - oldBandE[c*st->mode->nbEBands+i]=0; - oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT); - } - for (i=st->end;imode->nbEBands;i++) - { - oldBandE[c*st->mode->nbEBands+i]=0; - oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT); - } - } while (++cconsec_transient++; - else - st->consec_transient=0; - st->rng = enc->rng; - - /* If there's any room left (can only happen for very high rates), - it's already filled with zeros */ - ec_enc_done(enc); - -#ifdef CUSTOM_MODES - if (st->signalling) - nbCompressedBytes++; -#endif - - RESTORE_STACK; - if (ec_get_error(enc)) - return OPUS_INTERNAL_ERROR; - else - return nbCompressedBytes; -} - - -#ifdef CUSTOM_MODES - -#ifdef FIXED_POINT -int opus_custom_encode(CELTEncoder * restrict st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) -{ - return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL); -} - -#ifndef DISABLE_FLOAT_API -int opus_custom_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) -{ - int j, ret, C, N; - VARDECL(opus_int16, in); - ALLOC_STACK; - - if (pcm==NULL) - return OPUS_BAD_ARG; - - C = st->channels; - N = frame_size; - ALLOC(in, C*N, opus_int16); - - for (j=0;jchannels; - N=frame_size; - ALLOC(in, C*N, celt_sig); - for (j=0;j10) - goto bad_arg; - st->complexity = value; - } - break; - case CELT_SET_START_BAND_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<0 || value>=st->mode->nbEBands) - goto bad_arg; - st->start = value; - } - break; - case CELT_SET_END_BAND_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<1 || value>st->mode->nbEBands) - goto bad_arg; - st->end = value; - } - break; - case CELT_SET_PREDICTION_REQUEST: - { - int value = va_arg(ap, opus_int32); - if (value<0 || value>2) - goto bad_arg; - st->disable_pf = value<=1; - st->force_intra = value==0; - } - break; - case OPUS_SET_PACKET_LOSS_PERC_REQUEST: - { - int value = va_arg(ap, opus_int32); - if (value<0 || value>100) - goto bad_arg; - st->loss_rate = value; - } - break; - case OPUS_SET_VBR_CONSTRAINT_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->constrained_vbr = value; - } - break; - case OPUS_SET_VBR_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->vbr = value; - } - break; - case OPUS_SET_BITRATE_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<=500 && value!=OPUS_BITRATE_MAX) - goto bad_arg; - value = IMIN(value, 260000*st->channels); - st->bitrate = value; - } - break; - case CELT_SET_CHANNELS_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<1 || value>2) - goto bad_arg; - st->stream_channels = value; - } - break; - case OPUS_RESET_STATE: - { - int i; - opus_val16 *oldBandE, *oldLogE, *oldLogE2; - oldBandE = (opus_val16*)(st->in_mem+st->channels*(2*st->overlap+COMBFILTER_MAXPERIOD)); - oldLogE = oldBandE + st->channels*st->mode->nbEBands; - oldLogE2 = oldLogE + st->channels*st->mode->nbEBands; - OPUS_CLEAR((char*)&st->ENCODER_RESET_START, - opus_custom_encoder_get_size(st->mode, st->channels)- - ((char*)&st->ENCODER_RESET_START - (char*)st)); - for (i=0;ichannels*st->mode->nbEBands;i++) - oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); - st->vbr_offset = 0; - st->delayedIntra = 1; - st->spread_decision = SPREAD_NORMAL; - st->tonal_average = 256; - st->hf_average = 0; - st->tapset_decision = 0; - } - break; -#ifdef CUSTOM_MODES - case CELT_SET_INPUT_CLIPPING_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->clip = value; - } - break; -#endif - case CELT_SET_SIGNALLING_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->signalling = value; - } - break; - case CELT_GET_MODE_REQUEST: - { - const CELTMode ** value = va_arg(ap, const CELTMode**); - if (value==0) - goto bad_arg; - *value=st->mode; - } - break; - case OPUS_GET_FINAL_RANGE_REQUEST: - { - opus_uint32 * value = va_arg(ap, opus_uint32 *); - if (value==0) - goto bad_arg; - *value=st->rng; - } - break; - default: - goto bad_request; - } - va_end(ap); - return OPUS_OK; -bad_arg: - va_end(ap); - return OPUS_BAD_ARG; -bad_request: - va_end(ap); - return OPUS_UNIMPLEMENTED; -} - -/**********************************************************************/ -/* */ -/* DECODER */ -/* */ -/**********************************************************************/ -#define DECODE_BUFFER_SIZE 2048 - -/** Decoder state - @brief Decoder state - */ -struct OpusCustomDecoder { - const OpusCustomMode *mode; - int overlap; - int channels; - int stream_channels; - - int downsample; - int start, end; - int signalling; - - /* Everything beyond this point gets cleared on a reset */ -#define DECODER_RESET_START rng - - opus_uint32 rng; - int error; - int last_pitch_index; - int loss_count; - int postfilter_period; - int postfilter_period_old; - opus_val16 postfilter_gain; - opus_val16 postfilter_gain_old; - int postfilter_tapset; - int postfilter_tapset_old; - - celt_sig preemph_memD[2]; - - celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */ - /* opus_val16 lpc[], Size = channels*LPC_ORDER */ - /* opus_val16 oldEBands[], Size = 2*mode->nbEBands */ - /* opus_val16 oldLogE[], Size = 2*mode->nbEBands */ - /* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */ - /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */ -}; - -int celt_decoder_get_size(int channels) -{ - const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); - return opus_custom_decoder_get_size(mode, channels); -} - -OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_get_size(const CELTMode *mode, int channels) -{ - int size = sizeof(struct CELTDecoder) - + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig) - + channels*LPC_ORDER*sizeof(opus_val16) - + 4*2*mode->nbEBands*sizeof(opus_val16); - return size; -} - -#ifdef CUSTOM_MODES -CELTDecoder *opus_custom_decoder_create(const CELTMode *mode, int channels, int *error) -{ - int ret; - CELTDecoder *st = (CELTDecoder *)opus_alloc(opus_custom_decoder_get_size(mode, channels)); - ret = opus_custom_decoder_init(st, mode, channels); - if (ret != OPUS_OK) - { - opus_custom_decoder_destroy(st); - st = NULL; - } - if (error) - *error = ret; - return st; -} -#endif /* CUSTOM_MODES */ - -int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels) -{ - int ret; - ret = opus_custom_decoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels); - if (ret != OPUS_OK) - return ret; - st->downsample = resampling_factor(sampling_rate); - if (st->downsample==0) - return OPUS_BAD_ARG; - else - return OPUS_OK; -} - -OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels) -{ - if (channels < 0 || channels > 2) - return OPUS_BAD_ARG; - - if (st==NULL) - return OPUS_ALLOC_FAIL; - - OPUS_CLEAR((char*)st, opus_custom_decoder_get_size(mode, channels)); - - st->mode = mode; - st->overlap = mode->overlap; - st->stream_channels = st->channels = channels; - - st->downsample = 1; - st->start = 0; - st->end = st->mode->effEBands; - st->signalling = 1; - - st->loss_count = 0; - - opus_custom_decoder_ctl(st, OPUS_RESET_STATE); - - return OPUS_OK; -} - -#ifdef CUSTOM_MODES -void opus_custom_decoder_destroy(CELTDecoder *st) -{ - opus_free(st); -} -#endif /* CUSTOM_MODES */ - -static void celt_decode_lost(CELTDecoder * restrict st, opus_val16 * restrict pcm, int N, int LM) -{ - int c; - int pitch_index; - int overlap = st->mode->overlap; - opus_val16 fade = Q15ONE; - int i, len; - const int C = st->channels; - int offset; - celt_sig *out_mem[2]; - celt_sig *decode_mem[2]; - celt_sig *overlap_mem[2]; - opus_val16 *lpc; - opus_val32 *out_syn[2]; - opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE; - SAVE_STACK; - - c=0; do { - decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap); - out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD; - overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE; - } while (++c_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C); - oldBandE = lpc+C*LPC_ORDER; - oldLogE = oldBandE + 2*st->mode->nbEBands; - oldLogE2 = oldLogE + 2*st->mode->nbEBands; - backgroundLogE = oldLogE2 + 2*st->mode->nbEBands; - - out_syn[0] = out_mem[0]+MAX_PERIOD-N; - if (C==2) - out_syn[1] = out_mem[1]+MAX_PERIOD-N; - - len = N+st->mode->overlap; - - if (st->loss_count >= 5 || st->start!=0) - { - /* Noise-based PLC/CNG */ - VARDECL(celt_sig, freq); - VARDECL(celt_norm, X); - VARDECL(celt_ener, bandE); - opus_uint32 seed; - int effEnd; - - effEnd = st->end; - if (effEnd > st->mode->effEBands) - effEnd = st->mode->effEBands; - - ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */ - ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ - ALLOC(bandE, st->mode->nbEBands*C, celt_ener); - - if (st->loss_count >= 5) - log2Amp(st->mode, st->start, st->end, bandE, backgroundLogE, C); - else { - /* Energy decay */ - opus_val16 decay = st->loss_count==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT); - c=0; do - { - for (i=st->start;iend;i++) - oldBandE[c*st->mode->nbEBands+i] -= decay; - } while (++cmode, st->start, st->end, bandE, oldBandE, C); - } - seed = st->rng; - for (c=0;cmode->eBands[st->start]<start;imode->effEBands;i++) - { - int j; - int boffs; - int blen; - boffs = N*c+(st->mode->eBands[i]<mode->eBands[i+1]-st->mode->eBands[i])<>20); - } - renormalise_vector(X+boffs, blen, Q15ONE); - } - for (i=(st->mode->eBands[st->end]<rng = seed; - - denormalise_bands(st->mode, X, freq, bandE, st->mode->effEBands, C, 1<mode->eBands[st->start]<mode->eBands[effEnd]<downsample!=1) - bound = IMIN(bound, N/st->downsample); - for (i=bound;imode, 0, freq, out_syn, overlap_mem, C, LM); - } else { - /* Pitch-based PLC */ - if (st->loss_count == 0) - { - opus_val16 pitch_buf[DECODE_BUFFER_SIZE>>1]; - /* Corresponds to a min pitch of 67 Hz. It's possible to save CPU in this - search by using only part of the decode buffer */ - int poffset = 720; - pitch_downsample(decode_mem, pitch_buf, DECODE_BUFFER_SIZE, C); - /* Max pitch is 100 samples (480 Hz) */ - pitch_search(pitch_buf+((poffset)>>1), pitch_buf, DECODE_BUFFER_SIZE-poffset, - poffset-100, &pitch_index); - pitch_index = poffset-pitch_index; - st->last_pitch_index = pitch_index; - } else { - pitch_index = st->last_pitch_index; - fade = QCONST16(.8f,15); - } - - c=0; do { - VARDECL(opus_val32, e); - opus_val16 exc[MAX_PERIOD]; - opus_val32 ac[LPC_ORDER+1]; - opus_val16 decay = 1; - opus_val32 S1=0; - opus_val16 mem[LPC_ORDER]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - - ALLOC(e, MAX_PERIOD+2*st->mode->overlap, opus_val32); - - offset = MAX_PERIOD-pitch_index; - for (i=0;iloss_count == 0) - { - _celt_autocorr(exc, ac, st->mode->window, st->mode->overlap, - LPC_ORDER, MAX_PERIOD); - - /* Noise floor -40 dB */ -#ifdef FIXED_POINT - ac[0] += SHR32(ac[0],13); -#else - ac[0] *= 1.0001f; -#endif - /* Lag windowing */ - for (i=1;i<=LPC_ORDER;i++) - { - /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/ -#ifdef FIXED_POINT - ac[i] -= MULT16_32_Q15(2*i*i, ac[i]); -#else - ac[i] -= ac[i]*(.008f*i)*(.008f*i); -#endif - } - - _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER); - } - for (i=0;i E2) - E1 = E2; - decay = celt_sqrt(frac_div32(SHR(E1,1),E2)); - } - - /* Copy excitation, taking decay into account */ - for (i=0;imode->overlap;i++) - { - opus_val16 tmp; - if (offset+i >= MAX_PERIOD) - { - offset -= pitch_index; - decay = MULT16_16_Q15(decay, decay); - } - e[i] = SHL32(EXTEND32(MULT16_16_Q15(decay, exc[offset+i])), SIG_SHIFT); - tmp = ROUND16(out_mem[c][offset+i],SIG_SHIFT); - S1 += SHR32(MULT16_16(tmp,tmp),8); - } - for (i=0;imode->overlap;i++) - e[i] = MULT16_32_Q15(fade, e[i]); - celt_iir(e, lpc+c*LPC_ORDER, e, len+st->mode->overlap, LPC_ORDER, mem); - - { - opus_val32 S2=0; - for (i=0;i SHR32(S2,2))) -#else - /* Float test is written this way to catch NaNs at the same time */ - if (!(S1 > 0.2f*S2)) -#endif - { - for (i=0;ipostfilter_period, st->postfilter_period, st->overlap, - st->postfilter_gain, st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset, - NULL, 0); - - for (i=0;imode->overlap-N;i++) - out_mem[c][i] = out_mem[c][N+i]; - - /* Apply TDAC to the concealed audio so that it blends with the - previous and next frames */ - for (i=0;imode->window[i], e[N+overlap-1-i]) + - MULT16_32_Q15(st->mode->window[overlap-i-1], e[N+i ]); - out_mem[c][MAX_PERIOD+i] = MULT16_32_Q15(st->mode->window[overlap-i-1], tmp); - out_mem[c][MAX_PERIOD+overlap-i-1] = MULT16_32_Q15(st->mode->window[i], tmp); - } - for (i=0;ipostfilter_period, st->postfilter_period, st->overlap, - -st->postfilter_gain, -st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset, - NULL, 0); - for (i=0;idownsample, st->mode->preemph, st->preemph_memD); - - st->loss_count++; - - RESTORE_STACK; -} - -int celt_decode_with_ec(CELTDecoder * restrict st, const unsigned char *data, int len, opus_val16 * restrict pcm, int frame_size, ec_dec *dec) -{ - int c, i, N; - int spread_decision; - opus_int32 bits; - ec_dec _dec; - VARDECL(celt_sig, freq); - VARDECL(celt_norm, X); - VARDECL(celt_ener, bandE); - VARDECL(int, fine_quant); - VARDECL(int, pulses); - VARDECL(int, cap); - VARDECL(int, offsets); - VARDECL(int, fine_priority); - VARDECL(int, tf_res); - VARDECL(unsigned char, collapse_masks); - celt_sig *out_mem[2]; - celt_sig *decode_mem[2]; - celt_sig *overlap_mem[2]; - celt_sig *out_syn[2]; - opus_val16 *lpc; - opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE; - - int shortBlocks; - int isTransient; - int intra_ener; - const int CC = st->channels; - int LM, M; - int effEnd; - int codedBands; - int alloc_trim; - int postfilter_pitch; - opus_val16 postfilter_gain; - int intensity=0; - int dual_stereo=0; - opus_int32 total_bits; - opus_int32 balance; - opus_int32 tell; - int dynalloc_logp; - int postfilter_tapset; - int anti_collapse_rsv; - int anti_collapse_on=0; - int silence; - int C = st->stream_channels; - ALLOC_STACK; - - frame_size *= st->downsample; - - c=0; do { - decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap); - out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD; - overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE; - } while (++c_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*CC); - oldBandE = lpc+CC*LPC_ORDER; - oldLogE = oldBandE + 2*st->mode->nbEBands; - oldLogE2 = oldLogE + 2*st->mode->nbEBands; - backgroundLogE = oldLogE2 + 2*st->mode->nbEBands; - -#ifdef CUSTOM_MODES - if (st->signalling && data!=NULL) - { - int data0=data[0]; - /* Convert "standard mode" to Opus header */ - if (st->mode->Fs==48000 && st->mode->shortMdctSize==120) - { - data0 = fromOpus(data0); - if (data0<0) - return OPUS_INVALID_PACKET; - } - st->end = IMAX(1, st->mode->effEBands-2*(data0>>5)); - LM = (data0>>3)&0x3; - C = 1 + ((data0>>2)&0x1); - data++; - len--; - if (LM>st->mode->maxLM) - return OPUS_INVALID_PACKET; - if (frame_size < st->mode->shortMdctSize<mode->shortMdctSize<mode->maxLM;LM++) - if (st->mode->shortMdctSize<st->mode->maxLM) - return OPUS_BAD_ARG; - } - M=1<1275 || pcm==NULL) - return OPUS_BAD_ARG; - - N = M*st->mode->shortMdctSize; - - effEnd = st->end; - if (effEnd > st->mode->effEBands) - effEnd = st->mode->effEBands; - - ALLOC(freq, IMAX(CC,C)*N, celt_sig); /**< Interleaved signal MDCTs */ - ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ - ALLOC(bandE, st->mode->nbEBands*C, celt_ener); - c=0; do - for (i=0;imode->eBands[st->start];i++) - X[c*N+i] = 0; - while (++cmode->eBands[effEnd];idownsample; - } - - if (dec == NULL) - { - ec_dec_init(&_dec,(unsigned char*)data,len); - dec = &_dec; - } - - if (C==1) - { - for (i=0;imode->nbEBands;i++) - oldBandE[i]=MAX16(oldBandE[i],oldBandE[st->mode->nbEBands+i]); - } - - total_bits = len*8; - tell = ec_tell(dec); - - if (tell >= total_bits) - silence = 1; - else if (tell==1) - silence = ec_dec_bit_logp(dec, 15); - else - silence = 0; - if (silence) - { - /* Pretend we've read all the remaining bits */ - tell = len*8; - dec->nbits_total+=tell-ec_tell(dec); - } - - postfilter_gain = 0; - postfilter_pitch = 0; - postfilter_tapset = 0; - if (st->start==0 && tell+16 <= total_bits) - { - if(ec_dec_bit_logp(dec, 1)) - { - int qg, octave; - octave = ec_dec_uint(dec, 6); - postfilter_pitch = (16< 0 && tell+3 <= total_bits) - { - isTransient = ec_dec_bit_logp(dec, 3); - tell = ec_tell(dec); - } - else - isTransient = 0; - - if (isTransient) - shortBlocks = M; - else - shortBlocks = 0; - - /* Decode the global flags (first symbols in the stream) */ - intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0; - /* Get band energies */ - unquant_coarse_energy(st->mode, st->start, st->end, oldBandE, - intra_ener, dec, C, LM); - - ALLOC(tf_res, st->mode->nbEBands, int); - tf_decode(st->start, st->end, isTransient, tf_res, LM, dec); - - tell = ec_tell(dec); - spread_decision = SPREAD_NORMAL; - if (tell+4 <= total_bits) - spread_decision = ec_dec_icdf(dec, spread_icdf, 5); - - ALLOC(pulses, st->mode->nbEBands, int); - ALLOC(cap, st->mode->nbEBands, int); - ALLOC(offsets, st->mode->nbEBands, int); - ALLOC(fine_priority, st->mode->nbEBands, int); - - init_caps(st->mode,cap,LM,C); - - dynalloc_logp = 6; - total_bits<<=BITRES; - tell = ec_tell_frac(dec); - for (i=st->start;iend;i++) - { - int width, quanta; - int dynalloc_loop_logp; - int boost; - width = C*(st->mode->eBands[i+1]-st->mode->eBands[i])<0) - dynalloc_logp = IMAX(2, dynalloc_logp-1); - } - - ALLOC(fine_quant, st->mode->nbEBands, int); - alloc_trim = tell+(6<=2&&bits>=((LM+2)<mode, st->start, st->end, offsets, cap, - alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses, - fine_quant, fine_priority, C, LM, dec, 0, 0); - - unquant_fine_energy(st->mode, st->start, st->end, oldBandE, fine_quant, dec, C); - - /* Decode fixed codebook */ - ALLOC(collapse_masks, C*st->mode->nbEBands, unsigned char); - quant_all_bands(0, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks, - NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res, - len*(8<rng); - - if (anti_collapse_rsv > 0) - { - anti_collapse_on = ec_dec_bits(dec, 1); - } - - unquant_energy_finalise(st->mode, st->start, st->end, oldBandE, - fine_quant, fine_priority, len*8-ec_tell(dec), dec, C); - - if (anti_collapse_on) - anti_collapse(st->mode, X, collapse_masks, LM, C, N, - st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng); - - log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C); - - if (silence) - { - for (i=0;imode->nbEBands;i++) - { - bandE[i] = 0; - oldBandE[i] = -QCONST16(28.f,DB_SHIFT); - } - } - /* Synthesis */ - denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M); - - OPUS_MOVE(decode_mem[0], decode_mem[0]+N, DECODE_BUFFER_SIZE-N); - if (CC==2) - OPUS_MOVE(decode_mem[1], decode_mem[1]+N, DECODE_BUFFER_SIZE-N); - - c=0; do - for (i=0;imode->eBands[st->start];i++) - freq[c*N+i] = 0; - while (++cmode->eBands[effEnd]; - if (st->downsample!=1) - bound = IMIN(bound, N/st->downsample); - for (i=bound;imode, shortBlocks, freq, out_syn, overlap_mem, CC, LM); - - c=0; do { - st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD); - st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD); - comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, st->mode->shortMdctSize, - st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset, - st->mode->window, st->overlap); - if (LM!=0) - comb_filter(out_syn[c]+st->mode->shortMdctSize, out_syn[c]+st->mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-st->mode->shortMdctSize, - st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset, - st->mode->window, st->mode->overlap); - - } while (++cpostfilter_period_old = st->postfilter_period; - st->postfilter_gain_old = st->postfilter_gain; - st->postfilter_tapset_old = st->postfilter_tapset; - st->postfilter_period = postfilter_pitch; - st->postfilter_gain = postfilter_gain; - st->postfilter_tapset = postfilter_tapset; - if (LM!=0) - { - st->postfilter_period_old = st->postfilter_period; - st->postfilter_gain_old = st->postfilter_gain; - st->postfilter_tapset_old = st->postfilter_tapset; - } - - if (C==1) { - for (i=0;imode->nbEBands;i++) - oldBandE[st->mode->nbEBands+i]=oldBandE[i]; - } - - /* In case start or end were to change */ - if (!isTransient) - { - for (i=0;i<2*st->mode->nbEBands;i++) - oldLogE2[i] = oldLogE[i]; - for (i=0;i<2*st->mode->nbEBands;i++) - oldLogE[i] = oldBandE[i]; - for (i=0;i<2*st->mode->nbEBands;i++) - backgroundLogE[i] = MIN16(backgroundLogE[i] + M*QCONST16(0.001f,DB_SHIFT), oldBandE[i]); - } else { - for (i=0;i<2*st->mode->nbEBands;i++) - oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]); - } - c=0; do - { - for (i=0;istart;i++) - { - oldBandE[c*st->mode->nbEBands+i]=0; - oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT); - } - for (i=st->end;imode->nbEBands;i++) - { - oldBandE[c*st->mode->nbEBands+i]=0; - oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT); - } - } while (++c<2); - st->rng = dec->rng; - - deemphasis(out_syn, pcm, N, CC, st->downsample, st->mode->preemph, st->preemph_memD); - st->loss_count = 0; - RESTORE_STACK; - if (ec_tell(dec) > 8*len) - return OPUS_INTERNAL_ERROR; - if(ec_get_error(dec)) - st->error = 1; - return frame_size/st->downsample; -} - - -#ifdef CUSTOM_MODES - -#ifdef FIXED_POINT -int opus_custom_decode(CELTDecoder * restrict st, const unsigned char *data, int len, opus_int16 * restrict pcm, int frame_size) -{ - return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL); -} - -#ifndef DISABLE_FLOAT_API -int opus_custom_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size) -{ - int j, ret, C, N; - VARDECL(opus_int16, out); - ALLOC_STACK; - - if (pcm==NULL) - return OPUS_BAD_ARG; - - C = st->channels; - N = frame_size; - - ALLOC(out, C*N, opus_int16); - ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL); - if (ret>0) - for (j=0;jchannels; - N = frame_size; - ALLOC(out, C*N, celt_sig); - - ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL); - - if (ret>0) - for (j=0;j=st->mode->nbEBands) - goto bad_arg; - st->start = value; - } - break; - case CELT_SET_END_BAND_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<1 || value>st->mode->nbEBands) - goto bad_arg; - st->end = value; - } - break; - case CELT_SET_CHANNELS_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<1 || value>2) - goto bad_arg; - st->stream_channels = value; - } - break; - case CELT_GET_AND_CLEAR_ERROR_REQUEST: - { - int *value = va_arg(ap, opus_int32*); - if (value==NULL) - goto bad_arg; - *value=st->error; - st->error = 0; - } - break; - case OPUS_GET_LOOKAHEAD_REQUEST: - { - int *value = va_arg(ap, opus_int32*); - if (value==NULL) - goto bad_arg; - *value = st->overlap/st->downsample; - } - break; - case OPUS_RESET_STATE: - { - int i; - opus_val16 *lpc, *oldBandE, *oldLogE, *oldLogE2; - lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels); - oldBandE = lpc+st->channels*LPC_ORDER; - oldLogE = oldBandE + 2*st->mode->nbEBands; - oldLogE2 = oldLogE + 2*st->mode->nbEBands; - OPUS_CLEAR((char*)&st->DECODER_RESET_START, - opus_custom_decoder_get_size(st->mode, st->channels)- - ((char*)&st->DECODER_RESET_START - (char*)st)); - for (i=0;i<2*st->mode->nbEBands;i++) - oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); - } - break; - case OPUS_GET_PITCH_REQUEST: - { - int *value = va_arg(ap, opus_int32*); - if (value==NULL) - goto bad_arg; - *value = st->postfilter_period; - } - break; -#ifdef OPUS_BUILD - case CELT_GET_MODE_REQUEST: - { - const CELTMode ** value = va_arg(ap, const CELTMode**); - if (value==0) - goto bad_arg; - *value=st->mode; - } - break; - case CELT_SET_SIGNALLING_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->signalling = value; - } - break; - case OPUS_GET_FINAL_RANGE_REQUEST: - { - opus_uint32 * value = va_arg(ap, opus_uint32 *); - if (value==0) - goto bad_arg; - *value=st->rng; - } - break; -#endif - default: - goto bad_request; - } - va_end(ap); - return OPUS_OK; -bad_arg: - va_end(ap); - return OPUS_BAD_ARG; -bad_request: - va_end(ap); - return OPUS_UNIMPLEMENTED; -} - const char *opus_strerror(int error) { - static const char *error_strings[8] = { + static const char * const error_strings[8] = { "success", "invalid argument", "buffer too small", @@ -2847,7 +212,10 @@ const char *opus_strerror(int error) const char *opus_get_version_string(void) { - return "libopus " OPUS_VERSION + return "libopus " PACKAGE_VERSION +#ifdef FIXED_POINT + "-fixed" +#endif #ifdef FUZZING "-fuzzing" #endif diff --git a/media/libopus/celt/celt.h b/media/libopus/celt/celt.h index 54372750dec0..0911c72f7210 100644 --- a/media/libopus/celt/celt.h +++ b/media/libopus/celt/celt.h @@ -1,5 +1,6 @@ -/* Copyright (c) 2007-2012 IETF Trust, CSIRO, Xiph.Org Foundation, - Gregory Maxwell. All rights reserved. +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2008 Gregory Maxwell Written by Jean-Marc Valin and Gregory Maxwell */ /** @file celt.h @@ -7,10 +8,6 @@ */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -22,11 +19,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -58,7 +50,19 @@ extern "C" { #define CELTDecoder OpusCustomDecoder #define CELTMode OpusCustomMode -#define _celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr))) +typedef struct { + int valid; + opus_val16 tonality; + opus_val16 tonality_slope; + opus_val16 noisiness; + opus_val16 activity; + opus_val16 music_prob; + int bandwidth; +}AnalysisInfo; + +#define __celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr))) + +#define __celt_check_analysis_ptr(ptr) ((ptr) + ((ptr) - (const AnalysisInfo*)(ptr))) /* Encoder/decoder Requests */ @@ -89,18 +93,33 @@ extern "C" { #define CELT_GET_MODE_REQUEST 10015 /** Get the CELTMode used by an encoder or decoder */ -#define CELT_GET_MODE(x) CELT_GET_MODE_REQUEST, _celt_check_mode_ptr_ptr(x) +#define CELT_GET_MODE(x) CELT_GET_MODE_REQUEST, __celt_check_mode_ptr_ptr(x) #define CELT_SET_SIGNALLING_REQUEST 10016 #define CELT_SET_SIGNALLING(x) CELT_SET_SIGNALLING_REQUEST, __opus_check_int(x) +#define CELT_SET_TONALITY_REQUEST 10018 +#define CELT_SET_TONALITY(x) CELT_SET_TONALITY_REQUEST, __opus_check_int(x) +#define CELT_SET_TONALITY_SLOPE_REQUEST 10020 +#define CELT_SET_TONALITY_SLOPE(x) CELT_SET_TONALITY_SLOPE_REQUEST, __opus_check_int(x) +#define CELT_SET_ANALYSIS_REQUEST 10022 +#define CELT_SET_ANALYSIS(x) CELT_SET_ANALYSIS_REQUEST, __celt_check_analysis_ptr(x) + +#define OPUS_SET_LFE_REQUEST 10024 +#define OPUS_SET_LFE(x) OPUS_SET_LFE_REQUEST, __opus_check_int(x) + +#define OPUS_SET_ENERGY_SAVE_REQUEST 10026 +#define OPUS_SET_ENERGY_SAVE(x) OPUS_SET_ENERGY_SAVE_REQUEST, __opus_check_val16_ptr(x) + +#define OPUS_SET_ENERGY_MASK_REQUEST 10028 +#define OPUS_SET_ENERGY_MASK(x) OPUS_SET_ENERGY_MASK_REQUEST, __opus_check_val16_ptr(x) /* Encoder stuff */ int celt_encoder_get_size(int channels); -int celt_encode_with_ec(OpusCustomEncoder * restrict st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc); +int celt_encode_with_ec(OpusCustomEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc); int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels); @@ -113,11 +132,80 @@ int celt_decoder_get_size(int channels); int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels); -int celt_decode_with_ec(OpusCustomDecoder * restrict st, const unsigned char *data, int len, opus_val16 * restrict pcm, int frame_size, ec_dec *dec); +int celt_decode_with_ec(OpusCustomDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec); #define celt_encoder_ctl opus_custom_encoder_ctl #define celt_decoder_ctl opus_custom_decoder_ctl + +#ifdef CUSTOM_MODES +#define OPUS_CUSTOM_NOSTATIC +#else +#define OPUS_CUSTOM_NOSTATIC static inline +#endif + +static const unsigned char trim_icdf[11] = {126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0}; +/* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */ +static const unsigned char spread_icdf[4] = {25, 23, 2, 0}; + +static const unsigned char tapset_icdf[3]={2,1,0}; + +#ifdef CUSTOM_MODES +static const unsigned char toOpusTable[20] = { + 0xE0, 0xE8, 0xF0, 0xF8, + 0xC0, 0xC8, 0xD0, 0xD8, + 0xA0, 0xA8, 0xB0, 0xB8, + 0x00, 0x00, 0x00, 0x00, + 0x80, 0x88, 0x90, 0x98, +}; + +static const unsigned char fromOpusTable[16] = { + 0x80, 0x88, 0x90, 0x98, + 0x40, 0x48, 0x50, 0x58, + 0x20, 0x28, 0x30, 0x38, + 0x00, 0x08, 0x10, 0x18 +}; + +static inline int toOpus(unsigned char c) +{ + int ret=0; + if (c<0xA0) + ret = toOpusTable[c>>3]; + if (ret == 0) + return -1; + else + return ret|(c&0x7); +} + +static inline int fromOpus(unsigned char c) +{ + if (c<0x80) + return -1; + else + return fromOpusTable[(c>>3)-16] | (c&0x7); +} +#endif /* CUSTOM_MODES */ + +#define COMBFILTER_MAXPERIOD 1024 +#define COMBFILTER_MINPERIOD 15 + +extern const signed char tf_select_table[4][8]; + +int resampling_factor(opus_int32 rate); + +void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N, + opus_val16 g0, opus_val16 g1, int tapset0, int tapset1, + const opus_val16 *window, int overlap); + +void init_caps(const CELTMode *m,int *cap,int LM,int C); + +#ifdef RESYNTH +void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem, celt_sig * OPUS_RESTRICT scratch); + +void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig *X, + celt_sig * OPUS_RESTRICT out_mem[], int C, int LM); +#endif + #ifdef __cplusplus } #endif diff --git a/media/libopus/celt/celt_decoder.c b/media/libopus/celt/celt_decoder.c new file mode 100644 index 000000000000..4424b9709878 --- /dev/null +++ b/media/libopus/celt/celt_decoder.c @@ -0,0 +1,1195 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2010 Xiph.Org Foundation + Copyright (c) 2008 Gregory Maxwell + Written by Jean-Marc Valin and Gregory Maxwell */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define CELT_DECODER_C + +#include "cpu_support.h" +#include "os_support.h" +#include "mdct.h" +#include +#include "celt.h" +#include "pitch.h" +#include "bands.h" +#include "modes.h" +#include "entcode.h" +#include "quant_bands.h" +#include "rate.h" +#include "stack_alloc.h" +#include "mathops.h" +#include "float_cast.h" +#include +#include "celt_lpc.h" +#include "vq.h" + +/**********************************************************************/ +/* */ +/* DECODER */ +/* */ +/**********************************************************************/ +#define DECODE_BUFFER_SIZE 2048 + +/** Decoder state + @brief Decoder state + */ +struct OpusCustomDecoder { + const OpusCustomMode *mode; + int overlap; + int channels; + int stream_channels; + + int downsample; + int start, end; + int signalling; + int arch; + + /* Everything beyond this point gets cleared on a reset */ +#define DECODER_RESET_START rng + + opus_uint32 rng; + int error; + int last_pitch_index; + int loss_count; + int postfilter_period; + int postfilter_period_old; + opus_val16 postfilter_gain; + opus_val16 postfilter_gain_old; + int postfilter_tapset; + int postfilter_tapset_old; + + celt_sig preemph_memD[2]; + + celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */ + /* opus_val16 lpc[], Size = channels*LPC_ORDER */ + /* opus_val16 oldEBands[], Size = 2*mode->nbEBands */ + /* opus_val16 oldLogE[], Size = 2*mode->nbEBands */ + /* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */ + /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */ +}; + +int celt_decoder_get_size(int channels) +{ + const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); + return opus_custom_decoder_get_size(mode, channels); +} + +OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_get_size(const CELTMode *mode, int channels) +{ + int size = sizeof(struct CELTDecoder) + + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig) + + channels*LPC_ORDER*sizeof(opus_val16) + + 4*2*mode->nbEBands*sizeof(opus_val16); + return size; +} + +#ifdef CUSTOM_MODES +CELTDecoder *opus_custom_decoder_create(const CELTMode *mode, int channels, int *error) +{ + int ret; + CELTDecoder *st = (CELTDecoder *)opus_alloc(opus_custom_decoder_get_size(mode, channels)); + ret = opus_custom_decoder_init(st, mode, channels); + if (ret != OPUS_OK) + { + opus_custom_decoder_destroy(st); + st = NULL; + } + if (error) + *error = ret; + return st; +} +#endif /* CUSTOM_MODES */ + +int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels) +{ + int ret; + ret = opus_custom_decoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels); + if (ret != OPUS_OK) + return ret; + st->downsample = resampling_factor(sampling_rate); + if (st->downsample==0) + return OPUS_BAD_ARG; + else + return OPUS_OK; +} + +OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels) +{ + if (channels < 0 || channels > 2) + return OPUS_BAD_ARG; + + if (st==NULL) + return OPUS_ALLOC_FAIL; + + OPUS_CLEAR((char*)st, opus_custom_decoder_get_size(mode, channels)); + + st->mode = mode; + st->overlap = mode->overlap; + st->stream_channels = st->channels = channels; + + st->downsample = 1; + st->start = 0; + st->end = st->mode->effEBands; + st->signalling = 1; + st->arch = opus_select_arch(); + + st->loss_count = 0; + + opus_custom_decoder_ctl(st, OPUS_RESET_STATE); + + return OPUS_OK; +} + +#ifdef CUSTOM_MODES +void opus_custom_decoder_destroy(CELTDecoder *st) +{ + opus_free(st); +} +#endif /* CUSTOM_MODES */ + +static inline opus_val16 SIG2WORD16(celt_sig x) +{ +#ifdef FIXED_POINT + x = PSHR32(x, SIG_SHIFT); + x = MAX32(x, -32768); + x = MIN32(x, 32767); + return EXTRACT16(x); +#else + return (opus_val16)x; +#endif +} + +#ifndef RESYNTH +static +#endif +void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem, celt_sig * OPUS_RESTRICT scratch) +{ + int c; + int Nd; + int apply_downsampling=0; + opus_val16 coef0; + + coef0 = coef[0]; + Nd = N/downsample; + c=0; do { + int j; + celt_sig * OPUS_RESTRICT x; + opus_val16 * OPUS_RESTRICT y; + celt_sig m = mem[c]; + x =in[c]; + y = pcm+c; +#ifdef CUSTOM_MODES + if (coef[1] != 0) + { + opus_val16 coef1 = coef[1]; + opus_val16 coef3 = coef[3]; + for (j=0;j1) + { + /* Shortcut for the standard (non-custom modes) case */ + for (j=0;jshortMdctSize; + shift = mode->maxLM; + } else { + B = 1; + N = mode->shortMdctSize<maxLM-LM; + } + c=0; do { + /* IMDCT on the interleaved the sub-frames, overlap-add is performed by the IMDCT */ + for (b=0;bmdct, &X[b+c*N*B], out_mem[c]+N*b, mode->window, overlap, shift, B); + } while (++cstorage*8; + tell = ec_tell(dec); + logp = isTransient ? 2 : 4; + tf_select_rsv = LM>0 && tell+logp+1<=budget; + budget -= tf_select_rsv; + tf_changed = curr = 0; + for (i=start;ichannels; + celt_sig *decode_mem[2]; + celt_sig *out_syn[2]; + opus_val16 *lpc; + opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE; + const OpusCustomMode *mode; + int nbEBands; + int overlap; + int start; + int downsample; + int loss_count; + int noise_based; + const opus_int16 *eBands; + VARDECL(celt_sig, scratch); + SAVE_STACK; + + mode = st->mode; + nbEBands = mode->nbEBands; + overlap = mode->overlap; + eBands = mode->eBands; + + c=0; do { + decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap); + out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N; + } while (++c_decode_mem+(DECODE_BUFFER_SIZE+overlap)*C); + oldBandE = lpc+C*LPC_ORDER; + oldLogE = oldBandE + 2*nbEBands; + oldLogE2 = oldLogE + 2*nbEBands; + backgroundLogE = oldLogE2 + 2*nbEBands; + + loss_count = st->loss_count; + start = st->start; + downsample = st->downsample; + noise_based = loss_count >= 5 || start != 0; + ALLOC(scratch, noise_based?N*C:N, celt_sig); + if (noise_based) + { + /* Noise-based PLC/CNG */ + celt_sig *freq; + VARDECL(celt_norm, X); + opus_uint32 seed; + opus_val16 *plcLogE; + int end; + int effEnd; + + end = st->end; + effEnd = IMAX(start, IMIN(end, mode->effEBands)); + + /* Share the interleaved signal MDCT coefficient buffer with the + deemphasis scratch buffer. */ + freq = scratch; + ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ + + if (loss_count >= 5) + plcLogE = backgroundLogE; + else { + /* Energy decay */ + opus_val16 decay = loss_count==0 ? + QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT); + c=0; do + { + for (i=start;irng; + for (c=0;c>20); + } + renormalise_vector(X+boffs, blen, Q15ONE); + } + } + st->rng = seed; + + denormalise_bands(mode, X, freq, plcLogE, start, effEnd, C, 1<>1)); + } while (++c>1, opus_val16 ); + pitch_downsample(decode_mem, lp_pitch_buf, DECODE_BUFFER_SIZE, C); + pitch_search(lp_pitch_buf+(PLC_PITCH_LAG_MAX>>1), lp_pitch_buf, + DECODE_BUFFER_SIZE-PLC_PITCH_LAG_MAX, + PLC_PITCH_LAG_MAX-PLC_PITCH_LAG_MIN, &pitch_index); + pitch_index = PLC_PITCH_LAG_MAX-pitch_index; + st->last_pitch_index = pitch_index; + } else { + pitch_index = st->last_pitch_index; + fade = QCONST16(.8f,15); + } + + ALLOC(etmp, overlap, opus_val32); + ALLOC(exc, MAX_PERIOD, opus_val16); + window = mode->window; + c=0; do { + opus_val16 decay; + opus_val16 attenuation; + opus_val32 S1=0; + celt_sig *buf; + int extrapolation_offset; + int extrapolation_len; + int exc_length; + int j; + + buf = decode_mem[c]; + for (i=0;i>1; + for (i=0;i= pitch_index) { + j -= pitch_index; + attenuation = MULT16_16_Q15(attenuation, decay); + } + buf[DECODE_BUFFER_SIZE-N+i] = + SHL32(EXTEND32(MULT16_16_Q15(attenuation, + exc[extrapolation_offset+j])), SIG_SHIFT); + /* Compute the energy of the previously decoded signal whose + excitation we're copying. */ + tmp = ROUND16( + buf[DECODE_BUFFER_SIZE-MAX_PERIOD-N+extrapolation_offset+j], + SIG_SHIFT); + S1 += SHR32(MULT16_16(tmp, tmp), 8); + } + + { + opus_val16 lpc_mem[LPC_ORDER]; + /* Copy the last decoded samples (prior to the overlap region) to + synthesis filter memory so we can have a continuous signal. */ + for (i=0;i SHR32(S2,2))) +#else + /* The float test is written this way to catch NaNs in the output + of the IIR filter at the same time. */ + if (!(S1 > 0.2f*S2)) +#endif + { + for (i=0;ipostfilter_period, st->postfilter_period, overlap, + -st->postfilter_gain, -st->postfilter_gain, + st->postfilter_tapset, st->postfilter_tapset, NULL, 0); + + /* Simulate TDAC on the concealed audio so that it blends with the + MDCT of the next frame. */ + for (i=0;ipreemph, st->preemph_memD, scratch); + + st->loss_count = loss_count+1; + + RESTORE_STACK; +} + +int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec) +{ + int c, i, N; + int spread_decision; + opus_int32 bits; + ec_dec _dec; + VARDECL(celt_sig, freq); + VARDECL(celt_norm, X); + VARDECL(int, fine_quant); + VARDECL(int, pulses); + VARDECL(int, cap); + VARDECL(int, offsets); + VARDECL(int, fine_priority); + VARDECL(int, tf_res); + VARDECL(unsigned char, collapse_masks); + celt_sig *out_mem[2]; + celt_sig *decode_mem[2]; + celt_sig *out_syn[2]; + opus_val16 *lpc; + opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE; + + int shortBlocks; + int isTransient; + int intra_ener; + const int CC = st->channels; + int LM, M; + int effEnd; + int codedBands; + int alloc_trim; + int postfilter_pitch; + opus_val16 postfilter_gain; + int intensity=0; + int dual_stereo=0; + opus_int32 total_bits; + opus_int32 balance; + opus_int32 tell; + int dynalloc_logp; + int postfilter_tapset; + int anti_collapse_rsv; + int anti_collapse_on=0; + int silence; + int C = st->stream_channels; + const OpusCustomMode *mode; + int nbEBands; + int overlap; + const opus_int16 *eBands; + ALLOC_STACK; + + mode = st->mode; + nbEBands = mode->nbEBands; + overlap = mode->overlap; + eBands = mode->eBands; + frame_size *= st->downsample; + + c=0; do { + decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap); + out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD; + } while (++c_decode_mem+(DECODE_BUFFER_SIZE+overlap)*CC); + oldBandE = lpc+CC*LPC_ORDER; + oldLogE = oldBandE + 2*nbEBands; + oldLogE2 = oldLogE + 2*nbEBands; + backgroundLogE = oldLogE2 + 2*nbEBands; + +#ifdef CUSTOM_MODES + if (st->signalling && data!=NULL) + { + int data0=data[0]; + /* Convert "standard mode" to Opus header */ + if (mode->Fs==48000 && mode->shortMdctSize==120) + { + data0 = fromOpus(data0); + if (data0<0) + return OPUS_INVALID_PACKET; + } + st->end = IMAX(1, mode->effEBands-2*(data0>>5)); + LM = (data0>>3)&0x3; + C = 1 + ((data0>>2)&0x1); + data++; + len--; + if (LM>mode->maxLM) + return OPUS_INVALID_PACKET; + if (frame_size < mode->shortMdctSize<shortMdctSize<maxLM;LM++) + if (mode->shortMdctSize<mode->maxLM) + return OPUS_BAD_ARG; + } + M=1<1275 || pcm==NULL) + return OPUS_BAD_ARG; + + N = M*mode->shortMdctSize; + + effEnd = st->end; + if (effEnd > mode->effEBands) + effEnd = mode->effEBands; + + if (data == NULL || len<=1) + { + celt_decode_lost(st, pcm, N, LM); + RESTORE_STACK; + return frame_size/st->downsample; + } + + if (dec == NULL) + { + ec_dec_init(&_dec,(unsigned char*)data,len); + dec = &_dec; + } + + if (C==1) + { + for (i=0;i= total_bits) + silence = 1; + else if (tell==1) + silence = ec_dec_bit_logp(dec, 15); + else + silence = 0; + if (silence) + { + /* Pretend we've read all the remaining bits */ + tell = len*8; + dec->nbits_total+=tell-ec_tell(dec); + } + + postfilter_gain = 0; + postfilter_pitch = 0; + postfilter_tapset = 0; + if (st->start==0 && tell+16 <= total_bits) + { + if(ec_dec_bit_logp(dec, 1)) + { + int qg, octave; + octave = ec_dec_uint(dec, 6); + postfilter_pitch = (16< 0 && tell+3 <= total_bits) + { + isTransient = ec_dec_bit_logp(dec, 3); + tell = ec_tell(dec); + } + else + isTransient = 0; + + if (isTransient) + shortBlocks = M; + else + shortBlocks = 0; + + /* Decode the global flags (first symbols in the stream) */ + intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0; + /* Get band energies */ + unquant_coarse_energy(mode, st->start, st->end, oldBandE, + intra_ener, dec, C, LM); + + ALLOC(tf_res, nbEBands, int); + tf_decode(st->start, st->end, isTransient, tf_res, LM, dec); + + tell = ec_tell(dec); + spread_decision = SPREAD_NORMAL; + if (tell+4 <= total_bits) + spread_decision = ec_dec_icdf(dec, spread_icdf, 5); + + ALLOC(cap, nbEBands, int); + + init_caps(mode,cap,LM,C); + + ALLOC(offsets, nbEBands, int); + + dynalloc_logp = 6; + total_bits<<=BITRES; + tell = ec_tell_frac(dec); + for (i=st->start;iend;i++) + { + int width, quanta; + int dynalloc_loop_logp; + int boost; + width = C*(eBands[i+1]-eBands[i])<0) + dynalloc_logp = IMAX(2, dynalloc_logp-1); + } + + ALLOC(fine_quant, nbEBands, int); + alloc_trim = tell+(6<=2&&bits>=((LM+2)<start, st->end, offsets, cap, + alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses, + fine_quant, fine_priority, C, LM, dec, 0, 0, 0); + + unquant_fine_energy(mode, st->start, st->end, oldBandE, fine_quant, dec, C); + + /* Decode fixed codebook */ + ALLOC(collapse_masks, C*nbEBands, unsigned char); + ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ + + quant_all_bands(0, mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks, + NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res, + len*(8<rng); + + if (anti_collapse_rsv > 0) + { + anti_collapse_on = ec_dec_bits(dec, 1); + } + + unquant_energy_finalise(mode, st->start, st->end, oldBandE, + fine_quant, fine_priority, len*8-ec_tell(dec), dec, C); + + if (anti_collapse_on) + anti_collapse(mode, X, collapse_masks, LM, C, N, + st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng); + + ALLOC(freq, IMAX(CC,C)*N, celt_sig); /**< Interleaved signal MDCTs */ + + if (silence) + { + for (i=0;istart, effEnd, C, M); + } + c=0; do { + OPUS_MOVE(decode_mem[c], decode_mem[c]+N, DECODE_BUFFER_SIZE-N+overlap/2); + } while (++cdownsample!=1) + bound = IMIN(bound, N/st->downsample); + for (i=bound;ipostfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD); + st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD); + comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, mode->shortMdctSize, + st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset, + mode->window, overlap); + if (LM!=0) + comb_filter(out_syn[c]+mode->shortMdctSize, out_syn[c]+mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-mode->shortMdctSize, + st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset, + mode->window, overlap); + + } while (++cpostfilter_period_old = st->postfilter_period; + st->postfilter_gain_old = st->postfilter_gain; + st->postfilter_tapset_old = st->postfilter_tapset; + st->postfilter_period = postfilter_pitch; + st->postfilter_gain = postfilter_gain; + st->postfilter_tapset = postfilter_tapset; + if (LM!=0) + { + st->postfilter_period_old = st->postfilter_period; + st->postfilter_gain_old = st->postfilter_gain; + st->postfilter_tapset_old = st->postfilter_tapset; + } + + if (C==1) { + for (i=0;istart;i++) + { + oldBandE[c*nbEBands+i]=0; + oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT); + } + for (i=st->end;irng = dec->rng; + + /* We reuse freq[] as scratch space for the de-emphasis */ + deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, freq); + st->loss_count = 0; + RESTORE_STACK; + if (ec_tell(dec) > 8*len) + return OPUS_INTERNAL_ERROR; + if(ec_get_error(dec)) + st->error = 1; + return frame_size/st->downsample; +} + + +#ifdef CUSTOM_MODES + +#ifdef FIXED_POINT +int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size) +{ + return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL); +} + +#ifndef DISABLE_FLOAT_API +int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size) +{ + int j, ret, C, N; + VARDECL(opus_int16, out); + ALLOC_STACK; + + if (pcm==NULL) + return OPUS_BAD_ARG; + + C = st->channels; + N = frame_size; + + ALLOC(out, C*N, opus_int16); + ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL); + if (ret>0) + for (j=0;jchannels; + N = frame_size; + ALLOC(out, C*N, celt_sig); + + ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL); + + if (ret>0) + for (j=0;j=st->mode->nbEBands) + goto bad_arg; + st->start = value; + } + break; + case CELT_SET_END_BAND_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<1 || value>st->mode->nbEBands) + goto bad_arg; + st->end = value; + } + break; + case CELT_SET_CHANNELS_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<1 || value>2) + goto bad_arg; + st->stream_channels = value; + } + break; + case CELT_GET_AND_CLEAR_ERROR_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (value==NULL) + goto bad_arg; + *value=st->error; + st->error = 0; + } + break; + case OPUS_GET_LOOKAHEAD_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (value==NULL) + goto bad_arg; + *value = st->overlap/st->downsample; + } + break; + case OPUS_RESET_STATE: + { + int i; + opus_val16 *lpc, *oldBandE, *oldLogE, *oldLogE2; + lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels); + oldBandE = lpc+st->channels*LPC_ORDER; + oldLogE = oldBandE + 2*st->mode->nbEBands; + oldLogE2 = oldLogE + 2*st->mode->nbEBands; + OPUS_CLEAR((char*)&st->DECODER_RESET_START, + opus_custom_decoder_get_size(st->mode, st->channels)- + ((char*)&st->DECODER_RESET_START - (char*)st)); + for (i=0;i<2*st->mode->nbEBands;i++) + oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); + } + break; + case OPUS_GET_PITCH_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (value==NULL) + goto bad_arg; + *value = st->postfilter_period; + } + break; + case CELT_GET_MODE_REQUEST: + { + const CELTMode ** value = va_arg(ap, const CELTMode**); + if (value==0) + goto bad_arg; + *value=st->mode; + } + break; + case CELT_SET_SIGNALLING_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->signalling = value; + } + break; + case OPUS_GET_FINAL_RANGE_REQUEST: + { + opus_uint32 * value = va_arg(ap, opus_uint32 *); + if (value==0) + goto bad_arg; + *value=st->rng; + } + break; + default: + goto bad_request; + } + va_end(ap); + return OPUS_OK; +bad_arg: + va_end(ap); + return OPUS_BAD_ARG; +bad_request: + va_end(ap); + return OPUS_UNIMPLEMENTED; +} diff --git a/media/libopus/celt/celt_encoder.c b/media/libopus/celt/celt_encoder.c new file mode 100644 index 000000000000..d4b84ffde711 --- /dev/null +++ b/media/libopus/celt/celt_encoder.c @@ -0,0 +1,2287 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2010 Xiph.Org Foundation + Copyright (c) 2008 Gregory Maxwell + Written by Jean-Marc Valin and Gregory Maxwell */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define CELT_ENCODER_C + +#include "cpu_support.h" +#include "os_support.h" +#include "mdct.h" +#include +#include "celt.h" +#include "pitch.h" +#include "bands.h" +#include "modes.h" +#include "entcode.h" +#include "quant_bands.h" +#include "rate.h" +#include "stack_alloc.h" +#include "mathops.h" +#include "float_cast.h" +#include +#include "celt_lpc.h" +#include "vq.h" + + +/** Encoder state + @brief Encoder state + */ +struct OpusCustomEncoder { + const OpusCustomMode *mode; /**< Mode used by the encoder */ + int overlap; + int channels; + int stream_channels; + + int force_intra; + int clip; + int disable_pf; + int complexity; + int upsample; + int start, end; + + opus_int32 bitrate; + int vbr; + int signalling; + int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */ + int loss_rate; + int lsb_depth; + int variable_duration; + int lfe; + int arch; + + /* Everything beyond this point gets cleared on a reset */ +#define ENCODER_RESET_START rng + + opus_uint32 rng; + int spread_decision; + opus_val32 delayedIntra; + int tonal_average; + int lastCodedBands; + int hf_average; + int tapset_decision; + + int prefilter_period; + opus_val16 prefilter_gain; + int prefilter_tapset; +#ifdef RESYNTH + int prefilter_period_old; + opus_val16 prefilter_gain_old; + int prefilter_tapset_old; +#endif + int consec_transient; + AnalysisInfo analysis; + + opus_val32 preemph_memE[2]; + opus_val32 preemph_memD[2]; + + /* VBR-related parameters */ + opus_int32 vbr_reservoir; + opus_int32 vbr_drift; + opus_int32 vbr_offset; + opus_int32 vbr_count; + opus_val32 overlap_max; + opus_val16 stereo_saving; + int intensity; + opus_val16 *energy_save; + opus_val16 *energy_mask; + opus_val16 spec_avg; + +#ifdef RESYNTH + /* +MAX_PERIOD/2 to make space for overlap */ + celt_sig syn_mem[2][2*MAX_PERIOD+MAX_PERIOD/2]; +#endif + + celt_sig in_mem[1]; /* Size = channels*mode->overlap */ + /* celt_sig prefilter_mem[], Size = channels*COMBFILTER_MAXPERIOD */ + /* opus_val16 oldBandE[], Size = channels*mode->nbEBands */ + /* opus_val16 oldLogE[], Size = channels*mode->nbEBands */ + /* opus_val16 oldLogE2[], Size = channels*mode->nbEBands */ +}; + +int celt_encoder_get_size(int channels) +{ + CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); + return opus_custom_encoder_get_size(mode, channels); +} + +OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_get_size(const CELTMode *mode, int channels) +{ + int size = sizeof(struct CELTEncoder) + + (channels*mode->overlap-1)*sizeof(celt_sig) /* celt_sig in_mem[channels*mode->overlap]; */ + + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig) /* celt_sig prefilter_mem[channels*COMBFILTER_MAXPERIOD]; */ + + 3*channels*mode->nbEBands*sizeof(opus_val16); /* opus_val16 oldBandE[channels*mode->nbEBands]; */ + /* opus_val16 oldLogE[channels*mode->nbEBands]; */ + /* opus_val16 oldLogE2[channels*mode->nbEBands]; */ + return size; +} + +#ifdef CUSTOM_MODES +CELTEncoder *opus_custom_encoder_create(const CELTMode *mode, int channels, int *error) +{ + int ret; + CELTEncoder *st = (CELTEncoder *)opus_alloc(opus_custom_encoder_get_size(mode, channels)); + /* init will handle the NULL case */ + ret = opus_custom_encoder_init(st, mode, channels); + if (ret != OPUS_OK) + { + opus_custom_encoder_destroy(st); + st = NULL; + } + if (error) + *error = ret; + return st; +} +#endif /* CUSTOM_MODES */ + +int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels) +{ + int ret; + ret = opus_custom_encoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels); + if (ret != OPUS_OK) + return ret; + st->upsample = resampling_factor(sampling_rate); + return OPUS_OK; +} + +OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels) +{ + if (channels < 0 || channels > 2) + return OPUS_BAD_ARG; + + if (st==NULL || mode==NULL) + return OPUS_ALLOC_FAIL; + + OPUS_CLEAR((char*)st, opus_custom_encoder_get_size(mode, channels)); + + st->mode = mode; + st->overlap = mode->overlap; + st->stream_channels = st->channels = channels; + + st->upsample = 1; + st->start = 0; + st->end = st->mode->effEBands; + st->signalling = 1; + + st->arch = opus_select_arch(); + + st->constrained_vbr = 1; + st->clip = 1; + + st->bitrate = OPUS_BITRATE_MAX; + st->vbr = 0; + st->force_intra = 0; + st->complexity = 5; + st->lsb_depth=24; + + opus_custom_encoder_ctl(st, OPUS_RESET_STATE); + + return OPUS_OK; +} + +#ifdef CUSTOM_MODES +void opus_custom_encoder_destroy(CELTEncoder *st) +{ + opus_free(st); +} +#endif /* CUSTOM_MODES */ + + +static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int C, + opus_val16 *tf_estimate, int *tf_chan) +{ + int i; + VARDECL(opus_val16, tmp); + opus_val32 mem0,mem1; + int is_transient = 0; + opus_int32 mask_metric = 0; + int c; + opus_val16 tf_max; + int len2; + /* Table of 6*64/x, trained on real data to minimize the average error */ + static const unsigned char inv_table[128] = { + 255,255,156,110, 86, 70, 59, 51, 45, 40, 37, 33, 31, 28, 26, 25, + 23, 22, 21, 20, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12, + 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, + 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, + }; + SAVE_STACK; + ALLOC(tmp, len, opus_val16); + + len2=len/2; + tf_max = 0; + for (c=0;c=0;i--) + { +#ifdef FIXED_POINT + /* FIXME: Use PSHR16() instead */ + tmp[i] = mem0 + PSHR32(tmp[i]-mem0,3); +#else + tmp[i] = mem0 + MULT16_16_P15(QCONST16(0.125f,15),tmp[i]-mem0); +#endif + mem0 = tmp[i]; + maxE = MAX16(maxE, mem0); + } + /*for (i=0;i>1))); +#else + mean = celt_sqrt(mean * maxE*.5*len2); +#endif + /* Inverse of the mean energy in Q15+6 */ + norm = SHL32(EXTEND32(len2),6+14)/ADD32(EPSILON,SHR32(mean,1)); + /* Compute harmonic mean discarding the unreliable boundaries + The data is smooth, so we only take 1/4th of the samples */ + unmask=0; + for (i=12;imask_metric) + { + *tf_chan = c; + mask_metric = unmask; + } + } + is_transient = mask_metric>200; + + /* Arbitrary metric for VBR boost */ + tf_max = MAX16(0,celt_sqrt(27*mask_metric)-42); + /* *tf_estimate = 1 + MIN16(1, sqrt(MAX16(0, tf_max-30))/20); */ + *tf_estimate = celt_sqrt(MAX16(0, SHL32(MULT16_16(QCONST16(0.0069,14),MIN16(163,tf_max)),14)-QCONST32(0.139,28))); + /*printf("%d %f\n", tf_max, mask_metric);*/ + RESTORE_STACK; +#ifdef FUZZING + is_transient = rand()&0x1; +#endif + /*printf("%d %f %d\n", is_transient, (float)*tf_estimate, tf_max);*/ + return is_transient; +} + +/* Looks for sudden increases of energy to decide whether we need to patch + the transient decision */ +int patch_transient_decision(opus_val16 *new, opus_val16 *old, int nbEBands, + int end, int C) +{ + int i, c; + opus_val32 mean_diff=0; + opus_val16 spread_old[26]; + /* Apply an aggressive (-6 dB/Bark) spreading function to the old frame to + avoid false detection caused by irrelevant bands */ + if (C==1) + { + spread_old[0] = old[0]; + for (i=1;i=0;i--) + spread_old[i] = MAX16(spread_old[i], spread_old[i+1]-QCONST16(1.0f, DB_SHIFT)); + /* Compute mean increase */ + c=0; do { + for (i=2;i QCONST16(1.f, DB_SHIFT); +} + +/** Apply window and compute the MDCT for all sub-frames and + all channels in a frame */ +static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * OPUS_RESTRICT in, + celt_sig * OPUS_RESTRICT out, int C, int CC, int LM, int upsample) +{ + const int overlap = OVERLAP(mode); + int N; + int B; + int shift; + int i, b, c; + if (shortBlocks) + { + B = shortBlocks; + N = mode->shortMdctSize; + shift = mode->maxLM; + } else { + B = 1; + N = mode->shortMdctSize<maxLM-LM; + } + c=0; do { + for (b=0;bmdct, in+c*(B*N+overlap)+b*N, &out[b+c*N*B], mode->window, overlap, shift, B); + } + } while (++ceBands[len]-m->eBands[len-1])<eBands[len]-m->eBands[len-1])<eBands[i+1]-m->eBands[i])<eBands[i+1]-m->eBands[i])==1; + for (j=0;jeBands[i]<eBands[i]<>LM, 1<>k, 1<=0;i--) + { + if (tf_res[i+1] == 1) + tf_res[i] = path1[i+1]; + else + tf_res[i] = path0[i+1]; + } + /*printf("%d %f\n", *tf_sum, tf_estimate);*/ + RESTORE_STACK; +#ifdef FUZZING + tf_select = rand()&0x1; + tf_res[0] = rand()&0x1; + for (i=1;istorage*8; + tell = ec_tell(enc); + logp = isTransient ? 2 : 4; + /* Reserve space to code the tf_select decision. */ + tf_select_rsv = LM>0 && tell+logp+1 <= budget; + budget -= tf_select_rsv; + curr = tf_changed = 0; + for (i=start;ieBands[i]<eBands[i+1]<eBands[i]<eBands[i+1]< QCONST16(.995f,10)) + trim_index-=4; + else if (sum > QCONST16(.92f,10)) + trim_index-=3; + else if (sum > QCONST16(.85f,10)) + trim_index-=2; + else if (sum > QCONST16(.8f,10)) + trim_index-=1; + /* mid-side savings estimations based on the LF average*/ + logXC = celt_log2(QCONST32(1.001f, 20)-MULT16_16(sum, sum)); + /* mid-side savings estimations based on min correlation */ + logXC2 = MAX16(HALF16(logXC), celt_log2(QCONST32(1.001f, 20)-MULT16_16(minXC, minXC))); +#ifdef FIXED_POINT + /* Compensate for Q20 vs Q14 input and convert output to Q8 */ + logXC = PSHR32(logXC-QCONST16(6.f, DB_SHIFT),DB_SHIFT-8); + logXC2 = PSHR32(logXC2-QCONST16(6.f, DB_SHIFT),DB_SHIFT-8); +#endif + + trim += MAX16(-QCONST16(4.f, 8), MULT16_16_Q15(QCONST16(.75f,15),logXC)); + *stereo_saving = MIN16(*stereo_saving + QCONST16(0.25f, 8), -HALF16(logXC2)); + } + + /* Estimate spectral tilt */ + c=0; do { + for (i=0;inbEBands]*(opus_int32)(2+2*i-end); + } + } while (++c QCONST16(2.f, DB_SHIFT)) + trim_index--; + if (diff > QCONST16(8.f, DB_SHIFT)) + trim_index--; + if (diff < -QCONST16(4.f, DB_SHIFT)) + trim_index++; + if (diff < -QCONST16(10.f, DB_SHIFT)) + trim_index++; + trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8), SHR16(diff+QCONST16(1.f, DB_SHIFT),DB_SHIFT-8)/6 )); + trim -= 2*SHR16(tf_estimate, 14-8); +#ifndef FIXED_POINT + if (analysis->valid) + { + trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8), 2*(analysis->tonality_slope+.05f))); + } +#endif + +#ifdef FIXED_POINT + trim_index = PSHR32(trim, 8); +#else + trim_index = (int)floor(.5f+trim); +#endif + if (trim_index<0) + trim_index = 0; + if (trim_index>10) + trim_index = 10; + /*printf("%d\n", trim_index);*/ +#ifdef FUZZING + trim_index = rand()%11; +#endif + return trim_index; +} + +static int stereo_analysis(const CELTMode *m, const celt_norm *X, + int LM, int N0) +{ + int i; + int thetas; + opus_val32 sumLR = EPSILON, sumMS = EPSILON; + + /* Use the L1 norm to model the entropy of the L/R signal vs the M/S signal */ + for (i=0;i<13;i++) + { + int j; + for (j=m->eBands[i]<eBands[i+1]<eBands[13]<<(LM+1))+thetas, sumMS) + > MULT16_32_Q15(m->eBands[13]<<(LM+1), sumLR); +} + +static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16 *bandLogE2, + int nbEBands, int start, int end, int C, int *offsets, int lsb_depth, const opus_int16 *logN, + int isTransient, int vbr, int constrained_vbr, const opus_int16 *eBands, int LM, + int effectiveBytes, opus_int32 *tot_boost_, int lfe) +{ + int i, c; + opus_int32 tot_boost=0; + opus_val16 maxDepth; + VARDECL(opus_val16, follower); + VARDECL(opus_val16, noise_floor); + SAVE_STACK; + ALLOC(follower, C*nbEBands, opus_val16); + ALLOC(noise_floor, C*nbEBands, opus_val16); + for (i=0;i 50 && LM>=1 && !lfe) + { + int last=0; + c=0;do + { + follower[c*nbEBands] = bandLogE2[c*nbEBands]; + for (i=1;i bandLogE2[c*nbEBands+i-1]+QCONST16(.5f,DB_SHIFT)) + last=i; + follower[c*nbEBands+i] = MIN16(follower[c*nbEBands+i-1]+QCONST16(1.5f,DB_SHIFT), bandLogE2[c*nbEBands+i]); + } + for (i=last-1;i>=0;i--) + follower[c*nbEBands+i] = MIN16(follower[c*nbEBands+i], MIN16(follower[c*nbEBands+i+1]+QCONST16(2.f,DB_SHIFT), bandLogE2[c*nbEBands+i])); + for (i=0;i=12) + follower[i] = HALF16(follower[i]); + follower[i] = MIN16(follower[i], QCONST16(4, DB_SHIFT)); + + width = C*(eBands[i+1]-eBands[i])< 48) { + boost = (int)SHR32(EXTEND32(follower[i])*8,DB_SHIFT); + boost_bits = (boost*width<>BITRES>>3 > effectiveBytes/4) + { + opus_int32 cap = ((effectiveBytes/4)<mode; + ALLOC(_pre, CC*(N+COMBFILTER_MAXPERIOD), celt_sig); + + pre[0] = _pre; + pre[1] = _pre + (N+COMBFILTER_MAXPERIOD); + + + c=0; do { + OPUS_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD); + OPUS_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+st->overlap)+st->overlap, N); + } while (++c>1, opus_val16); + + pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC); + /* Don't search for the fir last 1.5 octave of the range because + there's too many false-positives due to short-term correlation */ + pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N, + COMBFILTER_MAXPERIOD-3*COMBFILTER_MINPERIOD, &pitch_index); + pitch_index = COMBFILTER_MAXPERIOD-pitch_index; + + gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD, + N, &pitch_index, st->prefilter_period, st->prefilter_gain); + if (pitch_index > COMBFILTER_MAXPERIOD-2) + pitch_index = COMBFILTER_MAXPERIOD-2; + gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1); + /*printf("%d %d %f %f\n", pitch_change, pitch_index, gain1, st->analysis.tonality);*/ + if (st->loss_rate>2) + gain1 = HALF32(gain1); + if (st->loss_rate>4) + gain1 = HALF32(gain1); + if (st->loss_rate>8) + gain1 = 0; + } else { + gain1 = 0; + pitch_index = COMBFILTER_MINPERIOD; + } + + /* Gain threshold for enabling the prefilter/postfilter */ + pf_threshold = QCONST16(.2f,15); + + /* Adjusting the threshold based on rate and continuity */ + if (abs(pitch_index-st->prefilter_period)*10>pitch_index) + pf_threshold += QCONST16(.2f,15); + if (nbAvailableBytes<25) + pf_threshold += QCONST16(.1f,15); + if (nbAvailableBytes<35) + pf_threshold += QCONST16(.1f,15); + if (st->prefilter_gain > QCONST16(.4f,15)) + pf_threshold -= QCONST16(.1f,15); + if (st->prefilter_gain > QCONST16(.55f,15)) + pf_threshold -= QCONST16(.1f,15); + + /* Hard threshold at 0.2 */ + pf_threshold = MAX16(pf_threshold, QCONST16(.2f,15)); + if (gain1prefilter_gain)prefilter_gain; + +#ifdef FIXED_POINT + qg = ((gain1+1536)>>10)/3-1; +#else + qg = (int)floor(.5f+gain1*32/3)-1; +#endif + qg = IMAX(0, IMIN(7, qg)); + gain1 = QCONST16(0.09375f,15)*(qg+1); + pf_on = 1; + } + /*printf("%d %f\n", pitch_index, gain1);*/ + + c=0; do { + int offset = mode->shortMdctSize-st->overlap; + st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); + OPUS_COPY(in+c*(N+st->overlap), st->in_mem+c*(st->overlap), st->overlap); + if (offset) + comb_filter(in+c*(N+st->overlap)+st->overlap, pre[c]+COMBFILTER_MAXPERIOD, + st->prefilter_period, st->prefilter_period, offset, -st->prefilter_gain, -st->prefilter_gain, + st->prefilter_tapset, st->prefilter_tapset, NULL, 0); + + comb_filter(in+c*(N+st->overlap)+st->overlap+offset, pre[c]+COMBFILTER_MAXPERIOD+offset, + st->prefilter_period, pitch_index, N-offset, -st->prefilter_gain, -gain1, + st->prefilter_tapset, prefilter_tapset, mode->window, st->overlap); + OPUS_COPY(st->in_mem+c*(st->overlap), in+c*(N+st->overlap)+N, st->overlap); + + if (N>COMBFILTER_MAXPERIOD) + { + OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD); + } else { + OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, prefilter_mem+c*COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD-N); + OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N); + } + } while (++cnbEBands; + eBands = mode->eBands; + + coded_bands = lastCodedBands ? lastCodedBands : nbEBands; + coded_bins = eBands[coded_bands]<analysis.activity, st->analysis.tonality, tf_estimate, st->stereo_saving, tot_boost, coded_bands);*/ +#ifndef FIXED_POINT + if (analysis->valid && analysis->activity<.4) + target -= (opus_int32)((coded_bins<activity)); +#endif + /* Stereo savings */ + if (C==2) + { + int coded_stereo_bands; + int coded_stereo_dof; + opus_val16 max_frac; + coded_stereo_bands = IMIN(intensity, coded_bands); + coded_stereo_dof = (eBands[coded_stereo_bands]<valid && !lfe) + { + opus_int32 tonal_target; + float tonal; + + /* Tonality boost (compensating for the average). */ + tonal = MAX16(0.f,analysis->tonality-.15f)-0.09f; + tonal_target = target + (opus_int32)((coded_bins<analysis.tonality, tonal);*/ + target = tonal_target; + } +#endif + + if (has_surround_mask&&!lfe) + { + opus_int32 surround_target = target + (opus_int32)SHR32(MULT16_16(surround_masking,coded_bins<end, st->intensity, surround_target, target, st->bitrate);*/ + target = IMAX(target/4, surround_target); + } + + { + opus_int32 floor_depth; + int bins; + bins = eBands[nbEBands-2]<>2); + target = IMIN(target, floor_depth); + /*printf("%f %d\n", maxDepth, floor_depth);*/ + } + + if ((!has_surround_mask||lfe) && (constrained_vbr || bitrate<64000)) + { + opus_val16 rate_factor; +#ifdef FIXED_POINT + rate_factor = MAX16(0,(bitrate-32000)); +#else + rate_factor = MAX16(0,(1.f/32768)*(bitrate-32000)); +#endif + if (constrained_vbr) + rate_factor = MIN16(rate_factor, QCONST16(0.67f, 15)); + target = base_target + (opus_int32)MULT16_32_Q15(rate_factor, target-base_target); + + } + + if (!has_surround_mask && tf_estimate < QCONST16(.2f, 14)) + { + opus_val16 amount; + opus_val16 tvbr_factor; + amount = MULT16_16_Q15(QCONST16(.0000031f, 30), IMAX(0, IMIN(32000, 96000-bitrate))); + tvbr_factor = SHR32(MULT16_16(temporal_vbr, amount), DB_SHIFT); + target += (opus_int32)MULT16_32_Q15(tvbr_factor, target); + } + + /* Don't allow more than doubling the rate */ + target = IMIN(2*base_target, target); + + return target; +} + +int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc) +{ + int i, c, N; + opus_int32 bits; + ec_enc _enc; + VARDECL(celt_sig, in); + VARDECL(celt_sig, freq); + VARDECL(celt_norm, X); + VARDECL(celt_ener, bandE); + VARDECL(opus_val16, bandLogE); + VARDECL(opus_val16, bandLogE2); + VARDECL(int, fine_quant); + VARDECL(opus_val16, error); + VARDECL(int, pulses); + VARDECL(int, cap); + VARDECL(int, offsets); + VARDECL(int, fine_priority); + VARDECL(int, tf_res); + VARDECL(unsigned char, collapse_masks); + celt_sig *prefilter_mem; + opus_val16 *oldBandE, *oldLogE, *oldLogE2; + int shortBlocks=0; + int isTransient=0; + const int CC = st->channels; + const int C = st->stream_channels; + int LM, M; + int tf_select; + int nbFilledBytes, nbAvailableBytes; + int effEnd; + int codedBands; + int tf_sum; + int alloc_trim; + int pitch_index=COMBFILTER_MINPERIOD; + opus_val16 gain1 = 0; + int dual_stereo=0; + int effectiveBytes; + int dynalloc_logp; + opus_int32 vbr_rate; + opus_int32 total_bits; + opus_int32 total_boost; + opus_int32 balance; + opus_int32 tell; + int prefilter_tapset=0; + int pf_on; + int anti_collapse_rsv; + int anti_collapse_on=0; + int silence=0; + int tf_chan = 0; + opus_val16 tf_estimate; + int pitch_change=0; + opus_int32 tot_boost; + opus_val32 sample_max; + opus_val16 maxDepth; + const OpusCustomMode *mode; + int nbEBands; + int overlap; + const opus_int16 *eBands; + int secondMdct; + int signalBandwidth; + int transient_got_disabled=0; + opus_val16 surround_masking=0; + opus_val16 temporal_vbr=0; + ALLOC_STACK; + + mode = st->mode; + nbEBands = mode->nbEBands; + overlap = mode->overlap; + eBands = mode->eBands; + tf_estimate = 0; + if (nbCompressedBytes<2 || pcm==NULL) + return OPUS_BAD_ARG; + + frame_size *= st->upsample; + for (LM=0;LM<=mode->maxLM;LM++) + if (mode->shortMdctSize<mode->maxLM) + return OPUS_BAD_ARG; + M=1<shortMdctSize; + + prefilter_mem = st->in_mem+CC*(st->overlap); + oldBandE = (opus_val16*)(st->in_mem+CC*(st->overlap+COMBFILTER_MAXPERIOD)); + oldLogE = oldBandE + CC*nbEBands; + oldLogE2 = oldLogE + CC*nbEBands; + + if (enc==NULL) + { + tell=1; + nbFilledBytes=0; + } else { + tell=ec_tell(enc); + nbFilledBytes=(tell+4)>>3; + } + +#ifdef CUSTOM_MODES + if (st->signalling && enc==NULL) + { + int tmp = (mode->effEBands-st->end)>>1; + st->end = IMAX(1, mode->effEBands-tmp); + compressed[0] = tmp<<5; + compressed[0] |= LM<<3; + compressed[0] |= (C==2)<<2; + /* Convert "standard mode" to Opus header */ + if (mode->Fs==48000 && mode->shortMdctSize==120) + { + int c0 = toOpus(compressed[0]); + if (c0<0) + return OPUS_BAD_ARG; + compressed[0] = c0; + } + compressed++; + nbCompressedBytes--; + } +#else + celt_assert(st->signalling==0); +#endif + + /* Can't produce more than 1275 output bytes */ + nbCompressedBytes = IMIN(nbCompressedBytes,1275); + nbAvailableBytes = nbCompressedBytes - nbFilledBytes; + + if (st->vbr && st->bitrate!=OPUS_BITRATE_MAX) + { + opus_int32 den=mode->Fs>>BITRES; + vbr_rate=(st->bitrate*frame_size+(den>>1))/den; +#ifdef CUSTOM_MODES + if (st->signalling) + vbr_rate -= 8<>(3+BITRES); + } else { + opus_int32 tmp; + vbr_rate = 0; + tmp = st->bitrate*frame_size; + if (tell>1) + tmp += tell; + if (st->bitrate!=OPUS_BITRATE_MAX) + nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes, + (tmp+4*mode->Fs)/(8*mode->Fs)-!!st->signalling)); + effectiveBytes = nbCompressedBytes; + } + + if (enc==NULL) + { + ec_enc_init(&_enc, compressed, nbCompressedBytes); + enc = &_enc; + } + + if (vbr_rate>0) + { + /* Computes the max bit-rate allowed in VBR mode to avoid violating the + target rate and buffering. + We must do this up front so that bust-prevention logic triggers + correctly if we don't have enough bits. */ + if (st->constrained_vbr) + { + opus_int32 vbr_bound; + opus_int32 max_allowed; + /* We could use any multiple of vbr_rate as bound (depending on the + delay). + This is clamped to ensure we use at least two bytes if the encoder + was entirely empty, but to allow 0 in hybrid mode. */ + vbr_bound = vbr_rate; + max_allowed = IMIN(IMAX(tell==1?2:0, + (vbr_rate+vbr_bound-st->vbr_reservoir)>>(BITRES+3)), + nbAvailableBytes); + if(max_allowed < nbAvailableBytes) + { + nbCompressedBytes = nbFilledBytes+max_allowed; + nbAvailableBytes = max_allowed; + ec_enc_shrink(enc, nbCompressedBytes); + } + } + } + total_bits = nbCompressedBytes*8; + + effEnd = st->end; + if (effEnd > mode->effEBands) + effEnd = mode->effEBands; + + ALLOC(in, CC*(N+st->overlap), celt_sig); + + sample_max=MAX32(st->overlap_max, celt_maxabs16(pcm, C*(N-overlap)/st->upsample)); + st->overlap_max=celt_maxabs16(pcm+C*(N-overlap)/st->upsample, C*overlap/st->upsample); + sample_max=MAX32(sample_max, st->overlap_max); +#ifdef FIXED_POINT + silence = (sample_max==0); +#else + silence = (sample_max <= (opus_val16)1/(1<lsb_depth)); +#endif +#ifdef FUZZING + if ((rand()&0x3F)==0) + silence = 1; +#endif + if (tell==1) + ec_enc_bit_logp(enc, silence, 15); + else + silence=0; + if (silence) + { + /*In VBR mode there is no need to send more than the minimum. */ + if (vbr_rate>0) + { + effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2); + total_bits=nbCompressedBytes*8; + nbAvailableBytes=2; + ec_enc_shrink(enc, nbCompressedBytes); + } + /* Pretend we've filled all the remaining bits with zeros + (that's what the initialiser did anyway) */ + tell = nbCompressedBytes*8; + enc->nbits_total+=tell-ec_tell(enc); + } + c=0; do { + preemphasis(pcm+c, in+c*(N+st->overlap)+st->overlap, N, CC, st->upsample, + mode->preemph, st->preemph_memE+c, st->clip); + } while (++clfe || nbAvailableBytes>12*C) && st->start==0 && !silence && !st->disable_pf + && st->complexity >= 5 && !(st->consec_transient && LM!=3 && st->variable_duration==OPUS_FRAMESIZE_VARIABLE); + + prefilter_tapset = st->tapset_decision; + pf_on = run_prefilter(st, in, prefilter_mem, CC, N, prefilter_tapset, &pitch_index, &gain1, &qg, enabled, nbAvailableBytes); + if ((gain1 > QCONST16(.4f,15) || st->prefilter_gain > QCONST16(.4f,15)) && (!st->analysis.valid || st->analysis.tonality > .3) + && (pitch_index > 1.26*st->prefilter_period || pitch_index < .79*st->prefilter_period)) + pitch_change = 1; + if (pf_on==0) + { + if(st->start==0 && tell+16<=total_bits) + ec_enc_bit_logp(enc, 0, 1); + } else { + /*This block is not gated by a total bits check only because + of the nbAvailableBytes check above.*/ + int octave; + ec_enc_bit_logp(enc, 1, 1); + pitch_index += 1; + octave = EC_ILOG(pitch_index)-5; + ec_enc_uint(enc, octave, 6); + ec_enc_bits(enc, pitch_index-(16<complexity >= 1 && !st->lfe) + { + isTransient = transient_analysis(in, N+st->overlap, CC, + &tf_estimate, &tf_chan); + } + if (LM>0 && ec_tell(enc)+3<=total_bits) + { + if (isTransient) + shortBlocks = M; + } else { + isTransient = 0; + transient_got_disabled=1; + } + + ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */ + ALLOC(bandE,nbEBands*CC, celt_ener); + ALLOC(bandLogE,nbEBands*CC, opus_val16); + + secondMdct = shortBlocks && st->complexity>=8; + ALLOC(bandLogE2, C*nbEBands, opus_val16); + if (secondMdct) + { + compute_mdcts(mode, 0, in, freq, C, CC, LM, st->upsample); + compute_band_energies(mode, freq, bandE, effEnd, C, M); + amp2Log2(mode, effEnd, st->end, bandE, bandLogE2, C); + for (i=0;iupsample); + if (CC==2&&C==1) + tf_chan = 0; + compute_band_energies(mode, freq, bandE, effEnd, C, M); + + if (st->lfe) + { + for (i=2;iend;i++) + { + bandE[i] = IMIN(bandE[i], MULT16_32_Q15(QCONST16(1e-4f,15),bandE[0])); + bandE[i] = MAX32(bandE[i], EPSILON); + } + } + amp2Log2(mode, effEnd, st->end, bandE, bandLogE, C); + if (st->energy_save) + { + opus_val16 offset = shortBlocks?HALF16(SHL16(LM, DB_SHIFT)):0; +#ifdef FIXED_POINT + /* Compensate for the 1/8 gain we apply in the fixed-point downshift to avoid overflows. */ + offset -= QCONST16(3.0f, DB_SHIFT); +#endif + for(i=0;ienergy_save[i]=bandLogE[i]-offset; + st->energy_save=NULL; + } + /* This computes how much masking takes place between surround channels */ + if (st->energy_mask&&!st->lfe) + { + opus_val32 mask_avg=0; + opus_val16 offset = shortBlocks?HALF16(SHL16(LM, DB_SHIFT)):0; + for (c=0;cend;i++) + { + /* We use a simple follower to approximate the masking spreading function. */ + followE = MAX16(followE-QCONST16(1.f, DB_SHIFT), bandLogE[nbEBands*c+i]-offset); + followMask = MAX16(followMask-QCONST16(1.f, DB_SHIFT), st->energy_mask[nbEBands*c+i]); + mask_avg += followE-followMask; + } + } + surround_masking = DIV32_16(mask_avg,C*st->end) + QCONST16(.7f, DB_SHIFT); + surround_masking = MIN16(MAX16(surround_masking, -QCONST16(2.f, DB_SHIFT)), QCONST16(.2f, DB_SHIFT)); + surround_masking -= HALF16(HALF16(surround_masking)); + } + /* Temporal VBR (but not for LFE) */ + if (!st->lfe) + { + opus_val16 follow=-QCONST16(10.0f,DB_SHIFT); + float frame_avg=0; + opus_val16 offset = shortBlocks?HALF16(SHL16(LM, DB_SHIFT)):0; + for(i=st->start;iend;i++) + { + follow = MAX16(follow-QCONST16(1.f, DB_SHIFT), bandLogE[i]-offset); + if (C==2) + follow = MAX16(follow, bandLogE[i+nbEBands]-offset); + frame_avg += follow; + } + frame_avg /= (st->end-st->start); + temporal_vbr = SUB16(frame_avg,st->spec_avg); + temporal_vbr = MIN16(QCONST16(3.f, DB_SHIFT), MAX16(-QCONST16(1.5f, DB_SHIFT), temporal_vbr)); + st->spec_avg += MULT16_16_Q15(QCONST16(.02f, 15), temporal_vbr); + } + /*for (i=0;i<21;i++) + printf("%f ", bandLogE[i]); + printf("\n");*/ + + if (!secondMdct) + { + for (i=0;i0 && ec_tell(enc)+3<=total_bits && !isTransient && st->complexity>=5 && !st->lfe) + { + if (patch_transient_decision(bandLogE, oldBandE, nbEBands, st->end, C)) + { + isTransient = 1; + shortBlocks = M; + compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample); + compute_band_energies(mode, freq, bandE, effEnd, C, M); + amp2Log2(mode, effEnd, st->end, bandE, bandLogE, C); + /* Compensate for the scaling of short vs long mdcts */ + for (i=0;i0 && ec_tell(enc)+3<=total_bits) + ec_enc_bit_logp(enc, isTransient, 3); + + ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ + + /* Band normalisation */ + normalise_bands(mode, freq, X, bandE, effEnd, C, M); + + ALLOC(tf_res, nbEBands, int); + /* Disable variable tf resolution for hybrid and at very low bitrate */ + if (effectiveBytes>=15*C && st->start==0 && st->complexity>=2 && !st->lfe) + { + int lambda; + if (effectiveBytes<40) + lambda = 12; + else if (effectiveBytes<60) + lambda = 6; + else if (effectiveBytes<100) + lambda = 4; + else + lambda = 3; + lambda*=2; + tf_select = tf_analysis(mode, effEnd, isTransient, tf_res, lambda, X, N, LM, &tf_sum, tf_estimate, tf_chan); + for (i=effEnd;iend;i++) + tf_res[i] = tf_res[effEnd-1]; + } else { + tf_sum = 0; + for (i=0;iend;i++) + tf_res[i] = isTransient; + tf_select=0; + } + + ALLOC(error, C*nbEBands, opus_val16); + quant_coarse_energy(mode, st->start, st->end, effEnd, bandLogE, + oldBandE, total_bits, error, enc, + C, LM, nbAvailableBytes, st->force_intra, + &st->delayedIntra, st->complexity >= 4, st->loss_rate, st->lfe); + + tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc); + + if (ec_tell(enc)+4<=total_bits) + { + if (st->lfe) + { + st->tapset_decision = 0; + st->spread_decision = SPREAD_NORMAL; + } else if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C || st->start != 0) + { + if (st->complexity == 0) + st->spread_decision = SPREAD_NONE; + else + st->spread_decision = SPREAD_NORMAL; + } else { + /* Disable new spreading+tapset estimator until we can show it works + better than the old one. So far it seems like spreading_decision() + works best. */ + if (0&&st->analysis.valid) + { + static const opus_val16 spread_thresholds[3] = {-QCONST16(.6f, 15), -QCONST16(.2f, 15), -QCONST16(.07f, 15)}; + static const opus_val16 spread_histeresis[3] = {QCONST16(.15f, 15), QCONST16(.07f, 15), QCONST16(.02f, 15)}; + static const opus_val16 tapset_thresholds[2] = {QCONST16(.0f, 15), QCONST16(.15f, 15)}; + static const opus_val16 tapset_histeresis[2] = {QCONST16(.1f, 15), QCONST16(.05f, 15)}; + st->spread_decision = hysteresis_decision(-st->analysis.tonality, spread_thresholds, spread_histeresis, 3, st->spread_decision); + st->tapset_decision = hysteresis_decision(st->analysis.tonality_slope, tapset_thresholds, tapset_histeresis, 2, st->tapset_decision); + } else { + st->spread_decision = spreading_decision(mode, X, + &st->tonal_average, st->spread_decision, &st->hf_average, + &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M); + } + /*printf("%d %d\n", st->tapset_decision, st->spread_decision);*/ + /*printf("%f %d %f %d\n\n", st->analysis.tonality, st->spread_decision, st->analysis.tonality_slope, st->tapset_decision);*/ + } + ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5); + } + + ALLOC(offsets, nbEBands, int); + + maxDepth = dynalloc_analysis(bandLogE, bandLogE2, nbEBands, st->start, st->end, C, offsets, + st->lsb_depth, mode->logN, isTransient, st->vbr, st->constrained_vbr, + eBands, LM, effectiveBytes, &tot_boost, st->lfe); + /* For LFE, everything interesting is in the first band */ + if (st->lfe) + offsets[0] = IMIN(8, effectiveBytes/3); + ALLOC(cap, nbEBands, int); + init_caps(mode,cap,LM,C); + + dynalloc_logp = 6; + total_bits<<=BITRES; + total_boost = 0; + tell = ec_tell_frac(enc); + for (i=st->start;iend;i++) + { + int width, quanta; + int dynalloc_loop_logp; + int boost; + int j; + width = C*(eBands[i+1]-eBands[i])<>LM; + + /* effectiveRate in kb/s */ + effectiveRate = 2*effectiveRate/5; + + st->intensity = hysteresis_decision((opus_val16)effectiveRate, intensity_thresholds, intensity_histeresis, 21, st->intensity); + st->intensity = IMIN(st->end,IMAX(st->start, st->intensity)); + } + + alloc_trim = 5; + if (tell+(6<lfe) + alloc_trim = 5; + else + alloc_trim = alloc_trim_analysis(mode, X, bandLogE, + st->end, LM, C, N, &st->analysis, &st->stereo_saving, tf_estimate, st->intensity); + ec_enc_icdf(enc, alloc_trim, trim_icdf, 7); + tell = ec_tell_frac(enc); + } + + /* Variable bitrate */ + if (vbr_rate>0) + { + opus_val16 alpha; + opus_int32 delta; + /* The target rate in 8th bits per frame */ + opus_int32 target, base_target; + opus_int32 min_allowed; + int lm_diff = mode->maxLM - LM; + + /* Don't attempt to use more than 510 kb/s, even for frames smaller than 20 ms. + The CELT allocator will just not be able to use more than that anyway. */ + nbCompressedBytes = IMIN(nbCompressedBytes,1275>>(3-LM)); + base_target = vbr_rate - ((40*C+20)<constrained_vbr) + base_target += (st->vbr_offset>>lm_diff); + + target = compute_vbr(mode, &st->analysis, base_target, LM, st->bitrate, + st->lastCodedBands, C, st->intensity, st->constrained_vbr, + st->stereo_saving, tot_boost, tf_estimate, pitch_change, maxDepth, + st->variable_duration, st->lfe, st->energy_mask!=NULL, surround_masking, + temporal_vbr); + + /* The current offset is removed from the target and the space used + so far is added*/ + target=target+tell; + /* In VBR mode the frame size must not be reduced so much that it would + result in the encoder running out of bits. + The margin of 2 bytes ensures that none of the bust-prevention logic + in the decoder will have triggered so far. */ + min_allowed = ((tell+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3)) + 2 - nbFilledBytes; + + nbAvailableBytes = (target+(1<<(BITRES+2)))>>(BITRES+3); + nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes); + nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes) - nbFilledBytes; + + /* By how much did we "miss" the target on that frame */ + delta = target - vbr_rate; + + target=nbAvailableBytes<<(BITRES+3); + + /*If the frame is silent we don't adjust our drift, otherwise + the encoder will shoot to very high rates after hitting a + span of silence, but we do allow the bitres to refill. + This means that we'll undershoot our target in CVBR/VBR modes + on files with lots of silence. */ + if(silence) + { + nbAvailableBytes = 2; + target = 2*8<vbr_count < 970) + { + st->vbr_count++; + alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+20),16)); + } else + alpha = QCONST16(.001f,15); + /* How many bits have we used in excess of what we're allowed */ + if (st->constrained_vbr) + st->vbr_reservoir += target - vbr_rate; + /*printf ("%d\n", st->vbr_reservoir);*/ + + /* Compute the offset we need to apply in order to reach the target */ + if (st->constrained_vbr) + { + st->vbr_drift += (opus_int32)MULT16_32_Q15(alpha,(delta*(1<vbr_offset-st->vbr_drift); + st->vbr_offset = -st->vbr_drift; + } + /*printf ("%d\n", st->vbr_drift);*/ + + if (st->constrained_vbr && st->vbr_reservoir < 0) + { + /* We're under the min value -- increase rate */ + int adjust = (-st->vbr_reservoir)/(8<vbr_reservoir = 0; + /*printf ("+%d\n", adjust);*/ + } + nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes); + /*printf("%d\n", nbCompressedBytes*50*8);*/ + /* This moves the raw bits to take into account the new compressed size */ + ec_enc_shrink(enc, nbCompressedBytes); + } + + /* Bit allocation */ + ALLOC(fine_quant, nbEBands, int); + ALLOC(pulses, nbEBands, int); + ALLOC(fine_priority, nbEBands, int); + + /* bits = packet size - where we are - safety*/ + bits = (((opus_int32)nbCompressedBytes*8)<=2&&bits>=((LM+2)<end-1; +#ifndef FIXED_POINT + if (st->analysis.valid) + { + int min_bandwidth; + if (st->bitrate < (opus_int32)32000*C) + min_bandwidth = 13; + else if (st->bitrate < (opus_int32)48000*C) + min_bandwidth = 16; + else if (st->bitrate < (opus_int32)60000*C) + min_bandwidth = 18; + else if (st->bitrate < (opus_int32)80000*C) + min_bandwidth = 19; + else + min_bandwidth = 20; + signalBandwidth = IMAX(st->analysis.bandwidth, min_bandwidth); + } +#endif + if (st->lfe) + signalBandwidth = 1; + codedBands = compute_allocation(mode, st->start, st->end, offsets, cap, + alloc_trim, &st->intensity, &dual_stereo, bits, &balance, pulses, + fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands, signalBandwidth); + if (st->lastCodedBands) + st->lastCodedBands = IMIN(st->lastCodedBands+1,IMAX(st->lastCodedBands-1,codedBands)); + else + st->lastCodedBands = codedBands; + + quant_fine_energy(mode, st->start, st->end, oldBandE, error, fine_quant, enc, C); + + /* Residual quantisation */ + ALLOC(collapse_masks, C*nbEBands, unsigned char); + quant_all_bands(1, mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks, + bandE, pulses, shortBlocks, st->spread_decision, dual_stereo, st->intensity, tf_res, + nbCompressedBytes*(8<rng); + + if (anti_collapse_rsv > 0) + { + anti_collapse_on = st->consec_transient<2; +#ifdef FUZZING + anti_collapse_on = rand()&0x1; +#endif + ec_enc_bits(enc, anti_collapse_on, 1); + } + quant_energy_finalise(mode, st->start, st->end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C); + + if (silence) + { + for (i=0;istart, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng); + } + + if (silence) + { + for (i=0;istart, effEnd, C, M); + } + + c=0; do { + OPUS_MOVE(st->syn_mem[c], st->syn_mem[c]+N, 2*MAX_PERIOD-N+overlap/2); + } while (++csyn_mem[c]+2*MAX_PERIOD-N; + } while (++cprefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); + st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD); + comb_filter(out_mem[c], out_mem[c], st->prefilter_period_old, st->prefilter_period, mode->shortMdctSize, + st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset, + mode->window, st->overlap); + if (LM!=0) + comb_filter(out_mem[c]+mode->shortMdctSize, out_mem[c]+mode->shortMdctSize, st->prefilter_period, pitch_index, N-mode->shortMdctSize, + st->prefilter_gain, gain1, st->prefilter_tapset, prefilter_tapset, + mode->window, overlap); + } while (++cupsample, mode->preemph, st->preemph_memD, freq); + st->prefilter_period_old = st->prefilter_period; + st->prefilter_gain_old = st->prefilter_gain; + st->prefilter_tapset_old = st->prefilter_tapset; + } +#endif + + st->prefilter_period = pitch_index; + st->prefilter_gain = gain1; + st->prefilter_tapset = prefilter_tapset; +#ifdef RESYNTH + if (LM!=0) + { + st->prefilter_period_old = st->prefilter_period; + st->prefilter_gain_old = st->prefilter_gain; + st->prefilter_tapset_old = st->prefilter_tapset; + } +#endif + + if (CC==2&&C==1) { + for (i=0;istart;i++) + { + oldBandE[c*nbEBands+i]=0; + oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT); + } + for (i=st->end;iconsec_transient++; + else + st->consec_transient=0; + st->rng = enc->rng; + + /* If there's any room left (can only happen for very high rates), + it's already filled with zeros */ + ec_enc_done(enc); + +#ifdef CUSTOM_MODES + if (st->signalling) + nbCompressedBytes++; +#endif + + RESTORE_STACK; + if (ec_get_error(enc)) + return OPUS_INTERNAL_ERROR; + else + return nbCompressedBytes; +} + + +#ifdef CUSTOM_MODES + +#ifdef FIXED_POINT +int opus_custom_encode(CELTEncoder * OPUS_RESTRICT st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) +{ + return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL); +} + +#ifndef DISABLE_FLOAT_API +int opus_custom_encode_float(CELTEncoder * OPUS_RESTRICT st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) +{ + int j, ret, C, N; + VARDECL(opus_int16, in); + ALLOC_STACK; + + if (pcm==NULL) + return OPUS_BAD_ARG; + + C = st->channels; + N = frame_size; + ALLOC(in, C*N, opus_int16); + + for (j=0;jchannels; + N=frame_size; + ALLOC(in, C*N, celt_sig); + for (j=0;j10) + goto bad_arg; + st->complexity = value; + } + break; + case CELT_SET_START_BAND_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<0 || value>=st->mode->nbEBands) + goto bad_arg; + st->start = value; + } + break; + case CELT_SET_END_BAND_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<1 || value>st->mode->nbEBands) + goto bad_arg; + st->end = value; + } + break; + case CELT_SET_PREDICTION_REQUEST: + { + int value = va_arg(ap, opus_int32); + if (value<0 || value>2) + goto bad_arg; + st->disable_pf = value<=1; + st->force_intra = value==0; + } + break; + case OPUS_SET_PACKET_LOSS_PERC_REQUEST: + { + int value = va_arg(ap, opus_int32); + if (value<0 || value>100) + goto bad_arg; + st->loss_rate = value; + } + break; + case OPUS_SET_VBR_CONSTRAINT_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->constrained_vbr = value; + } + break; + case OPUS_SET_VBR_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->vbr = value; + } + break; + case OPUS_SET_BITRATE_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<=500 && value!=OPUS_BITRATE_MAX) + goto bad_arg; + value = IMIN(value, 260000*st->channels); + st->bitrate = value; + } + break; + case CELT_SET_CHANNELS_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<1 || value>2) + goto bad_arg; + st->stream_channels = value; + } + break; + case OPUS_SET_LSB_DEPTH_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<8 || value>24) + goto bad_arg; + st->lsb_depth=value; + } + break; + case OPUS_GET_LSB_DEPTH_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + *value=st->lsb_depth; + } + break; + case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->variable_duration = value; + } + break; + case OPUS_RESET_STATE: + { + int i; + opus_val16 *oldBandE, *oldLogE, *oldLogE2; + oldBandE = (opus_val16*)(st->in_mem+st->channels*(st->overlap+COMBFILTER_MAXPERIOD)); + oldLogE = oldBandE + st->channels*st->mode->nbEBands; + oldLogE2 = oldLogE + st->channels*st->mode->nbEBands; + OPUS_CLEAR((char*)&st->ENCODER_RESET_START, + opus_custom_encoder_get_size(st->mode, st->channels)- + ((char*)&st->ENCODER_RESET_START - (char*)st)); + for (i=0;ichannels*st->mode->nbEBands;i++) + oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); + st->vbr_offset = 0; + st->delayedIntra = 1; + st->spread_decision = SPREAD_NORMAL; + st->tonal_average = 256; + st->hf_average = 0; + st->tapset_decision = 0; + } + break; +#ifdef CUSTOM_MODES + case CELT_SET_INPUT_CLIPPING_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->clip = value; + } + break; +#endif + case CELT_SET_SIGNALLING_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->signalling = value; + } + break; + case CELT_SET_ANALYSIS_REQUEST: + { + AnalysisInfo *info = va_arg(ap, AnalysisInfo *); + if (info) + OPUS_COPY(&st->analysis, info, 1); + } + break; + case CELT_GET_MODE_REQUEST: + { + const CELTMode ** value = va_arg(ap, const CELTMode**); + if (value==0) + goto bad_arg; + *value=st->mode; + } + break; + case OPUS_GET_FINAL_RANGE_REQUEST: + { + opus_uint32 * value = va_arg(ap, opus_uint32 *); + if (value==0) + goto bad_arg; + *value=st->rng; + } + break; + case OPUS_SET_LFE_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->lfe = value; + } + break; + case OPUS_SET_ENERGY_SAVE_REQUEST: + { + opus_val16 *value = va_arg(ap, opus_val16*); + st->energy_save=value; + } + break; + case OPUS_SET_ENERGY_MASK_REQUEST: + { + opus_val16 *value = va_arg(ap, opus_val16*); + st->energy_mask = value; + } + break; + default: + goto bad_request; + } + va_end(ap); + return OPUS_OK; +bad_arg: + va_end(ap); + return OPUS_BAD_ARG; +bad_request: + va_end(ap); + return OPUS_UNIMPLEMENTED; +} diff --git a/media/libopus/celt/celt_lpc.c b/media/libopus/celt/celt_lpc.c index 0b64eaf8c179..7ffe90a357ed 100644 --- a/media/libopus/celt/celt_lpc.c +++ b/media/libopus/celt/celt_lpc.c @@ -1,10 +1,6 @@ -/* Copyright (c) 2009-2012 IETF Trust, Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2009-2010 Xiph.Org Foundation Written by Jean-Marc Valin */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -41,6 +32,7 @@ #include "celt_lpc.h" #include "stack_alloc.h" #include "mathops.h" +#include "pitch.h" void _celt_lpc( opus_val16 *_lpc, /* out: [0...p-1] LPC coefficients */ @@ -96,42 +88,71 @@ int p #endif } -void celt_fir(const opus_val16 *x, +void celt_fir(const opus_val16 *_x, const opus_val16 *num, - opus_val16 *y, + opus_val16 *_y, int N, int ord, opus_val16 *mem) { int i,j; + VARDECL(opus_val16, rnum); + VARDECL(opus_val16, x); + SAVE_STACK; + ALLOC(rnum, ord, opus_val16); + ALLOC(x, N+ord, opus_val16); + for(i=0;i=1;j--) - { - mem[j]=mem[j-1]; - } - mem[0] = x[i]; - y[i] = ROUND16(sum, SIG_SHIFT); + _y[i] = SATURATE16(PSHR32(sum, SIG_SHIFT)); } +#else + for (i=0;i0); celt_assert(overlap>=0); - for (i=0;i0) + { + for(i=0;i=0) + celt_pitch_xcorr(xptr, xptr, ac, fastN, lag+1); + for (k=0;k<=lag;k++) { - for (i = lag, d = 0; i < n; i++) - d += xx[i] * xx[i-lag]; - ac[lag] = d; - /*printf ("%f ", ac[lag]);*/ - lag--; + for (i = k+fastN, d = 0; i < n; i++) + d = MAC16_16(d, xptr[i], xptr[i-k]); + ac[k] += d; } - /*printf ("\n");*/ - ac[0] += 10; +#ifdef FIXED_POINT + shift = 2*shift; + if (shift<=0) + ac[0] += SHL32((opus_int32)1, -shift); + if (ac[0] < 268435456) + { + int shift2 = 29 - EC_ILOG(ac[0]); + for (i=0;i<=lag;i++) + ac[i] = SHL32(ac[i], shift2); + shift -= shift2; + } else if (ac[0] >= 536870912) + { + int shift2=1; + if (ac[0] >= 1073741824) + shift2++; + for (i=0;i<=lag;i++) + ac[i] = SHR32(ac[i], shift2); + shift += shift2; + } +#endif RESTORE_STACK; + return shift; } diff --git a/media/libopus/celt/celt_lpc.h b/media/libopus/celt/celt_lpc.h index cce260608e40..19279a0ed66f 100644 --- a/media/libopus/celt/celt_lpc.h +++ b/media/libopus/celt/celt_lpc.h @@ -1,10 +1,6 @@ -/* Copyright (c) 2009-2012 IETF Trust, Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2009-2010 Xiph.Org Foundation Written by Jean-Marc Valin */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -57,6 +48,6 @@ void celt_iir(const opus_val32 *x, int ord, opus_val16 *mem); -void _celt_autocorr(const opus_val16 *x, opus_val32 *ac, const opus_val16 *window, int overlap, int lag, int n); +int _celt_autocorr(const opus_val16 *x, opus_val32 *ac, const opus_val16 *window, int overlap, int lag, int n); #endif /* PLC_H */ diff --git a/media/libopus/celt/cpu_support.h b/media/libopus/celt/cpu_support.h new file mode 100644 index 000000000000..41481feb9c69 --- /dev/null +++ b/media/libopus/celt/cpu_support.h @@ -0,0 +1,51 @@ +/* Copyright (c) 2010 Xiph.Org Foundation + * Copyright (c) 2013 Parrot */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CPU_SUPPORT_H +#define CPU_SUPPORT_H + +#if defined(OPUS_HAVE_RTCD) && defined(ARMv4_ASM) +#include "arm/armcpu.h" + +/* We currently support 4 ARM variants: + * arch[0] -> ARMv4 + * arch[1] -> ARMv5E + * arch[2] -> ARMv6 + * arch[3] -> NEON + */ +#define OPUS_ARCHMASK 3 + +#else +#define OPUS_ARCHMASK 0 + +static inline int opus_select_arch(void) +{ + return 0; +} +#endif + +#endif diff --git a/media/libopus/celt/cwrs.c b/media/libopus/celt/cwrs.c index 980eaaabf9e2..28e6561d4eea 100644 --- a/media/libopus/celt/cwrs.c +++ b/media/libopus/celt/cwrs.c @@ -1,11 +1,8 @@ -/* Copyright (c) 2007-2012 IETF Trust, CSIRO, Xiph.Org Foundation, - Timothy B. Terriberry. All rights reserved. +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2007-2009 Timothy B. Terriberry Written by Timothy B. Terriberry and Jean-Marc Valin */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -17,11 +14,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -56,8 +48,9 @@ int log2_frac(opus_uint32 val, int frac) l=EC_ILOG(val); if(val&(val-1)){ /*This is (val>>l-16), but guaranteed to round up, even if adding a bias - before the shift would cause overflow (e.g., for 0xFFFFxxxx).*/ - if(l>16)val=(val>>(l-16))+(((val&((1<<(l-16))-1))+(1<<(l-16))-1)>>(l-16)); + before the shift would cause overflow (e.g., for 0xFFFFxxxx). + Doesn't work for val=0, but that case fails the test above.*/ + if(l>16)val=((val-1)>>(l-16))+1; else val<<=16-l; l=(l-1)<0); - celt_assert(_d<=54); - shift=EC_ILOG(_d^(_d-1)); - inv=INV_TABLE[(_d-1)>>shift]; - shift--; - one=1<>shift)-(_c>>shift)+ - ((_a*(_b&mask)+one-(_c&mask))>>shift)-1)*inv&MASK32; -} - -#endif /* SMALL_FOOTPRINT */ - /*Although derived separately, the pulse vector coding scheme is equivalent to a Pyramid Vector Quantizer \cite{Fis86}. Some additional notes about an early version appear at @@ -255,46 +190,346 @@ static inline opus_uint32 imusdiv32even(opus_uint32 _a,opus_uint32 _b, year=1986 }*/ -#ifndef SMALL_FOOTPRINT -/*Compute U(2,_k). - Note that this may be called with _k=32768 (maxK[2]+1).*/ -static inline unsigned ucwrs2(unsigned _k){ - celt_assert(_k>0); - return _k+(_k-1); +#if !defined(SMALL_FOOTPRINT) + +/*U(N,K) = U(K,N) := N>0?K>0?U(N-1,K)+U(N,K-1)+U(N-1,K-1):0:K>0?1:0*/ +# define CELT_PVQ_U(_n,_k) (CELT_PVQ_U_ROW[IMIN(_n,_k)][IMAX(_n,_k)]) +/*V(N,K) := U(N,K)+U(N,K+1) = the number of PVQ codewords for a band of size N + with K pulses allocated to it.*/ +# define CELT_PVQ_V(_n,_k) (CELT_PVQ_U(_n,_k)+CELT_PVQ_U(_n,(_k)+1)) + +/*For each V(N,K) supported, we will access element U(min(N,K+1),max(N,K+1)). + Thus, the number of entries in row I is the larger of the maximum number of + pulses we will ever allocate for a given N=I (K=128, or however many fit in + 32 bits, whichever is smaller), plus one, and the maximum N for which + K=I-1 pulses fit in 32 bits. + The largest band size in an Opus Custom mode is 208. + Otherwise, we can limit things to the set of N which can be achieved by + splitting a band from a standard Opus mode: 176, 144, 96, 88, 72, 64, 48, + 44, 36, 32, 24, 22, 18, 16, 8, 4, 2).*/ +#if defined(CUSTOM_MODES) +static const opus_uint32 CELT_PVQ_U_DATA[1488]={ +#else +static const opus_uint32 CELT_PVQ_U_DATA[1272]={ +#endif + /*N=0, K=0...176:*/ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +#if defined(CUSTOM_MODES) + /*...208:*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, +#endif + /*N=1, K=1...176:*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +#if defined(CUSTOM_MODES) + /*...208:*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, +#endif + /*N=2, K=2...176:*/ + 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, + 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, + 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, + 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143, + 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, + 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, + 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, + 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, + 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293, + 295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319, 321, 323, + 325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, +#if defined(CUSTOM_MODES) + /*...208:*/ + 353, 355, 357, 359, 361, 363, 365, 367, 369, 371, 373, 375, 377, 379, 381, + 383, 385, 387, 389, 391, 393, 395, 397, 399, 401, 403, 405, 407, 409, 411, + 413, 415, +#endif + /*N=3, K=3...176:*/ + 13, 25, 41, 61, 85, 113, 145, 181, 221, 265, 313, 365, 421, 481, 545, 613, + 685, 761, 841, 925, 1013, 1105, 1201, 1301, 1405, 1513, 1625, 1741, 1861, + 1985, 2113, 2245, 2381, 2521, 2665, 2813, 2965, 3121, 3281, 3445, 3613, 3785, + 3961, 4141, 4325, 4513, 4705, 4901, 5101, 5305, 5513, 5725, 5941, 6161, 6385, + 6613, 6845, 7081, 7321, 7565, 7813, 8065, 8321, 8581, 8845, 9113, 9385, 9661, + 9941, 10225, 10513, 10805, 11101, 11401, 11705, 12013, 12325, 12641, 12961, + 13285, 13613, 13945, 14281, 14621, 14965, 15313, 15665, 16021, 16381, 16745, + 17113, 17485, 17861, 18241, 18625, 19013, 19405, 19801, 20201, 20605, 21013, + 21425, 21841, 22261, 22685, 23113, 23545, 23981, 24421, 24865, 25313, 25765, + 26221, 26681, 27145, 27613, 28085, 28561, 29041, 29525, 30013, 30505, 31001, + 31501, 32005, 32513, 33025, 33541, 34061, 34585, 35113, 35645, 36181, 36721, + 37265, 37813, 38365, 38921, 39481, 40045, 40613, 41185, 41761, 42341, 42925, + 43513, 44105, 44701, 45301, 45905, 46513, 47125, 47741, 48361, 48985, 49613, + 50245, 50881, 51521, 52165, 52813, 53465, 54121, 54781, 55445, 56113, 56785, + 57461, 58141, 58825, 59513, 60205, 60901, 61601, +#if defined(CUSTOM_MODES) + /*...208:*/ + 62305, 63013, 63725, 64441, 65161, 65885, 66613, 67345, 68081, 68821, 69565, + 70313, 71065, 71821, 72581, 73345, 74113, 74885, 75661, 76441, 77225, 78013, + 78805, 79601, 80401, 81205, 82013, 82825, 83641, 84461, 85285, 86113, +#endif + /*N=4, K=4...176:*/ + 63, 129, 231, 377, 575, 833, 1159, 1561, 2047, 2625, 3303, 4089, 4991, 6017, + 7175, 8473, 9919, 11521, 13287, 15225, 17343, 19649, 22151, 24857, 27775, + 30913, 34279, 37881, 41727, 45825, 50183, 54809, 59711, 64897, 70375, 76153, + 82239, 88641, 95367, 102425, 109823, 117569, 125671, 134137, 142975, 152193, + 161799, 171801, 182207, 193025, 204263, 215929, 228031, 240577, 253575, + 267033, 280959, 295361, 310247, 325625, 341503, 357889, 374791, 392217, + 410175, 428673, 447719, 467321, 487487, 508225, 529543, 551449, 573951, + 597057, 620775, 645113, 670079, 695681, 721927, 748825, 776383, 804609, + 833511, 863097, 893375, 924353, 956039, 988441, 1021567, 1055425, 1090023, + 1125369, 1161471, 1198337, 1235975, 1274393, 1313599, 1353601, 1394407, + 1436025, 1478463, 1521729, 1565831, 1610777, 1656575, 1703233, 1750759, + 1799161, 1848447, 1898625, 1949703, 2001689, 2054591, 2108417, 2163175, + 2218873, 2275519, 2333121, 2391687, 2451225, 2511743, 2573249, 2635751, + 2699257, 2763775, 2829313, 2895879, 2963481, 3032127, 3101825, 3172583, + 3244409, 3317311, 3391297, 3466375, 3542553, 3619839, 3698241, 3777767, + 3858425, 3940223, 4023169, 4107271, 4192537, 4278975, 4366593, 4455399, + 4545401, 4636607, 4729025, 4822663, 4917529, 5013631, 5110977, 5209575, + 5309433, 5410559, 5512961, 5616647, 5721625, 5827903, 5935489, 6044391, + 6154617, 6266175, 6379073, 6493319, 6608921, 6725887, 6844225, 6963943, + 7085049, 7207551, +#if defined(CUSTOM_MODES) + /*...208:*/ + 7331457, 7456775, 7583513, 7711679, 7841281, 7972327, 8104825, 8238783, + 8374209, 8511111, 8649497, 8789375, 8930753, 9073639, 9218041, 9363967, + 9511425, 9660423, 9810969, 9963071, 10116737, 10271975, 10428793, 10587199, + 10747201, 10908807, 11072025, 11236863, 11403329, 11571431, 11741177, + 11912575, +#endif + /*N=5, K=5...176:*/ + 321, 681, 1289, 2241, 3649, 5641, 8361, 11969, 16641, 22569, 29961, 39041, + 50049, 63241, 78889, 97281, 118721, 143529, 172041, 204609, 241601, 283401, + 330409, 383041, 441729, 506921, 579081, 658689, 746241, 842249, 947241, + 1061761, 1186369, 1321641, 1468169, 1626561, 1797441, 1981449, 2179241, + 2391489, 2618881, 2862121, 3121929, 3399041, 3694209, 4008201, 4341801, + 4695809, 5071041, 5468329, 5888521, 6332481, 6801089, 7295241, 7815849, + 8363841, 8940161, 9545769, 10181641, 10848769, 11548161, 12280841, 13047849, + 13850241, 14689089, 15565481, 16480521, 17435329, 18431041, 19468809, + 20549801, 21675201, 22846209, 24064041, 25329929, 26645121, 28010881, + 29428489, 30899241, 32424449, 34005441, 35643561, 37340169, 39096641, + 40914369, 42794761, 44739241, 46749249, 48826241, 50971689, 53187081, + 55473921, 57833729, 60268041, 62778409, 65366401, 68033601, 70781609, + 73612041, 76526529, 79526721, 82614281, 85790889, 89058241, 92418049, + 95872041, 99421961, 103069569, 106816641, 110664969, 114616361, 118672641, + 122835649, 127107241, 131489289, 135983681, 140592321, 145317129, 150160041, + 155123009, 160208001, 165417001, 170752009, 176215041, 181808129, 187533321, + 193392681, 199388289, 205522241, 211796649, 218213641, 224775361, 231483969, + 238341641, 245350569, 252512961, 259831041, 267307049, 274943241, 282741889, + 290705281, 298835721, 307135529, 315607041, 324252609, 333074601, 342075401, + 351257409, 360623041, 370174729, 379914921, 389846081, 399970689, 410291241, + 420810249, 431530241, 442453761, 453583369, 464921641, 476471169, 488234561, + 500214441, 512413449, 524834241, 537479489, 550351881, 563454121, 576788929, + 590359041, 604167209, 618216201, 632508801, +#if defined(CUSTOM_MODES) + /*...208:*/ + 647047809, 661836041, 676876329, 692171521, 707724481, 723538089, 739615241, + 755958849, 772571841, 789457161, 806617769, 824056641, 841776769, 859781161, + 878072841, 896654849, 915530241, 934702089, 954173481, 973947521, 994027329, + 1014416041, 1035116809, 1056132801, 1077467201, 1099123209, 1121104041, + 1143412929, 1166053121, 1189027881, 1212340489, 1235994241, +#endif + /*N=6, K=6...96:*/ + 1683, 3653, 7183, 13073, 22363, 36365, 56695, 85305, 124515, 177045, 246047, + 335137, 448427, 590557, 766727, 982729, 1244979, 1560549, 1937199, 2383409, + 2908411, 3522221, 4235671, 5060441, 6009091, 7095093, 8332863, 9737793, + 11326283, 13115773, 15124775, 17372905, 19880915, 22670725, 25765455, + 29189457, 32968347, 37129037, 41699767, 46710137, 52191139, 58175189, + 64696159, 71789409, 79491819, 87841821, 96879431, 106646281, 117185651, + 128542501, 140763503, 153897073, 167993403, 183104493, 199284183, 216588185, + 235074115, 254801525, 275831935, 298228865, 322057867, 347386557, 374284647, + 402823977, 433078547, 465124549, 499040399, 534906769, 572806619, 612825229, + 655050231, 699571641, 746481891, 795875861, 847850911, 902506913, 959946283, + 1020274013, 1083597703, 1150027593, 1219676595, 1292660325, 1369097135, + 1449108145, 1532817275, 1620351277, 1711839767, 1807415257, 1907213187, + 2011371957, 2120032959, +#if defined(CUSTOM_MODES) + /*...109:*/ + 2233340609U, 2351442379U, 2474488829U, 2602633639U, 2736033641U, 2874848851U, + 3019242501U, 3169381071U, 3325434321U, 3487575323U, 3655980493U, 3830829623U, + 4012305913U, +#endif + /*N=7, K=7...54*/ + 8989, 19825, 40081, 75517, 134245, 227305, 369305, 579125, 880685, 1303777, + 1884961, 2668525, 3707509, 5064793, 6814249, 9041957, 11847485, 15345233, + 19665841, 24957661, 31388293, 39146185, 48442297, 59511829, 72616013, + 88043969, 106114625, 127178701, 151620757, 179861305, 212358985, 249612805, + 292164445, 340600625, 395555537, 457713341, 527810725, 606639529, 695049433, + 793950709, 904317037, 1027188385, 1163673953, 1314955181, 1482288821, + 1667010073, 1870535785, 2094367717, +#if defined(CUSTOM_MODES) + /*...60:*/ + 2340095869U, 2609401873U, 2904062449U, 3225952925U, 3577050821U, 3959439497U, +#endif + /*N=8, K=8...37*/ + 48639, 108545, 224143, 433905, 795455, 1392065, 2340495, 3800305, 5984767, + 9173505, 13726991, 20103025, 28875327, 40754369, 56610575, 77500017, + 104692735, 139703809, 184327311, 240673265, 311207743, 398796225, 506750351, + 638878193, 799538175, 993696769, 1226990095, 1505789553, 1837271615, + 2229491905U, +#if defined(CUSTOM_MODES) + /*...40:*/ + 2691463695U, 3233240945U, 3866006015U, +#endif + /*N=9, K=9...28:*/ + 265729, 598417, 1256465, 2485825, 4673345, 8405905, 14546705, 24331777, + 39490049, 62390545, 96220561, 145198913, 214828609, 312193553, 446304145, + 628496897, 872893441, 1196924561, 1621925137, 2173806145U, +#if defined(CUSTOM_MODES) + /*...29:*/ + 2883810113U, +#endif + /*N=10, K=10...24:*/ + 1462563, 3317445, 7059735, 14218905, 27298155, 50250765, 89129247, 152951073, + 254831667, 413442773, 654862247, 1014889769, 1541911931, 2300409629U, + 3375210671U, + /*N=11, K=11...19:*/ + 8097453, 18474633, 39753273, 81270333, 158819253, 298199265, 540279585, + 948062325, 1616336765, +#if defined(CUSTOM_MODES) + /*...20:*/ + 2684641785U, +#endif + /*N=12, K=12...18:*/ + 45046719, 103274625, 224298231, 464387817, 921406335, 1759885185, + 3248227095U, + /*N=13, K=13...16:*/ + 251595969, 579168825, 1267854873, 2653649025U, + /*N=14, K=14:*/ + 1409933619 +}; + +#if defined(CUSTOM_MODES) +const opus_uint32 *const CELT_PVQ_U_ROW[15]={ + CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 208,CELT_PVQ_U_DATA+ 415, + CELT_PVQ_U_DATA+ 621,CELT_PVQ_U_DATA+ 826,CELT_PVQ_U_DATA+1030, + CELT_PVQ_U_DATA+1233,CELT_PVQ_U_DATA+1336,CELT_PVQ_U_DATA+1389, + CELT_PVQ_U_DATA+1421,CELT_PVQ_U_DATA+1441,CELT_PVQ_U_DATA+1455, + CELT_PVQ_U_DATA+1464,CELT_PVQ_U_DATA+1470,CELT_PVQ_U_DATA+1473 +}; +#else +const opus_uint32 *const CELT_PVQ_U_ROW[15]={ + CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 176,CELT_PVQ_U_DATA+ 351, + CELT_PVQ_U_DATA+ 525,CELT_PVQ_U_DATA+ 698,CELT_PVQ_U_DATA+ 870, + CELT_PVQ_U_DATA+1041,CELT_PVQ_U_DATA+1131,CELT_PVQ_U_DATA+1178, + CELT_PVQ_U_DATA+1207,CELT_PVQ_U_DATA+1226,CELT_PVQ_U_DATA+1240, + CELT_PVQ_U_DATA+1248,CELT_PVQ_U_DATA+1254,CELT_PVQ_U_DATA+1257 +}; +#endif + +#if defined(CUSTOM_MODES) +void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){ + int k; + /*_maxk==0 => there's nothing to do.*/ + celt_assert(_maxk>0); + _bits[0]=0; + for(k=1;k<=_maxk;k++)_bits[k]=log2_frac(CELT_PVQ_V(_n,k),_frac); +} +#endif + +static opus_uint32 icwrs(int _n,const int *_y){ + opus_uint32 i; + int j; + int k; + celt_assert(_n>=2); + j=_n-1; + i=_y[j]<0; + k=abs(_y[j]); + do{ + j--; + i+=CELT_PVQ_U(_n-j,k); + k+=abs(_y[j]); + if(_y[j]<0)i+=CELT_PVQ_U(_n-j,k+1); + } + while(j>0); + return i; } -/*Compute V(2,_k).*/ -static inline opus_uint32 ncwrs2(int _k){ +void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){ celt_assert(_k>0); - return 4*(opus_uint32)_k; + ec_enc_uint(_enc,icwrs(_n,_y),CELT_PVQ_V(_n,_k)); } -/*Compute U(3,_k). - Note that this may be called with _k=32768 (maxK[3]+1).*/ -static inline opus_uint32 ucwrs3(unsigned _k){ +static void cwrsi(int _n,int _k,opus_uint32 _i,int *_y){ + opus_uint32 p; + int s; + int k0; celt_assert(_k>0); - return (2*(opus_uint32)_k-2)*_k+1; + celt_assert(_n>1); + while(_n>2){ + opus_uint32 q; + /*Lots of pulses case:*/ + if(_k>=_n){ + const opus_uint32 *row; + row=CELT_PVQ_U_ROW[_n]; + /*Are the pulses in this dimension negative?*/ + p=row[_k+1]; + s=-(_i>=p); + _i-=p&s; + /*Count how many pulses were placed in this dimension.*/ + k0=_k; + q=row[_n]; + if(q>_i){ + celt_assert(p>q); + _k=_n; + do p=CELT_PVQ_U_ROW[--_k][_n]; + while(p>_i); + } + else for(p=row[_k];p>_i;p=row[_k])_k--; + _i-=p; + *_y++=(k0-_k+s)^s; + } + /*Lots of dimensions case:*/ + else{ + /*Are there any pulses in this dimension at all?*/ + p=CELT_PVQ_U_ROW[_k][_n]; + q=CELT_PVQ_U_ROW[_k+1][_n]; + if(p<=_i&&_i=q); + _i-=q&s; + /*Count how many pulses were placed in this dimension.*/ + k0=_k; + do p=CELT_PVQ_U_ROW[--_k][_n]; + while(p>_i); + _i-=p; + *_y++=(k0-_k+s)^s; + } + } + _n--; + } + /*_n==2*/ + p=2*_k+1; + s=-(_i>=p); + _i-=p&s; + k0=_k; + _k=(_i+1)>>1; + if(_k)_i-=2*_k-1; + *_y++=(k0-_k+s)^s; + /*_n==1*/ + s=-(int)_i; + *_y=(_k+s)^s; } -/*Compute V(3,_k).*/ -static inline opus_uint32 ncwrs3(int _k){ - celt_assert(_k>0); - return 2*(2*(unsigned)_k*(opus_uint32)_k+1); +void decode_pulses(int *_y,int _n,int _k,ec_dec *_dec){ + cwrsi(_n,_k,ec_dec_uint(_dec,CELT_PVQ_V(_n,_k)),_y); } -/*Compute U(4,_k).*/ -static inline opus_uint32 ucwrs4(int _k){ - celt_assert(_k>0); - return imusdiv32odd(2*_k,(2*_k-3)*(opus_uint32)_k+4,3,1); -} - -/*Compute V(4,_k).*/ -static inline opus_uint32 ncwrs4(int _k){ - celt_assert(_k>0); - return ((_k*(opus_uint32)_k+2)*_k)/3<<3; -} - -#endif /* SMALL_FOOTPRINT */ +#else /* SMALL_FOOTPRINT */ /*Computes the next row/column of any recurrence that obeys the relation u[i][j]=u[i-1][j]+u[i][j-1]+u[i-1][j-1]. @@ -339,125 +574,18 @@ static opus_uint32 ncwrs_urow(unsigned _n,unsigned _k,opus_uint32 *_u){ celt_assert(len>=3); _u[0]=0; _u[1]=um2=1; -#ifndef SMALL_FOOTPRINT - /*_k>52 doesn't work in the false branch due to the limits of INV_TABLE, - but _k isn't tested here because k<=52 for n=7*/ - if(_n<=6) -#endif - { - /*If _n==0, _u[0] should be 1 and the rest should be 0.*/ - /*If _n==1, _u[i] should be 1 for i>1.*/ - celt_assert(_n>=2); - /*If _k==0, the following do-while loop will overflow the buffer.*/ - celt_assert(_k>0); - k=2; - do _u[k]=(k<<1)-1; - while(++k=len)break; - _u[k]=um1=imusdiv32odd(n2m1,um2,um1,(k-1)>>1)+um1; - } - } -#endif /* SMALL_FOOTPRINT */ + /*If _n==0, _u[0] should be 1 and the rest should be 0.*/ + /*If _n==1, _u[i] should be 1 for i>1.*/ + celt_assert(_n>=2); + /*If _k==0, the following do-while loop will overflow the buffer.*/ + celt_assert(_k>0); + k=2; + do _u[k]=(k<<1)-1; + while(++k=p); - _i-=p&s; - yj=_k; - _k=(_i+1)>>1; - p=_k?ucwrs2(_k):0; - _i-=p; - yj-=_k; - _y[0]=(yj+s)^s; - cwrsi1(_k,_i,_y+1); -} - -/*Returns the _i'th combination of _k elements (at most 32767) chosen from a - set of size 3 with associated sign bits. - _y: Returns the vector of pulses.*/ -static void cwrsi3(int _k,opus_uint32 _i,int *_y){ - opus_uint32 p; - int s; - int yj; - p=ucwrs3(_k+1U); - s=-(_i>=p); - _i-=p&s; - yj=_k; - /*Finds the maximum _k such that ucwrs3(_k)<=_i (tested for all - _i<2147418113=U(3,32768)).*/ - _k=_i>0?(isqrt32(2*_i-1)+1)>>1:0; - p=_k?ucwrs3(_k):0; - _i-=p; - yj-=_k; - _y[0]=(yj+s)^s; - cwrsi2(_k,_i,_y+1); -} - -/*Returns the _i'th combination of _k elements (at most 1172) chosen from a set - of size 4 with associated sign bits. - _y: Returns the vector of pulses.*/ -static void cwrsi4(int _k,opus_uint32 _i,int *_y){ - opus_uint32 p; - int s; - int yj; - int kl; - int kr; - p=ucwrs4(_k+1); - s=-(_i>=p); - _i-=p&s; - yj=_k; - /*We could solve a cubic for k here, but the form of the direct solution does - not lend itself well to exact integer arithmetic. - Instead we do a binary search on U(4,K).*/ - kl=0; - kr=_k; - for(;;){ - _k=(kl+kr)>>1; - p=_k?ucwrs4(_k):0; - if(p<_i){ - if(_k>=kr)break; - kl=_k+1; - } - else if(p>_i)kr=_k-1; - else break; - } - _i-=p; - yj-=_k; - _y[0]=(yj+s)^s; - cwrsi3(_k,_i,_y+1); -} - -#endif /* SMALL_FOOTPRINT */ - /*Returns the _i'th combination of _k elements chosen from a set of size _n with associated sign bits. _y: Returns the vector of pulses. @@ -494,55 +622,6 @@ static inline opus_uint32 icwrs1(const int *_y,int *_k){ return _y[0]<0; } -#ifndef SMALL_FOOTPRINT - -/*Returns the index of the given combination of K elements chosen from a set - of size 2 with associated sign bits. - _y: The vector of pulses, whose sum of absolute values is K. - _k: Returns K.*/ -static inline opus_uint32 icwrs2(const int *_y,int *_k){ - opus_uint32 i; - int k; - i=icwrs1(_y+1,&k); - i+=k?ucwrs2(k):0; - k+=abs(_y[0]); - if(_y[0]<0)i+=ucwrs2(k+1U); - *_k=k; - return i; -} - -/*Returns the index of the given combination of K elements chosen from a set - of size 3 with associated sign bits. - _y: The vector of pulses, whose sum of absolute values is K. - _k: Returns K.*/ -static inline opus_uint32 icwrs3(const int *_y,int *_k){ - opus_uint32 i; - int k; - i=icwrs2(_y+1,&k); - i+=k?ucwrs3(k):0; - k+=abs(_y[0]); - if(_y[0]<0)i+=ucwrs3(k+1U); - *_k=k; - return i; -} - -/*Returns the index of the given combination of K elements chosen from a set - of size 4 with associated sign bits. - _y: The vector of pulses, whose sum of absolute values is K. - _k: Returns K.*/ -static inline opus_uint32 icwrs4(const int *_y,int *_k){ - opus_uint32 i; - int k; - i=icwrs3(_y+1,&k); - i+=k?ucwrs4(k):0; - k+=abs(_y[0]); - if(_y[0]<0)i+=ucwrs4(k+1); - *_k=k; - return i; -} - -#endif /* SMALL_FOOTPRINT */ - /*Returns the index of the given combination of K elements chosen from a set of size _n with associated sign bits. _y: The vector of pulses, whose sum of absolute values must be _k. @@ -550,8 +629,8 @@ static inline opus_uint32 icwrs4(const int *_y,int *_k){ static inline opus_uint32 icwrs(int _n,int _k,opus_uint32 *_nc,const int *_y, opus_uint32 *_u){ opus_uint32 i; - int j; - int k; + int j; + int k; /*We can't unroll the first two iterations of the loop unless _n>=2.*/ celt_assert(_n>=2); _u[0]=0; @@ -596,57 +675,23 @@ void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){ void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){ opus_uint32 i; + VARDECL(opus_uint32,u); + opus_uint32 nc; + SAVE_STACK; celt_assert(_k>0); -#ifndef SMALL_FOOTPRINT - switch(_n){ - case 2:{ - i=icwrs2(_y,&_k); - ec_enc_uint(_enc,i,ncwrs2(_k)); - }break; - case 3:{ - i=icwrs3(_y,&_k); - ec_enc_uint(_enc,i,ncwrs3(_k)); - }break; - case 4:{ - i=icwrs4(_y,&_k); - ec_enc_uint(_enc,i,ncwrs4(_k)); - }break; - default: - { -#endif - VARDECL(opus_uint32,u); - opus_uint32 nc; - SAVE_STACK; - ALLOC(u,_k+2U,opus_uint32); - i=icwrs(_n,_k,&nc,_y,u); - ec_enc_uint(_enc,i,nc); - RESTORE_STACK; -#ifndef SMALL_FOOTPRINT - } - break; - } -#endif + ALLOC(u,_k+2U,opus_uint32); + i=icwrs(_n,_k,&nc,_y,u); + ec_enc_uint(_enc,i,nc); + RESTORE_STACK; } -void decode_pulses(int *_y,int _n,int _k,ec_dec *_dec) -{ +void decode_pulses(int *_y,int _n,int _k,ec_dec *_dec){ + VARDECL(opus_uint32,u); + SAVE_STACK; celt_assert(_k>0); -#ifndef SMALL_FOOTPRINT - switch(_n){ - case 2:cwrsi2(_k,ec_dec_uint(_dec,ncwrs2(_k)),_y);break; - case 3:cwrsi3(_k,ec_dec_uint(_dec,ncwrs3(_k)),_y);break; - case 4:cwrsi4(_k,ec_dec_uint(_dec,ncwrs4(_k)),_y);break; - default: - { -#endif - VARDECL(opus_uint32,u); - SAVE_STACK; - ALLOC(u,_k+2U,opus_uint32); - cwrsi(_n,_k,ec_dec_uint(_dec,ncwrs_urow(_n,_k,u)),_y,u); - RESTORE_STACK; -#ifndef SMALL_FOOTPRINT - } - break; - } -#endif + ALLOC(u,_k+2U,opus_uint32); + cwrsi(_n,_k,ec_dec_uint(_dec,ncwrs_urow(_n,_k,u)),_y,u); + RESTORE_STACK; } + +#endif /* SMALL_FOOTPRINT */ diff --git a/media/libopus/celt/cwrs.h b/media/libopus/celt/cwrs.h index 14c4ce67998d..7dfbd076d169 100644 --- a/media/libopus/celt/cwrs.h +++ b/media/libopus/celt/cwrs.h @@ -1,11 +1,8 @@ -/* Copyright (c) 2007-2012 IETF Trust, CSIRO, Xiph.Org Foundation, - Timothy B. Terriberry. All rights reserved. +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2007-2009 Timothy B. Terriberry Written by Timothy B. Terriberry and Jean-Marc Valin */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -17,11 +14,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR diff --git a/media/libopus/celt/ecintrin.h b/media/libopus/celt/ecintrin.h index f8327f68890b..be57dd40de91 100644 --- a/media/libopus/celt/ecintrin.h +++ b/media/libopus/celt/ecintrin.h @@ -1,10 +1,6 @@ -/* Copyright (c) 2003-2012 IETF Trust, Timothy B. Terriberry, - Xiph.Org Foundation. All rights reserved.*/ +/* Copyright (c) 2003-2008 Timothy B. Terriberry + Copyright (c) 2008 Xiph.Org Foundation */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -57,7 +48,7 @@ /*Count leading zeros. This macro should only be used for implementing ec_ilog(), if it is defined. All other code should use EC_ILOG() instead.*/ -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1400) # include /*In _DEBUG mode this is not an intrinsic by default.*/ # pragma intrinsic(_BitScanReverse) diff --git a/media/libopus/celt/entcode.c b/media/libopus/celt/entcode.c index 9151a921a2d0..fa5d7c7c2c92 100644 --- a/media/libopus/celt/entcode.c +++ b/media/libopus/celt/entcode.c @@ -1,10 +1,6 @@ -/* Copyright (c) 2001-2012 IETF Trust, Timothy B. Terriberry. All rights reserved. +/* Copyright (c) 2001-2011 Timothy B. Terriberry */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -42,6 +33,11 @@ #include "arch.h" #if !defined(EC_CLZ) +/*This is a fallback for systems where we don't know how to access + a BSR or CLZ instruction (see ecintrin.h). + If you are optimizing Opus on a new platform and it has a native CLZ or + BZR (e.g. cell, MIPS, x86, etc) then making it available to Opus will be + an easy performance win.*/ int ec_ilog(opus_uint32 _v){ /*On a Pentium M, this branchless version tested as the fastest on 1,000,000,000 random 32-bit integers, edging out a similar version with diff --git a/media/libopus/celt/entcode.h b/media/libopus/celt/entcode.h index f0b0bda436f3..aebecc064756 100644 --- a/media/libopus/celt/entcode.h +++ b/media/libopus/celt/entcode.h @@ -1,10 +1,6 @@ -/* Copyright (c) 2001-2012 IETF Trust, Timothy B. Terriberry, - Xiph.Org Foundation. All rights reserved.*/ +/* Copyright (c) 2001-2011 Timothy B. Terriberry + Copyright (c) 2008-2009 Xiph.Org Foundation */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR diff --git a/media/libopus/celt/entdec.c b/media/libopus/celt/entdec.c index c407fb9a5e8c..3c264685c262 100644 --- a/media/libopus/celt/entdec.c +++ b/media/libopus/celt/entdec.c @@ -1,10 +1,6 @@ -/* Copyright (c) 2001-2012 IETF Trust, Timothy B. Terriberry, - Xiph.Org Foundation. All rights reserved.*/ +/* Copyright (c) 2001-2011 Timothy B. Terriberry + Copyright (c) 2008-2009 Xiph.Org Foundation */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -94,7 +85,7 @@ number=3, pages="256--294", month=Jul, - URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf" + URL="http://www.stanford.edu/class/ee398a/handouts/papers/Moffat98ArithmCoding.pdf" }*/ static int ec_read_byte(ec_dec *_this){ diff --git a/media/libopus/celt/entdec.h b/media/libopus/celt/entdec.h index b59b2471a100..d8ab31873088 100644 --- a/media/libopus/celt/entdec.h +++ b/media/libopus/celt/entdec.h @@ -1,10 +1,6 @@ -/* Copyright (c) 2001-2012 IETF Trust, Timothy B. Terriberry, - Xiph.Org Foundation. All rights reserved.*/ +/* Copyright (c) 2001-2011 Timothy B. Terriberry + Copyright (c) 2008-2009 Xiph.Org Foundation */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR diff --git a/media/libopus/celt/entenc.c b/media/libopus/celt/entenc.c index 467928bd01c3..a7e34ecef971 100644 --- a/media/libopus/celt/entenc.c +++ b/media/libopus/celt/entenc.c @@ -1,10 +1,6 @@ -/* Copyright (c) 2001-2012 IETF Trust, Timothy B. Terriberry, - Xiph.Org Foundation. All rights reserved.*/ +/* Copyright (c) 2001-2011 Timothy B. Terriberry + Copyright (c) 2008-2009 Xiph.Org Foundation */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR diff --git a/media/libopus/celt/entenc.h b/media/libopus/celt/entenc.h index 7bbe8e82153c..796bc4d5727f 100644 --- a/media/libopus/celt/entenc.h +++ b/media/libopus/celt/entenc.h @@ -1,10 +1,6 @@ -/* Copyright (c) 2001-2012 IETF Trust, Timothy B. Terriberry, - Xiph.Org Foundation. All rights reserved.*/ +/* Copyright (c) 2001-2011 Timothy B. Terriberry + Copyright (c) 2008-2009 Xiph.Org Foundation */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR diff --git a/media/libopus/celt/fixed_debug.h b/media/libopus/celt/fixed_debug.h index a5f5149530b7..f11d890dff59 100644 --- a/media/libopus/celt/fixed_debug.h +++ b/media/libopus/celt/fixed_debug.h @@ -1,14 +1,10 @@ -/* Copyright (C) 2003-2012 IETF Trust, Jean-Marc Valin, - Xiph.Org Foundation. All rights reserved.*/ +/* Copyright (C) 2003-2008 Jean-Marc Valin + Copyright (C) 2007-2012 Xiph.Org Foundation */ /** @file fixed_debug.h @brief Fixed-point operations with debugging */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -20,11 +16,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -44,9 +35,10 @@ #include #ifdef CELT_C -long long celt_mips=0; +#include "opus_defines.h" +OPUS_EXPORT opus_int64 celt_mips=0; #else -extern long long celt_mips; +extern opus_int64 celt_mips; #endif #define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b)) @@ -55,6 +47,8 @@ extern long long celt_mips; /** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ #define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR32((b),16)), SHR32(MULT16_16SU((a),((b)&0x0000ffff)),16)) +#define MULT16_32_P16(a,b) MULT16_32_PX(a,b,16) + #define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits)))) #define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits)))) @@ -71,23 +65,39 @@ static inline short NEG16(int x) if (!VERIFY_SHORT(x)) { fprintf (stderr, "NEG16: input is not short: %d\n", (int)x); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } res = -x; if (!VERIFY_SHORT(res)) + { fprintf (stderr, "NEG16: output is not short: %d\n", (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } celt_mips++; return res; } -static inline int NEG32(long long x) +static inline int NEG32(opus_int64 x) { - long long res; + opus_int64 res; if (!VERIFY_INT(x)) { fprintf (stderr, "NEG16: input is not int: %d\n", (int)x); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } res = -x; if (!VERIFY_INT(res)) + { fprintf (stderr, "NEG16: output is not int: %d\n", (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } celt_mips+=2; return res; } @@ -99,6 +109,9 @@ static inline short EXTRACT16_(int x, char *file, int line) if (!VERIFY_SHORT(x)) { fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } res = x; celt_mips++; @@ -112,6 +125,9 @@ static inline int EXTEND32_(int x, char *file, int line) if (!VERIFY_SHORT(x)) { fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } res = x; celt_mips++; @@ -125,10 +141,18 @@ static inline short SHR16_(int a, int shift, char *file, int line) if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) { fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } res = a>>shift; if (!VERIFY_SHORT(res)) + { fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } celt_mips++; return res; } @@ -139,40 +163,61 @@ static inline short SHL16_(int a, int shift, char *file, int line) if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) { fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } res = a<>shift; if (!VERIFY_INT(res)) { fprintf (stderr, "SHR32: output is not int: %d\n", (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } celt_mips+=2; return res; } -static inline int SHL32(long long a, int shift) +#define SHL32(a, shift) SHL32_(a, shift, __FILE__, __LINE__) +static inline int SHL32_(opus_int64 a, int shift, char *file, int line) { - long long res; + opus_int64 res; if (!VERIFY_INT(a) || !VERIFY_SHORT(shift)) { - fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int)a, shift); + fprintf (stderr, "SHL32: inputs are not int: %lld %d in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } res = a<=((opus_val32)(1)<<(15+Q))) + { fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); - res = (((long long)a)*(long long)b) >> Q; +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = (((opus_int64)a)*(opus_int64)b) >> Q; if (!VERIFY_INT(res)) + { fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } if (Q==15) celt_mips+=3; else @@ -340,6 +461,39 @@ static inline int MULT16_32_QX_(int a, long long b, int Q, char *file, int line) return res; } +#define MULT16_32_PX(a, b, Q) MULT16_32_PX_(a, b, Q, __FILE__, __LINE__) +static inline int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line) +{ + opus_int64 res; + if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d in %s: line %d\n\n", Q, (int)a, (int)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + if (ABS32(b)>=((opus_int64)(1)<<(15+Q))) + { + fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n\n", Q, (int)a, (int)b,file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = ((((opus_int64)a)*(opus_int64)b) + (((opus_val32)(1)<>1))>> Q; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d in %s: line %d\n\n", Q, (int)a, (int)b,(int)res, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + if (Q==15) + celt_mips+=4; + else + celt_mips+=5; + return res; +} + #define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15) #define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b)))) @@ -355,43 +509,67 @@ static inline int SATURATE(int a, int b) static inline int MULT16_16_Q11_32(int a, int b) { - long long res; + opus_int64 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } - res = ((long long)a)*b; + res = ((opus_int64)a)*b; res >>= 11; if (!VERIFY_INT(res)) + { fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } celt_mips+=3; return res; } static inline short MULT16_16_Q13(int a, int b) { - long long res; + opus_int64 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } - res = ((long long)a)*b; + res = ((opus_int64)a)*b; res >>= 13; if (!VERIFY_SHORT(res)) + { fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } celt_mips+=3; return res; } static inline short MULT16_16_Q14(int a, int b) { - long long res; + opus_int64 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } - res = ((long long)a)*b; + res = ((opus_int64)a)*b; res >>= 14; if (!VERIFY_SHORT(res)) + { fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } celt_mips+=3; return res; } @@ -399,16 +577,22 @@ static inline short MULT16_16_Q14(int a, int b) #define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__) static inline short MULT16_16_Q15_(int a, int b, char *file, int line) { - long long res; + opus_int64 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } - res = ((long long)a)*b; + res = ((opus_int64)a)*b; res >>= 15; if (!VERIFY_SHORT(res)) { fprintf (stderr, "MULT16_16_Q15: output is not short: %d in %s: line %d\n", (int)res, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } celt_mips+=1; return res; @@ -416,69 +600,114 @@ static inline short MULT16_16_Q15_(int a, int b, char *file, int line) static inline short MULT16_16_P13(int a, int b) { - long long res; + opus_int64 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } - res = ((long long)a)*b; + res = ((opus_int64)a)*b; res += 4096; if (!VERIFY_INT(res)) + { fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } res >>= 13; if (!VERIFY_SHORT(res)) + { fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } celt_mips+=4; return res; } static inline short MULT16_16_P14(int a, int b) { - long long res; + opus_int64 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } - res = ((long long)a)*b; + res = ((opus_int64)a)*b; res += 8192; if (!VERIFY_INT(res)) + { fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } res >>= 14; if (!VERIFY_SHORT(res)) + { fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } celt_mips+=4; return res; } static inline short MULT16_16_P15(int a, int b) { - long long res; + opus_int64 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } - res = ((long long)a)*b; + res = ((opus_int64)a)*b; res += 16384; if (!VERIFY_INT(res)) + { fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } res >>= 15; if (!VERIFY_SHORT(res)) + { fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } celt_mips+=2; return res; } #define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__) -static inline int DIV32_16_(long long a, long long b, char *file, int line) +static inline int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line) { - long long res; + opus_int64 res; if (b==0) { fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif return 0; } if (!VERIFY_INT(a) || !VERIFY_SHORT(b)) { fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } res = a/b; if (!VERIFY_SHORT(res)) @@ -488,28 +717,42 @@ static inline int DIV32_16_(long long a, long long b, char *file, int line) res = 32767; if (res<-32768) res = -32768; +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } celt_mips+=35; return res; } #define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__) -static inline int DIV32_(long long a, long long b, char *file, int line) +static inline int DIV32_(opus_int64 a, opus_int64 b, char *file, int line) { - long long res; + opus_int64 res; if (b==0) { fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif return 0; } if (!VERIFY_INT(a) || !VERIFY_INT(b)) { fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif } res = a/b; if (!VERIFY_INT(res)) + { fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } celt_mips+=70; return res; } diff --git a/media/libopus/celt/fixed_generic.h b/media/libopus/celt/fixed_generic.h index 0137411c2583..0e77976e83bb 100644 --- a/media/libopus/celt/fixed_generic.h +++ b/media/libopus/celt/fixed_generic.h @@ -1,14 +1,11 @@ -/* Copyright (C) 2002-2012 IETF Trust, Xiph.Org Foundation, - Jean-Marc Valin, CSIRO. All rights reserved.*/ +/* Copyright (C) 2007-2009 Xiph.Org Foundation + Copyright (C) 2003-2008 Jean-Marc Valin + Copyright (C) 2007-2008 CSIRO */ /** @file fixed_generic.h @brief Generic fixed-point operations */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -20,11 +17,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -47,6 +39,9 @@ /** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ #define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16)) +/** 16x32 multiplication, followed by a 16-bit shift right (round-to-nearest). Results fits in 32 bits */ +#define MULT16_32_P16(a,b) ADD32(MULT16_16((a),SHR((b),16)), PSHR(MULT16_16((a),((b)&0x0000ffff)),16)) + /** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */ #define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15)) @@ -89,6 +84,8 @@ #define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift)) #define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) +#define SATURATE16(x) (EXTRACT16((x)>32767 ? 32767 : (x)<-32768 ? -32768 : (x))) + /** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */ #define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a)))) /** Divide by two */ @@ -113,7 +110,9 @@ /** 16x16 multiply-add where the result fits in 32 bits */ #define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b)))) -/** 16x32 multiply-add, followed by a 15-bit shift right. Results fits in 32 bits */ +/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add. + b must fit in 31 bits. + Result fits in 32 bits. */ #define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))) #define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11)) diff --git a/media/libopus/celt/float_cast.h b/media/libopus/celt/float_cast.h index b0f2352e5011..5ded29159986 100644 --- a/media/libopus/celt/float_cast.h +++ b/media/libopus/celt/float_cast.h @@ -1,9 +1,5 @@ -/* Copyright (C) 2001-2012 IETF Trust, Erik de Castro Lopo. All rights reserved.*/ +/* Copyright (C) 2001 Erik de Castro Lopo */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -15,11 +11,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -99,14 +90,14 @@ #include #define float2int(x) lrint(x) -#elif (defined (WIN64) || defined (_WIN64)) +#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined (WIN64) || defined (_WIN64)) #include __inline long int float2int(float value) { return _mm_cvtss_si32(_mm_load_ss(&value)); } -#elif (defined (WIN32) || defined (_WIN32)) +#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined (WIN32) || defined (_WIN32)) #include /* Win32 doesn't seem to have these functions. @@ -136,6 +127,7 @@ #define float2int(flt) ((int)(floor(.5+flt))) #endif +#ifndef DISABLE_FLOAT_API static inline opus_int16 FLOAT2INT16(float x) { x = x*CELT_SIG_SCALE; @@ -143,5 +135,6 @@ static inline opus_int16 FLOAT2INT16(float x) x = MIN32(x, 32767); return (opus_int16)float2int(x); } +#endif /* DISABLE_FLOAT_API */ #endif /* FLOAT_CAST_H */ diff --git a/media/libopus/celt/kiss_fft.c b/media/libopus/celt/kiss_fft.c index bd547979ac05..ad706c739717 100644 --- a/media/libopus/celt/kiss_fft.c +++ b/media/libopus/celt/kiss_fft.c @@ -1,9 +1,9 @@ -/*Copyright (c) 2003-2012 IETF Trust, Mark Borgerding, Jean-Marc Valin - Xiph.Org Foundation, CSIRO. All rights reserved. +/*Copyright (c) 2003-2004, Mark Borgerding + Lots of modifications by Jean-Marc Valin + Copyright (c) 2005-2007, Xiph.Org Foundation + Copyright (c) 2008, Xiph.Org Foundation, CSIRO - - This file is extracted from RFC6716. Please see that RFC for additional - information. + All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -14,11 +14,6 @@ this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -45,7 +40,6 @@ #include "os_support.h" #include "mathops.h" #include "stack_alloc.h" -#include "os_support.h" /* The guts header contains all the multiplication and addition macros that are defined for complex numbers. It also delares the kf_ internal functions. @@ -72,8 +66,8 @@ static void kf_bfly2( for(j=0;jr = SHR(Fout->r, 1);Fout->i = SHR(Fout->i, 1); - Fout2->r = SHR(Fout2->r, 1);Fout2->i = SHR(Fout2->i, 1); + Fout->r = SHR32(Fout->r, 1);Fout->i = SHR32(Fout->i, 1); + Fout2->r = SHR32(Fout2->r, 1);Fout2->i = SHR32(Fout2->i, 1); C_MUL (t, *Fout2 , *tw1); tw1 += fstride; C_SUB( *Fout2 , *Fout , t ); @@ -141,14 +135,12 @@ static void kf_bfly4( C_MUL4(scratch[1],Fout[m2] , *tw2 ); C_MUL4(scratch[2],Fout[m3] , *tw3 ); - Fout->r = PSHR(Fout->r, 2); - Fout->i = PSHR(Fout->i, 2); + Fout->r = PSHR32(Fout->r, 2); + Fout->i = PSHR32(Fout->i, 2); C_SUB( scratch[5] , *Fout, scratch[1] ); C_ADDTO(*Fout, scratch[1]); C_ADD( scratch[3] , scratch[0] , scratch[2] ); C_SUB( scratch[4] , scratch[0] , scratch[2] ); - Fout[m2].r = PSHR(Fout[m2].r, 2); - Fout[m2].i = PSHR(Fout[m2].i, 2); C_SUB( Fout[m2], *Fout, scratch[3] ); tw1 += fstride; tw2 += fstride*2; @@ -564,7 +556,7 @@ kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, co st->nfft=nfft; #ifndef FIXED_POINT - st->scale = 1./nfft; + st->scale = 1.f/nfft; #endif if (base != NULL) { diff --git a/media/libopus/celt/kiss_fft.h b/media/libopus/celt/kiss_fft.h index e13f6af486f6..66332e3bb95b 100644 --- a/media/libopus/celt/kiss_fft.h +++ b/media/libopus/celt/kiss_fft.h @@ -1,9 +1,9 @@ -/*Copyright (c) 2003-2012 IETF Trust, Mark Borgerding, Jean-Marc Valin - Xiph.Org Foundation, CSIRO. All rights reserved. +/*Copyright (c) 2003-2004, Mark Borgerding + Lots of modifications by Jean-Marc Valin + Copyright (c) 2005-2007, Xiph.Org Foundation + Copyright (c) 2008, Xiph.Org Foundation, CSIRO - - This file is extracted from RFC6716. Please see that RFC for additional - information. + All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -14,11 +14,6 @@ this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE diff --git a/media/libopus/celt/laplace.c b/media/libopus/celt/laplace.c index 56b2ecd95e7c..a7bca874b6e6 100644 --- a/media/libopus/celt/laplace.c +++ b/media/libopus/celt/laplace.c @@ -1,10 +1,7 @@ -/* Copyright (c) 2007-2012 IETF Trust, CSIRO, Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2007 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +13,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -48,11 +40,12 @@ direction). */ #define LAPLACE_NMIN (16) +/* When called, decay is positive and at most 11456. */ static unsigned ec_laplace_get_freq1(unsigned fs0, int decay) { unsigned ft; ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN) - fs0; - return ft*(16384-decay)>>15; + return ft*(opus_int32)(16384-decay)>>15; } void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay) diff --git a/media/libopus/celt/laplace.h b/media/libopus/celt/laplace.h index 1693ef7b78b5..46c14b5da583 100644 --- a/media/libopus/celt/laplace.h +++ b/media/libopus/celt/laplace.h @@ -1,10 +1,7 @@ -/* Copyright (c) 2007-2012 IETF Trust, CSIRO, Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2007 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +13,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR diff --git a/media/libopus/celt/mathops.c b/media/libopus/celt/mathops.c index e91ec4340d4e..21fd94296025 100644 --- a/media/libopus/celt/mathops.c +++ b/media/libopus/celt/mathops.c @@ -1,15 +1,12 @@ -/* Copyright (c) 2002-2012 IETF Trust, Jean-Marc Valin, - CSIRO, Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2002-2008 Jean-Marc Valin + Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /** @file mathops.h @brief Various math functions */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -21,11 +18,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -83,10 +75,15 @@ opus_val32 frac_div32(opus_val32 a, opus_val32 b) b = VSHR32(b,shift); /* 16-bit reciprocal */ rcp = ROUND16(celt_rcp(ROUND16(b,16)),3); - result = SHL32(MULT16_32_Q15(rcp, a),2); - rem = a-MULT32_32_Q31(result, b); - result += SHL32(MULT16_32_Q15(rcp, rem),2); - return result; + result = MULT16_32_Q15(rcp, a); + rem = PSHR32(a,2)-MULT32_32_Q31(result, b); + result = ADD32(result, SHL32(MULT16_32_Q15(rcp, rem),2)); + if (result >= 536870912) /* 2^29 */ + return 2147483647; /* 2^31 - 1 */ + else if (result <= -536870912) /* -2^29 */ + return -2147483647; /* -2^31 */ + else + return SHL32(result, 2); } /** Reciprocal sqrt approximation in the range [0.25,1) (Q16 in, Q14 out) */ @@ -126,6 +123,8 @@ opus_val32 celt_sqrt(opus_val32 x) static const opus_val16 C[5] = {23175, 11561, -3011, 1699, -664}; if (x==0) return 0; + else if (x>=1073741824) + return 32767; k = (celt_ilog2(x)>>1)-7; x = VSHR32(x, 2*k); n = x-32768; diff --git a/media/libopus/celt/mathops.h b/media/libopus/celt/mathops.h index 3a45f46982da..44fa97c69751 100644 --- a/media/libopus/celt/mathops.h +++ b/media/libopus/celt/mathops.h @@ -1,15 +1,12 @@ -/* Copyright (c) 2002-2012 IETF Trust, Jean-Marc Valin, CSIRO, - Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2002-2008 Jean-Marc Valin + Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /** @file mathops.h @brief Various math functions */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -21,11 +18,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -51,6 +43,41 @@ unsigned isqrt32(opus_uint32 _val); +#ifndef OVERRIDE_CELT_MAXABS16 +static inline opus_val32 celt_maxabs16(const opus_val16 *x, int len) +{ + int i; + opus_val16 maxval = 0; + opus_val16 minval = 0; + for (i=0;in; - N >>= shift; - N2 = N>>1; - N4 = N>>2; - ALLOC(f, N2, kiss_fft_scalar); - /* sin(x) ~= x here */ -#ifdef FIXED_POINT - sine = TRIG_UPSCALE*(QCONST16(0.7853981f, 15)+N2)/N; -#else - sine = (kiss_twiddle_scalar)2*PI*(.125f)/N; -#endif - - /* Consider the input to be composed of four blocks: [a, b, c, d] */ - /* Window, shuffle, fold */ - { - /* Temp pointers to make it really clear to the compiler what we're doing */ - const kiss_fft_scalar * restrict xp1 = in+(overlap>>1); - const kiss_fft_scalar * restrict xp2 = in+N2-1+(overlap>>1); - kiss_fft_scalar * restrict yp = f; - const opus_val16 * restrict wp1 = window+(overlap>>1); - const opus_val16 * restrict wp2 = window+(overlap>>1)-1; - for(i=0;i<(overlap>>2);i++) - { - /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/ - *yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2); - *yp++ = MULT16_32_Q15(*wp1, *xp1) - MULT16_32_Q15(*wp2, xp2[-N2]); - xp1+=2; - xp2-=2; - wp1+=2; - wp2-=2; - } - wp1 = window; - wp2 = window+overlap-1; - for(;i>2);i++) - { - /* Real part arranged as a-bR, Imag part arranged as -c-dR */ - *yp++ = *xp2; - *yp++ = *xp1; - xp1+=2; - xp2-=2; - } - for(;itrig[0]; - for(i=0;ikfft[shift], (kiss_fft_cpx *)f, (kiss_fft_cpx *)in); - - /* Post-rotate */ - { - /* Temp pointers to make it really clear to the compiler what we're doing */ - const kiss_fft_scalar * restrict fp = in; - kiss_fft_scalar * restrict yp1 = out; - kiss_fft_scalar * restrict yp2 = out+stride*(N2-1); - const kiss_twiddle_scalar *t = &l->trig[0]; - /* Temp pointers to make it really clear to the compiler what we're doing */ - for(i=0;i>1); + const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1); + kiss_fft_scalar * OPUS_RESTRICT yp = f; + const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1); + const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1; + for(i=0;i<((overlap+3)>>2);i++) + { + /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/ + *yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2); + *yp++ = MULT16_32_Q15(*wp1, *xp1) - MULT16_32_Q15(*wp2, xp2[-N2]); + xp1+=2; + xp2-=2; + wp1+=2; + wp2-=2; + } + wp1 = window; + wp2 = window+overlap-1; + for(;i>2);i++) + { + /* Real part arranged as a-bR, Imag part arranged as -c-dR */ + *yp++ = *xp2; + *yp++ = *xp1; + xp1+=2; + xp2-=2; + } + for(;itrig[0]; + for(i=0;ikfft[shift], (kiss_fft_cpx *)f, (kiss_fft_cpx *)f2); + + /* Post-rotate */ + { + /* Temp pointers to make it really clear to the compiler what we're doing */ + const kiss_fft_scalar * OPUS_RESTRICT fp = f2; + kiss_fft_scalar * OPUS_RESTRICT yp1 = out; + kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1); + const kiss_twiddle_scalar *t = &l->trig[0]; + /* Temp pointers to make it really clear to the compiler what we're doing */ + for(i=0;in; + N >>= shift; + N2 = N>>1; + N4 = N>>2; + ALLOC(f2, N2, kiss_fft_scalar); + /* sin(x) ~= x here */ +#ifdef FIXED_POINT + sine = TRIG_UPSCALE*(QCONST16(0.7853981f, 15)+N2)/N; +#else + sine = (kiss_twiddle_scalar)2*PI*(.125f)/N; +#endif + /* Pre-rotate */ { /* Temp pointers to make it really clear to the compiler what we're doing */ - const kiss_fft_scalar * restrict xp1 = in; - const kiss_fft_scalar * restrict xp2 = in+stride*(N2-1); - kiss_fft_scalar * restrict yp = f2; + const kiss_fft_scalar * OPUS_RESTRICT xp1 = in; + const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1); + kiss_fft_scalar * OPUS_RESTRICT yp = f2; const kiss_twiddle_scalar *t = &l->trig[0]; for(i=0;ikfft[shift], (kiss_fft_cpx *)f2, (kiss_fft_cpx *)f); + opus_ifft(l->kfft[shift], (kiss_fft_cpx *)f2, (kiss_fft_cpx *)(out+(overlap>>1))); - /* Post-rotate */ + /* Post-rotate and de-shuffle from both ends of the buffer at once to make + it in-place. */ { - kiss_fft_scalar * restrict fp = f; + kiss_fft_scalar * OPUS_RESTRICT yp0 = out+(overlap>>1); + kiss_fft_scalar * OPUS_RESTRICT yp1 = out+(overlap>>1)+N2-2; const kiss_twiddle_scalar *t = &l->trig[0]; - - for(i=0;i>1 to handle odd N4. When N4 is odd, the + middle pair will be computed twice. */ + for(i=0;i<(N4+1)>>1;i++) { kiss_fft_scalar re, im, yr, yi; - re = fp[0]; - im = fp[1]; + kiss_twiddle_scalar t0, t1; + re = yp0[0]; + im = yp0[1]; + t0 = t[i<>1; + /* Mirror on both sides for TDAC */ { - kiss_fft_scalar * restrict fp1 = f2+N4-1; - kiss_fft_scalar * restrict xp1 = out+N2-1; - kiss_fft_scalar * restrict yp1 = out+N4-overlap/2; - const opus_val16 * restrict wp1 = window; - const opus_val16 * restrict wp2 = window+overlap-1; - for(i = 0; i< N4-overlap/2; i++) + kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1; + kiss_fft_scalar * OPUS_RESTRICT yp1 = out; + const opus_val16 * OPUS_RESTRICT wp1 = window; + const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1; + + for(i = 0; i < overlap/2; i++) { - *xp1 = *fp1; - xp1--; - fp1--; - } - for(; i < N4; i++) - { - kiss_fft_scalar x1; - x1 = *fp1--; - *yp1++ +=-MULT16_32_Q15(*wp1, x1); - *xp1-- += MULT16_32_Q15(*wp2, x1); - wp1++; - wp2--; - } - } - { - kiss_fft_scalar * restrict fp2 = f2+N4; - kiss_fft_scalar * restrict xp2 = out+N2; - kiss_fft_scalar * restrict yp2 = out+N-1-(N4-overlap/2); - const opus_val16 * restrict wp1 = window; - const opus_val16 * restrict wp2 = window+overlap-1; - for(i = 0; i< N4-overlap/2; i++) - { - *xp2 = *fp2; - xp2++; - fp2++; - } - for(; i < N4; i++) - { - kiss_fft_scalar x2; - x2 = *fp2++; - *yp2-- = MULT16_32_Q15(*wp1, x2); - *xp2++ = MULT16_32_Q15(*wp2, x2); + kiss_fft_scalar x1, x2; + x1 = *xp1; + x2 = *yp1; + *yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1); + *xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1); wp1++; wp2--; } diff --git a/media/libopus/celt/mdct.h b/media/libopus/celt/mdct.h index a07bbc98728a..d72182138ac2 100644 --- a/media/libopus/celt/mdct.h +++ b/media/libopus/celt/mdct.h @@ -1,10 +1,7 @@ -/* Copyright (c) 2007-2012 IETF Trust, CSIRO, Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2008 Xiph.Org Foundation Written by Jean-Marc Valin */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +13,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -50,6 +42,7 @@ #ifndef MDCT_H #define MDCT_H +#include "opus_defines.h" #include "kiss_fft.h" #include "arch.h" @@ -57,19 +50,21 @@ typedef struct { int n; int maxshift; const kiss_fft_state *kfft[4]; - const kiss_twiddle_scalar * restrict trig; + const kiss_twiddle_scalar * OPUS_RESTRICT trig; } mdct_lookup; int clt_mdct_init(mdct_lookup *l,int N, int maxshift); void clt_mdct_clear(mdct_lookup *l); /** Compute a forward MDCT and scale by 4/N, trashes the input array */ -void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar *out, +void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, + kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window, int overlap, int shift, int stride); /** Compute a backward MDCT (no scaling) and performs weighted overlap-add (scales implicitly by 1/2) */ -void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar *out, - const opus_val16 * restrict window, int overlap, int shift, int stride); +void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, + kiss_fft_scalar * OPUS_RESTRICT out, + const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride); #endif diff --git a/media/libopus/celt/mfrngcod.h b/media/libopus/celt/mfrngcod.h index dee950e32beb..809152a59a96 100644 --- a/media/libopus/celt/mfrngcod.h +++ b/media/libopus/celt/mfrngcod.h @@ -1,10 +1,6 @@ -/* Copyright (c) 2001-2012 IETF Trust, Timothy B. Terriberry, - Xiph.Org Foundation. All rights reserved.*/ +/* Copyright (c) 2001-2008 Timothy B. Terriberry + Copyright (c) 2008-2009 Xiph.Org Foundation */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR diff --git a/media/libopus/celt/modes.c b/media/libopus/celt/modes.c index dfebf375391d..42e68e1cb72f 100644 --- a/media/libopus/celt/modes.c +++ b/media/libopus/celt/modes.c @@ -1,11 +1,8 @@ -/* Copyright (c) 2007-2012 IETF Trust, CSIRO, Xiph.Org Foundation, - Gregory Maxwell. All rights reserved. +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2008 Gregory Maxwell Written by Jean-Marc Valin and Gregory Maxwell */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -17,11 +14,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -353,6 +345,14 @@ CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error) mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands); if (mode->eBands==NULL) goto failure; +#if !defined(SMALL_FOOTPRINT) + /* Make sure we don't allocate a band larger than our PVQ table. + 208 should be enough, but let's be paranoid. */ + if ((mode->eBands[mode->nbEBands] - mode->eBands[mode->nbEBands-1])< + 208) { + goto failure; + } +#endif mode->effEBands = mode->nbEBands; while (mode->eBands[mode->effEBands] > mode->shortMdctSize) diff --git a/media/libopus/celt/modes.h b/media/libopus/celt/modes.h index cf2a5e4a9106..c8340f9875c2 100644 --- a/media/libopus/celt/modes.h +++ b/media/libopus/celt/modes.h @@ -1,11 +1,8 @@ -/* Copyright (c) 2007-2012 IETF Trust, CSIRO, Xiph.Org Foundation, - Gregory Maxwell. All rights reserved. +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2008 Gregory Maxwell Written by Jean-Marc Valin and Gregory Maxwell */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -17,11 +14,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR diff --git a/media/libopus/celt/os_support.h b/media/libopus/celt/os_support.h index fbec8d164624..2484f0b2f751 100644 --- a/media/libopus/celt/os_support.h +++ b/media/libopus/celt/os_support.h @@ -1,13 +1,9 @@ -/* Copyright (C) 2007-2012 IETF Trust, Jean-Marc Valin. All rights reserved. +/* Copyright (C) 2007 Jean-Marc Valin File: os_support.h This is the (tiny) OS abstraction layer. Aside from math.h, this is the only place where system headers are allowed. - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -19,11 +15,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE diff --git a/media/libopus/celt/pitch.c b/media/libopus/celt/pitch.c index a2224a931413..0352b3025246 100644 --- a/media/libopus/celt/pitch.c +++ b/media/libopus/celt/pitch.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2007-2012 IETF Trust, CSIRO, Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /** @file pitch.c @@ -6,10 +7,6 @@ */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -21,11 +18,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -74,7 +66,7 @@ static void find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len, best_pitch[0] = 0; best_pitch[1] = 1; for (j=0;j0) @@ -82,6 +74,11 @@ static void find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len, opus_val16 num; opus_val32 xcorr16; xcorr16 = EXTRACT16(VSHR32(xcorr[i], xshift)); +#ifndef FIXED_POINT + /* Considering the range of xcorr16, this should avoid both underflows + and overflows (inf) when squaring xcorr16 */ + xcorr16 *= 1e-12f; +#endif num = MULT16_16_Q15(xcorr16,xcorr16); if (MULT16_32_Q15(num,best_den[1]) > MULT16_32_Q15(best_num[1],Syy)) { @@ -105,21 +102,81 @@ static void find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len, } } -void pitch_downsample(celt_sig * restrict x[], opus_val16 * restrict x_lp, +static void celt_fir5(const opus_val16 *x, + const opus_val16 *num, + opus_val16 *y, + int N, + opus_val16 *mem) +{ + int i; + opus_val16 num0, num1, num2, num3, num4; + opus_val32 mem0, mem1, mem2, mem3, mem4; + num0=num[0]; + num1=num[1]; + num2=num[2]; + num3=num[3]; + num4=num[4]; + mem0=mem[0]; + mem1=mem[1]; + mem2=mem[2]; + mem3=mem[3]; + mem4=mem[4]; + for (i=0;i>1;i++) - x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), SIG_SHIFT+3); - x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), SIG_SHIFT+3); + x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), shift); + x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), shift); if (C==2) { for (i=1;i>1;i++) - x_lp[i] += SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), SIG_SHIFT+3); - x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), SIG_SHIFT+3); + x_lp[i] += SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), shift); + x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), shift); } _celt_autocorr(x_lp, ac, NULL, 0, @@ -148,15 +205,90 @@ void pitch_downsample(celt_sig * restrict x[], opus_val16 * restrict x_lp, tmp = MULT16_16_Q15(QCONST16(.9f,15), tmp); lpc[i] = MULT16_16_Q15(lpc[i], tmp); } - celt_fir(x_lp, lpc, x_lp, len>>1, 4, mem); - - mem[0]=0; - lpc[0]=QCONST16(.8f,12); - celt_fir(x_lp, lpc, x_lp, len>>1, 1, mem); - + /* Add a zero */ + lpc2[0] = lpc[0] + QCONST16(.8f,SIG_SHIFT); + lpc2[1] = lpc[1] + MULT16_16_Q15(c1,lpc[0]); + lpc2[2] = lpc[2] + MULT16_16_Q15(c1,lpc[1]); + lpc2[3] = lpc[3] + MULT16_16_Q15(c1,lpc[2]); + lpc2[4] = MULT16_16_Q15(c1,lpc[3]); + celt_fir5(x_lp, lpc2, x_lp, len>>1, mem); } -void pitch_search(const opus_val16 * restrict x_lp, opus_val16 * restrict y, +#if 0 /* This is a simple version of the pitch correlation that should work + well on DSPs like Blackfin and TI C5x/C6x */ + +#ifdef FIXED_POINT +opus_val32 +#else +void +#endif +celt_pitch_xcorr(opus_val16 *x, opus_val16 *y, opus_val32 *xcorr, int len, int max_pitch) +{ + int i, j; +#ifdef FIXED_POINT + opus_val32 maxcorr=1; +#endif + for (i=0;i>2), celt_maxabs16(y_lp4, lag>>2))))-11; + xmax = celt_maxabs16(x_lp4, len>>2); + ymax = celt_maxabs16(y_lp4, lag>>2); + shift = celt_ilog2(MAX32(1, MAX32(xmax, ymax)))-11; if (shift>0) { for (j=0;j>2;j++) @@ -204,16 +339,11 @@ void pitch_search(const opus_val16 * restrict x_lp, opus_val16 * restrict y, /* Coarse search with 4x decimation */ - for (i=0;i>2;i++) - { - opus_val32 sum = 0; - for (j=0;j>2;j++) - sum = MAC16_16(sum, x_lp4[j],y_lp4[i+j]); - xcorr[i] = MAX32(-1, sum); #ifdef FIXED_POINT - maxcorr = MAX32(maxcorr, sum); + maxcorr = #endif - } + celt_pitch_xcorr(x_lp4, y_lp4, xcorr, len>>2, max_pitch>>2); + find_best_pitch(xcorr, y_lp4, len>>2, max_pitch>>2, best_pitch #ifdef FIXED_POINT , 0, maxcorr @@ -239,7 +369,7 @@ void pitch_search(const opus_val16 * restrict x_lp, opus_val16 * restrict y, } find_best_pitch(xcorr, y, len>>1, max_pitch>>1, best_pitch #ifdef FIXED_POINT - , shift, maxcorr + , shift+1, maxcorr #endif ); @@ -271,11 +401,13 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod, int k, i, T, T0; opus_val16 g, g0; opus_val16 pg; - opus_val32 xy,xx,yy; + opus_val32 xy,xx,yy,xy2; opus_val32 xcorr[3]; opus_val32 best_xy, best_yy; int offset; int minperiod0; + VARDECL(opus_val32, yy_lookup); + SAVE_STACK; minperiod0 = minperiod; maxperiod /= 2; @@ -288,13 +420,16 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod, *T0_=maxperiod-1; T = T0 = *T0_; - xx=xy=yy=0; - for (i=0;i QCONST16(.3f,15) + MULT16_16_Q15(QCONST16(.4f,15),g0)-cont) + thresh = MAX16(QCONST16(.3f,15), MULT16_16_Q15(QCONST16(.7f,15),g0)-cont); + /* Bias against very high pitch (very short period) to avoid false-positives + due to short-term correlation */ + if (T1<3*minperiod) + thresh = MAX16(QCONST16(.4f,15), MULT16_16_Q15(QCONST16(.85f,15),g0)-cont); + else if (T1<2*minperiod) + thresh = MAX16(QCONST16(.5f,15), MULT16_16_Q15(QCONST16(.9f,15),g0)-cont); + if (g1 > thresh) { best_xy = xy; best_yy = yy; @@ -364,6 +501,7 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod, g = g1; } } + best_xy = MAX32(0, best_xy); if (best_yy <= best_xy) pg = Q15ONE; else @@ -389,5 +527,6 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod, if (*T0_=2) + qi = IMIN(qi, 0); if (budget-tell >= 15) { int pi; @@ -261,13 +255,13 @@ static int quant_coarse_energy_impl(const CELTMode *m, int start, int end, prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8)); } while (++c < C); } - return badness; + return lfe ? 0 : badness; } void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd, const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget, opus_val16 *error, ec_enc *enc, int C, int LM, int nbAvailableBytes, - int force_intra, opus_val32 *delayedIntra, int two_pass, int loss_rate) + int force_intra, opus_val32 *delayedIntra, int two_pass, int loss_rate, int lfe) { int intra; opus_val16 max_decay; @@ -288,15 +282,17 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd, if (tell+3 > budget) two_pass = intra = 0; - /* Encode the global flags using a simple probability model - (first symbols in the stream) */ - + max_decay = QCONST16(16.f,DB_SHIFT); + if (end-start>10) + { #ifdef FIXED_POINT - max_decay = MIN32(QCONST16(16.f,DB_SHIFT), SHL32(EXTEND32(nbAvailableBytes),DB_SHIFT-3)); + max_decay = MIN32(max_decay, SHL32(EXTEND32(nbAvailableBytes),DB_SHIFT-3)); #else - max_decay = MIN32(16.f, .125f*nbAvailableBytes); + max_decay = MIN32(max_decay, .125f*nbAvailableBytes); #endif - + } + if (lfe) + max_decay=3; enc_start_state = *enc; ALLOC(oldEBands_intra, C*m->nbEBands, opus_val16); @@ -306,7 +302,7 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd, if (two_pass || intra) { badness1 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands_intra, budget, - tell, e_prob_model[LM][1], error_intra, enc, C, LM, 1, max_decay); + tell, e_prob_model[LM][1], error_intra, enc, C, LM, 1, max_decay, lfe); } if (!intra) @@ -333,7 +329,7 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd, *enc = enc_start_state; badness2 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands, budget, - tell, e_prob_model[LM][intra], error, enc, C, LM, 0, max_decay); + tell, e_prob_model[LM][intra], error, enc, C, LM, 0, max_decay, lfe); if (two_pass && (badness1 < badness2 || (badness1 == badness2 && ((opus_int32)ec_tell_frac(enc))+intra_bias > tell_intra))) { @@ -540,25 +536,6 @@ void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 * } } -void log2Amp(const CELTMode *m, int start, int end, - celt_ener *eBands, const opus_val16 *oldEBands, int C) -{ - int c, i; - c=0; - do { - for (i=0;inbEBands] = 0; - for (;inbEBands], - SHL16((opus_val16)eMeans[i],6)); - eBands[i+c*m->nbEBands] = PSHR32(celt_exp2(lg),4); - } - for (;inbEBands;i++) - eBands[i+c*m->nbEBands] = 0; - } while (++c < C); -} - void amp2Log2(const CELTMode *m, int effEnd, int end, celt_ener *bandE, opus_val16 *bandLogE, int C) { diff --git a/media/libopus/celt/quant_bands.h b/media/libopus/celt/quant_bands.h index 77d94a311782..0490bca4b404 100644 --- a/media/libopus/celt/quant_bands.h +++ b/media/libopus/celt/quant_bands.h @@ -1,10 +1,7 @@ -/* Copyright (c) 2007-2012 IETF Trust, CSIRO, Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +13,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -43,6 +35,12 @@ #include "entdec.h" #include "mathops.h" +#ifdef FIXED_POINT +extern const signed char eMeans[25]; +#else +extern const opus_val16 eMeans[25]; +#endif + void amp2Log2(const CELTMode *m, int effEnd, int end, celt_ener *bandE, opus_val16 *bandLogE, int C); @@ -53,7 +51,7 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd, const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget, opus_val16 *error, ec_enc *enc, int C, int LM, int nbAvailableBytes, int force_intra, opus_val32 *delayedIntra, - int two_pass, int loss_rate); + int two_pass, int loss_rate, int lfe); void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C); diff --git a/media/libopus/celt/rate.c b/media/libopus/celt/rate.c index 364a5db4bb5e..e474cf50047f 100644 --- a/media/libopus/celt/rate.c +++ b/media/libopus/celt/rate.c @@ -1,10 +1,7 @@ -/* Copyright (c) 2007-2012 IETF Trust, CSIRO, Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +13,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -92,7 +84,7 @@ void compute_pulse_cache(CELTMode *m, int LM) unsigned char *bits; unsigned char *cap; - cindex = opus_alloc(sizeof(cache->index[0])*m->nbEBands*(LM+2)); + cindex = (opus_int16 *)opus_alloc(sizeof(cache->index[0])*m->nbEBands*(LM+2)); cache->index = cindex; /* Scan for all unique band sizes */ @@ -132,7 +124,7 @@ void compute_pulse_cache(CELTMode *m, int LM) } } } - bits = opus_alloc(sizeof(unsigned char)*curr); + bits = (unsigned char *)opus_alloc(sizeof(unsigned char)*curr); cache->bits = bits; cache->size = curr; /* Compute the cache for all unique sizes */ @@ -148,7 +140,7 @@ void compute_pulse_cache(CELTMode *m, int LM) /* Compute the maximum rate for each band at which we'll reliably use as many bits as we ask for. */ - cache->caps = cap = opus_alloc(sizeof(cache->caps[0])*(LM+1)*2*m->nbEBands); + cache->caps = cap = (unsigned char *)opus_alloc(sizeof(cache->caps[0])*(LM+1)*2*m->nbEBands); for (i=0;i<=LM;i++) { for (C=1;C<=2;C++) @@ -256,7 +248,7 @@ void compute_pulse_cache(CELTMode *m, int LM) static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int skip_start, const int *bits1, const int *bits2, const int *thresh, const int *cap, opus_int32 total, opus_int32 *_balance, int skip_rsv, int *intensity, int intensity_rsv, int *dual_stereo, int dual_stereo_rsv, int *bits, - int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev) + int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth) { opus_int32 psum; int lo, hi; @@ -267,7 +259,7 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int int alloc_floor; opus_int32 left, percoeff; int done; - int balance; + opus_int32 balance; SAVE_STACK; alloc_floor = C< ((j>4) + if (codedBands<=start+2 || (band_bits > ((j>4 && j<=signalBandwidth)) #endif { ec_enc_bit_logp(ec, 1, 1); @@ -440,17 +432,17 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int int N0, N, den; int offset; int NClogN; - int excess; + opus_int32 excess, bit; celt_assert(bits[j] >= 0); N0 = m->eBands[j+1]-m->eBands[j]; N=N0<1) { - excess = IMAX(bits[j]-cap[j],0); - bits[j] -= excess; + excess = MAX32(bit-cap[j],0); + bits[j] = bit-excess; /* Compensate for the extra DoF in stereo */ den=(C*N+ ((C==2 && N>2 && !*dual_stereo && j<*intensity) ? 1 : 0)); @@ -491,8 +483,8 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int } else { /* For N=1, all bits go to fine energy except for a single sign bit */ - excess = IMAX(0,bits[j]-(C<>1; /* OPT: Make sure this is implemented with a conditional move */ - if (cache[mid] >= bits) + if ((int)cache[mid] >= bits) hi = mid; else lo = mid; } - if (bits- (lo == 0 ? -1 : cache[lo]) <= cache[hi]-bits) + if (bits- (lo == 0 ? -1 : (int)cache[lo]) <= (int)cache[hi]-bits) return lo; else return hi; @@ -104,6 +96,6 @@ static inline int pulses2bits(const CELTMode *m, int band, int LM, int pulses) @return Total number of bits allocated */ int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero, - opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev); + opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth); #endif diff --git a/media/libopus/celt/stack_alloc.h b/media/libopus/celt/stack_alloc.h index 4c0fd74bfb8d..1c093a8cdce6 100644 --- a/media/libopus/celt/stack_alloc.h +++ b/media/libopus/celt/stack_alloc.h @@ -1,14 +1,10 @@ -/* Copyright (C) 2002-2012 IETF Trust, Jean-Marc Valin, Xiph.Org Foundation. - All rights reserved.*/ +/* Copyright (C) 2002-2003 Jean-Marc Valin + Copyright (C) 2007-2009 Xiph.Org Foundation */ /** @file stack_alloc.h @brief Temporary memory allocation on stack */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -20,11 +16,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -41,6 +32,10 @@ #ifndef STACK_ALLOC_H #define STACK_ALLOC_H +#if (!defined (VAR_ARRAYS) && !defined (USE_ALLOCA) && !defined (NONTHREADSAFE_PSEUDOSTACK)) +#error "Opus requires one of VAR_ARRAYS, USE_ALLOCA, or NONTHREADSAFE_PSEUDOSTACK be defined to select the temporary allocation mode." +#endif + #ifdef USE_ALLOCA # ifdef WIN32 # include @@ -151,4 +146,26 @@ extern char *global_stack_top; #endif /* VAR_ARRAYS */ + +#ifdef ENABLE_VALGRIND + +#include +#define OPUS_CHECK_ARRAY(ptr, len) VALGRIND_CHECK_MEM_IS_DEFINED(ptr, len*sizeof(*ptr)) +#define OPUS_CHECK_VALUE(value) VALGRIND_CHECK_VALUE_IS_DEFINED(value) +#define OPUS_CHECK_ARRAY_COND(ptr, len) VALGRIND_CHECK_MEM_IS_DEFINED(ptr, len*sizeof(*ptr)) +#define OPUS_CHECK_VALUE_COND(value) VALGRIND_CHECK_VALUE_IS_DEFINED(value) +#define OPUS_PRINT_INT(value) do {fprintf(stderr, #value " = %d at %s:%d\n", value, __FILE__, __LINE__);}while(0) +#define OPUS_FPRINTF fprintf + +#else + +static inline int _opus_false(void) {return 0;} +#define OPUS_CHECK_ARRAY(ptr, len) _opus_false() +#define OPUS_CHECK_VALUE(value) _opus_false() +#define OPUS_PRINT_INT(value) do{}while(0) +#define OPUS_FPRINTF (void) + +#endif + + #endif /* STACK_ALLOC_H */ diff --git a/media/libopus/celt/static_modes_fixed.h b/media/libopus/celt/static_modes_fixed.h index cfa1f45341eb..216df9e605f2 100644 --- a/media/libopus/celt/static_modes_fixed.h +++ b/media/libopus/celt/static_modes_fixed.h @@ -1,43 +1,6 @@ /* The contents of this file was automatically generated by dump_modes.c with arguments: 48000 960 It contains static definitions for some pre-defined modes. */ - -/* Copyright (c) 2011-2012 IETF Trust, CSIRO, Xiph.Org Foundation. All rights reserved. - - - This file is extracted from RFC6716. Please see that RFC for additional - information. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - #include "modes.h" #include "rate.h" diff --git a/media/libopus/celt/static_modes_float.h b/media/libopus/celt/static_modes_float.h index 381ca4c3483e..5d7e7b8e684c 100644 --- a/media/libopus/celt/static_modes_float.h +++ b/media/libopus/celt/static_modes_float.h @@ -1,42 +1,6 @@ /* The contents of this file was automatically generated by dump_modes.c with arguments: 48000 960 It contains static definitions for some pre-defined modes. */ - -/* Copyright (c) 2011-2012 IETF Trust, CSIRO, Xiph.Org Foundation. All rights reserved. - - - This file is extracted from RFC6716. Please see that RFC for additional - information. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - #include "modes.h" #include "rate.h" diff --git a/media/libopus/celt/vq.c b/media/libopus/celt/vq.c index 18abe6d4ba76..98a0f36c9f0f 100644 --- a/media/libopus/celt/vq.c +++ b/media/libopus/celt/vq.c @@ -1,10 +1,7 @@ -/* Copyright (c) 2007-2012 IETF Trust, CSIRO, Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +13,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -117,7 +109,7 @@ static void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int /** Takes the pitch vector and the decoded residual vector, computes the gain that will give ||p+g*y||=1 and mixes the residual with the pitch. */ -static void normalise_residual(int * restrict iy, celt_norm * restrict X, +static void normalise_residual(int * OPUS_RESTRICT iy, celt_norm * OPUS_RESTRICT X, int N, opus_val32 Ryy, opus_val16 gain) { int i; diff --git a/media/libopus/celt/vq.h b/media/libopus/celt/vq.h index 0b6bf7f29ab2..ffdc69cdc4e4 100644 --- a/media/libopus/celt/vq.h +++ b/media/libopus/celt/vq.h @@ -1,14 +1,11 @@ -/* Copyright (c) 2007-2012 IETF Trust, CSIRO, Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation Written by Jean-Marc Valin */ /** @file vq.h @brief Vector quantisation of the residual */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -20,11 +17,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -48,11 +40,9 @@ /** Algebraic pulse-vector quantiser. The signal x is replaced by the sum of * the pitch and a combination of pulses such that its norm is still equal * to 1. This is the function that will typically require the most CPU. - * @param x Residual signal to quantise/encode (returns quantised version) - * @param W Perceptual weight to use when optimising (currently unused) + * @param X Residual signal to quantise/encode (returns quantised version) * @param N Number of samples to encode * @param K Number of pulses to use - * @param p Pitch vector (it is assumed that p+x is a unit vector) * @param enc Entropy encoder state * @ret A mask indicating which blocks in the band received pulses */ @@ -64,10 +54,9 @@ unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ); /** Algebraic pulse decoder - * @param x Decoded normalised spectrum (returned) + * @param X Decoded normalised spectrum (returned) * @param N Number of samples to decode * @param K Number of pulses to use - * @param p Pitch vector (automatically added to x) * @param dec Entropy decoder state * @ret A mask indicating which blocks in the band received pulses */ diff --git a/media/libopus/celt/x86/pitch_sse.h b/media/libopus/celt/x86/pitch_sse.h new file mode 100644 index 000000000000..63ae3d46a134 --- /dev/null +++ b/media/libopus/celt/x86/pitch_sse.h @@ -0,0 +1,156 @@ +/* Copyright (c) 2013 Jean-Marc Valin and John Ridges */ +/** + @file pitch_sse.h + @brief Pitch analysis + */ + +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef PITCH_SSE_H +#define PITCH_SSE_H + +#include +#include "arch.h" + +#define OVERRIDE_XCORR_KERNEL +static inline void xcorr_kernel(const opus_val16 *x, const opus_val16 *y, opus_val32 sum[4], int len) +{ + int j; + __m128 xsum1, xsum2; + xsum1 = _mm_loadu_ps(sum); + xsum2 = _mm_setzero_ps(); + + for (j = 0; j < len-3; j += 4) + { + __m128 x0 = _mm_loadu_ps(x+j); + __m128 yj = _mm_loadu_ps(y+j); + __m128 y3 = _mm_loadu_ps(y+j+3); + + xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0x00),yj)); + xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0x55), + _mm_shuffle_ps(yj,y3,0x49))); + xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0xaa), + _mm_shuffle_ps(yj,y3,0x9e))); + xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0xff),y3)); + } + if (j < len) + { + xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j))); + if (++j < len) + { + xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j))); + if (++j < len) + { + xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j))); + } + } + } + _mm_storeu_ps(sum,_mm_add_ps(xsum1,xsum2)); +} + +#define OVERRIDE_DUAL_INNER_PROD +static inline void dual_inner_prod(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02, + int N, opus_val32 *xy1, opus_val32 *xy2) +{ + int i; + __m128 xsum1, xsum2; + xsum1 = _mm_setzero_ps(); + xsum2 = _mm_setzero_ps(); + for (i=0;iaudio_frame is the audio data in opus_int16 (or float for opus_encode_float()) *
  • frame_size is the duration of the frame in samples (per channel)
  • *
  • packet is the byte array to which the compressed data is written
  • - *
  • max_packet is the maximum number of bytes that can be written in the packet (1276 bytes is recommended)
  • + *
  • max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended). + * Do not use max_packet to control VBR target bitrate, instead use the #OPUS_SET_BITRATE CTL.
  • * * - * opus_encode() and opus_encode_frame() return the number of bytes actually written to the packet. + * opus_encode() and opus_encode_float() return the number of bytes actually written to the packet. * The return value can be negative, which indicates that an error has occurred. If the return value * is 1 byte, then the packet does not need to be transmitted (DTX). * @@ -166,7 +163,12 @@ extern "C" { */ typedef struct OpusEncoder OpusEncoder; -OPUS_EXPORT int opus_encoder_get_size(int channels); +/** Gets the size of an OpusEncoder structure. + * @param[in] channels int: Number of channels. + * This must be 1 or 2. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels); /** */ @@ -188,18 +190,22 @@ OPUS_EXPORT int opus_encoder_get_size(int channels); * * @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY configures low-delay mode that * disables the speech-optimized mode in exchange for slightly reduced delay. + * This mode can only be set on an newly initialized or freshly reset encoder + * because it changes the codec delay. * * This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution). * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) - * @param [in] channels int: Number of channels (1/2) in input signal + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) in input signal * @param [in] application int: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY) - * @param [out] error int*: @ref errorcodes + * @param [out] error int*: @ref opus_errorcodes * @note Regardless of the sampling rate and number channels selected, the Opus encoder - * can switch to a lower audio audio bandwidth or number of channels if the bitrate + * can switch to a lower audio bandwidth or number of channels if the bitrate * selected is too low. This also means that it is safe to always use 48 kHz stereo input * and let the encoder optimize the encoding. */ -OPUS_EXPORT OpusEncoder *opus_encoder_create( +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create( opus_int32 Fs, int channels, int application, @@ -207,64 +213,103 @@ OPUS_EXPORT OpusEncoder *opus_encoder_create( ); /** Initializes a previously allocated encoder state - * The memory pointed to by st must be the size returned by opus_encoder_get_size. + * The memory pointed to by st must be at least the size returned by opus_encoder_get_size(). * This is intended for applications which use their own allocator instead of malloc. * @see opus_encoder_create(),opus_encoder_get_size() - * To reset a previously initialized state use the OPUS_RESET_STATE CTL. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. * @param [in] st OpusEncoder*: Encoder state * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) - * @param [in] channels int: Number of channels (1/2) in input signal + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) in input signal * @param [in] application int: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY) - * @retval OPUS_OK Success or @ref errorcodes + * @retval #OPUS_OK Success or @ref opus_errorcodes */ OPUS_EXPORT int opus_encoder_init( OpusEncoder *st, opus_int32 Fs, int channels, int application -); +) OPUS_ARG_NONNULL(1); /** Encodes an Opus frame. - * The passed frame_size must an opus frame size for the encoder's sampling rate. - * For example, at 48kHz the permitted values are 120, 240, 480, or 960. - * Passing in a duration of less than 10ms (480 samples at 48kHz) will - * prevent the encoder from using the LPC or hybrid modes. * @param [in] st OpusEncoder*: Encoder state * @param [in] pcm opus_int16*: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16) - * @param [in] frame_size int: Number of samples per frame of input signal - * @param [out] data char*: Output payload (at least max_data_bytes long) - * @param [in] max_data_bytes int: Allocated memory for payload; don't use for controlling bitrate - * @returns length of the data payload (in bytes) or @ref errorcodes + * @param [in] frame_size int: Number of samples per channel in the + * input signal. + * This must be an Opus frame size for + * the encoder's sampling rate. + * For example, at 48 kHz the permitted + * values are 120, 240, 480, 960, 1920, + * and 2880. + * Passing in a duration of less than + * 10 ms (480 samples at 48 kHz) will + * prevent the encoder from using the LPC + * or hybrid modes. + * @param [out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. */ -OPUS_EXPORT int opus_encode( +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode( OpusEncoder *st, const opus_int16 *pcm, int frame_size, unsigned char *data, - int max_data_bytes -); + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); /** Encodes an Opus frame from floating point input. - * The passed frame_size must an opus frame size for the encoder's sampling rate. - * For example, at 48kHz the permitted values are 120, 240, 480, or 960. - * Passing in a duration of less than 10ms (480 samples at 48kHz) will - * prevent the encoder from using the LPC or hybrid modes. * @param [in] st OpusEncoder*: Encoder state - * @param [in] pcm float*: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(float) - * @param [in] frame_size int: Number of samples per frame of input signal - * @param [out] data char*: Output payload (at least max_data_bytes long) - * @param [in] max_data_bytes int: Allocated memory for payload; don't use for controlling bitrate - * @returns length of the data payload (in bytes) or @ref errorcodes + * @param [in] pcm float*: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0. + * Samples with a range beyond +/-1.0 are supported but will + * be clipped by decoders using the integer API and should + * only be used if it is known that the far end supports + * extended dynamic range. + * length is frame_size*channels*sizeof(float) + * @param [in] frame_size int: Number of samples per channel in the + * input signal. + * This must be an Opus frame size for + * the encoder's sampling rate. + * For example, at 48 kHz the permitted + * values are 120, 240, 480, 960, 1920, + * and 2880. + * Passing in a duration of less than + * 10 ms (480 samples at 48 kHz) will + * prevent the encoder from using the LPC + * or hybrid modes. + * @param [out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. */ -OPUS_EXPORT int opus_encode_float( +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float( OpusEncoder *st, const float *pcm, int frame_size, unsigned char *data, - int max_data_bytes -); + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); -/** Frees an OpusEncoder allocated by opus_encoder_create. +/** Frees an OpusEncoder allocated by opus_encoder_create(). * @param[in] st OpusEncoder*: State to be freed. */ OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st); @@ -273,14 +318,20 @@ OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st); * * Generally the request and subsequent arguments are generated * by a convenience macro. - * @see encoderctls + * @param st OpusEncoder*: Encoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls or + * @ref opus_encoderctls. + * @see opus_genericctls + * @see opus_encoderctls */ -OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...); +OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); /**@}*/ -/** @defgroup opusdecoder Opus Decoder +/** @defgroup opus_decoder Opus Decoder * @{ * + * @brief This page describes the process and functions used to decode Opus. * * The decoding process also starts with creating a decoder * state. This can be done with: @@ -292,7 +343,7 @@ OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...); * where * @li Fs is the sampling rate and must be 8000, 12000, 16000, 24000, or 48000 * @li channels is the number of channels (1 or 2) - * @li error will hold the error code in case or failure (or OPUS_OK on success) + * @li error will hold the error code in case of failure (or #OPUS_OK on success) * @li the return value is a newly created decoder state to be used for decoding * * While opus_decoder_create() allocates memory for the state, it's also possible @@ -313,7 +364,7 @@ OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...); * * To decode a frame, opus_decode() or opus_decode_float() must be called with a packet of compressed audio data: * @code - * frame_size = opus_decode(enc, packet, len, decoded, max_size); + * frame_size = opus_decode(dec, packet, len, decoded, max_size, 0); * @endcode * where * @@ -322,11 +373,23 @@ OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...); * @li decoded is the decoded audio data in opus_int16 (or float for opus_decode_float()) * @li max_size is the max duration of the frame in samples (per channel) that can fit into the decoded_frame array * - * opus_decode() and opus_decode_frame() return the number of samples ()per channel) decoded from the packet. - * If that value is negative, then an error has occured. This can occur if the packet is corrupted or if the audio + * opus_decode() and opus_decode_float() return the number of samples (per channel) decoded from the packet. + * If that value is negative, then an error has occurred. This can occur if the packet is corrupted or if the audio * buffer is too small to hold the decoded audio. - -*/ + * + * Opus is a stateful codec with overlapping blocks and as a result Opus + * packets are not coded independently of each other. Packets must be + * passed into the decoder serially and in the correct order for a correct + * decode. Lost packets can be replaced with loss concealment by calling + * the decoder with a null pointer and zero length for the missing packet. + * + * A single codec state may only be accessed from a single thread at + * a time and any required locking must be performed by the caller. Separate + * streams must be decoded with separate decoder states and can be decoded + * in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK + * defined. + * + */ /** Opus decoder state. * This contains the complete state of an Opus decoder. @@ -335,89 +398,115 @@ OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...); */ typedef struct OpusDecoder OpusDecoder; -/** Gets the size of an OpusDecoder structure. - * @param [in] channels int: Number of channels - * @returns size +/** Gets the size of an OpusDecoder structure. + * @param [in] channels int: Number of channels. + * This must be 1 or 2. + * @returns The size in bytes. */ -OPUS_EXPORT int opus_decoder_get_size(int channels); +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_size(int channels); /** Allocates and initializes a decoder state. - * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) - * @param [in] channels int: Number of channels (1/2) in input signal - * @param [out] error int*: OPUS_OK Success or @ref errorcodes + * @param [in] Fs opus_int32: Sample rate to decode at (Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) to decode + * @param [out] error int*: #OPUS_OK Success or @ref opus_errorcodes + * + * Internally Opus stores data at 48000 Hz, so that should be the default + * value for Fs. However, the decoder can efficiently decode to buffers + * at 8, 12, 16, and 24 kHz so if for some reason the caller cannot use + * data at the full sample rate, or knows the compressed data doesn't + * use the full frequency range, it can request decoding at a reduced + * rate. Likewise, the decoder is capable of filling in either mono or + * interleaved stereo pcm buffers, at the caller's request. */ -OPUS_EXPORT OpusDecoder *opus_decoder_create( +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusDecoder *opus_decoder_create( opus_int32 Fs, int channels, int *error ); /** Initializes a previously allocated decoder state. - * The state must be the size returned by opus_decoder_get_size. + * The state must be at least the size returned by opus_decoder_get_size(). * This is intended for applications which use their own allocator instead of malloc. @see opus_decoder_create,opus_decoder_get_size - * To reset a previously initialized state use the OPUS_RESET_STATE CTL. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. * @param [in] st OpusDecoder*: Decoder state. - * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) - * @param [in] channels int: Number of channels (1/2) in input signal - * @retval OPUS_OK Success or @ref errorcodes + * @param [in] Fs opus_int32: Sampling rate to decode to (Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) to decode + * @retval #OPUS_OK Success or @ref opus_errorcodes */ OPUS_EXPORT int opus_decoder_init( OpusDecoder *st, opus_int32 Fs, int channels -); +) OPUS_ARG_NONNULL(1); -/** Decode an Opus frame +/** Decode an Opus packet. * @param [in] st OpusDecoder*: Decoder state * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss - * @param [in] len int: Number of bytes in payload* + * @param [in] len opus_int32: Number of bytes in payload* * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length * is frame_size*channels*sizeof(opus_int16) - * @param [in] frame_size Number of samples per channel of available space in *pcm, - * if less than the maximum frame size (120ms) some frames can not be decoded - * @param [in] decode_fec int: Flag (0/1) to request that any in-band forward error correction data be - * decoded. If no such data is available the frame is decoded as if it were lost. - * @returns Number of decoded samples or @ref errorcodes + * @param [in] frame_size Number of samples per channel of available space in \a pcm. + * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will + * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), + * then frame_size needs to be exactly the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and + * FEC cases, frame_size must be a multiple of 2.5 ms. + * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be + * decoded. If no such data is available, the frame is decoded as if it were lost. + * @returns Number of decoded samples or @ref opus_errorcodes */ -OPUS_EXPORT int opus_decode( +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode( OpusDecoder *st, const unsigned char *data, - int len, + opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec -); +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); -/** Decode an opus frame with floating point output +/** Decode an Opus packet with floating point output. * @param [in] st OpusDecoder*: Decoder state * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss - * @param [in] len int: Number of bytes in payload + * @param [in] len opus_int32: Number of bytes in payload * @param [out] pcm float*: Output signal (interleaved if 2 channels). length * is frame_size*channels*sizeof(float) - * @param [in] frame_size Number of samples per channel of available space in *pcm, - * if less than the maximum frame size (120ms) some frames can not be decoded - * @param [in] decode_fec int: Flag (0/1) to request that any in-band forward error correction data be + * @param [in] frame_size Number of samples per channel of available space in \a pcm. + * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will + * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), + * then frame_size needs to be exactly the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and + * FEC cases, frame_size must be a multiple of 2.5 ms. + * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be * decoded. If no such data is available the frame is decoded as if it were lost. - * @returns Number of decoded samples or @ref errorcodes + * @returns Number of decoded samples or @ref opus_errorcodes */ -OPUS_EXPORT int opus_decode_float( +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode_float( OpusDecoder *st, const unsigned char *data, - int len, + opus_int32 len, float *pcm, int frame_size, int decode_fec -); +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); /** Perform a CTL function on an Opus decoder. * * Generally the request and subsequent arguments are generated * by a convenience macro. - * @see genericctls + * @param st OpusDecoder*: Decoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls or + * @ref opus_decoderctls. + * @see opus_genericctls + * @see opus_decoderctls */ -OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...); +OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); -/** Frees an OpusDecoder allocated by opus_decoder_create. +/** Frees an OpusDecoder allocated by opus_decoder_create(). * @param[in] st OpusDecoder*: State to be freed. */ OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st); @@ -428,21 +517,21 @@ OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st); * This function does not copy the frames, the returned pointers are pointers into * the input packet. * @param [in] data char*: Opus packet to be parsed - * @param [in] len int: size of data + * @param [in] len opus_int32: size of data * @param [out] out_toc char*: TOC pointer * @param [out] frames char*[48] encapsulated frames - * @param [out] size short[48] sizes of the encapsulated frames + * @param [out] size opus_int16[48] sizes of the encapsulated frames * @param [out] payload_offset int*: returns the position of the payload within the packet (in bytes) * @returns number of frames */ OPUS_EXPORT int opus_packet_parse( const unsigned char *data, - int len, + opus_int32 len, unsigned char *out_toc, const unsigned char *frames[48], - short size[48], + opus_int16 size[48], int *payload_offset -); +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); /** Gets the bandwidth of an Opus packet. * @param [in] data char*: Opus packet @@ -453,66 +542,374 @@ OPUS_EXPORT int opus_packet_parse( * @retval OPUS_BANDWIDTH_FULLBAND Fullband (20kHz bandpass) * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type */ -OPUS_EXPORT int opus_packet_get_bandwidth(const unsigned char *data); +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_bandwidth(const unsigned char *data) OPUS_ARG_NONNULL(1); /** Gets the number of samples per frame from an Opus packet. - * @param [in] data char*: Opus packet - * @param [in] Fs opus_int32: Sampling rate in Hz - * @returns Number of samples per frame - * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + * @param [in] data char*: Opus packet. + * This must contain at least one byte of + * data. + * @param [in] Fs opus_int32: Sampling rate in Hz. + * This must be a multiple of 400, or + * inaccurate results will be returned. + * @returns Number of samples per frame. */ -OPUS_EXPORT int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs); +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs) OPUS_ARG_NONNULL(1); /** Gets the number of channels from an Opus packet. * @param [in] data char*: Opus packet * @returns Number of channels * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type */ -OPUS_EXPORT int opus_packet_get_nb_channels(const unsigned char *data); +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_channels(const unsigned char *data) OPUS_ARG_NONNULL(1); /** Gets the number of frames in an Opus packet. * @param [in] packet char*: Opus packet - * @param [in] len int: Length of packet + * @param [in] len opus_int32: Length of packet * @returns Number of frames + * @retval OPUS_BAD_ARG Insufficient data was passed to the function * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type */ -OPUS_EXPORT int opus_packet_get_nb_frames(const unsigned char packet[], int len); +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1); + +/** Gets the number of samples of an Opus packet. + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @param [in] Fs opus_int32: Sampling rate in Hz. + * This must be a multiple of 400, or + * inaccurate results will be returned. + * @returns Number of samples + * @retval OPUS_BAD_ARG Insufficient data was passed to the function + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1); /** Gets the number of samples of an Opus packet. * @param [in] dec OpusDecoder*: Decoder state * @param [in] packet char*: Opus packet - * @param [in] len int: Length of packet + * @param [in] len opus_int32: Length of packet * @returns Number of samples + * @retval OPUS_BAD_ARG Insufficient data was passed to the function * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type */ -OPUS_EXPORT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], int len); +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); + +/** Applies soft-clipping to bring a float signal within the [-1,1] range. If + * the signal is already in that range, nothing is done. If there are values + * outside of [-1,1], then the signal is clipped as smoothly as possible to + * both fit in the range and avoid creating excessive distortion in the + * process. + * @param [in,out] pcm float*: Input PCM and modified PCM + * @param [in] frame_size int Number of samples per channel to process + * @param [in] channels int: Number of channels + * @param [in,out] softclip_mem float*: State memory for the soft clipping process (one float per channel, initialized to zero) + */ +OPUS_EXPORT void opus_pcm_soft_clip(float *pcm, int frame_size, int channels, float *softclip_mem); + + /**@}*/ -/** @defgroup repacketizer Repacketizer +/** @defgroup opus_repacketizer Repacketizer * @{ * - * The repacketizer can be used to merge multiple Opus packets into a single packet - * or alternatively to split Opus packets that have previously been merged. + * The repacketizer can be used to merge multiple Opus packets into a single + * packet or alternatively to split Opus packets that have previously been + * merged. Splitting valid Opus packets is always guaranteed to succeed, + * whereas merging valid packets only succeeds if all frames have the same + * mode, bandwidth, and frame size, and when the total duration of the merged + * packet is no more than 120 ms. + * The repacketizer currently only operates on elementary Opus + * streams. It will not manipualte multistream packets successfully, except in + * the degenerate case where they consist of data from a single stream. * + * The repacketizing process starts with creating a repacketizer state, either + * by calling opus_repacketizer_create() or by allocating the memory yourself, + * e.g., + * @code + * OpusRepacketizer *rp; + * rp = (OpusRepacketizer*)malloc(opus_repacketizer_get_size()); + * if (rp != NULL) + * opus_repacketizer_init(rp); + * @endcode + * + * Then the application should submit packets with opus_repacketizer_cat(), + * extract new packets with opus_repacketizer_out() or + * opus_repacketizer_out_range(), and then reset the state for the next set of + * input packets via opus_repacketizer_init(). + * + * For example, to split a sequence of packets into individual frames: + * @code + * unsigned char *data; + * int len; + * while (get_next_packet(&data, &len)) + * { + * unsigned char out[1276]; + * opus_int32 out_len; + * int nb_frames; + * int err; + * int i; + * err = opus_repacketizer_cat(rp, data, len); + * if (err != OPUS_OK) + * { + * release_packet(data); + * return err; + * } + * nb_frames = opus_repacketizer_get_nb_frames(rp); + * for (i = 0; i < nb_frames; i++) + * { + * out_len = opus_repacketizer_out_range(rp, i, i+1, out, sizeof(out)); + * if (out_len < 0) + * { + * release_packet(data); + * return (int)out_len; + * } + * output_next_packet(out, out_len); + * } + * opus_repacketizer_init(rp); + * release_packet(data); + * } + * @endcode + * + * Alternatively, to combine a sequence of frames into packets that each + * contain up to TARGET_DURATION_MS milliseconds of data: + * @code + * // The maximum number of packets with duration TARGET_DURATION_MS occurs + * // when the frame size is 2.5 ms, for a total of (TARGET_DURATION_MS*2/5) + * // packets. + * unsigned char *data[(TARGET_DURATION_MS*2/5)+1]; + * opus_int32 len[(TARGET_DURATION_MS*2/5)+1]; + * int nb_packets; + * unsigned char out[1277*(TARGET_DURATION_MS*2/2)]; + * opus_int32 out_len; + * int prev_toc; + * nb_packets = 0; + * while (get_next_packet(data+nb_packets, len+nb_packets)) + * { + * int nb_frames; + * int err; + * nb_frames = opus_packet_get_nb_frames(data[nb_packets], len[nb_packets]); + * if (nb_frames < 1) + * { + * release_packets(data, nb_packets+1); + * return nb_frames; + * } + * nb_frames += opus_repacketizer_get_nb_frames(rp); + * // If adding the next packet would exceed our target, or it has an + * // incompatible TOC sequence, output the packets we already have before + * // submitting it. + * // N.B., The nb_packets > 0 check ensures we've submitted at least one + * // packet since the last call to opus_repacketizer_init(). Otherwise a + * // single packet longer than TARGET_DURATION_MS would cause us to try to + * // output an (invalid) empty packet. It also ensures that prev_toc has + * // been set to a valid value. Additionally, len[nb_packets] > 0 is + * // guaranteed by the call to opus_packet_get_nb_frames() above, so the + * // reference to data[nb_packets][0] should be valid. + * if (nb_packets > 0 && ( + * ((prev_toc & 0xFC) != (data[nb_packets][0] & 0xFC)) || + * opus_packet_get_samples_per_frame(data[nb_packets], 48000)*nb_frames > + * TARGET_DURATION_MS*48)) + * { + * out_len = opus_repacketizer_out(rp, out, sizeof(out)); + * if (out_len < 0) + * { + * release_packets(data, nb_packets+1); + * return (int)out_len; + * } + * output_next_packet(out, out_len); + * opus_repacketizer_init(rp); + * release_packets(data, nb_packets); + * data[0] = data[nb_packets]; + * len[0] = len[nb_packets]; + * nb_packets = 0; + * } + * err = opus_repacketizer_cat(rp, data[nb_packets], len[nb_packets]); + * if (err != OPUS_OK) + * { + * release_packets(data, nb_packets+1); + * return err; + * } + * prev_toc = data[nb_packets][0]; + * nb_packets++; + * } + * // Output the final, partial packet. + * if (nb_packets > 0) + * { + * out_len = opus_repacketizer_out(rp, out, sizeof(out)); + * release_packets(data, nb_packets); + * if (out_len < 0) + * return (int)out_len; + * output_next_packet(out, out_len); + * } + * @endcode + * + * An alternate way of merging packets is to simply call opus_repacketizer_cat() + * unconditionally until it fails. At that point, the merged packet can be + * obtained with opus_repacketizer_out() and the input packet for which + * opus_repacketizer_cat() needs to be re-added to a newly reinitialized + * repacketizer state. */ typedef struct OpusRepacketizer OpusRepacketizer; -OPUS_EXPORT int opus_repacketizer_get_size(void); +/** Gets the size of an OpusRepacketizer structure. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_size(void); -OPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp); +/** (Re)initializes a previously allocated repacketizer state. + * The state must be at least the size returned by opus_repacketizer_get_size(). + * This can be used for applications which use their own allocator instead of + * malloc(). + * It must also be called to reset the queue of packets waiting to be + * repacketized, which is necessary if the maximum packet duration of 120 ms + * is reached or if you wish to submit packets with a different Opus + * configuration (coding mode, audio bandwidth, frame size, or channel count). + * Failure to do so will prevent a new packet from being added with + * opus_repacketizer_cat(). + * @see opus_repacketizer_create + * @see opus_repacketizer_get_size + * @see opus_repacketizer_cat + * @param rp OpusRepacketizer*: The repacketizer state to + * (re)initialize. + * @returns A pointer to the same repacketizer state that was passed in. + */ +OPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); -OPUS_EXPORT OpusRepacketizer *opus_repacketizer_create(void); +/** Allocates memory and initializes the new repacketizer with + * opus_repacketizer_init(). + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusRepacketizer *opus_repacketizer_create(void); +/** Frees an OpusRepacketizer allocated by + * opus_repacketizer_create(). + * @param[in] rp OpusRepacketizer*: State to be freed. + */ OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp); -OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, int len); +/** Add a packet to the current repacketizer state. + * This packet must match the configuration of any packets already submitted + * for repacketization since the last call to opus_repacketizer_init(). + * This means that it must have the same coding mode, audio bandwidth, frame + * size, and channel count. + * This can be checked in advance by examining the top 6 bits of the first + * byte of the packet, and ensuring they match the top 6 bits of the first + * byte of any previously submitted packet. + * The total duration of audio in the repacketizer state also must not exceed + * 120 ms, the maximum duration of a single packet, after adding this packet. + * + * The contents of the current repacketizer state can be extracted into new + * packets using opus_repacketizer_out() or opus_repacketizer_out_range(). + * + * In order to add a packet with a different configuration or to add more + * audio beyond 120 ms, you must clear the repacketizer state by calling + * opus_repacketizer_init(). + * If a packet is too large to add to the current repacketizer state, no part + * of it is added, even if it contains multiple frames, some of which might + * fit. + * If you wish to be able to add parts of such packets, you should first use + * another repacketizer to split the packet into pieces and add them + * individually. + * @see opus_repacketizer_out_range + * @see opus_repacketizer_out + * @see opus_repacketizer_init + * @param rp OpusRepacketizer*: The repacketizer state to which to + * add the packet. + * @param[in] data const unsigned char*: The packet data. + * The application must ensure + * this pointer remains valid + * until the next call to + * opus_repacketizer_init() or + * opus_repacketizer_destroy(). + * @param len opus_int32: The number of bytes in the packet data. + * @returns An error code indicating whether or not the operation succeeded. + * @retval #OPUS_OK The packet's contents have been added to the repacketizer + * state. + * @retval #OPUS_INVALID_PACKET The packet did not have a valid TOC sequence, + * the packet's TOC sequence was not compatible + * with previously submitted packets (because + * the coding mode, audio bandwidth, frame size, + * or channel count did not match), or adding + * this packet would increase the total amount of + * audio stored in the repacketizer state to more + * than 120 ms. + */ +OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); -OPUS_EXPORT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, int maxlen); -OPUS_EXPORT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp); +/** Construct a new packet from data previously submitted to the repacketizer + * state via opus_repacketizer_cat(). + * @param rp OpusRepacketizer*: The repacketizer state from which to + * construct the new packet. + * @param begin int: The index of the first frame in the current + * repacketizer state to include in the output. + * @param end int: One past the index of the last frame in the + * current repacketizer state to include in the + * output. + * @param[out] data const unsigned char*: The buffer in which to + * store the output packet. + * @param maxlen opus_int32: The maximum number of bytes to store in + * the output buffer. In order to guarantee + * success, this should be at least + * 1276 for a single frame, + * or for multiple frames, + * 1277*(end-begin). + * However, 1*(end-begin) plus + * the size of all packet data submitted to + * the repacketizer since the last call to + * opus_repacketizer_init() or + * opus_repacketizer_create() is also + * sufficient, and possibly much smaller. + * @returns The total size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BAD_ARG [begin,end) was an invalid range of + * frames (begin < 0, begin >= end, or end > + * opus_repacketizer_get_nb_frames()). + * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the + * complete output packet. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); -OPUS_EXPORT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, int maxlen); +/** Return the total number of frames contained in packet data submitted to + * the repacketizer state so far via opus_repacketizer_cat() since the last + * call to opus_repacketizer_init() or opus_repacketizer_create(). + * This defines the valid range of packets that can be extracted with + * opus_repacketizer_out_range() or opus_repacketizer_out(). + * @param rp OpusRepacketizer*: The repacketizer state containing the + * frames. + * @returns The total number of frames contained in the packet data submitted + * to the repacketizer state. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); + +/** Construct a new packet from data previously submitted to the repacketizer + * state via opus_repacketizer_cat(). + * This is a convenience routine that returns all the data submitted so far + * in a single packet. + * It is equivalent to calling + * @code + * opus_repacketizer_out_range(rp, 0, opus_repacketizer_get_nb_frames(rp), + * data, maxlen) + * @endcode + * @param rp OpusRepacketizer*: The repacketizer state from which to + * construct the new packet. + * @param[out] data const unsigned char*: The buffer in which to + * store the output packet. + * @param maxlen opus_int32: The maximum number of bytes to store in + * the output buffer. In order to guarantee + * success, this should be at least + * 1277*opus_repacketizer_get_nb_frames(rp). + * However, + * 1*opus_repacketizer_get_nb_frames(rp) + * plus the size of all packet data + * submitted to the repacketizer since the + * last call to opus_repacketizer_init() or + * opus_repacketizer_create() is also + * sufficient, and possibly much smaller. + * @returns The total size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the + * complete output packet. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1); /**@}*/ diff --git a/media/libopus/include/opus_custom.h b/media/libopus/include/opus_custom.h index 53d0834f00c3..6cf3963076af 100644 --- a/media/libopus/include/opus_custom.h +++ b/media/libopus/include/opus_custom.h @@ -1,16 +1,8 @@ -/* Copyright (c) 2007-2012 IETF Trust, CSIRO, Xiph.Org Foundation, - Gregory Maxwell. All rights reserved. +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2008-2012 Gregory Maxwell Written by Jean-Marc Valin and Gregory Maxwell */ -/** - @file celt.h - @brief Contains all the functions for encoding and decoding audio - */ - /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -22,11 +14,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -40,10 +27,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/** + @file opus_custom.h + @brief Opus-Custom reference implementation API + */ + #ifndef OPUS_CUSTOM_H #define OPUS_CUSTOM_H - #include "opus_defines.h" #ifdef __cplusplus @@ -51,168 +42,297 @@ extern "C" { #endif #ifdef CUSTOM_MODES -#define OPUS_CUSTOM_EXPORT OPUS_EXPORT -#define OPUS_CUSTOM_EXPORT_STATIC OPUS_EXPORT +# define OPUS_CUSTOM_EXPORT OPUS_EXPORT +# define OPUS_CUSTOM_EXPORT_STATIC OPUS_EXPORT #else -#define OPUS_CUSTOM_EXPORT -#ifdef CELT_C -#define OPUS_CUSTOM_EXPORT_STATIC static inline -#else -#define OPUS_CUSTOM_EXPORT_STATIC -#endif +# define OPUS_CUSTOM_EXPORT +# ifdef OPUS_BUILD +# define OPUS_CUSTOM_EXPORT_STATIC static inline +# else +# define OPUS_CUSTOM_EXPORT_STATIC +# endif #endif +/** @defgroup opus_custom Opus Custom + * @{ + * Opus Custom is an optional part of the Opus specification and + * reference implementation which uses a distinct API from the regular + * API and supports frame sizes that are not normally supported.\ Use + * of Opus Custom is discouraged for all but very special applications + * for which a frame size different from 2.5, 5, 10, or 20 ms is needed + * (for either complexity or latency reasons) and where interoperability + * is less important. + * + * In addition to the interoperability limitations the use of Opus custom + * disables a substantial chunk of the codec and generally lowers the + * quality available at a given bitrate. Normally when an application needs + * a different frame size from the codec it should buffer to match the + * sizes but this adds a small amount of delay which may be important + * in some very low latency applications. Some transports (especially + * constant rate RF transports) may also work best with frames of + * particular durations. + * + * Libopus only supports custom modes if they are enabled at compile time. + * + * The Opus Custom API is similar to the regular API but the + * @ref opus_encoder_create and @ref opus_decoder_create calls take + * an additional mode parameter which is a structure produced by + * a call to @ref opus_custom_mode_create. Both the encoder and decoder + * must create a mode using the same sample rate (fs) and frame size + * (frame size) so these parameters must either be signaled out of band + * or fixed in a particular implementation. + * + * Similar to regular Opus the custom modes support on the fly frame size + * switching, but the sizes available depend on the particular frame size in + * use. For some initial frame sizes on a single on the fly size is available. + */ + /** Contains the state of an encoder. One encoder state is needed - for each stream. It is initialised once at the beginning of the - stream. Do *not* re-initialise the state for every frame. + for each stream. It is initialized once at the beginning of the + stream. Do *not* re-initialize the state for every frame. @brief Encoder state */ typedef struct OpusCustomEncoder OpusCustomEncoder; /** State of the decoder. One decoder state is needed for each stream. - It is initialised once at the beginning of the stream. Do *not* - re-initialise the state for every frame */ + It is initialized once at the beginning of the stream. Do *not* + re-initialize the state for every frame. + @brief Decoder state + */ typedef struct OpusCustomDecoder OpusCustomDecoder; /** The mode contains all the information necessary to create an - encoder. Both the encoder and decoder need to be initialised - with exactly the same mode, otherwise the quality will be very - bad */ + encoder. Both the encoder and decoder need to be initialized + with exactly the same mode, otherwise the output will be + corrupted. + @brief Mode configuration + */ typedef struct OpusCustomMode OpusCustomMode; /** Creates a new mode struct. This will be passed to an encoder or - decoder. The mode MUST NOT BE DESTROYED until the encoders and - decoders that use it are destroyed as well. - @param Fs Sampling rate (32000 to 96000 Hz) - @param frame_size Number of samples (per channel) to encode in each - packet (even values; 64 - 512) - @param error Returned error code (if NULL, no error will be returned) - @return A newly created mode -*/ -OPUS_CUSTOM_EXPORT OpusCustomMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error); + * decoder. The mode MUST NOT BE DESTROYED until the encoders and + * decoders that use it are destroyed as well. + * @param [in] Fs int: Sampling rate (8000 to 96000 Hz) + * @param [in] frame_size int: Number of samples (per channel) to encode in each + * packet (64 - 1024, prime factorization must contain zero or more 2s, 3s, or 5s and no other primes) + * @param [out] error int*: Returned error code (if NULL, no error will be returned) + * @return A newly created mode + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error); /** Destroys a mode struct. Only call this after all encoders and - decoders using this mode are destroyed as well. - @param mode Mode to be destroyed -*/ + * decoders using this mode are destroyed as well. + * @param [in] mode OpusCustomMode*: Mode to be freed. + */ OPUS_CUSTOM_EXPORT void opus_custom_mode_destroy(OpusCustomMode *mode); -/* Encoder */ -OPUS_CUSTOM_EXPORT_STATIC int opus_custom_encoder_get_size(const OpusCustomMode *mode, int channels); +#if !defined(OPUS_BUILD) || defined(CELT_ENCODER_C) + +/* Encoder */ +/** Gets the size of an OpusCustomEncoder structure. + * @param [in] mode OpusCustomMode *: Mode configuration + * @param [in] channels int: Number of channels + * @returns size + */ +OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_encoder_get_size( + const OpusCustomMode *mode, + int channels +) OPUS_ARG_NONNULL(1); + +/** Initializes a previously allocated encoder state + * The memory pointed to by st must be the size returned by opus_custom_encoder_get_size. + * This is intended for applications which use their own allocator instead of malloc. + * @see opus_custom_encoder_create(),opus_custom_encoder_get_size() + * To reset a previously initialized state use the OPUS_RESET_STATE CTL. + * @param [in] st OpusCustomEncoder*: Encoder state + * @param [in] mode OpusCustomMode *: Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * decoder) + * @param [in] channels int: Number of channels + * @return OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT_STATIC int opus_custom_encoder_init( + OpusCustomEncoder *st, + const OpusCustomMode *mode, + int channels +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); + +#endif + /** Creates a new encoder state. Each stream needs its own encoder - state (can't be shared across simultaneous streams). - @param mode Contains all the information about the characteristics of - * the stream (must be the same characteristics as used for the - * decoder) - @param channels Number of channels - @param error Returns an error code - @return Newly created encoder state. + * state (can't be shared across simultaneous streams). + * @param [in] mode OpusCustomMode*: Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * decoder) + * @param [in] channels int: Number of channels + * @param [out] error int*: Returns an error code + * @return Newly created encoder state. */ -OPUS_CUSTOM_EXPORT OpusCustomEncoder *opus_custom_encoder_create(const OpusCustomMode *mode, int channels, int *error); +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomEncoder *opus_custom_encoder_create( + const OpusCustomMode *mode, + int channels, + int *error +) OPUS_ARG_NONNULL(1); -OPUS_CUSTOM_EXPORT_STATIC int opus_custom_encoder_init(OpusCustomEncoder *st, const OpusCustomMode *mode, int channels); /** Destroys a an encoder state. - @param st Encoder state to be destroyed - */ + * @param[in] st OpusCustomEncoder*: State to be freed. + */ OPUS_CUSTOM_EXPORT void opus_custom_encoder_destroy(OpusCustomEncoder *st); /** Encodes a frame of audio. - @param st Encoder state - @param pcm PCM audio in float format, with a normal range of +/-1.0. - * Samples with a range beyond +/-1.0 are supported but will - * be clipped by decoders using the integer API and should - * only be used if it is known that the far end supports - * extended dynmaic range. There must be exactly - * frame_size samples per channel. - @param compressed The compressed data is written here. This may not alias pcm or - * optional_synthesis. - @param nbCompressedBytes Maximum number of bytes to use for compressing the frame - * (can change from one frame to another) - @return Number of bytes written to "compressed". Will be the same as - * "nbCompressedBytes" unless the stream is VBR and will never be larger. - * If negative, an error has occurred (see error codes). It is IMPORTANT that - * the length returned be somehow transmitted to the decoder. Otherwise, no - * decoding is possible. -*/ -OPUS_CUSTOM_EXPORT int opus_custom_encode_float(OpusCustomEncoder *st, const float *pcm, int frame_size, unsigned char *compressed, int maxCompressedBytes); + * @param [in] st OpusCustomEncoder*: Encoder state + * @param [in] pcm float*: PCM audio in float format, with a normal range of +/-1.0. + * Samples with a range beyond +/-1.0 are supported but will + * be clipped by decoders using the integer API and should + * only be used if it is known that the far end supports + * extended dynamic range. There must be exactly + * frame_size samples per channel. + * @param [in] frame_size int: Number of samples per frame of input signal + * @param [out] compressed char *: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long. + * @param [in] maxCompressedBytes int: Maximum number of bytes to use for compressing the frame + * (can change from one frame to another) + * @return Number of bytes written to "compressed". + * If negative, an error has occurred (see error codes). It is IMPORTANT that + * the length returned be somehow transmitted to the decoder. Otherwise, no + * decoding is possible. + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode_float( + OpusCustomEncoder *st, + const float *pcm, + int frame_size, + unsigned char *compressed, + int maxCompressedBytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); /** Encodes a frame of audio. - @param st Encoder state - @param pcm PCM audio in signed 16-bit format (native endian). There must be - * exactly frame_size samples per channel. - @param compressed The compressed data is written here. This may not alias pcm or - * optional_synthesis. - @param nbCompressedBytes Maximum number of bytes to use for compressing the frame - * (can change from one frame to another) - @return Number of bytes written to "compressed". Will be the same as - * "nbCompressedBytes" unless the stream is VBR and will never be larger. - * If negative, an error has occurred (see error codes). It is IMPORTANT that - * the length returned be somehow transmitted to the decoder. Otherwise, no - * decoding is possible. + * @param [in] st OpusCustomEncoder*: Encoder state + * @param [in] pcm opus_int16*: PCM audio in signed 16-bit format (native endian). + * There must be exactly frame_size samples per channel. + * @param [in] frame_size int: Number of samples per frame of input signal + * @param [out] compressed char *: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long. + * @param [in] maxCompressedBytes int: Maximum number of bytes to use for compressing the frame + * (can change from one frame to another) + * @return Number of bytes written to "compressed". + * If negative, an error has occurred (see error codes). It is IMPORTANT that + * the length returned be somehow transmitted to the decoder. Otherwise, no + * decoding is possible. */ -OPUS_CUSTOM_EXPORT int opus_custom_encode(OpusCustomEncoder *st, const opus_int16 *pcm, int frame_size, unsigned char *compressed, int maxCompressedBytes); +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode( + OpusCustomEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *compressed, + int maxCompressedBytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); -/** Query and set encoder parameters - @param st Encoder state - @param request Parameter to change or query - @param value Pointer to a 32-bit int value - @return Error code -*/ -OPUS_CUSTOM_EXPORT int opus_custom_encoder_ctl(OpusCustomEncoder * restrict st, int request, ...); +/** Perform a CTL function on an Opus custom encoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @see opus_encoderctls + */ +OPUS_CUSTOM_EXPORT int opus_custom_encoder_ctl(OpusCustomEncoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1); + +#if !defined(OPUS_BUILD) || defined(CELT_DECODER_C) /* Decoder */ -OPUS_CUSTOM_EXPORT_STATIC int opus_custom_decoder_get_size(const OpusCustomMode *mode, int channels); +/** Gets the size of an OpusCustomDecoder structure. + * @param [in] mode OpusCustomMode *: Mode configuration + * @param [in] channels int: Number of channels + * @returns size + */ +OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_decoder_get_size( + const OpusCustomMode *mode, + int channels +) OPUS_ARG_NONNULL(1); + +/** Initializes a previously allocated decoder state + * The memory pointed to by st must be the size returned by opus_custom_decoder_get_size. + * This is intended for applications which use their own allocator instead of malloc. + * @see opus_custom_decoder_create(),opus_custom_decoder_get_size() + * To reset a previously initialized state use the OPUS_RESET_STATE CTL. + * @param [in] st OpusCustomDecoder*: Decoder state + * @param [in] mode OpusCustomMode *: Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * encoder) + * @param [in] channels int: Number of channels + * @return OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT_STATIC int opus_custom_decoder_init( + OpusCustomDecoder *st, + const OpusCustomMode *mode, + int channels +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); + +#endif + /** Creates a new decoder state. Each stream needs its own decoder state (can't - be shared across simultaneous streams). - @param mode Contains all the information about the characteristics of the - stream (must be the same characteristics as used for the encoder) - @param channels Number of channels - @param error Returns an error code - @return Newly created decoder state. - */ -OPUS_CUSTOM_EXPORT OpusCustomDecoder *opus_custom_decoder_create(const OpusCustomMode *mode, int channels, int *error); + * be shared across simultaneous streams). + * @param [in] mode OpusCustomMode: Contains all the information about the characteristics of the + * stream (must be the same characteristics as used for the encoder) + * @param [in] channels int: Number of channels + * @param [out] error int*: Returns an error code + * @return Newly created decoder state. + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomDecoder *opus_custom_decoder_create( + const OpusCustomMode *mode, + int channels, + int *error +) OPUS_ARG_NONNULL(1); -OPUS_CUSTOM_EXPORT_STATIC int opus_custom_decoder_init(OpusCustomDecoder *st, const OpusCustomMode *mode, int channels); - -/** Destroys a a decoder state. - @param st Decoder state to be destroyed - */ +/** Destroys a an decoder state. + * @param[in] st OpusCustomDecoder*: State to be freed. + */ OPUS_CUSTOM_EXPORT void opus_custom_decoder_destroy(OpusCustomDecoder *st); -/** Decodes a frame of audio. - @param st Decoder state - @param data Compressed data produced by an encoder - @param len Number of bytes to read from "data". This MUST be exactly the number - of bytes returned by the encoder. Using a larger value WILL NOT WORK. - @param pcm One frame (frame_size samples per channel) of decoded PCM will be - returned here in float format. - @return Error code. - */ -OPUS_CUSTOM_EXPORT int opus_custom_decode_float(OpusCustomDecoder *st, const unsigned char *data, int len, float *pcm, int frame_size); +/** Decode an opus custom frame with floating point output + * @param [in] st OpusCustomDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len int: Number of bytes in payload + * @param [out] pcm float*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(float) + * @param [in] frame_size Number of samples per channel of available space in *pcm. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode_float( + OpusCustomDecoder *st, + const unsigned char *data, + int len, + float *pcm, + int frame_size +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); -/** Decodes a frame of audio. - @param st Decoder state - @param data Compressed data produced by an encoder - @param len Number of bytes to read from "data". This MUST be exactly the number - of bytes returned by the encoder. Using a larger value WILL NOT WORK. - @param pcm One frame (frame_size samples per channel) of decoded PCM will be - returned here in 16-bit PCM format (native endian). - @return Error code. - */ -OPUS_CUSTOM_EXPORT int opus_custom_decode(OpusCustomDecoder *st, const unsigned char *data, int len, opus_int16 *pcm, int frame_size); +/** Decode an opus custom frame + * @param [in] st OpusCustomDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len int: Number of bytes in payload + * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size Number of samples per channel of available space in *pcm. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode( + OpusCustomDecoder *st, + const unsigned char *data, + int len, + opus_int16 *pcm, + int frame_size +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); -/** Query and set decoder parameters - @param st Decoder state - @param request Parameter to change or query - @param value Pointer to a 32-bit int value - @return Error code - */ -OPUS_CUSTOM_EXPORT int opus_custom_decoder_ctl(OpusCustomDecoder * restrict st, int request, ...); +/** Perform a CTL function on an Opus custom decoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @see opus_genericctls + */ +OPUS_CUSTOM_EXPORT int opus_custom_decoder_ctl(OpusCustomDecoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1); + +/**@}*/ #ifdef __cplusplus } diff --git a/media/libopus/include/opus_defines.h b/media/libopus/include/opus_defines.h index b64049bda9e6..3474e84c4342 100644 --- a/media/libopus/include/opus_defines.h +++ b/media/libopus/include/opus_defines.h @@ -1,10 +1,6 @@ -/* Copyright (c) 2010-2012 IETF Trust, Xiph.Org Foundation, Skype Limited. All rights reserved. +/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited Written by Jean-Marc Valin and Koen Vos */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -48,7 +39,7 @@ extern "C" { #endif -/** @defgroup errorcodes Error codes +/** @defgroup opus_errorcodes Error codes * @{ */ /** No error @hideinitializer*/ @@ -72,20 +63,58 @@ extern "C" { /** @cond OPUS_INTERNAL_DOC */ /**Export control for opus functions */ -#if defined(WIN32) -# ifdef OPUS_BUILD +#ifndef OPUS_EXPORT +# if defined(WIN32) +# ifdef OPUS_BUILD # define OPUS_EXPORT __declspec(dllexport) +# else +# define OPUS_EXPORT +# endif +# elif defined(__GNUC__) && defined(OPUS_BUILD) +# define OPUS_EXPORT __attribute__ ((visibility ("default"))) # else -# define OPUS_EXPORT __declspec(dllimport) +# define OPUS_EXPORT +# endif +#endif + +# if !defined(OPUS_GNUC_PREREQ) +# if defined(__GNUC__)&&defined(__GNUC_MINOR__) +# define OPUS_GNUC_PREREQ(_maj,_min) \ + ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) +# else +# define OPUS_GNUC_PREREQ(_maj,_min) 0 +# endif +# endif + +#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) +# if OPUS_GNUC_PREREQ(3,0) +# define OPUS_RESTRICT __restrict__ +# elif (defined(_MSC_VER) && _MSC_VER >= 1400) +# define OPUS_RESTRICT __restrict +# else +# define OPUS_RESTRICT # endif -#elif defined(__GNUC__) && defined(OPUS_BUILD) -# define OPUS_EXPORT __attribute__ ((visibility ("default"))) #else -# define OPUS_EXPORT +# define OPUS_RESTRICT restrict +#endif + +/**Warning attributes for opus functions + * NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out + * some paranoid null checks. */ +#if defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) +# define OPUS_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) +#else +# define OPUS_WARN_UNUSED_RESULT +#endif +#if !defined(OPUS_BUILD) && defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) +# define OPUS_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x))) +#else +# define OPUS_ARG_NONNULL(_x) #endif /** These are the actual Encoder CTL ID numbers. - * They should not be used directly by applications. */ + * They should not be used directly by applications. + * In general, SETs should be even and GETs should be odd.*/ #define OPUS_SET_APPLICATION_REQUEST 4000 #define OPUS_GET_APPLICATION_REQUEST 4001 #define OPUS_SET_BITRATE_REQUEST 4002 @@ -112,17 +141,28 @@ extern "C" { #define OPUS_GET_SIGNAL_REQUEST 4025 #define OPUS_GET_LOOKAHEAD_REQUEST 4027 /* #define OPUS_RESET_STATE 4028 */ +#define OPUS_GET_SAMPLE_RATE_REQUEST 4029 #define OPUS_GET_FINAL_RANGE_REQUEST 4031 #define OPUS_GET_PITCH_REQUEST 4033 +#define OPUS_SET_GAIN_REQUEST 4034 +#define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */ +#define OPUS_SET_LSB_DEPTH_REQUEST 4036 +#define OPUS_GET_LSB_DEPTH_REQUEST 4037 +#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039 +#define OPUS_SET_EXPERT_FRAME_DURATION_REQUEST 4040 +#define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041 + +/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */ /* Macros to trigger compilation errors when the wrong types are provided to a CTL */ #define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x)) #define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr))) #define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr))) +#define __opus_check_val16_ptr(ptr) ((ptr) + ((ptr) - (opus_val16*)(ptr))) /** @endcond */ -/** @defgroup ctlvalues Pre-defined values for CTL interface - * @see genericctls, encoderctls +/** @defgroup opus_ctlvalues Pre-defined values for CTL interface + * @see opus_genericctls, opus_encoderctls * @{ */ /* Values for the various encoder CTLs */ @@ -141,16 +181,25 @@ extern "C" { #define OPUS_SIGNAL_VOICE 3001 /**< Signal being encoded is voice */ #define OPUS_SIGNAL_MUSIC 3002 /**< Signal being encoded is music */ -#define OPUS_BANDWIDTH_NARROWBAND 1101 /**< 4kHz bandpass @hideinitializer*/ -#define OPUS_BANDWIDTH_MEDIUMBAND 1102 /**< 6kHz bandpass @hideinitializer*/ -#define OPUS_BANDWIDTH_WIDEBAND 1103 /**< 8kHz bandpass @hideinitializer*/ -#define OPUS_BANDWIDTH_SUPERWIDEBAND 1104 /**<12kHz bandpass @hideinitializer*/ -#define OPUS_BANDWIDTH_FULLBAND 1105 /**<20kHz bandpass @hideinitializer*/ +#define OPUS_BANDWIDTH_NARROWBAND 1101 /**< 4 kHz bandpass @hideinitializer*/ +#define OPUS_BANDWIDTH_MEDIUMBAND 1102 /**< 6 kHz bandpass @hideinitializer*/ +#define OPUS_BANDWIDTH_WIDEBAND 1103 /**< 8 kHz bandpass @hideinitializer*/ +#define OPUS_BANDWIDTH_SUPERWIDEBAND 1104 /**<12 kHz bandpass @hideinitializer*/ +#define OPUS_BANDWIDTH_FULLBAND 1105 /**<20 kHz bandpass @hideinitializer*/ + +#define OPUS_FRAMESIZE_ARG 5000 /**< Select frame size from the argument (default) */ +#define OPUS_FRAMESIZE_2_5_MS 5001 /**< Use 2.5 ms frames */ +#define OPUS_FRAMESIZE_5_MS 5002 /**< Use 5 ms frames */ +#define OPUS_FRAMESIZE_10_MS 5003 /**< Use 10 ms frames */ +#define OPUS_FRAMESIZE_20_MS 5004 /**< Use 20 ms frames */ +#define OPUS_FRAMESIZE_40_MS 5005 /**< Use 40 ms frames */ +#define OPUS_FRAMESIZE_60_MS 5006 /**< Use 60 ms frames */ +#define OPUS_FRAMESIZE_VARIABLE 5010 /**< Optimize the frame size dynamically */ /**@}*/ -/** @defgroup encoderctls Encoder related CTLs +/** @defgroup opus_encoderctls Encoder related CTLs * * These are convenience macros for use with the \c opus_encode_ctl * interface. They are used to generate the appropriate series of @@ -164,144 +213,242 @@ extern "C" { * ret = opus_encoder_ctl(enc_ctx, OPUS_SET_BANDWIDTH(OPUS_AUTO)); * if (ret != OPUS_OK) return ret; * - * int rate; + * opus_int32 rate; * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&rate)); * * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE); * @endcode * - * @see genericctls, opusencoder + * @see opus_genericctls, opus_encoder * @{ */ /** Configures the encoder's computational complexity. * The supported range is 0-10 inclusive with 10 representing the highest complexity. - * The default value is 10. - * @param[in] x int: 0-10, inclusive + * @see OPUS_GET_COMPLEXITY + * @param[in] x opus_int32: Allowed values: 0-10, inclusive. + * * @hideinitializer */ #define OPUS_SET_COMPLEXITY(x) OPUS_SET_COMPLEXITY_REQUEST, __opus_check_int(x) -/** Gets the encoder's complexity configuration, @see OPUS_SET_COMPLEXITY - * @param[out] x int*: 0-10, inclusive +/** Gets the encoder's complexity configuration. + * @see OPUS_SET_COMPLEXITY + * @param[out] x opus_int32 *: Returns a value in the range 0-10, + * inclusive. * @hideinitializer */ #define OPUS_GET_COMPLEXITY(x) OPUS_GET_COMPLEXITY_REQUEST, __opus_check_int_ptr(x) /** Configures the bitrate in the encoder. - * Rates from 500 to 512000 bits per second are meaningful as well as the - * special values OPUS_BITRATE_AUTO and OPUS_BITRATE_MAX. - * The value OPUS_BITRATE_MAX can be used to cause the codec to use as much rate - * as it can, which is useful for controlling the rate by adjusting the output - * buffer size. - * @param[in] x opus_int32: bitrate in bits per second. + * Rates from 500 to 512000 bits per second are meaningful, as well as the + * special values #OPUS_AUTO and #OPUS_BITRATE_MAX. + * The value #OPUS_BITRATE_MAX can be used to cause the codec to use as much + * rate as it can, which is useful for controlling the rate by adjusting the + * output buffer size. + * @see OPUS_GET_BITRATE + * @param[in] x opus_int32: Bitrate in bits per second. The default + * is determined based on the number of + * channels and the input sampling rate. * @hideinitializer */ #define OPUS_SET_BITRATE(x) OPUS_SET_BITRATE_REQUEST, __opus_check_int(x) -/** Gets the encoder's bitrate configuration, @see OPUS_SET_BITRATE - * @param[out] x opus_int32*: bitrate in bits per second. +/** Gets the encoder's bitrate configuration. + * @see OPUS_SET_BITRATE + * @param[out] x opus_int32 *: Returns the bitrate in bits per second. + * The default is determined based on the + * number of channels and the input + * sampling rate. * @hideinitializer */ #define OPUS_GET_BITRATE(x) OPUS_GET_BITRATE_REQUEST, __opus_check_int_ptr(x) -/** Configures VBR in the encoder. - * The following values are currently supported: - * - 0 CBR - * - 1 VBR (default) +/** Enables or disables variable bitrate (VBR) in the encoder. * The configured bitrate may not be met exactly because frames must * be an integer number of bytes in length. * @warning Only the MDCT mode of Opus can provide hard CBR behavior. - * @param[in] x int: 0; 1 (default) + * @see OPUS_GET_VBR + * @see OPUS_SET_VBR_CONSTRAINT + * @param[in] x opus_int32: Allowed values: + *
    + *
    0
    Hard CBR. For LPC/hybrid modes at very low bit-rate, this can + * cause noticeable quality degradation.
    + *
    1
    VBR (default). The exact type of VBR is controlled by + * #OPUS_SET_VBR_CONSTRAINT.
    + *
    * @hideinitializer */ #define OPUS_SET_VBR(x) OPUS_SET_VBR_REQUEST, __opus_check_int(x) -/** Gets the encoder's VBR configuration, @see OPUS_SET_VBR - * @param[out] x int*: 0; 1 +/** Determine if variable bitrate (VBR) is enabled in the encoder. + * @see OPUS_SET_VBR + * @see OPUS_GET_VBR_CONSTRAINT + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    0
    Hard CBR.
    + *
    1
    VBR (default). The exact type of VBR may be retrieved via + * #OPUS_GET_VBR_CONSTRAINT.
    + *
    * @hideinitializer */ #define OPUS_GET_VBR(x) OPUS_GET_VBR_REQUEST, __opus_check_int_ptr(x) -/** Configures constrained VBR in the encoder. - * The following values are currently supported: - * - 0 Unconstrained VBR (default) - * - 1 Maximum one frame buffering delay assuming transport with a serialization speed of the nominal bitrate - * This setting is irrelevant when the encoder is in CBR mode. +/** Enables or disables constrained VBR in the encoder. + * This setting is ignored when the encoder is in CBR mode. * @warning Only the MDCT mode of Opus currently heeds the constraint. * Speech mode ignores it completely, hybrid mode may fail to obey it * if the LPC layer uses more bitrate than the constraint would have * permitted. - * @param[in] x int: 0 (default); 1 + * @see OPUS_GET_VBR_CONSTRAINT + * @see OPUS_SET_VBR + * @param[in] x opus_int32: Allowed values: + *
    + *
    0
    Unconstrained VBR.
    + *
    1
    Constrained VBR (default). This creates a maximum of one + * frame of buffering delay assuming a transport with a + * serialization speed of the nominal bitrate.
    + *
    * @hideinitializer */ #define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x) -/** Gets the encoder's constrained VBR configuration @see OPUS_SET_VBR_CONSTRAINT - * @param[out] x int*: 0; 1 +/** Determine if constrained VBR is enabled in the encoder. + * @see OPUS_SET_VBR_CONSTRAINT + * @see OPUS_GET_VBR + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    0
    Unconstrained VBR.
    + *
    1
    Constrained VBR (default).
    + *
    * @hideinitializer */ #define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x) /** Configures mono/stereo forcing in the encoder. - * This is useful when the caller knows that the input signal is currently a mono - * source embedded in a stereo stream. - * @param[in] x int: OPUS_AUTO (default); 1 (forced mono); 2 (forced stereo) + * This can force the encoder to produce packets encoded as either mono or + * stereo, regardless of the format of the input audio. This is useful when + * the caller knows that the input signal is currently a mono source embedded + * in a stereo stream. + * @see OPUS_GET_FORCE_CHANNELS + * @param[in] x opus_int32: Allowed values: + *
    + *
    #OPUS_AUTO
    Not forced (default)
    + *
    1
    Forced mono
    + *
    2
    Forced stereo
    + *
    * @hideinitializer */ #define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x) -/** Gets the encoder's forced channel configuration, @see OPUS_SET_FORCE_CHANNELS - * @param[out] x int*: OPUS_AUTO; 0; 1 +/** Gets the encoder's forced channel configuration. + * @see OPUS_SET_FORCE_CHANNELS + * @param[out] x opus_int32 *: + *
    + *
    #OPUS_AUTO
    Not forced (default)
    + *
    1
    Forced mono
    + *
    2
    Forced stereo
    + *
    * @hideinitializer */ #define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x) -/** Configures the encoder's maximum bandpass allowed, @see OPUS_GET_MAX_BANDWIDTH - * The supported values are: - * - OPUS_BANDWIDTH_NARROWBAND 4kHz passband - * - OPUS_BANDWIDTH_MEDIUMBAND 6kHz passband - * - OPUS_BANDWIDTH_WIDEBAND 8kHz passband - * - OPUS_BANDWIDTH_SUPERWIDEBAND 12kHz passband - * - OPUS_BANDWIDTH_FULLBAND 20kHz passband (default) - * @param[in] x int: Bandwidth value +/** Configures the maximum bandpass that the encoder will select automatically. + * Applications should normally use this instead of #OPUS_SET_BANDWIDTH + * (leaving that set to the default, #OPUS_AUTO). This allows the + * application to set an upper bound based on the type of input it is + * providing, but still gives the encoder the freedom to reduce the bandpass + * when the bitrate becomes too low, for better overall quality. + * @see OPUS_GET_MAX_BANDWIDTH + * @param[in] x opus_int32: Allowed values: + *
    + *
    OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    + *
    OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    + *
    OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    + *
    OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    + *
    OPUS_BANDWIDTH_FULLBAND
    20 kHz passband (default)
    + *
    * @hideinitializer */ #define OPUS_SET_MAX_BANDWIDTH(x) OPUS_SET_MAX_BANDWIDTH_REQUEST, __opus_check_int(x) -/** Gets the encoder's configured maximum bandpass allowed, @see OPUS_SET_MAX_BANDWIDTH - * @param[out] x int*: Bandwidth value +/** Gets the encoder's configured maximum allowed bandpass. + * @see OPUS_SET_MAX_BANDWIDTH + * @param[out] x opus_int32 *: Allowed values: + *
    + *
    #OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    + *
    #OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    + *
    #OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    + *
    #OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    + *
    #OPUS_BANDWIDTH_FULLBAND
    20 kHz passband (default)
    + *
    * @hideinitializer */ #define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) -/** Configures the encoder's bandpass, @see OPUS_GET_BANDWIDTH - * The supported values are: - * - OPUS_AUTO (default) - * - OPUS_BANDWIDTH_NARROWBAND 4kHz passband - * - OPUS_BANDWIDTH_MEDIUMBAND 6kHz passband - * - OPUS_BANDWIDTH_WIDEBAND 8kHz passband - * - OPUS_BANDWIDTH_SUPERWIDEBAND 12kHz passband - * - OPUS_BANDWIDTH_FULLBAND 20kHz passband - * @param[in] x int: Bandwidth value +/** Sets the encoder's bandpass to a specific value. + * This prevents the encoder from automatically selecting the bandpass based + * on the available bitrate. If an application knows the bandpass of the input + * audio it is providing, it should normally use #OPUS_SET_MAX_BANDWIDTH + * instead, which still gives the encoder the freedom to reduce the bandpass + * when the bitrate becomes too low, for better overall quality. + * @see OPUS_GET_BANDWIDTH + * @param[in] x opus_int32: Allowed values: + *
    + *
    #OPUS_AUTO
    (default)
    + *
    #OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    + *
    #OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    + *
    #OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    + *
    #OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    + *
    #OPUS_BANDWIDTH_FULLBAND
    20 kHz passband
    + *
    * @hideinitializer */ #define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __opus_check_int(x) /** Configures the type of signal being encoded. * This is a hint which helps the encoder's mode selection. - * The supported values are: - * - OPUS_SIGNAL_AUTO (default) - * - OPUS_SIGNAL_VOICE - * - OPUS_SIGNAL_MUSIC - * @param[in] x int: Signal type + * @see OPUS_GET_SIGNAL + * @param[in] x opus_int32: Allowed values: + *
    + *
    #OPUS_AUTO
    (default)
    + *
    #OPUS_SIGNAL_VOICE
    Bias thresholds towards choosing LPC or Hybrid modes.
    + *
    #OPUS_SIGNAL_MUSIC
    Bias thresholds towards choosing MDCT modes.
    + *
    * @hideinitializer */ #define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __opus_check_int(x) -/** Gets the encoder's configured signal type, @see OPUS_SET_SIGNAL - * - * @param[out] x int*: Signal type +/** Gets the encoder's configured signal type. + * @see OPUS_SET_SIGNAL + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    #OPUS_AUTO
    (default)
    + *
    #OPUS_SIGNAL_VOICE
    Bias thresholds towards choosing LPC or Hybrid modes.
    + *
    #OPUS_SIGNAL_MUSIC
    Bias thresholds towards choosing MDCT modes.
    + *
    * @hideinitializer */ #define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __opus_check_int_ptr(x) /** Configures the encoder's intended application. * The initial value is a mandatory argument to the encoder_create function. - * The supported values are: - * - OPUS_APPLICATION_VOIP Process signal for improved speech intelligibility - * - OPUS_APPLICATION_AUDIO Favor faithfulness to the original input - * - OPUS_APPLICATION_RESTRICTED_LOWDELAY Configure the minimum possible coding delay - * - * @param[in] x int: Application value + * @see OPUS_GET_APPLICATION + * @param[in] x opus_int32: Returns one of the following values: + *
    + *
    #OPUS_APPLICATION_VOIP
    + *
    Process signal for improved speech intelligibility.
    + *
    #OPUS_APPLICATION_AUDIO
    + *
    Favor faithfulness to the original input.
    + *
    #OPUS_APPLICATION_RESTRICTED_LOWDELAY
    + *
    Configure the minimum possible coding delay by disabling certain modes + * of operation.
    + *
    * @hideinitializer */ #define OPUS_SET_APPLICATION(x) OPUS_SET_APPLICATION_REQUEST, __opus_check_int(x) -/** Gets the encoder's configured application, @see OPUS_SET_APPLICATION - * - * @param[out] x int*: Application value +/** Gets the encoder's configured application. + * @see OPUS_SET_APPLICATION + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    #OPUS_APPLICATION_VOIP
    + *
    Process signal for improved speech intelligibility.
    + *
    #OPUS_APPLICATION_AUDIO
    + *
    Favor faithfulness to the original input.
    + *
    #OPUS_APPLICATION_RESTRICTED_LOWDELAY
    + *
    Configure the minimum possible coding delay by disabling certain modes + * of operation.
    + *
    * @hideinitializer */ #define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x) +/** Gets the sampling rate the encoder or decoder was initialized with. + * This simply returns the Fs value passed to opus_encoder_init() + * or opus_decoder_init(). + * @param[out] x opus_int32 *: Sampling rate of encoder or decoder. + * @hideinitializer + */ +#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x) + /** Gets the total samples of delay added by the entire codec. * This can be queried by the encoder and then the provided number of samples can be * skipped on from the start of the decoder's output to provide time aligned input @@ -313,19 +460,27 @@ extern "C" { * version to version, or even depend on the encoder's initial configuration. * Applications needing delay compensation should call this CTL rather than * hard-coding a value. - * @param[out] x int*: Number of lookahead samples + * @param[out] x opus_int32 *: Number of lookahead samples * @hideinitializer */ #define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x) -/** Configures the encoder's use of inband forward error correction. +/** Configures the encoder's use of inband forward error correction (FEC). * @note This is only applicable to the LPC layer - * - * @param[in] x int: FEC flag, 0 (disabled) is default + * @see OPUS_GET_INBAND_FEC + * @param[in] x opus_int32: Allowed values: + *
    + *
    0
    Disable inband FEC (default).
    + *
    1
    Enable inband FEC.
    + *
    * @hideinitializer */ #define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x) -/** Gets encoder's configured use of inband forward error correction, @see OPUS_SET_INBAND_FEC - * - * @param[out] x int*: FEC flag +/** Gets encoder's configured use of inband forward error correction. + * @see OPUS_SET_INBAND_FEC + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    0
    Inband FEC disabled (default).
    + *
    1
    Inband FEC enabled.
    + *
    * @hideinitializer */ #define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x) @@ -333,30 +488,96 @@ extern "C" { * Higher values with trigger progressively more loss resistant behavior in the encoder * at the expense of quality at a given bitrate in the lossless case, but greater quality * under loss. - * - * @param[in] x int: Loss percentage in the range 0-100, inclusive. + * @see OPUS_GET_PACKET_LOSS_PERC + * @param[in] x opus_int32: Loss percentage in the range 0-100, inclusive (default: 0). * @hideinitializer */ #define OPUS_SET_PACKET_LOSS_PERC(x) OPUS_SET_PACKET_LOSS_PERC_REQUEST, __opus_check_int(x) -/** Gets the encoder's configured packet loss percentage, @see OPUS_SET_PACKET_LOSS_PERC - * - * @param[out] x int*: Loss percentage in the range 0-100, inclusive. +/** Gets the encoder's configured packet loss percentage. + * @see OPUS_SET_PACKET_LOSS_PERC + * @param[out] x opus_int32 *: Returns the configured loss percentage + * in the range 0-100, inclusive (default: 0). * @hideinitializer */ #define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __opus_check_int_ptr(x) -/** Configures the encoder's use of discontinuous transmission. +/** Configures the encoder's use of discontinuous transmission (DTX). * @note This is only applicable to the LPC layer - * - * @param[in] x int: DTX flag, 0 (disabled) is default + * @see OPUS_GET_DTX + * @param[in] x opus_int32: Allowed values: + *
    + *
    0
    Disable DTX (default).
    + *
    1
    Enabled DTX.
    + *
    * @hideinitializer */ #define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __opus_check_int(x) -/** Gets encoder's configured use of discontinuous transmission, @see OPUS_SET_DTX - * - * @param[out] x int*: DTX flag +/** Gets encoder's configured use of discontinuous transmission. + * @see OPUS_SET_DTX + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    0
    DTX disabled (default).
    + *
    1
    DTX enabled.
    + *
    * @hideinitializer */ #define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x) +/** Configures the depth of signal being encoded. + * This is a hint which helps the encoder identify silence and near-silence. + * @see OPUS_GET_LSB_DEPTH + * @param[in] x opus_int32: Input precision in bits, between 8 and 24 + * (default: 24). + * @hideinitializer */ +#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured signal depth. + * @see OPUS_SET_LSB_DEPTH + * @param[out] x opus_int32 *: Input precision in bits, between 8 and + * 24 (default: 24). + * @hideinitializer */ +#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x) + +/** Gets the duration (in samples) of the last packet successfully decoded or concealed. + * @param[out] x opus_int32 *: Number of samples (at current sampling rate). + * @hideinitializer */ +#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's use of variable duration frames. + * When variable duration is enabled, the encoder is free to use a shorter frame + * size than the one requested in the opus_encode*() call. + * It is then the user's responsibility + * to verify how much audio was encoded by checking the ToC byte of the encoded + * packet. The part of the audio that was not encoded needs to be resent to the + * encoder for the next call. Do not use this option unless you really + * know what you are doing. + * @see OPUS_GET_EXPERT_VARIABLE_DURATION + * @param[in] x opus_int32: Allowed values: + *
    + *
    OPUS_FRAMESIZE_ARG
    Select frame size from the argument (default).
    + *
    OPUS_FRAMESIZE_2_5_MS
    Use 2.5 ms frames.
    + *
    OPUS_FRAMESIZE_5_MS
    Use 2.5 ms frames.
    + *
    OPUS_FRAMESIZE_10_MS
    Use 10 ms frames.
    + *
    OPUS_FRAMESIZE_20_MS
    Use 20 ms frames.
    + *
    OPUS_FRAMESIZE_40_MS
    Use 40 ms frames.
    + *
    OPUS_FRAMESIZE_60_MS
    Use 60 ms frames.
    + *
    OPUS_FRAMESIZE_VARIABLE
    Optimize the frame size dynamically.
    + *
    + * @hideinitializer */ +#define OPUS_SET_EXPERT_FRAME_DURATION(x) OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured use of variable duration frames. + * @see OPUS_SET_EXPERT_VARIABLE_DURATION + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    OPUS_FRAMESIZE_ARG
    Select frame size from the argument (default).
    + *
    OPUS_FRAMESIZE_2_5_MS
    Use 2.5 ms frames.
    + *
    OPUS_FRAMESIZE_5_MS
    Use 2.5 ms frames.
    + *
    OPUS_FRAMESIZE_10_MS
    Use 10 ms frames.
    + *
    OPUS_FRAMESIZE_20_MS
    Use 20 ms frames.
    + *
    OPUS_FRAMESIZE_40_MS
    Use 40 ms frames.
    + *
    OPUS_FRAMESIZE_60_MS
    Use 60 ms frames.
    + *
    OPUS_FRAMESIZE_VARIABLE
    Optimize the frame size dynamically.
    + *
    + * @hideinitializer */ +#define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x) + /**@}*/ -/** @defgroup genericctls Generic CTLs +/** @defgroup opus_genericctls Generic CTLs * * These macros are used with the \c opus_decoder_ctl and * \c opus_encoder_ctl calls to generate a particular @@ -386,7 +607,7 @@ extern "C" { * } * @endcode * - * @see opusencoder, opus_decoder_ctl, opus_encoder_ctl + * @see opus_encoder, opus_decoder_ctl, opus_encoder_ctl, opus_decoderctls, opus_encoderctls * @{ */ @@ -402,7 +623,7 @@ extern "C" { * The encoder and decoder state should be identical after coding a payload * (assuming no data corruption or software bugs) * - * @param[out] x opus_uint32*: Entropy coder state + * @param[out] x opus_uint32 *: Entropy coder state * * @hideinitializer */ #define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x) @@ -414,19 +635,52 @@ extern "C" { * * This CTL is only implemented for decoder instances. * - * @param[out] x opus_int32*: pitch period at 48 kHz (or 0 if not available) + * @param[out] x opus_int32 *: pitch period at 48 kHz (or 0 if not available) * * @hideinitializer */ #define OPUS_GET_PITCH(x) OPUS_GET_PITCH_REQUEST, __opus_check_int_ptr(x) -/** Gets the encoder's configured bandpass or the decoder's last bandpass, @see OPUS_SET_BANDWIDTH - * @param[out] x int*: Bandwidth value +/** Gets the encoder's configured bandpass or the decoder's last bandpass. + * @see OPUS_SET_BANDWIDTH + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    #OPUS_AUTO
    (default)
    + *
    #OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    + *
    #OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    + *
    #OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    + *
    #OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    + *
    #OPUS_BANDWIDTH_FULLBAND
    20 kHz passband
    + *
    * @hideinitializer */ #define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) /**@}*/ -/** @defgroup libinfo Opus library information functions +/** @defgroup opus_decoderctls Decoder related CTLs + * @see opus_genericctls, opus_encoderctls, opus_decoder + * @{ + */ + +/** Configures decoder gain adjustment. + * Scales the decoded output by a factor specified in Q8 dB units. + * This has a maximum range of -32768 to 32767 inclusive, and returns + * OPUS_BAD_ARG otherwise. The default is zero indicating no adjustment. + * This setting survives decoder reset. + * + * gain = pow(10, x/(20.0*256)) + * + * @param[in] x opus_int32: Amount to scale PCM signal by in Q8 dB units. + * @hideinitializer */ +#define OPUS_SET_GAIN(x) OPUS_SET_GAIN_REQUEST, __opus_check_int(x) +/** Gets the decoder's configured gain adjustment. @see OPUS_SET_GAIN + * + * @param[out] x opus_int32 *: Amount to scale PCM signal by in Q8 dB units. + * @hideinitializer */ +#define OPUS_GET_GAIN(x) OPUS_GET_GAIN_REQUEST, __opus_check_int_ptr(x) + +/**@}*/ + +/** @defgroup opus_libinfo Opus library information functions * @{ */ diff --git a/media/libopus/include/opus_multistream.h b/media/libopus/include/opus_multistream.h index 772c0d1d0362..ae5997934ae2 100644 --- a/media/libopus/include/opus_multistream.h +++ b/media/libopus/include/opus_multistream.h @@ -1,10 +1,6 @@ -/* Copyright (c) 2011-2012 IETF Trust, Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2011 Xiph.Org Foundation Written by Jean-Marc Valin */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -48,132 +39,620 @@ extern "C" { #endif -typedef struct OpusMSEncoder OpusMSEncoder; -typedef struct OpusMSDecoder OpusMSDecoder; +/** @cond OPUS_INTERNAL_DOC */ +/** Macros to trigger compilation errors when the wrong types are provided to a + * CTL. */ +/**@{*/ #define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr))) #define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr))) +/**@}*/ +/** These are the actual encoder and decoder CTL ID numbers. + * They should not be used directly by applications. + * In general, SETs should be even and GETs should be odd.*/ +/**@{*/ #define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120 #define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122 +/**@}*/ +/** @endcond */ + +/** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs + * + * These are convenience macros that are specific to the + * opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl() + * interface. + * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and + * @ref opus_decoderctls may be applied to a multistream encoder or decoder as + * well. + * In addition, you may retrieve the encoder or decoder state for an specific + * stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or + * #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually. + */ +/**@{*/ + +/** Gets the encoder state for an individual stream of a multistream encoder. + * @param[in] x opus_int32: The index of the stream whose encoder you + * wish to retrieve. + * This must be non-negative and less than + * the streams parameter used + * to initialize the encoder. + * @param[out] y OpusEncoder**: Returns a pointer to the given + * encoder state. + * @retval OPUS_BAD_ARG The index of the requested stream was out of range. + * @hideinitializer + */ #define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y) + +/** Gets the decoder state for an individual stream of a multistream decoder. + * @param[in] x opus_int32: The index of the stream whose decoder you + * wish to retrieve. + * This must be non-negative and less than + * the streams parameter used + * to initialize the decoder. + * @param[out] y OpusDecoder**: Returns a pointer to the given + * decoder state. + * @retval OPUS_BAD_ARG The index of the requested stream was out of range. + * @hideinitializer + */ #define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y) -/** Allocate and initialize a multistream encoder state object. - * Call opus_multistream_encoder_destroy() to release - * this object when finished. */ -OPUS_EXPORT OpusMSEncoder *opus_multistream_encoder_create( - opus_int32 Fs, /**< Sampling rate of input signal (Hz) */ - int channels, /**< Number of channels in the input signal */ - int streams, /**< Total number of streams to encode from the input */ - int coupled_streams, /**< Number of coupled (stereo) streams to encode */ - unsigned char *mapping, /**< Encoded mapping between channels and streams */ - int application, /**< Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */ - int *error /**< Error code */ -); +/**@}*/ -/** Initialize an already allocated multistream encoder state. */ -OPUS_EXPORT int opus_multistream_encoder_init( - OpusMSEncoder *st, /**< Encoder state */ - opus_int32 Fs, /**< Sampling rate of input signal (Hz) */ - int channels, /**< Number of channels in the input signal */ - int streams, /**< Total number of streams to encode from the input */ - int coupled_streams, /**< Number of coupled (stereo) streams to encode */ - unsigned char *mapping, /**< Encoded mapping between channels and streams */ - int application /**< Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */ -); +/** @defgroup opus_multistream Opus Multistream API + * @{ + * + * The multistream API allows individual Opus streams to be combined into a + * single packet, enabling support for up to 255 channels. Unlike an + * elementary Opus stream, the encoder and decoder must negotiate the channel + * configuration before the decoder can successfully interpret the data in the + * packets produced by the encoder. Some basic information, such as packet + * duration, can be computed without any special negotiation. + * + * The format for multistream Opus packets is defined in the + * Ogg + * encapsulation specification and is based on the self-delimited Opus + * framing described in Appendix B of RFC 6716. + * Normal Opus packets are just a degenerate case of multistream Opus packets, + * and can be encoded or decoded with the multistream API by setting + * streams to 1 when initializing the encoder or + * decoder. + * + * Multistream Opus streams can contain up to 255 elementary Opus streams. + * These may be either "uncoupled" or "coupled", indicating that the decoder + * is configured to decode them to either 1 or 2 channels, respectively. + * The streams are ordered so that all coupled streams appear at the + * beginning. + * + * A mapping table defines which decoded channel i + * should be used for each input/output (I/O) channel j. This table is + * typically provided as an unsigned char array. + * Let i = mapping[j] be the index for I/O channel j. + * If i < 2*coupled_streams, then I/O channel j is + * encoded as the left channel of stream (i/2) if i + * is even, or as the right channel of stream (i/2) if + * i is odd. Otherwise, I/O channel j is encoded as + * mono in stream (i - coupled_streams), unless it has the special + * value 255, in which case it is omitted from the encoding entirely (the + * decoder will reproduce it as silence). Each value i must either + * be the special value 255 or be less than streams + coupled_streams. + * + * The output channels specified by the encoder + * should use the + * Vorbis + * channel ordering. A decoder may wish to apply an additional permutation + * to the mapping the encoder used to achieve a different output channel + * order (e.g. for outputing in WAV order). + * + * Each multistream packet contains an Opus packet for each stream, and all of + * the Opus packets in a single multistream packet must have the same + * duration. Therefore the duration of a multistream packet can be extracted + * from the TOC sequence of the first stream, which is located at the + * beginning of the packet, just like an elementary Opus stream: + * + * @code + * int nb_samples; + * int nb_frames; + * nb_frames = opus_packet_get_nb_frames(data, len); + * if (nb_frames < 1) + * return nb_frames; + * nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames; + * @endcode + * + * The general encoding and decoding process proceeds exactly the same as in + * the normal @ref opus_encoder and @ref opus_decoder APIs. + * See their documentation for an overview of how to use the corresponding + * multistream functions. + */ -/** Returns length of the data payload (in bytes) or a negative error code */ -OPUS_EXPORT int opus_multistream_encode( - OpusMSEncoder *st, /**< Encoder state */ - const opus_int16 *pcm, /**< Input signal as interleaved samples. Length is frame_size*channels */ - int frame_size, /**< Number of samples per frame of input signal */ - unsigned char *data, /**< Output buffer for the compressed payload (no more than max_data_bytes long) */ - int max_data_bytes /**< Allocated memory for payload; don't use for controlling bitrate */ -); +/** Opus multistream encoder state. + * This contains the complete state of a multistream Opus encoder. + * It is position independent and can be freely copied. + * @see opus_multistream_encoder_create + * @see opus_multistream_encoder_init + */ +typedef struct OpusMSEncoder OpusMSEncoder; -/** Returns length of the data payload (in bytes) or a negative error code. */ -OPUS_EXPORT int opus_multistream_encode_float( - OpusMSEncoder *st, /**< Encoder state */ - const float *pcm, /**< Input signal interleaved in channel order. length is frame_size*channels */ - int frame_size, /**< Number of samples per frame of input signal */ - unsigned char *data, /**< Output buffer for the compressed payload (no more than max_data_bytes long) */ - int max_data_bytes /**< Allocated memory for payload; don't use for controlling bitrate */ - ); +/** Opus multistream decoder state. + * This contains the complete state of a multistream Opus decoder. + * It is position independent and can be freely copied. + * @see opus_multistream_decoder_create + * @see opus_multistream_decoder_init + */ +typedef struct OpusMSDecoder OpusMSDecoder; + +/**\name Multistream encoder functions */ +/**@{*/ /** Gets the size of an OpusMSEncoder structure. - * @returns size + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than 255. + * @returns The size in bytes on success, or a negative error code + * (see @ref opus_errorcodes) on error. */ -OPUS_EXPORT opus_int32 opus_multistream_encoder_get_size( - int streams, /**< Total number of coded streams */ - int coupled_streams /**< Number of coupled (stereo) streams */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size( + int streams, + int coupled_streams ); -/** Deallocate a multstream encoder state */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_surround_encoder_get_size( + int channels, + int mapping_family +); + + +/** Allocates and initializes a multistream encoder state. + * Call opus_multistream_encoder_destroy() to release + * this object when finished. + * @param Fs opus_int32: Sampling rate of the input signal (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels in the input signal. + * This must be at most 255. + * It may be greater than the number of + * coded channels (streams + + * coupled_streams). + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than the number of channels. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than the number of input channels. + * @param[in] mapping const unsigned char[channels]: Mapping from + * encoded channels to input channels, as described in + * @ref opus_multistream. As an extra constraint, the + * multistream encoder does not allow encoding coupled + * streams for which one channel is unused since this + * is never a good idea. + * @param application int: The target encoder application. + * This must be one of the following: + *
    + *
    #OPUS_APPLICATION_VOIP
    + *
    Process signal for improved speech intelligibility.
    + *
    #OPUS_APPLICATION_AUDIO
    + *
    Favor faithfulness to the original input.
    + *
    #OPUS_APPLICATION_RESTRICTED_LOWDELAY
    + *
    Configure the minimum possible coding delay by disabling certain modes + * of operation.
    + *
    + * @param[out] error int *: Returns #OPUS_OK on success, or an error + * code (see @ref opus_errorcodes) on + * failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application, + int *error +) OPUS_ARG_NONNULL(5); + +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_surround_encoder_create( + opus_int32 Fs, + int channels, + int mapping_family, + int *streams, + int *coupled_streams, + unsigned char *mapping, + int application, + int *error +) OPUS_ARG_NONNULL(5); + +/** Initialize a previously allocated multistream encoder state. + * The memory pointed to by \a st must be at least the size returned by + * opus_multistream_encoder_get_size(). + * This is intended for applications which use their own allocator instead of + * malloc. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @see opus_multistream_encoder_create + * @see opus_multistream_encoder_get_size + * @param st OpusMSEncoder*: Multistream encoder state to initialize. + * @param Fs opus_int32: Sampling rate of the input signal (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels in the input signal. + * This must be at most 255. + * It may be greater than the number of + * coded channels (streams + + * coupled_streams). + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than the number of channels. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than the number of input channels. + * @param[in] mapping const unsigned char[channels]: Mapping from + * encoded channels to input channels, as described in + * @ref opus_multistream. As an extra constraint, the + * multistream encoder does not allow encoding coupled + * streams for which one channel is unused since this + * is never a good idea. + * @param application int: The target encoder application. + * This must be one of the following: + *
    + *
    #OPUS_APPLICATION_VOIP
    + *
    Process signal for improved speech intelligibility.
    + *
    #OPUS_APPLICATION_AUDIO
    + *
    Favor faithfulness to the original input.
    + *
    #OPUS_APPLICATION_RESTRICTED_LOWDELAY
    + *
    Configure the minimum possible coding delay by disabling certain modes + * of operation.
    + *
    + * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) + * on failure. + */ +OPUS_EXPORT int opus_multistream_encoder_init( + OpusMSEncoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); + +OPUS_EXPORT int opus_multistream_surround_encoder_init( + OpusMSEncoder *st, + opus_int32 Fs, + int channels, + int mapping_family, + int *streams, + int *coupled_streams, + unsigned char *mapping, + int application +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); + +/** Encodes a multistream Opus frame. + * @param st OpusMSEncoder*: Multistream encoder state. + * @param[in] pcm const opus_int16*: The input signal as interleaved + * samples. + * This must contain + * frame_size*channels + * samples. + * @param frame_size int: Number of samples per channel in the input + * signal. + * This must be an Opus frame size for the + * encoder's sampling rate. + * For example, at 48 kHz the permitted values + * are 120, 240, 480, 960, 1920, and 2880. + * Passing in a duration of less than 10 ms + * (480 samples at 48 kHz) will prevent the + * encoder from using the LPC or hybrid modes. + * @param[out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode( + OpusMSEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Encodes a multistream Opus frame from floating point input. + * @param st OpusMSEncoder*: Multistream encoder state. + * @param[in] pcm const float*: The input signal as interleaved + * samples with a normal range of + * +/-1.0. + * Samples with a range beyond +/-1.0 + * are supported but will be clipped by + * decoders using the integer API and + * should only be used if it is known + * that the far end supports extended + * dynamic range. + * This must contain + * frame_size*channels + * samples. + * @param frame_size int: Number of samples per channel in the input + * signal. + * This must be an Opus frame size for the + * encoder's sampling rate. + * For example, at 48 kHz the permitted values + * are 120, 240, 480, 960, 1920, and 2880. + * Passing in a duration of less than 10 ms + * (480 samples at 48 kHz) will prevent the + * encoder from using the LPC or hybrid modes. + * @param[out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float( + OpusMSEncoder *st, + const float *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Frees an OpusMSEncoder allocated by + * opus_multistream_encoder_create(). + * @param st OpusMSEncoder*: Multistream encoder state to be freed. + */ OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st); -/** Get or set options on a multistream encoder state */ -OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...); - -/** Allocate and initialize a multistream decoder state object. - * Call opus_multistream_decoder_destroy() to release - * this object when finished. */ -OPUS_EXPORT OpusMSDecoder *opus_multistream_decoder_create( - opus_int32 Fs, /**< Sampling rate to decode at (Hz) */ - int channels, /**< Number of channels to decode */ - int streams, /**< Total number of coded streams in the multistream */ - int coupled_streams, /**< Number of coupled (stereo) streams in the multistream */ - unsigned char *mapping, /**< Stream to channel mapping table */ - int *error /**< Error code */ -); - -/** Intialize a previously allocated decoder state object. */ -OPUS_EXPORT int opus_multistream_decoder_init( - OpusMSDecoder *st, /**< Encoder state */ - opus_int32 Fs, /**< Sample rate of input signal (Hz) */ - int channels, /**< Number of channels in the input signal */ - int streams, /**< Total number of coded streams */ - int coupled_streams, /**< Number of coupled (stereo) streams */ - unsigned char *mapping /**< Stream to channel mapping table */ -); - -/** Returns the number of samples decoded or a negative error code */ -OPUS_EXPORT int opus_multistream_decode( - OpusMSDecoder *st, /**< Decoder state */ - const unsigned char *data, /**< Input payload. Use a NULL pointer to indicate packet loss */ - int len, /**< Number of bytes in payload */ - opus_int16 *pcm, /**< Output signal, samples interleaved in channel order . length is frame_size*channels */ - int frame_size, /**< Number of samples per frame of input signal */ - int decode_fec /**< Flag (0/1) to request that any in-band forward error correction data be */ - /**< decoded. If no such data is available the frame is decoded as if it were lost. */ -); - -/** Returns the number of samples decoded or a negative error code */ -OPUS_EXPORT int opus_multistream_decode_float( - OpusMSDecoder *st, /**< Decoder state */ - const unsigned char *data, /**< Input payload buffer. Use a NULL pointer to indicate packet loss */ - int len, /**< Number of payload bytes in data */ - float *pcm, /**< Buffer for the output signal (interleaved iin channel order). length is frame_size*channels */ - int frame_size, /**< Number of samples per frame of input signal */ - int decode_fec /**< Flag (0/1) to request that any in-band forward error correction data be */ - /**< decoded. If no such data is available the frame is decoded as if it were lost. */ -); - -/** Gets the size of an OpusMSDecoder structure. - * @returns size +/** Perform a CTL function on a multistream Opus encoder. + * + * Generally the request and subsequent arguments are generated by a + * convenience macro. + * @param st OpusMSEncoder*: Multistream encoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls, + * @ref opus_encoderctls, or @ref opus_multistream_ctls. + * @see opus_genericctls + * @see opus_encoderctls + * @see opus_multistream_ctls */ -OPUS_EXPORT opus_int32 opus_multistream_decoder_get_size( - int streams, /**< Total number of coded streams */ - int coupled_streams /**< Number of coupled (stereo) streams */ +OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); + +/**@}*/ + +/**\name Multistream decoder functions */ +/**@{*/ + +/** Gets the size of an OpusMSDecoder structure. + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @returns The size in bytes on success, or a negative error code + * (see @ref opus_errorcodes) on error. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size( + int streams, + int coupled_streams ); -/** Get or set options on a multistream decoder state */ -OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...); +/** Allocates and initializes a multistream decoder state. + * Call opus_multistream_decoder_destroy() to release + * this object when finished. + * @param Fs opus_int32: Sampling rate to decode at (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels to output. + * This must be at most 255. + * It may be different from the number of coded + * channels (streams + + * coupled_streams). + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @param[in] mapping const unsigned char[channels]: Mapping from + * coded channels to output channels, as described in + * @ref opus_multistream. + * @param[out] error int *: Returns #OPUS_OK on success, or an error + * code (see @ref opus_errorcodes) on + * failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int *error +) OPUS_ARG_NONNULL(5); -/** Deallocate a multistream decoder state object */ +/** Intialize a previously allocated decoder state object. + * The memory pointed to by \a st must be at least the size returned by + * opus_multistream_encoder_get_size(). + * This is intended for applications which use their own allocator instead of + * malloc. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @see opus_multistream_decoder_create + * @see opus_multistream_deocder_get_size + * @param st OpusMSEncoder*: Multistream encoder state to initialize. + * @param Fs opus_int32: Sampling rate to decode at (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels to output. + * This must be at most 255. + * It may be different from the number of coded + * channels (streams + + * coupled_streams). + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @param[in] mapping const unsigned char[channels]: Mapping from + * coded channels to output channels, as described in + * @ref opus_multistream. + * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) + * on failure. + */ +OPUS_EXPORT int opus_multistream_decoder_init( + OpusMSDecoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); + +/** Decode a multistream Opus packet. + * @param st OpusMSDecoder*: Multistream decoder state. + * @param[in] data const unsigned char*: Input payload. + * Use a NULL + * pointer to indicate packet + * loss. + * @param len opus_int32: Number of bytes in payload. + * @param[out] pcm opus_int16*: Output signal, with interleaved + * samples. + * This must contain room for + * frame_size*channels + * samples. + * @param frame_size int: The number of samples per channel of + * available space in \a pcm. + * If this is less than the maximum packet duration + * (120 ms; 5760 for 48kHz), this function will not be capable + * of decoding some packets. In the case of PLC (data==NULL) + * or FEC (decode_fec=1), then frame_size needs to be exactly + * the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the + * next incoming packet. For the PLC and FEC cases, frame_size + * must be a multiple of 2.5 ms. + * @param decode_fec int: Flag (0 or 1) to request that any in-band + * forward error correction data be decoded. + * If no such data is available, the frame is + * decoded as if it were lost. + * @returns Number of samples decoded on success or a negative error code + * (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode( + OpusMSDecoder *st, + const unsigned char *data, + opus_int32 len, + opus_int16 *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Decode a multistream Opus packet with floating point output. + * @param st OpusMSDecoder*: Multistream decoder state. + * @param[in] data const unsigned char*: Input payload. + * Use a NULL + * pointer to indicate packet + * loss. + * @param len opus_int32: Number of bytes in payload. + * @param[out] pcm opus_int16*: Output signal, with interleaved + * samples. + * This must contain room for + * frame_size*channels + * samples. + * @param frame_size int: The number of samples per channel of + * available space in \a pcm. + * If this is less than the maximum packet duration + * (120 ms; 5760 for 48kHz), this function will not be capable + * of decoding some packets. In the case of PLC (data==NULL) + * or FEC (decode_fec=1), then frame_size needs to be exactly + * the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the + * next incoming packet. For the PLC and FEC cases, frame_size + * must be a multiple of 2.5 ms. + * @param decode_fec int: Flag (0 or 1) to request that any in-band + * forward error correction data be decoded. + * If no such data is available, the frame is + * decoded as if it were lost. + * @returns Number of samples decoded on success or a negative error code + * (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float( + OpusMSDecoder *st, + const unsigned char *data, + opus_int32 len, + float *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on a multistream Opus decoder. + * + * Generally the request and subsequent arguments are generated by a + * convenience macro. + * @param st OpusMSDecoder*: Multistream decoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls, + * @ref opus_decoderctls, or @ref opus_multistream_ctls. + * @see opus_genericctls + * @see opus_decoderctls + * @see opus_multistream_ctls + */ +OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); + +/** Frees an OpusMSDecoder allocated by + * opus_multistream_decoder_create(). + * @param st OpusMSDecoder: Multistream decoder state to be freed. + */ OPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st); +/**@}*/ + +/**@}*/ + #ifdef __cplusplus } #endif diff --git a/media/libopus/include/opus_types.h b/media/libopus/include/opus_types.h index df9234122f7f..b28e03aea202 100644 --- a/media/libopus/include/opus_types.h +++ b/media/libopus/include/opus_types.h @@ -1,10 +1,6 @@ -/* (C) COPYRIGHT 1994-2012 IETF Trust, Xiph.Org Foundation. All rights reserved */ +/* (C) COPYRIGHT 1994-2002 Xiph.Org Foundation */ /* Modified by Jean-Marc Valin */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR diff --git a/media/libopus/mingw.patch b/media/libopus/mingw.patch deleted file mode 100644 index 59e0394975e8..000000000000 --- a/media/libopus/mingw.patch +++ /dev/null @@ -1,28 +0,0 @@ -commit 986fb3ec557aa7aeb8788360224708ffa2955072 -Author: Jacek Caban -Date: Wed Jun 12 17:30:47 2013 +0200 - - Use __declspec(dllexport) on mingw build. - -diff --git a/media/libopus/include/opus_defines.h b/media/libopus/include/opus_defines.h -index db6b3b7..b64049b 100644 ---- a/media/libopus/include/opus_defines.h -+++ b/media/libopus/include/opus_defines.h -@@ -72,14 +72,14 @@ extern "C" { - /** @cond OPUS_INTERNAL_DOC */ - /**Export control for opus functions */ - --#if defined(__GNUC__) && defined(OPUS_BUILD) --# define OPUS_EXPORT __attribute__ ((visibility ("default"))) --#elif defined(WIN32) -+#if defined(WIN32) - # ifdef OPUS_BUILD - # define OPUS_EXPORT __declspec(dllexport) - # else - # define OPUS_EXPORT __declspec(dllimport) - # endif -+#elif defined(__GNUC__) && defined(OPUS_BUILD) -+# define OPUS_EXPORT __attribute__ ((visibility ("default"))) - #else - # define OPUS_EXPORT - #endif diff --git a/media/libopus/opus_sources.mk b/media/libopus/opus_sources.mk index bf82f93af779..e4eeb919cffc 100644 --- a/media/libopus/opus_sources.mk +++ b/media/libopus/opus_sources.mk @@ -1,38 +1,12 @@ -# Copyright (c) 2011-2012 IETF Trust, Jean-Marc Valin. All rights reserved. -# -# This file is extracted from RFC6716. Please see that RFC for additional -# information. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Internet Society, IETF or IETF Trust, nor the -# names of specific contributors, may be used to endorse or promote -# products derived from this software without specific prior written -# permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - OPUS_SOURCES = src/opus.c \ src/opus_decoder.c \ src/opus_encoder.c \ src/opus_multistream.c \ +src/opus_multistream_encoder.c \ +src/opus_multistream_decoder.c \ src/repacketizer.c + +OPUS_SOURCES_FLOAT = \ +src/analysis.c \ +src/mlp.c \ +src/mlp_data.c diff --git a/media/libopus/padding.patch b/media/libopus/padding.patch deleted file mode 100644 index cf32214ff444..000000000000 --- a/media/libopus/padding.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 9345aaa5ca1c2fb7d62981b2a538e0ce20612c38 Mon Sep 17 00:00:00 2001 -From: Jean-Marc Valin -Date: Fri, 30 Nov 2012 17:36:36 -0500 -Subject: [PATCH] Fixes an out-of-bounds read issue with the padding handling - code - -This was reported by Juri Aedla and is limited to reading memory up -to about 60 kB beyond the compressed buffer. This can only be triggered -by a compressed packet more than about 16 MB long, so it's not a problem -for RTP. In theory, it *could* crash an Ogg decoder if the memory just after -the incoming packet is out-of-range. ---- - src/opus_decoder.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/src/opus_decoder.c b/src/opus_decoder.c -index 167e4e4..0be6730 100644 ---- a/src/opus_decoder.c -+++ b/src/opus_decoder.c -@@ -641,16 +641,14 @@ static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, - /* Padding flag is bit 6 */ - if (ch&0x40) - { -- int padding=0; - int p; - do { - if (len<=0) - return OPUS_INVALID_PACKET; - p = *data++; - len--; -- padding += p==255 ? 254: p; -+ len -= p==255 ? 254: p; - } while (p==255); -- len -= padding; - } - if (len<0) - return OPUS_INVALID_PACKET; --- -1.7.11.7 - diff --git a/media/libopus/silk/A2NLSF.c b/media/libopus/silk/A2NLSF.c index 2f582e76dab2..e84cc46a98ed 100644 --- a/media/libopus/silk/A2NLSF.c +++ b/media/libopus/silk/A2NLSF.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/API.h b/media/libopus/silk/API.h index 6904067ab328..4fe76294cb9e 100644 --- a/media/libopus/silk/API.h +++ b/media/libopus/silk/API.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -71,14 +67,6 @@ opus_int silk_InitEncoder( /* O Returns error co silk_EncControlStruct *encStatus /* O Encoder Status */ ); -/***************************************/ -/* Read control structure from encoder */ -/***************************************/ -opus_int silk_QueryEncoder( /* O Returns error code */ - const void *encState, /* I State */ - silk_EncControlStruct *encStatus /* O Encoder Status */ -); - /**************************/ /* Encode frame with Silk */ /**************************/ @@ -90,7 +78,7 @@ opus_int silk_Encode( /* O Returns error co const opus_int16 *samplesIn, /* I Speech sample input vector */ opus_int nSamplesIn, /* I Number of samples in input vector */ ec_enc *psRangeEnc, /* I/O Compressor data structure */ - opus_int *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ + opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ const opus_int prefillFlag /* I Flag to indicate prefilling buffers no coding */ ); @@ -125,6 +113,7 @@ opus_int silk_Decode( /* O Returns error co opus_int32 *nSamplesOut /* O Number of samples decoded */ ); +#if 0 /**************************************/ /* Get table of contents for a packet */ /**************************************/ @@ -134,6 +123,7 @@ opus_int silk_get_TOC( const opus_int nFramesPerPayload, /* I Number of SILK frames per payload */ silk_TOC_struct *Silk_TOC /* O Type of content */ ); +#endif #ifdef __cplusplus } diff --git a/media/libopus/silk/CNG.c b/media/libopus/silk/CNG.c index 6ea55c43e778..d175dd5f172a 100644 --- a/media/libopus/silk/CNG.c +++ b/media/libopus/silk/CNG.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main.h" +#include "stack_alloc.h" /* Generates excitation for CNG LPC synthesis */ static inline void silk_CNG_exc( @@ -90,8 +87,8 @@ void silk_CNG( opus_int i, subfr; opus_int32 sum_Q6, max_Gain_Q16; opus_int16 A_Q12[ MAX_LPC_ORDER ]; - opus_int32 CNG_sig_Q10[ MAX_FRAME_LENGTH + MAX_LPC_ORDER ]; silk_CNG_struct *psCNG = &psDec->sCNG; + SAVE_STACK; if( psDec->fs_kHz != psCNG->fs_kHz ) { /* Reset state */ @@ -104,7 +101,7 @@ void silk_CNG( /* Smoothing of LSF's */ for( i = 0; i < psDec->LPC_order; i++ ) { - psCNG->CNG_smth_NLSF_Q15[ i ] += silk_SMULWB( psDec->prevNLSF_Q15[ i ] - psCNG->CNG_smth_NLSF_Q15[ i ], CNG_NLSF_SMTH_Q16 ); + psCNG->CNG_smth_NLSF_Q15[ i ] += silk_SMULWB( (opus_int32)psDec->prevNLSF_Q15[ i ] - (opus_int32)psCNG->CNG_smth_NLSF_Q15[ i ], CNG_NLSF_SMTH_Q16 ); } /* Find the subframe with the highest gain */ max_Gain_Q16 = 0; @@ -127,6 +124,9 @@ void silk_CNG( /* Add CNG when packet is lost or during DTX */ if( psDec->lossCnt ) { + VARDECL( opus_int32, CNG_sig_Q10 ); + + ALLOC( CNG_sig_Q10, length + MAX_LPC_ORDER, opus_int32 ); /* Generate CNG excitation */ silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, psCNG->CNG_smth_Gain_Q16, length, &psCNG->rand_seed ); @@ -168,4 +168,5 @@ void silk_CNG( } else { silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( opus_int32 ) ); } + RESTORE_STACK; } diff --git a/media/libopus/silk/HP_variable_cutoff.c b/media/libopus/silk/HP_variable_cutoff.c index 1ce5ccceb784..bbe10f04cefa 100644 --- a/media/libopus/silk/HP_variable_cutoff.c +++ b/media/libopus/silk/HP_variable_cutoff.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/Inlines.h b/media/libopus/silk/Inlines.h index 78844bdb13a5..244f66ff392e 100644 --- a/media/libopus/silk/Inlines.h +++ b/media/libopus/silk/Inlines.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -166,7 +162,7 @@ static inline opus_int32 silk_INVERSE32_varQ( /* O returns a good approxima result = silk_LSHIFT(b32_inv, 16); /* Q: 61 - b_headrm */ /* Compute residual by subtracting product of denominator and first approximation from one */ - err_Q32 = silk_LSHIFT( (1<<29) - silk_SMULWB(b32_nrm, b32_inv), 3 ); /* Q32 */ + err_Q32 = silk_LSHIFT( ((opus_int32)1<<29) - silk_SMULWB(b32_nrm, b32_inv), 3 ); /* Q32 */ /* Refinement */ result = silk_SMLAWW(result, err_Q32, b32_inv); /* Q: 61 - b_headrm */ diff --git a/media/libopus/silk/LPC_analysis_filter.c b/media/libopus/silk/LPC_analysis_filter.c index 0bbdda19eb8a..9d1f16cb7d25 100644 --- a/media/libopus/silk/LPC_analysis_filter.c +++ b/media/libopus/silk/LPC_analysis_filter.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "SigProc_FIX.h" +#include "celt_lpc.h" /*******************************************/ /* LPC analysis filter */ @@ -50,14 +47,33 @@ void silk_LPC_analysis_filter( const opus_int32 d /* I Filter order */ ) { - opus_int ix, j; + opus_int j; +#ifdef FIXED_POINT + opus_int16 mem[SILK_MAX_ORDER_LPC]; + opus_int16 num[SILK_MAX_ORDER_LPC]; +#else + int ix; opus_int32 out32_Q12, out32; const opus_int16 *in_ptr; +#endif silk_assert( d >= 6 ); silk_assert( (d & 1) == 0 ); silk_assert( d <= len ); +#ifdef FIXED_POINT + silk_assert( d <= SILK_MAX_ORDER_LPC ); + for ( j = 0; j < d; j++ ) { + num[ j ] = -B[ j ]; + } + for (j=0;j 0; k-- ) { /* Check for stability */ if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) { diff --git a/media/libopus/silk/LP_variable_cutoff.c b/media/libopus/silk/LP_variable_cutoff.c index 1e8a175ca14a..c1ac23e9945d 100644 --- a/media/libopus/silk/LP_variable_cutoff.c +++ b/media/libopus/silk/LP_variable_cutoff.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -77,14 +73,14 @@ static inline void silk_LP_interpolate_filter_taps( silk_Transition_LP_B_Q28[ ind + 1 ][ nb ], silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] - silk_Transition_LP_B_Q28[ ind ][ nb ], - fac_Q16 - ( 1 << 16 ) ); + fac_Q16 - ( (opus_int32)1 << 16 ) ); } for( na = 0; na < TRANSITION_NA; na++ ) { A_Q28[ na ] = silk_SMLAWB( silk_Transition_LP_A_Q28[ ind + 1 ][ na ], silk_Transition_LP_A_Q28[ ind + 1 ][ na ] - silk_Transition_LP_A_Q28[ ind ][ na ], - fac_Q16 - ( 1 << 16 ) ); + fac_Q16 - ( (opus_int32)1 << 16 ) ); } } } else { diff --git a/media/libopus/silk/MacroCount.h b/media/libopus/silk/MacroCount.h index 7f6729277840..dbb9775e6d09 100644 --- a/media/libopus/silk/MacroCount.h +++ b/media/libopus/silk/MacroCount.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -481,7 +477,7 @@ static inline opus_int64 silk_abs_int64(opus_int64 a){ #undef silk_abs_int32 static inline opus_int32 silk_abs_int32(opus_int32 a){ ops_count += 1; - return abs(a); + return silk_abs(a); } @@ -714,7 +710,6 @@ static inline opus_int silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 } #else -#define exVarDefine #define varDefine #define silk_SaveCount() diff --git a/media/libopus/silk/MacroDebug.h b/media/libopus/silk/MacroDebug.h index afb01f2a9e6d..9c29576b93de 100644 --- a/media/libopus/silk/MacroDebug.h +++ b/media/libopus/silk/MacroDebug.h @@ -1,9 +1,6 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Copyright (C) 2012 Xiph.Org Foundation Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +13,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -35,266 +32,462 @@ POSSIBILITY OF SUCH DAMAGE. /* Redefine macro functions with extensive assertion in DEBUG mode. As functions can't be undefined, this file can't work with SigProcFIX_MacroCount.h */ -#if 0 && defined (_DEBUG) && !defined (silk_MACRO_COUNT) +#if ( defined (FIXED_DEBUG) || ( 0 && defined (_DEBUG) ) ) && !defined (silk_MACRO_COUNT) #undef silk_ADD16 -static inline opus_int16 silk_ADD16(opus_int16 a, opus_int16 b){ +#define silk_ADD16(a,b) silk_ADD16_((a), (b), __FILE__, __LINE__) +static inline opus_int16 silk_ADD16_(opus_int16 a, opus_int16 b, char *file, int line){ opus_int16 ret; ret = a + b; - silk_assert( ret == silk_ADD_SAT16( a, b )); + if ( ret != silk_ADD_SAT16( a, b ) ) + { + fprintf (stderr, "silk_ADD16(%d, %d) in %s: line %d\n", a, b, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_ADD32 -static inline opus_int32 silk_ADD32(opus_int32 a, opus_int32 b){ +#define silk_ADD32(a,b) silk_ADD32_((a), (b), __FILE__, __LINE__) +static inline opus_int32 silk_ADD32_(opus_int32 a, opus_int32 b, char *file, int line){ opus_int32 ret; ret = a + b; - silk_assert( ret == silk_ADD_SAT32( a, b )); + if ( ret != silk_ADD_SAT32( a, b ) ) + { + fprintf (stderr, "silk_ADD32(%d, %d) in %s: line %d\n", a, b, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_ADD64 -static inline opus_int64 silk_ADD64(opus_int64 a, opus_int64 b){ +#define silk_ADD64(a,b) silk_ADD64_((a), (b), __FILE__, __LINE__) +static inline opus_int64 silk_ADD64_(opus_int64 a, opus_int64 b, char *file, int line){ opus_int64 ret; ret = a + b; - silk_assert( ret == silk_ADD_SAT64( a, b )); + if ( ret != silk_ADD_SAT64( a, b ) ) + { + fprintf (stderr, "silk_ADD64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_SUB16 -static inline opus_int16 silk_SUB16(opus_int16 a, opus_int16 b){ +#define silk_SUB16(a,b) silk_SUB16_((a), (b), __FILE__, __LINE__) +static inline opus_int16 silk_SUB16_(opus_int16 a, opus_int16 b, char *file, int line){ opus_int16 ret; ret = a - b; - silk_assert( ret == silk_SUB_SAT16( a, b )); + if ( ret != silk_SUB_SAT16( a, b ) ) + { + fprintf (stderr, "silk_SUB16(%d, %d) in %s: line %d\n", a, b, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_SUB32 -static inline opus_int32 silk_SUB32(opus_int32 a, opus_int32 b){ +#define silk_SUB32(a,b) silk_SUB32_((a), (b), __FILE__, __LINE__) +static inline opus_int32 silk_SUB32_(opus_int32 a, opus_int32 b, char *file, int line){ opus_int32 ret; ret = a - b; - silk_assert( ret == silk_SUB_SAT32( a, b )); + if ( ret != silk_SUB_SAT32( a, b ) ) + { + fprintf (stderr, "silk_SUB32(%d, %d) in %s: line %d\n", a, b, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_SUB64 -static inline opus_int64 silk_SUB64(opus_int64 a, opus_int64 b){ +#define silk_SUB64(a,b) silk_SUB64_((a), (b), __FILE__, __LINE__) +static inline opus_int64 silk_SUB64_(opus_int64 a, opus_int64 b, char *file, int line){ opus_int64 ret; ret = a - b; - silk_assert( ret == silk_SUB_SAT64( a, b )); + if ( ret != silk_SUB_SAT64( a, b ) ) + { + fprintf (stderr, "silk_SUB64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_ADD_SAT16 -static inline opus_int16 silk_ADD_SAT16( opus_int16 a16, opus_int16 b16 ) { +#define silk_ADD_SAT16(a,b) silk_ADD_SAT16_((a), (b), __FILE__, __LINE__) +static inline opus_int16 silk_ADD_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line) { opus_int16 res; res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) ); - silk_assert( res == silk_SAT16( (opus_int32)a16 + (opus_int32)b16 ) ); + if ( res != silk_SAT16( (opus_int32)a16 + (opus_int32)b16 ) ) + { + fprintf (stderr, "silk_ADD_SAT16(%d, %d) in %s: line %d\n", a16, b16, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return res; } #undef silk_ADD_SAT32 -static inline opus_int32 silk_ADD_SAT32(opus_int32 a32, opus_int32 b32){ +#define silk_ADD_SAT32(a,b) silk_ADD_SAT32_((a), (b), __FILE__, __LINE__) +static inline opus_int32 silk_ADD_SAT32_(opus_int32 a32, opus_int32 b32, char *file, int line){ opus_int32 res; - res = ((((a32) + (b32)) & 0x80000000) == 0 ? \ - ((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \ + res = ((((opus_uint32)(a32) + (opus_uint32)(b32)) & 0x80000000) == 0 ? \ + ((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \ ((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) ); - silk_assert( res == silk_SAT32( (opus_int64)a32 + (opus_int64)b32 ) ); + if ( res != silk_SAT32( (opus_int64)a32 + (opus_int64)b32 ) ) + { + fprintf (stderr, "silk_ADD_SAT32(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return res; } #undef silk_ADD_SAT64 -static inline opus_int64 silk_ADD_SAT64( opus_int64 a64, opus_int64 b64 ) { +#define silk_ADD_SAT64(a,b) silk_ADD_SAT64_((a), (b), __FILE__, __LINE__) +static inline opus_int64 silk_ADD_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line) { opus_int64 res; - res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \ - ((((a64) & (b64)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a64)+(b64)) : \ + int fail = 0; + res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \ + ((((a64) & (b64)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a64)+(b64)) : \ ((((a64) | (b64)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a64)+(b64)) ); if( res != a64 + b64 ) { /* Check that we saturated to the correct extreme value */ - silk_assert( ( res == silk_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( silk_int64_MAX >> 3 ) ) ) || - ( res == silk_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( silk_int64_MIN >> 3 ) ) ) ); + if ( !(( res == silk_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( silk_int64_MAX >> 3 ) ) ) || + ( res == silk_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( silk_int64_MIN >> 3 ) ) ) ) ) + { + fail = 1; + } } else { /* Saturation not necessary */ - silk_assert( res == a64 + b64 ); + fail = res != a64 + b64; + } + if ( fail ) + { + fprintf (stderr, "silk_ADD_SAT64(%lld, %lld) in %s: line %d\n", (long long)a64, (long long)b64, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif } return res; } #undef silk_SUB_SAT16 -static inline opus_int16 silk_SUB_SAT16( opus_int16 a16, opus_int16 b16 ) { +#define silk_SUB_SAT16(a,b) silk_SUB_SAT16_((a), (b), __FILE__, __LINE__) +static inline opus_int16 silk_SUB_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line ) { opus_int16 res; res = (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a16), (b16) ) ); - silk_assert( res == silk_SAT16( (opus_int32)a16 - (opus_int32)b16 ) ); + if ( res != silk_SAT16( (opus_int32)a16 - (opus_int32)b16 ) ) + { + fprintf (stderr, "silk_SUB_SAT16(%d, %d) in %s: line %d\n", a16, b16, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return res; } #undef silk_SUB_SAT32 -static inline opus_int32 silk_SUB_SAT32( opus_int32 a32, opus_int32 b32 ) { +#define silk_SUB_SAT32(a,b) silk_SUB_SAT32_((a), (b), __FILE__, __LINE__) +static inline opus_int32 silk_SUB_SAT32_( opus_int32 a32, opus_int32 b32, char *file, int line ) { opus_int32 res; - res = ((((a32)-(b32)) & 0x80000000) == 0 ? \ - (( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \ + res = ((((opus_uint32)(a32)-(opus_uint32)(b32)) & 0x80000000) == 0 ? \ + (( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \ ((((a32)^0x80000000) & (b32) & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) ); - silk_assert( res == silk_SAT32( (opus_int64)a32 - (opus_int64)b32 ) ); + if ( res != silk_SAT32( (opus_int64)a32 - (opus_int64)b32 ) ) + { + fprintf (stderr, "silk_SUB_SAT32(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return res; } #undef silk_SUB_SAT64 -static inline opus_int64 silk_SUB_SAT64( opus_int64 a64, opus_int64 b64 ) { +#define silk_SUB_SAT64(a,b) silk_SUB_SAT64_((a), (b), __FILE__, __LINE__) +static inline opus_int64 silk_SUB_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line ) { opus_int64 res; - res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \ - (( (a64) & ((b64)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a64)-(b64)) : \ + int fail = 0; + res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \ + (( (a64) & ((b64)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a64)-(b64)) : \ ((((a64)^0x8000000000000000LL) & (b64) & 0x8000000000000000LL) ? silk_int64_MAX : (a64)-(b64)) ); - if( res != a64 - b64 ) { /* Check that we saturated to the correct extreme value */ - silk_assert( ( res == silk_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( silk_int64_MAX >> 3 ) ) ) || - ( res == silk_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( silk_int64_MIN >> 3 ) ) ) ); + if( !(( res == silk_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( silk_int64_MAX >> 3 ) ) ) || + ( res == silk_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( silk_int64_MIN >> 3 ) ) ) )) + { + fail = 1; + } } else { /* Saturation not necessary */ - silk_assert( res == a64 - b64 ); + fail = res != a64 - b64; + } + if ( fail ) + { + fprintf (stderr, "silk_SUB_SAT64(%lld, %lld) in %s: line %d\n", (long long)a64, (long long)b64, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif } return res; } #undef silk_MUL -static inline opus_int32 silk_MUL(opus_int32 a32, opus_int32 b32){ +#define silk_MUL(a,b) silk_MUL_((a), (b), __FILE__, __LINE__) +static inline opus_int32 silk_MUL_(opus_int32 a32, opus_int32 b32, char *file, int line){ opus_int32 ret; opus_int64 ret64; ret = a32 * b32; ret64 = (opus_int64)a32 * (opus_int64)b32; - silk_assert((opus_int64)ret == ret64 ); /* Check output overflow */ + if ( (opus_int64)ret != ret64 ) + { + fprintf (stderr, "silk_MUL(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_MUL_uint -static inline opus_uint32 silk_MUL_uint(opus_uint32 a32, opus_uint32 b32){ +#define silk_MUL_uint(a,b) silk_MUL_uint_((a), (b), __FILE__, __LINE__) +static inline opus_uint32 silk_MUL_uint_(opus_uint32 a32, opus_uint32 b32, char *file, int line){ opus_uint32 ret; ret = a32 * b32; - silk_assert((opus_uint64)ret == (opus_uint64)a32 * (opus_uint64)b32); /* Check output overflow */ + if ( (opus_uint64)ret != (opus_uint64)a32 * (opus_uint64)b32 ) + { + fprintf (stderr, "silk_MUL_uint(%u, %u) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_MLA -static inline opus_int32 silk_MLA(opus_int32 a32, opus_int32 b32, opus_int32 c32){ +#define silk_MLA(a,b,c) silk_MLA_((a), (b), (c), __FILE__, __LINE__) +static inline opus_int32 silk_MLA_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret; ret = a32 + b32 * c32; - silk_assert((opus_int64)ret == (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32); /* Check output overflow */ + if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 ) + { + fprintf (stderr, "silk_MLA(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_MLA_uint -static inline opus_int32 silk_MLA_uint(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32){ +#define silk_MLA_uint(a,b,c) silk_MLA_uint_((a), (b), (c), __FILE__, __LINE__) +static inline opus_int32 silk_MLA_uint_(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32, char *file, int line){ opus_uint32 ret; ret = a32 + b32 * c32; - silk_assert((opus_int64)ret == (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32); /* Check output overflow */ + if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 ) + { + fprintf (stderr, "silk_MLA_uint(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_SMULWB -static inline opus_int32 silk_SMULWB(opus_int32 a32, opus_int32 b32){ +#define silk_SMULWB(a,b) silk_SMULWB_((a), (b), __FILE__, __LINE__) +static inline opus_int32 silk_SMULWB_(opus_int32 a32, opus_int32 b32, char *file, int line){ opus_int32 ret; ret = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16); - silk_assert((opus_int64)ret == ((opus_int64)a32 * (opus_int16)b32) >> 16); + if ( (opus_int64)ret != ((opus_int64)a32 * (opus_int16)b32) >> 16 ) + { + fprintf (stderr, "silk_SMULWB(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_SMLAWB -static inline opus_int32 silk_SMLAWB(opus_int32 a32, opus_int32 b32, opus_int32 c32){ +#define silk_SMLAWB(a,b,c) silk_SMLAWB_((a), (b), (c), __FILE__, __LINE__) +static inline opus_int32 silk_SMLAWB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret; ret = silk_ADD32( a32, silk_SMULWB( b32, c32 ) ); - silk_assert(silk_ADD32( a32, silk_SMULWB( b32, c32 ) ) == silk_ADD_SAT32( a32, silk_SMULWB( b32, c32 ) )); + if ( silk_ADD32( a32, silk_SMULWB( b32, c32 ) ) != silk_ADD_SAT32( a32, silk_SMULWB( b32, c32 ) ) ) + { + fprintf (stderr, "silk_SMLAWB(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_SMULWT -static inline opus_int32 silk_SMULWT(opus_int32 a32, opus_int32 b32){ +#define silk_SMULWT(a,b) silk_SMULWT_((a), (b), __FILE__, __LINE__) +static inline opus_int32 silk_SMULWT_(opus_int32 a32, opus_int32 b32, char *file, int line){ opus_int32 ret; ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16); - silk_assert((opus_int64)ret == ((opus_int64)a32 * (b32 >> 16)) >> 16); + if ( (opus_int64)ret != ((opus_int64)a32 * (b32 >> 16)) >> 16 ) + { + fprintf (stderr, "silk_SMULWT(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_SMLAWT -static inline opus_int32 silk_SMLAWT(opus_int32 a32, opus_int32 b32, opus_int32 c32){ +#define silk_SMLAWT(a,b,c) silk_SMLAWT_((a), (b), (c), __FILE__, __LINE__) +static inline opus_int32 silk_SMLAWT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret; ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16)); - silk_assert((opus_int64)ret == (opus_int64)a32 + (((opus_int64)b32 * (c32 >> 16)) >> 16)); + if ( (opus_int64)ret != (opus_int64)a32 + (((opus_int64)b32 * (c32 >> 16)) >> 16) ) + { + fprintf (stderr, "silk_SMLAWT(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_SMULL -static inline opus_int64 silk_SMULL(opus_int64 a64, opus_int64 b64){ +#define silk_SMULL(a,b) silk_SMULL_((a), (b), __FILE__, __LINE__) +static inline opus_int64 silk_SMULL_(opus_int64 a64, opus_int64 b64, char *file, int line){ opus_int64 ret64; + int fail = 0; ret64 = a64 * b64; if( b64 != 0 ) { - silk_assert( a64 == (ret64 / b64) ); + fail = a64 != (ret64 / b64); } else if( a64 != 0 ) { - silk_assert( b64 == (ret64 / a64) ); + fail = b64 != (ret64 / a64); + } + if ( fail ) + { + fprintf (stderr, "silk_SMULL(%lld, %lld) in %s: line %d\n", (long long)a64, (long long)b64, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif } return ret64; } /* no checking needed for silk_SMULBB */ #undef silk_SMLABB -static inline opus_int32 silk_SMLABB(opus_int32 a32, opus_int32 b32, opus_int32 c32){ +#define silk_SMLABB(a,b,c) silk_SMLABB_((a), (b), (c), __FILE__, __LINE__) +static inline opus_int32 silk_SMLABB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret; ret = a32 + (opus_int32)((opus_int16)b32) * (opus_int32)((opus_int16)c32); - silk_assert((opus_int64)ret == (opus_int64)a32 + (opus_int64)b32 * (opus_int16)c32); + if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int16)c32 ) + { + fprintf (stderr, "silk_SMLABB(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } /* no checking needed for silk_SMULBT */ #undef silk_SMLABT -static inline opus_int32 silk_SMLABT(opus_int32 a32, opus_int32 b32, opus_int32 c32){ +#define silk_SMLABT(a,b,c) silk_SMLABT_((a), (b), (c), __FILE__, __LINE__) +static inline opus_int32 silk_SMLABT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret; ret = a32 + ((opus_int32)((opus_int16)b32)) * (c32 >> 16); - silk_assert((opus_int64)ret == (opus_int64)a32 + (opus_int64)b32 * (c32 >> 16)); + if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (c32 >> 16) ) + { + fprintf (stderr, "silk_SMLABT(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } /* no checking needed for silk_SMULTT */ #undef silk_SMLATT -static inline opus_int32 silk_SMLATT(opus_int32 a32, opus_int32 b32, opus_int32 c32){ +#define silk_SMLATT(a,b,c) silk_SMLATT_((a), (b), (c), __FILE__, __LINE__) +static inline opus_int32 silk_SMLATT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret; ret = a32 + (b32 >> 16) * (c32 >> 16); - silk_assert((opus_int64)ret == (opus_int64)a32 + (b32 >> 16) * (c32 >> 16)); + if ( (opus_int64)ret != (opus_int64)a32 + (b32 >> 16) * (c32 >> 16) ) + { + fprintf (stderr, "silk_SMLATT(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_SMULWW -static inline opus_int32 silk_SMULWW(opus_int32 a32, opus_int32 b32){ +#define silk_SMULWW(a,b) silk_SMULWW_((a), (b), __FILE__, __LINE__) +static inline opus_int32 silk_SMULWW_(opus_int32 a32, opus_int32 b32, char *file, int line){ opus_int32 ret, tmp1, tmp2; opus_int64 ret64; + int fail = 0; ret = silk_SMULWB( a32, b32 ); tmp1 = silk_RSHIFT_ROUND( b32, 16 ); tmp2 = silk_MUL( a32, tmp1 ); - silk_assert( (opus_int64)tmp2 == (opus_int64) a32 * (opus_int64) tmp1 ); + fail |= (opus_int64)tmp2 != (opus_int64) a32 * (opus_int64) tmp1; tmp1 = ret; ret = silk_ADD32( tmp1, tmp2 ); - silk_assert( silk_ADD32( tmp1, tmp2 ) == silk_ADD_SAT32( tmp1, tmp2 ) ); + fail |= silk_ADD32( tmp1, tmp2 ) != silk_ADD_SAT32( tmp1, tmp2 ); ret64 = silk_RSHIFT64( silk_SMULL( a32, b32 ), 16 ); - silk_assert( (opus_int64)ret == ret64 ); + fail |= (opus_int64)ret != ret64; + + if ( fail ) + { + fprintf (stderr, "silk_SMULWT(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_SMLAWW -static inline opus_int32 silk_SMLAWW(opus_int32 a32, opus_int32 b32, opus_int32 c32){ +#define silk_SMLAWW(a,b,c) silk_SMLAWW_((a), (b), (c), __FILE__, __LINE__) +static inline opus_int32 silk_SMLAWW_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret, tmp; tmp = silk_SMULWW( b32, c32 ); ret = silk_ADD32( a32, tmp ); - silk_assert( ret == silk_ADD_SAT32( a32, tmp ) ); + if ( ret != silk_ADD_SAT32( a32, tmp ) ) + { + fprintf (stderr, "silk_SMLAWW(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } @@ -311,16 +504,32 @@ static inline opus_int32 silk_SMLAWW(opus_int32 a32, opus_int32 b32, opus_int32 no checking needed for SigProcFIX_CLZ32*/ #undef silk_DIV32 -static inline opus_int32 silk_DIV32(opus_int32 a32, opus_int32 b32){ - silk_assert( b32 != 0 ); +#define silk_DIV32(a,b) silk_DIV32_((a), (b), __FILE__, __LINE__) +static inline opus_int32 silk_DIV32_(opus_int32 a32, opus_int32 b32, char *file, int line){ + if ( b32 == 0 ) + { + fprintf (stderr, "silk_DIV32(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return a32 / b32; } #undef silk_DIV32_16 -static inline opus_int32 silk_DIV32_16(opus_int32 a32, opus_int32 b32){ - silk_assert( b32 != 0 ); - silk_assert( b32 <= silk_int16_MAX ); - silk_assert( b32 >= silk_int16_MIN ); +#define silk_DIV32_16(a,b) silk_DIV32_16_((a), (b), __FILE__, __LINE__) +static inline opus_int32 silk_DIV32_16_(opus_int32 a32, opus_int32 b32, char *file, int line){ + int fail = 0; + fail |= b32 == 0; + fail |= b32 > silk_int16_MAX; + fail |= b32 < silk_int16_MIN; + if ( fail ) + { + fprintf (stderr, "silk_DIV32_16(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return a32 / b32; } @@ -334,187 +543,322 @@ static inline opus_int32 silk_DIV32_16(opus_int32 a32, opus_int32 b32){ no checking needed for silk_ADD_POS_SAT64 */ #undef silk_LSHIFT8 -static inline opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){ +#define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__) +static inline opus_int8 silk_LSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){ opus_int8 ret; + int fail = 0; ret = a << shift; - silk_assert(shift >= 0); - silk_assert(shift < 8); - silk_assert((opus_int64)ret == ((opus_int64)a) << shift); + fail |= shift < 0; + fail |= shift >= 8; + fail |= (opus_int64)ret != ((opus_int64)a) << shift; + if ( fail ) + { + fprintf (stderr, "silk_LSHIFT8(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_LSHIFT16 -static inline opus_int16 silk_LSHIFT16(opus_int16 a, opus_int32 shift){ +#define silk_LSHIFT16(a,b) silk_LSHIFT16_((a), (b), __FILE__, __LINE__) +static inline opus_int16 silk_LSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){ opus_int16 ret; + int fail = 0; ret = a << shift; - silk_assert(shift >= 0); - silk_assert(shift < 16); - silk_assert((opus_int64)ret == ((opus_int64)a) << shift); + fail |= shift < 0; + fail |= shift >= 16; + fail |= (opus_int64)ret != ((opus_int64)a) << shift; + if ( fail ) + { + fprintf (stderr, "silk_LSHIFT16(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_LSHIFT32 -static inline opus_int32 silk_LSHIFT32(opus_int32 a, opus_int32 shift){ +#define silk_LSHIFT32(a,b) silk_LSHIFT32_((a), (b), __FILE__, __LINE__) +static inline opus_int32 silk_LSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){ opus_int32 ret; + int fail = 0; ret = a << shift; - silk_assert(shift >= 0); - silk_assert(shift < 32); - silk_assert((opus_int64)ret == ((opus_int64)a) << shift); + fail |= shift < 0; + fail |= shift >= 32; + fail |= (opus_int64)ret != ((opus_int64)a) << shift; + if ( fail ) + { + fprintf (stderr, "silk_LSHIFT32(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_LSHIFT64 -static inline opus_int64 silk_LSHIFT64(opus_int64 a, opus_int shift){ - silk_assert(shift >= 0); - silk_assert(shift < 64); - return a << shift; +#define silk_LSHIFT64(a,b) silk_LSHIFT64_((a), (b), __FILE__, __LINE__) +static inline opus_int64 silk_LSHIFT64_(opus_int64 a, opus_int shift, char *file, int line){ + opus_int64 ret; + int fail = 0; + ret = a << shift; + fail |= shift < 0; + fail |= shift >= 64; + fail |= (ret>>shift) != ((opus_int64)a); + if ( fail ) + { + fprintf (stderr, "silk_LSHIFT64(%lld, %d) in %s: line %d\n", (long long)a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; } #undef silk_LSHIFT_ovflw -static inline opus_int32 silk_LSHIFT_ovflw(opus_int32 a, opus_int32 shift){ - silk_assert(shift >= 0); /* no check for overflow */ +#define silk_LSHIFT_ovflw(a,b) silk_LSHIFT_ovflw_((a), (b), __FILE__, __LINE__) +static inline opus_int32 silk_LSHIFT_ovflw_(opus_int32 a, opus_int32 shift, char *file, int line){ + if ( (shift < 0) || (shift >= 32) ) /* no check for overflow */ + { + fprintf (stderr, "silk_LSHIFT_ovflw(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return a << shift; } #undef silk_LSHIFT_uint -static inline opus_uint32 silk_LSHIFT_uint(opus_uint32 a, opus_int32 shift){ +#define silk_LSHIFT_uint(a,b) silk_LSHIFT_uint_((a), (b), __FILE__, __LINE__) +static inline opus_uint32 silk_LSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){ opus_uint32 ret; ret = a << shift; - silk_assert(shift >= 0); - silk_assert((opus_int64)ret == ((opus_int64)a) << shift); + if ( (shift < 0) || ((opus_int64)ret != ((opus_int64)a) << shift)) + { + fprintf (stderr, "silk_LSHIFT_uint(%u, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_RSHIFT8 -static inline opus_int8 silk_RSHIFT8(opus_int8 a, opus_int32 shift){ - silk_assert(shift >= 0); - silk_assert(shift < 8); +#define silk_RSHITF8(a,b) silk_RSHIFT8_((a), (b), __FILE__, __LINE__) +static inline opus_int8 silk_RSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){ + if ( (shift < 0) || (shift>=8) ) + { + fprintf (stderr, "silk_RSHITF8(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return a >> shift; } #undef silk_RSHIFT16 -static inline opus_int16 silk_RSHIFT16(opus_int16 a, opus_int32 shift){ - silk_assert(shift >= 0); - silk_assert(shift < 16); +#define silk_RSHITF16(a,b) silk_RSHIFT16_((a), (b), __FILE__, __LINE__) +static inline opus_int16 silk_RSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){ + if ( (shift < 0) || (shift>=16) ) + { + fprintf (stderr, "silk_RSHITF16(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return a >> shift; } #undef silk_RSHIFT32 -static inline opus_int32 silk_RSHIFT32(opus_int32 a, opus_int32 shift){ - silk_assert(shift >= 0); - silk_assert(shift < 32); +#define silk_RSHIFT32(a,b) silk_RSHIFT32_((a), (b), __FILE__, __LINE__) +static inline opus_int32 silk_RSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){ + if ( (shift < 0) || (shift>=32) ) + { + fprintf (stderr, "silk_RSHITF32(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return a >> shift; } #undef silk_RSHIFT64 -static inline opus_int64 silk_RSHIFT64(opus_int64 a, opus_int64 shift){ - silk_assert(shift >= 0); - silk_assert(shift <= 63); +#define silk_RSHIFT64(a,b) silk_RSHIFT64_((a), (b), __FILE__, __LINE__) +static inline opus_int64 silk_RSHIFT64_(opus_int64 a, opus_int64 shift, char *file, int line){ + if ( (shift < 0) || (shift>=64) ) + { + fprintf (stderr, "silk_RSHITF64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return a >> shift; } #undef silk_RSHIFT_uint -static inline opus_uint32 silk_RSHIFT_uint(opus_uint32 a, opus_int32 shift){ - silk_assert(shift >= 0); - silk_assert(shift <= 32); +#define silk_RSHIFT_uint(a,b) silk_RSHIFT_uint_((a), (b), __FILE__, __LINE__) +static inline opus_uint32 silk_RSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){ + if ( (shift < 0) || (shift>32) ) + { + fprintf (stderr, "silk_RSHIFT_uint(%u, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return a >> shift; } #undef silk_ADD_LSHIFT -static inline opus_int32 silk_ADD_LSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){ - opus_int32 ret; - silk_assert(shift >= 0); - silk_assert(shift <= 31); +#define silk_ADD_LSHIFT(a,b,c) silk_ADD_LSHIFT_((a), (b), (c), __FILE__, __LINE__) +static inline int silk_ADD_LSHIFT_(int a, int b, int shift, char *file, int line){ + opus_int16 ret; ret = a + (b << shift); - silk_assert((opus_int64)ret == (opus_int64)a + (((opus_int64)b) << shift)); + if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) + { + fprintf (stderr, "silk_ADD_LSHIFT(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; /* shift >= 0 */ } #undef silk_ADD_LSHIFT32 -static inline opus_int32 silk_ADD_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ +#define silk_ADD_LSHIFT32(a,b,c) silk_ADD_LSHIFT32_((a), (b), (c), __FILE__, __LINE__) +static inline opus_int32 silk_ADD_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; - silk_assert(shift >= 0); - silk_assert(shift <= 31); ret = a + (b << shift); - silk_assert((opus_int64)ret == (opus_int64)a + (((opus_int64)b) << shift)); + if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) + { + fprintf (stderr, "silk_ADD_LSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; /* shift >= 0 */ } #undef silk_ADD_LSHIFT_uint -static inline opus_uint32 silk_ADD_LSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){ +#define silk_ADD_LSHIFT_uint(a,b,c) silk_ADD_LSHIFT_uint_((a), (b), (c), __FILE__, __LINE__) +static inline opus_uint32 silk_ADD_LSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){ opus_uint32 ret; - silk_assert(shift >= 0); - silk_assert(shift <= 32); ret = a + (b << shift); - silk_assert((opus_int64)ret == (opus_int64)a + (((opus_int64)b) << shift)); + if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) + { + fprintf (stderr, "silk_ADD_LSHIFT_uint(%u, %u, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; /* shift >= 0 */ } #undef silk_ADD_RSHIFT -static inline opus_int32 silk_ADD_RSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){ - opus_int32 ret; - silk_assert(shift >= 0); - silk_assert(shift <= 31); +#define silk_ADD_RSHIFT(a,b,c) silk_ADD_RSHIFT_((a), (b), (c), __FILE__, __LINE__) +static inline int silk_ADD_RSHIFT_(int a, int b, int shift, char *file, int line){ + opus_int16 ret; ret = a + (b >> shift); - silk_assert((opus_int64)ret == (opus_int64)a + (((opus_int64)b) >> shift)); + if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) ) + { + fprintf (stderr, "silk_ADD_RSHIFT(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; /* shift > 0 */ } #undef silk_ADD_RSHIFT32 -static inline opus_int32 silk_ADD_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ +#define silk_ADD_RSHIFT32(a,b,c) silk_ADD_RSHIFT32_((a), (b), (c), __FILE__, __LINE__) +static inline opus_int32 silk_ADD_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; - silk_assert(shift >= 0); - silk_assert(shift <= 31); ret = a + (b >> shift); - silk_assert((opus_int64)ret == (opus_int64)a + (((opus_int64)b) >> shift)); + if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) ) + { + fprintf (stderr, "silk_ADD_RSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; /* shift > 0 */ } #undef silk_ADD_RSHIFT_uint -static inline opus_uint32 silk_ADD_RSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){ +#define silk_ADD_RSHIFT_uint(a,b,c) silk_ADD_RSHIFT_uint_((a), (b), (c), __FILE__, __LINE__) +static inline opus_uint32 silk_ADD_RSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){ opus_uint32 ret; - silk_assert(shift >= 0); - silk_assert(shift <= 32); ret = a + (b >> shift); - silk_assert((opus_int64)ret == (opus_int64)a + (((opus_int64)b) >> shift)); + if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) ) + { + fprintf (stderr, "silk_ADD_RSHIFT_uint(%u, %u, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; /* shift > 0 */ } #undef silk_SUB_LSHIFT32 -static inline opus_int32 silk_SUB_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ +#define silk_SUB_LSHIFT32(a,b,c) silk_SUB_LSHIFT32_((a), (b), (c), __FILE__, __LINE__) +static inline opus_int32 silk_SUB_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; - silk_assert(shift >= 0); - silk_assert(shift <= 31); ret = a - (b << shift); - silk_assert((opus_int64)ret == (opus_int64)a - (((opus_int64)b) << shift)); + if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) << shift)) ) + { + fprintf (stderr, "silk_SUB_LSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; /* shift >= 0 */ } #undef silk_SUB_RSHIFT32 -static inline opus_int32 silk_SUB_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ +#define silk_SUB_RSHIFT32(a,b,c) silk_SUB_RSHIFT32_((a), (b), (c), __FILE__, __LINE__) +static inline opus_int32 silk_SUB_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; - silk_assert(shift >= 0); - silk_assert(shift <= 31); ret = a - (b >> shift); - silk_assert((opus_int64)ret == (opus_int64)a - (((opus_int64)b) >> shift)); + if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) >> shift)) ) + { + fprintf (stderr, "silk_SUB_RSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; /* shift > 0 */ } #undef silk_RSHIFT_ROUND -static inline opus_int32 silk_RSHIFT_ROUND(opus_int32 a, opus_int32 shift){ +#define silk_RSHIFT_ROUND(a,b) silk_RSHIFT_ROUND_((a), (b), __FILE__, __LINE__) +static inline opus_int32 silk_RSHIFT_ROUND_(opus_int32 a, opus_int32 shift, char *file, int line){ opus_int32 ret; - silk_assert(shift > 0); /* the marco definition can't handle a shift of zero */ - silk_assert(shift < 32); ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; - silk_assert((opus_int64)ret == ((opus_int64)a + ((opus_int64)1 << (shift - 1))) >> shift); + /* the marco definition can't handle a shift of zero */ + if ( (shift <= 0) || (shift>31) || ((opus_int64)ret != ((opus_int64)a + ((opus_int64)1 << (shift - 1))) >> shift) ) + { + fprintf (stderr, "silk_RSHIFT_ROUND(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return ret; } #undef silk_RSHIFT_ROUND64 -static inline opus_int64 silk_RSHIFT_ROUND64(opus_int64 a, opus_int32 shift){ +#define silk_RSHIFT_ROUND64(a,b) silk_RSHIFT_ROUND64_((a), (b), __FILE__, __LINE__) +static inline opus_int64 silk_RSHIFT_ROUND64_(opus_int64 a, opus_int32 shift, char *file, int line){ opus_int64 ret; - silk_assert(shift > 0); /* the marco definition can't handle a shift of zero */ - silk_assert(shift < 64); + /* the marco definition can't handle a shift of zero */ + if ( (shift <= 0) || (shift>=64) ) + { + fprintf (stderr, "silk_RSHIFT_ROUND64(%lld, %d) in %s: line %d\n", (long long)a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; return ret; } @@ -527,38 +871,73 @@ static inline opus_int32 silk_abs(opus_int32 a){ }*/ #undef silk_abs_int64 -static inline opus_int64 silk_abs_int64(opus_int64 a){ - silk_assert(a != 0x8000000000000000); +#define silk_abs_int64(a) silk_abs_int64_((a), __FILE__, __LINE__) +static inline opus_int64 silk_abs_int64_(opus_int64 a, char *file, int line){ + if ( a == silk_int64_MIN ) + { + fprintf (stderr, "silk_abs_int64(%lld) in %s: line %d\n", (long long)a, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return (((a) > 0) ? (a) : -(a)); /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN */ } #undef silk_abs_int32 -static inline opus_int32 silk_abs_int32(opus_int32 a){ - silk_assert(a != 0x80000000); - return abs(a); +#define silk_abs_int32(a) silk_abs_int32_((a), __FILE__, __LINE__) +static inline opus_int32 silk_abs_int32_(opus_int32 a, char *file, int line){ + if ( a == silk_int32_MIN ) + { + fprintf (stderr, "silk_abs_int32(%d) in %s: line %d\n", a, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return silk_abs(a); } #undef silk_CHECK_FIT8 -static inline opus_int8 silk_CHECK_FIT8( opus_int64 a ){ +#define silk_CHECK_FIT8(a) silk_CHECK_FIT8_((a), __FILE__, __LINE__) +static inline opus_int8 silk_CHECK_FIT8_( opus_int64 a, char *file, int line ){ opus_int8 ret; ret = (opus_int8)a; - silk_assert( (opus_int64)ret == a ); + if ( (opus_int64)ret != a ) + { + fprintf (stderr, "silk_CHECK_FIT8(%lld) in %s: line %d\n", (long long)a, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return( ret ); } #undef silk_CHECK_FIT16 -static inline opus_int16 silk_CHECK_FIT16( opus_int64 a ){ +#define silk_CHECK_FIT16(a) silk_CHECK_FIT16_((a), __FILE__, __LINE__) +static inline opus_int16 silk_CHECK_FIT16_( opus_int64 a, char *file, int line ){ opus_int16 ret; ret = (opus_int16)a; - silk_assert( (opus_int64)ret == a ); + if ( (opus_int64)ret != a ) + { + fprintf (stderr, "silk_CHECK_FIT16(%lld) in %s: line %d\n", (long long)a, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return( ret ); } #undef silk_CHECK_FIT32 -static inline opus_int32 silk_CHECK_FIT32( opus_int64 a ){ +#define silk_CHECK_FIT32(a) silk_CHECK_FIT32_((a), __FILE__, __LINE__) +static inline opus_int32 silk_CHECK_FIT32_( opus_int64 a, char *file, int line ){ opus_int32 ret; ret = (opus_int32)a; - silk_assert( (opus_int64)ret == a ); + if ( (opus_int64)ret != a ) + { + fprintf (stderr, "silk_CHECK_FIT32(%lld) in %s: line %d\n", (long long)a, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } return( ret ); } diff --git a/media/libopus/silk/NLSF2A.c b/media/libopus/silk/NLSF2A.c index 4f373f072b16..06635f1c8157 100644 --- a/media/libopus/silk/NLSF2A.c +++ b/media/libopus/silk/NLSF2A.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/NLSF_VQ.c b/media/libopus/silk/NLSF_VQ.c index 3f4f6833a514..69b6e22e1896 100644 --- a/media/libopus/silk/NLSF_VQ.c +++ b/media/libopus/silk/NLSF_VQ.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/NLSF_VQ_weights_laroia.c b/media/libopus/silk/NLSF_VQ_weights_laroia.c index 0628bbea521c..04894c59ab7e 100644 --- a/media/libopus/silk/NLSF_VQ_weights_laroia.c +++ b/media/libopus/silk/NLSF_VQ_weights_laroia.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -57,28 +53,28 @@ void silk_NLSF_VQ_weights_laroia( /* First value */ tmp1_int = silk_max_int( pNLSF_Q15[ 0 ], 1 ); - tmp1_int = silk_DIV32_16( 1 << ( 15 + NLSF_W_Q ), tmp1_int ); + tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int ); tmp2_int = silk_max_int( pNLSF_Q15[ 1 ] - pNLSF_Q15[ 0 ], 1 ); - tmp2_int = silk_DIV32_16( 1 << ( 15 + NLSF_W_Q ), tmp2_int ); + tmp2_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp2_int ); pNLSFW_Q_OUT[ 0 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); silk_assert( pNLSFW_Q_OUT[ 0 ] > 0 ); /* Main loop */ for( k = 1; k < D - 1; k += 2 ) { tmp1_int = silk_max_int( pNLSF_Q15[ k + 1 ] - pNLSF_Q15[ k ], 1 ); - tmp1_int = silk_DIV32_16( 1 << ( 15 + NLSF_W_Q ), tmp1_int ); + tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int ); pNLSFW_Q_OUT[ k ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); silk_assert( pNLSFW_Q_OUT[ k ] > 0 ); tmp2_int = silk_max_int( pNLSF_Q15[ k + 2 ] - pNLSF_Q15[ k + 1 ], 1 ); - tmp2_int = silk_DIV32_16( 1 << ( 15 + NLSF_W_Q ), tmp2_int ); + tmp2_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp2_int ); pNLSFW_Q_OUT[ k + 1 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); silk_assert( pNLSFW_Q_OUT[ k + 1 ] > 0 ); } /* Last value */ tmp1_int = silk_max_int( ( 1 << 15 ) - pNLSF_Q15[ D - 1 ], 1 ); - tmp1_int = silk_DIV32_16( 1 << ( 15 + NLSF_W_Q ), tmp1_int ); + tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int ); pNLSFW_Q_OUT[ D - 1 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); silk_assert( pNLSFW_Q_OUT[ D - 1 ] > 0 ); } diff --git a/media/libopus/silk/NLSF_decode.c b/media/libopus/silk/NLSF_decode.c index c1a8650b9da1..3839acde751b 100644 --- a/media/libopus/silk/NLSF_decode.c +++ b/media/libopus/silk/NLSF_decode.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -55,7 +51,7 @@ static inline void silk_NLSF_residual_dequant( /* O Returns RD } else if( out_Q10 < 0 ) { out_Q10 = silk_ADD16( out_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); } - out_Q10 = silk_SMLAWB( pred_Q10, out_Q10, quant_step_size_Q16 ); + out_Q10 = silk_SMLAWB( pred_Q10, (opus_int32)out_Q10, quant_step_size_Q16 ); x_Q10[ i ] = out_Q10; } } diff --git a/media/libopus/silk/NLSF_del_dec_quant.c b/media/libopus/silk/NLSF_del_dec_quant.c index 2e1d06a9c293..4139e8f8ff7a 100644 --- a/media/libopus/silk/NLSF_del_dec_quant.c +++ b/media/libopus/silk/NLSF_del_dec_quant.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -72,7 +68,7 @@ opus_int32 silk_NLSF_del_dec_quant( /* O Returns for( j = 0; j < nStates; j++ ) { pred_Q10 = silk_SMULWB( pred_coef_Q16, prev_out_Q10[ j ] ); res_Q10 = silk_SUB16( in_Q10, pred_Q10 ); - ind_tmp = silk_SMULWB( inv_quant_step_size_Q6, res_Q10 ); + ind_tmp = silk_SMULWB( (opus_int32)inv_quant_step_size_Q6, res_Q10 ); ind_tmp = silk_LIMIT( ind_tmp, -NLSF_QUANT_MAX_AMPLITUDE_EXT, NLSF_QUANT_MAX_AMPLITUDE_EXT-1 ); ind[ j ][ i ] = (opus_int8)ind_tmp; @@ -90,8 +86,8 @@ opus_int32 silk_NLSF_del_dec_quant( /* O Returns out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); out1_Q10 = silk_ADD16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); } - out0_Q10 = silk_SMULWB( out0_Q10, quant_step_size_Q16 ); - out1_Q10 = silk_SMULWB( out1_Q10, quant_step_size_Q16 ); + out0_Q10 = silk_SMULWB( (opus_int32)out0_Q10, quant_step_size_Q16 ); + out1_Q10 = silk_SMULWB( (opus_int32)out1_Q10, quant_step_size_Q16 ); out0_Q10 = silk_ADD16( out0_Q10, pred_Q10 ); out1_Q10 = silk_ADD16( out1_Q10, pred_Q10 ); prev_out_Q10[ j ] = out0_Q10; diff --git a/media/libopus/silk/NLSF_encode.c b/media/libopus/silk/NLSF_encode.c index 8aa6ce07d94c..03a036fda2f7 100644 --- a/media/libopus/silk/NLSF_encode.c +++ b/media/libopus/silk/NLSF_encode.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main.h" +#include "stack_alloc.h" /***********************/ /* NLSF vector encoder */ @@ -50,10 +47,10 @@ opus_int32 silk_NLSF_encode( /* O Returns { opus_int i, s, ind1, bestIndex, prob_Q8, bits_q7; opus_int32 W_tmp_Q9; - opus_int32 err_Q26[ NLSF_VQ_MAX_VECTORS ]; - opus_int32 RD_Q25[ NLSF_VQ_MAX_SURVIVORS ]; - opus_int tempIndices1[ NLSF_VQ_MAX_SURVIVORS ]; - opus_int8 tempIndices2[ NLSF_VQ_MAX_SURVIVORS * MAX_LPC_ORDER ]; + VARDECL( opus_int32, err_Q26 ); + VARDECL( opus_int32, RD_Q25 ); + VARDECL( opus_int, tempIndices1 ); + VARDECL( opus_int8, tempIndices2 ); opus_int16 res_Q15[ MAX_LPC_ORDER ]; opus_int16 res_Q10[ MAX_LPC_ORDER ]; opus_int16 NLSF_tmp_Q15[ MAX_LPC_ORDER ]; @@ -62,6 +59,7 @@ opus_int32 silk_NLSF_encode( /* O Returns opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; opus_int16 ec_ix[ MAX_LPC_ORDER ]; const opus_uint8 *pCB_element, *iCDF_ptr; + SAVE_STACK; silk_assert( nSurvivors <= NLSF_VQ_MAX_SURVIVORS ); silk_assert( signalType >= 0 && signalType <= 2 ); @@ -71,11 +69,16 @@ opus_int32 silk_NLSF_encode( /* O Returns silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order ); /* First stage: VQ */ + ALLOC( err_Q26, psNLSF_CB->nVectors, opus_int32 ); silk_NLSF_VQ( err_Q26, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->nVectors, psNLSF_CB->order ); /* Sort the quantization errors */ + ALLOC( tempIndices1, nSurvivors, opus_int ); silk_insertion_sort_increasing( err_Q26, tempIndices1, psNLSF_CB->nVectors, nSurvivors ); + ALLOC( RD_Q25, nSurvivors, opus_int32 ); + ALLOC( tempIndices2, nSurvivors * MAX_LPC_ORDER, opus_int8 ); + /* Loop over survivors */ for( s = 0; s < nSurvivors; s++ ) { ind1 = tempIndices1[ s ]; @@ -128,5 +131,6 @@ opus_int32 silk_NLSF_encode( /* O Returns /* Decode */ silk_NLSF_decode( pNLSF_Q15, NLSFIndices, psNLSF_CB ); + RESTORE_STACK; return RD_Q25[ 0 ]; } diff --git a/media/libopus/silk/NLSF_stabilize.c b/media/libopus/silk/NLSF_stabilize.c index 979aaba28020..1fa1ea379bdd 100644 --- a/media/libopus/silk/NLSF_stabilize.c +++ b/media/libopus/silk/NLSF_stabilize.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -35,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE. /* NLSF stabilizer: */ /* */ -/* - Moves NLSFs futher apart if they are too close */ +/* - Moves NLSFs further apart if they are too close */ /* - Moves NLSFs away from borders if they are too close */ /* - High effort to achieve a modification with minimum */ /* Euclidean distance to input vector */ diff --git a/media/libopus/silk/NLSF_unpack.c b/media/libopus/silk/NLSF_unpack.c index f043172d744d..17bd23f752f3 100644 --- a/media/libopus/silk/NLSF_unpack.c +++ b/media/libopus/silk/NLSF_unpack.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/NSQ.c b/media/libopus/silk/NSQ.c index 1d3b53660669..4f2b7fe53efd 100644 --- a/media/libopus/silk/NSQ.c +++ b/media/libopus/silk/NSQ.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main.h" +#include "stack_alloc.h" static inline void silk_nsq_scale_states( const silk_encoder_state *psEncC, /* I Encoder State */ @@ -92,11 +89,12 @@ void silk_NSQ( opus_int k, lag, start_idx, LSF_interpolation_flag; const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; opus_int16 *pxq; - opus_int32 sLTP_Q15[ 2 * MAX_FRAME_LENGTH ]; - opus_int16 sLTP[ 2 * MAX_FRAME_LENGTH ]; + VARDECL( opus_int32, sLTP_Q15 ); + VARDECL( opus_int16, sLTP ); opus_int32 HarmShapeFIRPacked_Q14; opus_int offset_Q10; - opus_int32 x_sc_Q10[ MAX_SUB_FRAME_LENGTH ]; + VARDECL( opus_int32, x_sc_Q10 ); + SAVE_STACK; NSQ->rand_seed = psIndices->Seed; @@ -113,6 +111,10 @@ void silk_NSQ( LSF_interpolation_flag = 1; } + ALLOC( sLTP_Q15, + psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); + ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); + ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); /* Set up pointers to start of sub frame */ NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; @@ -164,6 +166,7 @@ void silk_NSQ( /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[ psEncC->ltp_mem_length ], psEncC->frame_length * sizeof( opus_int16 ) ) */ silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); + RESTORE_STACK; } /***********************************/ @@ -392,7 +395,7 @@ static inline void silk_nsq_scale_states( if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); } else { - gain_adj_Q16 = 1 << 16; + gain_adj_Q16 = (opus_int32)1 << 16; } /* Scale input */ @@ -417,7 +420,7 @@ static inline void silk_nsq_scale_states( } /* Adjust for changing gain */ - if( gain_adj_Q16 != 1 << 16 ) { + if( gain_adj_Q16 != (opus_int32)1 << 16 ) { /* Scale long-term shaping state */ for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) { NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); diff --git a/media/libopus/silk/NSQ_del_dec.c b/media/libopus/silk/NSQ_del_dec.c index 2fcc059dd597..a1b96062d471 100644 --- a/media/libopus/silk/NSQ_del_dec.c +++ b/media/libopus/silk/NSQ_del_dec.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main.h" +#include "stack_alloc.h" typedef struct { opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; @@ -58,6 +55,8 @@ typedef struct { opus_int32 LPC_exc_Q14; } NSQ_sample_struct; +typedef NSQ_sample_struct NSQ_sample_pair[ 2 ]; + static inline void silk_nsq_del_dec_scale_states( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ @@ -127,17 +126,18 @@ void silk_NSQ_del_dec( { opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr; opus_int last_smple_idx, smpl_buf_idx, decisionDelay; - const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; + const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; opus_int16 *pxq; - opus_int32 sLTP_Q15[ 2 * MAX_FRAME_LENGTH ]; - opus_int16 sLTP[ 2 * MAX_FRAME_LENGTH ]; + VARDECL( opus_int32, sLTP_Q15 ); + VARDECL( opus_int16, sLTP ); opus_int32 HarmShapeFIRPacked_Q14; opus_int offset_Q10; opus_int32 RDmin_Q10, Gain_Q10; - opus_int32 x_sc_Q10[ MAX_SUB_FRAME_LENGTH ]; - opus_int32 delayedGain_Q10[ DECISION_DELAY ]; - NSQ_del_dec_struct psDelDec[ MAX_DEL_DEC_STATES ]; + VARDECL( opus_int32, x_sc_Q10 ); + VARDECL( opus_int32, delayedGain_Q10 ); + VARDECL( NSQ_del_dec_struct, psDelDec ); NSQ_del_dec_struct *psDD; + SAVE_STACK; /* Set unvoiced lag to the previous one, overwrite later for voiced */ lag = NSQ->lagPrev; @@ -145,6 +145,7 @@ void silk_NSQ_del_dec( silk_assert( NSQ->prev_gain_Q16 != 0 ); /* Initialize delayed decision states */ + ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct ); silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) ); for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) { psDD = &psDelDec[ k ]; @@ -179,6 +180,11 @@ void silk_NSQ_del_dec( LSF_interpolation_flag = 1; } + ALLOC( sLTP_Q15, + psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); + ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); + ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); + ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 ); /* Set up pointers to start of sub frame */ pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; @@ -291,6 +297,7 @@ void silk_NSQ_del_dec( /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[psEncC->ltp_mem_length], psEncC->frame_length * sizeof( opus_int16 ) ) */ silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); + RESTORE_STACK; } /******************************************/ @@ -332,11 +339,13 @@ static inline void silk_noise_shape_quantizer_del_dec( opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14; - NSQ_sample_struct psSampleState[ MAX_DEL_DEC_STATES ][ 2 ]; + VARDECL( NSQ_sample_pair, psSampleState ); NSQ_del_dec_struct *psDD; NSQ_sample_struct *psSS; + SAVE_STACK; silk_assert( nStatesDelayedDecision > 0 ); + ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair ); shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; @@ -618,6 +627,7 @@ static inline void silk_noise_shape_quantizer_del_dec( psDD = &psDelDec[ k ]; silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); } + RESTORE_STACK; } static inline void silk_nsq_del_dec_scale_states( @@ -649,7 +659,7 @@ static inline void silk_nsq_del_dec_scale_states( if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); } else { - gain_adj_Q16 = 1 << 16; + gain_adj_Q16 = (opus_int32)1 << 16; } /* Scale input */ @@ -674,7 +684,7 @@ static inline void silk_nsq_del_dec_scale_states( } /* Adjust for changing gain */ - if( gain_adj_Q16 != 1 << 16 ) { + if( gain_adj_Q16 != (opus_int32)1 << 16 ) { /* Scale long-term shaping state */ for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) { NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); diff --git a/media/libopus/silk/PLC.c b/media/libopus/silk/PLC.c index 4733646c1c58..697ad056ac0a 100644 --- a/media/libopus/silk/PLC.c +++ b/media/libopus/silk/PLC.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main.h" +#include "stack_alloc.h" #include "PLC.h" #define NB_ATT 2 @@ -49,7 +46,7 @@ static inline void silk_PLC_update( static inline void silk_PLC_conceal( silk_decoder_state *psDec, /* I/O Decoder state */ silk_decoder_control *psDecCtrl, /* I/O Decoder control */ - opus_int16 signal[] /* O LPC residual signal */ + opus_int16 frame[] /* O LPC residual signal */ ); @@ -182,12 +179,17 @@ static inline void silk_PLC_conceal( opus_int16 rand_scale_Q14; opus_int16 *B_Q14, *exc_buf_ptr; opus_int32 *sLPC_Q14_ptr; - opus_int16 exc_buf[ 2 * MAX_SUB_FRAME_LENGTH ]; + VARDECL( opus_int16, exc_buf ); opus_int16 A_Q12[ MAX_LPC_ORDER ]; - opus_int16 sLTP[ MAX_FRAME_LENGTH ]; - opus_int32 sLTP_Q14[ 2 * MAX_FRAME_LENGTH ]; + VARDECL( opus_int16, sLTP ); + VARDECL( opus_int32, sLTP_Q14 ); silk_PLC_struct *psPLC = &psDec->sPLC; opus_int32 prevGain_Q10[2]; + SAVE_STACK; + + ALLOC( exc_buf, 2*psPLC->subfr_length, opus_int16 ); + ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 ); + ALLOC( sLTP_Q14, psDec->ltp_mem_length + psDec->frame_length, opus_int32 ); prevGain_Q10[0] = silk_RSHIFT( psPLC->prevGain_Q16[ 0 ], 6); prevGain_Q10[1] = silk_RSHIFT( psPLC->prevGain_Q16[ 1 ], 6); @@ -253,8 +255,8 @@ static inline void silk_PLC_conceal( invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order ); - down_scale_Q30 = silk_min_32( silk_RSHIFT( 1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 ); - down_scale_Q30 = silk_max_32( silk_RSHIFT( 1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 ); + down_scale_Q30 = silk_min_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 ); + down_scale_Q30 = silk_max_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 ); down_scale_Q30 = silk_LSHIFT( down_scale_Q30, LOG2_INV_LPC_GAIN_HIGH_THRES ); rand_Gain_Q15 = silk_RSHIFT( silk_SMULWB( down_scale_Q30, rand_Gain_Q15 ), 14 ); @@ -358,9 +360,10 @@ static inline void silk_PLC_conceal( for( i = 0; i < MAX_NB_SUBFR; i++ ) { psDecCtrl->pitchL[ i ] = lag; } + RESTORE_STACK; } -/* Glues concealed frames with new good recieved frames */ +/* Glues concealed frames with new good received frames */ void silk_PLC_glue_frames( silk_decoder_state *psDec, /* I/O decoder state */ opus_int16 frame[], /* I/O signal */ @@ -402,14 +405,14 @@ void silk_PLC_glue_frames( frac_Q24 = silk_DIV32( psPLC->conc_energy, silk_max( energy, 1 ) ); gain_Q16 = silk_LSHIFT( silk_SQRT_APPROX( frac_Q24 ), 4 ); - slope_Q16 = silk_DIV32_16( ( 1 << 16 ) - gain_Q16, length ); + slope_Q16 = silk_DIV32_16( ( (opus_int32)1 << 16 ) - gain_Q16, length ); /* Make slope 4x steeper to avoid missing onsets after DTX */ slope_Q16 = silk_LSHIFT( slope_Q16, 2 ); for( i = 0; i < length; i++ ) { frame[ i ] = silk_SMULWB( gain_Q16, frame[ i ] ); gain_Q16 += slope_Q16; - if( gain_Q16 > 1 << 16 ) { + if( gain_Q16 > (opus_int32)1 << 16 ) { break; } } diff --git a/media/libopus/silk/PLC.h b/media/libopus/silk/PLC.h index dfa82b515d8f..f1e2eccc69a3 100644 --- a/media/libopus/silk/PLC.h +++ b/media/libopus/silk/PLC.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -38,7 +34,6 @@ POSSIBILITY OF SUCH DAMAGE. #define V_PITCH_GAIN_START_MIN_Q14 11469 /* 0.7 in Q14 */ #define V_PITCH_GAIN_START_MAX_Q14 15565 /* 0.95 in Q14 */ #define MAX_PITCH_LAG_MS 18 -#define SA_THRES_Q8 50 #define RAND_BUF_SIZE 128 #define RAND_BUF_MASK ( RAND_BUF_SIZE - 1 ) #define LOG2_INV_LPC_GAIN_HIGH_THRES 3 /* 2^3 = 8 dB LPC gain */ diff --git a/media/libopus/silk/SigProc_FIX.h b/media/libopus/silk/SigProc_FIX.h index 846eab67ad29..3344ddb84e2b 100644 --- a/media/libopus/silk/SigProc_FIX.h +++ b/media/libopus/silk/SigProc_FIX.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -41,7 +37,6 @@ extern "C" #define SILK_MAX_ORDER_LPC 16 /* max order of the LPC analysis in schur() and k2a() */ -#include /* for abs() */ #include /* for memset(), memcpy(), memmove() */ #include "typedef.h" #include "resampler_structs.h" @@ -173,12 +168,6 @@ opus_int32 silk_log2lin( const opus_int32 inLog_Q7 /* I input on log scale */ ); -/* Function that returns the maximum absolut value of the input vector */ -opus_int16 silk_int16_array_maxabs( /* O Maximum absolute value, max: 2^15-1 */ - const opus_int16 *vec, /* I Input vector [len] */ - const opus_int32 len /* I Length of input vector */ -); - /* Compute number of bits to right shift the sum of squares of a vector */ /* of int16s to make it fit in an int32 */ void silk_sum_sqr_shift( @@ -257,7 +246,7 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */ opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */ - const opus_int search_thres2_Q15, /* I Final threshold for lag candidates 0 - 1 */ + const opus_int search_thres2_Q13, /* I Final threshold for lag candidates 0 - 1 */ const opus_int Fs_kHz, /* I Sample frequency (kHz) */ const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ const opus_int nb_subfr /* I number of 5 ms subframes */ @@ -318,7 +307,7 @@ void silk_burg_modified( opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ - const opus_int subfr_length, /* I Input signal subframe length (incl. D preceeding samples) */ + const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ const opus_int nb_subfr, /* I Number of subframes stacked in x */ const opus_int D /* I Order */ ); @@ -384,7 +373,7 @@ static inline opus_int32 silk_ROR32( opus_int32 a32, opus_int rot ) } } -/* Allocate opus_int16 alligned to 4-byte memory address */ +/* Allocate opus_int16 aligned to 4-byte memory address */ #if EMBEDDED_ARM #define silk_DWORD_ALIGN __attribute__((aligned(4))) #else @@ -487,8 +476,6 @@ static inline opus_int32 silk_ROR32( opus_int32 a32, opus_int rot ) #define silk_RSHIFT(a, shift) silk_RSHIFT32(a, shift) /* shift >= 0, shift < 32 */ /* saturates before shifting */ -#define silk_LSHIFT_SAT16(a, shift) (silk_LSHIFT16( silk_LIMIT( (a), silk_RSHIFT16( silk_int16_MIN, (shift) ), \ - silk_RSHIFT16( silk_int16_MAX, (shift) ) ), (shift) )) #define silk_LSHIFT_SAT32(a, shift) (silk_LSHIFT32( silk_LIMIT( (a), silk_RSHIFT32( silk_int32_MIN, (shift) ), \ silk_RSHIFT32( silk_int32_MAX, (shift) ) ), (shift) )) @@ -570,8 +557,6 @@ static inline opus_int64 silk_max_64(opus_int64 a, opus_int64 b) #define silk_sign(a) ((a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 )) -#define silk_sqrt(a) (sqrt(a)) - /* PSEUDO-RANDOM GENERATOR */ /* Make sure to store the result as the seed for the next call (also in between */ /* frames), otherwise result won't be random at all. When only using some of the */ @@ -591,6 +576,14 @@ static inline opus_int64 silk_max_64(opus_int64 a, opus_int64 b) #include "MacroCount.h" #include "MacroDebug.h" +#ifdef ARMv4_ASM +#include "arm/SigProc_FIX_armv4.h" +#endif + +#ifdef ARMv5E_ASM +#include "arm/SigProc_FIX_armv5e.h" +#endif + #ifdef __cplusplus } #endif diff --git a/media/libopus/silk/VAD.c b/media/libopus/silk/VAD.c index e12424fa2600..a9359e958097 100644 --- a/media/libopus/silk/VAD.c +++ b/media/libopus/silk/VAD.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -33,8 +29,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "config.h" #endif -#include #include "main.h" +#include "stack_alloc.h" /* Silk VAD noise level estimation */ static inline void silk_VAD_GetNoiseLevels( @@ -87,15 +83,19 @@ opus_int silk_VAD_GetSA_Q8( /* O Return v ) { opus_int SA_Q15, pSNR_dB_Q7, input_tilt; - opus_int decimated_framelength, dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s; + opus_int decimated_framelength1, decimated_framelength2; + opus_int decimated_framelength; + opus_int dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s; opus_int32 sumSquared, smooth_coef_Q16; opus_int16 HPstateTmp; - opus_int16 X[ VAD_N_BANDS ][ MAX_FRAME_LENGTH / 2 ]; + VARDECL( opus_int16, X ); opus_int32 Xnrg[ VAD_N_BANDS ]; opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ]; opus_int32 speech_nrg, x_tmp; + opus_int X_offset[ VAD_N_BANDS ]; opus_int ret = 0; silk_VAD_state *psSilk_VAD = &psEncC->sVAD; + SAVE_STACK; /* Safety checks */ silk_assert( VAD_N_BANDS == 4 ); @@ -106,26 +106,46 @@ opus_int silk_VAD_GetSA_Q8( /* O Return v /***********************/ /* Filter and Decimate */ /***********************/ + decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 ); + decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 ); + decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 ); + /* Decimate into 4 bands: + 0 L 3L L 3L 5L + - -- - -- -- + 8 8 2 4 4 + + [0-1 kHz| temp. |1-2 kHz| 2-4 kHz | 4-8 kHz | + + They're arranged to allow the minimal ( frame_length / 4 ) extra + scratch space during the downsampling process */ + X_offset[ 0 ] = 0; + X_offset[ 1 ] = decimated_framelength + decimated_framelength2; + X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength; + X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2; + ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 ); + /* 0-8 kHz to 0-4 kHz and 4-8 kHz */ - silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ], &X[ 0 ][ 0 ], &X[ 3 ][ 0 ], psEncC->frame_length ); + silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ], + X, &X[ X_offset[ 3 ] ], psEncC->frame_length ); /* 0-4 kHz to 0-2 kHz and 2-4 kHz */ - silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState1[ 0 ], &X[ 0 ][ 0 ], &X[ 2 ][ 0 ], silk_RSHIFT( psEncC->frame_length, 1 ) ); + silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ], + X, &X[ X_offset[ 2 ] ], decimated_framelength1 ); /* 0-2 kHz to 0-1 kHz and 1-2 kHz */ - silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState2[ 0 ], &X[ 0 ][ 0 ], &X[ 1 ][ 0 ], silk_RSHIFT( psEncC->frame_length, 2 ) ); + silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ], + X, &X[ X_offset[ 1 ] ], decimated_framelength2 ); /*********************************************/ /* HP filter on lowest band (differentiator) */ /*********************************************/ - decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 ); - X[ 0 ][ decimated_framelength - 1 ] = silk_RSHIFT( X[ 0 ][ decimated_framelength - 1 ], 1 ); - HPstateTmp = X[ 0 ][ decimated_framelength - 1 ]; + X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 ); + HPstateTmp = X[ decimated_framelength - 1 ]; for( i = decimated_framelength - 1; i > 0; i-- ) { - X[ 0 ][ i - 1 ] = silk_RSHIFT( X[ 0 ][ i - 1 ], 1 ); - X[ 0 ][ i ] -= X[ 0 ][ i - 1 ]; + X[ i - 1 ] = silk_RSHIFT( X[ i - 1 ], 1 ); + X[ i ] -= X[ i - 1 ]; } - X[ 0 ][ 0 ] -= psSilk_VAD->HPstate; + X[ 0 ] -= psSilk_VAD->HPstate; psSilk_VAD->HPstate = HPstateTmp; /*************************************/ @@ -147,7 +167,8 @@ opus_int silk_VAD_GetSA_Q8( /* O Return v for( i = 0; i < dec_subframe_length; i++ ) { /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2. */ /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */ - x_tmp = silk_RSHIFT( X[ b ][ i + dec_subframe_offset ], 3 ); + x_tmp = silk_RSHIFT( + X[ X_offset[ b ] + i + dec_subframe_offset ], 3 ); sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp ); /* Safety check */ @@ -194,7 +215,7 @@ opus_int silk_VAD_GetSA_Q8( /* O Return v sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */ /* Tilt measure */ - if( speech_nrg < ( 1 << 20 ) ) { + if( speech_nrg < ( (opus_int32)1 << 20 ) ) { /* Scale down SNR value for small subband speech energies */ SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 ); } @@ -251,7 +272,7 @@ opus_int silk_VAD_GetSA_Q8( /* O Return v /* Energy Level and SNR estimation */ /***********************************/ /* Smoothing coefficient */ - smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( SA_Q15, SA_Q15 ) ); + smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) ); if( psEncC->frame_length == 10 * psEncC->fs_kHz ) { smooth_coef_Q16 >>= 1; @@ -268,6 +289,7 @@ opus_int silk_VAD_GetSA_Q8( /* O Return v psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) ); } + RESTORE_STACK; return( ret ); } diff --git a/media/libopus/silk/VQ_WMat_EC.c b/media/libopus/silk/VQ_WMat_EC.c index 17536d45ca60..c5c6f714625d 100644 --- a/media/libopus/silk/VQ_WMat_EC.c +++ b/media/libopus/silk/VQ_WMat_EC.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/ana_filt_bank_1.c b/media/libopus/silk/ana_filt_bank_1.c index 98512b8ec917..24cfb03fdb2a 100644 --- a/media/libopus/silk/ana_filt_bank_1.c +++ b/media/libopus/silk/ana_filt_bank_1.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/arm/SigProc_FIX_armv4.h b/media/libopus/silk/arm/SigProc_FIX_armv4.h new file mode 100644 index 000000000000..d69573e3d4d2 --- /dev/null +++ b/media/libopus/silk/arm/SigProc_FIX_armv4.h @@ -0,0 +1,47 @@ +/*********************************************************************** +Copyright (C) 2013 Xiph.Org Foundation and contributors +Copyright (c) 2013 Parrot +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_SIGPROC_FIX_ARMv4_H +#define SILK_SIGPROC_FIX_ARMv4_H + +#undef silk_MLA +static inline opus_int32 silk_MLA_armv4(opus_int32 a, opus_int32 b, + opus_int32 c) +{ + opus_int32 res; + __asm__( + "#silk_MLA\n\t" + "mla %0, %1, %2, %3\n\t" + : "=&r"(res) + : "r"(b), "r"(c), "r"(a) + ); + return res; +} +#define silk_MLA(a, b, c) (silk_MLA_armv4(a, b, c)) + +#endif diff --git a/media/libopus/silk/arm/SigProc_FIX_armv5e.h b/media/libopus/silk/arm/SigProc_FIX_armv5e.h new file mode 100644 index 000000000000..81a6324f6520 --- /dev/null +++ b/media/libopus/silk/arm/SigProc_FIX_armv5e.h @@ -0,0 +1,61 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Copyright (c) 2013 Parrot +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_SIGPROC_FIX_ARMv5E_H +#define SILK_SIGPROC_FIX_ARMv5E_H + +#undef silk_SMULTT +static inline opus_int32 silk_SMULTT_armv5e(opus_int32 a, opus_int32 b) +{ + opus_int32 res; + __asm__( + "#silk_SMULTT\n\t" + "smultt %0, %1, %2\n\t" + : "=r"(res) + : "%r"(a), "r"(b) + ); + return res; +} +#define silk_SMULTT(a, b) (silk_SMULTT_armv5e(a, b)) + +#undef silk_SMLATT +static inline opus_int32 silk_SMLATT_armv5e(opus_int32 a, opus_int32 b, + opus_int32 c) +{ + opus_int32 res; + __asm__( + "#silk_SMLATT\n\t" + "smlatt %0, %1, %2, %3\n\t" + : "=r"(res) + : "%r"(b), "r"(c), "r"(a) + ); + return res; +} +#define silk_SMLATT(a, b, c) (silk_SMLATT_armv5e(a, b, c)) + +#endif diff --git a/media/libopus/silk/arm/macros_armv4.h b/media/libopus/silk/arm/macros_armv4.h new file mode 100644 index 000000000000..58df6c2e2b31 --- /dev/null +++ b/media/libopus/silk/arm/macros_armv4.h @@ -0,0 +1,103 @@ +/*********************************************************************** +Copyright (C) 2013 Xiph.Org Foundation and contributors. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_MACROS_ARMv4_H +#define SILK_MACROS_ARMv4_H + +/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ +#undef silk_SMULWB +static inline opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b) +{ + unsigned rd_lo; + int rd_hi; + __asm__( + "#silk_SMULWB\n\t" + "smull %0, %1, %2, %3\n\t" + : "=&r"(rd_lo), "=&r"(rd_hi) + : "%r"(a), "r"(b<<16) + ); + return rd_hi; +} +#define silk_SMULWB(a, b) (silk_SMULWB_armv4(a, b)) + +/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */ +#undef silk_SMLAWB +#define silk_SMLAWB(a, b, c) ((a) + silk_SMULWB(b, c)) + +/* (a32 * (b32 >> 16)) >> 16 */ +#undef silk_SMULWT +static inline opus_int32 silk_SMULWT_armv4(opus_int32 a, opus_int32 b) +{ + unsigned rd_lo; + int rd_hi; + __asm__( + "#silk_SMULWT\n\t" + "smull %0, %1, %2, %3\n\t" + : "=&r"(rd_lo), "=&r"(rd_hi) + : "%r"(a), "r"(b&~0xFFFF) + ); + return rd_hi; +} +#define silk_SMULWT(a, b) (silk_SMULWT_armv4(a, b)) + +/* a32 + (b32 * (c32 >> 16)) >> 16 */ +#undef silk_SMLAWT +#define silk_SMLAWT(a, b, c) ((a) + silk_SMULWT(b, c)) + +/* (a32 * b32) >> 16 */ +#undef silk_SMULWW +static inline opus_int32 silk_SMULWW_armv4(opus_int32 a, opus_int32 b) +{ + unsigned rd_lo; + int rd_hi; + __asm__( + "#silk_SMULWW\n\t" + "smull %0, %1, %2, %3\n\t" + : "=&r"(rd_lo), "=&r"(rd_hi) + : "%r"(a), "r"(b) + ); + return (rd_hi<<16)+(rd_lo>>16); +} +#define silk_SMULWW(a, b) (silk_SMULWW_armv4(a, b)) + +#undef silk_SMLAWW +static inline opus_int32 silk_SMLAWW_armv4(opus_int32 a, opus_int32 b, + opus_int32 c) +{ + unsigned rd_lo; + int rd_hi; + __asm__( + "#silk_SMLAWW\n\t" + "smull %0, %1, %2, %3\n\t" + : "=&r"(rd_lo), "=&r"(rd_hi) + : "%r"(b), "r"(c) + ); + return a+(rd_hi<<16)+(rd_lo>>16); +} +#define silk_SMLAWW(a, b, c) (silk_SMLAWW_armv4(a, b, c)) + +#endif /* SILK_MACROS_ARMv4_H */ diff --git a/media/libopus/silk/arm/macros_armv5e.h b/media/libopus/silk/arm/macros_armv5e.h new file mode 100644 index 000000000000..63b1e30f48bc --- /dev/null +++ b/media/libopus/silk/arm/macros_armv5e.h @@ -0,0 +1,213 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Copyright (c) 2013 Parrot +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_MACROS_ARMv5E_H +#define SILK_MACROS_ARMv5E_H + +/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ +#undef silk_SMULWB +static inline opus_int32 silk_SMULWB_armv5e(opus_int32 a, opus_int16 b) +{ + int res; + __asm__( + "#silk_SMULWB\n\t" + "smulwb %0, %1, %2\n\t" + : "=r"(res) + : "r"(a), "r"(b) + ); + return res; +} +#define silk_SMULWB(a, b) (silk_SMULWB_armv5e(a, b)) + +/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */ +#undef silk_SMLAWB +static inline opus_int32 silk_SMLAWB_armv5e(opus_int32 a, opus_int32 b, + opus_int16 c) +{ + int res; + __asm__( + "#silk_SMLAWB\n\t" + "smlawb %0, %1, %2, %3\n\t" + : "=r"(res) + : "r"(b), "r"(c), "r"(a) + ); + return res; +} +#define silk_SMLAWB(a, b, c) (silk_SMLAWB_armv5e(a, b, c)) + +/* (a32 * (b32 >> 16)) >> 16 */ +#undef silk_SMULWT +static inline opus_int32 silk_SMULWT_armv5e(opus_int32 a, opus_int32 b) +{ + int res; + __asm__( + "#silk_SMULWT\n\t" + "smulwt %0, %1, %2\n\t" + : "=r"(res) + : "r"(a), "r"(b) + ); + return res; +} +#define silk_SMULWT(a, b) (silk_SMULWT_armv5e(a, b)) + +/* a32 + (b32 * (c32 >> 16)) >> 16 */ +#undef silk_SMLAWT +static inline opus_int32 silk_SMLAWT_armv5e(opus_int32 a, opus_int32 b, + opus_int32 c) +{ + int res; + __asm__( + "#silk_SMLAWT\n\t" + "smlawt %0, %1, %2, %3\n\t" + : "=r"(res) + : "r"(b), "r"(c), "r"(a) + ); + return res; +} +#define silk_SMLAWT(a, b, c) (silk_SMLAWT_armv5e(a, b, c)) + +/* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */ +#undef silk_SMULBB +static inline opus_int32 silk_SMULBB_armv5e(opus_int32 a, opus_int32 b) +{ + int res; + __asm__( + "#silk_SMULBB\n\t" + "smulbb %0, %1, %2\n\t" + : "=r"(res) + : "%r"(a), "r"(b) + ); + return res; +} +#define silk_SMULBB(a, b) (silk_SMULBB_armv5e(a, b)) + +/* a32 + (opus_int32)((opus_int16)(b32)) * (opus_int32)((opus_int16)(c32)) output have to be 32bit int */ +#undef silk_SMLABB +static inline opus_int32 silk_SMLABB_armv5e(opus_int32 a, opus_int32 b, + opus_int32 c) +{ + int res; + __asm__( + "#silk_SMLABB\n\t" + "smlabb %0, %1, %2, %3\n\t" + : "=r"(res) + : "%r"(b), "r"(c), "r"(a) + ); + return res; +} +#define silk_SMLABB(a, b, c) (silk_SMLABB_armv5e(a, b, c)) + +/* (opus_int32)((opus_int16)(a32)) * (b32 >> 16) */ +#undef silk_SMULBT +static inline opus_int32 silk_SMULBT_armv5e(opus_int32 a, opus_int32 b) +{ + int res; + __asm__( + "#silk_SMULBT\n\t" + "smulbt %0, %1, %2\n\t" + : "=r"(res) + : "r"(a), "r"(b) + ); + return res; +} +#define silk_SMULBT(a, b) (silk_SMULBT_armv5e(a, b)) + +/* a32 + (opus_int32)((opus_int16)(b32)) * (c32 >> 16) */ +#undef silk_SMLABT +static inline opus_int32 silk_SMLABT_armv5e(opus_int32 a, opus_int32 b, + opus_int32 c) +{ + int res; + __asm__( + "#silk_SMLABT\n\t" + "smlabt %0, %1, %2, %3\n\t" + : "=r"(res) + : "r"(b), "r"(c), "r"(a) + ); + return res; +} +#define silk_SMLABT(a, b, c) (silk_SMLABT_armv5e(a, b, c)) + +/* add/subtract with output saturated */ +#undef silk_ADD_SAT32 +static inline opus_int32 silk_ADD_SAT32_armv5e(opus_int32 a, opus_int32 b) +{ + int res; + __asm__( + "#silk_ADD_SAT32\n\t" + "qadd %0, %1, %2\n\t" + : "=r"(res) + : "%r"(a), "r"(b) + ); + return res; +} +#define silk_ADD_SAT32(a, b) (silk_ADD_SAT32_armv5e(a, b)) + +#undef silk_SUB_SAT32 +static inline opus_int32 silk_SUB_SAT32_armv5e(opus_int32 a, opus_int32 b) +{ + int res; + __asm__( + "#silk_SUB_SAT32\n\t" + "qsub %0, %1, %2\n\t" + : "=r"(res) + : "r"(a), "r"(b) + ); + return res; +} +#define silk_SUB_SAT32(a, b) (silk_SUB_SAT32_armv5e(a, b)) + +#undef silk_CLZ16 +static inline opus_int32 silk_CLZ16_armv5(opus_int16 in16) +{ + int res; + __asm__( + "#silk_CLZ16\n\t" + "clz %0, %1;\n" + : "=r"(res) + : "r"(in16<<16|0x8000) + ); + return res; +} +#define silk_CLZ16(in16) (silk_CLZ16_armv5(in16)) + +#undef silk_CLZ32 +static inline opus_int32 silk_CLZ32_armv5(opus_int32 in32) +{ + int res; + __asm__( + "#silk_CLZ32\n\t" + "clz %0, %1\n\t" + : "=r"(res) + : "r"(in32) + ); + return res; +} +#define silk_CLZ32(in32) (silk_CLZ32_armv5(in32)) + +#endif /* SILK_MACROS_ARMv5E_H */ diff --git a/media/libopus/silk/biquad_alt.c b/media/libopus/silk/biquad_alt.c index fa7719c12e65..d55f5ee92ec2 100644 --- a/media/libopus/silk/biquad_alt.c +++ b/media/libopus/silk/biquad_alt.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/bwexpander.c b/media/libopus/silk/bwexpander.c index 7367185d856c..2eb4456695e7 100644 --- a/media/libopus/silk/bwexpander.c +++ b/media/libopus/silk/bwexpander.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/bwexpander_32.c b/media/libopus/silk/bwexpander_32.c index 4e684cd61cda..d0010f73dfd5 100644 --- a/media/libopus/silk/bwexpander_32.c +++ b/media/libopus/silk/bwexpander_32.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/check_control_input.c b/media/libopus/silk/check_control_input.c index e37b2bdb2f1a..b5de9ce48d69 100644 --- a/media/libopus/silk/check_control_input.c +++ b/media/libopus/silk/check_control_input.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/code_signs.c b/media/libopus/silk/code_signs.c index 8567775cfa4a..0419ea2626a7 100644 --- a/media/libopus/silk/code_signs.c +++ b/media/libopus/silk/code_signs.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/control.h b/media/libopus/silk/control.h index 465b54f63ef3..896cbe8c1241 100644 --- a/media/libopus/silk/control.h +++ b/media/libopus/silk/control.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/control_SNR.c b/media/libopus/silk/control_SNR.c index 88ccfe16a520..f04e69fce248 100644 --- a/media/libopus/silk/control_SNR.c +++ b/media/libopus/silk/control_SNR.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/control_audio_bandwidth.c b/media/libopus/silk/control_audio_bandwidth.c index fc989d4499ec..4f9bc5cbdaa9 100644 --- a/media/libopus/silk/control_audio_bandwidth.c +++ b/media/libopus/silk/control_audio_bandwidth.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -84,6 +80,8 @@ opus_int silk_control_audio_bandwidth( } else { if( psEncC->sLP.transition_frame_no <= 0 ) { encControl->switchReady = 1; + /* Make room for redundancy */ + encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 ); } else { /* Direction: down (at double speed) */ psEncC->sLP.mode = -2; @@ -110,11 +108,16 @@ opus_int silk_control_audio_bandwidth( } else { if( psEncC->sLP.mode == 0 ) { encControl->switchReady = 1; + /* Make room for redundancy */ + encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 ); } else { /* Direction: up */ psEncC->sLP.mode = 1; } } + } else { + if (psEncC->sLP.mode<0) + psEncC->sLP.mode = 1; } } } diff --git a/media/libopus/silk/control_codec.c b/media/libopus/silk/control_codec.c index 06b3c6052cc0..56ce14c7f9c9 100644 --- a/media/libopus/silk/control_codec.c +++ b/media/libopus/silk/control_codec.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -39,21 +35,22 @@ POSSIBILITY OF SUCH DAMAGE. #include "main_FLP.h" #define silk_encoder_state_Fxx silk_encoder_state_FLP #endif +#include "stack_alloc.h" #include "tuning_parameters.h" #include "pitch_est_defines.h" -opus_int silk_setup_resamplers( +static opus_int silk_setup_resamplers( silk_encoder_state_Fxx *psEnc, /* I/O */ opus_int fs_kHz /* I */ ); -opus_int silk_setup_fs( +static opus_int silk_setup_fs( silk_encoder_state_Fxx *psEnc, /* I/O */ opus_int fs_kHz, /* I */ opus_int PacketSize_ms /* I */ ); -opus_int silk_setup_complexity( +static opus_int silk_setup_complexity( silk_encoder_state *psEncC, /* I/O */ opus_int Complexity /* I */ ); @@ -135,13 +132,13 @@ opus_int silk_control_encoder( return ret; } -opus_int silk_setup_resamplers( +static opus_int silk_setup_resamplers( silk_encoder_state_Fxx *psEnc, /* I/O */ opus_int fs_kHz /* I */ ) { opus_int ret = SILK_NO_ERROR; - opus_int32 nSamples_temp; + SAVE_STACK; if( psEnc->sCmn.fs_kHz != fs_kHz || psEnc->sCmn.prev_API_fs_Hz != psEnc->sCmn.API_fs_Hz ) { @@ -149,48 +146,58 @@ opus_int silk_setup_resamplers( /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */ ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000, 1 ); } else { - /* Allocate worst case space for temporary upsampling, 8 to 48 kHz, so a factor 6 */ - opus_int16 x_buf_API_fs_Hz[ ( 2 * MAX_FRAME_LENGTH_MS + LA_SHAPE_MS ) * MAX_API_FS_KHZ ]; - silk_resampler_state_struct temp_resampler_state; + VARDECL( opus_int16, x_buf_API_fs_Hz ); + VARDECL( silk_resampler_state_struct, temp_resampler_state ); #ifdef FIXED_POINT opus_int16 *x_bufFIX = psEnc->x_buf; #else - opus_int16 x_bufFIX[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; + VARDECL( opus_int16, x_bufFIX ); + opus_int32 new_buf_samples; #endif + opus_int32 api_buf_samples; + opus_int32 old_buf_samples; + opus_int32 buf_length_ms; - nSamples_temp = silk_LSHIFT( psEnc->sCmn.frame_length, 1 ) + LA_SHAPE_MS * psEnc->sCmn.fs_kHz; + buf_length_ms = silk_LSHIFT( psEnc->sCmn.nb_subfr * 5, 1 ) + LA_SHAPE_MS; + old_buf_samples = buf_length_ms * psEnc->sCmn.fs_kHz; #ifndef FIXED_POINT - silk_float2short_array( x_bufFIX, psEnc->x_buf, nSamples_temp ); + new_buf_samples = buf_length_ms * fs_kHz; + ALLOC( x_bufFIX, silk_max( old_buf_samples, new_buf_samples ), + opus_int16 ); + silk_float2short_array( x_bufFIX, psEnc->x_buf, old_buf_samples ); #endif /* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */ - ret += silk_resampler_init( &temp_resampler_state, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz, 0 ); + ALLOC( temp_resampler_state, 1, silk_resampler_state_struct ); + ret += silk_resampler_init( temp_resampler_state, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz, 0 ); + + /* Calculate number of samples to temporarily upsample */ + api_buf_samples = buf_length_ms * silk_DIV32_16( psEnc->sCmn.API_fs_Hz, 1000 ); /* Temporary resampling of x_buf data to API_fs_Hz */ - ret += silk_resampler( &temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, nSamples_temp ); - - /* Calculate number of samples that has been temporarily upsampled */ - nSamples_temp = silk_DIV32_16( nSamples_temp * psEnc->sCmn.API_fs_Hz, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ) ); + ALLOC( x_buf_API_fs_Hz, api_buf_samples, opus_int16 ); + ret += silk_resampler( temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, old_buf_samples ); /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */ ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, silk_SMULBB( fs_kHz, 1000 ), 1 ); /* Correct resampler state by resampling buffered data from API_fs_Hz to fs_kHz */ - ret += silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, nSamples_temp ); + ret += silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, api_buf_samples ); #ifndef FIXED_POINT - silk_short2float_array( psEnc->x_buf, x_bufFIX, ( 2 * MAX_FRAME_LENGTH_MS + LA_SHAPE_MS ) * fs_kHz ); + silk_short2float_array( psEnc->x_buf, x_bufFIX, new_buf_samples); #endif } } psEnc->sCmn.prev_API_fs_Hz = psEnc->sCmn.API_fs_Hz; + RESTORE_STACK; return ret; } -opus_int silk_setup_fs( +static opus_int silk_setup_fs( silk_encoder_state_Fxx *psEnc, /* I/O */ opus_int fs_kHz, /* I */ opus_int PacketSize_ms /* I */ @@ -303,7 +310,7 @@ opus_int silk_setup_fs( return ret; } -opus_int silk_setup_complexity( +static opus_int silk_setup_complexity( silk_encoder_state *psEncC, /* I/O */ opus_int Complexity /* I */ ) @@ -407,7 +414,7 @@ static inline opus_int silk_setup_LBRR( if( TargetRate_bps > LBRR_rate_thres_bps ) { /* Set gain increase for coding LBRR excitation */ psEncC->LBRR_enabled = 1; - psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 ); + psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 ); } } diff --git a/media/libopus/silk/debug.c b/media/libopus/silk/debug.c index d6441e6ed626..9253faf71bfe 100644 --- a/media/libopus/silk/debug.c +++ b/media/libopus/silk/debug.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/debug.h b/media/libopus/silk/debug.h index 308b2b38e4ff..efb6d3e99e7f 100644 --- a/media/libopus/silk/debug.h +++ b/media/libopus/silk/debug.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -32,10 +28,6 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef SILK_DEBUG_H #define SILK_DEBUG_H -#ifdef _WIN32 -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif - #include "typedef.h" #include /* file writing */ #include /* strcpy, strcmp */ @@ -73,7 +65,6 @@ unsigned long GetHighResolutionTime(void); /* O time in usec*/ #if (defined(_WIN32) || defined(_WINCE)) #include /* timer */ -#pragma warning( disable : 4996 ) /* stop bitching about strcpy in TIC()*/ #else /* Linux or Mac*/ #include #endif @@ -273,9 +264,6 @@ extern int silk_debug_store_count; } \ } -/* micro sec */ -#define silk_GETTIME(void) time = (opus_int64) silk_GetHighResolutionTime(); - #else /* SILK_DEBUG */ /* define macros as empty strings */ diff --git a/media/libopus/silk/dec_API.c b/media/libopus/silk/dec_API.c index f639e4032eaf..bb0bc07784af 100644 --- a/media/libopus/silk/dec_API.c +++ b/media/libopus/silk/dec_API.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "API.h" #include "main.h" +#include "stack_alloc.h" /************************/ /* Decoder Super Struct */ @@ -72,6 +69,9 @@ opus_int silk_InitDecoder( /* O Returns error co for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) { ret = silk_init_decoder( &channel_state[ n ] ); } + silk_memset(&((silk_decoder *)decState)->sStereo, 0, sizeof(((silk_decoder *)decState)->sStereo)); + /* Not strictly needed, but it's cleaner that way */ + ((silk_decoder *)decState)->prev_decode_only_middle = 0; return ret; } @@ -89,14 +89,18 @@ opus_int silk_Decode( /* O Returns error co { opus_int i, n, decode_only_middle = 0, ret = SILK_NO_ERROR; opus_int32 nSamplesOutDec, LBRR_symbol; - opus_int16 samplesOut1_tmp[ 2 ][ MAX_FS_KHZ * MAX_FRAME_LENGTH_MS + 2 ]; - opus_int16 samplesOut2_tmp[ MAX_API_FS_KHZ * MAX_FRAME_LENGTH_MS ]; + opus_int16 *samplesOut1_tmp[ 2 ]; + VARDECL( opus_int16, samplesOut1_tmp_storage ); + VARDECL( opus_int16, samplesOut2_tmp ); opus_int32 MS_pred_Q13[ 2 ] = { 0 }; opus_int16 *resample_out_ptr; silk_decoder *psDec = ( silk_decoder * )decState; silk_decoder_state *channel_state = psDec->channel_state; opus_int has_side; opus_int stereo_to_mono; + SAVE_STACK; + + silk_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 ); /**********************************/ /* Test if first frame in payload */ @@ -136,11 +140,13 @@ opus_int silk_Decode( /* O Returns error co channel_state[ n ].nb_subfr = 4; } else { silk_assert( 0 ); + RESTORE_STACK; return SILK_DEC_INVALID_FRAME_SIZE; } fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1; if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) { silk_assert( 0 ); + RESTORE_STACK; return SILK_DEC_INVALID_SAMPLING_FREQUENCY; } ret += silk_decoder_set_fs( &channel_state[ n ], fs_kHz_dec, decControl->API_sampleRate ); @@ -155,8 +161,9 @@ opus_int silk_Decode( /* O Returns error co psDec->nChannelsAPI = decControl->nChannelsAPI; psDec->nChannelsInternal = decControl->nChannelsInternal; - if( decControl->API_sampleRate > MAX_API_FS_KHZ * 1000 || decControl->API_sampleRate < 8000 ) { + if( decControl->API_sampleRate > (opus_int32)MAX_API_FS_KHZ * 1000 || decControl->API_sampleRate < 8000 ) { ret = SILK_DEC_INVALID_SAMPLING_FREQUENCY; + RESTORE_STACK; return( ret ); } @@ -244,6 +251,14 @@ opus_int silk_Decode( /* O Returns error co psDec->channel_state[ 1 ].first_frame_after_reset = 1; } + ALLOC( samplesOut1_tmp_storage, + decControl->nChannelsInternal*( + channel_state[ 0 ].frame_length + 2 ), + opus_int16 ); + samplesOut1_tmp[ 0 ] = samplesOut1_tmp_storage; + samplesOut1_tmp[ 1 ] = samplesOut1_tmp_storage + + channel_state[ 0 ].frame_length + 2; + if( lostFlag == FLAG_DECODE_NORMAL ) { has_side = !decode_only_middle; } else { @@ -289,6 +304,8 @@ opus_int silk_Decode( /* O Returns error co *nSamplesOut = silk_DIV32( nSamplesOutDec * decControl->API_sampleRate, silk_SMULBB( channel_state[ 0 ].fs_kHz, 1000 ) ); /* Set up pointers to temp buffers */ + ALLOC( samplesOut2_tmp, + decControl->nChannelsAPI == 2 ? *nSamplesOut : 0, opus_int16 ); if( decControl->nChannelsAPI == 2 ) { resample_out_ptr = samplesOut2_tmp; } else { @@ -341,9 +358,11 @@ opus_int silk_Decode( /* O Returns error co } else { psDec->prev_decode_only_middle = decode_only_middle; } + RESTORE_STACK; return ret; } +#if 0 /* Getting table of contents for a packet */ opus_int silk_get_TOC( const opus_uint8 *payload, /* I Payload data */ @@ -375,3 +394,4 @@ opus_int silk_get_TOC( return ret; } +#endif diff --git a/media/libopus/silk/decode_core.c b/media/libopus/silk/decode_core.c index 944e49497e09..a820bf11d6a7 100644 --- a/media/libopus/silk/decode_core.c +++ b/media/libopus/silk/decode_core.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main.h" +#include "stack_alloc.h" /**********************************************************/ /* Core decoder. Performs inverse NSQ operation LTP + LPC */ @@ -47,15 +44,21 @@ void silk_decode_core( { opus_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType; opus_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ]; - opus_int16 sLTP[ MAX_FRAME_LENGTH ]; - opus_int32 sLTP_Q15[ 2 * MAX_FRAME_LENGTH ]; + VARDECL( opus_int16, sLTP ); + VARDECL( opus_int32, sLTP_Q15 ); opus_int32 LTP_pred_Q13, LPC_pred_Q10, Gain_Q10, inv_gain_Q31, gain_adj_Q16, rand_seed, offset_Q10; opus_int32 *pred_lag_ptr, *pexc_Q14, *pres_Q14; - opus_int32 res_Q14[ MAX_SUB_FRAME_LENGTH ]; - opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ]; + VARDECL( opus_int32, res_Q14 ); + VARDECL( opus_int32, sLPC_Q14 ); + SAVE_STACK; silk_assert( psDec->prev_gain_Q16 != 0 ); + ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 ); + ALLOC( sLTP_Q15, psDec->ltp_mem_length + psDec->frame_length, opus_int32 ); + ALLOC( res_Q14, psDec->subfr_length, opus_int32 ); + ALLOC( sLPC_Q14, psDec->subfr_length + MAX_LPC_ORDER, opus_int32 ); + offset_Q10 = silk_Quantization_Offsets_Q10[ psDec->indices.signalType >> 1 ][ psDec->indices.quantOffsetType ]; if( psDec->indices.NLSFInterpCoef_Q2 < 1 << 2 ) { @@ -111,7 +114,7 @@ void silk_decode_core( sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, sLPC_Q14[ i ] ); } } else { - gain_adj_Q16 = 1 << 16; + gain_adj_Q16 = (opus_int32)1 << 16; } /* Save inv_gain */ @@ -156,7 +159,7 @@ void silk_decode_core( } } else { /* Update LTP state when Gain changes */ - if( gain_adj_Q16 != 1 << 16 ) { + if( gain_adj_Q16 != (opus_int32)1 << 16 ) { for( i = 0; i < lag + LTP_ORDER/2; i++ ) { sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ sLTP_buf_idx - i - 1 ] ); } @@ -231,4 +234,5 @@ void silk_decode_core( /* Save LPC state */ silk_memcpy( psDec->sLPC_Q14_buf, sLPC_Q14, MAX_LPC_ORDER * sizeof( opus_int32 ) ); + RESTORE_STACK; } diff --git a/media/libopus/silk/decode_frame.c b/media/libopus/silk/decode_frame.c index bad1396e735e..abc00a3d545c 100644 --- a/media/libopus/silk/decode_frame.c +++ b/media/libopus/silk/decode_frame.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main.h" +#include "stack_alloc.h" #include "PLC.h" /****************/ @@ -48,12 +45,16 @@ opus_int silk_decode_frame( opus_int condCoding /* I The type of conditional coding to use */ ) { - silk_decoder_control sDecCtrl; + VARDECL( silk_decoder_control, psDecCtrl ); opus_int L, mv_len, ret = 0; - opus_int pulses[ MAX_FRAME_LENGTH ]; + VARDECL( opus_int, pulses ); + SAVE_STACK; L = psDec->frame_length; - sDecCtrl.LTP_scale_Q14 = 0; + ALLOC( psDecCtrl, 1, silk_decoder_control ); + ALLOC( pulses, (L + SHELL_CODEC_FRAME_LENGTH - 1) & + ~(SHELL_CODEC_FRAME_LENGTH - 1), opus_int ); + psDecCtrl->LTP_scale_Q14 = 0; /* Safety checks */ silk_assert( L > 0 && L <= MAX_FRAME_LENGTH ); @@ -75,20 +76,17 @@ opus_int silk_decode_frame( /********************************************/ /* Decode parameters and pulse signal */ /********************************************/ - silk_decode_parameters( psDec, &sDecCtrl, condCoding ); - - /* Update length. Sampling frequency may have changed */ - L = psDec->frame_length; + silk_decode_parameters( psDec, psDecCtrl, condCoding ); /********************************************************/ /* Run inverse NSQ */ /********************************************************/ - silk_decode_core( psDec, &sDecCtrl, pOut, pulses ); + silk_decode_core( psDec, psDecCtrl, pOut, pulses ); /********************************************************/ /* Update PLC state */ /********************************************************/ - silk_PLC( psDec, &sDecCtrl, pOut, 0 ); + silk_PLC( psDec, psDecCtrl, pOut, 0 ); psDec->lossCnt = 0; psDec->prevSignalType = psDec->indices.signalType; @@ -98,7 +96,7 @@ opus_int silk_decode_frame( psDec->first_frame_after_reset = 0; } else { /* Handle packet loss by extrapolation */ - silk_PLC( psDec, &sDecCtrl, pOut, 1 ); + silk_PLC( psDec, psDecCtrl, pOut, 1 ); } /*************************/ @@ -117,13 +115,14 @@ opus_int silk_decode_frame( /************************************************/ /* Comfort noise generation / estimation */ /************************************************/ - silk_CNG( psDec, &sDecCtrl, pOut, L ); + silk_CNG( psDec, psDecCtrl, pOut, L ); /* Update some decoder state variables */ - psDec->lagPrev = sDecCtrl.pitchL[ psDec->nb_subfr - 1 ]; + psDec->lagPrev = psDecCtrl->pitchL[ psDec->nb_subfr - 1 ]; /* Set output frame length */ *pN = L; + RESTORE_STACK; return ret; } diff --git a/media/libopus/silk/decode_indices.c b/media/libopus/silk/decode_indices.c index 7c30db81ca85..7afe5c26c192 100644 --- a/media/libopus/silk/decode_indices.c +++ b/media/libopus/silk/decode_indices.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/decode_parameters.c b/media/libopus/silk/decode_parameters.c index 948723f13c51..e345b1dcefb9 100644 --- a/media/libopus/silk/decode_parameters.c +++ b/media/libopus/silk/decode_parameters.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/decode_pitch.c b/media/libopus/silk/decode_pitch.c index 3019871c6a2e..fedbc6a52557 100644 --- a/media/libopus/silk/decode_pitch.c +++ b/media/libopus/silk/decode_pitch.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/decode_pulses.c b/media/libopus/silk/decode_pulses.c index c4c529674b66..e8a87c2ab750 100644 --- a/media/libopus/silk/decode_pulses.c +++ b/media/libopus/silk/decode_pulses.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/decoder_set_fs.c b/media/libopus/silk/decoder_set_fs.c index 317a6d2abb5c..eef0fd25e183 100644 --- a/media/libopus/silk/decoder_set_fs.c +++ b/media/libopus/silk/decoder_set_fs.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -39,7 +35,7 @@ POSSIBILITY OF SUCH DAMAGE. opus_int silk_decoder_set_fs( silk_decoder_state *psDec, /* I/O Decoder state pointer */ opus_int fs_kHz, /* I Sampling frequency (kHz) */ - opus_int fs_API_Hz /* I API Sampling frequency (Hz) */ + opus_int32 fs_API_Hz /* I API Sampling frequency (Hz) */ ) { opus_int frame_length, ret = 0; diff --git a/media/libopus/silk/define.h b/media/libopus/silk/define.h index 4944a3b97469..c47aca9f58fd 100644 --- a/media/libopus/silk/define.h +++ b/media/libopus/silk/define.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -183,11 +179,6 @@ extern "C" # define NSQ_LPC_BUF_LENGTH DECISION_DELAY #endif -/***********************/ -/* High pass filtering */ -/***********************/ -#define HIGH_PASS_INPUT 1 - /***************************/ /* Voice activity detector */ /***************************/ diff --git a/media/libopus/silk/enc_API.c b/media/libopus/silk/enc_API.c index cbf025a7f152..44b9ab3591ab 100644 --- a/media/libopus/silk/enc_API.c +++ b/media/libopus/silk/enc_API.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -36,6 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "API.h" #include "control.h" #include "typedef.h" +#include "stack_alloc.h" #include "structs.h" #include "tuning_parameters.h" #ifdef FIXED_POINT @@ -44,6 +41,14 @@ POSSIBILITY OF SUCH DAMAGE. #include "main_FLP.h" #endif +/***************************************/ +/* Read control structure from encoder */ +/***************************************/ +static opus_int silk_QueryEncoder( /* O Returns error code */ + const void *encState, /* I State */ + silk_EncControlStruct *encStatus /* O Encoder Status */ +); + /****************************************/ /* Encoder functions */ /****************************************/ @@ -94,7 +99,7 @@ opus_int silk_InitEncoder( /* O Returns error co /***************************************/ /* Read control structure from encoder */ /***************************************/ -opus_int silk_QueryEncoder( /* O Returns error code */ +static opus_int silk_QueryEncoder( /* O Returns error code */ const void *encState, /* I State */ silk_EncControlStruct *encStatus /* O Encoder Status */ ) @@ -137,23 +142,26 @@ opus_int silk_Encode( /* O Returns error co const opus_int16 *samplesIn, /* I Speech sample input vector */ opus_int nSamplesIn, /* I Number of samples in input vector */ ec_enc *psRangeEnc, /* I/O Compressor data structure */ - opus_int *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ + opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ const opus_int prefillFlag /* I Flag to indicate prefilling buffers no coding */ ) { opus_int n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0; - opus_int nSamplesToBuffer, nBlocksOf10ms, nSamplesFromInput = 0; + opus_int nSamplesToBuffer, nSamplesToBufferMax, nBlocksOf10ms; + opus_int nSamplesFromInput = 0, nSamplesFromInputMax; opus_int speech_act_thr_for_switch_Q8; opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol, sum; silk_encoder *psEnc = ( silk_encoder * )encState; - opus_int16 buf[ MAX_FRAME_LENGTH_MS * MAX_API_FS_KHZ ]; + VARDECL( opus_int16, buf ); opus_int transition, curr_block, tot_blocks; + SAVE_STACK; psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0; /* Check values in encoder control structure */ if( ( ret = check_control_input( encControl ) != 0 ) ) { silk_assert( 0 ); + RESTORE_STACK; return ret; } @@ -187,9 +195,9 @@ opus_int silk_Encode( /* O Returns error co if( prefillFlag ) { /* Only accept input length of 10 ms */ if( nBlocksOf10ms != 1 ) { - ret = SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; silk_assert( 0 ); - return ret; + RESTORE_STACK; + return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; } /* Reset Encoder */ for( n = 0; n < encControl->nChannelsInternal; n++ ) { @@ -208,15 +216,15 @@ opus_int silk_Encode( /* O Returns error co } else { /* Only accept input lengths that are a multiple of 10 ms */ if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) { - ret = SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; silk_assert( 0 ); - return ret; + RESTORE_STACK; + return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; } /* Make sure no more than one packet can be produced */ if( 1000 * (opus_int32)nSamplesIn > encControl->payloadSize_ms * encControl->API_sampleRate ) { - ret = SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; silk_assert( 0 ); - return ret; + RESTORE_STACK; + return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; } } @@ -226,6 +234,7 @@ opus_int silk_Encode( /* O Returns error co opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0; if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, TargetRate_bps, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) { silk_assert( 0 ); + RESTORE_STACK; return ret; } if( psEnc->state_Fxx[n].sCmn.first_frame_after_reset || transition ) { @@ -238,9 +247,16 @@ opus_int silk_Encode( /* O Returns error co silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz ); /* Input buffering/resampling and encoding */ + nSamplesToBufferMax = + 10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz; + nSamplesFromInputMax = + silk_DIV32_16( nSamplesToBufferMax * + psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, + psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 ); + ALLOC( buf, nSamplesFromInputMax, opus_int16 ); while( 1 ) { nSamplesToBuffer = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx; - nSamplesToBuffer = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz ); + nSamplesToBuffer = silk_min( nSamplesToBuffer, nSamplesToBufferMax ); nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 ); /* Resample and write to buffer */ if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) { @@ -529,6 +545,7 @@ opus_int silk_Encode( /* O Returns error co } } + RESTORE_STACK; return ret; } diff --git a/media/libopus/silk/encode_indices.c b/media/libopus/silk/encode_indices.c index 03c32b48fe81..666c8c0b13e4 100644 --- a/media/libopus/silk/encode_indices.c +++ b/media/libopus/silk/encode_indices.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/encode_pulses.c b/media/libopus/silk/encode_pulses.c index cd46be0013c4..d1b2f5dc5422 100644 --- a/media/libopus/silk/encode_pulses.c +++ b/media/libopus/silk/encode_pulses.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main.h" +#include "stack_alloc.h" /*********************************************/ /* Encode quantization indices of excitation */ @@ -70,14 +67,15 @@ void silk_encode_pulses( { opus_int i, k, j, iter, bit, nLS, scale_down, RateLevelIndex = 0; opus_int32 abs_q, minSumBits_Q5, sumBits_Q5; - opus_int abs_pulses[ MAX_FRAME_LENGTH ]; - opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ]; - opus_int nRshifts[ MAX_NB_SHELL_BLOCKS ]; + VARDECL( opus_int, abs_pulses ); + VARDECL( opus_int, sum_pulses ); + VARDECL( opus_int, nRshifts ); opus_int pulses_comb[ 8 ]; opus_int *abs_pulses_ptr; const opus_int8 *pulses_ptr; const opus_uint8 *cdf_ptr; const opus_uint8 *nBits_ptr; + SAVE_STACK; silk_memset( pulses_comb, 0, 8 * sizeof( opus_int ) ); /* Fixing Valgrind reported problem*/ @@ -94,6 +92,8 @@ void silk_encode_pulses( } /* Take the absolute value of the pulses */ + ALLOC( abs_pulses, iter * SHELL_CODEC_FRAME_LENGTH, opus_int ); + silk_assert( !( SHELL_CODEC_FRAME_LENGTH & 3 ) ); for( i = 0; i < iter * SHELL_CODEC_FRAME_LENGTH; i+=4 ) { abs_pulses[i+0] = ( opus_int )silk_abs( pulses[ i + 0 ] ); abs_pulses[i+1] = ( opus_int )silk_abs( pulses[ i + 1 ] ); @@ -102,6 +102,8 @@ void silk_encode_pulses( } /* Calc sum pulses per shell code frame */ + ALLOC( sum_pulses, iter, opus_int ); + ALLOC( nRshifts, iter, opus_int ); abs_pulses_ptr = abs_pulses; for( i = 0; i < iter; i++ ) { nRshifts[ i ] = 0; @@ -200,4 +202,5 @@ void silk_encode_pulses( /* Encode signs */ /****************/ silk_encode_signs( psRangeEnc, pulses, frame_length, signalType, quantOffsetType, sum_pulses ); + RESTORE_STACK; } diff --git a/media/libopus/silk/errors.h b/media/libopus/silk/errors.h index 0e2488319636..45070800f212 100644 --- a/media/libopus/silk/errors.h +++ b/media/libopus/silk/errors.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/fixed/LTP_analysis_filter_FIX.c b/media/libopus/silk/fixed/LTP_analysis_filter_FIX.c index 8d90d59077b2..a94190808e90 100644 --- a/media/libopus/silk/fixed/LTP_analysis_filter_FIX.c +++ b/media/libopus/silk/fixed/LTP_analysis_filter_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -37,13 +33,13 @@ POSSIBILITY OF SUCH DAMAGE. void silk_LTP_analysis_filter_FIX( opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */ - const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceeding samples */ + const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */ const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */ const opus_int subfr_length, /* I Length of each subframe */ const opus_int nb_subfr, /* I Number of subframes */ - const opus_int pre_length /* I Length of the preceeding samples starting at &x[0] for each subframe */ + const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */ ) { const opus_int16 *x_ptr, *x_lag_ptr; diff --git a/media/libopus/silk/fixed/LTP_scale_ctrl_FIX.c b/media/libopus/silk/fixed/LTP_scale_ctrl_FIX.c index 3d474aeef682..3dcedef89189 100644 --- a/media/libopus/silk/fixed/LTP_scale_ctrl_FIX.c +++ b/media/libopus/silk/fixed/LTP_scale_ctrl_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/fixed/apply_sine_window_FIX.c b/media/libopus/silk/fixed/apply_sine_window_FIX.c index 51c679283c33..4502b7130e97 100644 --- a/media/libopus/silk/fixed/apply_sine_window_FIX.c +++ b/media/libopus/silk/fixed/apply_sine_window_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -45,7 +41,7 @@ POSSIBILITY OF SUCH DAMAGE. /* Matlab code for table: for k=16:9*4:16+2*9*4, fprintf(' %7.d,', -round(65536*pi ./ (k:4:k+8*4))); fprintf('\n'); end */ -static opus_int16 freq_table_Q16[ 27 ] = { +static const opus_int16 freq_table_Q16[ 27 ] = { 12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202, 3885, 3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422, 2313, 2214, 2123, 2038, 1961, 1889, 1822, 1760, 1702, @@ -73,7 +69,7 @@ void silk_apply_sine_window( f_Q16 = (opus_int)freq_table_Q16[ k ]; /* Factor used for cosine approximation */ - c_Q16 = silk_SMULWB( f_Q16, -f_Q16 ); + c_Q16 = silk_SMULWB( (opus_int32)f_Q16, -f_Q16 ); silk_assert( c_Q16 >= -32768 ); /* initialize state */ @@ -84,9 +80,9 @@ void silk_apply_sine_window( S1_Q16 = f_Q16 + silk_RSHIFT( length, 3 ); } else { /* start from 1 */ - S0_Q16 = ( 1 << 16 ); + S0_Q16 = ( (opus_int32)1 << 16 ); /* approximation of cos(f) */ - S1_Q16 = ( 1 << 16 ) + silk_RSHIFT( c_Q16, 1 ) + silk_RSHIFT( length, 4 ); + S1_Q16 = ( (opus_int32)1 << 16 ) + silk_RSHIFT( c_Q16, 1 ) + silk_RSHIFT( length, 4 ); } /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */ @@ -95,11 +91,11 @@ void silk_apply_sine_window( px_win[ k ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] ); px_win[ k + 1 ] = (opus_int16)silk_SMULWB( S1_Q16, px[ k + 1] ); S0_Q16 = silk_SMULWB( S1_Q16, c_Q16 ) + silk_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1; - S0_Q16 = silk_min( S0_Q16, ( 1 << 16 ) ); + S0_Q16 = silk_min( S0_Q16, ( (opus_int32)1 << 16 ) ); px_win[ k + 2 ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] ); px_win[ k + 3 ] = (opus_int16)silk_SMULWB( S0_Q16, px[ k + 3 ] ); S1_Q16 = silk_SMULWB( S0_Q16, c_Q16 ) + silk_LSHIFT( S0_Q16, 1 ) - S1_Q16; - S1_Q16 = silk_min( S1_Q16, ( 1 << 16 ) ); + S1_Q16 = silk_min( S1_Q16, ( (opus_int32)1 << 16 ) ); } } diff --git a/media/libopus/silk/fixed/autocorr_FIX.c b/media/libopus/silk/fixed/autocorr_FIX.c index d3fb49bf799c..dec3cc0bf48a 100644 --- a/media/libopus/silk/fixed/autocorr_FIX.c +++ b/media/libopus/silk/fixed/autocorr_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "SigProc_FIX.h" +#include "celt_lpc.h" /* Compute autocorrelation */ void silk_autocorr( @@ -44,37 +41,7 @@ void silk_autocorr( const opus_int correlationCount /* I Number of correlation taps to compute */ ) { - opus_int i, lz, nRightShifts, corrCount; - opus_int64 corr64; - + opus_int corrCount; corrCount = silk_min_int( inputDataSize, correlationCount ); - - /* compute energy (zero-lag correlation) */ - corr64 = silk_inner_prod16_aligned_64( inputData, inputData, inputDataSize ); - - /* deal with all-zero input data */ - corr64 += 1; - - /* number of leading zeros */ - lz = silk_CLZ64( corr64 ); - - /* scaling: number of right shifts applied to correlations */ - nRightShifts = 35 - lz; - *scale = nRightShifts; - - if( nRightShifts <= 0 ) { - results[ 0 ] = silk_LSHIFT( (opus_int32)silk_CHECK_FIT32( corr64 ), -nRightShifts ); - - /* compute remaining correlations based on int32 inner product */ - for( i = 1; i < corrCount; i++ ) { - results[ i ] = silk_LSHIFT( silk_inner_prod_aligned( inputData, inputData + i, inputDataSize - i ), -nRightShifts ); - } - } else { - results[ 0 ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr64, nRightShifts ) ); - - /* compute remaining correlations based on int64 inner product */ - for( i = 1; i < corrCount; i++ ) { - results[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( silk_inner_prod16_aligned_64( inputData, inputData + i, inputDataSize - i ), nRightShifts ) ); - } - } + *scale = _celt_autocorr(inputData, results, NULL, 0, corrCount-1, inputDataSize); } diff --git a/media/libopus/silk/fixed/burg_modified_FIX.c b/media/libopus/silk/fixed/burg_modified_FIX.c index d17a3dff03c5..f5112b64195a 100644 --- a/media/libopus/silk/fixed/burg_modified_FIX.c +++ b/media/libopus/silk/fixed/burg_modified_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -36,6 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "SigProc_FIX.h" #include "define.h" #include "tuning_parameters.h" +#include "pitch.h" #define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */ @@ -51,7 +48,7 @@ void silk_burg_modified( opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ - const opus_int subfr_length, /* I Input signal subframe length (incl. D preceeding samples) */ + const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ const opus_int nb_subfr, /* I Number of subframes stacked in x */ const opus_int D /* I Order */ ) @@ -64,6 +61,7 @@ void silk_burg_modified( opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ]; opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ]; opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ]; + opus_int32 xcorr[ SILK_MAX_ORDER_LPC ]; silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); @@ -97,10 +95,17 @@ void silk_burg_modified( } } else { for( s = 0; s < nb_subfr; s++ ) { + int i; + opus_int32 d; x_ptr = x + s * subfr_length; + celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D ); for( n = 1; n < D + 1; n++ ) { - C_first_row[ n - 1 ] += silk_LSHIFT32( - silk_inner_prod_aligned( x_ptr, x_ptr + n, subfr_length - n ), -rshifts ); + for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ ) + d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] ); + xcorr[ n - 1 ] += d; + } + for( n = 1; n < D + 1; n++ ) { + C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts ); } } } @@ -109,7 +114,7 @@ void silk_burg_modified( /* Initialize */ CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */ - invGain_Q30 = 1 << 30; + invGain_Q30 = (opus_int32)1 << 30; reached_max_gain = 0; for( n = 0; n < D; n++ ) { /* Update first row of correlation matrix (without first element) */ @@ -196,7 +201,7 @@ void silk_burg_modified( tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 ); if( tmp1 <= minInvGain_Q30 ) { /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */ - tmp2 = ( 1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */ + tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */ rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */ /* Newton-Raphson iteration */ rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */ @@ -242,7 +247,7 @@ void silk_burg_modified( /* Scale coefficients */ A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); } - /* Subtract energy of preceeding samples from C0 */ + /* Subtract energy of preceding samples from C0 */ if( rshifts > 0 ) { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; @@ -260,14 +265,14 @@ void silk_burg_modified( } else { /* Return residual energy */ nrg = CAf[ 0 ]; /* Q( -rshifts ) */ - tmp1 = 1 << 16; /* Q16 */ + tmp1 = (opus_int32)1 << 16; /* Q16 */ for( k = 0; k < D; k++ ) { Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16 */ nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts ) */ tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16 */ A_Q16[ k ] = -Atmp1; } - *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( FIND_LPC_COND_FAC, C0 ), -tmp1 ); /* Q( -rshifts ) */ + *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */ *res_nrg_Q = -rshifts; } } diff --git a/media/libopus/silk/fixed/corrMatrix_FIX.c b/media/libopus/silk/fixed/corrMatrix_FIX.c index cad4bac93ef3..c61727053699 100644 --- a/media/libopus/silk/fixed/corrMatrix_FIX.c +++ b/media/libopus/silk/fixed/corrMatrix_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/fixed/encode_frame_FIX.c b/media/libopus/silk/fixed/encode_frame_FIX.c index fc1d82fd28b0..cacfd67e742a 100644 --- a/media/libopus/silk/fixed/encode_frame_FIX.c +++ b/media/libopus/silk/fixed/encode_frame_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main_FIX.h" +#include "stack_alloc.h" #include "tuning_parameters.h" /* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */ @@ -88,9 +85,7 @@ opus_int silk_encode_frame_FIX( { silk_encoder_control_FIX sEncCtrl; opus_int i, iter, maxIter, found_upper, found_lower, ret = 0; - opus_int16 *x_frame, *res_pitch_frame; - opus_int32 xfw_Q3[ MAX_FRAME_LENGTH ]; - opus_int16 res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ]; + opus_int16 *x_frame; ec_enc sRangeEnc_copy, sRangeEnc_copy2; silk_nsq_state sNSQ_copy, sNSQ_copy2; opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; @@ -99,7 +94,7 @@ opus_int silk_encode_frame_FIX( opus_int16 ec_prevLagIndex_copy; opus_int ec_prevSignalType_copy; opus_int8 LastGainIndex_copy2; - opus_uint8 ec_buf_copy[ 1275 ]; + SAVE_STACK; /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */ LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0; @@ -109,9 +104,8 @@ opus_int silk_encode_frame_FIX( /**************************************************************/ /* Set up Input Pointers, and insert frame in input buffer */ /*************************************************************/ - /* pointers aligned with start of frame to encode */ - x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */ - res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */ + /* start of frame to encode */ + x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /***************************************/ /* Ensure smooth bandwidth transitions */ @@ -124,6 +118,17 @@ opus_int silk_encode_frame_FIX( silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) ); if( !psEnc->sCmn.prefillFlag ) { + VARDECL( opus_int32, xfw_Q3 ); + VARDECL( opus_int16, res_pitch ); + VARDECL( opus_uint8, ec_buf_copy ); + opus_int16 *res_pitch_frame; + + ALLOC( res_pitch, + psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + + psEnc->sCmn.ltp_mem_length, opus_int16 ); + /* start of pitch LPC residual frame */ + res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; + /*****************************************/ /* Find pitch lags, initial LPC analysis */ /*****************************************/ @@ -147,6 +152,7 @@ opus_int silk_encode_frame_FIX( /*****************************************/ /* Prefiltering for noise shaper */ /*****************************************/ + ALLOC( xfw_Q3, psEnc->sCmn.frame_length, opus_int32 ); silk_prefilter_FIX( psEnc, &sEncCtrl, xfw_Q3, x_frame ); /****************************************/ @@ -168,6 +174,7 @@ opus_int silk_encode_frame_FIX( seed_copy = psEnc->sCmn.indices.Seed; ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; + ALLOC( ec_buf_copy, 1275, opus_uint8 ); for( iter = 0; ; iter++ ) { if( gainsID == gainsID_lower ) { nBits = nBits_lower; @@ -280,7 +287,7 @@ opus_int silk_encode_frame_FIX( for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 ); } - + /* Quantize gains */ psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16, @@ -303,6 +310,7 @@ opus_int silk_encode_frame_FIX( if( psEnc->sCmn.prefillFlag ) { /* No payload */ *pnBytesOut = 0; + RESTORE_STACK; return ret; } @@ -313,6 +321,7 @@ opus_int silk_encode_frame_FIX( /* Payload size */ *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); + RESTORE_STACK; return ret; } diff --git a/media/libopus/silk/fixed/find_LPC_FIX.c b/media/libopus/silk/fixed/find_LPC_FIX.c index 3fadbe7f37a0..70cefb6be8bd 100644 --- a/media/libopus/silk/fixed/find_LPC_FIX.c +++ b/media/libopus/silk/fixed/find_LPC_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main_FIX.h" +#include "stack_alloc.h" #include "tuning_parameters.h" /* Finds LPC vector from correlations, and converts to NLSF */ @@ -55,7 +52,7 @@ void silk_find_LPC_FIX( opus_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q; opus_int16 a_tmp_Q12[ MAX_LPC_ORDER ]; opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ]; - opus_int16 LPC_res[ MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ]; + SAVE_STACK; subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder; @@ -66,6 +63,8 @@ void silk_find_LPC_FIX( silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, minInvGain_Q30, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder ); if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) { + VARDECL( opus_int16, LPC_res ); + /* Optimal solution for last 10 ms */ silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + 2 * subfr_length, minInvGain_Q30, subfr_length, 2, psEncC->predictLPCOrder ); @@ -85,6 +84,8 @@ void silk_find_LPC_FIX( /* Convert to NLSFs */ silk_A2NLSF( NLSF_Q15, a_tmp_Q16, psEncC->predictLPCOrder ); + ALLOC( LPC_res, 2 * subfr_length, opus_int16 ); + /* Search over interpolation indices to find the one with lowest residual energy */ for( k = 3; k >= 0; k-- ) { /* Interpolate NLSFs for first half */ @@ -146,4 +147,5 @@ void silk_find_LPC_FIX( } silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) ); + RESTORE_STACK; } diff --git a/media/libopus/silk/fixed/find_LTP_FIX.c b/media/libopus/silk/fixed/find_LTP_FIX.c index 465f5a4f09e0..8c4d70376cb8 100644 --- a/media/libopus/silk/fixed/find_LTP_FIX.c +++ b/media/libopus/silk/fixed/find_LTP_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -114,7 +110,7 @@ void silk_find_LTP_FIX( /* temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); */ extra_shifts = silk_min_int( corr_rshifts[ k ], LTP_CORRS_HEAD_ROOM ); denom32 = silk_LSHIFT_SAT32( silk_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 + extra_shifts ) + /* Q( -corr_rshifts[ k ] + extra_shifts ) */ - silk_RSHIFT( silk_SMULWB( subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts ); /* Q( -corr_rshifts[ k ] + extra_shifts ) */ + silk_RSHIFT( silk_SMULWB( (opus_int32)subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts ); /* Q( -corr_rshifts[ k ] + extra_shifts ) */ denom32 = silk_max( denom32, 1 ); silk_assert( ((opus_int64)Wght_Q15[ k ] << 16 ) < silk_int32_MAX ); /* Wght always < 0.5 in Q0 */ temp32 = silk_DIV32( silk_LSHIFT( (opus_int32)Wght_Q15[ k ], 16 ), denom32 ); /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */ diff --git a/media/libopus/silk/fixed/find_pitch_lags_FIX.c b/media/libopus/silk/fixed/find_pitch_lags_FIX.c index b8e8f161406e..f60b43641564 100644 --- a/media/libopus/silk/fixed/find_pitch_lags_FIX.c +++ b/media/libopus/silk/fixed/find_pitch_lags_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main_FIX.h" +#include "stack_alloc.h" #include "tuning_parameters.h" /* Find pitch lags */ @@ -45,20 +42,22 @@ void silk_find_pitch_lags_FIX( ) { opus_int buf_len, i, scale; - opus_int32 thrhld_Q15, res_nrg; + opus_int32 thrhld_Q13, res_nrg; const opus_int16 *x_buf, *x_buf_ptr; - opus_int16 Wsig[ FIND_PITCH_LPC_WIN_MAX ], *Wsig_ptr; + VARDECL( opus_int16, Wsig ); + opus_int16 *Wsig_ptr; opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; opus_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ]; opus_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ]; opus_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ]; + SAVE_STACK; /******************************************/ /* Set up buffer lengths etc based on Fs */ /******************************************/ buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; - /* Safty check */ + /* Safety check */ silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); x_buf = x - psEnc->sCmn.ltp_mem_length; @@ -69,6 +68,8 @@ void silk_find_pitch_lags_FIX( /* Calculate windowed signal */ + ALLOC( Wsig, psEnc->sCmn.pitch_LPC_win_length, opus_int16 ); + /* First LA_LTP samples */ x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length; Wsig_ptr = Wsig; @@ -105,7 +106,7 @@ void silk_find_pitch_lags_FIX( } /* Do BWE */ - silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWITH_EXPANSION, 16 ) ); + silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWIDTH_EXPANSION, 16 ) ); /*****************************************/ /* LPC analysis filtering */ @@ -114,19 +115,19 @@ void silk_find_pitch_lags_FIX( if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) { /* Threshold for pitch estimator */ - thrhld_Q15 = SILK_FIX_CONST( 0.6, 15 ); - thrhld_Q15 = silk_SMLABB( thrhld_Q15, SILK_FIX_CONST( -0.004, 15 ), psEnc->sCmn.pitchEstimationLPCOrder ); - thrhld_Q15 = silk_SMLABB( thrhld_Q15, SILK_FIX_CONST( -0.1, 7 ), psEnc->sCmn.speech_activity_Q8 ); - thrhld_Q15 = silk_SMLABB( thrhld_Q15, SILK_FIX_CONST( -0.15, 15 ), silk_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) ); - thrhld_Q15 = silk_SMLAWB( thrhld_Q15, SILK_FIX_CONST( -0.1, 16 ), psEnc->sCmn.input_tilt_Q15 ); - thrhld_Q15 = silk_SAT16( thrhld_Q15 ); + thrhld_Q13 = SILK_FIX_CONST( 0.6, 13 ); + thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.004, 13 ), psEnc->sCmn.pitchEstimationLPCOrder ); + thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 21 ), psEnc->sCmn.speech_activity_Q8 ); + thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.15, 13 ), silk_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) ); + thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 14 ), psEnc->sCmn.input_tilt_Q15 ); + thrhld_Q13 = silk_SAT16( thrhld_Q13 ); /*****************************************/ /* Call pitch estimator */ /*****************************************/ if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex, &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16, - (opus_int16)thrhld_Q15, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr ) == 0 ) + (opus_int)thrhld_Q13, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr ) == 0 ) { psEnc->sCmn.indices.signalType = TYPE_VOICED; } else { @@ -138,4 +139,5 @@ void silk_find_pitch_lags_FIX( psEnc->sCmn.indices.contourIndex = 0; psEnc->LTPCorr_Q15 = 0; } + RESTORE_STACK; } diff --git a/media/libopus/silk/fixed/find_pred_coefs_FIX.c b/media/libopus/silk/fixed/find_pred_coefs_FIX.c index a023c45742bc..70d0279a1d3d 100644 --- a/media/libopus/silk/fixed/find_pred_coefs_FIX.c +++ b/media/libopus/silk/fixed/find_pred_coefs_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main_FIX.h" +#include "stack_alloc.h" void silk_find_pred_coefs_FIX( silk_encoder_state_FIX *psEnc, /* I/O encoder state */ @@ -44,13 +41,14 @@ void silk_find_pred_coefs_FIX( ) { opus_int i; - opus_int32 WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ]; opus_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ], Wght_Q15[ MAX_NB_SUBFR ]; opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]; const opus_int16 *x_ptr; - opus_int16 *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ]; + opus_int16 *x_pre_ptr; + VARDECL( opus_int16, LPC_in_pre ); opus_int32 tmp, min_gain_Q16, minInvGain_Q30; opus_int LTP_corrs_rshift[ MAX_NB_SUBFR ]; + SAVE_STACK; /* weighting for weighted least squares */ min_gain_Q16 = silk_int32_MAX >> 6; @@ -72,15 +70,22 @@ void silk_find_pred_coefs_FIX( Wght_Q15[ i ] = silk_RSHIFT( tmp, 1 ); /* Invert the inverted and normalized gains */ - local_gains[ i ] = silk_DIV32( ( 1 << 16 ), invGains_Q16[ i ] ); + local_gains[ i ] = silk_DIV32( ( (opus_int32)1 << 16 ), invGains_Q16[ i ] ); } + ALLOC( LPC_in_pre, + psEnc->sCmn.nb_subfr * psEnc->sCmn.predictLPCOrder + + psEnc->sCmn.frame_length, opus_int16 ); if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + VARDECL( opus_int32, WLTP ); + /**********/ /* VOICED */ /**********/ silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 ); + ALLOC( WLTP, psEnc->sCmn.nb_subfr * LTP_ORDER * LTP_ORDER, opus_int32 ); + /* LTP analysis */ silk_find_LTP_FIX( psEncCtrl->LTPCoef_Q14, WLTP, &psEncCtrl->LTPredCodGain_Q7, res_pitch, psEncCtrl->pitchL, Wght_Q15, psEnc->sCmn.subfr_length, @@ -118,10 +123,10 @@ void silk_find_pred_coefs_FIX( /* Limit on total predictive coding gain */ if( psEnc->sCmn.first_frame_after_reset ) { minInvGain_Q30 = SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET, 30 ); - } else { - minInvGain_Q30 = silk_log2lin( silk_SMLAWB( 16 << 7, psEncCtrl->LTPredCodGain_Q7, SILK_FIX_CONST( 1.0 / 3, 16 ) ) ); /* Q16 */ - minInvGain_Q30 = silk_DIV32_varQ( minInvGain_Q30, - silk_SMULWW( SILK_FIX_CONST( MAX_PREDICTION_POWER_GAIN, 0 ), + } else { + minInvGain_Q30 = silk_log2lin( silk_SMLAWB( 16 << 7, (opus_int32)psEncCtrl->LTPredCodGain_Q7, SILK_FIX_CONST( 1.0 / 3, 16 ) ) ); /* Q16 */ + minInvGain_Q30 = silk_DIV32_varQ( minInvGain_Q30, + silk_SMULWW( SILK_FIX_CONST( MAX_PREDICTION_POWER_GAIN, 0 ), silk_SMLAWB( SILK_FIX_CONST( 0.25, 18 ), SILK_FIX_CONST( 0.75, 18 ), psEncCtrl->coding_quality_Q14 ) ), 14 ); } @@ -137,4 +142,5 @@ void silk_find_pred_coefs_FIX( /* Copy to prediction struct for use in next frame for interpolation */ silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); + RESTORE_STACK; } diff --git a/media/libopus/silk/fixed/k2a_FIX.c b/media/libopus/silk/fixed/k2a_FIX.c index 5f1dc96e112f..5fee599bcb74 100644 --- a/media/libopus/silk/fixed/k2a_FIX.c +++ b/media/libopus/silk/fixed/k2a_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/fixed/k2a_Q16_FIX.c b/media/libopus/silk/fixed/k2a_Q16_FIX.c index 8d5890ea23dd..3b039875446a 100644 --- a/media/libopus/silk/fixed/k2a_Q16_FIX.c +++ b/media/libopus/silk/fixed/k2a_Q16_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/fixed/main_FIX.h b/media/libopus/silk/fixed/main_FIX.h index c77143e81405..d999b13fa5be 100644 --- a/media/libopus/silk/fixed/main_FIX.h +++ b/media/libopus/silk/fixed/main_FIX.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -172,17 +168,17 @@ void silk_find_LTP_FIX( void silk_LTP_analysis_filter_FIX( opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */ - const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceeding samples */ + const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */ const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */ const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */ const opus_int subfr_length, /* I Length of each subframe */ const opus_int nb_subfr, /* I Number of subframes */ - const opus_int pre_length /* I Length of the preceeding samples starting at &x[0] for each subframe */ + const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */ ); /* Calculates residual energies of input subframes where all subframes have LPC_order */ -/* of preceeding samples */ +/* of preceding samples */ void silk_residual_energy_FIX( opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */ diff --git a/media/libopus/silk/fixed/noise_shape_analysis_FIX.c b/media/libopus/silk/fixed/noise_shape_analysis_FIX.c index 8fd76d3de87f..b97881bf0fbd 100644 --- a/media/libopus/silk/fixed/noise_shape_analysis_FIX.c +++ b/media/libopus/silk/fixed/noise_shape_analysis_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main_FIX.h" +#include "stack_alloc.h" #include "tuning_parameters.h" /* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ @@ -77,7 +74,7 @@ static inline void limit_warped_coefs( coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); } lambda_Q16 = -lambda_Q16; - nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -lambda_Q16, lambda_Q16 ); + nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 ); den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 ); gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 ); @@ -128,7 +125,7 @@ static inline void limit_warped_coefs( coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); } lambda_Q16 = -lambda_Q16; - nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -lambda_Q16, lambda_Q16 ); + nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 ); den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 ); gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 ); @@ -160,8 +157,9 @@ void silk_noise_shape_analysis_FIX( opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ]; opus_int32 AR1_Q24[ MAX_SHAPE_LPC_ORDER ]; opus_int32 AR2_Q24[ MAX_SHAPE_LPC_ORDER ]; - opus_int16 x_windowed[ SHAPE_LPC_WIN_MAX ]; + VARDECL( opus_int16, x_windowed ); const opus_int16 *x_ptr, *pitch_res_ptr; + SAVE_STACK; /* Point to start of first LPC analysis block */ x_ptr = x - psEnc->sCmn.la_shape; @@ -203,7 +201,7 @@ void silk_noise_shape_analysis_FIX( /*************************/ /* Set quantizer offset */ if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Initally set to 0; may be overruled in process_gains(..) */ + /* Initially set to 0; may be overruled in process_gains(..) */ psEnc->sCmn.indices.quantOffsetType = 0; psEncCtrl->sparseness_Q8 = 0; } else { @@ -254,7 +252,7 @@ void silk_noise_shape_analysis_FIX( if( psEnc->sCmn.warping_Q16 > 0 ) { /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ - warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) ); + warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) ); } else { warping_Q16 = 0; } @@ -262,6 +260,7 @@ void silk_noise_shape_analysis_FIX( /********************************************/ /* Compute noise shaping AR coefs and gains */ /********************************************/ + ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { /* Apply window: sine slope followed by flat part followed by cosine slope */ opus_int shift, slope_part, flat_part; @@ -315,9 +314,10 @@ void silk_noise_shape_analysis_FIX( /* Adjust gain for warping */ gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder ); silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); - psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); - if( psEncCtrl->Gains_Q16[ k ] < 0 ) { - psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX; + if ( silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ) >= ( silk_int32_MAX >> 1 ) ) { + psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX; + } else { + psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); } } @@ -440,4 +440,5 @@ void silk_noise_shape_analysis_FIX( psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 ); psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 ); } + RESTORE_STACK; } diff --git a/media/libopus/silk/fixed/pitch_analysis_core_FIX.c b/media/libopus/silk/fixed/pitch_analysis_core_FIX.c index a7a75af6b651..b6bc0bbfaa11 100644 --- a/media/libopus/silk/fixed/pitch_analysis_core_FIX.c +++ b/media/libopus/silk/fixed/pitch_analysis_core_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -38,15 +34,30 @@ POSSIBILITY OF SUCH DAMAGE. ********************************************************** */ #include "SigProc_FIX.h" #include "pitch_est_defines.h" +#include "stack_alloc.h" #include "debug.h" +#include "pitch.h" #define SCRATCH_SIZE 22 +#define SF_LENGTH_4KHZ ( PE_SUBFR_LENGTH_MS * 4 ) +#define SF_LENGTH_8KHZ ( PE_SUBFR_LENGTH_MS * 8 ) +#define MIN_LAG_4KHZ ( PE_MIN_LAG_MS * 4 ) +#define MIN_LAG_8KHZ ( PE_MIN_LAG_MS * 8 ) +#define MAX_LAG_4KHZ ( PE_MAX_LAG_MS * 4 ) +#define MAX_LAG_8KHZ ( PE_MAX_LAG_MS * 8 - 1 ) +#define CSTRIDE_4KHZ ( MAX_LAG_4KHZ + 1 - MIN_LAG_4KHZ ) +#define CSTRIDE_8KHZ ( MAX_LAG_8KHZ + 3 - ( MIN_LAG_8KHZ - 2 ) ) +#define D_COMP_MIN ( MIN_LAG_8KHZ - 3 ) +#define D_COMP_MAX ( MAX_LAG_8KHZ + 4 ) +#define D_COMP_STRIDE ( D_COMP_MAX - D_COMP_MIN ) + +typedef opus_int32 silk_pe_stage3_vals[ PE_NB_STAGE3_LAGS ]; /************************************************************/ /* Internally used functions */ /************************************************************/ -void silk_P_Ana_calc_corr_st3( - opus_int32 cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM correlation array */ +static void silk_P_Ana_calc_corr_st3( + silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */ const opus_int16 frame[], /* I vector to correlate */ opus_int start_lag, /* I lag offset to search around */ opus_int sf_length, /* I length of a 5 ms subframe */ @@ -54,8 +65,8 @@ void silk_P_Ana_calc_corr_st3( opus_int complexity /* I Complexity setting */ ); -void silk_P_Ana_calc_energy_st3( - opus_int32 energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM energy array */ +static void silk_P_Ana_calc_energy_st3( + silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */ const opus_int16 frame[], /* I vector to calc energy in */ opus_int start_lag, /* I lag offset to search around */ opus_int sf_length, /* I length of one 5 ms subframe */ @@ -63,12 +74,6 @@ void silk_P_Ana_calc_energy_st3( opus_int complexity /* I Complexity setting */ ); -opus_int32 silk_P_Ana_find_scaling( - const opus_int16 *frame, - const opus_int frame_length, - const opus_int sum_sqr_len -); - /*************************************************************/ /* FIXED POINT CORE PITCH ANALYSIS FUNCTION */ /*************************************************************/ @@ -80,36 +85,37 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */ opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */ - const opus_int search_thres2_Q15, /* I Final threshold for lag candidates 0 - 1 */ + const opus_int search_thres2_Q13, /* I Final threshold for lag candidates 0 - 1 */ const opus_int Fs_kHz, /* I Sample frequency (kHz) */ const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ const opus_int nb_subfr /* I number of 5 ms subframes */ ) { - opus_int16 frame_8kHz[ PE_MAX_FRAME_LENGTH_ST_2 ]; - opus_int16 frame_4kHz[ PE_MAX_FRAME_LENGTH_ST_1 ]; + VARDECL( opus_int16, frame_8kHz ); + VARDECL( opus_int16, frame_4kHz ); opus_int32 filt_state[ 6 ]; - opus_int32 scratch_mem[ 3 * PE_MAX_FRAME_LENGTH ]; - opus_int16 *input_frame_ptr; + const opus_int16 *input_frame_ptr; opus_int i, k, d, j; - opus_int16 C[ PE_MAX_NB_SUBFR ][ ( PE_MAX_LAG >> 1 ) + 5 ]; + VARDECL( opus_int16, C ); + VARDECL( opus_int32, xcorr32 ); const opus_int16 *target_ptr, *basis_ptr; opus_int32 cross_corr, normalizer, energy, shift, energy_basis, energy_target; opus_int d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp; - opus_int16 d_comp[ ( PE_MAX_LAG >> 1 ) + 5 ]; - opus_int32 sum, threshold, temp32, lag_counter; + VARDECL( opus_int16, d_comp ); + opus_int32 sum, threshold, lag_counter; opus_int CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new; opus_int32 CC[ PE_NB_CBKS_STAGE2_EXT ], CCmax, CCmax_b, CCmax_new_b, CCmax_new; - opus_int32 energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ]; - opus_int32 crosscorr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ]; - opus_int frame_length, frame_length_8kHz, frame_length_4kHz, max_sum_sq_length; - opus_int sf_length, sf_length_8kHz, sf_length_4kHz; - opus_int min_lag, min_lag_8kHz, min_lag_4kHz; - opus_int max_lag, max_lag_8kHz, max_lag_4kHz; - opus_int32 contour_bias_Q20, diff, lz, lshift; + VARDECL( silk_pe_stage3_vals, energies_st3 ); + VARDECL( silk_pe_stage3_vals, cross_corr_st3 ); + opus_int frame_length, frame_length_8kHz, frame_length_4kHz; + opus_int sf_length; + opus_int min_lag; + opus_int max_lag; + opus_int32 contour_bias_Q15, diff; opus_int nb_cbk_search, cbk_size; - opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q15, corr_thres_Q15; + opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q13; const opus_int8 *Lag_CB_ptr; + SAVE_STACK; /* Check for valid sampling frequency */ silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 ); @@ -118,25 +124,18 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 silk_assert( complexity <= SILK_PE_MAX_COMPLEX ); silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) ); - silk_assert( search_thres2_Q15 >= 0 && search_thres2_Q15 <= (1<<15) ); + silk_assert( search_thres2_Q13 >= 0 && search_thres2_Q13 <= (1<<13) ); /* Set up frame lengths max / min lag for the sampling frequency */ frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz; frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4; frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8; sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz; - sf_length_4kHz = PE_SUBFR_LENGTH_MS * 4; - sf_length_8kHz = PE_SUBFR_LENGTH_MS * 8; min_lag = PE_MIN_LAG_MS * Fs_kHz; - min_lag_4kHz = PE_MIN_LAG_MS * 4; - min_lag_8kHz = PE_MIN_LAG_MS * 8; max_lag = PE_MAX_LAG_MS * Fs_kHz - 1; - max_lag_4kHz = PE_MAX_LAG_MS * 4; - max_lag_8kHz = PE_MAX_LAG_MS * 8 - 1; - - silk_memset( C, 0, sizeof( opus_int16 ) * nb_subfr * ( ( PE_MAX_LAG >> 1 ) + 5) ); /* Resample from input sampled at Fs_kHz to 8 kHz */ + ALLOC( frame_8kHz, frame_length_8kHz, opus_int16 ); if( Fs_kHz == 16 ) { silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) ); silk_resampler_down2( filt_state, frame_8kHz, frame, frame_length ); @@ -150,6 +149,7 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 /* Decimate again to 4 kHz */ silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );/* Set state to zero */ + ALLOC( frame_4kHz, frame_length_4kHz, opus_int16 ); silk_resampler_down2( filt_state, frame_4kHz, frame_8kHz, frame_length_8kHz ); /* Low-pass filter */ @@ -163,9 +163,9 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 *******************************************************************************/ /* Inner product is calculated with different lengths, so scale for the worst case */ - max_sum_sq_length = silk_max_32( sf_length_8kHz, silk_LSHIFT( sf_length_4kHz, 2 ) ); - shift = silk_P_Ana_find_scaling( frame_4kHz, frame_length_4kHz, max_sum_sq_length ); + silk_sum_sqr_shift( &energy, &shift, frame_4kHz, frame_length_4kHz ); if( shift > 0 ) { + shift = silk_RSHIFT( shift, 1 ); for( i = 0; i < frame_length_4kHz; i++ ) { frame_4kHz[ i ] = silk_RSHIFT( frame_4kHz[ i ], shift ); } @@ -174,94 +174,93 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 /****************************************************************************** * FIRST STAGE, operating in 4 khz ******************************************************************************/ - target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ]; + ALLOC( C, nb_subfr * CSTRIDE_8KHZ, opus_int16 ); + ALLOC( xcorr32, MAX_LAG_4KHZ-MIN_LAG_4KHZ+1, opus_int32 ); + silk_memset( C, 0, (nb_subfr >> 1) * CSTRIDE_4KHZ * sizeof( opus_int16 ) ); + target_ptr = &frame_4kHz[ silk_LSHIFT( SF_LENGTH_4KHZ, 2 ) ]; for( k = 0; k < nb_subfr >> 1; k++ ) { /* Check that we are within range of the array */ silk_assert( target_ptr >= frame_4kHz ); - silk_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); + silk_assert( target_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz ); - basis_ptr = target_ptr - min_lag_4kHz; + basis_ptr = target_ptr - MIN_LAG_4KHZ; /* Check that we are within range of the array */ silk_assert( basis_ptr >= frame_4kHz ); - silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); + silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz ); + + celt_pitch_xcorr( target_ptr, target_ptr - MAX_LAG_4KHZ, xcorr32, SF_LENGTH_8KHZ, MAX_LAG_4KHZ - MIN_LAG_4KHZ + 1 ); /* Calculate first vector products before loop */ - cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz ); - normalizer = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length_8kHz ); - normalizer = silk_ADD_SAT32( normalizer, silk_SMULBB( sf_length_8kHz, 4000 ) ); + cross_corr = xcorr32[ MAX_LAG_4KHZ - MIN_LAG_4KHZ ]; + normalizer = silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ ); + normalizer = silk_ADD32( normalizer, silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ ) ); + normalizer = silk_ADD32( normalizer, silk_SMULBB( SF_LENGTH_8KHZ, 4000 ) ); - temp32 = silk_DIV32( cross_corr, silk_SQRT_APPROX( normalizer ) + 1 ); - C[ k ][ min_lag_4kHz ] = (opus_int16)silk_SAT16( temp32 ); /* Q0 */ + matrix_ptr( C, k, 0, CSTRIDE_4KHZ ) = + (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */ /* From now on normalizer is computed recursively */ - for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) { + for( d = MIN_LAG_4KHZ + 1; d <= MAX_LAG_4KHZ; d++ ) { basis_ptr--; /* Check that we are within range of the array */ silk_assert( basis_ptr >= frame_4kHz ); - silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); + silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz ); - cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz ); + cross_corr = xcorr32[ MAX_LAG_4KHZ - d ]; /* Add contribution of new sample and remove contribution from oldest sample */ - normalizer += + normalizer = silk_ADD32( normalizer, silk_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) - - silk_SMULBB( basis_ptr[ sf_length_8kHz ], basis_ptr[ sf_length_8kHz ] ); + silk_SMULBB( basis_ptr[ SF_LENGTH_8KHZ ], basis_ptr[ SF_LENGTH_8KHZ ] ) ); - temp32 = silk_DIV32( cross_corr, silk_SQRT_APPROX( normalizer ) + 1 ); - C[ k ][ d ] = (opus_int16)silk_SAT16( temp32 ); /* Q0 */ + matrix_ptr( C, k, d - MIN_LAG_4KHZ, CSTRIDE_4KHZ) = + (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */ } /* Update target pointer */ - target_ptr += sf_length_8kHz; + target_ptr += SF_LENGTH_8KHZ; } /* Combine two subframes into single correlation measure and apply short-lag bias */ if( nb_subfr == PE_MAX_NB_SUBFR ) { - for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) { - sum = (opus_int32)C[ 0 ][ i ] + (opus_int32)C[ 1 ][ i ]; /* Q0 */ - silk_assert( silk_RSHIFT( sum, 1 ) == silk_SAT16( silk_RSHIFT( sum, 1 ) ) ); - sum = silk_RSHIFT( sum, 1 ); /* Q-1 */ - silk_assert( silk_LSHIFT( (opus_int32)-i, 4 ) == silk_SAT16( silk_LSHIFT( (opus_int32)-i, 4 ) ) ); - sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q-1 */ - silk_assert( sum == silk_SAT16( sum ) ); - C[ 0 ][ i ] = (opus_int16)sum; /* Q-1 */ + for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) { + sum = (opus_int32)matrix_ptr( C, 0, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ ) + + (opus_int32)matrix_ptr( C, 1, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ ); /* Q14 */ + sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */ + C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */ } } else { /* Only short-lag bias */ - for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) { - sum = (opus_int32)C[ 0 ][ i ]; - sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q-1 */ - C[ 0 ][ i ] = (opus_int16)sum; /* Q-1 */ + for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) { + sum = silk_LSHIFT( (opus_int32)C[ i - MIN_LAG_4KHZ ], 1 ); /* Q14 */ + sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */ + C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */ } } /* Sort */ length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 ); silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH ); - silk_insertion_sort_decreasing_int16( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch ); + silk_insertion_sort_decreasing_int16( C, d_srch, CSTRIDE_4KHZ, + length_d_srch ); /* Escape if correlation is very low already here */ - target_ptr = &frame_4kHz[ silk_SMULBB( sf_length_4kHz, nb_subfr ) ]; - energy = silk_inner_prod_aligned( target_ptr, target_ptr, silk_LSHIFT( sf_length_4kHz, 2 ) ); - energy = silk_ADD_SAT32( energy, 1000 ); /* Q0 */ - Cmax = (opus_int)C[ 0 ][ min_lag_4kHz ]; /* Q-1 */ - threshold = silk_SMULBB( Cmax, Cmax ); /* Q-2 */ - - /* Compare in Q-2 domain */ - if( silk_RSHIFT( energy, 4 + 2 ) > threshold ) { + Cmax = (opus_int)C[ 0 ]; /* Q14 */ + if( Cmax < SILK_FIX_CONST( 0.2, 14 ) ) { silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); *LTPCorr_Q15 = 0; *lagIndex = 0; *contourIndex = 0; + RESTORE_STACK; return 1; } threshold = silk_SMULWB( search_thres1_Q16, Cmax ); for( i = 0; i < length_d_srch; i++ ) { /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */ - if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) { - d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + min_lag_4kHz, 1 ); + if( C[ i ] > threshold ) { + d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + MIN_LAG_4KHZ, 1 ); } else { length_d_srch = i; break; @@ -269,34 +268,37 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 } silk_assert( length_d_srch > 0 ); - for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) { - d_comp[ i ] = 0; + ALLOC( d_comp, D_COMP_STRIDE, opus_int16 ); + for( i = D_COMP_MIN; i < D_COMP_MAX; i++ ) { + d_comp[ i - D_COMP_MIN ] = 0; } for( i = 0; i < length_d_srch; i++ ) { - d_comp[ d_srch[ i ] ] = 1; + d_comp[ d_srch[ i ] - D_COMP_MIN ] = 1; } /* Convolution */ - for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { - d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ]; + for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) { + d_comp[ i - D_COMP_MIN ] += + d_comp[ i - 1 - D_COMP_MIN ] + d_comp[ i - 2 - D_COMP_MIN ]; } length_d_srch = 0; - for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) { - if( d_comp[ i + 1 ] > 0 ) { + for( i = MIN_LAG_8KHZ; i < MAX_LAG_8KHZ + 1; i++ ) { + if( d_comp[ i + 1 - D_COMP_MIN ] > 0 ) { d_srch[ length_d_srch ] = i; length_d_srch++; } } /* Convolution */ - for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { - d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ]; + for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) { + d_comp[ i - D_COMP_MIN ] += d_comp[ i - 1 - D_COMP_MIN ] + + d_comp[ i - 2 - D_COMP_MIN ] + d_comp[ i - 3 - D_COMP_MIN ]; } length_d_comp = 0; - for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) { - if( d_comp[ i ] > 0 ) { + for( i = MIN_LAG_8KHZ; i < D_COMP_MAX; i++ ) { + if( d_comp[ i - D_COMP_MIN ] > 0 ) { d_comp[ length_d_comp ] = i - 2; length_d_comp++; } @@ -310,8 +312,9 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 ** Scale signal down to avoid correlations measures from overflowing *******************************************************************************/ /* find scaling as max scaling for each subframe */ - shift = silk_P_Ana_find_scaling( frame_8kHz, frame_length_8kHz, sf_length_8kHz ); + silk_sum_sqr_shift( &energy, &shift, frame_8kHz, frame_length_8kHz ); if( shift > 0 ) { + shift = silk_RSHIFT( shift, 1 ); for( i = 0; i < frame_length_8kHz; i++ ) { frame_8kHz[ i ] = silk_RSHIFT( frame_8kHz[ i ], shift ); } @@ -320,43 +323,37 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 /********************************************************************************* * Find energy of each subframe projected onto its history, for a range of delays *********************************************************************************/ - silk_memset( C, 0, PE_MAX_NB_SUBFR * ( ( PE_MAX_LAG >> 1 ) + 5 ) * sizeof( opus_int16 ) ); + silk_memset( C, 0, nb_subfr * CSTRIDE_8KHZ * sizeof( opus_int16 ) ); target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ]; for( k = 0; k < nb_subfr; k++ ) { /* Check that we are within range of the array */ silk_assert( target_ptr >= frame_8kHz ); - silk_assert( target_ptr + sf_length_8kHz <= frame_8kHz + frame_length_8kHz ); + silk_assert( target_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz ); - energy_target = silk_inner_prod_aligned( target_ptr, target_ptr, sf_length_8kHz ); + energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ ), 1 ); for( j = 0; j < length_d_comp; j++ ) { d = d_comp[ j ]; basis_ptr = target_ptr - d; /* Check that we are within range of the array */ silk_assert( basis_ptr >= frame_8kHz ); - silk_assert( basis_ptr + sf_length_8kHz <= frame_8kHz + frame_length_8kHz ); + silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz ); - cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz ); - energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length_8kHz ); + cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, SF_LENGTH_8KHZ ); if( cross_corr > 0 ) { - energy = silk_max( energy_target, energy_basis ); /* Find max to make sure first division < 1.0 */ - lz = silk_CLZ32( cross_corr ); - lshift = silk_LIMIT_32( lz - 1, 0, 15 ); - temp32 = silk_DIV32( silk_LSHIFT( cross_corr, lshift ), silk_RSHIFT( energy, 15 - lshift ) + 1 ); /* Q15 */ - silk_assert( temp32 == silk_SAT16( temp32 ) ); - temp32 = silk_SMULWB( cross_corr, temp32 ); /* Q(-1), cc * ( cc / max(b, t) ) */ - temp32 = silk_ADD_SAT32( temp32, temp32 ); /* Q(0) */ - lz = silk_CLZ32( temp32 ); - lshift = silk_LIMIT_32( lz - 1, 0, 15 ); - energy = silk_min( energy_target, energy_basis ); - C[ k ][ d ] = silk_DIV32( silk_LSHIFT( temp32, lshift ), silk_RSHIFT( energy, 15 - lshift ) + 1 ); /* Q15*/ + energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ ); + matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = + (opus_int16)silk_DIV32_varQ( cross_corr, + silk_ADD32( energy_target, + energy_basis ), + 13 + 1 ); /* Q13 */ } else { - C[ k ][ d ] = 0; + matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = 0; } } - target_ptr += sf_length_8kHz; + target_ptr += SF_LENGTH_8KHZ; } /* search over lag range and lags codebook */ @@ -378,7 +375,7 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 } else { prevLag_log2_Q7 = 0; } - silk_assert( search_thres2_Q15 == silk_SAT16( search_thres2_Q15 ) ); + silk_assert( search_thres2_Q13 == silk_SAT16( search_thres2_Q13 ) ); /* Set up stage 2 codebook based on number of subframes */ if( nb_subfr == PE_MAX_NB_SUBFR ) { cbk_size = PE_NB_CBKS_STAGE2_EXT; @@ -389,12 +386,10 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 } else { nb_cbk_search = PE_NB_CBKS_STAGE2; } - corr_thres_Q15 = silk_RSHIFT( silk_SMULBB( search_thres2_Q15, search_thres2_Q15 ), 13 ); } else { cbk_size = PE_NB_CBKS_STAGE2_10MS; Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; nb_cbk_search = PE_NB_CBKS_STAGE2_10MS; - corr_thres_Q15 = silk_RSHIFT( silk_SMULBB( search_thres2_Q15, search_thres2_Q15 ), 14 ); } for( k = 0; k < length_d_srch; k++ ) { @@ -402,8 +397,13 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 for( j = 0; j < nb_cbk_search; j++ ) { CC[ j ] = 0; for( i = 0; i < nb_subfr; i++ ) { + opus_int d_subfr; /* Try all codebooks */ - CC[ j ] = CC[ j ] + (opus_int32)C[ i ][ d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size )]; + d_subfr = d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size ); + CC[ j ] = CC[ j ] + + (opus_int32)matrix_ptr( C, i, + d_subfr - ( MIN_LAG_8KHZ - 2 ), + CSTRIDE_8KHZ ); } } /* Find best codebook */ @@ -417,25 +417,25 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 } /* Bias towards shorter lags */ - lag_log2_Q7 = silk_lin2log( (opus_int32)d ); /* Q7 */ + lag_log2_Q7 = silk_lin2log( d ); /* Q7 */ silk_assert( lag_log2_Q7 == silk_SAT16( lag_log2_Q7 ) ); - silk_assert( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 15 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 15 ) ) ); - CCmax_new_b = CCmax_new - silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 15 ), lag_log2_Q7 ), 7 ); /* Q15 */ + silk_assert( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) ) ); + CCmax_new_b = CCmax_new - silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ), lag_log2_Q7 ), 7 ); /* Q13 */ /* Bias towards previous lag */ - silk_assert( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 15 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 15 ) ) ); + silk_assert( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) ) ); if( prevLag > 0 ) { delta_lag_log2_sqr_Q7 = lag_log2_Q7 - prevLag_log2_Q7; silk_assert( delta_lag_log2_sqr_Q7 == silk_SAT16( delta_lag_log2_sqr_Q7 ) ); delta_lag_log2_sqr_Q7 = silk_RSHIFT( silk_SMULBB( delta_lag_log2_sqr_Q7, delta_lag_log2_sqr_Q7 ), 7 ); - prev_lag_bias_Q15 = silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 15 ), *LTPCorr_Q15 ), 15 ); /* Q15 */ - prev_lag_bias_Q15 = silk_DIV32( silk_MUL( prev_lag_bias_Q15, delta_lag_log2_sqr_Q7 ), delta_lag_log2_sqr_Q7 + ( 1 << 6 ) ); - CCmax_new_b -= prev_lag_bias_Q15; /* Q15 */ + prev_lag_bias_Q13 = silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ), *LTPCorr_Q15 ), 15 ); /* Q13 */ + prev_lag_bias_Q13 = silk_DIV32( silk_MUL( prev_lag_bias_Q13, delta_lag_log2_sqr_Q7 ), delta_lag_log2_sqr_Q7 + SILK_FIX_CONST( 0.5, 7 ) ); + CCmax_new_b -= prev_lag_bias_Q13; /* Q13 */ } if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */ - CCmax_new > corr_thres_Q15 && /* Correlation needs to be high enough to be voiced */ - silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= min_lag_8kHz /* Lag must be in range */ + CCmax_new > silk_SMULBB( nb_subfr, search_thres2_Q13 ) && /* Correlation needs to be high enough to be voiced */ + silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= MIN_LAG_8KHZ /* Lag must be in range */ ) { CCmax_b = CCmax_new_b; CCmax = CCmax_new; @@ -450,24 +450,31 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 *LTPCorr_Q15 = 0; *lagIndex = 0; *contourIndex = 0; + RESTORE_STACK; return 1; } + /* Output normalized correlation */ + *LTPCorr_Q15 = (opus_int)silk_LSHIFT( silk_DIV32_16( CCmax, nb_subfr ), 2 ); + silk_assert( *LTPCorr_Q15 >= 0 ); + if( Fs_kHz > 8 ) { + VARDECL( opus_int16, scratch_mem ); /***************************************************************************/ /* Scale input signal down to avoid correlations measures from overflowing */ /***************************************************************************/ /* find scaling as max scaling for each subframe */ - shift = silk_P_Ana_find_scaling( frame, frame_length, sf_length ); + silk_sum_sqr_shift( &energy, &shift, frame, frame_length ); + ALLOC( scratch_mem, shift > 0 ? frame_length : 0, opus_int16 ); if( shift > 0 ) { /* Move signal to scratch mem because the input signal should be unchanged */ - /* Reuse the 32 bit scratch mem vector, use a 16 bit pointer from now */ - input_frame_ptr = (opus_int16*)scratch_mem; + shift = silk_RSHIFT( shift, 1 ); for( i = 0; i < frame_length; i++ ) { - input_frame_ptr[ i ] = silk_RSHIFT( frame[ i ], shift ); + scratch_mem[ i ] = silk_RSHIFT( frame[ i ], shift ); } + input_frame_ptr = scratch_mem; } else { - input_frame_ptr = (opus_int16*)frame; + input_frame_ptr = frame; } /* Search in original signal */ @@ -487,24 +494,15 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 start_lag = silk_max_int( lag - 2, min_lag ); end_lag = silk_min_int( lag + 2, max_lag ); lag_new = lag; /* to avoid undefined lag */ - CBimax = 0; /* to avoid undefined lag */ - silk_assert( silk_LSHIFT( CCmax, 13 ) >= 0 ); - *LTPCorr_Q15 = (opus_int)silk_SQRT_APPROX( silk_LSHIFT( CCmax, 13 ) ); /* Output normalized correlation */ + CBimax = 0; /* to avoid undefined lag */ CCmax = silk_int32_MIN; /* pitch lags according to second stage */ for( k = 0; k < nb_subfr; k++ ) { pitch_out[ k ] = lag + 2 * silk_CB_lags_stage2[ k ][ CBimax_old ]; } - /* Calculate the correlations and energies needed in stage 3 */ - silk_P_Ana_calc_corr_st3( crosscorr_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity ); - silk_P_Ana_calc_energy_st3( energies_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity ); - lag_counter = 0; - silk_assert( lag == silk_SAT16( lag ) ); - contour_bias_Q20 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 20 ), lag ); - - /* Set up codebook parameters acording to complexity setting and frame length */ + /* Set up codebook parameters according to complexity setting and frame length */ if( nb_subfr == PE_MAX_NB_SUBFR ) { nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ]; cbk_size = PE_NB_CBKS_STAGE3_MAX; @@ -514,41 +512,43 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 cbk_size = PE_NB_CBKS_STAGE3_10MS; Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; } + + /* Calculate the correlations and energies needed in stage 3 */ + ALLOC( energies_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals ); + ALLOC( cross_corr_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals ); + silk_P_Ana_calc_corr_st3( cross_corr_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity ); + silk_P_Ana_calc_energy_st3( energies_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity ); + + lag_counter = 0; + silk_assert( lag == silk_SAT16( lag ) ); + contour_bias_Q15 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 15 ), lag ); + + target_ptr = &input_frame_ptr[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ]; + energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, nb_subfr * sf_length ), 1 ); for( d = start_lag; d <= end_lag; d++ ) { for( j = 0; j < nb_cbk_search; j++ ) { cross_corr = 0; - energy = 0; + energy = energy_target; for( k = 0; k < nb_subfr; k++ ) { - silk_assert( PE_MAX_NB_SUBFR == 4 ); - energy += silk_RSHIFT( energies_st3[ k ][ j ][ lag_counter ], 2 ); /* use mean, to avoid overflow */ + cross_corr = silk_ADD32( cross_corr, + matrix_ptr( cross_corr_st3, k, j, + nb_cbk_search )[ lag_counter ] ); + energy = silk_ADD32( energy, + matrix_ptr( energies_st3, k, j, + nb_cbk_search )[ lag_counter ] ); silk_assert( energy >= 0 ); - cross_corr += silk_RSHIFT( crosscorr_st3[ k ][ j ][ lag_counter ], 2 ); /* use mean, to avoid overflow */ } if( cross_corr > 0 ) { - /* Divide cross_corr / energy and get result in Q15 */ - lz = silk_CLZ32( cross_corr ); - /* Divide with result in Q13, cross_corr could be larger than energy */ - lshift = silk_LIMIT_32( lz - 1, 0, 13 ); - CCmax_new = silk_DIV32( silk_LSHIFT( cross_corr, lshift ), silk_RSHIFT( energy, 13 - lshift ) + 1 ); - CCmax_new = silk_SAT16( CCmax_new ); - CCmax_new = silk_SMULWB( cross_corr, CCmax_new ); - /* Saturate */ - if( CCmax_new > silk_RSHIFT( silk_int32_MAX, 3 ) ) { - CCmax_new = silk_int32_MAX; - } else { - CCmax_new = silk_LSHIFT( CCmax_new, 3 ); - } + CCmax_new = silk_DIV32_varQ( cross_corr, energy, 13 + 1 ); /* Q13 */ /* Reduce depending on flatness of contour */ - diff = silk_int16_MAX - silk_RSHIFT( silk_MUL( contour_bias_Q20, j ), 5 ); /* Q20 -> Q15 */ + diff = silk_int16_MAX - silk_MUL( contour_bias_Q15, j ); /* Q15 */ silk_assert( diff == silk_SAT16( diff ) ); - CCmax_new = silk_LSHIFT( silk_SMULWB( CCmax_new, diff ), 1 ); + CCmax_new = silk_SMULWB( CCmax_new, diff ); /* Q14 */ } else { CCmax_new = 0; } - if( CCmax_new > CCmax && - ( d + silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag - ) { + if( CCmax_new > CCmax && ( d + silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) { CCmax = CCmax_new; lag_new = d; CBimax = j; @@ -564,27 +564,35 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 *lagIndex = (opus_int16)( lag_new - min_lag); *contourIndex = (opus_int8)CBimax; } else { /* Fs_kHz == 8 */ - /* Save Lags and correlation */ - CCmax = silk_max( CCmax, 0 ); - *LTPCorr_Q15 = (opus_int)silk_SQRT_APPROX( silk_LSHIFT( CCmax, 13 ) ); /* Output normalized correlation */ + /* Save Lags */ for( k = 0; k < nb_subfr; k++ ) { pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); - pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * Fs_kHz ); + pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], MIN_LAG_8KHZ, PE_MAX_LAG_MS * 8 ); } - *lagIndex = (opus_int16)( lag - min_lag_8kHz ); + *lagIndex = (opus_int16)( lag - MIN_LAG_8KHZ ); *contourIndex = (opus_int8)CBimax; } silk_assert( *lagIndex >= 0 ); /* return as voiced */ + RESTORE_STACK; return 0; } -/*************************************************************************/ -/* Calculates the correlations used in stage 3 search. In order to cover */ -/* the whole lag codebook for all the searched offset lags (lag +- 2), */ -/*************************************************************************/ -void silk_P_Ana_calc_corr_st3( - opus_int32 cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM correlation array */ +/*********************************************************************** + * Calculates the correlations used in stage 3 search. In order to cover + * the whole lag codebook for all the searched offset lags (lag +- 2), + * the following correlations are needed in each sub frame: + * + * sf1: lag range [-8,...,7] total 16 correlations + * sf2: lag range [-4,...,4] total 9 correlations + * sf3: lag range [-3,....4] total 8 correltions + * sf4: lag range [-6,....8] total 15 correlations + * + * In total 48 correlations. The direct implementation computed in worst + * case 4*12*5 = 240 correlations, but more likely around 120. + ***********************************************************************/ +static void silk_P_Ana_calc_corr_st3( + silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */ const opus_int16 frame[], /* I vector to correlate */ opus_int start_lag, /* I lag offset to search around */ opus_int sf_length, /* I length of a 5 ms subframe */ @@ -592,12 +600,13 @@ void silk_P_Ana_calc_corr_st3( opus_int complexity /* I Complexity setting */ ) { - const opus_int16 *target_ptr, *basis_ptr; - opus_int32 cross_corr; + const opus_int16 *target_ptr; opus_int i, j, k, lag_counter, lag_low, lag_high; opus_int nb_cbk_search, delta, idx, cbk_size; - opus_int32 scratch_mem[ SCRATCH_SIZE ]; + VARDECL( opus_int32, scratch_mem ); + VARDECL( opus_int32, xcorr32 ); const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; + SAVE_STACK; silk_assert( complexity >= SILK_PE_MIN_COMPLEX ); silk_assert( complexity <= SILK_PE_MAX_COMPLEX ); @@ -614,6 +623,8 @@ void silk_P_Ana_calc_corr_st3( nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; cbk_size = PE_NB_CBKS_STAGE3_10MS; } + ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 ); + ALLOC( xcorr32, SCRATCH_SIZE, opus_int32 ); target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */ for( k = 0; k < nb_subfr; k++ ) { @@ -622,11 +633,11 @@ void silk_P_Ana_calc_corr_st3( /* Calculate the correlations for each subframe */ lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 ); lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 ); + silk_assert(lag_high-lag_low+1 <= SCRATCH_SIZE); + celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr32, sf_length, lag_high - lag_low + 1 ); for( j = lag_low; j <= lag_high; j++ ) { - basis_ptr = target_ptr - ( start_lag + j ); - cross_corr = silk_inner_prod_aligned( (opus_int16*)target_ptr, (opus_int16*)basis_ptr, sf_length ); silk_assert( lag_counter < SCRATCH_SIZE ); - scratch_mem[ lag_counter ] = cross_corr; + scratch_mem[ lag_counter ] = xcorr32[ lag_high - j ]; lag_counter++; } @@ -638,32 +649,35 @@ void silk_P_Ana_calc_corr_st3( for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { silk_assert( idx + j < SCRATCH_SIZE ); silk_assert( idx + j < lag_counter ); - cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; + matrix_ptr( cross_corr_st3, k, i, nb_cbk_search )[ j ] = + scratch_mem[ idx + j ]; } } target_ptr += sf_length; } + RESTORE_STACK; } /********************************************************************/ /* Calculate the energies for first two subframes. The energies are */ /* calculated recursively. */ /********************************************************************/ -void silk_P_Ana_calc_energy_st3( - opus_int32 energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM energy array */ - const opus_int16 frame[], /* I vector to calc energy in */ - opus_int start_lag, /* I lag offset to search around */ - opus_int sf_length, /* I length of one 5 ms subframe */ - opus_int nb_subfr, /* I number of subframes */ - opus_int complexity /* I Complexity setting */ +static void silk_P_Ana_calc_energy_st3( + silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */ + const opus_int16 frame[], /* I vector to calc energy in */ + opus_int start_lag, /* I lag offset to search around */ + opus_int sf_length, /* I length of one 5 ms subframe */ + opus_int nb_subfr, /* I number of subframes */ + opus_int complexity /* I Complexity setting */ ) { const opus_int16 *target_ptr, *basis_ptr; opus_int32 energy; opus_int k, i, j, lag_counter; opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff; - opus_int32 scratch_mem[ SCRATCH_SIZE ]; + VARDECL( opus_int32, scratch_mem ); const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; + SAVE_STACK; silk_assert( complexity >= SILK_PE_MIN_COMPLEX ); silk_assert( complexity <= SILK_PE_MAX_COMPLEX ); @@ -680,6 +694,8 @@ void silk_P_Ana_calc_energy_st3( nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; cbk_size = PE_NB_CBKS_STAGE3_10MS; } + ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 ); + target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; for( k = 0; k < nb_subfr; k++ ) { lag_counter = 0; @@ -713,37 +729,13 @@ void silk_P_Ana_calc_energy_st3( for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { silk_assert( idx + j < SCRATCH_SIZE ); silk_assert( idx + j < lag_counter ); - energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; - silk_assert( energies_st3[ k ][ i ][ j ] >= 0 ); + matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] = + scratch_mem[ idx + j ]; + silk_assert( + matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] >= 0 ); } } target_ptr += sf_length; } -} - -opus_int32 silk_P_Ana_find_scaling( - const opus_int16 *frame, - const opus_int frame_length, - const opus_int sum_sqr_len -) -{ - opus_int32 nbits, x_max; - - x_max = silk_int16_array_maxabs( frame, frame_length ); - - if( x_max < silk_int16_MAX ) { - /* Number of bits needed for the sum of the squares */ - nbits = 32 - silk_CLZ32( silk_SMULBB( x_max, x_max ) ); - } else { - /* Here we don't know if x_max should have been silk_int16_MAX + 1, so we expect the worst case */ - nbits = 30; - } - nbits += 17 - silk_CLZ16( sum_sqr_len ); - - /* Without a guarantee of saturation, we need to keep the 31st bit free */ - if( nbits < 31 ) { - return 0; - } else { - return( nbits - 30 ); - } + RESTORE_STACK; } diff --git a/media/libopus/silk/fixed/prefilter_FIX.c b/media/libopus/silk/fixed/prefilter_FIX.c index c762e69e5d20..1cfe4f9b7eb2 100644 --- a/media/libopus/silk/fixed/prefilter_FIX.c +++ b/media/libopus/silk/fixed/prefilter_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main_FIX.h" +#include "stack_alloc.h" #include "tuning_parameters.h" /* Prefilter for finding Quantizer input signal */ @@ -105,14 +102,17 @@ void silk_prefilter_FIX( opus_int32 *pxw_Q3; opus_int HarmShapeGain_Q12, Tilt_Q14; opus_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14; - opus_int32 x_filt_Q12[ MAX_SUB_FRAME_LENGTH ]; - opus_int32 st_res_Q2[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ]; + VARDECL( opus_int32, x_filt_Q12 ); + VARDECL( opus_int32, st_res_Q2 ); opus_int16 B_Q10[ 2 ]; + SAVE_STACK; /* Set up pointers */ px = x; pxw_Q3 = xw_Q3; lag = P->lagPrev; + ALLOC( x_filt_Q12, psEnc->sCmn.subfr_length, opus_int32 ); + ALLOC( st_res_Q2, psEnc->sCmn.subfr_length, opus_int32 ); for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { /* Update Variables that change per sub frame */ if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { @@ -120,7 +120,7 @@ void silk_prefilter_FIX( } /* Noise shape parameters */ - HarmShapeGain_Q12 = silk_SMULWB( psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] ); + HarmShapeGain_Q12 = silk_SMULWB( (opus_int32)psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] ); silk_assert( HarmShapeGain_Q12 >= 0 ); HarmShapeFIRPacked_Q12 = silk_RSHIFT( HarmShapeGain_Q12, 2 ); HarmShapeFIRPacked_Q12 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q12, 1 ), 16 ); @@ -139,9 +139,9 @@ void silk_prefilter_FIX( tmp_32 = silk_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] ); /* Q24 */ tmp_32 = silk_RSHIFT_ROUND( tmp_32, 14 ); /* Q10 */ B_Q10[ 1 ]= silk_SAT16( tmp_32 ); - x_filt_Q12[ 0 ] = silk_SMLABB( silk_SMULBB( st_res_Q2[ 0 ], B_Q10[ 0 ] ), P->sHarmHP_Q2, B_Q10[ 1 ] ); + x_filt_Q12[ 0 ] = silk_MLA( silk_MUL( st_res_Q2[ 0 ], B_Q10[ 0 ] ), P->sHarmHP_Q2, B_Q10[ 1 ] ); for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) { - x_filt_Q12[ j ] = silk_SMLABB( silk_SMULBB( st_res_Q2[ j ], B_Q10[ 0 ] ), st_res_Q2[ j - 1 ], B_Q10[ 1 ] ); + x_filt_Q12[ j ] = silk_MLA( silk_MUL( st_res_Q2[ j ], B_Q10[ 0 ] ), st_res_Q2[ j - 1 ], B_Q10[ 1 ] ); } P->sHarmHP_Q2 = st_res_Q2[ psEnc->sCmn.subfr_length - 1 ]; @@ -152,6 +152,7 @@ void silk_prefilter_FIX( } P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ]; + RESTORE_STACK; } /* Prefilter for finding Quantizer input signal */ diff --git a/media/libopus/silk/fixed/process_gains_FIX.c b/media/libopus/silk/fixed/process_gains_FIX.c index 38cbea8a5b70..05aba317889b 100644 --- a/media/libopus/silk/fixed/process_gains_FIX.c +++ b/media/libopus/silk/fixed/process_gains_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/fixed/regularize_correlations_FIX.c b/media/libopus/silk/fixed/regularize_correlations_FIX.c index 33abae049f08..a2836b05f4f8 100644 --- a/media/libopus/silk/fixed/regularize_correlations_FIX.c +++ b/media/libopus/silk/fixed/regularize_correlations_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/fixed/residual_energy16_FIX.c b/media/libopus/silk/fixed/residual_energy16_FIX.c index 00c47c505fc3..ebffb2a66f9a 100644 --- a/media/libopus/silk/fixed/residual_energy16_FIX.c +++ b/media/libopus/silk/fixed/residual_energy16_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/fixed/residual_energy_FIX.c b/media/libopus/silk/fixed/residual_energy_FIX.c index d1628c908707..105ae31807b0 100644 --- a/media/libopus/silk/fixed/residual_energy_FIX.c +++ b/media/libopus/silk/fixed/residual_energy_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,9 +30,10 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main_FIX.h" +#include "stack_alloc.h" /* Calculates residual energies of input subframes where all subframes have LPC_order */ -/* of preceeding samples */ +/* of preceding samples */ void silk_residual_energy_FIX( opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */ @@ -49,16 +46,20 @@ void silk_residual_energy_FIX( ) { opus_int offset, i, j, rshift, lz1, lz2; - opus_int16 *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; + opus_int16 *LPC_res_ptr; + VARDECL( opus_int16, LPC_res ); const opus_int16 *x_ptr; opus_int32 tmp32; + SAVE_STACK; x_ptr = x; offset = LPC_order + subfr_length; /* Filter input to create the LPC residual for each frame half, and measure subframe energies */ + ALLOC( LPC_res, ( MAX_NB_SUBFR >> 1 ) * offset, opus_int16 ); + silk_assert( ( nb_subfr >> 1 ) * ( MAX_NB_SUBFR >> 1 ) == nb_subfr ); for( i = 0; i < nb_subfr >> 1; i++ ) { - /* Calculate half frame LPC residual signal including preceeding samples */ + /* Calculate half frame LPC residual signal including preceding samples */ silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order ); /* Point to first subframe of the just calculated LPC residual signal */ @@ -92,4 +93,5 @@ void silk_residual_energy_FIX( nrgs[ i ] = silk_SMMUL( tmp32, silk_LSHIFT32( nrgs[ i ], lz1 ) ); /* Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 )*/ nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32; } + RESTORE_STACK; } diff --git a/media/libopus/silk/fixed/schur64_FIX.c b/media/libopus/silk/fixed/schur64_FIX.c index 7d43ff53f8f8..764a10ef3ea5 100644 --- a/media/libopus/silk/fixed/schur64_FIX.c +++ b/media/libopus/silk/fixed/schur64_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -60,6 +56,17 @@ opus_int32 silk_schur64( /* O returns residual ene } for( k = 0; k < order; k++ ) { + /* Check that we won't be getting an unstable rc, otherwise stop here. */ + if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) { + if ( C[ k + 1 ][ 0 ] > 0 ) { + rc_Q16[ k ] = -SILK_FIX_CONST( .99f, 16 ); + } else { + rc_Q16[ k ] = SILK_FIX_CONST( .99f, 16 ); + } + k++; + break; + } + /* Get reflection coefficient: divide two Q30 values and get result in Q31 */ rc_tmp_Q31 = silk_DIV32_varQ( -C[ k + 1 ][ 0 ], C[ 0 ][ 1 ], 31 ); @@ -77,5 +84,9 @@ opus_int32 silk_schur64( /* O returns residual ene } } - return( C[ 0 ][ 1 ] ); + for(; k < order; k++ ) { + rc_Q16[ k ] = 0; + } + + return silk_max_32( 1, C[ 0 ][ 1 ] ); } diff --git a/media/libopus/silk/fixed/schur_FIX.c b/media/libopus/silk/fixed/schur_FIX.c index ea3d7644428c..c4c0ef23b478 100644 --- a/media/libopus/silk/fixed/schur_FIX.c +++ b/media/libopus/silk/fixed/schur_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -72,6 +68,16 @@ opus_int32 silk_schur( /* O Returns residual ene } for( k = 0; k < order; k++ ) { + /* Check that we won't be getting an unstable rc, otherwise stop here. */ + if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) { + if ( C[ k + 1 ][ 0 ] > 0 ) { + rc_Q15[ k ] = -SILK_FIX_CONST( .99f, 15 ); + } else { + rc_Q15[ k ] = SILK_FIX_CONST( .99f, 15 ); + } + k++; + break; + } /* Get reflection coefficient */ rc_tmp_Q15 = -silk_DIV32_16( C[ k + 1 ][ 0 ], silk_max_32( silk_RSHIFT( C[ 0 ][ 1 ], 15 ), 1 ) ); @@ -91,6 +97,10 @@ opus_int32 silk_schur( /* O Returns residual ene } } + for(; k < order; k++ ) { + rc_Q15[ k ] = 0; + } + /* return residual energy */ - return C[ 0 ][ 1 ]; + return silk_max_32( 1, C[ 0 ][ 1 ] ); } diff --git a/media/libopus/silk/fixed/solve_LS_FIX.c b/media/libopus/silk/fixed/solve_LS_FIX.c index 658371cadc9a..1a39018d8b04 100644 --- a/media/libopus/silk/fixed/solve_LS_FIX.c +++ b/media/libopus/silk/fixed/solve_LS_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main_FIX.h" +#include "stack_alloc.h" #include "tuning_parameters.h" /*****************************/ @@ -83,11 +80,13 @@ void silk_solve_LDL_FIX( opus_int32 *x_Q16 /* O Pointer to x solution vector */ ) { - opus_int32 L_Q16[ MAX_MATRIX_SIZE * MAX_MATRIX_SIZE ]; + VARDECL( opus_int32, L_Q16 ); opus_int32 Y[ MAX_MATRIX_SIZE ]; inv_D_t inv_D[ MAX_MATRIX_SIZE ]; + SAVE_STACK; silk_assert( M <= MAX_MATRIX_SIZE ); + ALLOC( L_Q16, M * M, opus_int32 ); /*************************************************** Factorize A by LDL such that A = L*D*L', @@ -111,6 +110,7 @@ void silk_solve_LDL_FIX( x = inv(L') * inv(D) * Y *****************************************************/ silk_LS_SolveLast_FIX( L_Q16, M, Y, x_Q16 ); + RESTORE_STACK; } static inline void silk_LDL_factorize_FIX( @@ -155,7 +155,7 @@ static inline void silk_LDL_factorize_FIX( /* two-step division */ one_div_diag_Q36 = silk_INVERSE32_varQ( tmp_32, 36 ); /* Q36 */ one_div_diag_Q40 = silk_LSHIFT( one_div_diag_Q36, 4 ); /* Q40 */ - err = silk_SUB32( 1 << 24, silk_SMULWW( tmp_32, one_div_diag_Q40 ) ); /* Q24 */ + err = silk_SUB32( (opus_int32)1 << 24, silk_SMULWW( tmp_32, one_div_diag_Q40 ) ); /* Q24 */ one_div_diag_Q48 = silk_SMULWW( err, one_div_diag_Q40 ); /* Q48 */ /* Save 1/Ds */ diff --git a/media/libopus/silk/fixed/structs_FIX.h b/media/libopus/silk/fixed/structs_FIX.h index badff6a03dd3..244b4793445e 100644 --- a/media/libopus/silk/fixed/structs_FIX.h +++ b/media/libopus/silk/fixed/structs_FIX.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/fixed/vector_ops_FIX.c b/media/libopus/silk/fixed/vector_ops_FIX.c index 3e2be9f700bc..509c8b35a112 100644 --- a/media/libopus/silk/fixed/vector_ops_FIX.c +++ b/media/libopus/silk/fixed/vector_ops_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -98,34 +94,3 @@ opus_int64 silk_inner_prod16_aligned_64( } return sum; } - -/* Function that returns the maximum absolut value of the input vector */ -opus_int16 silk_int16_array_maxabs( /* O Maximum absolute value, max: 2^15-1 */ - const opus_int16 *vec, /* I Input vector [len] */ - const opus_int32 len /* I Length of input vector */ -) -{ - opus_int32 max = 0, i, lvl = 0, ind; - if( len == 0 ) return 0; - - ind = len - 1; - max = silk_SMULBB( vec[ ind ], vec[ ind ] ); - for( i = len - 2; i >= 0; i-- ) { - lvl = silk_SMULBB( vec[ i ], vec[ i ] ); - if( lvl > max ) { - max = lvl; - ind = i; - } - } - - /* Do not return 32768, as it will not fit in an int16 so may lead to problems later on */ - if( max >= 1073676289 ) { /* (2^15-1)^2 = 1073676289 */ - return( silk_int16_MAX ); - } else { - if( vec[ ind ] < 0 ) { - return( -vec[ ind ] ); - } else { - return( vec[ ind ] ); - } - } -} diff --git a/media/libopus/silk/fixed/warped_autocorrelation_FIX.c b/media/libopus/silk/fixed/warped_autocorrelation_FIX.c index f52497b0eb06..a4a579b10d78 100644 --- a/media/libopus/silk/fixed/warped_autocorrelation_FIX.c +++ b/media/libopus/silk/fixed/warped_autocorrelation_FIX.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/LPC_analysis_filter_FLP.c b/media/libopus/silk/float/LPC_analysis_filter_FLP.c index e6254251c11e..3bb9244be1ca 100644 --- a/media/libopus/silk/float/LPC_analysis_filter_FLP.c +++ b/media/libopus/silk/float/LPC_analysis_filter_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/LPC_inv_pred_gain_FLP.c b/media/libopus/silk/float/LPC_inv_pred_gain_FLP.c index 0923f16a5263..25178bacdde4 100644 --- a/media/libopus/silk/float/LPC_inv_pred_gain_FLP.c +++ b/media/libopus/silk/float/LPC_inv_pred_gain_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/LTP_analysis_filter_FLP.c b/media/libopus/silk/float/LTP_analysis_filter_FLP.c index 5804b6087ec0..849b7c1c528b 100644 --- a/media/libopus/silk/float/LTP_analysis_filter_FLP.c +++ b/media/libopus/silk/float/LTP_analysis_filter_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -37,13 +33,13 @@ POSSIBILITY OF SUCH DAMAGE. void silk_LTP_analysis_filter_FLP( silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */ - const silk_float *x, /* I Input signal, with preceeding samples */ + const silk_float *x, /* I Input signal, with preceding samples */ const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */ const opus_int subfr_length, /* I Length of each subframe */ const opus_int nb_subfr, /* I number of subframes */ - const opus_int pre_length /* I Preceeding samples for each subframe */ + const opus_int pre_length /* I Preceding samples for each subframe */ ) { const silk_float *x_ptr, *x_lag_ptr; diff --git a/media/libopus/silk/float/LTP_scale_ctrl_FLP.c b/media/libopus/silk/float/LTP_scale_ctrl_FLP.c index a4a7f4a0b73c..8dbe29d0fa6b 100644 --- a/media/libopus/silk/float/LTP_scale_ctrl_FLP.c +++ b/media/libopus/silk/float/LTP_scale_ctrl_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/SigProc_FLP.h b/media/libopus/silk/float/SigProc_FLP.h index 1821111175d8..2f5bb4cbf106 100644 --- a/media/libopus/silk/float/SigProc_FLP.h +++ b/media/libopus/silk/float/SigProc_FLP.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -113,7 +109,7 @@ silk_float silk_burg_modified_FLP( /* O returns residual energy silk_float A[], /* O prediction coefficients (length order) */ const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */ const silk_float minInvGain, /* I minimum inverse prediction gain */ - const opus_int subfr_length, /* I input signal subframe length (incl. D preceeding samples) */ + const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */ const opus_int nb_subfr, /* I number of subframes stacked in x */ const opus_int D /* I order */ ); @@ -156,9 +152,6 @@ double silk_energy_FLP( #define silk_max_float( a, b ) (((a) > (b)) ? (a) : (b)) #define silk_abs_float( a ) ((silk_float)fabs(a)) -#define silk_LIMIT_float( a, limit1, limit2 ) ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ - : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))) - /* sigmoid function */ static inline silk_float silk_sigmoid( silk_float x ) { diff --git a/media/libopus/silk/float/apply_sine_window_FLP.c b/media/libopus/silk/float/apply_sine_window_FLP.c index a7ab8773ab40..6aae57c0ab99 100644 --- a/media/libopus/silk/float/apply_sine_window_FLP.c +++ b/media/libopus/silk/float/apply_sine_window_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/autocorrelation_FLP.c b/media/libopus/silk/float/autocorrelation_FLP.c index 802d0a217f98..8b8a9e659aae 100644 --- a/media/libopus/silk/float/autocorrelation_FLP.c +++ b/media/libopus/silk/float/autocorrelation_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/burg_modified_FLP.c b/media/libopus/silk/float/burg_modified_FLP.c index 15c8d776c4a9..ea5dc25a93a7 100644 --- a/media/libopus/silk/float/burg_modified_FLP.c +++ b/media/libopus/silk/float/burg_modified_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -44,7 +40,7 @@ silk_float silk_burg_modified_FLP( /* O returns residual energy silk_float A[], /* O prediction coefficients (length order) */ const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */ const silk_float minInvGain, /* I minimum inverse prediction gain */ - const opus_int subfr_length, /* I input signal subframe length (incl. D preceeding samples) */ + const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */ const opus_int nb_subfr, /* I number of subframes stacked in x */ const opus_int D /* I order */ ) @@ -166,7 +162,7 @@ silk_float silk_burg_modified_FLP( /* O returns residual energy for( k = 0; k < D; k++ ) { A[ k ] = (silk_float)( -Af[ k ] ); } - /* Subtract energy of preceeding samples from C0 */ + /* Subtract energy of preceding samples from C0 */ for( s = 0; s < nb_subfr; s++ ) { C0 -= silk_energy_FLP( x + s * subfr_length, D ); } diff --git a/media/libopus/silk/float/bwexpander_FLP.c b/media/libopus/silk/float/bwexpander_FLP.c index 307a962bd536..d55a4d79ab63 100644 --- a/media/libopus/silk/float/bwexpander_FLP.c +++ b/media/libopus/silk/float/bwexpander_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/corrMatrix_FLP.c b/media/libopus/silk/float/corrMatrix_FLP.c index ef91a69e5e33..eae6a1cfca29 100644 --- a/media/libopus/silk/float/corrMatrix_FLP.c +++ b/media/libopus/silk/float/corrMatrix_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/encode_frame_FLP.c b/media/libopus/silk/float/encode_frame_FLP.c index f84fa4827e34..3221686614f5 100644 --- a/media/libopus/silk/float/encode_frame_FLP.c +++ b/media/libopus/silk/float/encode_frame_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/energy_FLP.c b/media/libopus/silk/float/energy_FLP.c index 26f059777b9c..24b8179f9e3b 100644 --- a/media/libopus/silk/float/energy_FLP.c +++ b/media/libopus/silk/float/energy_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/find_LPC_FLP.c b/media/libopus/silk/float/find_LPC_FLP.c index 5187d7edc72f..61c1ad9554b4 100644 --- a/media/libopus/silk/float/find_LPC_FLP.c +++ b/media/libopus/silk/float/find_LPC_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -103,6 +99,6 @@ void silk_find_LPC_FLP( silk_A2NLSF_FLP( NLSF_Q15, a, psEncC->predictLPCOrder ); } - silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || + silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) ); } diff --git a/media/libopus/silk/float/find_LTP_FLP.c b/media/libopus/silk/float/find_LTP_FLP.c index 98ce4ce77e90..722999601409 100644 --- a/media/libopus/silk/float/find_LTP_FLP.c +++ b/media/libopus/silk/float/find_LTP_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/find_pitch_lags_FLP.c b/media/libopus/silk/float/find_pitch_lags_FLP.c index 395690ced44d..455db82f2443 100644 --- a/media/libopus/silk/float/find_pitch_lags_FLP.c +++ b/media/libopus/silk/float/find_pitch_lags_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -58,7 +54,7 @@ void silk_find_pitch_lags_FLP( /******************************************/ buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; - /* Safty check */ + /* Safety check */ silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); x_buf = x - psEnc->sCmn.ltp_mem_length; @@ -100,7 +96,7 @@ void silk_find_pitch_lags_FLP( silk_k2a_FLP( A, refl_coef, psEnc->sCmn.pitchEstimationLPCOrder ); /* Bandwidth expansion */ - silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWITH_EXPANSION ); + silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWIDTH_EXPANSION ); /*****************************************/ /* LPC analysis filtering */ diff --git a/media/libopus/silk/float/find_pred_coefs_FLP.c b/media/libopus/silk/float/find_pred_coefs_FLP.c index 248d8c380289..0c6f0d6bf51c 100644 --- a/media/libopus/silk/float/find_pred_coefs_FLP.c +++ b/media/libopus/silk/float/find_pred_coefs_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -99,7 +95,7 @@ void silk_find_pred_coefs_FLP( /* Limit on total predictive coding gain */ if( psEnc->sCmn.first_frame_after_reset ) { minInvGain = 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET; - } else { + } else { minInvGain = (silk_float)pow( 2, psEncCtrl->LTPredCodGain / 3 ) / MAX_PREDICTION_POWER_GAIN; minInvGain /= 0.25f + 0.75f * psEncCtrl->coding_quality; } diff --git a/media/libopus/silk/float/inner_product_FLP.c b/media/libopus/silk/float/inner_product_FLP.c index 6166f9473fb3..029c012911da 100644 --- a/media/libopus/silk/float/inner_product_FLP.c +++ b/media/libopus/silk/float/inner_product_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/k2a_FLP.c b/media/libopus/silk/float/k2a_FLP.c index a8ffc1d25942..12af4e76697a 100644 --- a/media/libopus/silk/float/k2a_FLP.c +++ b/media/libopus/silk/float/k2a_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/levinsondurbin_FLP.c b/media/libopus/silk/float/levinsondurbin_FLP.c index 587da42ff107..f0ba6069812f 100644 --- a/media/libopus/silk/float/levinsondurbin_FLP.c +++ b/media/libopus/silk/float/levinsondurbin_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/main_FLP.h b/media/libopus/silk/float/main_FLP.h index ee060242a269..dbd34aef462a 100644 --- a/media/libopus/silk/float/main_FLP.h +++ b/media/libopus/silk/float/main_FLP.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -168,17 +164,17 @@ void silk_find_LTP_FLP( void silk_LTP_analysis_filter_FLP( silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */ - const silk_float *x, /* I Input signal, with preceeding samples */ + const silk_float *x, /* I Input signal, with preceding samples */ const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */ const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */ const opus_int subfr_length, /* I Length of each subframe */ const opus_int nb_subfr, /* I number of subframes */ - const opus_int pre_length /* I Preceeding samples for each subframe */ + const opus_int pre_length /* I Preceding samples for each subframe */ ); /* Calculates residual energies of input subframes where all subframes have LPC_order */ -/* of preceeding samples */ +/* of preceding samples */ void silk_residual_energy_FLP( silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ const silk_float x[], /* I Input signal */ diff --git a/media/libopus/silk/float/noise_shape_analysis_FLP.c b/media/libopus/silk/float/noise_shape_analysis_FLP.c index 07e44eac5d3a..e7c26fc030d2 100644 --- a/media/libopus/silk/float/noise_shape_analysis_FLP.c +++ b/media/libopus/silk/float/noise_shape_analysis_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -178,7 +174,7 @@ void silk_noise_shape_analysis_FLP( /*************************/ /* Set quantizer offset */ if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Initally set to 0; may be overruled in process_gains(..) */ + /* Initially set to 0; may be overruled in process_gains(..) */ psEnc->sCmn.indices.quantOffsetType = 0; psEncCtrl->sparseness = 0.0f; } else { diff --git a/media/libopus/silk/float/pitch_analysis_core_FLP.c b/media/libopus/silk/float/pitch_analysis_core_FLP.c index 20d3e7631728..605ea25fa271 100644 --- a/media/libopus/silk/float/pitch_analysis_core_FLP.c +++ b/media/libopus/silk/float/pitch_analysis_core_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -39,9 +35,9 @@ POSSIBILITY OF SUCH DAMAGE. #include "SigProc_FLP.h" #include "SigProc_FIX.h" #include "pitch_est_defines.h" +#include "pitch.h" #define SCRATCH_SIZE 22 -#define eps 1.192092896e-07f /************************************************************/ /* Internally used functions */ @@ -89,6 +85,7 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, opus_int32 filt_state[ 6 ]; silk_float threshold, contour_bias; silk_float C[ PE_MAX_NB_SUBFR][ (PE_MAX_LAG >> 1) + 5 ]; + opus_val32 xcorr[ PE_MAX_LAG_MS * 4 - PE_MIN_LAG_MS * 4 + 1 ]; silk_float CC[ PE_NB_CBKS_STAGE2_EXT ]; const silk_float *target_ptr, *basis_ptr; double cross_corr, normalizer, energy, energy_tmp; @@ -133,8 +130,6 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, max_lag_4kHz = PE_MAX_LAG_MS * 4; max_lag_8kHz = PE_MAX_LAG_MS * 8 - 1; - silk_memset(C, 0, sizeof(silk_float) * nb_subfr * ((PE_MAX_LAG >> 1) + 5)); - /* Resample from input sampled at Fs_kHz to 8 kHz */ if( Fs_kHz == 16 ) { /* Resample to 16 -> 8 khz */ @@ -168,6 +163,7 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, /****************************************************************************** * FIRST STAGE, operating in 4 khz ******************************************************************************/ + silk_memset(C, 0, sizeof(silk_float) * nb_subfr * ((PE_MAX_LAG >> 1) + 5)); target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ]; for( k = 0; k < nb_subfr >> 1; k++ ) { /* Check that we are within range of the array */ @@ -180,27 +176,31 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, silk_assert( basis_ptr >= frame_4kHz ); silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); - /* Calculate first vector products before loop */ - cross_corr = silk_inner_product_FLP( target_ptr, basis_ptr, sf_length_8kHz ); - normalizer = silk_energy_FLP( basis_ptr, sf_length_8kHz ) + sf_length_8kHz * 4000.0f; + celt_pitch_xcorr( target_ptr, target_ptr-max_lag_4kHz, xcorr, sf_length_8kHz, max_lag_4kHz - min_lag_4kHz + 1 ); - C[ 0 ][ min_lag_4kHz ] += (silk_float)(cross_corr / sqrt(normalizer)); + /* Calculate first vector products before loop */ + cross_corr = xcorr[ max_lag_4kHz - min_lag_4kHz ]; + normalizer = silk_energy_FLP( target_ptr, sf_length_8kHz ) + + silk_energy_FLP( basis_ptr, sf_length_8kHz ) + + sf_length_8kHz * 4000.0f; + + C[ 0 ][ min_lag_4kHz ] += (silk_float)( 2 * cross_corr / normalizer ); /* From now on normalizer is computed recursively */ - for(d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++) { + for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) { basis_ptr--; /* Check that we are within range of the array */ silk_assert( basis_ptr >= frame_4kHz ); silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); - cross_corr = silk_inner_product_FLP(target_ptr, basis_ptr, sf_length_8kHz); + cross_corr = xcorr[ max_lag_4kHz - d ]; /* Add contribution of new sample and remove contribution from oldest sample */ normalizer += basis_ptr[ 0 ] * (double)basis_ptr[ 0 ] - basis_ptr[ sf_length_8kHz ] * (double)basis_ptr[ sf_length_8kHz ]; - C[ 0 ][ d ] += (silk_float)(cross_corr / sqrt( normalizer )); + C[ 0 ][ d ] += (silk_float)( 2 * cross_corr / normalizer ); } /* Update target pointer */ target_ptr += sf_length_8kHz; @@ -218,13 +218,7 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, /* Escape if correlation is very low already here */ Cmax = C[ 0 ][ min_lag_4kHz ]; - target_ptr = &frame_4kHz[ silk_SMULBB( sf_length_4kHz, nb_subfr ) ]; - energy = 1000.0f; - for( i = 0; i < silk_LSHIFT( sf_length_4kHz, 2 ); i++ ) { - energy += target_ptr[i] * (double)target_ptr[i]; - } - threshold = Cmax * Cmax; - if( energy / 16.0f > threshold ) { + if( Cmax < 0.2f ) { silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); *LTPCorr = 0.0f; *lagIndex = 0; @@ -291,14 +285,14 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ]; } for( k = 0; k < nb_subfr; k++ ) { - energy_tmp = silk_energy_FLP( target_ptr, sf_length_8kHz ); + energy_tmp = silk_energy_FLP( target_ptr, sf_length_8kHz ) + 1.0; for( j = 0; j < length_d_comp; j++ ) { d = d_comp[ j ]; basis_ptr = target_ptr - d; cross_corr = silk_inner_product_FLP( basis_ptr, target_ptr, sf_length_8kHz ); - energy = silk_energy_FLP( basis_ptr, sf_length_8kHz ); if( cross_corr > 0.0f ) { - C[ k ][ d ] = (silk_float)(cross_corr * cross_corr / (energy * energy_tmp + eps)); + energy = silk_energy_FLP( basis_ptr, sf_length_8kHz ); + C[ k ][ d ] = (silk_float)( 2 * cross_corr / ( energy + energy_tmp ) ); } else { C[ k ][ d ] = 0.0f; } @@ -321,7 +315,7 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, } else if( Fs_kHz == 16 ) { prevLag = silk_RSHIFT( prevLag, 1 ); } - prevLag_log2 = silk_log2((silk_float)prevLag); + prevLag_log2 = silk_log2( (silk_float)prevLag ); } else { prevLag_log2 = 0; } @@ -360,23 +354,20 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, CBimax_new = i; } } - CCmax_new = silk_max_float(CCmax_new, 0.0f); /* To avoid taking square root of negative number later */ - CCmax_new_b = CCmax_new; /* Bias towards shorter lags */ - lag_log2 = silk_log2((silk_float)d); - CCmax_new_b -= PE_SHORTLAG_BIAS * nb_subfr * lag_log2; + lag_log2 = silk_log2( (silk_float)d ); + CCmax_new_b = CCmax_new - PE_SHORTLAG_BIAS * nb_subfr * lag_log2; /* Bias towards previous lag */ if( prevLag > 0 ) { delta_lag_log2_sqr = lag_log2 - prevLag_log2; delta_lag_log2_sqr *= delta_lag_log2_sqr; - CCmax_new_b -= PE_PREVLAG_BIAS * nb_subfr * (*LTPCorr) * delta_lag_log2_sqr / (delta_lag_log2_sqr + 0.5f); + CCmax_new_b -= PE_PREVLAG_BIAS * nb_subfr * (*LTPCorr) * delta_lag_log2_sqr / ( delta_lag_log2_sqr + 0.5f ); } - if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */ - CCmax_new > nb_subfr * search_thres2 * search_thres2 && /* Correlation needs to be high enough to be voiced */ - silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= min_lag_8kHz /* Lag must be in range */ + if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */ + CCmax_new > nb_subfr * search_thres2 /* Correlation needs to be high enough to be voiced */ ) { CCmax_b = CCmax_new_b; CCmax = CCmax_new; @@ -394,6 +385,10 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, return 1; } + /* Output normalized correlation */ + *LTPCorr = (silk_float)( CCmax / nb_subfr ); + silk_assert( *LTPCorr >= 0.0f ); + if( Fs_kHz > 8 ) { /* Search in original signal */ @@ -410,8 +405,6 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, end_lag = silk_min_int( lag + 2, max_lag ); lag_new = lag; /* to avoid undefined lag */ CBimax = 0; /* to avoid undefined lag */ - silk_assert( CCmax >= 0.0f ); - *LTPCorr = (silk_float)sqrt( CCmax / nb_subfr ); /* Output normalized correlation */ CCmax = -1000.0f; @@ -423,7 +416,7 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, silk_assert( lag == silk_SAT16( lag ) ); contour_bias = PE_FLATCONTOUR_BIAS / lag; - /* Set up cbk parameters acording to complexity setting and frame length */ + /* Set up cbk parameters according to complexity setting and frame length */ if( nb_subfr == PE_MAX_NB_SUBFR ) { nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ]; cbk_size = PE_NB_CBKS_STAGE3_MAX; @@ -434,25 +427,25 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; } + target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ]; + energy_tmp = silk_energy_FLP( target_ptr, nb_subfr * sf_length ) + 1.0; for( d = start_lag; d <= end_lag; d++ ) { for( j = 0; j < nb_cbk_search; j++ ) { cross_corr = 0.0; - energy = eps; + energy = energy_tmp; for( k = 0; k < nb_subfr; k++ ) { - energy += energies_st3[ k ][ j ][ lag_counter ]; cross_corr += cross_corr_st3[ k ][ j ][ lag_counter ]; + energy += energies_st3[ k ][ j ][ lag_counter ]; } if( cross_corr > 0.0 ) { - CCmax_new = (silk_float)(cross_corr * cross_corr / energy); + CCmax_new = (silk_float)( 2 * cross_corr / energy ); /* Reduce depending on flatness of contour */ CCmax_new *= 1.0f - contour_bias * j; } else { CCmax_new = 0.0f; } - if( CCmax_new > CCmax && - ( d + (opus_int)silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag - ) { + if( CCmax_new > CCmax && ( d + (opus_int)silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) { CCmax = CCmax_new; lag_new = d; CBimax = j; @@ -468,12 +461,10 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, *lagIndex = (opus_int16)( lag_new - min_lag ); *contourIndex = (opus_int8)CBimax; } else { /* Fs_kHz == 8 */ - /* Save Lags and correlation */ - silk_assert( CCmax >= 0.0f ); - *LTPCorr = (silk_float)sqrt( CCmax / nb_subfr ); /* Output normalized correlation */ + /* Save Lags */ for( k = 0; k < nb_subfr; k++ ) { pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); - pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * Fs_kHz ); + pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * 8 ); } *lagIndex = (opus_int16)( lag - min_lag_8kHz ); *contourIndex = (opus_int8)CBimax; @@ -483,6 +474,19 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, return 0; } +/*********************************************************************** + * Calculates the correlations used in stage 3 search. In order to cover + * the whole lag codebook for all the searched offset lags (lag +- 2), + * the following correlations are needed in each sub frame: + * + * sf1: lag range [-8,...,7] total 16 correlations + * sf2: lag range [-4,...,4] total 9 correlations + * sf3: lag range [-3,....4] total 8 correltions + * sf4: lag range [-6,....8] total 15 correlations + * + * In total 48 correlations. The direct implementation computed in worst + * case 4*12*5 = 240 correlations, but more likely around 120. + ***********************************************************************/ static void silk_P_Ana_calc_corr_st3( silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ const silk_float frame[], /* I vector to correlate */ @@ -491,24 +495,12 @@ static void silk_P_Ana_calc_corr_st3( opus_int nb_subfr, /* I number of subframes */ opus_int complexity /* I Complexity setting */ ) - /*********************************************************************** - Calculates the correlations used in stage 3 search. In order to cover - the whole lag codebook for all the searched offset lags (lag +- 2), - the following correlations are needed in each sub frame: - - sf1: lag range [-8,...,7] total 16 correlations - sf2: lag range [-4,...,4] total 9 correlations - sf3: lag range [-3,....4] total 8 correltions - sf4: lag range [-6,....8] total 15 correlations - - In total 48 correlations. The direct implementation computed in worst case - 4*12*5 = 240 correlations, but more likely around 120. - **********************************************************************/ { const silk_float *target_ptr, *basis_ptr; opus_int i, j, k, lag_counter, lag_low, lag_high; opus_int nb_cbk_search, delta, idx, cbk_size; silk_float scratch_mem[ SCRATCH_SIZE ]; + opus_val32 xcorr[ SCRATCH_SIZE ]; const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; silk_assert( complexity >= SILK_PE_MIN_COMPLEX ); @@ -534,10 +526,12 @@ static void silk_P_Ana_calc_corr_st3( /* Calculate the correlations for each subframe */ lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 ); lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 ); + silk_assert(lag_high-lag_low+1 <= SCRATCH_SIZE); + celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr, sf_length, lag_high - lag_low + 1 ); for( j = lag_low; j <= lag_high; j++ ) { basis_ptr = target_ptr - ( start_lag + j ); silk_assert( lag_counter < SCRATCH_SIZE ); - scratch_mem[ lag_counter ] = (silk_float)silk_inner_product_FLP( target_ptr, basis_ptr, sf_length ); + scratch_mem[ lag_counter ] = xcorr[ lag_high - j ]; lag_counter++; } @@ -556,6 +550,10 @@ static void silk_P_Ana_calc_corr_st3( } } +/********************************************************************/ +/* Calculate the energies for first two subframes. The energies are */ +/* calculated recursively. */ +/********************************************************************/ static void silk_P_Ana_calc_energy_st3( silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ const silk_float frame[], /* I vector to correlate */ @@ -564,10 +562,6 @@ static void silk_P_Ana_calc_energy_st3( opus_int nb_subfr, /* I number of subframes */ opus_int complexity /* I Complexity setting */ ) -/**************************************************************** -Calculate the energies for first two subframes. The energies are -calculated recursively. -****************************************************************/ { const silk_float *target_ptr, *basis_ptr; double energy; diff --git a/media/libopus/silk/float/prefilter_FLP.c b/media/libopus/silk/float/prefilter_FLP.c index aeaa814994c2..a3f81c9596e9 100644 --- a/media/libopus/silk/float/prefilter_FLP.c +++ b/media/libopus/silk/float/prefilter_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -51,7 +47,7 @@ static inline void silk_prefilt_FLP( opus_int length /* I */ ); -void silk_warped_LPC_analysis_filter_FLP( +static void silk_warped_LPC_analysis_filter_FLP( silk_float state[], /* I/O State [order + 1] */ silk_float res[], /* O Residual signal [length] */ const silk_float coef[], /* I Coefficients [order] */ diff --git a/media/libopus/silk/float/process_gains_FLP.c b/media/libopus/silk/float/process_gains_FLP.c index b29515153059..c0da0dae44b0 100644 --- a/media/libopus/silk/float/process_gains_FLP.c +++ b/media/libopus/silk/float/process_gains_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/regularize_correlations_FLP.c b/media/libopus/silk/float/regularize_correlations_FLP.c index 43f6e67d7863..df4612604ca0 100644 --- a/media/libopus/silk/float/regularize_correlations_FLP.c +++ b/media/libopus/silk/float/regularize_correlations_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/residual_energy_FLP.c b/media/libopus/silk/float/residual_energy_FLP.c index f3c1d800289e..b2e03a86a490 100644 --- a/media/libopus/silk/float/residual_energy_FLP.c +++ b/media/libopus/silk/float/residual_energy_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -91,7 +87,7 @@ silk_float silk_residual_energy_covar_FLP( /* O } /* Calculates residual energies of input subframes where all subframes have LPC_order */ -/* of preceeding samples */ +/* of preceding samples */ void silk_residual_energy_FLP( silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ const silk_float x[], /* I Input signal */ diff --git a/media/libopus/silk/float/scale_copy_vector_FLP.c b/media/libopus/silk/float/scale_copy_vector_FLP.c index 319324895216..20db32b3b19a 100644 --- a/media/libopus/silk/float/scale_copy_vector_FLP.c +++ b/media/libopus/silk/float/scale_copy_vector_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/scale_vector_FLP.c b/media/libopus/silk/float/scale_vector_FLP.c index 1f23913bd76a..108fdcbed54d 100644 --- a/media/libopus/silk/float/scale_vector_FLP.c +++ b/media/libopus/silk/float/scale_vector_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/schur_FLP.c b/media/libopus/silk/float/schur_FLP.c index ab920f264c17..ee436f8351c8 100644 --- a/media/libopus/silk/float/schur_FLP.c +++ b/media/libopus/silk/float/schur_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/solve_LS_FLP.c b/media/libopus/silk/float/solve_LS_FLP.c index 413f6eb8aee1..0eda65a4fb08 100644 --- a/media/libopus/silk/float/solve_LS_FLP.c +++ b/media/libopus/silk/float/solve_LS_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/sort_FLP.c b/media/libopus/silk/float/sort_FLP.c index cce23599647f..f08d7592c56e 100644 --- a/media/libopus/silk/float/sort_FLP.c +++ b/media/libopus/silk/float/sort_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/structs_FLP.h b/media/libopus/silk/float/structs_FLP.h index 46a6c89c19bf..bb529e71a44d 100644 --- a/media/libopus/silk/float/structs_FLP.h +++ b/media/libopus/silk/float/structs_FLP.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/warped_autocorrelation_FLP.c b/media/libopus/silk/float/warped_autocorrelation_FLP.c index aa554c7bcf0f..542414f48ec5 100644 --- a/media/libopus/silk/float/warped_autocorrelation_FLP.c +++ b/media/libopus/silk/float/warped_autocorrelation_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/float/wrappers_FLP.c b/media/libopus/silk/float/wrappers_FLP.c index 36ed55578338..0d33d9e5e272 100644 --- a/media/libopus/silk/float/wrappers_FLP.c +++ b/media/libopus/silk/float/wrappers_FLP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -159,7 +155,7 @@ void silk_NSQ_wrapper_FLP( /* Convert input to fix */ for( i = 0; i < psEnc->sCmn.frame_length; i++ ) { - x_Q3[ i ] = silk_float2int( 8.0 * x[ i ] ); + x_Q3[ i ] = silk_float2int( 8.0f * x[ i ] ); } /* Call NSQ */ diff --git a/media/libopus/silk/gain_quant.c b/media/libopus/silk/gain_quant.c index a4475f64c700..64ccd0611bff 100644 --- a/media/libopus/silk/gain_quant.c +++ b/media/libopus/silk/gain_quant.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/init_decoder.c b/media/libopus/silk/init_decoder.c index 7d195a0de7bf..f887c67886fb 100644 --- a/media/libopus/silk/init_decoder.c +++ b/media/libopus/silk/init_decoder.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/init_encoder.c b/media/libopus/silk/init_encoder.c index dca29839a4c4..7a4d918c4b20 100644 --- a/media/libopus/silk/init_encoder.c +++ b/media/libopus/silk/init_encoder.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/inner_prod_aligned.c b/media/libopus/silk/inner_prod_aligned.c index fcbc9d933d07..257ae9e04eb3 100644 --- a/media/libopus/silk/inner_prod_aligned.c +++ b/media/libopus/silk/inner_prod_aligned.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/interpolate.c b/media/libopus/silk/interpolate.c index cbe58eb77e5e..1bd8ca4d5327 100644 --- a/media/libopus/silk/interpolate.c +++ b/media/libopus/silk/interpolate.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/lin2log.c b/media/libopus/silk/lin2log.c index 7d3f45fd08ee..d4fe515321f0 100644 --- a/media/libopus/silk/lin2log.c +++ b/media/libopus/silk/lin2log.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/log2lin.c b/media/libopus/silk/log2lin.c index 227221917a05..07d97a955e52 100644 --- a/media/libopus/silk/log2lin.c +++ b/media/libopus/silk/log2lin.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -37,7 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. /* Approximation of 2^() (very close inverse of silk_lin2log()) */ /* Convert input to a linear scale */ -opus_int32 silk_log2lin( +opus_int32 silk_log2lin( const opus_int32 inLog_Q7 /* I input on log scale */ ) { @@ -51,7 +47,7 @@ opus_int32 silk_log2lin( frac_Q7 = inLog_Q7 & 0x7F; if( inLog_Q7 < 2048 ) { /* Piece-wise parabolic approximation */ - out = silk_ADD_RSHIFT( out, silk_MUL( out, silk_SMLAWB( frac_Q7, silk_SMULBB( frac_Q7, 128 - frac_Q7 ), -174 ) ), 7 ); + out = silk_ADD_RSHIFT32( out, silk_MUL( out, silk_SMLAWB( frac_Q7, silk_SMULBB( frac_Q7, 128 - frac_Q7 ), -174 ) ), 7 ); } else { /* Piece-wise parabolic approximation */ out = silk_MLA( out, silk_RSHIFT( out, 7 ), silk_SMLAWB( frac_Q7, silk_SMULBB( frac_Q7, 128 - frac_Q7 ), -174 ) ); diff --git a/media/libopus/silk/macros.h b/media/libopus/silk/macros.h index d0d99a2e1679..35d63fa4356f 100644 --- a/media/libopus/silk/macros.h +++ b/media/libopus/silk/macros.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -72,69 +68,45 @@ POSSIBILITY OF SUCH DAMAGE. #define silk_SMLAWW(a32, b32, c32) silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16)) /* add/subtract with output saturated */ -#define silk_ADD_SAT32(a, b) ((((a) + (b)) & 0x80000000) == 0 ? \ +#define silk_ADD_SAT32(a, b) ((((opus_uint32)(a) + (opus_uint32)(b)) & 0x80000000) == 0 ? \ ((((a) & (b)) & 0x80000000) != 0 ? silk_int32_MIN : (a)+(b)) : \ ((((a) | (b)) & 0x80000000) == 0 ? silk_int32_MAX : (a)+(b)) ) -#define silk_SUB_SAT32(a, b) ((((a)-(b)) & 0x80000000) == 0 ? \ +#define silk_SUB_SAT32(a, b) ((((opus_uint32)(a)-(opus_uint32)(b)) & 0x80000000) == 0 ? \ (( (a) & ((b)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a)-(b)) : \ ((((a)^0x80000000) & (b) & 0x80000000) ? silk_int32_MAX : (a)-(b)) ) +#include "ecintrin.h" + static inline opus_int32 silk_CLZ16(opus_int16 in16) { - opus_int32 out32 = 0; - if( in16 == 0 ) { - return 16; - } - /* test nibbles */ - if( in16 & 0xFF00 ) { - if( in16 & 0xF000 ) { - in16 >>= 12; - } else { - out32 += 4; - in16 >>= 8; - } - } else { - if( in16 & 0xFFF0 ) { - out32 += 8; - in16 >>= 4; - } else { - out32 += 12; - } - } - /* test bits and return */ - if( in16 & 0xC ) { - if( in16 & 0x8 ) - return out32 + 0; - else - return out32 + 1; - } else { - if( in16 & 0xE ) - return out32 + 2; - else - return out32 + 3; - } + return 32 - EC_ILOG(in16<<16|0x8000); } static inline opus_int32 silk_CLZ32(opus_int32 in32) { - /* test highest 16 bits and convert to opus_int16 */ - if( in32 & 0xFFFF0000 ) { - return silk_CLZ16((opus_int16)(in32 >> 16)); - } else { - return silk_CLZ16((opus_int16)in32) + 16; - } + return in32 ? 32 - EC_ILOG(in32) : 32; } /* Row based */ -#define matrix_ptr(Matrix_base_adr, row, column, N) *(Matrix_base_adr + ((row)*(N)+(column))) -#define matrix_adr(Matrix_base_adr, row, column, N) (Matrix_base_adr + ((row)*(N)+(column))) +#define matrix_ptr(Matrix_base_adr, row, column, N) \ + (*((Matrix_base_adr) + ((row)*(N)+(column)))) +#define matrix_adr(Matrix_base_adr, row, column, N) \ + ((Matrix_base_adr) + ((row)*(N)+(column))) /* Column based */ #ifndef matrix_c_ptr -# define matrix_c_ptr(Matrix_base_adr, row, column, M) *(Matrix_base_adr + ((row)+(M)*(column))) +# define matrix_c_ptr(Matrix_base_adr, row, column, M) \ + (*((Matrix_base_adr) + ((row)+(M)*(column)))) +#endif + +#ifdef ARMv4_ASM +#include "arm/macros_armv4.h" +#endif + +#ifdef ARMv5E_ASM +#include "arm/macros_armv5e.h" #endif -#define matrix_c_adr(Matrix_base_adr, row, column, M) (Matrix_base_adr + ((row)+(M)*(column))) #endif /* SILK_MACROS_H */ diff --git a/media/libopus/silk/main.h b/media/libopus/silk/main.h index 665cc392df65..8676316e597b 100644 --- a/media/libopus/silk/main.h +++ b/media/libopus/silk/main.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -361,7 +357,7 @@ opus_int silk_init_decoder( opus_int silk_decoder_set_fs( silk_decoder_state *psDec, /* I/O Decoder state pointer */ opus_int fs_kHz, /* I Sampling frequency (kHz) */ - opus_int fs_API_Hz /* I API Sampling frequency (Hz) */ + opus_int32 fs_API_Hz /* I API Sampling frequency (Hz) */ ); /****************/ diff --git a/media/libopus/silk/pitch_est_defines.h b/media/libopus/silk/pitch_est_defines.h index 9d847182c1e6..e1e4b5d76866 100644 --- a/media/libopus/silk/pitch_est_defines.h +++ b/media/libopus/silk/pitch_est_defines.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -49,7 +45,6 @@ POSSIBILITY OF SUCH DAMAGE. #define PE_MAX_FRAME_LENGTH ( PE_MAX_FRAME_LENGTH_MS * PE_MAX_FS_KHZ ) #define PE_MAX_FRAME_LENGTH_ST_1 ( PE_MAX_FRAME_LENGTH >> 2 ) #define PE_MAX_FRAME_LENGTH_ST_2 ( PE_MAX_FRAME_LENGTH >> 1 ) -#define PE_MAX_SF_FRAME_LENGTH ( PE_SUB_FRAME * PE_MAX_FS_KHZ ) #define PE_MAX_LAG_MS 18 /* 18 ms -> 56 Hz */ #define PE_MIN_LAG_MS 2 /* 2 ms -> 500 Hz */ @@ -63,9 +58,6 @@ POSSIBILITY OF SUCH DAMAGE. #define PE_NB_CBKS_STAGE2 3 #define PE_NB_CBKS_STAGE2_EXT 11 -#define PE_CB_mn2 1 -#define PE_CB_mx2 2 - #define PE_NB_CBKS_STAGE3_MAX 34 #define PE_NB_CBKS_STAGE3_MID 24 #define PE_NB_CBKS_STAGE3_MIN 16 diff --git a/media/libopus/silk/pitch_est_tables.c b/media/libopus/silk/pitch_est_tables.c index 5e23bec7a73d..81a8bacaca2b 100644 --- a/media/libopus/silk/pitch_est_tables.c +++ b/media/libopus/silk/pitch_est_tables.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/process_NLSFs.c b/media/libopus/silk/process_NLSFs.c index c24ef1acfd0f..c27cf0304697 100644 --- a/media/libopus/silk/process_NLSFs.c +++ b/media/libopus/silk/process_NLSFs.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -83,7 +79,7 @@ void silk_process_NLSFs( /* Update NLSF weights with contribution from first half */ i_sqr_Q15 = silk_LSHIFT( silk_SMULBB( psEncC->indices.NLSFInterpCoef_Q2, psEncC->indices.NLSFInterpCoef_Q2 ), 11 ); for( i = 0; i < psEncC->predictLPCOrder; i++ ) { - pNLSFW_QW[ i ] = silk_SMLAWB( silk_RSHIFT( pNLSFW_QW[ i ], 1 ), pNLSFW0_temp_QW[ i ], i_sqr_Q15 ); + pNLSFW_QW[ i ] = silk_SMLAWB( silk_RSHIFT( pNLSFW_QW[ i ], 1 ), (opus_int32)pNLSFW0_temp_QW[ i ], i_sqr_Q15 ); silk_assert( pNLSFW_QW[ i ] >= 1 ); } } diff --git a/media/libopus/silk/quant_LTP_gains.c b/media/libopus/silk/quant_LTP_gains.c index 2ffa801141c6..43b43cb8d806 100644 --- a/media/libopus/silk/quant_LTP_gains.c +++ b/media/libopus/silk/quant_LTP_gains.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/resampler.c b/media/libopus/silk/resampler.c index 3b6d2adb8927..374fbb37225a 100644 --- a/media/libopus/silk/resampler.c +++ b/media/libopus/silk/resampler.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/resampler_down2.c b/media/libopus/silk/resampler_down2.c index 92adaa5b741c..cec36346408b 100644 --- a/media/libopus/silk/resampler_down2.c +++ b/media/libopus/silk/resampler_down2.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -39,8 +35,8 @@ POSSIBILITY OF SUCH DAMAGE. /* Downsample by a factor 2 */ void silk_resampler_down2( opus_int32 *S, /* I/O State vector [ 2 ] */ - opus_int16 *out, /* O Output signal [ len ] */ - const opus_int16 *in, /* I Input signal [ floor(len/2) ] */ + opus_int16 *out, /* O Output signal [ floor(len/2) ] */ + const opus_int16 *in, /* I Input signal [ len ] */ opus_int32 inLen /* I Number of input samples */ ) { diff --git a/media/libopus/silk/resampler_down2_3.c b/media/libopus/silk/resampler_down2_3.c index 9ec5f5099599..4342614dcccc 100644 --- a/media/libopus/silk/resampler_down2_3.c +++ b/media/libopus/silk/resampler_down2_3.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -35,6 +31,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "SigProc_FIX.h" #include "resampler_private.h" +#include "stack_alloc.h" #define ORDER_FIR 4 @@ -47,8 +44,11 @@ void silk_resampler_down2_3( ) { opus_int32 nSamplesIn, counter, res_Q6; - opus_int32 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR ]; + VARDECL( opus_int32, buf ); opus_int32 *buf_ptr; + SAVE_STACK; + + ALLOC( buf, RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR, opus_int32 ); /* Copy buffered samples to start of buffer */ silk_memcpy( buf, S, ORDER_FIR * sizeof( opus_int32 ) ); @@ -99,4 +99,5 @@ void silk_resampler_down2_3( /* Copy last part of filtered signal to the state for the next call */ silk_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) ); + RESTORE_STACK; } diff --git a/media/libopus/silk/resampler_private.h b/media/libopus/silk/resampler_private.h index 263e172ff013..422a7d9d9537 100644 --- a/media/libopus/silk/resampler_private.h +++ b/media/libopus/silk/resampler_private.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/resampler_private_AR2.c b/media/libopus/silk/resampler_private_AR2.c index 4d10150a4d7d..5fff23714f9e 100644 --- a/media/libopus/silk/resampler_private_AR2.c +++ b/media/libopus/silk/resampler_private_AR2.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/resampler_private_IIR_FIR.c b/media/libopus/silk/resampler_private_IIR_FIR.c index dbd6d9a86725..4cc8f3b35e58 100644 --- a/media/libopus/silk/resampler_private_IIR_FIR.c +++ b/media/libopus/silk/resampler_private_IIR_FIR.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -35,6 +31,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "SigProc_FIX.h" #include "resampler_private.h" +#include "stack_alloc.h" static inline opus_int16 *silk_resampler_private_IIR_FIR_INTERPOL( opus_int16 *out, @@ -75,10 +72,13 @@ void silk_resampler_private_IIR_FIR( silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS; opus_int32 nSamplesIn; opus_int32 max_index_Q16, index_increment_Q16; - opus_int16 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_ORDER_FIR_12 ]; + VARDECL( opus_int16, buf ); + SAVE_STACK; + + ALLOC( buf, 2 * S->batchSize + RESAMPLER_ORDER_FIR_12, opus_int16 ); /* Copy buffered samples to start of buffer */ - silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) ); + silk_memcpy( buf, S->sFIR.i16, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) ); /* Iterate over blocks of frameSizeIn input samples */ index_increment_Q16 = S->invRatio_Q16; @@ -95,13 +95,13 @@ void silk_resampler_private_IIR_FIR( if( inLen > 0 ) { /* More iterations to do; copy last part of filtered signal to beginning of buffer */ - silk_memcpy( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) ); + silk_memcpy( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) ); } else { break; } } /* Copy last part of filtered signal to the state for the next call */ - silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) ); + silk_memcpy( S->sFIR.i16, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) ); + RESTORE_STACK; } - diff --git a/media/libopus/silk/resampler_private_down_FIR.c b/media/libopus/silk/resampler_private_down_FIR.c index 1fbe91d8acb3..73b1c4098ca4 100644 --- a/media/libopus/silk/resampler_private_down_FIR.c +++ b/media/libopus/silk/resampler_private_down_FIR.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -35,6 +31,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "SigProc_FIX.h" #include "resampler_private.h" +#include "stack_alloc.h" static inline opus_int16 *silk_resampler_private_down_FIR_INTERPOL( opus_int16 *out, @@ -155,11 +152,14 @@ void silk_resampler_private_down_FIR( silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS; opus_int32 nSamplesIn; opus_int32 max_index_Q16, index_increment_Q16; - opus_int32 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + SILK_RESAMPLER_MAX_FIR_ORDER ]; + VARDECL( opus_int32, buf ); const opus_int16 *FIR_Coefs; + SAVE_STACK; + + ALLOC( buf, S->batchSize + S->FIR_Order, opus_int32 ); /* Copy buffered samples to start of buffer */ - silk_memcpy( buf, S->sFIR, S->FIR_Order * sizeof( opus_int32 ) ); + silk_memcpy( buf, S->sFIR.i32, S->FIR_Order * sizeof( opus_int32 ) ); FIR_Coefs = &S->Coefs[ 2 ]; @@ -189,5 +189,6 @@ void silk_resampler_private_down_FIR( } /* Copy last part of filtered signal to the state for the next call */ - silk_memcpy( S->sFIR, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) ); + silk_memcpy( S->sFIR.i32, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) ); + RESTORE_STACK; } diff --git a/media/libopus/silk/resampler_private_up2_HQ.c b/media/libopus/silk/resampler_private_up2_HQ.c index 75044bf8efb3..c7ec8de3651d 100644 --- a/media/libopus/silk/resampler_private_up2_HQ.c +++ b/media/libopus/silk/resampler_private_up2_HQ.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/resampler_rom.c b/media/libopus/silk/resampler_rom.c index 9cf910eb771c..2d502706f9fe 100644 --- a/media/libopus/silk/resampler_rom.c +++ b/media/libopus/silk/resampler_rom.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -38,18 +34,10 @@ POSSIBILITY OF SUCH DAMAGE. #include "resampler_private.h" -/* Tables for 2x downsampler */ -const opus_int16 silk_resampler_down2_0 = 9872; -const opus_int16 silk_resampler_down2_1 = 39809 - 65536; - -/* Tables for 2x upsampler, high quality */ -const opus_int16 silk_resampler_up2_hq_0[ 3 ] = { 1746, 14986, 39083 - 65536 }; -const opus_int16 silk_resampler_up2_hq_1[ 3 ] = { 6854, 25769, 55542 - 65536 }; - /* Matlab code for the notch filter coefficients: */ /* B = [1, 0.147, 1]; A = [1, 0.107, 0.89]; G = 0.93; freqz(G * B, A, 2^14, 16e3); axis([0, 8000, -10, 1]) */ /* fprintf('\t%6d, %6d, %6d, %6d\n', round(B(2)*2^16), round(-A(2)*2^16), round((1-A(3))*2^16), round(G*2^15)) */ -const opus_int16 silk_resampler_up2_hq_notch[ 4 ] = { 9634, -7012, 7209, 30474 }; +/* const opus_int16 silk_resampler_up2_hq_notch[ 4 ] = { 9634, -7012, 7209, 30474 }; */ /* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */ silk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = { diff --git a/media/libopus/silk/resampler_rom.h b/media/libopus/silk/resampler_rom.h index faab1539ba89..490b3388dced 100644 --- a/media/libopus/silk/resampler_rom.h +++ b/media/libopus/silk/resampler_rom.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -46,12 +42,12 @@ extern "C" #define RESAMPLER_ORDER_FIR_12 8 /* Tables for 2x downsampler */ -extern const opus_int16 silk_resampler_down2_0; -extern const opus_int16 silk_resampler_down2_1; +static const opus_int16 silk_resampler_down2_0 = 9872; +static const opus_int16 silk_resampler_down2_1 = 39809 - 65536; /* Tables for 2x upsampler, high quality */ -extern const opus_int16 silk_resampler_up2_hq_0[ 3 ]; -extern const opus_int16 silk_resampler_up2_hq_1[ 3 ]; +static const opus_int16 silk_resampler_up2_hq_0[ 3 ] = { 1746, 14986, 39083 - 65536 }; +static const opus_int16 silk_resampler_up2_hq_1[ 3 ] = { 6854, 25769, 55542 - 65536 }; /* Tables with IIR and FIR coefficients for fractional downsamplers */ extern const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ]; diff --git a/media/libopus/silk/resampler_structs.h b/media/libopus/silk/resampler_structs.h index d79f10b29352..9e9457d11cac 100644 --- a/media/libopus/silk/resampler_structs.h +++ b/media/libopus/silk/resampler_structs.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -41,7 +37,10 @@ extern "C" { typedef struct _silk_resampler_state_struct{ opus_int32 sIIR[ SILK_RESAMPLER_MAX_IIR_ORDER ]; /* this must be the first element of this struct */ - opus_int32 sFIR[ SILK_RESAMPLER_MAX_FIR_ORDER ]; + union{ + opus_int32 i32[ SILK_RESAMPLER_MAX_FIR_ORDER ]; + opus_int16 i16[ SILK_RESAMPLER_MAX_FIR_ORDER ]; + } sFIR; opus_int16 delayBuf[ 48 ]; opus_int resampler_function; opus_int batchSize; diff --git a/media/libopus/silk/shell_coder.c b/media/libopus/silk/shell_coder.c index 50a0deb3873b..9fe5e40f37c0 100644 --- a/media/libopus/silk/shell_coder.c +++ b/media/libopus/silk/shell_coder.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/sigm_Q15.c b/media/libopus/silk/sigm_Q15.c index 1f4439e5c846..3c507d255b15 100644 --- a/media/libopus/silk/sigm_Q15.c +++ b/media/libopus/silk/sigm_Q15.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/sort.c b/media/libopus/silk/sort.c index e3a295ee0cc7..8670dbdd02c7 100644 --- a/media/libopus/silk/sort.c +++ b/media/libopus/silk/sort.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/stereo_LR_to_MS.c b/media/libopus/silk/stereo_LR_to_MS.c index 5fa4bb85f3e7..42906e6f6769 100644 --- a/media/libopus/silk/stereo_LR_to_MS.c +++ b/media/libopus/silk/stereo_LR_to_MS.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "main.h" +#include "stack_alloc.h" /* Convert Left/Right stereo signal to adaptive Mid/Side representation */ void silk_stereo_LR_to_MS( @@ -53,11 +50,15 @@ void silk_stereo_LR_to_MS( opus_int n, is10msFrame, denom_Q16, delta0_Q13, delta1_Q13; opus_int32 sum, diff, smooth_coef_Q16, pred_Q13[ 2 ], pred0_Q13, pred1_Q13; opus_int32 LP_ratio_Q14, HP_ratio_Q14, frac_Q16, frac_3_Q16, min_mid_rate_bps, width_Q14, w_Q24, deltaw_Q24; - opus_int16 side[ MAX_FRAME_LENGTH + 2 ]; - opus_int16 LP_mid[ MAX_FRAME_LENGTH ], HP_mid[ MAX_FRAME_LENGTH ]; - opus_int16 LP_side[ MAX_FRAME_LENGTH ], HP_side[ MAX_FRAME_LENGTH ]; + VARDECL( opus_int16, side ); + VARDECL( opus_int16, LP_mid ); + VARDECL( opus_int16, HP_mid ); + VARDECL( opus_int16, LP_side ); + VARDECL( opus_int16, HP_side ); opus_int16 *mid = &x1[ -2 ]; + SAVE_STACK; + ALLOC( side, frame_length + 2, opus_int16 ); /* Convert to basic mid/side signals */ for( n = 0; n < frame_length + 2; n++ ) { sum = x1[ n - 2 ] + (opus_int32)x2[ n - 2 ]; @@ -73,6 +74,8 @@ void silk_stereo_LR_to_MS( silk_memcpy( state->sSide, &side[ frame_length ], 2 * sizeof( opus_int16 ) ); /* LP and HP filter mid signal */ + ALLOC( LP_mid, frame_length, opus_int16 ); + ALLOC( HP_mid, frame_length, opus_int16 ); for( n = 0; n < frame_length; n++ ) { sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 ); LP_mid[ n ] = sum; @@ -80,6 +83,8 @@ void silk_stereo_LR_to_MS( } /* LP and HP filter side signal */ + ALLOC( LP_side, frame_length, opus_int16 ); + ALLOC( HP_side, frame_length, opus_int16 ); for( n = 0; n < frame_length; n++ ) { sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( side[ n ] + side[ n + 2 ], side[ n + 1 ], 1 ), 2 ); LP_side[ n ] = sum; @@ -194,7 +199,7 @@ void silk_stereo_LR_to_MS( pred0_Q13 = -state->pred_prev_Q13[ 0 ]; pred1_Q13 = -state->pred_prev_Q13[ 1 ]; w_Q24 = silk_LSHIFT( state->width_prev_Q14, 10 ); - denom_Q16 = silk_DIV32_16( 1 << 16, STEREO_INTERP_LEN_MS * fs_kHz ); + denom_Q16 = silk_DIV32_16( (opus_int32)1 << 16, STEREO_INTERP_LEN_MS * fs_kHz ); delta0_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 0 ] - state->pred_prev_Q13[ 0 ], denom_Q16 ), 16 ); delta1_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 1 ] - state->pred_prev_Q13[ 1 ], denom_Q16 ), 16 ); deltaw_Q24 = silk_LSHIFT( silk_SMULWB( width_Q14 - state->width_prev_Q14, denom_Q16 ), 10 ); @@ -220,4 +225,5 @@ void silk_stereo_LR_to_MS( state->pred_prev_Q13[ 0 ] = (opus_int16)pred_Q13[ 0 ]; state->pred_prev_Q13[ 1 ] = (opus_int16)pred_Q13[ 1 ]; state->width_prev_Q14 = (opus_int16)width_Q14; + RESTORE_STACK; } diff --git a/media/libopus/silk/stereo_MS_to_LR.c b/media/libopus/silk/stereo_MS_to_LR.c index 210d599b7c01..62521a4f352f 100644 --- a/media/libopus/silk/stereo_MS_to_LR.c +++ b/media/libopus/silk/stereo_MS_to_LR.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -57,7 +53,7 @@ void silk_stereo_MS_to_LR( /* Interpolate predictors and add prediction to side channel */ pred0_Q13 = state->pred_prev_Q13[ 0 ]; pred1_Q13 = state->pred_prev_Q13[ 1 ]; - denom_Q16 = silk_DIV32_16( 1 << 16, STEREO_INTERP_LEN_MS * fs_kHz ); + denom_Q16 = silk_DIV32_16( (opus_int32)1 << 16, STEREO_INTERP_LEN_MS * fs_kHz ); delta0_Q13 = silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 0 ] - state->pred_prev_Q13[ 0 ], denom_Q16 ), 16 ); delta1_Q13 = silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 1 ] - state->pred_prev_Q13[ 1 ], denom_Q16 ), 16 ); for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) { diff --git a/media/libopus/silk/stereo_decode_pred.c b/media/libopus/silk/stereo_decode_pred.c index 117daa22c1d2..56ba3925e871 100644 --- a/media/libopus/silk/stereo_decode_pred.c +++ b/media/libopus/silk/stereo_decode_pred.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/stereo_encode_pred.c b/media/libopus/silk/stereo_encode_pred.c index d8b086834c18..e6dd19506640 100644 --- a/media/libopus/silk/stereo_encode_pred.c +++ b/media/libopus/silk/stereo_encode_pred.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/stereo_find_predictor.c b/media/libopus/silk/stereo_find_predictor.c index 247c181ec2d9..e30e90bddc28 100644 --- a/media/libopus/silk/stereo_find_predictor.c +++ b/media/libopus/silk/stereo_find_predictor.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/stereo_quant_pred.c b/media/libopus/silk/stereo_quant_pred.c index ec2a2ec77a86..d4ced6c3e82f 100644 --- a/media/libopus/silk/stereo_quant_pred.c +++ b/media/libopus/silk/stereo_quant_pred.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/structs.h b/media/libopus/silk/structs.h index 48fc8977040c..4ccd0c1ae390 100644 --- a/media/libopus/silk/structs.h +++ b/media/libopus/silk/structs.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/sum_sqr_shift.c b/media/libopus/silk/sum_sqr_shift.c index 31527809b86c..12514c9917af 100644 --- a/media/libopus/silk/sum_sqr_shift.c +++ b/media/libopus/silk/sum_sqr_shift.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/table_LSF_cos.c b/media/libopus/silk/table_LSF_cos.c index e89b389504a5..ec9dc6392791 100644 --- a/media/libopus/silk/table_LSF_cos.c +++ b/media/libopus/silk/table_LSF_cos.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/tables.h b/media/libopus/silk/tables.h index b651d986937f..18bf9f2d6580 100644 --- a/media/libopus/silk/tables.h +++ b/media/libopus/silk/tables.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/tables_LTP.c b/media/libopus/silk/tables_LTP.c index 5739ad59b4a0..b0cff4433479 100644 --- a/media/libopus/silk/tables_LTP.c +++ b/media/libopus/silk/tables_LTP.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -39,16 +35,16 @@ const opus_uint8 silk_LTP_per_index_iCDF[3] = { 179, 99, 0 }; -const opus_uint8 silk_LTP_gain_iCDF_0[8] = { +static const opus_uint8 silk_LTP_gain_iCDF_0[8] = { 71, 56, 43, 30, 21, 12, 6, 0 }; -const opus_uint8 silk_LTP_gain_iCDF_1[16] = { +static const opus_uint8 silk_LTP_gain_iCDF_1[16] = { 199, 165, 144, 124, 109, 96, 84, 71, 61, 51, 42, 32, 23, 15, 8, 0 }; -const opus_uint8 silk_LTP_gain_iCDF_2[32] = { +static const opus_uint8 silk_LTP_gain_iCDF_2[32] = { 241, 225, 211, 199, 187, 175, 164, 153, 142, 132, 123, 114, 105, 96, 88, 80, 72, 64, 57, 50, 44, 38, 33, 29, @@ -57,16 +53,16 @@ const opus_uint8 silk_LTP_gain_iCDF_2[32] = { const opus_int16 silk_LTP_gain_middle_avg_RD_Q14 = 12304; -const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = { +static const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = { 15, 131, 138, 138, 155, 155, 173, 173 }; -const opus_uint8 silk_LTP_gain_BITS_Q5_1[16] = { +static const opus_uint8 silk_LTP_gain_BITS_Q5_1[16] = { 69, 93, 115, 118, 131, 138, 141, 138, 150, 150, 155, 150, 155, 160, 166, 160 }; -const opus_uint8 silk_LTP_gain_BITS_Q5_2[32] = { +static const opus_uint8 silk_LTP_gain_BITS_Q5_2[32] = { 131, 128, 134, 141, 141, 141, 145, 145, 145, 150, 155, 155, 155, 155, 160, 160, 160, 160, 166, 166, 173, 173, 182, 192, @@ -85,7 +81,7 @@ const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[NB_LTP_CBKS] = { silk_LTP_gain_BITS_Q5_2 }; -const opus_int8 silk_LTP_gain_vq_0[8][5] = +static const opus_int8 silk_LTP_gain_vq_0[8][5] = { { 4, 6, 24, 7, 5 @@ -113,7 +109,7 @@ const opus_int8 silk_LTP_gain_vq_0[8][5] = } }; -const opus_int8 silk_LTP_gain_vq_1[16][5] = +static const opus_int8 silk_LTP_gain_vq_1[16][5] = { { 13, 22, 39, 23, 12 @@ -165,7 +161,7 @@ const opus_int8 silk_LTP_gain_vq_1[16][5] = } }; -const opus_int8 silk_LTP_gain_vq_2[32][5] = +static const opus_int8 silk_LTP_gain_vq_2[32][5] = { { -6, 27, 61, 39, 5 diff --git a/media/libopus/silk/tables_NLSF_CB_NB_MB.c b/media/libopus/silk/tables_NLSF_CB_NB_MB.c index 7cd80c0f44d5..8c59d207aa00 100644 --- a/media/libopus/silk/tables_NLSF_CB_NB_MB.c +++ b/media/libopus/silk/tables_NLSF_CB_NB_MB.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -35,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "tables.h" -const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = { +static const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = { 12, 35, 60, 83, 108, 132, 157, 180, 206, 228, 15, 32, 55, 77, 101, 125, 151, 175, 201, 225, 19, 42, 66, 89, @@ -78,7 +74,7 @@ const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = { 64, 84, 104, 118, 156, 177, 201, 230 }; -const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = { +static const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = { 212, 178, 148, 129, 108, 96, 85, 82, 79, 77, 61, 59, 57, 56, 51, 49, 48, 45, 42, 41, 40, 38, 36, 34, @@ -89,7 +85,7 @@ const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = { 28, 20, 19, 18, 12, 11, 5, 0 }; -const opus_uint8 silk_NLSF_CB2_SELECT_NB_MB[ 160 ] = { +static const opus_uint8 silk_NLSF_CB2_SELECT_NB_MB[ 160 ] = { 16, 0, 0, 0, 0, 99, 66, 36, 36, 34, 36, 34, 34, 34, 34, 83, 69, 36, 52, 34, 116, 102, 70, 68, @@ -112,7 +108,7 @@ const opus_uint8 silk_NLSF_CB2_SELECT_NB_MB[ 160 ] = { 171, 137, 139, 137, 155, 218, 219, 139 }; -const opus_uint8 silk_NLSF_CB2_iCDF_NB_MB[ 72 ] = { +static const opus_uint8 silk_NLSF_CB2_iCDF_NB_MB[ 72 ] = { 255, 254, 253, 238, 14, 3, 2, 1, 0, 255, 254, 252, 218, 35, 3, 2, 1, 0, 255, 254, 250, 208, 59, 4, @@ -124,7 +120,7 @@ const opus_uint8 silk_NLSF_CB2_iCDF_NB_MB[ 72 ] = { 254, 236, 173, 95, 37, 7, 1, 0 }; -const opus_uint8 silk_NLSF_CB2_BITS_NB_MB_Q5[ 72 ] = { +static const opus_uint8 silk_NLSF_CB2_BITS_NB_MB_Q5[ 72 ] = { 255, 255, 255, 131, 6, 145, 255, 255, 255, 255, 255, 236, 93, 15, 96, 255, 255, 255, 255, 255, 194, 83, 25, 71, @@ -136,13 +132,13 @@ const opus_uint8 silk_NLSF_CB2_BITS_NB_MB_Q5[ 72 ] = { 251, 123, 65, 55, 68, 100, 171, 255 }; -const opus_uint8 silk_NLSF_PRED_NB_MB_Q8[ 18 ] = { +static const opus_uint8 silk_NLSF_PRED_NB_MB_Q8[ 18 ] = { 179, 138, 140, 148, 151, 149, 153, 151, 163, 116, 67, 82, 59, 92, 72, 100, 89, 92 }; -const opus_int16 silk_NLSF_DELTA_MIN_NB_MB_Q15[ 11 ] = { +static const opus_int16 silk_NLSF_DELTA_MIN_NB_MB_Q15[ 11 ] = { 250, 3, 6, 3, 3, 3, 4, 3, 3, 3, 461 }; diff --git a/media/libopus/silk/tables_NLSF_CB_WB.c b/media/libopus/silk/tables_NLSF_CB_WB.c index 5dc9b38bdfa3..50af87eb2e1c 100644 --- a/media/libopus/silk/tables_NLSF_CB_WB.c +++ b/media/libopus/silk/tables_NLSF_CB_WB.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -35,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "tables.h" -const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = { +static const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = { 7, 23, 38, 54, 69, 85, 100, 116, 131, 147, 162, 178, 193, 208, 223, 239, 13, 25, 41, 55, 69, 83, 98, 112, @@ -102,7 +98,7 @@ const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = { 110, 119, 129, 141, 175, 198, 218, 237 }; -const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = { +static const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = { 225, 204, 201, 184, 183, 175, 158, 154, 153, 135, 119, 115, 113, 110, 109, 99, 98, 95, 79, 68, 52, 50, 48, 45, @@ -113,7 +109,7 @@ const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = { 24, 21, 11, 6, 5, 4, 3, 0 }; -const opus_uint8 silk_NLSF_CB2_SELECT_WB[ 256 ] = { +static const opus_uint8 silk_NLSF_CB2_SELECT_WB[ 256 ] = { 0, 0, 0, 0, 0, 0, 0, 1, 100, 102, 102, 68, 68, 36, 34, 96, 164, 107, 158, 185, 180, 185, 139, 102, @@ -148,7 +144,7 @@ const opus_uint8 silk_NLSF_CB2_SELECT_WB[ 256 ] = { 100, 107, 120, 119, 36, 197, 24, 0 }; -const opus_uint8 silk_NLSF_CB2_iCDF_WB[ 72 ] = { +static const opus_uint8 silk_NLSF_CB2_iCDF_WB[ 72 ] = { 255, 254, 253, 244, 12, 3, 2, 1, 0, 255, 254, 252, 224, 38, 3, 2, 1, 0, 255, 254, 251, 209, 57, 4, @@ -160,7 +156,7 @@ const opus_uint8 silk_NLSF_CB2_iCDF_WB[ 72 ] = { 248, 227, 177, 100, 19, 2, 1, 0 }; -const opus_uint8 silk_NLSF_CB2_BITS_WB_Q5[ 72 ] = { +static const opus_uint8 silk_NLSF_CB2_BITS_WB_Q5[ 72 ] = { 255, 255, 255, 156, 4, 154, 255, 255, 255, 255, 255, 227, 102, 15, 92, 255, 255, 255, 255, 255, 213, 83, 24, 72, @@ -172,14 +168,14 @@ const opus_uint8 silk_NLSF_CB2_BITS_WB_Q5[ 72 ] = { 166, 116, 76, 55, 53, 125, 255, 255 }; -const opus_uint8 silk_NLSF_PRED_WB_Q8[ 30 ] = { +static const opus_uint8 silk_NLSF_PRED_WB_Q8[ 30 ] = { 175, 148, 160, 176, 178, 173, 174, 164, 177, 174, 196, 182, 198, 192, 182, 68, 62, 66, 60, 72, 117, 85, 90, 118, 136, 151, 142, 160, 142, 155 }; -const opus_int16 silk_NLSF_DELTA_MIN_WB_Q15[ 17 ] = { +static const opus_int16 silk_NLSF_DELTA_MIN_WB_Q15[ 17 ] = { 100, 3, 40, 3, 3, 3, 5, 14, 14, 10, 11, 3, 8, 9, 7, 3, 347 diff --git a/media/libopus/silk/tables_gain.c b/media/libopus/silk/tables_gain.c index 58c8364ac354..37e41d890c33 100644 --- a/media/libopus/silk/tables_gain.c +++ b/media/libopus/silk/tables_gain.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/tables_other.c b/media/libopus/silk/tables_other.c index be45b0764a65..398686bf26b9 100644 --- a/media/libopus/silk/tables_other.c +++ b/media/libopus/silk/tables_other.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -71,8 +67,8 @@ const opus_uint8 silk_stereo_pred_joint_iCDF[ 25 ] = { const opus_uint8 silk_stereo_only_code_mid_iCDF[ 2 ] = { 64, 0 }; /* Tables for LBRR flags */ -const opus_uint8 silk_LBRR_flags_2_iCDF[ 3 ] = { 203, 150, 0 }; -const opus_uint8 silk_LBRR_flags_3_iCDF[ 7 ] = { 215, 195, 166, 125, 110, 82, 0 }; +static const opus_uint8 silk_LBRR_flags_2_iCDF[ 3 ] = { 203, 150, 0 }; +static const opus_uint8 silk_LBRR_flags_3_iCDF[ 7 ] = { 215, 195, 166, 125, 110, 82, 0 }; const opus_uint8 * const silk_LBRR_flags_iCDF_ptr[ 2 ] = { silk_LBRR_flags_2_iCDF, silk_LBRR_flags_3_iCDF diff --git a/media/libopus/silk/tables_pitch_lag.c b/media/libopus/silk/tables_pitch_lag.c index 151531e0e5a6..e80cc59a2729 100644 --- a/media/libopus/silk/tables_pitch_lag.c +++ b/media/libopus/silk/tables_pitch_lag.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/tables_pulses_per_block.c b/media/libopus/silk/tables_pulses_per_block.c index 08a3c14cdf38..c7c01c8893fa 100644 --- a/media/libopus/silk/tables_pulses_per_block.c +++ b/media/libopus/silk/tables_pulses_per_block.c @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE diff --git a/media/libopus/silk/tuning_parameters.h b/media/libopus/silk/tuning_parameters.h index 6f64420f904c..bf4f63f012b8 100644 --- a/media/libopus/silk/tuning_parameters.h +++ b/media/libopus/silk/tuning_parameters.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -48,7 +44,7 @@ extern "C" #define FIND_PITCH_WHITE_NOISE_FRACTION 1e-3f /* Bandwidth expansion for whitening filter in pitch analysis */ -#define FIND_PITCH_BANDWITH_EXPANSION 0.99f +#define FIND_PITCH_BANDWIDTH_EXPANSION 0.99f /*********************/ /* Linear prediction */ diff --git a/media/libopus/silk/typedef.h b/media/libopus/silk/typedef.h index 2d15443aaca4..6394cde87866 100644 --- a/media/libopus/silk/typedef.h +++ b/media/libopus/silk/typedef.h @@ -1,9 +1,5 @@ /*********************************************************************** -Copyright (c) 2006-2012 IETF Trust and Skype Limited. All rights reserved. - -This file is extracted from RFC6716. Please see that RFC for additional -information. - +Copyright (c) 2006-2011, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,7 +12,7 @@ documentation and/or other materials provided with the distribution. names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE @@ -34,31 +30,12 @@ POSSIBILITY OF SUCH DAMAGE. #include "opus_types.h" -#ifndef silk_USE_DOUBLE_PRECISION_FLOATS -#define silk_USE_DOUBLE_PRECISION_FLOATS 0 -#endif - -#include -#if defined( __GNUC__ ) -#include -#endif - -#define silk_int_ptr_size intptr_t - -#if silk_USE_DOUBLE_PRECISION_FLOATS -# define silk_float double -# define silk_float_MAX DBL_MAX -#else +#ifndef FIXED_POINT +# include # define silk_float float # define silk_float_MAX FLT_MAX #endif -#ifdef _WIN32 -# define silk_STR_CASEINSENSITIVE_COMPARE(x, y) _stricmp(x, y) -#else -# define silk_STR_CASEINSENSITIVE_COMPARE(x, y) strcasecmp(x, y) -#endif - #define silk_int64_MAX ((opus_int64)0x7FFFFFFFFFFFFFFFLL) /* 2^63 - 1 */ #define silk_int64_MIN ((opus_int64)0x8000000000000000LL) /* -2^63 */ #define silk_int32_MAX 0x7FFFFFFF /* 2^31 - 1 = 2147483647 */ @@ -67,13 +44,7 @@ POSSIBILITY OF SUCH DAMAGE. #define silk_int16_MIN ((opus_int16)0x8000) /* -2^15 = -32768 */ #define silk_int8_MAX 0x7F /* 2^7 - 1 = 127 */ #define silk_int8_MIN ((opus_int8)0x80) /* -2^7 = -128 */ - -#define silk_uint32_MAX 0xFFFFFFFF /* 2^32 - 1 = 4294967295 */ -#define silk_uint32_MIN 0x00000000 -#define silk_uint16_MAX 0xFFFF /* 2^16 - 1 = 65535 */ -#define silk_uint16_MIN 0x0000 -#define silk_uint8_MAX 0xFF /* 2^8 - 1 = 255 */ -#define silk_uint8_MIN 0x00 +#define silk_uint8_MAX 0xFF /* 2^8 - 1 = 255 */ #define silk_TRUE 1 #define silk_FALSE 0 diff --git a/media/libopus/silk_sources.mk b/media/libopus/silk_sources.mk index 53c628b64e4f..0de367b43bbf 100644 --- a/media/libopus/silk_sources.mk +++ b/media/libopus/silk_sources.mk @@ -1,36 +1,3 @@ -# Copyright (c) 2011-2012 IETF Trust, Jean-Marc Valin. All rights reserved. -# -# This file is extracted from RFC6716. Please see that RFC for additional -# information. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# - Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# - Neither the name of Internet Society, IETF or IETF Trust, nor the -# names of specific contributors, may be used to endorse or promote -# products derived from this software without specific prior written -# permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - SILK_SOURCES = \ silk/CNG.c \ silk/code_signs.c \ diff --git a/media/libopus/src/analysis.c b/media/libopus/src/analysis.c new file mode 100644 index 000000000000..a9d2073fed6e --- /dev/null +++ b/media/libopus/src/analysis.c @@ -0,0 +1,654 @@ +/* Copyright (c) 2011 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "kiss_fft.h" +#include "celt.h" +#include "modes.h" +#include "arch.h" +#include "quant_bands.h" +#include +#include "analysis.h" +#include "mlp.h" +#include "stack_alloc.h" + +extern const MLP net; + +#ifndef M_PI +#define M_PI 3.141592653 +#endif + +static const float dct_table[128] = { + 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, + 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, + 0.351851f, 0.338330f, 0.311806f, 0.273300f, 0.224292f, 0.166664f, 0.102631f, 0.034654f, + -0.034654f,-0.102631f,-0.166664f,-0.224292f,-0.273300f,-0.311806f,-0.338330f,-0.351851f, + 0.346760f, 0.293969f, 0.196424f, 0.068975f,-0.068975f,-0.196424f,-0.293969f,-0.346760f, + -0.346760f,-0.293969f,-0.196424f,-0.068975f, 0.068975f, 0.196424f, 0.293969f, 0.346760f, + 0.338330f, 0.224292f, 0.034654f,-0.166664f,-0.311806f,-0.351851f,-0.273300f,-0.102631f, + 0.102631f, 0.273300f, 0.351851f, 0.311806f, 0.166664f,-0.034654f,-0.224292f,-0.338330f, + 0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f, + 0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f, + 0.311806f, 0.034654f,-0.273300f,-0.338330f,-0.102631f, 0.224292f, 0.351851f, 0.166664f, + -0.166664f,-0.351851f,-0.224292f, 0.102631f, 0.338330f, 0.273300f,-0.034654f,-0.311806f, + 0.293969f,-0.068975f,-0.346760f,-0.196424f, 0.196424f, 0.346760f, 0.068975f,-0.293969f, + -0.293969f, 0.068975f, 0.346760f, 0.196424f,-0.196424f,-0.346760f,-0.068975f, 0.293969f, + 0.273300f,-0.166664f,-0.338330f, 0.034654f, 0.351851f, 0.102631f,-0.311806f,-0.224292f, + 0.224292f, 0.311806f,-0.102631f,-0.351851f,-0.034654f, 0.338330f, 0.166664f,-0.273300f, +}; + +static const float analysis_window[240] = { + 0.000043f, 0.000171f, 0.000385f, 0.000685f, 0.001071f, 0.001541f, 0.002098f, 0.002739f, + 0.003466f, 0.004278f, 0.005174f, 0.006156f, 0.007222f, 0.008373f, 0.009607f, 0.010926f, + 0.012329f, 0.013815f, 0.015385f, 0.017037f, 0.018772f, 0.020590f, 0.022490f, 0.024472f, + 0.026535f, 0.028679f, 0.030904f, 0.033210f, 0.035595f, 0.038060f, 0.040604f, 0.043227f, + 0.045928f, 0.048707f, 0.051564f, 0.054497f, 0.057506f, 0.060591f, 0.063752f, 0.066987f, + 0.070297f, 0.073680f, 0.077136f, 0.080665f, 0.084265f, 0.087937f, 0.091679f, 0.095492f, + 0.099373f, 0.103323f, 0.107342f, 0.111427f, 0.115579f, 0.119797f, 0.124080f, 0.128428f, + 0.132839f, 0.137313f, 0.141849f, 0.146447f, 0.151105f, 0.155823f, 0.160600f, 0.165435f, + 0.170327f, 0.175276f, 0.180280f, 0.185340f, 0.190453f, 0.195619f, 0.200838f, 0.206107f, + 0.211427f, 0.216797f, 0.222215f, 0.227680f, 0.233193f, 0.238751f, 0.244353f, 0.250000f, + 0.255689f, 0.261421f, 0.267193f, 0.273005f, 0.278856f, 0.284744f, 0.290670f, 0.296632f, + 0.302628f, 0.308658f, 0.314721f, 0.320816f, 0.326941f, 0.333097f, 0.339280f, 0.345492f, + 0.351729f, 0.357992f, 0.364280f, 0.370590f, 0.376923f, 0.383277f, 0.389651f, 0.396044f, + 0.402455f, 0.408882f, 0.415325f, 0.421783f, 0.428254f, 0.434737f, 0.441231f, 0.447736f, + 0.454249f, 0.460770f, 0.467298f, 0.473832f, 0.480370f, 0.486912f, 0.493455f, 0.500000f, + 0.506545f, 0.513088f, 0.519630f, 0.526168f, 0.532702f, 0.539230f, 0.545751f, 0.552264f, + 0.558769f, 0.565263f, 0.571746f, 0.578217f, 0.584675f, 0.591118f, 0.597545f, 0.603956f, + 0.610349f, 0.616723f, 0.623077f, 0.629410f, 0.635720f, 0.642008f, 0.648271f, 0.654508f, + 0.660720f, 0.666903f, 0.673059f, 0.679184f, 0.685279f, 0.691342f, 0.697372f, 0.703368f, + 0.709330f, 0.715256f, 0.721144f, 0.726995f, 0.732807f, 0.738579f, 0.744311f, 0.750000f, + 0.755647f, 0.761249f, 0.766807f, 0.772320f, 0.777785f, 0.783203f, 0.788573f, 0.793893f, + 0.799162f, 0.804381f, 0.809547f, 0.814660f, 0.819720f, 0.824724f, 0.829673f, 0.834565f, + 0.839400f, 0.844177f, 0.848895f, 0.853553f, 0.858151f, 0.862687f, 0.867161f, 0.871572f, + 0.875920f, 0.880203f, 0.884421f, 0.888573f, 0.892658f, 0.896677f, 0.900627f, 0.904508f, + 0.908321f, 0.912063f, 0.915735f, 0.919335f, 0.922864f, 0.926320f, 0.929703f, 0.933013f, + 0.936248f, 0.939409f, 0.942494f, 0.945503f, 0.948436f, 0.951293f, 0.954072f, 0.956773f, + 0.959396f, 0.961940f, 0.964405f, 0.966790f, 0.969096f, 0.971321f, 0.973465f, 0.975528f, + 0.977510f, 0.979410f, 0.981228f, 0.982963f, 0.984615f, 0.986185f, 0.987671f, 0.989074f, + 0.990393f, 0.991627f, 0.992778f, 0.993844f, 0.994826f, 0.995722f, 0.996534f, 0.997261f, + 0.997902f, 0.998459f, 0.998929f, 0.999315f, 0.999615f, 0.999829f, 0.999957f, 1.000000f, +}; + +static const int tbands[NB_TBANDS+1] = { + 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120 +}; + +static const int extra_bands[NB_TOT_BANDS+1] = { + 1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120, 160, 200 +}; + +/*static const float tweight[NB_TBANDS+1] = { + .3, .4, .5, .6, .7, .8, .9, 1., 1., 1., 1., 1., 1., 1., .8, .7, .6, .5 +};*/ + +#define NB_TONAL_SKIP_BANDS 9 + +#define cA 0.43157974f +#define cB 0.67848403f +#define cC 0.08595542f +#define cE ((float)M_PI/2) +static inline float fast_atan2f(float y, float x) { + float x2, y2; + /* Should avoid underflow on the values we'll get */ + if (ABS16(x)+ABS16(y)<1e-9f) + { + x*=1e12f; + y*=1e12f; + } + x2 = x*x; + y2 = y*y; + if(x2read_pos; + curr_lookahead = tonal->write_pos-tonal->read_pos; + if (curr_lookahead<0) + curr_lookahead += DETECT_SIZE; + + if (len > 480 && pos != tonal->write_pos) + { + pos++; + if (pos==DETECT_SIZE) + pos=0; + } + if (pos == tonal->write_pos) + pos--; + if (pos<0) + pos = DETECT_SIZE-1; + OPUS_COPY(info_out, &tonal->info[pos], 1); + tonal->read_subframe += len/120; + while (tonal->read_subframe>=4) + { + tonal->read_subframe -= 4; + tonal->read_pos++; + } + if (tonal->read_pos>=DETECT_SIZE) + tonal->read_pos-=DETECT_SIZE; + + /* Compensate for the delay in the features themselves. + FIXME: Need a better estimate the 10 I just made up */ + curr_lookahead = IMAX(curr_lookahead-10, 0); + + psum=0; + /* Summing the probability of transition patterns that involve music at + time (DETECT_SIZE-curr_lookahead-1) */ + for (i=0;ipmusic[i]; + for (;ipspeech[i]; + psum = psum*tonal->music_confidence + (1-psum)*tonal->speech_confidence; + /*printf("%f %f\n", psum, info_out->music_prob);*/ + + info_out->music_prob = psum; +} + +void tonality_analysis(TonalityAnalysisState *tonal, AnalysisInfo *info_out, const CELTMode *celt_mode, const void *x, int len, int offset, int C, int lsb_depth, downmix_func downmix) +{ + int i, b; + const kiss_fft_state *kfft; + VARDECL(kiss_fft_cpx, in); + VARDECL(kiss_fft_cpx, out); + int N = 480, N2=240; + float * OPUS_RESTRICT A = tonal->angle; + float * OPUS_RESTRICT dA = tonal->d_angle; + float * OPUS_RESTRICT d2A = tonal->d2_angle; + VARDECL(float, tonality); + VARDECL(float, noisiness); + float band_tonality[NB_TBANDS]; + float logE[NB_TBANDS]; + float BFCC[8]; + float features[25]; + float frame_tonality; + float max_frame_tonality; + /*float tw_sum=0;*/ + float frame_noisiness; + const float pi4 = (float)(M_PI*M_PI*M_PI*M_PI); + float slope=0; + float frame_stationarity; + float relativeE; + float frame_probs[2]; + float alpha, alphaE, alphaE2; + float frame_loudness; + float bandwidth_mask; + int bandwidth=0; + float maxE = 0; + float noise_floor; + int remaining; + AnalysisInfo *info; + SAVE_STACK; + + tonal->last_transition++; + alpha = 1.f/IMIN(20, 1+tonal->count); + alphaE = 1.f/IMIN(50, 1+tonal->count); + alphaE2 = 1.f/IMIN(1000, 1+tonal->count); + + if (tonal->count<4) + tonal->music_prob = .5; + kfft = celt_mode->mdct.kfft[0]; + if (tonal->count==0) + tonal->mem_fill = 240; + downmix(x, &tonal->inmem[tonal->mem_fill], IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill), offset, C); + if (tonal->mem_fill+len < ANALYSIS_BUF_SIZE) + { + tonal->mem_fill += len; + /* Don't have enough to update the analysis */ + RESTORE_STACK; + return; + } + info = &tonal->info[tonal->write_pos++]; + if (tonal->write_pos>=DETECT_SIZE) + tonal->write_pos-=DETECT_SIZE; + + ALLOC(in, 480, kiss_fft_cpx); + ALLOC(out, 480, kiss_fft_cpx); + ALLOC(tonality, 240, float); + ALLOC(noisiness, 240, float); + for (i=0;iinmem[i]); + in[i].i = MULT16_16(w, tonal->inmem[N2+i]); + in[N-i-1].r = MULT16_16(w, tonal->inmem[N-i-1]); + in[N-i-1].i = MULT16_16(w, tonal->inmem[N+N2-i-1]); + } + OPUS_MOVE(tonal->inmem, tonal->inmem+ANALYSIS_BUF_SIZE-240, 240); + remaining = len - (ANALYSIS_BUF_SIZE-tonal->mem_fill); + downmix(x, &tonal->inmem[240], remaining, offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, C); + tonal->mem_fill = 240 + remaining; + opus_fft(kfft, in, out); + + for (i=1;iactivity = 0; + frame_noisiness = 0; + frame_stationarity = 0; + if (!tonal->count) + { + for (b=0;blowE[b] = 1e10; + tonal->highE[b] = -1e10; + } + } + relativeE = 0; + frame_loudness = 0; + bandwidth_mask = 0; + for (b=0;bE[tonal->E_count][b] = E; + frame_noisiness += nE/(1e-15f+E); + + frame_loudness += celt_sqrt(E+1e-10f); + logE[b] = (float)log(E+1e-10f); + tonal->lowE[b] = MIN32(logE[b], tonal->lowE[b]+.01f); + tonal->highE[b] = MAX32(logE[b], tonal->highE[b]-.1f); + if (tonal->highE[b] < tonal->lowE[b]+1.f) + { + tonal->highE[b]+=.5f; + tonal->lowE[b]-=.5f; + } + relativeE += (logE[b]-tonal->lowE[b])/(EPSILON+tonal->highE[b]-tonal->lowE[b]); + + L1=L2=0; + for (i=0;iE[i][b]); + L2 += tonal->E[i][b]; + } + + stationarity = MIN16(0.99f,L1/celt_sqrt(EPSILON+NB_FRAMES*L2)); + stationarity *= stationarity; + stationarity *= stationarity; + frame_stationarity += stationarity; + /*band_tonality[b] = tE/(1e-15+E)*/; + band_tonality[b] = MAX16(tE/(EPSILON+E), stationarity*tonal->prev_band_tonality[b]); +#if 0 + if (b>=NB_TONAL_SKIP_BANDS) + { + frame_tonality += tweight[b]*band_tonality[b]; + tw_sum += tweight[b]; + } +#else + frame_tonality += band_tonality[b]; + if (b>=NB_TBANDS-NB_TONAL_SKIP_BANDS) + frame_tonality -= band_tonality[b-NB_TBANDS+NB_TONAL_SKIP_BANDS]; +#endif + max_frame_tonality = MAX16(max_frame_tonality, (1.f+.03f*(b-NB_TBANDS))*frame_tonality); + slope += band_tonality[b]*(b-8); + /*printf("%f %f ", band_tonality[b], stationarity);*/ + tonal->prev_band_tonality[b] = band_tonality[b]; + } + + bandwidth_mask = 0; + bandwidth = 0; + maxE = 0; + noise_floor = 5.7e-4f/(1<<(IMAX(0,lsb_depth-8))); + noise_floor *= noise_floor; + for (b=0;bmeanE[b] = MAX32((1-alphaE2)*tonal->meanE[b], E); + E = MAX32(E, tonal->meanE[b]); + /* Use a simple follower with 13 dB/Bark slope for spreading function */ + bandwidth_mask = MAX32(.05f*bandwidth_mask, E); + /* Consider the band "active" only if all these conditions are met: + 1) less than 10 dB below the simple follower + 2) less than 90 dB below the peak band (maximal masking possible considering + both the ATH and the loudness-dependent slope of the spreading function) + 3) above the PCM quantization noise floor + */ + if (E>.1*bandwidth_mask && E*1e9f > maxE && E > noise_floor*(band_end-band_start)) + bandwidth = b; + } + if (tonal->count<=2) + bandwidth = 20; + frame_loudness = 20*(float)log10(frame_loudness); + tonal->Etracker = MAX32(tonal->Etracker-.03f, frame_loudness); + tonal->lowECount *= (1-alphaE); + if (frame_loudness < tonal->Etracker-30) + tonal->lowECount += alphaE; + + for (i=0;i<8;i++) + { + float sum=0; + for (b=0;b<16;b++) + sum += dct_table[i*16+b]*logE[b]; + BFCC[i] = sum; + } + + frame_stationarity /= NB_TBANDS; + relativeE /= NB_TBANDS; + if (tonal->count<10) + relativeE = .5; + frame_noisiness /= NB_TBANDS; +#if 1 + info->activity = frame_noisiness + (1-frame_noisiness)*relativeE; +#else + info->activity = .5*(1+frame_noisiness-frame_stationarity); +#endif + frame_tonality = (max_frame_tonality/(NB_TBANDS-NB_TONAL_SKIP_BANDS)); + frame_tonality = MAX16(frame_tonality, tonal->prev_tonality*.8f); + tonal->prev_tonality = frame_tonality; + + slope /= 8*8; + info->tonality_slope = slope; + + tonal->E_count = (tonal->E_count+1)%NB_FRAMES; + tonal->count++; + info->tonality = frame_tonality; + + for (i=0;i<4;i++) + features[i] = -0.12299f*(BFCC[i]+tonal->mem[i+24]) + 0.49195f*(tonal->mem[i]+tonal->mem[i+16]) + 0.69693f*tonal->mem[i+8] - 1.4349f*tonal->cmean[i]; + + for (i=0;i<4;i++) + tonal->cmean[i] = (1-alpha)*tonal->cmean[i] + alpha*BFCC[i]; + + for (i=0;i<4;i++) + features[4+i] = 0.63246f*(BFCC[i]-tonal->mem[i+24]) + 0.31623f*(tonal->mem[i]-tonal->mem[i+16]); + for (i=0;i<3;i++) + features[8+i] = 0.53452f*(BFCC[i]+tonal->mem[i+24]) - 0.26726f*(tonal->mem[i]+tonal->mem[i+16]) -0.53452f*tonal->mem[i+8]; + + if (tonal->count > 5) + { + for (i=0;i<9;i++) + tonal->std[i] = (1-alpha)*tonal->std[i] + alpha*features[i]*features[i]; + } + + for (i=0;i<8;i++) + { + tonal->mem[i+24] = tonal->mem[i+16]; + tonal->mem[i+16] = tonal->mem[i+8]; + tonal->mem[i+8] = tonal->mem[i]; + tonal->mem[i] = BFCC[i]; + } + for (i=0;i<9;i++) + features[11+i] = celt_sqrt(tonal->std[i]); + features[20] = info->tonality; + features[21] = info->activity; + features[22] = frame_stationarity; + features[23] = info->tonality_slope; + features[24] = tonal->lowECount; + +#ifndef FIXED_POINT + mlp_process(&net, features, frame_probs); + frame_probs[0] = .5f*(frame_probs[0]+1); + /* Curve fitting between the MLP probability and the actual probability */ + frame_probs[0] = .01f + 1.21f*frame_probs[0]*frame_probs[0] - .23f*(float)pow(frame_probs[0], 10); + /* Probability of active audio (as opposed to silence) */ + frame_probs[1] = .5f*frame_probs[1]+.5f; + /* Consider that silence has a 50-50 probability. */ + frame_probs[0] = frame_probs[1]*frame_probs[0] + (1-frame_probs[1])*.5f; + + /*printf("%f %f ", frame_probs[0], frame_probs[1]);*/ + { + /* Probability of state transition */ + float tau; + /* Represents independence of the MLP probabilities, where + beta=1 means fully independent. */ + float beta; + /* Denormalized probability of speech (p0) and music (p1) after update */ + float p0, p1; + /* Probabilities for "all speech" and "all music" */ + float s0, m0; + /* Probability sum for renormalisation */ + float psum; + /* Instantaneous probability of speech and music, with beta pre-applied. */ + float speech0; + float music0; + + /* One transition every 3 minutes of active audio */ + tau = .00005f*frame_probs[1]; + beta = .05f; + if (1) { + /* Adapt beta based on how "unexpected" the new prob is */ + float p, q; + p = MAX16(.05f,MIN16(.95f,frame_probs[0])); + q = MAX16(.05f,MIN16(.95f,tonal->music_prob)); + beta = .01f+.05f*ABS16(p-q)/(p*(1-q)+q*(1-p)); + } + /* p0 and p1 are the probabilities of speech and music at this frame + using only information from previous frame and applying the + state transition model */ + p0 = (1-tonal->music_prob)*(1-tau) + tonal->music_prob *tau; + p1 = tonal->music_prob *(1-tau) + (1-tonal->music_prob)*tau; + /* We apply the current probability with exponent beta to work around + the fact that the probability estimates aren't independent. */ + p0 *= (float)pow(1-frame_probs[0], beta); + p1 *= (float)pow(frame_probs[0], beta); + /* Normalise the probabilities to get the Marokv probability of music. */ + tonal->music_prob = p1/(p0+p1); + info->music_prob = tonal->music_prob; + + /* This chunk of code deals with delayed decision. */ + psum=1e-20f; + /* Instantaneous probability of speech and music, with beta pre-applied. */ + speech0 = (float)pow(1-frame_probs[0], beta); + music0 = (float)pow(frame_probs[0], beta); + if (tonal->count==1) + { + tonal->pspeech[0]=.5; + tonal->pmusic [0]=.5; + } + /* Updated probability of having only speech (s0) or only music (m0), + before considering the new observation. */ + s0 = tonal->pspeech[0] + tonal->pspeech[1]; + m0 = tonal->pmusic [0] + tonal->pmusic [1]; + /* Updates s0 and m0 with instantaneous probability. */ + tonal->pspeech[0] = s0*(1-tau)*speech0; + tonal->pmusic [0] = m0*(1-tau)*music0; + /* Propagate the transition probabilities */ + for (i=1;ipspeech[i] = tonal->pspeech[i+1]*speech0; + tonal->pmusic [i] = tonal->pmusic [i+1]*music0; + } + /* Probability that the latest frame is speech, when all the previous ones were music. */ + tonal->pspeech[DETECT_SIZE-1] = m0*tau*speech0; + /* Probability that the latest frame is music, when all the previous ones were speech. */ + tonal->pmusic [DETECT_SIZE-1] = s0*tau*music0; + + /* Renormalise probabilities to 1 */ + for (i=0;ipspeech[i] + tonal->pmusic[i]; + psum = 1.f/psum; + for (i=0;ipspeech[i] *= psum; + tonal->pmusic [i] *= psum; + } + psum = tonal->pmusic[0]; + for (i=1;ipspeech[i]; + + /* Estimate our confidence in the speech/music decisions */ + if (frame_probs[1]>.75) + { + if (tonal->music_prob>.9) + { + float adapt; + adapt = 1.f/(++tonal->music_confidence_count); + tonal->music_confidence_count = IMIN(tonal->music_confidence_count, 500); + tonal->music_confidence += adapt*MAX16(-.2f,frame_probs[0]-tonal->music_confidence); + } + if (tonal->music_prob<.1) + { + float adapt; + adapt = 1.f/(++tonal->speech_confidence_count); + tonal->speech_confidence_count = IMIN(tonal->speech_confidence_count, 500); + tonal->speech_confidence += adapt*MIN16(.2f,frame_probs[0]-tonal->speech_confidence); + } + } else { + if (tonal->music_confidence_count==0) + tonal->music_confidence = .9f; + if (tonal->speech_confidence_count==0) + tonal->speech_confidence = .1f; + } + psum = MAX16(tonal->speech_confidence, MIN16(tonal->music_confidence, psum)); + } + if (tonal->last_music != (tonal->music_prob>.5f)) + tonal->last_transition=0; + tonal->last_music = tonal->music_prob>.5f; +#else + info->music_prob = 0; +#endif + /*for (i=0;i<25;i++) + printf("%f ", features[i]); + printf("\n");*/ + + info->bandwidth = bandwidth; + /*printf("%d %d\n", info->bandwidth, info->opus_bandwidth);*/ + info->noisiness = frame_noisiness; + info->valid = 1; + if (info_out!=NULL) + OPUS_COPY(info_out, info, 1); + RESTORE_STACK; +} + +int run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *pcm, + const void *analysis_pcm, int frame_size, int variable_duration, int C, opus_int32 Fs, int bitrate_bps, + int delay_compensation, int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info) +{ + int offset; + int pcm_len; + + /* Avoid overflow/wrap-around of the analysis buffer */ + frame_size = IMIN((DETECT_SIZE-5)*Fs/100, frame_size); + + pcm_len = frame_size - analysis->analysis_offset; + offset = 0; + do { + tonality_analysis(analysis, NULL, celt_mode, analysis_pcm, IMIN(480, pcm_len), offset, C, lsb_depth, downmix); + offset += 480; + pcm_len -= 480; + } while (pcm_len>0); + analysis->analysis_offset = frame_size; + + if (variable_duration == OPUS_FRAMESIZE_VARIABLE && frame_size >= Fs/200) + { + int LM = 3; + LM = optimize_framesize((const opus_val16*)pcm, frame_size, C, Fs, bitrate_bps, + analysis->prev_tonality, analysis->subframe_mem, delay_compensation, downmix); + while ((Fs/400<frame_size) + LM--; + frame_size = (Fs/400<analysis_offset -= frame_size; + + /* Only perform analysis up to 20-ms frames. Longer ones will be split if + they're in CELT-only mode. */ + analysis_info->valid = 0; + tonality_get_info(analysis, analysis_info, frame_size); + + return frame_size; +} diff --git a/media/libopus/src/analysis.h b/media/libopus/src/analysis.h new file mode 100644 index 000000000000..8cd788832cee --- /dev/null +++ b/media/libopus/src/analysis.h @@ -0,0 +1,90 @@ +/* Copyright (c) 2011 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef ANALYSIS_H +#define ANALYSIS_H + +#include "celt.h" +#include "opus_private.h" + +#define NB_FRAMES 8 +#define NB_TBANDS 18 +#define NB_TOT_BANDS 21 +#define ANALYSIS_BUF_SIZE 720 /* 15 ms at 48 kHz */ + +#define DETECT_SIZE 200 + +typedef struct { + float angle[240]; + float d_angle[240]; + float d2_angle[240]; + float inmem[ANALYSIS_BUF_SIZE]; + int mem_fill; /* number of usable samples in the buffer */ + float prev_band_tonality[NB_TBANDS]; + float prev_tonality; + float E[NB_FRAMES][NB_TBANDS]; + float lowE[NB_TBANDS]; + float highE[NB_TBANDS]; + float meanE[NB_TOT_BANDS]; + float mem[32]; + float cmean[8]; + float std[9]; + float music_prob; + float Etracker; + float lowECount; + int E_count; + int last_music; + int last_transition; + int count; + opus_val32 subframe_mem[3]; + int analysis_offset; + /** Probability of having speech for time i to DETECT_SIZE-1 (and music before). + pspeech[0] is the probability that all frames in the window are speech. */ + float pspeech[DETECT_SIZE]; + /** Probability of having music for time i to DETECT_SIZE-1 (and speech before). + pmusic[0] is the probability that all frames in the window are music. */ + float pmusic[DETECT_SIZE]; + float speech_confidence; + float music_confidence; + int speech_confidence_count; + int music_confidence_count; + int write_pos; + int read_pos; + int read_subframe; + AnalysisInfo info[DETECT_SIZE]; +} TonalityAnalysisState; + +void tonality_analysis(TonalityAnalysisState *tonal, AnalysisInfo *info, + const CELTMode *celt_mode, const void *x, int len, int offset, int C, int lsb_depth, downmix_func downmix); + +void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len); + +int run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *pcm, + const void *analysis_pcm, int frame_size, int variable_duration, int C, opus_int32 Fs, int bitrate_bps, + int delay_compensation, int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info); + +#endif diff --git a/media/libopus/src/mlp.c b/media/libopus/src/mlp.c new file mode 100644 index 000000000000..90e94a5fcb4c --- /dev/null +++ b/media/libopus/src/mlp.c @@ -0,0 +1,111 @@ +/* Copyright (c) 2008-2011 Octasic Inc. + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "mlp.h" +#include "arch.h" +#include "tansig_table.h" +#define MAX_NEURONS 100 + +#ifdef FIXED_POINT +static inline opus_val16 tansig_approx(opus_val32 _x) /* Q19 */ +{ + int i; + opus_val16 xx; /* Q11 */ + /*double x, y;*/ + opus_val16 dy, yy; /* Q14 */ + /*x = 1.9073e-06*_x;*/ + if (_x>=QCONST32(10,19)) + return QCONST32(1.,14); + if (_x<=-QCONST32(10,19)) + return -QCONST32(1.,14); + xx = EXTRACT16(SHR32(_x, 8)); + /*i = lrint(25*x);*/ + i = SHR32(ADD32(1024,MULT16_16(25, xx)),11); + /*x -= .04*i;*/ + xx -= EXTRACT16(SHR32(MULT16_16(20972,i),8)); + /*x = xx*(1./2048);*/ + /*y = tansig_table[250+i];*/ + yy = tansig_table[250+i]; + /*y = yy*(1./16384);*/ + dy = 16384-MULT16_16_Q14(yy,yy); + yy = yy + MULT16_16_Q14(MULT16_16_Q11(xx,dy),(16384 - MULT16_16_Q11(yy,xx))); + return yy; +} +#else +/*extern const float tansig_table[501];*/ +static inline opus_val16 tansig_approx(opus_val16 x) +{ + int i; + opus_val16 y, dy; + opus_val16 sign=1; + if (x>=8) + return 1; + if (x<=-8) + return -1; + if (x<0) + { + x=-x; + sign=-1; + } + i = (int)floor(.5f+25*x); + x -= .04f*i; + y = tansig_table[i]; + dy = 1-y*y; + y = y + x*dy*(1 - y*x); + return sign*y; +} +#endif + +void mlp_process(const MLP *m, const opus_val16 *in, opus_val16 *out) +{ + int j; + opus_val16 hidden[MAX_NEURONS]; + const opus_val16 *W = m->weights; + /* Copy to tmp_in */ + for (j=0;jtopo[1];j++) + { + int k; + opus_val32 sum = SHL32(EXTEND32(*W++),8); + for (k=0;ktopo[0];k++) + sum = MAC16_16(sum, in[k],*W++); + hidden[j] = tansig_approx(sum); + } + for (j=0;jtopo[2];j++) + { + int k; + opus_val32 sum = SHL32(EXTEND32(*W++),14); + for (k=0;ktopo[1];k++) + sum = MAC16_16(sum, hidden[k], *W++); + out[j] = tansig_approx(EXTRACT16(PSHR32(sum,17))); + } +} + diff --git a/media/libopus/src/mlp.h b/media/libopus/src/mlp.h new file mode 100644 index 000000000000..68ff68d82ef2 --- /dev/null +++ b/media/libopus/src/mlp.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2008-2011 Octasic Inc. + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _MLP_H_ +#define _MLP_H_ + +#include "arch.h" + +typedef struct { + int layers; + const int *topo; + const opus_val16 *weights; +} MLP; + +void mlp_process(const MLP *m, const opus_val16 *in, opus_val16 *out); + +#endif /* _MLP_H_ */ diff --git a/media/libopus/src/mlp_data.c b/media/libopus/src/mlp_data.c new file mode 100644 index 000000000000..401c4c025014 --- /dev/null +++ b/media/libopus/src/mlp_data.c @@ -0,0 +1,105 @@ +/* The contents of this file was automatically generated by mlp_train.c + It contains multi-layer perceptron (MLP) weights. */ + +#include "mlp.h" + +/* RMS error was 0.138320, seed was 1361535663 */ + +static const float weights[422] = { + +/* hidden layer */ +-0.0941125f, -0.302976f, -0.603555f, -0.19393f, -0.185983f, +-0.601617f, -0.0465317f, -0.114563f, -0.103599f, -0.618938f, +-0.317859f, -0.169949f, -0.0702885f, 0.148065f, 0.409524f, +0.548432f, 0.367649f, -0.494393f, 0.764306f, -1.83957f, +0.170849f, 12.786f, -1.08848f, -1.27284f, -16.2606f, +24.1773f, -5.57454f, -0.17276f, -0.163388f, -0.224421f, +-0.0948944f, -0.0728695f, -0.26557f, -0.100283f, -0.0515459f, +-0.146142f, -0.120674f, -0.180655f, 0.12857f, 0.442138f, +-0.493735f, 0.167767f, 0.206699f, -0.197567f, 0.417999f, +1.50364f, -0.773341f, -10.0401f, 0.401872f, 2.97966f, +15.2165f, -1.88905f, -1.19254f, 0.0285397f, -0.00405139f, +0.0707565f, 0.00825699f, -0.0927269f, -0.010393f, -0.00428882f, +-0.00489743f, -0.0709731f, -0.00255992f, 0.0395619f, 0.226424f, +0.0325231f, 0.162175f, -0.100118f, 0.485789f, 0.12697f, +0.285937f, 0.0155637f, 0.10546f, 3.05558f, 1.15059f, +-1.00904f, -1.83088f, 3.31766f, -3.42516f, -0.119135f, +-0.0405654f, 0.00690068f, 0.0179877f, -0.0382487f, 0.00597941f, +-0.0183611f, 0.00190395f, -0.144322f, -0.0435671f, 0.000990594f, +0.221087f, 0.142405f, 0.484066f, 0.404395f, 0.511955f, +-0.237255f, 0.241742f, 0.35045f, -0.699428f, 10.3993f, +2.6507f, -2.43459f, -4.18838f, 1.05928f, 1.71067f, +0.00667811f, -0.0721335f, -0.0397346f, 0.0362704f, -0.11496f, +-0.0235776f, 0.0082161f, -0.0141741f, -0.0329699f, -0.0354253f, +0.00277404f, -0.290654f, -1.14767f, -0.319157f, -0.686544f, +0.36897f, 0.478899f, 0.182579f, -0.411069f, 0.881104f, +-4.60683f, 1.4697f, 0.335845f, -1.81905f, -30.1699f, +5.55225f, 0.0019508f, -0.123576f, -0.0727332f, -0.0641597f, +-0.0534458f, -0.108166f, -0.0937368f, -0.0697883f, -0.0275475f, +-0.192309f, -0.110074f, 0.285375f, -0.405597f, 0.0926724f, +-0.287881f, -0.851193f, -0.099493f, -0.233764f, -1.2852f, +1.13611f, 3.12168f, -0.0699f, -1.86216f, 2.65292f, +-7.31036f, 2.44776f, -0.00111802f, -0.0632786f, -0.0376296f, +-0.149851f, 0.142963f, 0.184368f, 0.123433f, 0.0756158f, +0.117312f, 0.0933395f, 0.0692163f, 0.0842592f, 0.0704683f, +0.0589963f, 0.0942205f, -0.448862f, 0.0262677f, 0.270352f, +-0.262317f, 0.172586f, 2.00227f, -0.159216f, 0.038422f, +10.2073f, 4.15536f, -2.3407f, -0.0550265f, 0.00964792f, +-0.141336f, 0.0274501f, 0.0343921f, -0.0487428f, 0.0950172f, +-0.00775017f, -0.0372492f, -0.00548121f, -0.0663695f, 0.0960506f, +-0.200008f, -0.0412827f, 0.58728f, 0.0515787f, 0.337254f, +0.855024f, 0.668371f, -0.114904f, -3.62962f, -0.467477f, +-0.215472f, 2.61537f, 0.406117f, -1.36373f, 0.0425394f, +0.12208f, 0.0934502f, 0.123055f, 0.0340935f, -0.142466f, +0.035037f, -0.0490666f, 0.0733208f, 0.0576672f, 0.123984f, +-0.0517194f, -0.253018f, 0.590565f, 0.145849f, 0.315185f, +0.221534f, -0.149081f, 0.216161f, -0.349575f, 24.5664f, +-0.994196f, 0.614289f, -18.7905f, -2.83277f, -0.716801f, +-0.347201f, 0.479515f, -0.246027f, 0.0758683f, 0.137293f, +-0.17781f, 0.118751f, -0.00108329f, -0.237334f, 0.355732f, +-0.12991f, -0.0547627f, -0.318576f, -0.325524f, 0.180494f, +-0.0625604f, 0.141219f, 0.344064f, 0.37658f, -0.591772f, +5.8427f, -0.38075f, 0.221894f, -1.41934f, -1.87943e+06f, +1.34114f, 0.0283355f, -0.0447856f, -0.0211466f, -0.0256927f, +0.0139618f, 0.0207934f, -0.0107666f, 0.0110969f, 0.0586069f, +-0.0253545f, -0.0328433f, 0.11872f, -0.216943f, 0.145748f, +0.119808f, -0.0915211f, -0.120647f, -0.0787719f, -0.143644f, +-0.595116f, -1.152f, -1.25335f, -1.17092f, 4.34023f, +-975268.f, -1.37033f, -0.0401123f, 0.210602f, -0.136656f, +0.135962f, -0.0523293f, 0.0444604f, 0.0143928f, 0.00412666f, +-0.0193003f, 0.218452f, -0.110204f, -2.02563f, 0.918238f, +-2.45362f, 1.19542f, -0.061362f, -1.92243f, 0.308111f, +0.49764f, 0.912356f, 0.209272f, -2.34525f, 2.19326f, +-6.47121f, 1.69771f, -0.725123f, 0.0118929f, 0.0377944f, +0.0554003f, 0.0226452f, -0.0704421f, -0.0300309f, 0.0122978f, +-0.0041782f, -0.0686612f, 0.0313115f, 0.039111f, 0.364111f, +-0.0945548f, 0.0229876f, -0.17414f, 0.329795f, 0.114714f, +0.30022f, 0.106997f, 0.132355f, 5.79932f, 0.908058f, +-0.905324f, -3.3561f, 0.190647f, 0.184211f, -0.673648f, +0.231807f, -0.0586222f, 0.230752f, -0.438277f, 0.245857f, +-0.17215f, 0.0876383f, -0.720512f, 0.162515f, 0.0170571f, +0.101781f, 0.388477f, 1.32931f, 1.08548f, -0.936301f, +-2.36958f, -6.71988f, -3.44376f, 2.13818f, 14.2318f, +4.91459f, -3.09052f, -9.69191f, -0.768234f, 1.79604f, +0.0549653f, 0.163399f, 0.0797025f, 0.0343933f, -0.0555876f, +-0.00505673f, 0.0187258f, 0.0326628f, 0.0231486f, 0.15573f, +0.0476223f, -0.254824f, 1.60155f, -0.801221f, 2.55496f, +0.737629f, -1.36249f, -0.695463f, -2.44301f, -1.73188f, +3.95279f, 1.89068f, 0.486087f, -11.3343f, 3.9416e+06f, + +/* output layer */ +-0.381439f, 0.12115f, -0.906927f, 2.93878f, 1.6388f, +0.882811f, 0.874344f, 1.21726f, -0.874545f, 0.321706f, +0.785055f, 0.946558f, -0.575066f, -3.46553f, 0.884905f, +0.0924047f, -9.90712f, 0.391338f, 0.160103f, -2.04954f, +4.1455f, 0.0684029f, -0.144761f, -0.285282f, 0.379244f, +-1.1584f, -0.0277241f, -9.85f, -4.82386f, 3.71333f, +3.87308f, 3.52558f}; + +static const int topo[3] = {25, 15, 2}; + +const MLP net = { + 3, + topo, + weights +}; diff --git a/media/libopus/src/opus.c b/media/libopus/src/opus.c index 7e6ab17bc44f..170bc4b6e504 100644 --- a/media/libopus/src/opus.c +++ b/media/libopus/src/opus.c @@ -1,10 +1,6 @@ -/* Copyright (c) 2011-2012 IETF Trust, Xiph.Org Foundation, Skype Limited. All rights reserved. +/* Copyright (c) 2011 Xiph.Org Foundation, Skype Limited Written by Jean-Marc Valin and Koen Vos */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -41,6 +32,105 @@ #include "opus.h" #include "opus_private.h" +#ifndef DISABLE_FLOAT_API +OPUS_EXPORT void opus_pcm_soft_clip(float *_x, int N, int C, float *declip_mem) +{ + int c; + int i; + float *x; + + /* First thing: saturate everything to +/- 2 which is the highest level our + non-linearity can handle. At the point where the signal reaches +/-2, + the derivative will be zero anyway, so this doesn't introduce any + discontinuity in the derivative. */ + for (i=0;i=0) + break; + x[i*C] = x[i*C]+a*x[i*C]*x[i*C]; + } + + curr=0; + x0 = x[0]; + while(1) + { + int start, end; + float maxval; + int special=0; + int peak_pos; + for (i=curr;i1 || x[i*C]<-1) + break; + } + if (i==N) + { + a=0; + break; + } + peak_pos = i; + start=end=i; + maxval=ABS16(x[i*C]); + /* Look for first zero crossing before clipping */ + while (start>0 && x[i*C]*x[(start-1)*C]>=0) + start--; + /* Look for first zero crossing after clipping */ + while (end=0) + { + /* Look for other peaks until the next zero-crossing. */ + if (ABS16(x[end*C])>maxval) + { + maxval = ABS16(x[end*C]); + peak_pos = end; + } + end++; + } + /* Detect the special case where we clip before the first zero crossing */ + special = (start==0 && x[i*C]*x[0]>=0); + + /* Compute a such that maxval + a*maxval^2 = 1 */ + a=(maxval-1)/(maxval*maxval); + if (x[i*C]>0) + a = -a; + /* Apply soft clipping */ + for (i=start;i=2) + { + /* Add a linear ramp from the first sample to the signal peak. + This avoids a discontinuity at the beginning of the frame. */ + float delta; + float offset = x0-x[0]; + delta = offset / peak_pos; + for (i=curr;i #include "celt.h" #include "opus.h" @@ -50,6 +45,8 @@ #include "os_support.h" #include "structs.h" #include "define.h" +#include "mathops.h" +#include "cpu_support.h" struct OpusDecoder { int celt_dec_offset; @@ -57,6 +54,7 @@ struct OpusDecoder { int channels; opus_int32 Fs; /** Sampling rate (at the API level) */ silk_DecControlStruct DecControl; + int decode_gain; /* Everything beyond this point gets cleared on a reset */ #define OPUS_DECODER_RESET_START stream_channels @@ -67,14 +65,19 @@ struct OpusDecoder { int prev_mode; int frame_size; int prev_redundancy; + int last_packet_duration; +#ifndef FIXED_POINT + opus_val16 softclip_mem[2]; +#endif opus_uint32 rangeFinal; + int arch; }; #ifdef FIXED_POINT static inline opus_int16 SAT16(opus_int32 x) { return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x; -}; +} #endif @@ -118,6 +121,7 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels) st->Fs = Fs; st->DecControl.API_sampleRate = st->Fs; st->DecControl.nChannelsAPI = st->channels; + st->arch = opus_select_arch(); /* Reset decoder */ ret = silk_InitDecoder( silk_dec ); @@ -196,15 +200,21 @@ static int opus_packet_get_mode(const unsigned char *data) } static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, - int len, opus_val16 *pcm, int frame_size, int decode_fec) + opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) { void *silk_dec; CELTDecoder *celt_dec; int i, silk_ret=0, celt_ret=0; ec_dec dec; opus_int32 silk_frame_size; + int pcm_silk_size; VARDECL(opus_int16, pcm_silk); - VARDECL(opus_val16, pcm_transition); + int pcm_transition_silk_size; + VARDECL(opus_val16, pcm_transition_silk); + int pcm_transition_celt_size; + VARDECL(opus_val16, pcm_transition_celt); + opus_val16 *pcm_transition; + int redundant_audio_size; VARDECL(opus_val16, redundant_audio); int audiosize; @@ -227,7 +237,12 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, F5 = F10>>1; F2_5 = F5>>1; if (frame_size < F2_5) + { + RESTORE_STACK; return OPUS_BUFFER_TOO_SMALL; + } + /* Limit frame_size to avoid excessive stack allocations. */ + frame_size = IMIN(frame_size, st->Fs/25*3); /* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */ if (len<=1) { @@ -255,30 +270,30 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, } } - /* For CELT/hybrid PLC of more than 20 ms, do multiple calls */ - if (data==NULL && frame_size > F20 && mode != MODE_SILK_ONLY) - { - int nb_samples = 0; - do { - int ret = opus_decode_frame(st, NULL, 0, pcm, F20, 0); - if (ret != F20) - return OPUS_INTERNAL_ERROR; - pcm += F20*st->channels; - nb_samples += F20; - } while (nb_samples < frame_size); - RESTORE_STACK; - return frame_size; - } - ALLOC(pcm_transition, F5*st->channels, opus_val16); + /* For CELT/hybrid PLC of more than 20 ms, opus_decode_native() will do + multiple calls */ + if (data==NULL && mode != MODE_SILK_ONLY) + frame_size = IMIN(frame_size, F20); + pcm_transition_silk_size = 0; + pcm_transition_celt_size = 0; if (data!=NULL && st->prev_mode > 0 && ( (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy) || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ) ) { transition = 1; + /* Decide where to allocate the stack memory for pcm_transition */ if (mode == MODE_CELT_ONLY) - opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); + pcm_transition_celt_size = F5*st->channels; + else + pcm_transition_silk_size = F5*st->channels; + } + ALLOC(pcm_transition_celt, pcm_transition_celt_size, opus_val16); + if (transition && mode == MODE_CELT_ONLY) + { + pcm_transition = pcm_transition_celt; + opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); } if (audiosize > frame_size) { @@ -289,8 +304,9 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, frame_size = audiosize; } - ALLOC(pcm_silk, IMAX(F10, frame_size)*st->channels, opus_int16); - ALLOC(redundant_audio, F5*st->channels, opus_val16); + /* Don't allocate any memory when in CELT-only mode */ + pcm_silk_size = (mode != MODE_CELT_ONLY) ? IMAX(F10, frame_size)*st->channels : 0; + ALLOC(pcm_silk, pcm_silk_size, opus_int16); /* SILK processing */ if (mode != MODE_CELT_ONLY) @@ -404,10 +420,22 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, } if (redundancy) + { transition = 0; + pcm_transition_silk_size=0; + } + + ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16); if (transition && mode != MODE_CELT_ONLY) + { + pcm_transition = pcm_transition_silk; opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); + } + + /* Only allocation memory for redundancy if/when needed */ + redundant_audio_size = redundancy ? F5*st->channels : 0; + ALLOC(redundant_audio, redundant_audio_size, opus_val16); /* 5 ms redundant frame for CELT->SILK*/ if (redundancy && celt_to_silk) @@ -450,7 +478,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, pcm[i] = SAT16(pcm[i] + pcm_silk[i]); #else for (i=0;ichannels;i++) - pcm[i] = pcm[i] + (opus_val16)((1./32768.)*pcm_silk[i]); + pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]); #endif } @@ -502,6 +530,18 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, } } + if(st->decode_gain) + { + opus_val32 gain; + gain = celt_exp2(MULT16_16_P15(QCONST16(6.48814081e-4f, 25), st->decode_gain)); + for (i=0;ichannels;i++) + { + opus_val32 x; + x = MULT16_32_P16(pcm[i],gain); + pcm[i] = SATURATE(x, 32767); + } + } + if (len <= 1) st->rangeFinal = 0; else @@ -509,12 +549,19 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, st->prev_mode = mode; st->prev_redundancy = redundancy && !celt_to_silk; + + if (celt_ret>=0) + { + if (OPUS_CHECK_ARRAY(pcm, audiosize*st->channels)) + OPUS_PRINT_INT(audiosize); + } + RESTORE_STACK; return celt_ret < 0 ? celt_ret : audiosize; } -static int parse_size(const unsigned char *data, int len, short *size) +static int parse_size(const unsigned char *data, opus_int32 len, opus_int16 *size) { if (len<1) { @@ -534,16 +581,16 @@ static int parse_size(const unsigned char *data, int len, short *size) } } -static int opus_packet_parse_impl(const unsigned char *data, int len, +static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, int self_delimited, unsigned char *out_toc, - const unsigned char *frames[48], short size[48], int *payload_offset) + const unsigned char *frames[48], opus_int16 size[48], int *payload_offset) { int i, bytes; int count; int cbr; unsigned char ch, toc; int framesize; - int last_size; + opus_int32 last_size; const unsigned char *data0 = data; if (size==NULL) @@ -569,7 +616,9 @@ static int opus_packet_parse_impl(const unsigned char *data, int len, { if (len&0x1) return OPUS_INVALID_PACKET; - size[0] = last_size = len/2; + last_size = len/2; + /* If last_size doesn't fit in size[0], we'll catch it later */ + size[0] = (opus_int16)last_size; } break; /* Two VBR frames */ @@ -630,7 +679,7 @@ static int opus_packet_parse_impl(const unsigned char *data, int len, if (last_size*count!=len) return OPUS_INVALID_PACKET; for (i=0;i 1275) return OPUS_INVALID_PACKET; - size[count-1] = last_size; + size[count-1] = (opus_int16)last_size; } if (frames) @@ -674,79 +723,149 @@ static int opus_packet_parse_impl(const unsigned char *data, int len, *out_toc = toc; if (payload_offset) - *payload_offset = data-data0; + *payload_offset = (int)(data-data0); return count; } -int opus_packet_parse(const unsigned char *data, int len, +int opus_packet_parse(const unsigned char *data, opus_int32 len, unsigned char *out_toc, const unsigned char *frames[48], - short size[48], int *payload_offset) + opus_int16 size[48], int *payload_offset) { return opus_packet_parse_impl(data, len, 0, out_toc, frames, size, payload_offset); } int opus_decode_native(OpusDecoder *st, const unsigned char *data, - int len, opus_val16 *pcm, int frame_size, int decode_fec, - int self_delimited, int *packet_offset) + opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec, + int self_delimited, int *packet_offset, int soft_clip) { int i, nb_samples; int count, offset; unsigned char toc; int tot_offset; + int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels; /* 48 x 2.5 ms = 120 ms */ - short size[48]; + opus_int16 size[48]; if (decode_fec<0 || decode_fec>1) return OPUS_BAD_ARG; + /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */ + if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0) + return OPUS_BAD_ARG; if (len==0 || data==NULL) - return opus_decode_frame(st, NULL, 0, pcm, frame_size, 0); - else if (len<0) + { + int pcm_count=0; + do { + int ret; + ret = opus_decode_frame(st, NULL, 0, pcm+pcm_count*st->channels, frame_size-pcm_count, 0); + if (ret<0) + return ret; + pcm_count += ret; + } while (pcm_count < frame_size); + celt_assert(pcm_count == frame_size); + if (OPUS_CHECK_ARRAY(pcm, pcm_count*st->channels)) + OPUS_PRINT_INT(pcm_count); + st->last_packet_duration = pcm_count; + return pcm_count; + } else if (len<0) return OPUS_BAD_ARG; - tot_offset = 0; - st->mode = opus_packet_get_mode(data); - st->bandwidth = opus_packet_get_bandwidth(data); - st->frame_size = opus_packet_get_samples_per_frame(data, st->Fs); - st->stream_channels = opus_packet_get_nb_channels(data); + packet_mode = opus_packet_get_mode(data); + packet_bandwidth = opus_packet_get_bandwidth(data); + packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs); + packet_stream_channels = opus_packet_get_nb_channels(data); count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset); + + data += offset; + + if (decode_fec) + { + int duration_copy; + int ret; + /* If no FEC can be present, run the PLC (recursive call) */ + if (frame_size < packet_frame_size || packet_mode == MODE_CELT_ONLY || st->mode == MODE_CELT_ONLY) + return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL, soft_clip); + /* Otherwise, run the PLC on everything except the size for which we might have FEC */ + duration_copy = st->last_packet_duration; + if (frame_size-packet_frame_size!=0) + { + ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0, 0, NULL, soft_clip); + if (ret<0) + { + st->last_packet_duration = duration_copy; + return ret; + } + celt_assert(ret==frame_size-packet_frame_size); + } + /* Complete with FEC */ + st->mode = packet_mode; + st->bandwidth = packet_bandwidth; + st->frame_size = packet_frame_size; + st->stream_channels = packet_stream_channels; + ret = opus_decode_frame(st, data, size[0], pcm+st->channels*(frame_size-packet_frame_size), + packet_frame_size, 1); + if (ret<0) + return ret; + else { + if (OPUS_CHECK_ARRAY(pcm, frame_size*st->channels)) + OPUS_PRINT_INT(frame_size); + st->last_packet_duration = frame_size; + return frame_size; + } + } + tot_offset = 0; if (count < 0) return count; - data += offset; tot_offset += offset; - if (count*st->frame_size > frame_size) + if (count*packet_frame_size > frame_size) return OPUS_BUFFER_TOO_SMALL; + + /* Update the state as the last step to avoid updating it on an invalid packet */ + st->mode = packet_mode; + st->bandwidth = packet_bandwidth; + st->frame_size = packet_frame_size; + st->stream_channels = packet_stream_channels; + nb_samples=0; for (i=0;ichannels, frame_size-nb_samples, 0); if (ret<0) return ret; + celt_assert(ret==packet_frame_size); data += size[i]; tot_offset += size[i]; - pcm += ret*st->channels; nb_samples += ret; } if (packet_offset != NULL) *packet_offset = tot_offset; + st->last_packet_duration = nb_samples; + if (OPUS_CHECK_ARRAY(pcm, nb_samples*st->channels)) + OPUS_PRINT_INT(nb_samples); +#ifndef FIXED_POINT + if (soft_clip) + opus_pcm_soft_clip(pcm, nb_samples, st->channels, st->softclip_mem); + else + st->softclip_mem[0]=st->softclip_mem[1]=0; +#endif return nb_samples; } #ifdef FIXED_POINT int opus_decode(OpusDecoder *st, const unsigned char *data, - int len, opus_val16 *pcm, int frame_size, int decode_fec) + opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) { - return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL); + return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0); } #ifndef DISABLE_FLOAT_API int opus_decode_float(OpusDecoder *st, const unsigned char *data, - int len, float *pcm, int frame_size, int decode_fec) + opus_int32 len, float *pcm, int frame_size, int decode_fec) { VARDECL(opus_int16, out); int ret, i; @@ -754,7 +873,7 @@ int opus_decode_float(OpusDecoder *st, const unsigned char *data, ALLOC(out, frame_size*st->channels, opus_int16); - ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL); + ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0); if (ret > 0) { for (i=0;ichannels;i++) @@ -768,17 +887,21 @@ int opus_decode_float(OpusDecoder *st, const unsigned char *data, #else int opus_decode(OpusDecoder *st, const unsigned char *data, - int len, opus_int16 *pcm, int frame_size, int decode_fec) + opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec) { VARDECL(float, out); int ret, i; ALLOC_STACK; - if(frame_size<0)return OPUS_BAD_ARG; + if(frame_size<0) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } ALLOC(out, frame_size*st->channels, float); - ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL); + ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1); if (ret > 0) { for (i=0;ichannels;i++) @@ -789,9 +912,9 @@ int opus_decode(OpusDecoder *st, const unsigned char *data, } int opus_decode_float(OpusDecoder *st, const unsigned char *data, - int len, opus_val16 *pcm, int frame_size, int decode_fec) + opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) { - return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL); + return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0); } #endif @@ -814,12 +937,20 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) case OPUS_GET_BANDWIDTH_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } *value = st->bandwidth; } break; case OPUS_GET_FINAL_RANGE_REQUEST: { opus_uint32 *value = va_arg(ap, opus_uint32*); + if (!value) + { + goto bad_arg; + } *value = st->rangeFinal; } break; @@ -835,13 +966,22 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) st->frame_size = st->Fs/400; } break; + case OPUS_GET_SAMPLE_RATE_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->Fs; + } + break; case OPUS_GET_PITCH_REQUEST: { - int *value = va_arg(ap, opus_int32*); - if (value==NULL) + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) { - ret = OPUS_BAD_ARG; - break; + goto bad_arg; } if (st->prev_mode == MODE_CELT_ONLY) celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value)); @@ -849,6 +989,36 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) *value = st->DecControl.prevPitchLag; } break; + case OPUS_GET_GAIN_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->decode_gain; + } + break; + case OPUS_SET_GAIN_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<-32768 || value>32767) + { + goto bad_arg; + } + st->decode_gain = value; + } + break; + case OPUS_GET_LAST_PACKET_DURATION_REQUEST: + { + opus_uint32 *value = va_arg(ap, opus_uint32*); + if (!value) + { + goto bad_arg; + } + *value = st->last_packet_duration; + } + break; default: /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/ ret = OPUS_UNIMPLEMENTED; @@ -857,6 +1027,9 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) va_end(ap); return ret; +bad_arg: + va_end(ap); + return OPUS_BAD_ARG; } void opus_decoder_destroy(OpusDecoder *st) @@ -909,7 +1082,7 @@ int opus_packet_get_nb_channels(const unsigned char *data) return (data[0]&0x4) ? 2 : 1; } -int opus_packet_get_nb_frames(const unsigned char packet[], int len) +int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) { int count; if (len<1) @@ -925,8 +1098,8 @@ int opus_packet_get_nb_frames(const unsigned char packet[], int len) return packet[1]&0x3F; } -int opus_decoder_get_nb_samples(const OpusDecoder *dec, - const unsigned char packet[], int len) +int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, + opus_int32 Fs) { int samples; int count = opus_packet_get_nb_frames(packet, len); @@ -934,10 +1107,16 @@ int opus_decoder_get_nb_samples(const OpusDecoder *dec, if (count<0) return count; - samples = count*opus_packet_get_samples_per_frame(packet, dec->Fs); + samples = count*opus_packet_get_samples_per_frame(packet, Fs); /* Can't have more than 120 ms */ - if (samples*25 > dec->Fs*3) + if (samples*25 > Fs*3) return OPUS_INVALID_PACKET; else return samples; } + +int opus_decoder_get_nb_samples(const OpusDecoder *dec, + const unsigned char packet[], opus_int32 len) +{ + return opus_packet_get_nb_samples(packet, len, dec->Fs); +} diff --git a/media/libopus/src/opus_encoder.c b/media/libopus/src/opus_encoder.c index 44171c2bc4cf..ac40edac7c74 100644 --- a/media/libopus/src/opus_encoder.c +++ b/media/libopus/src/opus_encoder.c @@ -1,10 +1,6 @@ -/* Copyright (c) 2010-2012 IETF Trust, Xiph.Org Foundation, Skype Limited. All rights reserved. +/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited Written by Jean-Marc Valin and Koen Vos */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -49,7 +40,9 @@ #include "arch.h" #include "opus_private.h" #include "os_support.h" - +#include "cpu_support.h" +#include "analysis.h" +#include "mathops.h" #include "tuning_parameters.h" #ifdef FIXED_POINT #include "fixed/structs_FIX.h" @@ -59,6 +52,12 @@ #define MAX_ENCODER_BUFFER 480 +typedef struct { + opus_val32 XX, XY, YY; + opus_val16 smoothed_width; + opus_val16 max_follower; +} StereoWidthState; + struct OpusEncoder { int celt_enc_offset; int silk_enc_offset; @@ -75,14 +74,18 @@ struct OpusEncoder { opus_int32 Fs; int use_vbr; int vbr_constraint; + int variable_duration; opus_int32 bitrate_bps; opus_int32 user_bitrate_bps; + int lsb_depth; int encoder_buffer; + int lfe; #define OPUS_ENCODER_RESET_START stream_channels int stream_channels; opus_int16 hybrid_stereo_width_Q14; opus_int32 variable_HP_smth2_Q15; + opus_val16 prev_HB_gain; opus_val32 hp_mem[4]; int mode; int prev_mode; @@ -92,9 +95,16 @@ struct OpusEncoder { int silk_bw_switch; /* Sampling rate (at the API level) */ int first; + int energy_masking; + StereoWidthState width_mem; opus_val16 delay_buffer[MAX_ENCODER_BUFFER*2]; - +#ifndef FIXED_POINT + TonalityAnalysisState analysis; + int detected_bandwidth; + int analysis_offset; +#endif opus_uint32 rangeFinal; + int arch; }; /* Transition tables for the voice and music. First column is the @@ -103,8 +113,8 @@ struct OpusEncoder { static const opus_int32 mono_voice_bandwidth_thresholds[8] = { 11000, 1000, /* NB<->MB */ 14000, 1000, /* MB<->WB */ - 21000, 2000, /* WB<->SWB */ - 29000, 2000, /* SWB<->FB */ + 17000, 1000, /* WB<->SWB */ + 20000, 1000, /* SWB<->FB */ }; static const opus_int32 mono_music_bandwidth_thresholds[8] = { 14000, 1000, /* MB not allowed */ @@ -125,14 +135,14 @@ static const opus_int32 stereo_music_bandwidth_thresholds[8] = { 48000, 2000, /* SWB<->FB */ }; /* Threshold bit-rates for switching between mono and stereo */ -static const opus_int32 stereo_voice_threshold = 26000; -static const opus_int32 stereo_music_threshold = 36000; +static const opus_int32 stereo_voice_threshold = 31000; +static const opus_int32 stereo_music_threshold = 31000; /* Threshold bit-rate for switching between SILK/hybrid and CELT-only */ static const opus_int32 mode_thresholds[2][2] = { /* voice */ /* music */ - { 48000, 24000}, /* mono */ - { 48000, 24000}, /* stereo */ + { 64000, 20000}, /* mono */ + { 36000, 20000}, /* stereo */ }; int opus_encoder_get_size(int channels) @@ -176,6 +186,8 @@ int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int applicat st->Fs = Fs; + st->arch = opus_select_arch(); + ret = silk_InitEncoder( silk_enc, &st->silk_mode ); if(ret)return OPUS_INTERNAL_ERROR; @@ -215,12 +227,15 @@ int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int applicat st->user_forced_mode = OPUS_AUTO; st->voice_ratio = -1; st->encoder_buffer = st->Fs/100; + st->lsb_depth = 24; + st->variable_duration = OPUS_FRAMESIZE_ARG; - /* Delay compensation of 4 ms (2.5 ms for SILK's extra look-ahead + /* Delay compensation of 4 ms (2.5 ms for SILK's extra look-ahead + 1.5 ms for SILK resamplers and stereo prediction) */ st->delay_compensation = st->Fs/250; st->hybrid_stereo_width_Q14 = 1 << 14; + st->prev_HB_gain = Q15ONE; st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ); st->first = 1; st->mode = MODE_HYBRID; @@ -229,7 +244,7 @@ int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int applicat return OPUS_OK; } -static int pad_frame(unsigned char *data, int len, int new_len) +static int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len) { if (len == new_len) return 0; @@ -300,7 +315,7 @@ static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channel } #ifndef FIXED_POINT -void silk_biquad_float( +static void silk_biquad_float( const opus_val16 *in, /* I: Input signal */ const opus_int32 *B_Q28, /* I: MA coefficients [3] */ const opus_int32 *A_Q28, /* I: AR coefficients [2] */ @@ -316,11 +331,11 @@ void silk_biquad_float( opus_val32 inval; opus_val32 A[2], B[3]; - A[0] = (opus_val32)(A_Q28[0] * (1./((opus_int32)1<<28))); - A[1] = (opus_val32)(A_Q28[1] * (1./((opus_int32)1<<28))); - B[0] = (opus_val32)(B_Q28[0] * (1./((opus_int32)1<<28))); - B[1] = (opus_val32)(B_Q28[1] * (1./((opus_int32)1<<28))); - B[2] = (opus_val32)(B_Q28[2] * (1./((opus_int32)1<<28))); + A[0] = (opus_val32)(A_Q28[0] * (1.f/((opus_int32)1<<28))); + A[1] = (opus_val32)(A_Q28[1] * (1.f/((opus_int32)1<<28))); + B[0] = (opus_val32)(B_Q28[0] * (1.f/((opus_int32)1<<28))); + B[1] = (opus_val32)(B_Q28[1] * (1.f/((opus_int32)1<<28))); + B[2] = (opus_val32)(B_Q28[2] * (1.f/((opus_int32)1<<28))); /* Negate A_Q28 values and split in two parts */ @@ -331,7 +346,7 @@ void silk_biquad_float( S[ 0 ] = S[1] - vout*A[0] + B[1]*inval; - S[ 1 ] = - vout*A[1] + B[2]*inval; + S[ 1 ] = - vout*A[1] + B[2]*inval + VERY_SMALL; /* Scale back to Q0 and saturate */ out[ k*stride ] = vout; @@ -374,11 +389,64 @@ static void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *ou #endif } +#ifdef FIXED_POINT +static void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs) +{ + int c, i; + int shift; + + /* Approximates -round(log2(4.*cutoff_Hz/Fs)) */ + shift=celt_ilog2(Fs/(cutoff_Hz*3)); + for (c=0;cuser_bitrate_bps; } -#ifdef FIXED_POINT -#define opus_encode_native opus_encode -int opus_encode(OpusEncoder *st, const opus_val16 *pcm, int frame_size, - unsigned char *data, int max_data_bytes) -#else -#define opus_encode_native opus_encode_float -int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, - unsigned char *data, int max_data_bytes) +#ifndef FIXED_POINT +/* Don't use more than 60 ms for the frame size analysis */ +#define MAX_DYNAMIC_FRAMESIZE 24 +/* Estimates how much the bitrate will be boosted based on the sub-frame energy */ +static float transient_boost(const float *E, const float *E_1, int LM, int maxM) +{ + int i; + int M; + float sumE=0, sumE_1=0; + float metric; + + M = IMIN(maxM, (1<10 ? 1 : 0;*/ + /*return MAX16(0,1-exp(-.25*(metric-2.)));*/ + return MIN16(1,(float)sqrt(MAX16(0,.05f*(metric-2)))); +} + +/* Viterbi decoding trying to find the best frame size combination using look-ahead + + State numbering: + 0: unused + 1: 2.5 ms + 2: 5 ms (#1) + 3: 5 ms (#2) + 4: 10 ms (#1) + 5: 10 ms (#2) + 6: 10 ms (#3) + 7: 10 ms (#4) + 8: 20 ms (#1) + 9: 20 ms (#2) + 10: 20 ms (#3) + 11: 20 ms (#4) + 12: 20 ms (#5) + 13: 20 ms (#6) + 14: 20 ms (#7) + 15: 20 ms (#8) +*/ +static int transient_viterbi(const float *E, const float *E_1, int N, int frame_cost, int rate) +{ + int i; + float cost[MAX_DYNAMIC_FRAMESIZE][16]; + int states[MAX_DYNAMIC_FRAMESIZE][16]; + float best_cost; + int best_state; + float factor; + /* Take into account that we damp VBR in the 32 kb/s to 64 kb/s range. */ + if (rate<80) + factor=0; + else if (rate>160) + factor=1; + else + factor = (rate-80.f)/80.f; + /* Makes variable framesize less aggressive at lower bitrates, but I can't + find any valid theoretical justification for this (other than it seems + to help) */ + for (i=0;i<16;i++) + { + /* Impossible state */ + states[0][i] = -1; + cost[0][i] = 1e10; + } + for (i=0;i<4;i++) + { + cost[0][1<=0;i--) + { + /*printf("%d ", best_state);*/ + best_state = states[i][best_state]; + } + /*printf("%d\n", best_state);*/ + return best_state; +} + +void downmix_float(const void *_x, float *sub, int subframe, int offset, int C) +{ + const float *x; + int c, j; + x = (const float *)_x; + for (j=0;j=0 && offset <= subframe); + x += C*offset; + len -= offset; + e[1]=mem[1]; + e_1[1]=1.f/(EPSILON+mem[1]); + e[2]=mem[2]; + e_1[2]=1.f/(EPSILON+mem[2]); + pos = 3; + } else { + pos=1; + } + N=IMIN(len/subframe, MAX_DYNAMIC_FRAMESIZE); + memx = x[0]; + for (i=0;i= OPUS_FRAMESIZE_2_5_MS && variable_duration <= OPUS_FRAMESIZE_60_MS) + new_size = IMIN(3*Fs/50, (Fs/400)<<(variable_duration-OPUS_FRAMESIZE_2_5_MS)); + else + return -1; + if (new_size>frame_size) + return -1; + if (400*new_size!=Fs && 200*new_size!=Fs && 100*new_size!=Fs && + 50*new_size!=Fs && 25*new_size!=Fs && 50*new_size!=3*Fs) + return -1; + return new_size; +} + +opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int32 Fs, StereoWidthState *mem) +{ + opus_val16 corr; + opus_val16 ldiff; + opus_val16 width; + opus_val32 xx, xy, yy; + opus_val16 sqrt_xx, sqrt_yy; + opus_val16 qrrt_xx, qrrt_yy; + int frame_rate; + int i; + opus_val16 short_alpha; + + frame_rate = Fs/frame_size; + short_alpha = Q15ONE - 25*Q15ONE/IMAX(50,frame_rate); + xx=xy=yy=0; + for (i=0;iXX += MULT16_32_Q15(short_alpha, xx-mem->XX); + mem->XY += MULT16_32_Q15(short_alpha, xy-mem->XY); + mem->YY += MULT16_32_Q15(short_alpha, yy-mem->YY); + mem->XX = MAX32(0, mem->XX); + mem->XY = MAX32(0, mem->XY); + mem->YY = MAX32(0, mem->YY); + if (MAX32(mem->XX, mem->YY)>QCONST16(8e-4f, 18)) + { + sqrt_xx = celt_sqrt(mem->XX); + sqrt_yy = celt_sqrt(mem->YY); + qrrt_xx = celt_sqrt(sqrt_xx); + qrrt_yy = celt_sqrt(sqrt_yy); + /* Inter-channel correlation */ + mem->XY = MIN32(mem->XY, sqrt_xx*sqrt_yy); + corr = SHR32(frac_div32(mem->XY,EPSILON+MULT16_16(sqrt_xx,sqrt_yy)),16); + /* Approximate loudness difference */ + ldiff = Q15ONE*ABS16(qrrt_xx-qrrt_yy)/(EPSILON+qrrt_xx+qrrt_yy); + width = MULT16_16_Q15(celt_sqrt(QCONST32(1.f,30)-MULT16_16(corr,corr)), ldiff); + /* Smoothing over one second */ + mem->smoothed_width += (width-mem->smoothed_width)/frame_rate; + /* Peak follower */ + mem->max_follower = MAX16(mem->max_follower-QCONST16(.02f,15)/frame_rate, mem->smoothed_width); + } else { + width = 0; + corr=Q15ONE; + ldiff=0; + } + /*printf("%f %f %f %f %f ", corr/(float)Q15ONE, ldiff/(float)Q15ONE, width/(float)Q15ONE, mem->smoothed_width/(float)Q15ONE, mem->max_follower/(float)Q15ONE);*/ + return EXTRACT16(MIN32(Q15ONE,20*mem->max_follower)); +} + +opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size, + unsigned char *data, opus_int32 out_data_bytes, int lsb_depth +#ifndef FIXED_POINT + , AnalysisInfo *analysis_info +#endif + ) { void *silk_enc; CELTEncoder *celt_enc; int i; int ret=0; - int nBytes; + opus_int32 nBytes; ec_enc enc; int bytes_target; int prefill=0; int start_band = 0; int redundancy = 0; - int redundancy_bytes = 0; + int redundancy_bytes = 0; /* Number of bytes to use for redundancy frame */ int celt_to_silk = 0; VARDECL(opus_val16, pcm_buf); int nb_compr_bytes; int to_celt = 0; opus_uint32 redundant_rng = 0; int cutoff_Hz, hp_freq_smth1; - int voice_est; + int voice_est; /* Probability of voice in Q7 */ opus_int32 equiv_rate; int delay_compensation; int frame_rate; - opus_int32 max_rate; + opus_int32 max_rate; /* Max bitrate we're allowed to use */ int curr_bandwidth; + opus_val16 HB_gain; + opus_int32 max_data_bytes; /* Max number of bytes we're allowed to use */ + int total_buffer; + opus_val16 stereo_width; VARDECL(opus_val16, tmp_prefill); ALLOC_STACK; - max_data_bytes = IMIN(1276, max_data_bytes); + max_data_bytes = IMIN(1276, out_data_bytes); st->rangeFinal = 0; - if (400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs && + if ((!st->variable_duration && 400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs && 50*frame_size != st->Fs && 25*frame_size != st->Fs && 50*frame_size != 3*st->Fs) - { - RESTORE_STACK; - return OPUS_BAD_ARG; - } - if (max_data_bytes<=0) + || (400*frame_size < st->Fs) + || max_data_bytes<=0 + ) { RESTORE_STACK; return OPUS_BAD_ARG; } silk_enc = (char*)st+st->silk_enc_offset; celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); - if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) delay_compensation = 0; else delay_compensation = st->delay_compensation; + lsb_depth = IMIN(lsb_depth, st->lsb_depth); + + st->voice_ratio = -1; + +#ifndef FIXED_POINT + st->detected_bandwidth = 0; + if (analysis_info->valid) + { + int analysis_bandwidth; + if (st->signal_type == OPUS_AUTO) + st->voice_ratio = (int)floor(.5+100*(1-analysis_info->music_prob)); + + analysis_bandwidth = analysis_info->bandwidth; + if (analysis_bandwidth<=12) + st->detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND; + else if (analysis_bandwidth<=14) + st->detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; + else if (analysis_bandwidth<=16) + st->detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND; + else if (analysis_bandwidth<=18) + st->detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; + else + st->detected_bandwidth = OPUS_BANDWIDTH_FULLBAND; + } +#endif + + if (st->channels==2 && st->force_channels!=1) + stereo_width = compute_stereo_width(pcm, frame_size, st->Fs, &st->width_mem); + else + stereo_width = 0; + total_buffer = delay_compensation; st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes); frame_rate = st->Fs/frame_size; if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8 || (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400))) { + /*If the space is too low to do something useful, emit 'PLC' frames.*/ int tocmode = st->mode; + int bw = st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth; if (tocmode==0) tocmode = MODE_SILK_ONLY; if (frame_rate>100) tocmode = MODE_CELT_ONLY; if (frame_rate < 50) tocmode = MODE_SILK_ONLY; - data[0] = gen_toc(tocmode, frame_rate, - st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth, - st->stream_channels); + if(tocmode==MODE_SILK_ONLY&&bw>OPUS_BANDWIDTH_WIDEBAND) + bw=OPUS_BANDWIDTH_WIDEBAND; + else if (tocmode==MODE_CELT_ONLY&&bw==OPUS_BANDWIDTH_MEDIUMBAND) + bw=OPUS_BANDWIDTH_NARROWBAND; + else if (bw<=OPUS_BANDWIDTH_SUPERWIDEBAND) + bw=OPUS_BANDWIDTH_SUPERWIDEBAND; + data[0] = gen_toc(tocmode, frame_rate, bw, st->stream_channels); RESTORE_STACK; return 1; } @@ -539,8 +1012,12 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, else if (st->signal_type == OPUS_SIGNAL_MUSIC) voice_est = 0; else if (st->voice_ratio >= 0) + { voice_est = st->voice_ratio*327>>8; - else if (st->application == OPUS_APPLICATION_VOIP) + /* For AUDIO, never be more than 90% confident of having speech */ + if (st->application == OPUS_APPLICATION_AUDIO) + voice_est = IMIN(voice_est, 115); + } else if (st->application == OPUS_APPLICATION_VOIP) voice_est = 115; else voice_est = 48; @@ -560,9 +1037,9 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, opus_int32 stereo_threshold; stereo_threshold = stereo_music_threshold + ((voice_est*voice_est*(stereo_voice_threshold-stereo_music_threshold))>>14); if (st->stream_channels == 2) - stereo_threshold -= 4000; + stereo_threshold -= 1000; else - stereo_threshold += 4000; + stereo_threshold += 1000; st->stream_channels = (equiv_rate > stereo_threshold) ? 2 : 1; } else { st->stream_channels = st->channels; @@ -591,15 +1068,21 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, st->mode = MODE_SILK_ONLY; } #else - int chan; opus_int32 mode_voice, mode_music; opus_int32 threshold; - chan = (st->channels==2) && st->force_channels!=1; - mode_voice = mode_thresholds[chan][0]; - mode_music = mode_thresholds[chan][1]; + /* Interpolate based on stereo width */ + mode_voice = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[0][0]) + + MULT16_32_Q15(stereo_width,mode_thresholds[1][0])); + mode_music = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[1][1]) + + MULT16_32_Q15(stereo_width,mode_thresholds[1][1])); + /* Interpolate based on speech/music probability */ threshold = mode_music + ((voice_est*voice_est*(mode_voice-mode_music))>>14); + /* Bias towards SILK for VoIP because of some useful features */ + if (st->application == OPUS_APPLICATION_VOIP) + threshold += 8000; + /*printf("%f %d\n", stereo_width/(float)Q15ONE, threshold);*/ /* Hysteresis */ if (st->prev_mode == MODE_CELT_ONLY) threshold -= 4000; @@ -651,11 +1134,22 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, } } } + /* For the first frame at a new SILK bandwidth */ if (st->silk_bw_switch) { redundancy = 1; celt_to_silk = 1; st->silk_bw_switch = 0; + prefill=1; + } + + if (redundancy) + { + /* Fair share of the max size allowed */ + redundancy_bytes = IMIN(257, max_data_bytes*(opus_int32)(st->Fs/200)/(frame_size+st->Fs/200)); + /* For VBR, target the actual bitrate (subject to the limit above) */ + if (st->use_vbr) + redundancy_bytes = IMIN(redundancy_bytes, st->bitrate_bps/1600); } if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) @@ -739,6 +1233,31 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, st->bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; if (st->Fs <= 8000 && st->bandwidth > OPUS_BANDWIDTH_NARROWBAND) st->bandwidth = OPUS_BANDWIDTH_NARROWBAND; +#ifndef FIXED_POINT + /* Use detected bandwidth to reduce the encoded bandwidth. */ + if (st->detected_bandwidth && st->user_bandwidth == OPUS_AUTO) + { + int min_detected_bandwidth; + /* Makes bandwidth detection more conservative just in case the detector + gets it wrong when we could have coded a high bandwidth transparently. + When operating in SILK/hybrid mode, we don't go below wideband to avoid + more complicated switches that require redundancy. */ + if (st->bitrate_bps <= 18000*st->stream_channels && st->mode == MODE_CELT_ONLY) + min_detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND; + else if (st->bitrate_bps <= 24000*st->stream_channels && st->mode == MODE_CELT_ONLY) + min_detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; + else if (st->bitrate_bps <= 30000*st->stream_channels) + min_detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND; + else if (st->bitrate_bps <= 44000*st->stream_channels) + min_detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; + else + min_detected_bandwidth = OPUS_BANDWIDTH_FULLBAND; + + st->detected_bandwidth = IMAX(st->detected_bandwidth, min_detected_bandwidth); + st->bandwidth = IMIN(st->bandwidth, st->detected_bandwidth); + } +#endif + celt_encoder_ctl(celt_enc, OPUS_SET_LSB_DEPTH(lsb_depth)); /* If max_data_bytes represents less than 8 kb/s, switch to CELT-only mode */ if (max_data_bytes < (frame_rate > 50 ? 12000 : 8000)*frame_size / (st->Fs * 8)) @@ -747,6 +1266,11 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, /* CELT mode doesn't support mediumband, use wideband instead */ if (st->mode == MODE_CELT_ONLY && st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) st->bandwidth = OPUS_BANDWIDTH_WIDEBAND; + if (st->lfe) + { + st->bandwidth = OPUS_BANDWIDTH_NARROWBAND; + st->mode = MODE_CELT_ONLY; + } /* Can't support higher than wideband for >20 ms frames */ if (frame_size > st->Fs/50 && (st->mode == MODE_CELT_ONLY || st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)) @@ -754,16 +1278,17 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, VARDECL(unsigned char, tmp_data); int nb_frames; int bak_mode, bak_bandwidth, bak_channels, bak_to_mono; - OpusRepacketizer rp; - int bytes_per_frame; + VARDECL(OpusRepacketizer, rp); + opus_int32 bytes_per_frame; nb_frames = frame_size > st->Fs/25 ? 3 : 2; - bytes_per_frame = max_data_bytes/nb_frames-3; + bytes_per_frame = IMIN(1276,(out_data_bytes-3)/nb_frames); ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char); - opus_repacketizer_init(&rp); + ALLOC(rp, 1, OpusRepacketizer); + opus_repacketizer_init(rp); bak_mode = st->user_forced_mode; bak_bandwidth = st->user_bandwidth; @@ -785,17 +1310,29 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, /* When switching from SILK/Hybrid to CELT, only ask for a switch at the last frame */ if (to_celt && i==nb_frames-1) st->user_forced_mode = MODE_CELT_ONLY; - tmp_len = opus_encode_native(st, pcm+i*(st->channels*st->Fs/50), st->Fs/50, tmp_data+i*bytes_per_frame, bytes_per_frame); + tmp_len = opus_encode_native(st, pcm+i*(st->channels*st->Fs/50), st->Fs/50, tmp_data+i*bytes_per_frame, bytes_per_frame, lsb_depth +#ifndef FIXED_POINT + , analysis_info +#endif + ); if (tmp_len<0) + { + RESTORE_STACK; return OPUS_INTERNAL_ERROR; - ret = opus_repacketizer_cat(&rp, tmp_data+i*bytes_per_frame, tmp_len); + } + ret = opus_repacketizer_cat(rp, tmp_data+i*bytes_per_frame, tmp_len); if (ret<0) + { + RESTORE_STACK; return OPUS_INTERNAL_ERROR; + } } - ret = opus_repacketizer_out(&rp, data, max_data_bytes); + ret = opus_repacketizer_out(rp, data, out_data_bytes); if (ret<0) + { + RESTORE_STACK; return OPUS_INTERNAL_ERROR; - + } st->user_forced_mode = bak_mode; st->user_bandwidth = bak_bandwidth; st->force_channels = bak_channels; @@ -803,7 +1340,6 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, RESTORE_STACK; return ret; } - curr_bandwidth = st->bandwidth; /* Chooses the appropriate mode for speech @@ -814,15 +1350,15 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, st->mode = MODE_SILK_ONLY; /* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */ - bytes_target = IMIN(max_data_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1; + bytes_target = IMIN(max_data_bytes-redundancy_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1; data += 1; ec_enc_init(&enc, data, max_data_bytes-1); - ALLOC(pcm_buf, (delay_compensation+frame_size)*st->channels, opus_val16); - for (i=0;ichannels;i++) - pcm_buf[i] = st->delay_buffer[(st->encoder_buffer-delay_compensation)*st->channels+i]; + ALLOC(pcm_buf, (total_buffer+frame_size)*st->channels, opus_val16); + for (i=0;ichannels;i++) + pcm_buf[i] = st->delay_buffer[(st->encoder_buffer-total_buffer)*st->channels+i]; if (st->mode == MODE_CELT_ONLY) hp_freq_smth1 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ); @@ -837,46 +1373,50 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, if (st->application == OPUS_APPLICATION_VOIP) { - hp_cutoff(pcm, cutoff_Hz, &pcm_buf[delay_compensation*st->channels], st->hp_mem, frame_size, st->channels, st->Fs); + hp_cutoff(pcm, cutoff_Hz, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs); } else { - for (i=0;ichannels;i++) - pcm_buf[delay_compensation*st->channels + i] = pcm[i]; + dc_reject(pcm, 3, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs); } + + /* SILK processing */ + HB_gain = Q15ONE; if (st->mode != MODE_CELT_ONLY) { + opus_int32 total_bitRate, celt_rate; #ifdef FIXED_POINT const opus_int16 *pcm_silk; #else VARDECL(opus_int16, pcm_silk); ALLOC(pcm_silk, st->channels*frame_size, opus_int16); #endif - st->silk_mode.bitRate = 8*bytes_target*frame_rate; + + /* Distribute bits between SILK and CELT */ + total_bitRate = 8 * bytes_target * frame_rate; if( st->mode == MODE_HYBRID ) { - st->silk_mode.bitRate /= st->stream_channels; + int HB_gain_ref; + /* Base rate for SILK */ + st->silk_mode.bitRate = st->stream_channels * ( 5000 + 1000 * ( st->Fs == 100 * frame_size ) ); if( curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND ) { - if( st->Fs == 100 * frame_size ) { - /* 24 kHz, 10 ms */ - st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 2000 + st->use_vbr * 1000 ) * 2 ) / 3; - } else { - /* 24 kHz, 20 ms */ - st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 1000 + st->use_vbr * 1000 ) * 2 ) / 3; - } - } else { - if( st->Fs == 100 * frame_size ) { - /* 48 kHz, 10 ms */ - st->silk_mode.bitRate = ( st->silk_mode.bitRate + 8000 + st->use_vbr * 3000 ) / 2; - } else { - /* 48 kHz, 20 ms */ - st->silk_mode.bitRate = ( st->silk_mode.bitRate + 9000 + st->use_vbr * 1000 ) / 2; - } + /* SILK gets 2/3 of the remaining bits */ + st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 2 / 3; + } else { /* FULLBAND */ + /* SILK gets 3/5 of the remaining bits */ + st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 3 / 5; } - st->silk_mode.bitRate *= st->stream_channels; - /* don't let SILK use more than 80% */ - if( st->silk_mode.bitRate > ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5 ) { - st->silk_mode.bitRate = ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5; + /* Don't let SILK use more than 80% */ + if( st->silk_mode.bitRate > total_bitRate * 4/5 ) { + st->silk_mode.bitRate = total_bitRate * 4/5; } + /* Increasingly attenuate high band when it gets allocated fewer bits */ + celt_rate = total_bitRate - st->silk_mode.bitRate; + HB_gain_ref = (curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND) ? 3000 : 3600; + HB_gain = SHL32((opus_val32)celt_rate, 9) / SHR32((opus_val32)celt_rate + st->stream_channels * HB_gain_ref, 6); + HB_gain = HB_gain < Q15ONE*6/7 ? HB_gain + Q15ONE/7 : Q15ONE; + } else { + /* SILK gets all bits */ + st->silk_mode.bitRate = total_bitRate; } st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs; @@ -920,7 +1460,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, st->silk_mode.useCBR = !st->use_vbr; /* Call SILK encoder for the low band */ - nBytes = IMIN(1275, max_data_bytes-1); + nBytes = IMIN(1275, max_data_bytes-1-redundancy_bytes); st->silk_mode.maxBits = nBytes*8; /* Only allow up to 90% of the bits for hybrid mode*/ @@ -932,12 +1472,24 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, /* Reduce the initial target to make it easier to reach the CBR rate */ st->silk_mode.bitRate = IMAX(1, st->silk_mode.bitRate-2000); } - if (redundancy) - st->silk_mode.maxBits -= st->silk_mode.maxBits/(1 + frame_size/(st->Fs/200)); if (prefill) { - int zero=0; + opus_int32 zero=0; + const CELTMode *celt_mode; + int prefill_offset; + celt_encoder_ctl(celt_enc, CELT_GET_MODE(&celt_mode)); + /* Use a smooth onset for the SILK prefill to avoid the encoder trying to encode + a discontinuity. The exact location is what we need to avoid leaving any "gap" + in the audio when mixing with the redundant CELT frame. Here we can afford to + overwrite st->delay_buffer because the only thing that uses it before it gets + rewritten is tmp_prefill[] and even then only the part after the ramp really + gets used (rather than sent to the encoder and discarded) */ + prefill_offset = st->channels*(st->encoder_buffer-st->delay_compensation-st->Fs/400); + gain_fade(st->delay_buffer+prefill_offset, st->delay_buffer+prefill_offset, + 0, Q15ONE, celt_mode->overlap, st->Fs/400, st->channels, celt_mode->window, st->Fs); + for(i=0;idelay_buffer[i]=0; #ifdef FIXED_POINT pcm_silk = st->delay_buffer; #else @@ -948,15 +1500,16 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, } #ifdef FIXED_POINT - pcm_silk = pcm_buf+delay_compensation*st->channels; + pcm_silk = pcm_buf+total_buffer*st->channels; #else for (i=0;ichannels;i++) - pcm_silk[i] = FLOAT2INT16(pcm_buf[delay_compensation*st->channels + i]); + pcm_silk[i] = FLOAT2INT16(pcm_buf[total_buffer*st->channels + i]); #endif ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0 ); if( ret ) { /*fprintf (stderr, "SILK encode error: %d\n", ret);*/ /* Handle error */ + RESTORE_STACK; return OPUS_INTERNAL_ERROR; } if (nBytes==0) @@ -980,6 +1533,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, } st->silk_mode.opusCanSwitch = st->silk_mode.switchReady; + /* FIXME: How do we allocate the redundancy for CBR? */ if (st->silk_mode.opusCanSwitch) { redundancy = 1; @@ -1034,10 +1588,19 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, } else { if (st->use_vbr) { + opus_int32 bonus=0; +#ifndef FIXED_POINT + if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != st->Fs/50) + { + bonus = (60*st->stream_channels+40)*(st->Fs/frame_size-50); + if (analysis_info->valid) + bonus = (opus_int32)(bonus*(1.f+.5f*analysis_info->tonality)); + } +#endif celt_encoder_ctl(celt_enc, OPUS_SET_VBR(1)); celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(st->vbr_constraint)); - celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps)); - nb_compr_bytes = max_data_bytes-1; + celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps+bonus)); + nb_compr_bytes = max_data_bytes-1-redundancy_bytes; } else { nb_compr_bytes = bytes_target; } @@ -1051,18 +1614,27 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, if (st->mode != MODE_SILK_ONLY && st->mode != st->prev_mode && st->prev_mode > 0) { for (i=0;ichannels*st->Fs/400;i++) - tmp_prefill[i] = st->delay_buffer[(st->encoder_buffer-st->delay_compensation-st->Fs/400)*st->channels + i]; + tmp_prefill[i] = st->delay_buffer[(st->encoder_buffer-total_buffer-st->Fs/400)*st->channels + i]; } - for (i=0;ichannels*(st->encoder_buffer-(frame_size+delay_compensation));i++) + for (i=0;ichannels*(st->encoder_buffer-(frame_size+total_buffer));i++) st->delay_buffer[i] = st->delay_buffer[i+st->channels*frame_size]; for (;iencoder_buffer*st->channels;i++) - st->delay_buffer[i] = pcm_buf[(frame_size+delay_compensation-st->encoder_buffer)*st->channels+i]; + st->delay_buffer[i] = pcm_buf[(frame_size+total_buffer-st->encoder_buffer)*st->channels+i]; + /* gain_fade() and stereo_fade() need to be after the buffer copying + because we don't want any of this to affect the SILK part */ + if( st->prev_HB_gain < Q15ONE || HB_gain < Q15ONE ) { + const CELTMode *celt_mode; + celt_encoder_ctl(celt_enc, CELT_GET_MODE(&celt_mode)); + gain_fade(pcm_buf, pcm_buf, + st->prev_HB_gain, HB_gain, celt_mode->overlap, frame_size, st->channels, celt_mode->window, st->Fs); + } + st->prev_HB_gain = HB_gain; if (st->mode != MODE_HYBRID || st->stream_channels==1) - st->silk_mode.stereoWidth_Q14 = 1<<14; - if( st->channels == 2 ) { + st->silk_mode.stereoWidth_Q14 = IMIN((1<<14),IMAX(0,st->bitrate_bps-32000)); + if( !st->energy_masking && st->channels == 2 ) { /* Apply stereo width reduction (at low bitrates) */ if( st->hybrid_stereo_width_Q14 < (1 << 14) || st->silk_mode.stereoWidth_Q14 < (1 << 14) ) { opus_val16 g1, g2; @@ -1075,8 +1647,8 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, g1 = g1==16384 ? Q15ONE : SHL16(g1,1); g2 = g2==16384 ? Q15ONE : SHL16(g2,1); #else - g1 *= (1./16384); - g2 *= (1./16384); + g1 *= (1.f/16384); + g2 *= (1.f/16384); #endif stereo_fade(pcm_buf, pcm_buf, g1, g2, celt_mode->overlap, frame_size, st->channels, celt_mode->window, st->Fs); @@ -1109,8 +1681,10 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, } if (!redundancy) + { st->silk_bw_switch = 0; - + redundancy_bytes = 0; + } if (st->mode != MODE_CELT_ONLY)start_band=17; if (st->mode == MODE_SILK_ONLY) @@ -1123,6 +1697,10 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, ec_enc_shrink(&enc, nb_compr_bytes); } +#ifndef FIXED_POINT + if (redundancy || st->mode != MODE_SILK_ONLY) + celt_encoder_ctl(celt_enc, CELT_SET_ANALYSIS(analysis_info)); +#endif /* 5 ms redundant frame for CELT->SILK */ if (redundancy && celt_to_silk) @@ -1132,7 +1710,10 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0)); err = celt_encode_with_ec(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes, NULL); if (err < 0) - return OPUS_INTERNAL_ERROR; + { + RESTORE_STACK; + return OPUS_INTERNAL_ERROR; + } celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng)); celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); } @@ -1155,7 +1736,10 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, { ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc); if (ret < 0) + { + RESTORE_STACK; return OPUS_INTERNAL_ERROR; + } } } @@ -1177,7 +1761,10 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, err = celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes, NULL); if (err < 0) - return OPUS_INTERNAL_ERROR; + { + RESTORE_STACK; + return OPUS_INTERNAL_ERROR; + } celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng)); } @@ -1202,6 +1789,11 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, the decoder to call the PLC */ if (ec_tell(&enc) > (max_data_bytes-1)*8) { + if (max_data_bytes < 2) + { + RESTORE_STACK; + return OPUS_BUFFER_TOO_SMALL; + } data[1] = 0; ret = 1; st->rangeFinal = 0; @@ -1220,7 +1812,10 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, if (!st->use_vbr && ret >= 3) { if (pad_frame(data, ret, max_data_bytes)) + { + RESTORE_STACK; return OPUS_INTERNAL_ERROR; + } ret = max_data_bytes; } RESTORE_STACK; @@ -1230,41 +1825,115 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, #ifdef FIXED_POINT #ifndef DISABLE_FLOAT_API -int opus_encode_float(OpusEncoder *st, const float *pcm, int frame_size, - unsigned char *data, int max_data_bytes) +opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int frame_size, + unsigned char *data, opus_int32 max_data_bytes) { int i, ret; VARDECL(opus_int16, in); ALLOC_STACK; - if(frame_size<0)return OPUS_BAD_ARG; + frame_size = frame_size_select(frame_size, st->variable_duration, st->Fs); + if(frame_size<0) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } ALLOC(in, frame_size*st->channels, opus_int16); for (i=0;ichannels;i++) in[i] = FLOAT2INT16(pcm[i]); - ret = opus_encode(st, in, frame_size, data, max_data_bytes); + ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16); RESTORE_STACK; return ret; } #endif +opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int frame_size, + unsigned char *data, opus_int32 out_data_bytes) +{ + frame_size = frame_size_select(frame_size, st->variable_duration, st->Fs); + if(frame_size<0) + { + return OPUS_BAD_ARG; + } + return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 16); +} + #else -int opus_encode(OpusEncoder *st, const opus_int16 *pcm, int frame_size, - unsigned char *data, int max_data_bytes) +opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int frame_size, + unsigned char *data, opus_int32 max_data_bytes) { int i, ret; + const CELTMode *celt_mode; + int delay_compensation; + int lsb_depth; VARDECL(float, in); + AnalysisInfo analysis_info; ALLOC_STACK; + opus_encoder_ctl(st, CELT_GET_MODE(&celt_mode)); + if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) + delay_compensation = 0; + else + delay_compensation = st->delay_compensation; + + lsb_depth = IMIN(16, st->lsb_depth); + + analysis_info.valid = 0; + if (st->silk_mode.complexity >= 7 && st->Fs==48000) + { + frame_size = run_analysis(&st->analysis, celt_mode, pcm, pcm+st->channels*st->analysis.analysis_offset, + frame_size, st->variable_duration, st->channels, st->Fs, st->bitrate_bps, delay_compensation, lsb_depth, downmix_int, &analysis_info); + } else { + frame_size = frame_size_select(frame_size, st->variable_duration, st->Fs); + } + if(frame_size<0) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } + ALLOC(in, frame_size*st->channels, float); for (i=0;ichannels;i++) in[i] = (1.0f/32768)*pcm[i]; - ret = opus_encode_float(st, in, frame_size, data, max_data_bytes); + ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16, &analysis_info); RESTORE_STACK; return ret; } +opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int frame_size, + unsigned char *data, opus_int32 out_data_bytes) +{ + const CELTMode *celt_mode; + int delay_compensation; + int lsb_depth; + AnalysisInfo analysis_info; + + opus_encoder_ctl(st, CELT_GET_MODE(&celt_mode)); + if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) + delay_compensation = 0; + else + delay_compensation = st->delay_compensation; + + lsb_depth = IMIN(24, st->lsb_depth); + + analysis_info.valid = 0; + if (st->silk_mode.complexity >= 7 && st->Fs==48000) + { + frame_size = run_analysis(&st->analysis, celt_mode, pcm, pcm+st->channels*st->analysis.analysis_offset, + frame_size, st->variable_duration, st->channels, st->Fs, st->bitrate_bps, delay_compensation, lsb_depth, downmix_float, &analysis_info); + } else { + frame_size = frame_size_select(frame_size, st->variable_duration, st->Fs); + } + if(frame_size<0) + { + return OPUS_BAD_ARG; + } + + return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 24, &analysis_info); + +} #endif @@ -1297,6 +1966,10 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) case OPUS_GET_APPLICATION_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } *value = st->application; } break; @@ -1318,6 +1991,10 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) case OPUS_GET_BITRATE_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } *value = user_bitrate_to_bitrate(st, st->prev_framesize, 1276); } break; @@ -1325,21 +2002,29 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) { opus_int32 value = va_arg(ap, opus_int32); if((value<1 || value>st->channels) && value != OPUS_AUTO) - return OPUS_BAD_ARG; + { + goto bad_arg; + } st->force_channels = value; } break; case OPUS_GET_FORCE_CHANNELS_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } *value = st->force_channels; } break; case OPUS_SET_MAX_BANDWIDTH_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); - if (value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) - return OPUS_BAD_ARG; + if (value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) + { + goto bad_arg; + } st->max_bandwidth = value; if (st->max_bandwidth == OPUS_BANDWIDTH_NARROWBAND) { st->silk_mode.maxInternalSampleRate = 8000; @@ -1353,6 +2038,10 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) case OPUS_GET_MAX_BANDWIDTH_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } *value = st->max_bandwidth; } break; @@ -1360,7 +2049,9 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) { opus_int32 value = va_arg(ap, opus_int32); if ((value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) && value != OPUS_AUTO) - return OPUS_BAD_ARG; + { + goto bad_arg; + } st->user_bandwidth = value; if (st->user_bandwidth == OPUS_BANDWIDTH_NARROWBAND) { st->silk_mode.maxInternalSampleRate = 8000; @@ -1374,6 +2065,10 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) case OPUS_GET_BANDWIDTH_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } *value = st->bandwidth; } break; @@ -1381,13 +2076,19 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) { opus_int32 value = va_arg(ap, opus_int32); if(value<0 || value>1) - return OPUS_BAD_ARG; + { + goto bad_arg; + } st->silk_mode.useDTX = value; } break; case OPUS_GET_DTX_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } *value = st->silk_mode.useDTX; } break; @@ -1395,7 +2096,9 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) { opus_int32 value = va_arg(ap, opus_int32); if(value<0 || value>10) - return OPUS_BAD_ARG; + { + goto bad_arg; + } st->silk_mode.complexity = value; celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(value)); } @@ -1403,6 +2106,10 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) case OPUS_GET_COMPLEXITY_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } *value = st->silk_mode.complexity; } break; @@ -1410,13 +2117,19 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) { opus_int32 value = va_arg(ap, opus_int32); if(value<0 || value>1) - return OPUS_BAD_ARG; + { + goto bad_arg; + } st->silk_mode.useInBandFEC = value; } break; case OPUS_GET_INBAND_FEC_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } *value = st->silk_mode.useInBandFEC; } break; @@ -1424,7 +2137,9 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) { opus_int32 value = va_arg(ap, opus_int32); if (value < 0 || value > 100) - return OPUS_BAD_ARG; + { + goto bad_arg; + } st->silk_mode.packetLossPercentage = value; celt_encoder_ctl(celt_enc, OPUS_SET_PACKET_LOSS_PERC(value)); } @@ -1432,6 +2147,10 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) case OPUS_GET_PACKET_LOSS_PERC_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } *value = st->silk_mode.packetLossPercentage; } break; @@ -1439,7 +2158,9 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) { opus_int32 value = va_arg(ap, opus_int32); if(value<0 || value>1) - return OPUS_BAD_ARG; + { + goto bad_arg; + } st->use_vbr = value; st->silk_mode.useCBR = 1-value; } @@ -1447,20 +2168,30 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) case OPUS_GET_VBR_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } *value = st->use_vbr; } break; case OPUS_SET_VOICE_RATIO_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); - if (value>100 || value<-1) - goto bad_arg; + if (value<-1 || value>100) + { + goto bad_arg; + } st->voice_ratio = value; } break; case OPUS_GET_VOICE_RATIO_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } *value = st->voice_ratio; } break; @@ -1468,13 +2199,19 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) { opus_int32 value = va_arg(ap, opus_int32); if(value<0 || value>1) - return OPUS_BAD_ARG; + { + goto bad_arg; + } st->vbr_constraint = value; } break; case OPUS_GET_VBR_CONSTRAINT_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } *value = st->vbr_constraint; } break; @@ -1482,30 +2219,98 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) { opus_int32 value = va_arg(ap, opus_int32); if(value!=OPUS_AUTO && value!=OPUS_SIGNAL_VOICE && value!=OPUS_SIGNAL_MUSIC) - return OPUS_BAD_ARG; + { + goto bad_arg; + } st->signal_type = value; } break; case OPUS_GET_SIGNAL_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } *value = st->signal_type; } break; case OPUS_GET_LOOKAHEAD_REQUEST: { opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } *value = st->Fs/400; if (st->application != OPUS_APPLICATION_RESTRICTED_LOWDELAY) *value += st->delay_compensation; } break; + case OPUS_GET_SAMPLE_RATE_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->Fs; + } + break; case OPUS_GET_FINAL_RANGE_REQUEST: { opus_uint32 *value = va_arg(ap, opus_uint32*); + if (!value) + { + goto bad_arg; + } *value = st->rangeFinal; } break; + case OPUS_SET_LSB_DEPTH_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<8 || value>24) + { + goto bad_arg; + } + st->lsb_depth=value; + } + break; + case OPUS_GET_LSB_DEPTH_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->lsb_depth; + } + break; + case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value != OPUS_FRAMESIZE_ARG && value != OPUS_FRAMESIZE_2_5_MS && + value != OPUS_FRAMESIZE_5_MS && value != OPUS_FRAMESIZE_10_MS && + value != OPUS_FRAMESIZE_20_MS && value != OPUS_FRAMESIZE_40_MS && + value != OPUS_FRAMESIZE_60_MS && value != OPUS_FRAMESIZE_VARIABLE) + { + goto bad_arg; + } + st->variable_duration = value; + celt_encoder_ctl(celt_enc, OPUS_SET_EXPERT_FRAME_DURATION(value)); + } + break; + case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->variable_duration; + } + break; case OPUS_RESET_STATE: { void *silk_enc; @@ -1520,6 +2325,7 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) silk_InitEncoder( silk_enc, &dummy ); st->stream_channels = st->channels; st->hybrid_stereo_width_Q14 = 1 << 14; + st->prev_HB_gain = Q15ONE; st->first = 1; st->mode = MODE_HYBRID; st->bandwidth = OPUS_BANDWIDTH_FULLBAND; @@ -1530,10 +2336,47 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) { opus_int32 value = va_arg(ap, opus_int32); if ((value < MODE_SILK_ONLY || value > MODE_CELT_ONLY) && value != OPUS_AUTO) + { goto bad_arg; + } st->user_forced_mode = value; } break; + case OPUS_SET_LFE_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->lfe = value; + ret = celt_encoder_ctl(celt_enc, OPUS_SET_LFE(value)); + } + break; + case OPUS_SET_ENERGY_SAVE_REQUEST: + { + opus_val16 *value = va_arg(ap, opus_val16*); + if (!value) + { + goto bad_arg; + } + ret = celt_encoder_ctl(celt_enc, OPUS_SET_ENERGY_SAVE(value)); + } + break; + case OPUS_SET_ENERGY_MASK_REQUEST: + { + opus_val16 *value = va_arg(ap, opus_val16*); + st->energy_masking = (value!=NULL); + ret = celt_encoder_ctl(celt_enc, OPUS_SET_ENERGY_MASK(value)); + } + break; + + case CELT_GET_MODE_REQUEST: + { + const CELTMode ** value = va_arg(ap, const CELTMode**); + if (!value) + { + goto bad_arg; + } + ret = celt_encoder_ctl(celt_enc, CELT_GET_MODE(value)); + } + break; default: /* fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);*/ ret = OPUS_UNIMPLEMENTED; diff --git a/media/libopus/src/opus_multistream.c b/media/libopus/src/opus_multistream.c index 2b1000b5dddb..09c3639b7f0d 100644 --- a/media/libopus/src/opus_multistream.c +++ b/media/libopus/src/opus_multistream.c @@ -1,10 +1,6 @@ -/* Copyright (c) 2011-2012 IETF Trust, Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2011 Xiph.Org Foundation Written by Jean-Marc Valin */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -46,32 +37,8 @@ #include "float_cast.h" #include "os_support.h" -typedef struct ChannelLayout { - int nb_channels; - int nb_streams; - int nb_coupled_streams; - unsigned char mapping[256]; -} ChannelLayout; -struct OpusMSEncoder { - ChannelLayout layout; - int bitrate; - /* Encoder states go here */ -}; - -struct OpusMSDecoder { - ChannelLayout layout; - /* Decoder states go here */ -}; - - -#ifdef FIXED_POINT -#define opus_encode_native opus_encode -#else -#define opus_encode_native opus_encode_float -#endif - -static int validate_layout(const ChannelLayout *layout) +int validate_layout(const ChannelLayout *layout) { int i, max_channel; @@ -87,7 +54,7 @@ static int validate_layout(const ChannelLayout *layout) } -static int get_left_channel(const ChannelLayout *layout, int stream_id, int prev) +int get_left_channel(const ChannelLayout *layout, int stream_id, int prev) { int i; i = (prev<0) ? 0 : prev+1; @@ -99,7 +66,7 @@ static int get_left_channel(const ChannelLayout *layout, int stream_id, int prev return -1; } -static int get_right_channel(const ChannelLayout *layout, int stream_id, int prev) +int get_right_channel(const ChannelLayout *layout, int stream_id, int prev) { int i; i = (prev<0) ? 0 : prev+1; @@ -111,7 +78,7 @@ static int get_right_channel(const ChannelLayout *layout, int stream_id, int pre return -1; } -static int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev) +int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev) { int i; i = (prev<0) ? 0 : prev+1; @@ -123,740 +90,3 @@ static int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev return -1; } -static int validate_encoder_layout(const ChannelLayout *layout) -{ - int s; - for (s=0;snb_streams;s++) - { - if (s < layout->nb_coupled_streams) - { - if (get_left_channel(layout, s, -1)==-1) - return 0; - if (get_right_channel(layout, s, -1)==-1) - return 0; - } else { - if (get_mono_channel(layout, s, -1)==-1) - return 0; - } - } - return 1; -} - -opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams) -{ - int coupled_size; - int mono_size; - - if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0; - coupled_size = opus_encoder_get_size(2); - mono_size = opus_encoder_get_size(1); - return align(sizeof(OpusMSEncoder)) - + nb_coupled_streams * align(coupled_size) - + (nb_streams-nb_coupled_streams) * align(mono_size); -} - - - -int opus_multistream_encoder_init( - OpusMSEncoder *st, - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - unsigned char *mapping, - int application -) -{ - int coupled_size; - int mono_size; - int i; - char *ptr; - - st->layout.nb_channels = channels; - st->layout.nb_streams = streams; - st->layout.nb_coupled_streams = coupled_streams; - - for (i=0;ilayout.nb_channels;i++) - st->layout.mapping[i] = mapping[i]; - if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout)) - return OPUS_BAD_ARG; - ptr = (char*)st + align(sizeof(OpusMSEncoder)); - coupled_size = opus_encoder_get_size(2); - mono_size = opus_encoder_get_size(1); - - for (i=0;ilayout.nb_coupled_streams;i++) - { - opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application); - ptr += align(coupled_size); - } - for (;ilayout.nb_streams;i++) - { - opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application); - ptr += align(mono_size); - } - return OPUS_OK; -} - -OpusMSEncoder *opus_multistream_encoder_create( - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - unsigned char *mapping, - int application, - int *error -) -{ - int ret; - OpusMSEncoder *st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams)); - if (st==NULL) - { - if (error) - *error = OPUS_ALLOC_FAIL; - return NULL; - } - ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application); - if (ret != OPUS_OK) - { - opus_free(st); - st = NULL; - } - if (error) - *error = ret; - return st; -} - - -#ifdef FIXED_POINT -int opus_multistream_encode( -#else -int opus_multistream_encode_float( -#endif - OpusMSEncoder *st, - const opus_val16 *pcm, - int frame_size, - unsigned char *data, - int max_data_bytes -) -{ - int coupled_size; - int mono_size; - int s, i; - char *ptr; - int tot_size; - VARDECL(opus_val16, buf); - /* Max size in case the encoder decides to return three frames */ - unsigned char tmp_data[3*1275+7]; - OpusRepacketizer rp; - ALLOC_STACK; - - ALLOC(buf, 2*frame_size, opus_val16); - ptr = (char*)st + align(sizeof(OpusMSEncoder)); - coupled_size = opus_encoder_get_size(2); - mono_size = opus_encoder_get_size(1); - - if (max_data_bytes < 2*st->layout.nb_streams-1) - { - RESTORE_STACK; - return OPUS_BUFFER_TOO_SMALL; - } - /* Counting ToC */ - tot_size = 0; - for (s=0;slayout.nb_streams;s++) - { - OpusEncoder *enc; - int len; - int curr_max; - - opus_repacketizer_init(&rp); - enc = (OpusEncoder*)ptr; - if (s < st->layout.nb_coupled_streams) - { - int left, right; - left = get_left_channel(&st->layout, s, -1); - right = get_right_channel(&st->layout, s, -1); - for (i=0;ilayout.nb_channels*i+left]; - buf[2*i+1] = pcm[st->layout.nb_channels*i+right]; - } - ptr += align(coupled_size); - } else { - int chan = get_mono_channel(&st->layout, s, -1); - for (i=0;ilayout.nb_channels*i+chan]; - ptr += align(mono_size); - } - /* number of bytes left (+Toc) */ - curr_max = max_data_bytes - tot_size; - /* Reserve one byte for the last stream and 2 for the others */ - curr_max -= 2*(st->layout.nb_streams-s)-1; - len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max); - if (len<0) - { - RESTORE_STACK; - return len; - } - /* We need to use the repacketizer to add the self-delimiting lengths - while taking into account the fact that the encoder can now return - more than one frame at a time (e.g. 60 ms CELT-only) */ - opus_repacketizer_cat(&rp, tmp_data, len); - len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp), data, max_data_bytes-tot_size, s != st->layout.nb_streams-1); - data += len; - tot_size += len; - } - RESTORE_STACK; - return tot_size; - -} - -#ifdef FIXED_POINT - -#ifndef DISABLE_FLOAT_API -int opus_multistream_encode_float( - OpusMSEncoder *st, - const float *pcm, - int frame_size, - unsigned char *data, - int max_data_bytes -) -{ - int i, ret; - VARDECL(opus_int16, in); - ALLOC_STACK; - - ALLOC(in, frame_size*st->layout.nb_channels, opus_int16); - - for (i=0;ilayout.nb_channels;i++) - in[i] = FLOAT2INT16(pcm[i]); - ret = opus_multistream_encode(st, in, frame_size, data, max_data_bytes); - RESTORE_STACK; - return ret; -} -#endif - -#else - -int opus_multistream_encode( - OpusMSEncoder *st, - const opus_int16 *pcm, - int frame_size, - unsigned char *data, - int max_data_bytes -) -{ - int i, ret; - VARDECL(float, in); - ALLOC_STACK; - - ALLOC(in, frame_size*st->layout.nb_channels, float); - - for (i=0;ilayout.nb_channels;i++) - in[i] = (1./32768)*pcm[i]; - ret = opus_multistream_encode_float(st, in, frame_size, data, max_data_bytes); - RESTORE_STACK; - return ret; -} - -#endif - -int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) -{ - va_list ap; - int coupled_size, mono_size; - char *ptr; - int ret = OPUS_OK; - - va_start(ap, request); - - coupled_size = opus_encoder_get_size(2); - mono_size = opus_encoder_get_size(1); - ptr = (char*)st + align(sizeof(OpusMSEncoder)); - switch (request) - { - case OPUS_SET_BITRATE_REQUEST: - { - int chan, s; - opus_int32 value = va_arg(ap, opus_int32); - chan = st->layout.nb_streams + st->layout.nb_coupled_streams; - value /= chan; - for (s=0;slayout.nb_streams;s++) - { - OpusEncoder *enc; - enc = (OpusEncoder*)ptr; - opus_encoder_ctl(enc, request, value * (s < st->layout.nb_coupled_streams ? 2 : 1)); - } - } - break; - case OPUS_GET_BITRATE_REQUEST: - { - int s; - opus_int32 *value = va_arg(ap, opus_int32*); - *value = 0; - for (s=0;slayout.nb_streams;s++) - { - opus_int32 rate; - OpusEncoder *enc; - enc = (OpusEncoder*)ptr; - opus_encoder_ctl(enc, request, &rate); - *value += rate; - } - } - break; - case OPUS_GET_VBR_REQUEST: - case OPUS_GET_APPLICATION_REQUEST: - case OPUS_GET_BANDWIDTH_REQUEST: - case OPUS_GET_COMPLEXITY_REQUEST: - case OPUS_GET_PACKET_LOSS_PERC_REQUEST: - case OPUS_GET_DTX_REQUEST: - case OPUS_GET_VOICE_RATIO_REQUEST: - case OPUS_GET_VBR_CONSTRAINT_REQUEST: - case OPUS_GET_SIGNAL_REQUEST: - case OPUS_GET_LOOKAHEAD_REQUEST: - case OPUS_GET_INBAND_FEC_REQUEST: - { - OpusEncoder *enc; - /* For int32* GET params, just query the first stream */ - opus_int32 *value = va_arg(ap, opus_int32*); - enc = (OpusEncoder*)ptr; - ret = opus_encoder_ctl(enc, request, value); - } - break; - case OPUS_GET_FINAL_RANGE_REQUEST: - { - int s; - opus_uint32 *value = va_arg(ap, opus_uint32*); - opus_uint32 tmp; - *value=0; - for (s=0;slayout.nb_streams;s++) - { - OpusEncoder *enc; - enc = (OpusEncoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - ret = opus_encoder_ctl(enc, request, &tmp); - if (ret != OPUS_OK) break; - *value ^= tmp; - } - } - break; - case OPUS_SET_COMPLEXITY_REQUEST: - case OPUS_SET_VBR_REQUEST: - case OPUS_SET_VBR_CONSTRAINT_REQUEST: - case OPUS_SET_BANDWIDTH_REQUEST: - case OPUS_SET_SIGNAL_REQUEST: - case OPUS_SET_APPLICATION_REQUEST: - case OPUS_SET_INBAND_FEC_REQUEST: - case OPUS_SET_PACKET_LOSS_PERC_REQUEST: - case OPUS_SET_DTX_REQUEST: - case OPUS_SET_FORCE_MODE_REQUEST: - { - int s; - /* This works for int32 params */ - opus_int32 value = va_arg(ap, opus_int32); - for (s=0;slayout.nb_streams;s++) - { - OpusEncoder *enc; - - enc = (OpusEncoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - ret = opus_encoder_ctl(enc, request, value); - if (ret != OPUS_OK) - break; - } - } - break; - case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST: - { - int s; - opus_int32 stream_id; - OpusEncoder **value; - stream_id = va_arg(ap, opus_int32); - if (stream_id<0 || stream_id >= st->layout.nb_streams) - ret = OPUS_BAD_ARG; - value = va_arg(ap, OpusEncoder**); - for (s=0;slayout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - } - *value = (OpusEncoder*)ptr; - } - break; - default: - ret = OPUS_UNIMPLEMENTED; - break; - } - - va_end(ap); - return ret; -} - -void opus_multistream_encoder_destroy(OpusMSEncoder *st) -{ - opus_free(st); -} - - -/* DECODER */ - -opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams) -{ - int coupled_size; - int mono_size; - - if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0; - coupled_size = opus_decoder_get_size(2); - mono_size = opus_decoder_get_size(1); - return align(sizeof(OpusMSDecoder)) - + nb_coupled_streams * align(coupled_size) - + (nb_streams-nb_coupled_streams) * align(mono_size); -} - -int opus_multistream_decoder_init( - OpusMSDecoder *st, - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - unsigned char *mapping -) -{ - int coupled_size; - int mono_size; - int i, ret; - char *ptr; - - st->layout.nb_channels = channels; - st->layout.nb_streams = streams; - st->layout.nb_coupled_streams = coupled_streams; - - for (i=0;ilayout.nb_channels;i++) - st->layout.mapping[i] = mapping[i]; - if (!validate_layout(&st->layout)) - return OPUS_BAD_ARG; - - ptr = (char*)st + align(sizeof(OpusMSDecoder)); - coupled_size = opus_decoder_get_size(2); - mono_size = opus_decoder_get_size(1); - - for (i=0;ilayout.nb_coupled_streams;i++) - { - ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 2); - if(ret!=OPUS_OK)return ret; - ptr += align(coupled_size); - } - for (;ilayout.nb_streams;i++) - { - ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 1); - if(ret!=OPUS_OK)return ret; - ptr += align(mono_size); - } - return OPUS_OK; -} - - -OpusMSDecoder *opus_multistream_decoder_create( - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - unsigned char *mapping, - int *error -) -{ - int ret; - OpusMSDecoder *st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams)); - if (st==NULL) - { - if (error) - *error = OPUS_ALLOC_FAIL; - return NULL; - } - ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping); - if (error) - *error = ret; - if (ret != OPUS_OK) - { - opus_free(st); - st = NULL; - } - return st; - - -} - -static int opus_multistream_decode_native( - OpusMSDecoder *st, - const unsigned char *data, - int len, - opus_val16 *pcm, - int frame_size, - int decode_fec -) -{ - int coupled_size; - int mono_size; - int s, i, c; - char *ptr; - int do_plc=0; - VARDECL(opus_val16, buf); - ALLOC_STACK; - - ALLOC(buf, 2*frame_size, opus_val16); - ptr = (char*)st + align(sizeof(OpusMSDecoder)); - coupled_size = opus_decoder_get_size(2); - mono_size = opus_decoder_get_size(1); - - if (len==0) - do_plc = 1; - if (len < 0) - return OPUS_BAD_ARG; - if (!do_plc && len < 2*st->layout.nb_streams-1) - return OPUS_INVALID_PACKET; - for (s=0;slayout.nb_streams;s++) - { - OpusDecoder *dec; - int packet_offset, ret; - - dec = (OpusDecoder*)ptr; - ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size); - - if (!do_plc && len<=0) - { - RESTORE_STACK; - return OPUS_INVALID_PACKET; - } - packet_offset = 0; - ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset); - data += packet_offset; - len -= packet_offset; - if (ret > frame_size) - { - RESTORE_STACK; - return OPUS_BUFFER_TOO_SMALL; - } - if (s>0 && ret != frame_size) - { - RESTORE_STACK; - return OPUS_INVALID_PACKET; - } - if (ret <= 0) - { - RESTORE_STACK; - return ret; - } - frame_size = ret; - if (s < st->layout.nb_coupled_streams) - { - int chan, prev; - prev = -1; - /* Copy "left" audio to the channel(s) where it belongs */ - while ( (chan = get_left_channel(&st->layout, s, prev)) != -1) - { - for (i=0;ilayout.nb_channels*i+chan] = buf[2*i]; - prev = chan; - } - prev = -1; - /* Copy "right" audio to the channel(s) where it belongs */ - while ( (chan = get_right_channel(&st->layout, s, prev)) != -1) - { - for (i=0;ilayout.nb_channels*i+chan] = buf[2*i+1]; - prev = chan; - } - } else { - int chan, prev; - prev = -1; - /* Copy audio to the channel(s) where it belongs */ - while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1) - { - for (i=0;ilayout.nb_channels*i+chan] = buf[i]; - prev = chan; - } - } - } - /* Handle muted channels */ - for (c=0;clayout.nb_channels;c++) - { - if (st->layout.mapping[c] == 255) - { - for (i=0;ilayout.nb_channels*i+c] = 0; - } - } - RESTORE_STACK; - return frame_size; -} - -#ifdef FIXED_POINT -int opus_multistream_decode( - OpusMSDecoder *st, - const unsigned char *data, - int len, - opus_int16 *pcm, - int frame_size, - int decode_fec -) -{ - return opus_multistream_decode_native(st, data, len, pcm, frame_size, decode_fec); -} - -#ifndef DISABLE_FLOAT_API -int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data, - int len, float *pcm, int frame_size, int decode_fec) -{ - VARDECL(opus_int16, out); - int ret, i; - ALLOC_STACK; - - ALLOC(out, frame_size*st->layout.nb_channels, opus_int16); - - ret = opus_multistream_decode_native(st, data, len, out, frame_size, decode_fec); - if (ret > 0) - { - for (i=0;ilayout.nb_channels;i++) - pcm[i] = (1./32768.)*(out[i]); - } - RESTORE_STACK; - return ret; -} -#endif - -#else - -int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data, - int len, opus_int16 *pcm, int frame_size, int decode_fec) -{ - VARDECL(float, out); - int ret, i; - ALLOC_STACK; - - ALLOC(out, frame_size*st->layout.nb_channels, float); - - ret = opus_multistream_decode_native(st, data, len, out, frame_size, decode_fec); - if (ret > 0) - { - for (i=0;ilayout.nb_channels;i++) - pcm[i] = FLOAT2INT16(out[i]); - } - RESTORE_STACK; - return ret; -} - -int opus_multistream_decode_float( - OpusMSDecoder *st, - const unsigned char *data, - int len, - float *pcm, - int frame_size, - int decode_fec -) -{ - return opus_multistream_decode_native(st, data, len, pcm, frame_size, decode_fec); -} -#endif - -int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) -{ - va_list ap; - int coupled_size, mono_size; - char *ptr; - int ret = OPUS_OK; - - va_start(ap, request); - - coupled_size = opus_decoder_get_size(2); - mono_size = opus_decoder_get_size(1); - ptr = (char*)st + align(sizeof(OpusMSDecoder)); - switch (request) - { - case OPUS_GET_BANDWIDTH_REQUEST: - { - OpusDecoder *dec; - /* For int32* GET params, just query the first stream */ - opus_int32 *value = va_arg(ap, opus_int32*); - dec = (OpusDecoder*)ptr; - ret = opus_decoder_ctl(dec, request, value); - } - break; - case OPUS_GET_FINAL_RANGE_REQUEST: - { - int s; - opus_uint32 *value = va_arg(ap, opus_uint32*); - opus_uint32 tmp; - *value = 0; - for (s=0;slayout.nb_streams;s++) - { - OpusDecoder *dec; - dec = (OpusDecoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - ret = opus_decoder_ctl(dec, request, &tmp); - if (ret != OPUS_OK) break; - *value ^= tmp; - } - } - break; - case OPUS_RESET_STATE: - { - int s; - for (s=0;slayout.nb_streams;s++) - { - OpusDecoder *dec; - - dec = (OpusDecoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - ret = opus_decoder_ctl(dec, OPUS_RESET_STATE); - if (ret != OPUS_OK) - break; - } - } - break; - case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST: - { - int s; - opus_int32 stream_id; - OpusDecoder **value; - stream_id = va_arg(ap, opus_int32); - if (stream_id<0 || stream_id >= st->layout.nb_streams) - ret = OPUS_BAD_ARG; - value = va_arg(ap, OpusDecoder**); - for (s=0;slayout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - } - *value = (OpusDecoder*)ptr; - } - break; - default: - ret = OPUS_UNIMPLEMENTED; - break; - } - - va_end(ap); - return ret; -} - - -void opus_multistream_decoder_destroy(OpusMSDecoder *st) -{ - opus_free(st); -} diff --git a/media/libopus/src/opus_multistream_decoder.c b/media/libopus/src/opus_multistream_decoder.c new file mode 100644 index 000000000000..f3d2311e450b --- /dev/null +++ b/media/libopus/src/opus_multistream_decoder.c @@ -0,0 +1,499 @@ +/* Copyright (c) 2011 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "opus_multistream.h" +#include "opus.h" +#include "opus_private.h" +#include "stack_alloc.h" +#include +#include "float_cast.h" +#include "os_support.h" + +struct OpusMSDecoder { + ChannelLayout layout; + /* Decoder states go here */ +}; + + + + +/* DECODER */ + +opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams) +{ + int coupled_size; + int mono_size; + + if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0; + coupled_size = opus_decoder_get_size(2); + mono_size = opus_decoder_get_size(1); + return align(sizeof(OpusMSDecoder)) + + nb_coupled_streams * align(coupled_size) + + (nb_streams-nb_coupled_streams) * align(mono_size); +} + +int opus_multistream_decoder_init( + OpusMSDecoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping +) +{ + int coupled_size; + int mono_size; + int i, ret; + char *ptr; + + if ((channels>255) || (channels<1) || (coupled_streams>streams) || + (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0)) + return OPUS_BAD_ARG; + + st->layout.nb_channels = channels; + st->layout.nb_streams = streams; + st->layout.nb_coupled_streams = coupled_streams; + + for (i=0;ilayout.nb_channels;i++) + st->layout.mapping[i] = mapping[i]; + if (!validate_layout(&st->layout)) + return OPUS_BAD_ARG; + + ptr = (char*)st + align(sizeof(OpusMSDecoder)); + coupled_size = opus_decoder_get_size(2); + mono_size = opus_decoder_get_size(1); + + for (i=0;ilayout.nb_coupled_streams;i++) + { + ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 2); + if(ret!=OPUS_OK)return ret; + ptr += align(coupled_size); + } + for (;ilayout.nb_streams;i++) + { + ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 1); + if(ret!=OPUS_OK)return ret; + ptr += align(mono_size); + } + return OPUS_OK; +} + + +OpusMSDecoder *opus_multistream_decoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int *error +) +{ + int ret; + OpusMSDecoder *st; + if ((channels>255) || (channels<1) || (coupled_streams>streams) || + (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0)) + { + if (error) + *error = OPUS_BAD_ARG; + return NULL; + } + st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams)); + if (st==NULL) + { + if (error) + *error = OPUS_ALLOC_FAIL; + return NULL; + } + ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping); + if (error) + *error = ret; + if (ret != OPUS_OK) + { + opus_free(st); + st = NULL; + } + return st; +} + +typedef void (*opus_copy_channel_out_func)( + void *dst, + int dst_stride, + int dst_channel, + const opus_val16 *src, + int src_stride, + int frame_size +); + +static int opus_multistream_decode_native( + OpusMSDecoder *st, + const unsigned char *data, + opus_int32 len, + void *pcm, + opus_copy_channel_out_func copy_channel_out, + int frame_size, + int decode_fec, + int soft_clip +) +{ + opus_int32 Fs; + int coupled_size; + int mono_size; + int s, c; + char *ptr; + int do_plc=0; + VARDECL(opus_val16, buf); + ALLOC_STACK; + + /* Limit frame_size to avoid excessive stack allocations. */ + opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs)); + frame_size = IMIN(frame_size, Fs/25*3); + ALLOC(buf, 2*frame_size, opus_val16); + ptr = (char*)st + align(sizeof(OpusMSDecoder)); + coupled_size = opus_decoder_get_size(2); + mono_size = opus_decoder_get_size(1); + + if (len==0) + do_plc = 1; + if (len < 0) + return OPUS_BAD_ARG; + if (!do_plc && len < 2*st->layout.nb_streams-1) + return OPUS_INVALID_PACKET; + for (s=0;slayout.nb_streams;s++) + { + OpusDecoder *dec; + int packet_offset, ret; + + dec = (OpusDecoder*)ptr; + ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size); + + if (!do_plc && len<=0) + { + RESTORE_STACK; + return OPUS_INVALID_PACKET; + } + packet_offset = 0; + ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset, soft_clip); + data += packet_offset; + len -= packet_offset; + if (ret > frame_size) + { + RESTORE_STACK; + return OPUS_BUFFER_TOO_SMALL; + } + if (s>0 && ret != frame_size) + { + RESTORE_STACK; + return OPUS_INVALID_PACKET; + } + if (ret <= 0) + { + RESTORE_STACK; + return ret; + } + frame_size = ret; + if (s < st->layout.nb_coupled_streams) + { + int chan, prev; + prev = -1; + /* Copy "left" audio to the channel(s) where it belongs */ + while ( (chan = get_left_channel(&st->layout, s, prev)) != -1) + { + (*copy_channel_out)(pcm, st->layout.nb_channels, chan, + buf, 2, frame_size); + prev = chan; + } + prev = -1; + /* Copy "right" audio to the channel(s) where it belongs */ + while ( (chan = get_right_channel(&st->layout, s, prev)) != -1) + { + (*copy_channel_out)(pcm, st->layout.nb_channels, chan, + buf+1, 2, frame_size); + prev = chan; + } + } else { + int chan, prev; + prev = -1; + /* Copy audio to the channel(s) where it belongs */ + while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1) + { + (*copy_channel_out)(pcm, st->layout.nb_channels, chan, + buf, 1, frame_size); + prev = chan; + } + } + } + /* Handle muted channels */ + for (c=0;clayout.nb_channels;c++) + { + if (st->layout.mapping[c] == 255) + { + (*copy_channel_out)(pcm, st->layout.nb_channels, c, + NULL, 0, frame_size); + } + } + RESTORE_STACK; + return frame_size; +} + +#if !defined(DISABLE_FLOAT_API) +static void opus_copy_channel_out_float( + void *dst, + int dst_stride, + int dst_channel, + const opus_val16 *src, + int src_stride, + int frame_size +) +{ + float *float_dst; + opus_int32 i; + float_dst = (float*)dst; + if (src != NULL) + { + for (i=0;ilayout.nb_streams;s++) + { + OpusDecoder *dec; + dec = (OpusDecoder*)ptr; + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + ret = opus_decoder_ctl(dec, request, &tmp); + if (ret != OPUS_OK) break; + *value ^= tmp; + } + } + break; + case OPUS_RESET_STATE: + { + int s; + for (s=0;slayout.nb_streams;s++) + { + OpusDecoder *dec; + + dec = (OpusDecoder*)ptr; + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + ret = opus_decoder_ctl(dec, OPUS_RESET_STATE); + if (ret != OPUS_OK) + break; + } + } + break; + case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST: + { + int s; + opus_int32 stream_id; + OpusDecoder **value; + stream_id = va_arg(ap, opus_int32); + if (stream_id<0 || stream_id >= st->layout.nb_streams) + ret = OPUS_BAD_ARG; + value = va_arg(ap, OpusDecoder**); + if (!value) + { + goto bad_arg; + } + for (s=0;slayout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + } + *value = (OpusDecoder*)ptr; + } + break; + case OPUS_SET_GAIN_REQUEST: + { + int s; + /* This works for int32 params */ + opus_int32 value = va_arg(ap, opus_int32); + for (s=0;slayout.nb_streams;s++) + { + OpusDecoder *dec; + + dec = (OpusDecoder*)ptr; + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + ret = opus_decoder_ctl(dec, request, value); + if (ret != OPUS_OK) + break; + } + } + break; + default: + ret = OPUS_UNIMPLEMENTED; + break; + } + + va_end(ap); + return ret; +bad_arg: + va_end(ap); + return OPUS_BAD_ARG; +} + + +void opus_multistream_decoder_destroy(OpusMSDecoder *st) +{ + opus_free(st); +} diff --git a/media/libopus/src/opus_multistream_encoder.c b/media/libopus/src/opus_multistream_encoder.c new file mode 100644 index 000000000000..4cddbffd5524 --- /dev/null +++ b/media/libopus/src/opus_multistream_encoder.c @@ -0,0 +1,1054 @@ +/* Copyright (c) 2011 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "opus_multistream.h" +#include "opus.h" +#include "opus_private.h" +#include "stack_alloc.h" +#include +#include "float_cast.h" +#include "os_support.h" +#include "analysis.h" +#include "mathops.h" + +typedef struct { + int nb_streams; + int nb_coupled_streams; + unsigned char mapping[8]; +} VorbisLayout; + +/* Index is nb_channel-1*/ +static const VorbisLayout vorbis_mappings[8] = { + {1, 0, {0}}, /* 1: mono */ + {1, 1, {0, 1}}, /* 2: stereo */ + {2, 1, {0, 2, 1}}, /* 3: 1-d surround */ + {2, 2, {0, 1, 2, 3}}, /* 4: quadraphonic surround */ + {3, 2, {0, 4, 1, 2, 3}}, /* 5: 5-channel surround */ + {4, 2, {0, 4, 1, 2, 3, 5}}, /* 6: 5.1 surround */ + {4, 3, {0, 4, 1, 2, 3, 5, 6}}, /* 7: 6.1 surround */ + {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */ +}; + +struct OpusMSEncoder { + TonalityAnalysisState analysis; + ChannelLayout layout; + int lfe_stream; + int variable_duration; + int surround; + opus_int32 bitrate_bps; + opus_val32 subframe_mem[3]; + /* Encoder states go here */ +}; + + +static int validate_encoder_layout(const ChannelLayout *layout) +{ + int s; + for (s=0;snb_streams;s++) + { + if (s < layout->nb_coupled_streams) + { + if (get_left_channel(layout, s, -1)==-1) + return 0; + if (get_right_channel(layout, s, -1)==-1) + return 0; + } else { + if (get_mono_channel(layout, s, -1)==-1) + return 0; + } + } + return 1; +} + + +opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams) +{ + int coupled_size; + int mono_size; + + if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0; + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + return align(sizeof(OpusMSEncoder)) + + nb_coupled_streams * align(coupled_size) + + (nb_streams-nb_coupled_streams) * align(mono_size); +} + +opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family) +{ + int nb_streams; + int nb_coupled_streams; + opus_int32 size; + + if (mapping_family==0) + { + if (channels==1) + { + nb_streams=1; + nb_coupled_streams=0; + } else if (channels==2) + { + nb_streams=1; + nb_coupled_streams=1; + } else + return 0; + } else if (mapping_family==1 && channels<=8 && channels>=1) + { + nb_streams=vorbis_mappings[channels-1].nb_streams; + nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams; + } else if (mapping_family==255) + { + nb_streams=channels; + nb_coupled_streams=0; + } else + return 0; + size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams); + if (channels>2) + size += align(opus_encoder_get_size(2)); + return size; +} + + +static int opus_multistream_encoder_init_impl( + OpusMSEncoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application, + int surround +) +{ + int coupled_size; + int mono_size; + int i, ret; + char *ptr; + + if ((channels>255) || (channels<1) || (coupled_streams>streams) || + (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0)) + return OPUS_BAD_ARG; + + st->layout.nb_channels = channels; + st->layout.nb_streams = streams; + st->layout.nb_coupled_streams = coupled_streams; + st->subframe_mem[0]=st->subframe_mem[1]=st->subframe_mem[2]=0; + OPUS_CLEAR(&st->analysis,1); + if (!surround) + st->lfe_stream = -1; + st->bitrate_bps = OPUS_AUTO; + st->variable_duration = OPUS_FRAMESIZE_ARG; + for (i=0;ilayout.nb_channels;i++) + st->layout.mapping[i] = mapping[i]; + if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout)) + return OPUS_BAD_ARG; + ptr = (char*)st + align(sizeof(OpusMSEncoder)); + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + + for (i=0;ilayout.nb_coupled_streams;i++) + { + ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application); + if(ret!=OPUS_OK)return ret; + if (i==st->lfe_stream) + opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); + ptr += align(coupled_size); + } + for (;ilayout.nb_streams;i++) + { + ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application); + if (i==st->lfe_stream) + opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); + if(ret!=OPUS_OK)return ret; + ptr += align(mono_size); + } + if (surround) + { + OpusEncoder *downmix_enc; + downmix_enc = (OpusEncoder*)ptr; + ret = opus_encoder_init(downmix_enc, Fs, 2, OPUS_APPLICATION_AUDIO); + if(ret!=OPUS_OK)return ret; + } + st->surround = surround; + return OPUS_OK; +} + +int opus_multistream_encoder_init( + OpusMSEncoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application +) +{ + return opus_multistream_encoder_init_impl(st, Fs, channels, streams, coupled_streams, mapping, application, 0); +} + +int opus_multistream_surround_encoder_init( + OpusMSEncoder *st, + opus_int32 Fs, + int channels, + int mapping_family, + int *streams, + int *coupled_streams, + unsigned char *mapping, + int application +) +{ + if ((channels>255) || (channels<1)) + return OPUS_BAD_ARG; + st->lfe_stream = -1; + if (mapping_family==0) + { + if (channels==1) + { + *streams=1; + *coupled_streams=0; + mapping[0]=0; + } else if (channels==2) + { + *streams=1; + *coupled_streams=1; + mapping[0]=0; + mapping[1]=1; + } else + return OPUS_UNIMPLEMENTED; + } else if (mapping_family==1 && channels<=8 && channels>=1) + { + int i; + *streams=vorbis_mappings[channels-1].nb_streams; + *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams; + for (i=0;i=6) + st->lfe_stream = *streams-1; + } else if (mapping_family==255) + { + int i; + *streams=channels; + *coupled_streams=0; + for(i=0;i2&&mapping_family==1); +} + +OpusMSEncoder *opus_multistream_encoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application, + int *error +) +{ + int ret; + OpusMSEncoder *st; + if ((channels>255) || (channels<1) || (coupled_streams>streams) || + (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0)) + { + if (error) + *error = OPUS_BAD_ARG; + return NULL; + } + st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams)); + if (st==NULL) + { + if (error) + *error = OPUS_ALLOC_FAIL; + return NULL; + } + ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application); + if (ret != OPUS_OK) + { + opus_free(st); + st = NULL; + } + if (error) + *error = ret; + return st; +} + +OpusMSEncoder *opus_multistream_surround_encoder_create( + opus_int32 Fs, + int channels, + int mapping_family, + int *streams, + int *coupled_streams, + unsigned char *mapping, + int application, + int *error +) +{ + int ret; + OpusMSEncoder *st; + if ((channels>255) || (channels<1)) + { + if (error) + *error = OPUS_BAD_ARG; + return NULL; + } + st = (OpusMSEncoder *)opus_alloc(opus_multistream_surround_encoder_get_size(channels, mapping_family)); + if (st==NULL) + { + if (error) + *error = OPUS_ALLOC_FAIL; + return NULL; + } + ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application); + if (ret != OPUS_OK) + { + opus_free(st); + st = NULL; + } + if (error) + *error = ret; + return st; +} + +typedef void (*opus_copy_channel_in_func)( + opus_val16 *dst, + int dst_stride, + const void *src, + int src_stride, + int src_channel, + int frame_size +); + +typedef void (*opus_surround_downmix_funct)( + opus_val16 *dst, + const void *src, + int channels, + int frame_size +); + +static void surround_rate_allocation( + OpusMSEncoder *st, + opus_int32 *rate, + int frame_size + ) +{ + int i; + opus_int32 channel_rate; + opus_int32 Fs; + char *ptr; + int stream_offset; + int lfe_offset; + int coupled_ratio; /* Q8 */ + int lfe_ratio; /* Q8 */ + + ptr = (char*)st + align(sizeof(OpusMSEncoder)); + opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs)); + + if (st->bitrate_bps > st->layout.nb_channels*40000) + stream_offset = 20000; + else + stream_offset = st->bitrate_bps/st->layout.nb_channels/2; + /* We start by giving each stream (coupled or uncoupled) the same bitrate. + This models the main saving of coupled channels over uncoupled. */ + /* The LFE stream is an exception to the above and gets fewer bits. */ + lfe_offset = 3500; + /* Coupled streams get twice the mono rate after the first 20 kb/s. */ + coupled_ratio = 512; + /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */ + lfe_ratio = 32; + + /* Compute bitrate allocation between streams */ + if (st->bitrate_bps==OPUS_AUTO) + { + channel_rate = Fs+60*Fs/frame_size; + } else if (st->bitrate_bps==OPUS_BITRATE_MAX) + { + channel_rate = 300000; + } else { + int nb_lfe; + int nb_uncoupled; + int nb_coupled; + int total; + nb_lfe = (st->lfe_stream!=-1); + nb_coupled = st->layout.nb_coupled_streams; + nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe; + total = (nb_uncoupled<<8) /* mono */ + + coupled_ratio*nb_coupled /* stereo */ + + nb_lfe*lfe_ratio; + channel_rate = 256*(st->bitrate_bps-lfe_offset*nb_lfe-stream_offset*(nb_coupled+nb_uncoupled))/total; + } +#ifndef FIXED_POINT + if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50) + { + opus_int32 bonus; + bonus = 60*(Fs/frame_size-50); + channel_rate += bonus; + } +#endif + + for (i=0;ilayout.nb_streams;i++) + { + if (ilayout.nb_coupled_streams) + rate[i] = stream_offset+(channel_rate*coupled_ratio>>8); + else if (i!=st->lfe_stream) + rate[i] = stream_offset+channel_rate; + else + rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8); + } +} + +/* Max size in case the encoder decides to return three frames */ +#define MS_FRAME_TMP (3*1275+7) +static int opus_multistream_encode_native +( + OpusMSEncoder *st, + opus_copy_channel_in_func copy_channel_in, + const void *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes, + int lsb_depth, + opus_surround_downmix_funct surround_downmix +#ifndef FIXED_POINT + , downmix_func downmix + , const void *pcm_analysis +#endif +) +{ + opus_int32 Fs; + int coupled_size; + int mono_size; + int s; + char *ptr; + int tot_size; + VARDECL(opus_val16, buf); + unsigned char tmp_data[MS_FRAME_TMP]; + OpusRepacketizer rp; + opus_int32 complexity; +#ifndef FIXED_POINT + AnalysisInfo analysis_info; +#endif + const CELTMode *celt_mode; + opus_int32 bitrates[256]; + opus_val16 bandLogE[42]; + opus_val16 bandLogE_mono[21]; + ALLOC_STACK; + + ptr = (char*)st + align(sizeof(OpusMSEncoder)); + opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs)); + opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_COMPLEXITY(&complexity)); + opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode)); + + if (400*frame_size < Fs) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } +#ifndef FIXED_POINT + analysis_info.valid = 0; + if (complexity >= 7 && Fs==48000) + { + opus_int32 delay_compensation; + int channels; + + channels = st->layout.nb_streams + st->layout.nb_coupled_streams; + opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation)); + delay_compensation -= Fs/400; + + frame_size = run_analysis(&st->analysis, celt_mode, pcm, pcm_analysis, + frame_size, st->variable_duration, channels, Fs, st->bitrate_bps, delay_compensation, lsb_depth, downmix, &analysis_info); + } else +#endif + { + frame_size = frame_size_select(frame_size, st->variable_duration, Fs); + } + /* Validate frame_size before using it to allocate stack space. + This mirrors the checks in opus_encode[_float](). */ + if (400*frame_size != Fs && 200*frame_size != Fs && + 100*frame_size != Fs && 50*frame_size != Fs && + 25*frame_size != Fs && 50*frame_size != 3*Fs) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } + ALLOC(buf, 2*frame_size, opus_val16); + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + + if (st->surround) + { + int i; + unsigned char dummy[512]; + /* Temporary kludge -- remove */ + OpusEncoder *downmix_enc; + + ptr = (char*)st + align(sizeof(OpusMSEncoder)); + for (s=0;slayout.nb_streams;s++) + { + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + } + downmix_enc = (OpusEncoder*)ptr; + surround_downmix(buf, pcm, st->layout.nb_channels, frame_size); + opus_encoder_ctl(downmix_enc, OPUS_SET_ENERGY_SAVE(bandLogE)); + opus_encoder_ctl(downmix_enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); + opus_encoder_ctl(downmix_enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY)); + opus_encoder_ctl(downmix_enc, OPUS_SET_FORCE_CHANNELS(2)); + opus_encode_native(downmix_enc, buf, frame_size, dummy, 512, lsb_depth +#ifndef FIXED_POINT + , &analysis_info +#endif + ); + /* Combines the left and right mask into a centre mask. We + use an approximation for the log of the sum of the energies. */ + for(i=0;i<21;i++) + { + opus_val16 diff; + diff = ABS16(SUB16(bandLogE[i], bandLogE[21+i])); + diff = diff + HALF16(diff); + diff = SHR32(HALF32(celt_exp2(-diff)), 16-DB_SHIFT); + bandLogE_mono[i] = MAX16(bandLogE[i], bandLogE[21+i]) + diff; + } + } + + if (max_data_bytes < 4*st->layout.nb_streams-1) + { + RESTORE_STACK; + return OPUS_BUFFER_TOO_SMALL; + } + + /* Compute bitrate allocation between streams (this could be a lot better) */ + surround_rate_allocation(st, bitrates, frame_size); + + ptr = (char*)st + align(sizeof(OpusMSEncoder)); + for (s=0;slayout.nb_streams;s++) + { + OpusEncoder *enc; + enc = (OpusEncoder*)ptr; + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s])); + if (st->surround) + { + opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY)); + opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); + if (s < st->layout.nb_coupled_streams) + opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2)); + } + } + + ptr = (char*)st + align(sizeof(OpusMSEncoder)); + /* Counting ToC */ + tot_size = 0; + for (s=0;slayout.nb_streams;s++) + { + OpusEncoder *enc; + int len; + int curr_max; + + opus_repacketizer_init(&rp); + enc = (OpusEncoder*)ptr; + if (s < st->layout.nb_coupled_streams) + { + int left, right; + left = get_left_channel(&st->layout, s, -1); + right = get_right_channel(&st->layout, s, -1); + (*copy_channel_in)(buf, 2, + pcm, st->layout.nb_channels, left, frame_size); + (*copy_channel_in)(buf+1, 2, + pcm, st->layout.nb_channels, right, frame_size); + ptr += align(coupled_size); + /* FIXME: This isn't correct for the coupled center channels in + 6.1 surround configuration */ + if (st->surround) + opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE)); + } else { + int chan = get_mono_channel(&st->layout, s, -1); + (*copy_channel_in)(buf, 1, + pcm, st->layout.nb_channels, chan, frame_size); + ptr += align(mono_size); + if (st->surround) + opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE_mono)); + } + /* number of bytes left (+Toc) */ + curr_max = max_data_bytes - tot_size; + /* Reserve three bytes for the last stream and four for the others */ + curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1); + curr_max = IMIN(curr_max,MS_FRAME_TMP); + len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth +#ifndef FIXED_POINT + , &analysis_info +#endif + ); + if (len<0) + { + RESTORE_STACK; + return len; + } + /* We need to use the repacketizer to add the self-delimiting lengths + while taking into account the fact that the encoder can now return + more than one frame at a time (e.g. 60 ms CELT-only) */ + opus_repacketizer_cat(&rp, tmp_data, len); + len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp), data, max_data_bytes-tot_size, s != st->layout.nb_streams-1); + data += len; + tot_size += len; + } + RESTORE_STACK; + return tot_size; + +} + +static void channel_pos(int channels, int pos[8]) +{ + /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */ + if (channels==4) + { + pos[0]=1; + pos[1]=3; + pos[2]=1; + pos[3]=3; + } else if (channels==3||channels==5||channels==6) + { + pos[0]=1; + pos[1]=2; + pos[2]=3; + pos[3]=1; + pos[4]=3; + pos[5]=0; + } else if (channels==7) + { + pos[0]=1; + pos[1]=2; + pos[2]=3; + pos[3]=1; + pos[4]=3; + pos[5]=2; + pos[6]=0; + } else if (channels==8) + { + pos[0]=1; + pos[1]=2; + pos[2]=3; + pos[3]=1; + pos[4]=3; + pos[5]=1; + pos[6]=3; + pos[7]=0; + } +} + +#if !defined(DISABLE_FLOAT_API) +static void opus_copy_channel_in_float( + opus_val16 *dst, + int dst_stride, + const void *src, + int src_stride, + int src_channel, + int frame_size +) +{ + const float *float_src; + opus_int32 i; + float_src = (const float *)src; + for (i=0;ilayout.nb_streams + st->layout.nb_coupled_streams; + return opus_multistream_encode_native(st, opus_copy_channel_in_float, + pcm, frame_size, data, max_data_bytes, 24, opus_surround_downmix_float, downmix_float, pcm+channels*st->analysis.analysis_offset); +} + +int opus_multistream_encode( + OpusMSEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) +{ + int channels = st->layout.nb_streams + st->layout.nb_coupled_streams; + return opus_multistream_encode_native(st, opus_copy_channel_in_short, + pcm, frame_size, data, max_data_bytes, 16, opus_surround_downmix_short, downmix_int, pcm+channels*st->analysis.analysis_offset); +} +#endif + +int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) +{ + va_list ap; + int coupled_size, mono_size; + char *ptr; + int ret = OPUS_OK; + + va_start(ap, request); + + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + ptr = (char*)st + align(sizeof(OpusMSEncoder)); + switch (request) + { + case OPUS_SET_BITRATE_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX) + { + goto bad_arg; + } + st->bitrate_bps = value; + } + break; + case OPUS_GET_BITRATE_REQUEST: + { + int s; + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = 0; + for (s=0;slayout.nb_streams;s++) + { + opus_int32 rate; + OpusEncoder *enc; + enc = (OpusEncoder*)ptr; + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + opus_encoder_ctl(enc, request, &rate); + *value += rate; + } + } + break; + case OPUS_GET_LSB_DEPTH_REQUEST: + case OPUS_GET_VBR_REQUEST: + case OPUS_GET_APPLICATION_REQUEST: + case OPUS_GET_BANDWIDTH_REQUEST: + case OPUS_GET_COMPLEXITY_REQUEST: + case OPUS_GET_PACKET_LOSS_PERC_REQUEST: + case OPUS_GET_DTX_REQUEST: + case OPUS_GET_VOICE_RATIO_REQUEST: + case OPUS_GET_VBR_CONSTRAINT_REQUEST: + case OPUS_GET_SIGNAL_REQUEST: + case OPUS_GET_LOOKAHEAD_REQUEST: + case OPUS_GET_SAMPLE_RATE_REQUEST: + case OPUS_GET_INBAND_FEC_REQUEST: + case OPUS_GET_FORCE_CHANNELS_REQUEST: + { + OpusEncoder *enc; + /* For int32* GET params, just query the first stream */ + opus_int32 *value = va_arg(ap, opus_int32*); + enc = (OpusEncoder*)ptr; + ret = opus_encoder_ctl(enc, request, value); + } + break; + case OPUS_GET_FINAL_RANGE_REQUEST: + { + int s; + opus_uint32 *value = va_arg(ap, opus_uint32*); + opus_uint32 tmp; + if (!value) + { + goto bad_arg; + } + *value=0; + for (s=0;slayout.nb_streams;s++) + { + OpusEncoder *enc; + enc = (OpusEncoder*)ptr; + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + ret = opus_encoder_ctl(enc, request, &tmp); + if (ret != OPUS_OK) break; + *value ^= tmp; + } + } + break; + case OPUS_SET_LSB_DEPTH_REQUEST: + case OPUS_SET_COMPLEXITY_REQUEST: + case OPUS_SET_VBR_REQUEST: + case OPUS_SET_VBR_CONSTRAINT_REQUEST: + case OPUS_SET_MAX_BANDWIDTH_REQUEST: + case OPUS_SET_BANDWIDTH_REQUEST: + case OPUS_SET_SIGNAL_REQUEST: + case OPUS_SET_APPLICATION_REQUEST: + case OPUS_SET_INBAND_FEC_REQUEST: + case OPUS_SET_PACKET_LOSS_PERC_REQUEST: + case OPUS_SET_DTX_REQUEST: + case OPUS_SET_FORCE_MODE_REQUEST: + case OPUS_SET_FORCE_CHANNELS_REQUEST: + { + int s; + /* This works for int32 params */ + opus_int32 value = va_arg(ap, opus_int32); + for (s=0;slayout.nb_streams;s++) + { + OpusEncoder *enc; + + enc = (OpusEncoder*)ptr; + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + ret = opus_encoder_ctl(enc, request, value); + if (ret != OPUS_OK) + break; + } + } + break; + case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST: + { + int s; + opus_int32 stream_id; + OpusEncoder **value; + stream_id = va_arg(ap, opus_int32); + if (stream_id<0 || stream_id >= st->layout.nb_streams) + ret = OPUS_BAD_ARG; + value = va_arg(ap, OpusEncoder**); + if (!value) + { + goto bad_arg; + } + for (s=0;slayout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + } + *value = (OpusEncoder*)ptr; + } + break; + case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->variable_duration = value; + } + break; + case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->variable_duration; + } + break; + default: + ret = OPUS_UNIMPLEMENTED; + break; + } + + va_end(ap); + return ret; +bad_arg: + va_end(ap); + return OPUS_BAD_ARG; +} + +void opus_multistream_encoder_destroy(OpusMSEncoder *st) +{ + opus_free(st); +} diff --git a/media/libopus/src/opus_private.h b/media/libopus/src/opus_private.h index e8ba0628abb6..9d8210b5f054 100644 --- a/media/libopus/src/opus_private.h +++ b/media/libopus/src/opus_private.h @@ -1,10 +1,6 @@ -/* Copyright (c) 2011-2012 IETF Trust, Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2012 Xiph.Org Foundation Written by Jean-Marc Valin */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -40,15 +31,29 @@ #include "arch.h" #include "opus.h" +#include "celt.h" struct OpusRepacketizer { unsigned char toc; int nb_frames; const unsigned char *frames[48]; - short len[48]; + opus_int16 len[48]; int framesize; }; +typedef struct ChannelLayout { + int nb_channels; + int nb_streams; + int nb_coupled_streams; + unsigned char mapping[256]; +} ChannelLayout; + +int validate_layout(const ChannelLayout *layout); +int get_left_channel(const ChannelLayout *layout, int stream_id, int prev); +int get_right_channel(const ChannelLayout *layout, int stream_id, int prev); +int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev); + + #define MODE_SILK_ONLY 1000 #define MODE_HYBRID 1001 @@ -77,18 +82,35 @@ struct OpusRepacketizer { #define OPUS_SET_FORCE_MODE_REQUEST 11002 #define OPUS_SET_FORCE_MODE(x) OPUS_SET_FORCE_MODE_REQUEST, __opus_check_int(x) +typedef void (*downmix_func)(const void *, float *, int, int, int); +void downmix_float(const void *_x, float *sub, int subframe, int offset, int C); +void downmix_int(const void *_x, float *sub, int subframe, int offset, int C); + +int optimize_framesize(const opus_val16 *x, int len, int C, opus_int32 Fs, + int bitrate, opus_val16 tonality, opus_val32 *mem, int buffering, + downmix_func downmix); int encode_size(int size, unsigned char *data); -int opus_decode_native(OpusDecoder *st, const unsigned char *data, int len, - opus_val16 *pcm, int frame_size, int decode_fec, int self_delimited, int *packet_offset); +opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs); + +opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size, + unsigned char *data, opus_int32 out_data_bytes, int lsb_depth +#ifndef FIXED_POINT + , AnalysisInfo *analysis_info +#endif + ); + +int opus_decode_native(OpusDecoder *st, const unsigned char *data, opus_int32 len, + opus_val16 *pcm, int frame_size, int decode_fec, int self_delimited, + int *packet_offset, int soft_clip); /* Make sure everything's aligned to sizeof(void *) bytes */ static inline int align(int i) { - return (i+sizeof(void *)-1)&-sizeof(void *); + return (i+(int)sizeof(void *)-1)&-(int)sizeof(void *); } -int opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, unsigned char *data, int maxlen, int self_delimited); +opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen, int self_delimited); #endif /* OPUS_PRIVATE_H */ diff --git a/media/libopus/src/repacketizer.c b/media/libopus/src/repacketizer.c index 9b7c986a2404..0c5d840c058e 100644 --- a/media/libopus/src/repacketizer.c +++ b/media/libopus/src/repacketizer.c @@ -1,10 +1,6 @@ -/* Copyright (c) 2011-2012 IETF Trust, Xiph.Org Foundation. All rights reserved. +/* Copyright (c) 2011 Xiph.Org Foundation Written by Jean-Marc Valin */ /* - - This file is extracted from RFC6716. Please see that RFC for additional - information. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -16,11 +12,6 @@ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of Internet Society, IETF or IETF Trust, nor the - names of specific contributors, may be used to endorse or promote - products derived from this software without specific prior written - permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -67,7 +58,7 @@ void opus_repacketizer_destroy(OpusRepacketizer *rp) opus_free(rp); } -int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, int len) +int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) { unsigned char tmp_toc; int curr_nb_frames,ret; @@ -107,7 +98,7 @@ opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int { int i, count; opus_int32 tot_size; - short *len; + opus_int16 *len; const unsigned char **frames; if (begin<0 || begin>=end || end>rp->nb_frames) diff --git a/media/libopus/src/tansig_table.h b/media/libopus/src/tansig_table.h new file mode 100644 index 000000000000..885ea3e8d7db --- /dev/null +++ b/media/libopus/src/tansig_table.h @@ -0,0 +1,45 @@ +/* This file is auto-generated by gen_tables */ + +static const opus_val16 tansig_table[201] = { +0.000000f, 0.039979f, 0.079830f, 0.119427f, 0.158649f, +0.197375f, 0.235496f, 0.272905f, 0.309507f, 0.345214f, +0.379949f, 0.413644f, 0.446244f, 0.477700f, 0.507977f, +0.537050f, 0.564900f, 0.591519f, 0.616909f, 0.641077f, +0.664037f, 0.685809f, 0.706419f, 0.725897f, 0.744277f, +0.761594f, 0.777888f, 0.793199f, 0.807569f, 0.821040f, +0.833655f, 0.845456f, 0.856485f, 0.866784f, 0.876393f, +0.885352f, 0.893698f, 0.901468f, 0.908698f, 0.915420f, +0.921669f, 0.927473f, 0.932862f, 0.937863f, 0.942503f, +0.946806f, 0.950795f, 0.954492f, 0.957917f, 0.961090f, +0.964028f, 0.966747f, 0.969265f, 0.971594f, 0.973749f, +0.975743f, 0.977587f, 0.979293f, 0.980869f, 0.982327f, +0.983675f, 0.984921f, 0.986072f, 0.987136f, 0.988119f, +0.989027f, 0.989867f, 0.990642f, 0.991359f, 0.992020f, +0.992631f, 0.993196f, 0.993718f, 0.994199f, 0.994644f, +0.995055f, 0.995434f, 0.995784f, 0.996108f, 0.996407f, +0.996682f, 0.996937f, 0.997172f, 0.997389f, 0.997590f, +0.997775f, 0.997946f, 0.998104f, 0.998249f, 0.998384f, +0.998508f, 0.998623f, 0.998728f, 0.998826f, 0.998916f, +0.999000f, 0.999076f, 0.999147f, 0.999213f, 0.999273f, +0.999329f, 0.999381f, 0.999428f, 0.999472f, 0.999513f, +0.999550f, 0.999585f, 0.999617f, 0.999646f, 0.999673f, +0.999699f, 0.999722f, 0.999743f, 0.999763f, 0.999781f, +0.999798f, 0.999813f, 0.999828f, 0.999841f, 0.999853f, +0.999865f, 0.999875f, 0.999885f, 0.999893f, 0.999902f, +0.999909f, 0.999916f, 0.999923f, 0.999929f, 0.999934f, +0.999939f, 0.999944f, 0.999948f, 0.999952f, 0.999956f, +0.999959f, 0.999962f, 0.999965f, 0.999968f, 0.999970f, +0.999973f, 0.999975f, 0.999977f, 0.999978f, 0.999980f, +0.999982f, 0.999983f, 0.999984f, 0.999986f, 0.999987f, +0.999988f, 0.999989f, 0.999990f, 0.999990f, 0.999991f, +0.999992f, 0.999992f, 0.999993f, 0.999994f, 0.999994f, +0.999994f, 0.999995f, 0.999995f, 0.999996f, 0.999996f, +0.999996f, 0.999997f, 0.999997f, 0.999997f, 0.999997f, +0.999997f, 0.999998f, 0.999998f, 0.999998f, 0.999998f, +0.999998f, 0.999998f, 0.999999f, 0.999999f, 0.999999f, +0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, +0.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f, +1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, +1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, +1.000000f, +}; diff --git a/media/libopus/update.sh b/media/libopus/update.sh index 068f8885c25d..e94aa9b11e25 100644 --- a/media/libopus/update.sh +++ b/media/libopus/update.sh @@ -13,7 +13,7 @@ TARGET='.' STATIC_FILES="COPYING" MK_FILES="opus_sources.mk celt_sources.mk silk_sources.mk \ - opus_headers.txt celt_headers.txt silk_headers.txt" + opus_headers.mk celt_headers.mk silk_headers.mk" # Make sure we have a source directory if test -z $1 || ! test -r $1/include/opus.h; then @@ -33,7 +33,6 @@ HDR_FILES="include/opus_custom.h" # make sure the necessary subdirectories exist for file in ${SRC_FILES}; do - echo "testing ${file}" base=${file##*/} dir="${file%"${base}"}" if test ! -d "${TARGET}/${dir}"; then @@ -61,8 +60,10 @@ echo "copied from revision ${version}" sed -e "s/^The git tag\/revision used was .*/The git tag\/revision used was ${version}./" \ ${TARGET}/README_MOZILLA > ${TARGET}/README_MOZILLA+ && \ mv ${TARGET}/README_MOZILLA+ ${TARGET}/README_MOZILLA +# update compiled-in version string +sed -e "s/-DOPUS_VERSION='\".*\"'/-DOPUS_VERSION='\"${version}-mozilla\"'/" \ + ${TARGET}/Makefile.in > ${TARGET}/Makefile.in+ && \ + mv ${TARGET}/Makefile.in+ ${TARGET}/Makefile.in # apply outstanding local patches -patch -p3 < bug776661.patch -patch -p1 < padding.patch -patch -p3 < mingw.patch +# ... no patches to apply ... From fe1956bda6a09f3447797c5a786eb322972ccf21 Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Mon, 23 Sep 2013 18:04:35 -0700 Subject: [PATCH 009/160] Bug 918167 - Clean up TraceLIR. (r=nmatsakis) --- js/src/jit/ParallelFunctions.cpp | 26 +++---- js/src/jit/ParallelFunctions.h | 4 +- js/src/jit/shared/CodeGenerator-shared.cpp | 81 ++++++++++++---------- js/src/vm/ForkJoin.cpp | 17 ++--- js/src/vm/ForkJoin.h | 13 ++-- 5 files changed, 63 insertions(+), 78 deletions(-) diff --git a/js/src/jit/ParallelFunctions.cpp b/js/src/jit/ParallelFunctions.cpp index 724c73f9fed5..eec0aecb84d7 100644 --- a/js/src/jit/ParallelFunctions.cpp +++ b/js/src/jit/ParallelFunctions.cpp @@ -54,16 +54,14 @@ printTrace(const char *prefix, struct IonLIRTraceData *cached) { fprintf(stderr, "%s / Block %3u / LIR %3u / Mode %u / LIR %s\n", prefix, - cached->bblock, cached->lir, cached->execModeInt, cached->lirOpName); + cached->blockIndex, cached->lirIndex, cached->execModeInt, cached->lirOpName); } struct IonLIRTraceData seqTraceData; #endif void -jit::TraceLIR(uint32_t bblock, uint32_t lir, uint32_t execModeInt, - const char *lirOpName, const char *mirOpName, - JSScript *script, jsbytecode *pc) +jit::TraceLIR(IonLIRTraceData *current) { #ifdef DEBUG static enum { NotSet, All, Bailouts } traceMode; @@ -73,7 +71,7 @@ jit::TraceLIR(uint32_t bblock, uint32_t lir, uint32_t execModeInt, // You can either modify it to do whatever you like, or use gdb scripting. // For example: // - // break TracePar + // break TraceLIR // commands // continue // exit @@ -88,27 +86,19 @@ jit::TraceLIR(uint32_t bblock, uint32_t lir, uint32_t execModeInt, } IonLIRTraceData *cached; - if (execModeInt == 0) + if (current->execModeInt == 0) cached = &seqTraceData; else cached = &ForkJoinSlice::Current()->traceData; - if (bblock == 0xDEADBEEF) { - if (execModeInt == 0) + if (current->blockIndex == 0xDEADBEEF) { + if (current->execModeInt == 0) printTrace("BAILOUT", cached); else - SpewBailoutIR(cached->bblock, cached->lir, - cached->lirOpName, cached->mirOpName, - cached->script, cached->pc); + SpewBailoutIR(cached); } - cached->bblock = bblock; - cached->lir = lir; - cached->execModeInt = execModeInt; - cached->lirOpName = lirOpName; - cached->mirOpName = mirOpName; - cached->script = script; - cached->pc = pc; + memcpy(cached, current, sizeof(IonLIRTraceData)); if (traceMode == All) printTrace("Exec", cached); diff --git a/js/src/jit/ParallelFunctions.h b/js/src/jit/ParallelFunctions.h index 56e7e51d39a7..ca91ab465313 100644 --- a/js/src/jit/ParallelFunctions.h +++ b/js/src/jit/ParallelFunctions.h @@ -79,9 +79,7 @@ void AbortPar(ParallelBailoutCause cause, JSScript *outermostScript, JSScript *c jsbytecode *bytecode); void PropagateAbortPar(JSScript *outermostScript, JSScript *currentScript); -void TraceLIR(uint32_t bblock, uint32_t lir, uint32_t execModeInt, - const char *lirOpName, const char *mirOpName, - JSScript *script, jsbytecode *pc); +void TraceLIR(IonLIRTraceData *current); void CallToUncompiledScriptPar(JSObject *obj); diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp index 7ec05ba498aa..3f2710811be3 100644 --- a/js/src/jit/shared/CodeGenerator-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-shared.cpp @@ -807,61 +807,66 @@ CodeGeneratorShared::callTraceLIR(uint32_t blockIndex, LInstruction *lir, { JS_ASSERT_IF(!lir, bailoutName); - uint32_t emi = (uint32_t) gen->info().executionMode(); - if (!IonSpewEnabled(IonSpew_Trace)) return true; - masm.PushRegsInMask(RegisterSet::All()); - RegisterSet regSet(RegisterSet::All()); + uint32_t execMode = (uint32_t) gen->info().executionMode(); + uint32_t lirIndex; + const char *lirOpName; + const char *mirOpName; + JSScript *script; + jsbytecode *pc; - Register blockIndexReg = regSet.takeGeneral(); - Register lirIndexReg = regSet.takeGeneral(); - Register emiReg = regSet.takeGeneral(); - Register lirOpNameReg = regSet.takeGeneral(); - Register mirOpNameReg = regSet.takeGeneral(); - Register scriptReg = regSet.takeGeneral(); - Register pcReg = regSet.takeGeneral(); + masm.PushRegsInMask(RegisterSet::Volatile()); + masm.reserveStack(sizeof(IonLIRTraceData)); // This first move is here so that when you scan the disassembly, // you can easily pick out where each instruction begins. The // next few items indicate to you the Basic Block / LIR. - masm.move32(Imm32(0xDEADBEEF), blockIndexReg); + masm.move32(Imm32(0xDEADBEEF), CallTempReg0); if (lir) { - masm.move32(Imm32(blockIndex), blockIndexReg); - masm.move32(Imm32(lir->id()), lirIndexReg); - masm.move32(Imm32(emi), emiReg); - masm.movePtr(ImmPtr(lir->opName()), lirOpNameReg); + lirIndex = lir->id(); + lirOpName = lir->opName(); if (MDefinition *mir = lir->mirRaw()) { - masm.movePtr(ImmPtr(mir->opName()), mirOpNameReg); - masm.movePtr(ImmPtr(mir->block()->info().script()), scriptReg); - masm.movePtr(ImmPtr(mir->trackedPc()), pcReg); + mirOpName = mir->opName(); + script = mir->block()->info().script(); + pc = mir->trackedPc(); } else { - masm.movePtr(ImmPtr(NULL), mirOpNameReg); - masm.movePtr(ImmPtr(NULL), scriptReg); - masm.movePtr(ImmPtr(NULL), pcReg); + mirOpName = NULL; + script = NULL; + pc = NULL; } } else { - masm.move32(Imm32(0xDEADBEEF), blockIndexReg); - masm.move32(Imm32(0xDEADBEEF), lirIndexReg); - masm.move32(Imm32(emi), emiReg); - masm.movePtr(ImmPtr(bailoutName), lirOpNameReg); - masm.movePtr(ImmPtr(bailoutName), mirOpNameReg); - masm.movePtr(ImmPtr(NULL), scriptReg); - masm.movePtr(ImmPtr(NULL), pcReg); + blockIndex = lirIndex = 0xDEADBEEF; + lirOpName = mirOpName = bailoutName; + script = NULL; + pc = NULL; } - masm.setupUnalignedABICall(7, CallTempReg4); - masm.passABIArg(blockIndexReg); - masm.passABIArg(lirIndexReg); - masm.passABIArg(emiReg); - masm.passABIArg(lirOpNameReg); - masm.passABIArg(mirOpNameReg); - masm.passABIArg(scriptReg); - masm.passABIArg(pcReg); + masm.store32(Imm32(blockIndex), + Address(StackPointer, offsetof(IonLIRTraceData, blockIndex))); + masm.store32(Imm32(lirIndex), + Address(StackPointer, offsetof(IonLIRTraceData, lirIndex))); + masm.store32(Imm32(execMode), + Address(StackPointer, offsetof(IonLIRTraceData, execModeInt))); + masm.storePtr(ImmPtr(lirOpName), + Address(StackPointer, offsetof(IonLIRTraceData, lirOpName))); + masm.storePtr(ImmPtr(mirOpName), + Address(StackPointer, offsetof(IonLIRTraceData, mirOpName))); + masm.storePtr(ImmGCPtr(script), + Address(StackPointer, offsetof(IonLIRTraceData, script))); + masm.storePtr(ImmPtr(pc), + Address(StackPointer, offsetof(IonLIRTraceData, pc))); + + masm.movePtr(StackPointer, CallTempReg0); + masm.setupUnalignedABICall(1, CallTempReg1); + masm.passABIArg(CallTempReg0); masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLIR)); - masm.PopRegsInMask(RegisterSet::All()); + + masm.freeStack(sizeof(IonLIRTraceData)); + masm.PopRegsInMask(RegisterSet::Volatile()); + return true; } diff --git a/js/src/vm/ForkJoin.cpp b/js/src/vm/ForkJoin.cpp index 1192783dacae..6559811f8637 100644 --- a/js/src/vm/ForkJoin.cpp +++ b/js/src/vm/ForkJoin.cpp @@ -2059,19 +2059,18 @@ class ParallelSpewer script->filename(), PCToLineNumber(script, mir->trackedPc())); } - void spewBailoutIR(uint32_t bblockId, uint32_t lirId, - const char *lir, const char *mir, JSScript *script, jsbytecode *pc) { + void spewBailoutIR(IonLIRTraceData *data) { if (!active[SpewBailouts]) return; // If we didn't bail from a LIR/MIR but from a propagated parallel // bailout, don't bother printing anything since we've printed it // elsewhere. - if (mir && script) { + if (data->mirOpName && data->script) { spew(SpewBailouts, "%sBailout%s: %s / %s%s%s (block %d lir %d) (%s:%u)", yellow(), reset(), - lir, cyan(), mir, reset(), - bblockId, lirId, - script->filename(), PCToLineNumber(script, pc)); + data->lirOpName, cyan(), data->mirOpName, reset(), + data->blockIndex, data->lirIndex, data->script->filename(), + PCToLineNumber(data->script, data->pc)); } } }; @@ -2137,11 +2136,9 @@ parallel::SpewMIR(MDefinition *mir, const char *fmt, ...) } void -parallel::SpewBailoutIR(uint32_t bblockId, uint32_t lirId, - const char *lir, const char *mir, - JSScript *script, jsbytecode *pc) +parallel::SpewBailoutIR(IonLIRTraceData *data) { - spewer.spewBailoutIR(bblockId, lirId, lir, mir, script, pc); + spewer.spewBailoutIR(data); } #endif // DEBUG diff --git a/js/src/vm/ForkJoin.h b/js/src/vm/ForkJoin.h index c0cd443822a6..d0c5f8348d46 100644 --- a/js/src/vm/ForkJoin.h +++ b/js/src/vm/ForkJoin.h @@ -207,17 +207,15 @@ bool ForkJoin(JSContext *cx, CallArgs &args); // executed. uint32_t ForkJoinSlices(JSContext *cx); -#ifdef DEBUG struct IonLIRTraceData { - uint32_t bblock; - uint32_t lir; + uint32_t blockIndex; + uint32_t lirIndex; uint32_t execModeInt; const char *lirOpName; const char *mirOpName; JSScript *script; jsbytecode *pc; }; -#endif /////////////////////////////////////////////////////////////////////////// // Bailout tracking @@ -449,8 +447,7 @@ ExecutionStatus SpewEndOp(ExecutionStatus status); void SpewBeginCompile(HandleScript script); jit::MethodStatus SpewEndCompile(jit::MethodStatus status); void SpewMIR(jit::MDefinition *mir, const char *fmt, ...); -void SpewBailoutIR(uint32_t bblockId, uint32_t lirId, - const char *lir, const char *mir, JSScript *script, jsbytecode *pc); +void SpewBailoutIR(IonLIRTraceData *data); #else @@ -465,9 +462,7 @@ static inline void SpewBeginCompile(HandleScript script) { } static inline jit::MethodStatus SpewEndCompile(jit::MethodStatus status) { return status; } static inline void SpewMIR(jit::MDefinition *mir, const char *fmt, ...) { } #endif -static inline void SpewBailoutIR(uint32_t bblockId, uint32_t lirId, - const char *lir, const char *mir, - JSScript *script, jsbytecode *pc) { } +static inline void SpewBailoutIR(IonLIRTraceData *data) { } #endif // DEBUG && JS_THREADSAFE && JS_ION From 645b1782128125f8141014f30ae2394ce3d7d328 Mon Sep 17 00:00:00 2001 From: Nicholas Cameron Date: Tue, 24 Sep 2013 13:14:11 +1200 Subject: [PATCH 010/160] Bug 912766. Refactor DataToTexture. r=mattwoodrow --- gfx/layers/d3d9/TextureD3D9.cpp | 127 +++++++++++++++++++++----------- 1 file changed, 82 insertions(+), 45 deletions(-) diff --git a/gfx/layers/d3d9/TextureD3D9.cpp b/gfx/layers/d3d9/TextureD3D9.cpp index 92402cac7217..aabf476e7f65 100644 --- a/gfx/layers/d3d9/TextureD3D9.cpp +++ b/gfx/layers/d3d9/TextureD3D9.cpp @@ -132,6 +132,83 @@ DeprecatedTextureHostD3D9::SetCompositor(Compositor* aCompositor) mDevice = mCompositor ? mCompositor->device() : nullptr; } +/** + * Helper method for DataToTexture and SurfaceToTexture. + * The last four params are out params. + * Returns success. + */ +static bool +InitTextures(IDirect3DDevice9* aDevice, + const gfxIntSize &aSize, + _D3DFORMAT aFormat, + RefPtr& aTexture, + RefPtr& aSurface, + D3DLOCKED_RECT& aLockedRect, + bool& aUsingD3D9Ex) +{ + nsRefPtr deviceEx; + aDevice->QueryInterface(IID_IDirect3DDevice9Ex, + (void**)getter_AddRefs(deviceEx)); + aUsingD3D9Ex = !!deviceEx; + + if (aUsingD3D9Ex) { + // D3D9Ex doesn't support managed textures. We could use dynamic textures + // here but since Images are immutable that probably isn't such a great + // idea. + if (FAILED(aDevice-> + CreateTexture(aSize.width, aSize.height, + 1, 0, aFormat, D3DPOOL_DEFAULT, + byRef(aTexture), nullptr))) + { + return false; + } + + RefPtr tmpTexture; + if (FAILED(aDevice-> + CreateTexture(aSize.width, aSize.height, + 1, 0, aFormat, D3DPOOL_SYSTEMMEM, + byRef(tmpTexture), nullptr))) + { + return false; + } + + tmpTexture->GetSurfaceLevel(0, byRef(aSurface)); + aSurface->LockRect(&aLockedRect, NULL, 0); + NS_ASSERTION(aLockedRect.pBits, "Could not lock surface"); + } else { + if (FAILED(aDevice-> + CreateTexture(aSize.width, aSize.height, + 1, 0, aFormat, D3DPOOL_MANAGED, + byRef(aTexture), nullptr))) { + return false; + } + + /* lock the entire texture */ + aTexture->LockRect(0, &aLockedRect, nullptr, 0); + } + + return true; +} + +/** + * Helper method for DataToTexture and SurfaceToTexture. + */ +static void +FinishTextures(IDirect3DDevice9* aDevice, + RefPtr& aTexture, + RefPtr aSurface, + bool aUsingD3D9Ex) +{ + if (aUsingD3D9Ex) { + aSurface->UnlockRect(); + nsRefPtr dstSurface; + aTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface)); + aDevice->UpdateSurface(aSurface, NULL, dstSurface, NULL); + } else { + aTexture->UnlockRect(0); + } +} + static TemporaryRef DataToTexture(IDirect3DDevice9 *aDevice, unsigned char *aData, @@ -141,46 +218,13 @@ DataToTexture(IDirect3DDevice9 *aDevice, uint32_t aBPP) { RefPtr texture; - nsRefPtr deviceEx; - aDevice->QueryInterface(IID_IDirect3DDevice9Ex, - (void**)getter_AddRefs(deviceEx)); - RefPtr surface; D3DLOCKED_RECT lockedRect; - if (deviceEx) { - // D3D9Ex doesn't support managed textures. We could use dynamic textures - // here but since Images are immutable that probably isn't such a great - // idea. - if (FAILED(aDevice-> - CreateTexture(aSize.width, aSize.height, - 1, 0, aFormat, D3DPOOL_DEFAULT, - byRef(texture), nullptr))) - { - return nullptr; - } + bool usingD3D9Ex; - RefPtr tmpTexture; - if (FAILED(aDevice-> - CreateTexture(aSize.width, aSize.height, - 1, 0, aFormat, D3DPOOL_SYSTEMMEM, - byRef(tmpTexture), nullptr))) - { - return nullptr; - } - - tmpTexture->GetSurfaceLevel(0, byRef(surface)); - surface->LockRect(&lockedRect, NULL, 0); - NS_ASSERTION(lockedRect.pBits, "Could not lock surface"); - } else { - if (FAILED(aDevice-> - CreateTexture(aSize.width, aSize.height, - 1, 0, aFormat, D3DPOOL_MANAGED, - byRef(texture), nullptr))) { - return nullptr; - } - - /* lock the entire texture */ - texture->LockRect(0, &lockedRect, nullptr, 0); + if (!InitTextures(aDevice, aSize, aFormat, + texture, surface, lockedRect, usingD3D9Ex)) { + return nullptr; } uint32_t width = aSize.width * aBPP; @@ -191,14 +235,7 @@ DataToTexture(IDirect3DDevice9 *aDevice, width); } - if (deviceEx) { - surface->UnlockRect(); - nsRefPtr dstSurface; - texture->GetSurfaceLevel(0, getter_AddRefs(dstSurface)); - aDevice->UpdateSurface(surface, NULL, dstSurface, NULL); - } else { - texture->UnlockRect(0); - } + FinishTextures(aDevice, texture, surface, usingD3D9Ex); return texture.forget(); } From d6482934be2e8b1361e20c2a86afea72f98dffaf Mon Sep 17 00:00:00 2001 From: Nicholas Cameron Date: Tue, 24 Sep 2013 13:14:11 +1200 Subject: [PATCH 011/160] Bug 912766. DIB texture client/host. r=mattwoodrow,jrmuizel --- gfx/layers/d3d9/TextureD3D9.cpp | 284 ++++++++++++++++++++------- gfx/layers/d3d9/TextureD3D9.h | 59 +++++- gfx/layers/ipc/ISurfaceAllocator.cpp | 1 + gfx/layers/ipc/LayersSurfaces.ipdlh | 6 + 4 files changed, 279 insertions(+), 71 deletions(-) diff --git a/gfx/layers/d3d9/TextureD3D9.cpp b/gfx/layers/d3d9/TextureD3D9.cpp index aabf476e7f65..c75014016f6c 100644 --- a/gfx/layers/d3d9/TextureD3D9.cpp +++ b/gfx/layers/d3d9/TextureD3D9.cpp @@ -460,6 +460,112 @@ DeprecatedTextureHostSystemMemD3D9::UpdateImpl(const SurfaceDescriptor& aImage, format, bpp); texture->UnlockRect(0); + if (!mTileTextures[i]) { + NS_WARNING("Could not upload texture"); + mSize.width = 0; + mSize.height = 0; + mIsTiled = false; + return; + } + } + } +} + +static TemporaryRef +SurfaceToTexture(IDirect3DDevice9* aDevice, + gfxWindowsSurface* aSurface, + const gfxIntSize& aSize, + _D3DFORMAT aFormat) +{ + RefPtr texture; + RefPtr surface; + D3DLOCKED_RECT lockedRect; + bool usingD3D9Ex; + + if (!InitTextures(aDevice, aSize, aFormat, + texture, surface, lockedRect, usingD3D9Ex)) { + return nullptr; + } + + nsRefPtr imgSurface = + new gfxImageSurface(reinterpret_cast(lockedRect.pBits), + gfxIntSize(aSize.width, aSize.height), + lockedRect.Pitch, + gfxPlatform::GetPlatform()->OptimalFormatForContent(aSurface->GetContentType())); + + nsRefPtr context = new gfxContext(imgSurface); + context->SetSource(aSurface); + context->SetOperator(gfxContext::OPERATOR_SOURCE); + context->Paint(); + + FinishTextures(aDevice, texture, surface, usingD3D9Ex); + + return texture.forget(); +} + +void +DeprecatedTextureHostDIB::UpdateImpl(const SurfaceDescriptor& aImage, + nsIntRegion *aRegion, + nsIntPoint *aOffset) +{ + MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TSurfaceDescriptorDIB); + MOZ_ASSERT(mCompositor, "Must have compositor to update."); + + nsRefPtr surf = + reinterpret_cast(aImage.get_SurfaceDescriptorDIB().surface()); + // We added an extra ref for transport, we can release it now. + surf->Release(); + + gfxIntSize size = surf->GetSize(); + mSize = IntSize(size.width, size.height); + + uint32_t bpp = 0; + + _D3DFORMAT format = D3DFMT_A8R8G8B8; + switch (gfxPlatform::GetPlatform()->OptimalFormatForContent(surf->GetContentType())) { + case gfxImageSurface::ImageFormatRGB24: + mFormat = FORMAT_B8G8R8X8; + format = D3DFMT_X8R8G8B8; + bpp = 4; + break; + case gfxImageSurface::ImageFormatARGB32: + mFormat = FORMAT_B8G8R8A8; + format = D3DFMT_A8R8G8B8; + bpp = 4; + break; + case gfxImageSurface::ImageFormatA8: + mFormat = FORMAT_A8; + format = D3DFMT_A8; + bpp = 1; + break; + default: + NS_ERROR("Bad image format"); + } + + int32_t maxSize = mCompositor->GetMaxTextureSize(); + if (size.width <= maxSize && size.height <= maxSize) { + mTextures[0] = SurfaceToTexture(mDevice, surf, size, format); + NS_ASSERTION(mTextures[0], "Could not upload texture"); + mIsTiled = false; + } else { + mIsTiled = true; + + uint32_t tileCount = GetRequiredTiles(mSize.width, maxSize) * + GetRequiredTiles(mSize.height, maxSize); + mTileTextures.resize(tileCount); + + for (uint32_t i = 0; i < tileCount; i++) { + IntRect tileRect = GetTileRect(i); + nsRefPtr imgSurface = surf->GetAsImageSurface(); + unsigned char* data = imgSurface->Data() + + tileRect.y * imgSurface->Stride() + + tileRect.x * bpp; + mTileTextures[i] = DataToTexture(mDevice, + data, + imgSurface->Stride(), + gfxIntSize(tileRect.width, tileRect.height), + format, + bpp); } } } @@ -467,8 +573,6 @@ DeprecatedTextureHostSystemMemD3D9::UpdateImpl(const SurfaceDescriptor& aImage, DeprecatedTextureClientD3D9::DeprecatedTextureClientD3D9(CompositableForwarder* aCompositableForwarder, const TextureInfo& aTextureInfo) : DeprecatedTextureClient(aCompositableForwarder, aTextureInfo) - , mDC(nullptr) - , mTextureLocked(false) { MOZ_COUNT_CTOR(DeprecatedTextureClientD3D9); } @@ -479,7 +583,7 @@ DeprecatedTextureClientD3D9::~DeprecatedTextureClientD3D9() Unlock(); mDescriptor = SurfaceDescriptor(); - ClearDT(); + mDrawTarget = nullptr; } bool @@ -506,15 +610,12 @@ DeprecatedTextureClientD3D9::EnsureAllocated(gfx::IntSize aSize, switch (aType) { case gfxASurface::CONTENT_COLOR: format = D3DFMT_X8R8G8B8; - mIsOpaque = true; break; case gfxASurface::CONTENT_COLOR_ALPHA: - format = D3DFMT_A8R8G8B8; - mIsOpaque = false; - break; + // fallback to DIB texture client + return false; case gfxASurface::CONTENT_ALPHA: format = D3DFMT_A8; - mIsOpaque = true; break; default: NS_ERROR("Bad image type"); @@ -534,15 +635,6 @@ DeprecatedTextureClientD3D9::EnsureAllocated(gfx::IntSize aSize, MOZ_ASSERT(mTexture); mDescriptor = SurfaceDescriptorD3D9(reinterpret_cast(mTexture.get())); - if (!mIsOpaque) { - nsRefPtr surface = LockSurface(); - nsRefPtr ctx = new gfxContext(surface); - ctx->SetOperator(gfxContext::OPERATOR_SOURCE); - ctx->SetColor(gfxRGBA(0.0, 0.0, 0.0, 0.0)); - ctx->Paint(); - Unlock(); - } - mContentType = aType; return true; } @@ -556,41 +648,21 @@ DeprecatedTextureClientD3D9::LockSurface() MOZ_ASSERT(mTexture, "Cannot lock surface without a texture to lock"); - if (mIsOpaque) { - MOZ_ASSERT(!mTextureLocked, "Shouldn't lock texture and have a surface"); - if (!mD3D9Surface) { - HRESULT hr = mTexture->GetSurfaceLevel(0, getter_AddRefs(mD3D9Surface)); - if (FAILED(hr)) { - NS_WARNING("Failed to get texture surface level."); - return nullptr; - } - } - - if (!mDC) { - HRESULT hr = mD3D9Surface->GetDC(&mDC); - if (FAILED(hr)) { - NS_WARNING("Failed to get device context for texture surface."); - return nullptr; - } - } - NS_ASSERTION(mDC, "We need a DC here"); - mSurface = new gfxWindowsSurface(mDC); - } else { - // d3d9 SYSTEMMEM surfaces do not support GDI with an alpha channel - MOZ_ASSERT(!mD3D9Surface && !mDC, "Shouldn't lock texture and have a surface"); - if (!mTextureLocked) { - D3DLOCKED_RECT lockedRect; - mTexture->LockRect(0, &lockedRect, nullptr, 0); - mTextureLocked = true; - - mSurface = new gfxImageSurface(reinterpret_cast(lockedRect.pBits), - gfxIntSize(mSize.width, mSize.height), - lockedRect.Pitch, - gfxASurface::ImageFormatARGB32); + if (!mD3D9Surface) { + HRESULT hr = mTexture->GetSurfaceLevel(0, getter_AddRefs(mD3D9Surface)); + if (FAILED(hr)) { + NS_WARNING("Failed to get texture surface level."); + return nullptr; } } - NS_ASSERTION(mSurface, "should have a surface one way or the other"); + mSurface = new gfxWindowsSurface(mD3D9Surface); + if (!mSurface || mSurface->CairoStatus()) { + NS_WARNING("Could not create surface for d3d9 surface"); + mSurface = nullptr; + return nullptr; + } + return mSurface.get(); } @@ -598,8 +670,10 @@ DrawTarget* DeprecatedTextureClientD3D9::LockDrawTarget() { if (!mDrawTarget) { - mDrawTarget = - gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(LockSurface(), mSize); + if (gfxASurface* surface = LockSurface()) { + mDrawTarget = + gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(LockSurface(), mSize); + } } return mDrawTarget.get(); @@ -613,17 +687,6 @@ DeprecatedTextureClientD3D9::Unlock() mDrawTarget = nullptr; } - if (mTextureLocked) { - MOZ_ASSERT(!mD3D9Surface && !mDC, "Shouldn't lock texture and have a surface"); - mTexture->UnlockRect(0); - mTextureLocked = false; - } else if (mDC) { - MOZ_ASSERT(mD3D9Surface, "we need a D3D9Surface to release our DC"); - MOZ_ASSERT(!mTextureLocked, "Shouldn't lock texture and have a surface"); - mD3D9Surface->ReleaseDC(mDC); - mDC = nullptr; - } - if (mSurface) { mSurface = nullptr; } @@ -639,7 +702,7 @@ DeprecatedTextureClientD3D9::SetDescriptor(const SurfaceDescriptor& aDescriptor) mDescriptor = aDescriptor; mSurface = nullptr; - ClearDT(); + mDrawTarget = nullptr; if (aDescriptor.type() == SurfaceDescriptor::T__None) { return; @@ -652,14 +715,103 @@ DeprecatedTextureClientD3D9::SetDescriptor(const SurfaceDescriptor& aDescriptor) mDescriptor.get_SurfaceDescriptorD3D9().texture()); } -void -DeprecatedTextureClientD3D9::ClearDT() +DeprecatedTextureClientDIB::DeprecatedTextureClientDIB(CompositableForwarder* aCompositableForwarder, + const TextureInfo& aTextureInfo) + : DeprecatedTextureClient(aCompositableForwarder, aTextureInfo) +{ + MOZ_COUNT_CTOR(DeprecatedTextureClientDIB); +} + +DeprecatedTextureClientDIB::~DeprecatedTextureClientDIB() +{ + MOZ_COUNT_DTOR(DeprecatedTextureClientDIB); + Unlock(); + mDescriptor = SurfaceDescriptor(); + mDrawTarget = nullptr; +} + +bool +DeprecatedTextureClientDIB::EnsureAllocated(gfx::IntSize aSize, + gfxASurface::gfxContentType aType) +{ + if (mSurface) { + gfxIntSize size = mSurface->GetSize(); + if (size.width == aSize.width && + size.height == aSize.height) { + return true; + } + + Unlock(); + mSurface = nullptr; + } + + mSurface = new gfxWindowsSurface(gfxIntSize(aSize.width, aSize.height), + gfxPlatform::GetPlatform()->OptimalFormatForContent(aType)); + if (!mSurface || mSurface->CairoStatus()) + { + NS_WARNING("Could not create surface"); + mSurface = nullptr; + return false; + } + mSize = aSize; + mContentType = aType; + + mDescriptor = SurfaceDescriptorDIB(reinterpret_cast(mSurface.get())); + // The host will release this ref when it receives the surface descriptor. + // We AddRef in case we die before the host receives the pointer. + mSurface->AddRef(); + + return true; +} + +gfxASurface* +DeprecatedTextureClientDIB::LockSurface() +{ + if (mSurface) { + return mSurface.get(); + } + + return nullptr; +} + +DrawTarget* +DeprecatedTextureClientDIB::LockDrawTarget() +{ + if (!mDrawTarget) { + if (gfxASurface* surface = LockSurface()) { + mDrawTarget = + gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(LockSurface(), mSize); + } + } + + return mDrawTarget.get(); +} + +void +DeprecatedTextureClientDIB::Unlock() { - // Perhaps this should be debug only. if (mDrawTarget) { + mDrawTarget->Flush(); mDrawTarget = nullptr; } } +void +DeprecatedTextureClientDIB::SetDescriptor(const SurfaceDescriptor& aDescriptor) +{ + mDescriptor = aDescriptor; + mDrawTarget = nullptr; + + if (aDescriptor.type() == SurfaceDescriptor::T__None) { + mSurface = nullptr; + return; + } + + MOZ_ASSERT(aDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorDIB); + Unlock(); + mSurface = reinterpret_cast( + mDescriptor.get_SurfaceDescriptorDIB().surface()); +} + } } diff --git a/gfx/layers/d3d9/TextureD3D9.h b/gfx/layers/d3d9/TextureD3D9.h index 718bad3fbb96..4f5048f41eb2 100644 --- a/gfx/layers/d3d9/TextureD3D9.h +++ b/gfx/layers/d3d9/TextureD3D9.h @@ -212,6 +212,21 @@ private: RefPtr mDevice; }; +class DeprecatedTextureHostDIB : public DeprecatedTextureHostD3D9 +{ +public: +#ifdef MOZ_LAYERS_HAVE_LOG + virtual const char* Name() { return "DeprecatedTextureHostDIB"; } +#endif + +protected: + virtual void UpdateImpl(const SurfaceDescriptor& aSurface, + nsIntRegion* aRegion, + nsIntPoint *aOffset = nullptr) MOZ_OVERRIDE; + + nsRefPtr mTexture; +}; + // If we want to use d3d9 textures for transport, use this class. // If we are using shmem, then use DeprecatedTextureClientShmem with DeprecatedTextureHostShmemD3D9 // Since we pass a raw pointer, you should not use this texture client for @@ -246,17 +261,51 @@ public: } private: - void ClearDT(); - nsRefPtr mTexture; nsRefPtr mSurface; nsRefPtr mD3D9Surface; - HDC mDC; RefPtr mDrawTarget; gfx::IntSize mSize; gfxContentType mContentType; - bool mTextureLocked; - bool mIsOpaque; +}; + +// Retains a DIB and uses it for transport. +// Used where we can't efficently use a gfxWindowsSurface wrapped around +// a DC from a IDirect3DSurface9, which is for surfaces with alpha. +class DeprecatedTextureClientDIB : public DeprecatedTextureClient +{ +public: + DeprecatedTextureClientDIB(CompositableForwarder* aCompositableForwarder, + const TextureInfo& aTextureInfo); + virtual ~DeprecatedTextureClientDIB(); + + virtual bool SupportsType(DeprecatedTextureClientType aType) MOZ_OVERRIDE + { + return aType == TEXTURE_CONTENT; + } + + virtual bool EnsureAllocated(gfx::IntSize aSize, + gfxASurface::gfxContentType aType) MOZ_OVERRIDE; + + virtual gfxASurface* LockSurface() MOZ_OVERRIDE; + virtual gfx::DrawTarget* LockDrawTarget() MOZ_OVERRIDE; + virtual gfx::BackendType BackendType() MOZ_OVERRIDE + { + return gfx::BACKEND_CAIRO; + } + virtual void Unlock() MOZ_OVERRIDE; + + virtual void SetDescriptor(const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE; + virtual gfxASurface::gfxContentType GetContentType() MOZ_OVERRIDE + { + return mContentType; + } + +private: + nsRefPtr mSurface; + RefPtr mDrawTarget; + gfx::IntSize mSize; + gfxContentType mContentType; }; } diff --git a/gfx/layers/ipc/ISurfaceAllocator.cpp b/gfx/layers/ipc/ISurfaceAllocator.cpp index 00c572f22cfd..c826f2ff77db 100644 --- a/gfx/layers/ipc/ISurfaceAllocator.cpp +++ b/gfx/layers/ipc/ISurfaceAllocator.cpp @@ -134,6 +134,7 @@ ISurfaceAllocator::DestroySharedSurface(SurfaceDescriptor* aSurface) DeallocShmem(aSurface->get_RGBImage().data()); break; case SurfaceDescriptor::TSurfaceDescriptorD3D9: + case SurfaceDescriptor::TSurfaceDescriptorDIB: case SurfaceDescriptor::TSurfaceDescriptorD3D10: break; case SurfaceDescriptor::TMemoryImage: diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces.ipdlh index ec1cf5e7c9bb..4c773fa03c9f 100644 --- a/gfx/layers/ipc/LayersSurfaces.ipdlh +++ b/gfx/layers/ipc/LayersSurfaces.ipdlh @@ -42,6 +42,11 @@ struct SurfaceDescriptorD3D9 { uintptr_t texture; }; +struct SurfaceDescriptorDIB { + // gfxWindowsSurface* + uintptr_t surface; +}; + struct SurfaceDescriptorD3D10 { WindowsHandle handle; bool hasAlpha; @@ -167,6 +172,7 @@ union SurfaceDescriptor { SurfaceDescriptorShmem; SurfaceDescriptorMemory; SurfaceDescriptorD3D9; + SurfaceDescriptorDIB; SurfaceDescriptorD3D10; SurfaceDescriptorX11; SharedTextureDescriptor; From f9ecccbcc4a4245418275793405bebad88492edf Mon Sep 17 00:00:00 2001 From: Nicholas Cameron Date: Tue, 24 Sep 2013 13:14:12 +1200 Subject: [PATCH 012/160] Bug 912766. Use the DIB texture client/host. r=mattwoodrow --- gfx/layers/client/CanvasClient.cpp | 21 ++++++++++++--------- gfx/layers/client/CompositableClient.cpp | 10 ++++++++-- gfx/layers/client/CompositableClient.h | 4 +++- gfx/layers/client/ContentClient.cpp | 4 ++-- gfx/layers/d3d9/TextureD3D9.cpp | 2 ++ 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/gfx/layers/client/CanvasClient.cpp b/gfx/layers/client/CanvasClient.cpp index c472c32bc1d9..eeefde7cdb3b 100644 --- a/gfx/layers/client/CanvasClient.cpp +++ b/gfx/layers/client/CanvasClient.cpp @@ -121,10 +121,15 @@ DeprecatedCanvasClient2D::DeprecatedCanvasClient2D(CompositableForwarder* aFwd, void DeprecatedCanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) { + bool isOpaque = (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE); + gfxASurface::gfxContentType contentType = isOpaque + ? gfxASurface::CONTENT_COLOR + : gfxASurface::CONTENT_COLOR_ALPHA; + if (!mDeprecatedTextureClient) { - mDeprecatedTextureClient = CreateDeprecatedTextureClient(TEXTURE_CONTENT); + mDeprecatedTextureClient = CreateDeprecatedTextureClient(TEXTURE_CONTENT, contentType); if (!mDeprecatedTextureClient) { - mDeprecatedTextureClient = CreateDeprecatedTextureClient(TEXTURE_FALLBACK); + mDeprecatedTextureClient = CreateDeprecatedTextureClient(TEXTURE_FALLBACK, contentType); if (!mDeprecatedTextureClient) { NS_WARNING("Could not create texture client"); return; @@ -132,17 +137,12 @@ DeprecatedCanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) } } - bool isOpaque = (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE); - gfxASurface::gfxContentType contentType = isOpaque - ? gfxASurface::CONTENT_COLOR - : gfxASurface::CONTENT_COLOR_ALPHA; - if (!mDeprecatedTextureClient->EnsureAllocated(aSize, contentType)) { // We might already be on the fallback texture client if we couldn't create a // better one above. In which case this call to create is wasted. But I don't // think this will happen often enough to be worth complicating the code with // further checks. - mDeprecatedTextureClient = CreateDeprecatedTextureClient(TEXTURE_FALLBACK); + mDeprecatedTextureClient = CreateDeprecatedTextureClient(TEXTURE_FALLBACK, contentType); MOZ_ASSERT(mDeprecatedTextureClient, "Failed to create texture client"); if (!mDeprecatedTextureClient->EnsureAllocated(aSize, contentType)) { NS_WARNING("Could not allocate texture client"); @@ -173,7 +173,10 @@ void DeprecatedCanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) { if (!mDeprecatedTextureClient) { - mDeprecatedTextureClient = CreateDeprecatedTextureClient(TEXTURE_STREAM_GL); + mDeprecatedTextureClient = CreateDeprecatedTextureClient(TEXTURE_STREAM_GL, + aLayer->GetSurfaceMode() == Layer::SURFACE_OPAQUE + ? gfxASurface::CONTENT_COLOR + : gfxASurface::CONTENT_COLOR_ALPHA); MOZ_ASSERT(mDeprecatedTextureClient, "Failed to create texture client"); } diff --git a/gfx/layers/client/CompositableClient.cpp b/gfx/layers/client/CompositableClient.cpp index 1cbfa46c8152..64941aa83895 100644 --- a/gfx/layers/client/CompositableClient.cpp +++ b/gfx/layers/client/CompositableClient.cpp @@ -10,6 +10,7 @@ #include "mozilla/layers/TextureClient.h" // for DeprecatedTextureClient, etc #include "mozilla/layers/TextureClientOGL.h" #include "mozilla/mozalloc.h" // for operator delete, etc +#include "gfxASurface.h" // for gfxContentType #ifdef XP_WIN #include "mozilla/layers/TextureD3D9.h" #include "mozilla/layers/TextureD3D11.h" @@ -107,7 +108,8 @@ CompositableChild::Destroy() } TemporaryRef -CompositableClient::CreateDeprecatedTextureClient(DeprecatedTextureClientType aDeprecatedTextureClientType) +CompositableClient::CreateDeprecatedTextureClient(DeprecatedTextureClientType aDeprecatedTextureClientType, + gfxASurface::gfxContentType aContentType) { MOZ_ASSERT(GetForwarder(), "Can't create a texture client if the compositable is not connected to the compositor."); LayersBackend parentBackend = GetForwarder()->GetCompositorBackendType(); @@ -145,7 +147,11 @@ CompositableClient::CreateDeprecatedTextureClient(DeprecatedTextureClientType aD } if (parentBackend == LAYERS_D3D9 && !GetForwarder()->ForwardsToDifferentProcess()) { - result = new DeprecatedTextureClientD3D9(GetForwarder(), GetTextureInfo()); + if (aContentType == gfxASurface::CONTENT_COLOR_ALPHA) { + result = new DeprecatedTextureClientDIB(GetForwarder(), GetTextureInfo()); + } else { + result = new DeprecatedTextureClientD3D9(GetForwarder(), GetTextureInfo()); + } break; } #endif diff --git a/gfx/layers/client/CompositableClient.h b/gfx/layers/client/CompositableClient.h index 9b3020e95251..06ca331be8fb 100644 --- a/gfx/layers/client/CompositableClient.h +++ b/gfx/layers/client/CompositableClient.h @@ -16,6 +16,7 @@ #include "mozilla/layers/LayersTypes.h" // for LayersBackend #include "mozilla/layers/PCompositableChild.h" // for PCompositableChild #include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc +#include "gfxASurface.h" // for gfxContentType namespace mozilla { namespace layers { @@ -80,7 +81,8 @@ public: LayersBackend GetCompositorBackendType() const; TemporaryRef - CreateDeprecatedTextureClient(DeprecatedTextureClientType aDeprecatedTextureClientType); + CreateDeprecatedTextureClient(DeprecatedTextureClientType aDeprecatedTextureClientType, + gfxASurface::gfxContentType aContentType = gfxASurface::CONTENT_SENTINEL); virtual TemporaryRef CreateBufferTextureClient(gfx::SurfaceFormat aFormat, TextureFlags aFlags); diff --git a/gfx/layers/client/ContentClient.cpp b/gfx/layers/client/ContentClient.cpp index 5ee32881d7b1..897cdc7589e6 100644 --- a/gfx/layers/client/ContentClient.cpp +++ b/gfx/layers/client/ContentClient.cpp @@ -163,11 +163,11 @@ ContentClientRemoteBuffer::EndPaint() bool ContentClientRemoteBuffer::CreateAndAllocateDeprecatedTextureClient(RefPtr& aClient) { - aClient = CreateDeprecatedTextureClient(TEXTURE_CONTENT); + aClient = CreateDeprecatedTextureClient(TEXTURE_CONTENT, mContentType); MOZ_ASSERT(aClient, "Failed to create texture client"); if (!aClient->EnsureAllocated(mSize, mContentType)) { - aClient = CreateDeprecatedTextureClient(TEXTURE_FALLBACK); + aClient = CreateDeprecatedTextureClient(TEXTURE_FALLBACK, mContentType); MOZ_ASSERT(aClient, "Failed to create texture client"); if (!aClient->EnsureAllocated(mSize, mContentType)) { NS_WARNING("Could not allocate texture client"); diff --git a/gfx/layers/d3d9/TextureD3D9.cpp b/gfx/layers/d3d9/TextureD3D9.cpp index c75014016f6c..874ad5ddbb49 100644 --- a/gfx/layers/d3d9/TextureD3D9.cpp +++ b/gfx/layers/d3d9/TextureD3D9.cpp @@ -27,6 +27,8 @@ CreateDeprecatedTextureHostD3D9(SurfaceDescriptorType aDescriptorType, result = new DeprecatedTextureHostYCbCrD3D9(); } else if (aDescriptorType == SurfaceDescriptor::TSurfaceDescriptorD3D9) { result = new DeprecatedTextureHostSystemMemD3D9(); + } else if (aDescriptorType == SurfaceDescriptor::TSurfaceDescriptorDIB) { + result = new DeprecatedTextureHostDIB(); } else { result = new DeprecatedTextureHostShmemD3D9(); } From 6b9eb7d0244ae86ed5f085865aaa8d977fedd208 Mon Sep 17 00:00:00 2001 From: Nicholas Cameron Date: Tue, 24 Sep 2013 13:14:12 +1200 Subject: [PATCH 013/160] Bug 912766. Funky refcounting to keep the gfxWindowsSurface alive during transport. r=mattwoodrow --- gfx/layers/client/CanvasClient.cpp | 6 +++--- gfx/layers/client/ContentClient.cpp | 31 ++++++++++++++++++++++------ gfx/layers/client/ImageClient.cpp | 2 +- gfx/layers/client/TextureClient.h | 7 +++++-- gfx/layers/composite/ContentHost.cpp | 8 +++---- gfx/layers/composite/TextureHost.h | 1 + gfx/layers/d3d9/TextureD3D9.cpp | 26 +++++++++++++++++------ gfx/layers/d3d9/TextureD3D9.h | 30 ++++++++++++++++++++++++--- 8 files changed, 86 insertions(+), 25 deletions(-) diff --git a/gfx/layers/client/CanvasClient.cpp b/gfx/layers/client/CanvasClient.cpp index eeefde7cdb3b..8b44605c55ec 100644 --- a/gfx/layers/client/CanvasClient.cpp +++ b/gfx/layers/client/CanvasClient.cpp @@ -107,7 +107,7 @@ CanvasClient2D::CreateBufferTextureClient(gfx::SurfaceFormat aFormat) void DeprecatedCanvasClient2D::Updated() { - mForwarder->UpdateTexture(this, 1, mDeprecatedTextureClient->GetDescriptor()); + mForwarder->UpdateTexture(this, 1, mDeprecatedTextureClient->LockSurfaceDescriptor()); } @@ -158,7 +158,7 @@ DeprecatedCanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) void DeprecatedCanvasClientSurfaceStream::Updated() { - mForwarder->UpdateTextureNoSwap(this, 1, mDeprecatedTextureClient->GetDescriptor()); + mForwarder->UpdateTextureNoSwap(this, 1, mDeprecatedTextureClient->LockSurfaceDescriptor()); } @@ -204,7 +204,7 @@ DeprecatedCanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLaye } SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf); - mDeprecatedTextureClient->SetDescriptor(grallocSurf->GetDescriptor()); + mDeprecatedTextureClient->SetDescriptor(grallocSurf->LockSurfaceDescriptor()); #else printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!"); MOZ_ASSERT(false); diff --git a/gfx/layers/client/ContentClient.cpp b/gfx/layers/client/ContentClient.cpp index 897cdc7589e6..610e41089136 100644 --- a/gfx/layers/client/ContentClient.cpp +++ b/gfx/layers/client/ContentClient.cpp @@ -171,6 +171,8 @@ ContentClientRemoteBuffer::CreateAndAllocateDeprecatedTextureClient(RefPtrEnsureAllocated(mSize, mContentType)) { NS_WARNING("Could not allocate texture client"); + aClient->SetFlags(0); + aClient = nullptr; return false; } } @@ -207,6 +209,8 @@ ContentClientRemoteBuffer::BuildDeprecatedTextureClients(ContentType aType, if (aFlags & BUFFER_COMPONENT_ALPHA) { if (!CreateAndAllocateDeprecatedTextureClient(mDeprecatedTextureClientOnWhite)) { + mDeprecatedTextureClient->SetFlags(0); + mDeprecatedTextureClient = nullptr; return; } mTextureInfo.mTextureFlags |= TEXTURE_COMPONENT_ALPHA; @@ -240,6 +244,9 @@ ContentClientRemoteBuffer::CreateBuffer(ContentType aType, RefPtr* aWhiteDT) { BuildDeprecatedTextureClients(aType, aRect, aFlags); + if (!mDeprecatedTextureClient) { + return; + } if (gfxPlatform::GetPlatform()->SupportsAzureContentForType( mDeprecatedTextureClient->BackendType())) { @@ -337,11 +344,23 @@ void ContentClientDoubleBuffered::CreateFrontBufferAndNotify(const nsIntRect& aBufferRect) { if (!CreateAndAllocateDeprecatedTextureClient(mFrontClient)) { + mDeprecatedTextureClient->SetFlags(0); + mDeprecatedTextureClient = nullptr; + if (mDeprecatedTextureClientOnWhite) { + mDeprecatedTextureClientOnWhite->SetFlags(0); + mDeprecatedTextureClientOnWhite = nullptr; + } return; } if (mTextureInfo.mTextureFlags & TEXTURE_COMPONENT_ALPHA) { if (!CreateAndAllocateDeprecatedTextureClient(mFrontClientOnWhite)) { + mDeprecatedTextureClient->SetFlags(0); + mDeprecatedTextureClient = nullptr; + mDeprecatedTextureClientOnWhite->SetFlags(0); + mDeprecatedTextureClientOnWhite = nullptr; + mFrontClient->SetFlags(0); + mFrontClient = nullptr; return; } } @@ -350,11 +369,11 @@ ContentClientDoubleBuffered::CreateFrontBufferAndNotify(const nsIntRect& aBuffer mFrontBufferRotation = nsIntPoint(); mForwarder->CreatedDoubleBuffer(this, - *mFrontClient->GetDescriptor(), - *mDeprecatedTextureClient->GetDescriptor(), + *mFrontClient->LockSurfaceDescriptor(), + *mDeprecatedTextureClient->LockSurfaceDescriptor(), mTextureInfo, - mFrontClientOnWhite ? mFrontClientOnWhite->GetDescriptor() : nullptr, - mDeprecatedTextureClientOnWhite ? mDeprecatedTextureClientOnWhite->GetDescriptor() : nullptr); + mFrontClientOnWhite ? mFrontClientOnWhite->LockSurfaceDescriptor() : nullptr, + mDeprecatedTextureClientOnWhite ? mDeprecatedTextureClientOnWhite->LockSurfaceDescriptor() : nullptr); } void @@ -566,9 +585,9 @@ void ContentClientSingleBuffered::CreateFrontBufferAndNotify(const nsIntRect& aBufferRect) { mForwarder->CreatedSingleBuffer(this, - *mDeprecatedTextureClient->GetDescriptor(), + *mDeprecatedTextureClient->LockSurfaceDescriptor(), mTextureInfo, - mDeprecatedTextureClientOnWhite ? mDeprecatedTextureClientOnWhite->GetDescriptor() : nullptr); + mDeprecatedTextureClientOnWhite ? mDeprecatedTextureClientOnWhite->LockSurfaceDescriptor() : nullptr); } void diff --git a/gfx/layers/client/ImageClient.cpp b/gfx/layers/client/ImageClient.cpp index dadf2eb2cec4..fdca9c3b1ccb 100644 --- a/gfx/layers/client/ImageClient.cpp +++ b/gfx/layers/client/ImageClient.cpp @@ -449,7 +449,7 @@ DeprecatedImageClientSingle::UpdateImage(ImageContainer* aContainer, void DeprecatedImageClientSingle::Updated() { - mForwarder->UpdateTexture(this, 1, mDeprecatedTextureClient->GetDescriptor()); + mForwarder->UpdateTexture(this, 1, mDeprecatedTextureClient->LockSurfaceDescriptor()); } ImageClientBridge::ImageClientBridge(CompositableForwarder* aFwd, diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index 94ce0ff5d0b4..2b6f47e81d24 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -410,8 +410,6 @@ public: return gfx::BACKEND_NONE; } - - virtual SurfaceDescriptor* LockSurfaceDescriptor() { return GetDescriptor(); } virtual void ReleaseResources() {} /** * This unlocks the current DrawableTexture and allows the host to composite @@ -441,6 +439,11 @@ public: mDescriptor = aDescriptor; } SurfaceDescriptor* GetDescriptor() { return &mDescriptor; } + /** + * Use LockSurfaceDescriptor to get the descriptor if it will be sent across IPC. + * Use GetDescriptor if you want to keep the descriptor on one thread. + */ + virtual SurfaceDescriptor* LockSurfaceDescriptor() { return GetDescriptor(); } CompositableForwarder* GetForwarder() const { diff --git a/gfx/layers/composite/ContentHost.cpp b/gfx/layers/composite/ContentHost.cpp index 2df0293491fb..be29e990fcc3 100644 --- a/gfx/layers/composite/ContentHost.cpp +++ b/gfx/layers/composite/ContentHost.cpp @@ -342,9 +342,9 @@ ContentHostSingleBuffered::UpdateThebes(const ThebesBufferData& aData, MOZ_ASSERT((destBounds.y % size.height) + destBounds.height <= size.height, "updated region lies across rotation boundaries!"); - mDeprecatedTextureHost->Update(*mDeprecatedTextureHost->GetBuffer(), &destRegion); + mDeprecatedTextureHost->Update(*mDeprecatedTextureHost->LockSurfaceDescriptor(), &destRegion); if (mDeprecatedTextureHostOnWhite) { - mDeprecatedTextureHostOnWhite->Update(*mDeprecatedTextureHostOnWhite->GetBuffer(), &destRegion); + mDeprecatedTextureHostOnWhite->Update(*mDeprecatedTextureHostOnWhite->LockSurfaceDescriptor(), &destRegion); } mInitialised = true; @@ -463,9 +463,9 @@ ContentHostDoubleBuffered::UpdateThebes(const ThebesBufferData& aData, mDeprecatedTextureHostOnWhite = mBackHostOnWhite; mBackHostOnWhite = oldFront; - mDeprecatedTextureHost->Update(*mDeprecatedTextureHost->GetBuffer()); + mDeprecatedTextureHost->Update(*mDeprecatedTextureHost->LockSurfaceDescriptor()); if (mDeprecatedTextureHostOnWhite) { - mDeprecatedTextureHostOnWhite->Update(*mDeprecatedTextureHostOnWhite->GetBuffer()); + mDeprecatedTextureHostOnWhite->Update(*mDeprecatedTextureHostOnWhite->LockSurfaceDescriptor()); } mInitialised = true; diff --git a/gfx/layers/composite/TextureHost.h b/gfx/layers/composite/TextureHost.h index 312421df15f6..1771f1a4dc6c 100644 --- a/gfx/layers/composite/TextureHost.h +++ b/gfx/layers/composite/TextureHost.h @@ -697,6 +697,7 @@ public: SurfaceDescriptor* GetBuffer() const { return mBuffer; } + virtual SurfaceDescriptor* LockSurfaceDescriptor() const { return GetBuffer(); } /** * Set a SurfaceDescriptor for this texture host. By setting a buffer and diff --git a/gfx/layers/d3d9/TextureD3D9.cpp b/gfx/layers/d3d9/TextureD3D9.cpp index 874ad5ddbb49..3fd6fc4b5f00 100644 --- a/gfx/layers/d3d9/TextureD3D9.cpp +++ b/gfx/layers/d3d9/TextureD3D9.cpp @@ -513,10 +513,13 @@ DeprecatedTextureHostDIB::UpdateImpl(const SurfaceDescriptor& aImage, MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TSurfaceDescriptorDIB); MOZ_ASSERT(mCompositor, "Must have compositor to update."); + if (!mCompositor->device()) { + return; + } + + // We added an extra ref for transport, so we shouldn't AddRef now. nsRefPtr surf = - reinterpret_cast(aImage.get_SurfaceDescriptorDIB().surface()); - // We added an extra ref for transport, we can release it now. - surf->Release(); + dont_AddRef(reinterpret_cast(aImage.get_SurfaceDescriptorDIB().surface())); gfxIntSize size = surf->GetSize(); mSize = IntSize(size.width, size.height); @@ -728,6 +731,8 @@ DeprecatedTextureClientDIB::~DeprecatedTextureClientDIB() { MOZ_COUNT_DTOR(DeprecatedTextureClientDIB); Unlock(); + // It is OK not to dealloc the surface descriptor because it is only a pointer + // to mSurface and we will release our strong reference to that automatically. mDescriptor = SurfaceDescriptor(); mDrawTarget = nullptr; } @@ -753,19 +758,28 @@ DeprecatedTextureClientDIB::EnsureAllocated(gfx::IntSize aSize, { NS_WARNING("Could not create surface"); mSurface = nullptr; + mDescriptor = SurfaceDescriptor(); return false; } mSize = aSize; mContentType = aType; mDescriptor = SurfaceDescriptorDIB(reinterpret_cast(mSurface.get())); - // The host will release this ref when it receives the surface descriptor. - // We AddRef in case we die before the host receives the pointer. - mSurface->AddRef(); return true; } +SurfaceDescriptor* +DeprecatedTextureClientDIB::LockSurfaceDescriptor() +{ + // The host will release this ref when it receives the surface descriptor. + // We AddRef in case we die before the host receives the pointer. + NS_ASSERTION(mSurface == reinterpret_cast(mDescriptor.get_SurfaceDescriptorDIB().surface()), + "SurfaceDescriptor is not up to date"); + mSurface->AddRef(); + return GetDescriptor(); +} + gfxASurface* DeprecatedTextureClientDIB::LockSurface() { diff --git a/gfx/layers/d3d9/TextureD3D9.h b/gfx/layers/d3d9/TextureD3D9.h index 4f5048f41eb2..70c68bd9a0a7 100644 --- a/gfx/layers/d3d9/TextureD3D9.h +++ b/gfx/layers/d3d9/TextureD3D9.h @@ -169,8 +169,6 @@ protected: virtual void UpdateImpl(const SurfaceDescriptor& aSurface, nsIntRegion* aRegion, nsIntPoint *aOffset = nullptr) MOZ_OVERRIDE; - - nsRefPtr mTexture; }; class DeprecatedTextureHostYCbCrD3D9 : public DeprecatedTextureHost @@ -218,13 +216,38 @@ public: #ifdef MOZ_LAYERS_HAVE_LOG virtual const char* Name() { return "DeprecatedTextureHostDIB"; } #endif + virtual void SetBuffer(SurfaceDescriptor* aBuffer, ISurfaceAllocator* aAllocator) MOZ_OVERRIDE + { + MOZ_ASSERT(aBuffer->type() == SurfaceDescriptor::TSurfaceDescriptorDIB); + // We are responsible for keeping the surface alive. But the client will have AddRefed it + // for transport to the host. So we don't need to AddRef here. + mSurface = dont_AddRef(reinterpret_cast(aBuffer->get_SurfaceDescriptorDIB().surface())); + DeprecatedTextureHost::SetBuffer(aBuffer, aAllocator); + } + virtual SurfaceDescriptor* LockSurfaceDescriptor() const MOZ_OVERRIDE + { + NS_ASSERTION(!mBuffer || + (mBuffer->type() == SurfaceDescriptor::TSurfaceDescriptorDIB && + mSurface == reinterpret_cast(mBuffer->get_SurfaceDescriptorDIB().surface())), + "SurfaceDescriptor is not up to date"); + // We are either going to pass the surface descriptor to the content thread + // or we are going to give the our surface descriptor to a compositable host, + // pretending that it is from the client thread. In either case it is going to + // get released, so we need to AddRef here. + if (mBuffer) { + mSurface->AddRef(); + } + return DeprecatedTextureHost::LockSurfaceDescriptor(); + } protected: virtual void UpdateImpl(const SurfaceDescriptor& aSurface, nsIntRegion* aRegion, nsIntPoint *aOffset = nullptr) MOZ_OVERRIDE; - nsRefPtr mTexture; + // Used to keep the surface alive if the host has responsibility for the + // lifetime of the surface. + nsRefPtr mSurface; }; // If we want to use d3d9 textures for transport, use this class. @@ -295,6 +318,7 @@ public: } virtual void Unlock() MOZ_OVERRIDE; + virtual SurfaceDescriptor* LockSurfaceDescriptor() MOZ_OVERRIDE; virtual void SetDescriptor(const SurfaceDescriptor& aDescriptor) MOZ_OVERRIDE; virtual gfxASurface::gfxContentType GetContentType() MOZ_OVERRIDE { From c12354f9117679edb3012d9118d47f4005d70e03 Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Tue, 24 Sep 2013 10:20:39 +0900 Subject: [PATCH 014/160] Bug 916071 - Detect RemoteFX on reftest. r=vlad --- layout/reftests/bugs/reftest.list | 2 +- layout/reftests/font-features/reftest.list | 2 +- layout/tools/reftest/reftest.js | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index fb011c824386..1588b78325e1 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1715,7 +1715,7 @@ skip-if(B2G) == 751012-1a.html 751012-1-ref.html skip-if(B2G) == 751012-1b.html 751012-1-ref.html random-if(Android) == 753329-1.html about:blank == 758561-1.html 758561-1-ref.html -fuzzy-if(true,1,19) fails-if(d2d) random-if(Android&&AndroidVersion<15) == 759036-1.html 759036-1-ref.html +fuzzy-if(true,1,19) fails-if(d2d&&!remoteFX) random-if(Android&&AndroidVersion<15) == 759036-1.html 759036-1-ref.html fuzzy-if(true,17,5860) random-if(Android&&AndroidVersion<15) == 759036-2.html 759036-2-ref.html == 776265-1a.html 776265-1-ref.html == 776265-1b.html 776265-1-ref.html diff --git a/layout/reftests/font-features/reftest.list b/layout/reftests/font-features/reftest.list index 7eebffa70f35..73f01d7cc53f 100644 --- a/layout/reftests/font-features/reftest.list +++ b/layout/reftests/font-features/reftest.list @@ -15,7 +15,7 @@ HTTP(..) != font-features-hlig.html font-features-ref.html # compare Turkish rendering with reference using ZWNJ to break the ligature # (also works via Pango) -fails-if(d2d) HTTP(..) == font-features-turkish.html font-features-turkish-ref.html +fails-if(d2d&&!remoteFX) HTTP(..) == font-features-turkish.html font-features-turkish-ref.html # compare Turkish rendering with explicitly disabled ligatures HTTP(..) == font-features-turkish.html font-features-noliga.html diff --git a/layout/tools/reftest/reftest.js b/layout/tools/reftest/reftest.js index 85496601a856..f76c16cc9b43 100644 --- a/layout/tools/reftest/reftest.js +++ b/layout/tools/reftest/reftest.js @@ -584,6 +584,7 @@ function BuildConditionSandbox(aURL) { sandbox.azureQuartz = info.AzureCanvasBackend == "quartz"; sandbox.azureSkia = info.AzureCanvasBackend == "skia"; sandbox.azureSkiaGL = info.AzureSkiaAccelerated; // FIXME: assumes GL right now + sandbox.remoteFX = gfxInfo.adapterVendorID == "0x1414"; // true if we are using the same Azure backend for rendering canvas and content sandbox.contentSameGfxBackendAsCanvas = info.AzureContentBackend == info.AzureCanvasBackend || (info.AzureContentBackend == "none" && info.AzureCanvasBackend == "cairo"); From 5488ca9bd977ffcfc8205fbe6686fdeec03ee2dd Mon Sep 17 00:00:00 2001 From: Nicholas Cameron Date: Tue, 24 Sep 2013 13:59:59 +1200 Subject: [PATCH 015/160] No bug. Fixbuild bustage in CanvasClient.cpp. r=bustage --- gfx/layers/client/CanvasClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/layers/client/CanvasClient.cpp b/gfx/layers/client/CanvasClient.cpp index 8b44605c55ec..a9bd1a90394c 100644 --- a/gfx/layers/client/CanvasClient.cpp +++ b/gfx/layers/client/CanvasClient.cpp @@ -204,7 +204,7 @@ DeprecatedCanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLaye } SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf); - mDeprecatedTextureClient->SetDescriptor(grallocSurf->LockSurfaceDescriptor()); + mDeprecatedTextureClient->SetDescriptor(grallocSurf->GetDescriptor()); #else printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!"); MOZ_ASSERT(false); From 6baf345b3fe28c57cee4ba22c3dd5be48d23aaf5 Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Tue, 24 Sep 2013 09:53:40 +0800 Subject: [PATCH 016/160] Bug 919380: Disable threadsafety assertions when --enable-profiling is set. r=smaug --- xpcom/glue/nsISupportsImpl.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xpcom/glue/nsISupportsImpl.h b/xpcom/glue/nsISupportsImpl.h index 932cd15cc30e..e23fca6a738d 100644 --- a/xpcom/glue/nsISupportsImpl.h +++ b/xpcom/glue/nsISupportsImpl.h @@ -49,7 +49,7 @@ ToCanonicalSupports(nsISupports* p) //////////////////////////////////////////////////////////////////////////////// // Macros to help detect thread-safety: -#if (defined(DEBUG) || defined(NIGHTLY_BUILD)) && !defined(XPCOM_GLUE_AVOID_NSPR) +#if (defined(DEBUG) || (defined(NIGHTLY_BUILD) && !defined(MOZ_PROFILING))) && !defined(XPCOM_GLUE_AVOID_NSPR) class nsAutoOwningThread { public: @@ -64,13 +64,13 @@ private: #define NS_ASSERT_OWNINGTHREAD_AGGREGATE(agg, _class) \ NS_CheckThreadSafe(agg->_mOwningThread.GetThread(), #_class " not thread-safe") #define NS_ASSERT_OWNINGTHREAD(_class) NS_ASSERT_OWNINGTHREAD_AGGREGATE(this, _class) -#else // !DEBUG && !NIGHTLY_BUILD +#else // !DEBUG && !(NIGHTLY_BUILD && !MOZ_PROFILING) #define NS_DECL_OWNINGTHREAD /* nothing */ #define NS_ASSERT_OWNINGTHREAD_AGGREGATE(agg, _class) ((void)0) #define NS_ASSERT_OWNINGTHREAD(_class) ((void)0) -#endif // DEBUG || NIGHTLY_BUILD +#endif // DEBUG || (NIGHTLY_BUILD && !MOZ_PROFILING) // Support for ISupports classes which interact with cycle collector. From e5d67f927dbe8d03103fc5e593fc7ec0abf7376e Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Tue, 24 Sep 2013 13:45:23 +1200 Subject: [PATCH 017/160] b=903270 remove default null initial event parameter from NS_NewNamedThread() call site r=chiajung --HG-- extra : transplant_source : %A9F%B6%CD%ED%DF%96%9C%AD%DE%B1%8E%3F%90%5E%DA%10%D2%7D%8E --- content/media/webrtc/MediaEngineWebRTC.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/media/webrtc/MediaEngineWebRTC.h b/content/media/webrtc/MediaEngineWebRTC.h index 756c97a3b217..3990c0248781 100644 --- a/content/media/webrtc/MediaEngineWebRTC.h +++ b/content/media/webrtc/MediaEngineWebRTC.h @@ -111,7 +111,7 @@ public: , mSnapshotPath(nullptr) { mState = kReleased; - NS_NewNamedThread("CameraThread", getter_AddRefs(mCameraThread), nullptr); + NS_NewNamedThread("CameraThread", getter_AddRefs(mCameraThread)); Init(); } #else From 7127e8b159d8d69645c563090ed2931feb747079 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Tue, 24 Sep 2013 13:45:41 +1200 Subject: [PATCH 018/160] b=914033 use AudioContext::RegisterActiveNode() in OscillatorNode r=ehsan Storing references on the AudioContext instead of on the AudioNodes will allow the AudioContext to report them to the cycle collector until offline rendering starts. --HG-- extra : transplant_source : %81%83Hp%F6T%E7%9EA%B3%D0%5Dz%EA%1FYv%A2%23%ED --- content/media/webaudio/AudioContext.cpp | 15 ------------ content/media/webaudio/AudioContext.h | 2 -- content/media/webaudio/OscillatorNode.cpp | 28 ++++------------------- content/media/webaudio/OscillatorNode.h | 1 - 4 files changed, 5 insertions(+), 41 deletions(-) diff --git a/content/media/webaudio/AudioContext.cpp b/content/media/webaudio/AudioContext.cpp index d942bc5189d7..8c5e49862a44 100644 --- a/content/media/webaudio/AudioContext.cpp +++ b/content/media/webaudio/AudioContext.cpp @@ -379,7 +379,6 @@ AudioContext::CreateOscillator() { nsRefPtr oscillatorNode = new OscillatorNode(this); - mOscillatorNodes.PutEntry(oscillatorNode); return oscillatorNode.forget(); } @@ -474,12 +473,6 @@ AudioContext::UnregisterPannerNode(PannerNode* aNode) } } -void -AudioContext::UnregisterOscillatorNode(OscillatorNode* aNode) -{ - mOscillatorNodes.RemoveEntry(aNode); -} - void AudioContext::UnregisterScriptProcessorNode(ScriptProcessorNode* aNode) { @@ -566,14 +559,6 @@ AudioContext::Shutdown() ErrorResult rv; sourceNodes[i]->Stop(0.0, rv, true); } - // Stop all Oscillator nodes to make sure they release their - // playing reference. - nsTArray oscNodes; - GetHashtableElements(mOscillatorNodes, oscNodes); - for (uint32_t i = 0; i < oscNodes.Length(); ++i) { - ErrorResult rv; - oscNodes[i]->Stop(0.0, rv); - } // Stop all script processor nodes, to make sure that they release // their self-references. nsTArray spNodes; diff --git a/content/media/webaudio/AudioContext.h b/content/media/webaudio/AudioContext.h index 7afa0f95f264..ec72ebbabcb8 100644 --- a/content/media/webaudio/AudioContext.h +++ b/content/media/webaudio/AudioContext.h @@ -229,7 +229,6 @@ public: void UnregisterAudioBufferSourceNode(AudioBufferSourceNode* aNode); void UnregisterPannerNode(PannerNode* aNode); - void UnregisterOscillatorNode(OscillatorNode* aNode); void UnregisterScriptProcessorNode(ScriptProcessorNode* aNode); void UpdatePannerSource(); @@ -262,7 +261,6 @@ private: // These are all weak pointers. nsTHashtable > mPannerNodes; nsTHashtable > mAudioBufferSourceNodes; - nsTHashtable > mOscillatorNodes; // Hashset containing all ScriptProcessorNodes in order to stop them. // These are all weak pointers. nsTHashtable > mScriptProcessorNodes; diff --git a/content/media/webaudio/OscillatorNode.cpp b/content/media/webaudio/OscillatorNode.cpp index 1e68533f8d24..c171e3437355 100644 --- a/content/media/webaudio/OscillatorNode.cpp +++ b/content/media/webaudio/OscillatorNode.cpp @@ -14,22 +14,8 @@ namespace mozilla { namespace dom { -NS_IMPL_CYCLE_COLLECTION_CLASS(OscillatorNode) - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(OscillatorNode) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mPeriodicWave) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mFrequency) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mDetune) - if (tmp->Context()) { - tmp->Context()->UnregisterOscillatorNode(tmp); - } -NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(AudioNode); - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(OscillatorNode, AudioNode) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPeriodicWave) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrequency) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDetune) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_INHERITED_3(OscillatorNode, AudioNode, + mPeriodicWave, mFrequency, mDetune) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(OscillatorNode) NS_INTERFACE_MAP_END_INHERITING(AudioNode) @@ -524,9 +510,6 @@ OscillatorNode::OscillatorNode(AudioContext* aContext) OscillatorNode::~OscillatorNode() { - if (Context()) { - Context()->UnregisterOscillatorNode(this); - } } JSObject* @@ -598,8 +581,7 @@ OscillatorNode::Start(double aWhen, ErrorResult& aRv) Context()->DestinationStream(), aWhen); - MOZ_ASSERT(!mPlayingRef, "We can only accept a successful start() call once"); - mPlayingRef.Take(this); + MarkActive(); } void @@ -615,7 +597,7 @@ OscillatorNode::Stop(double aWhen, ErrorResult& aRv) return; } - mPlayingRef.Drop(this); + MarkInactive(); AudioNodeStream* ns = static_cast(mStream.get()); if (!ns || !Context()) { @@ -660,7 +642,7 @@ OscillatorNode::NotifyMainThreadStateChanged() // Drop the playing reference // Warning: The below line might delete this. - mPlayingRef.Drop(this); + MarkInactive(); } } diff --git a/content/media/webaudio/OscillatorNode.h b/content/media/webaudio/OscillatorNode.h index 8059b9c485ae..3def13211e86 100644 --- a/content/media/webaudio/OscillatorNode.h +++ b/content/media/webaudio/OscillatorNode.h @@ -129,7 +129,6 @@ private: nsRefPtr mPeriodicWave; nsRefPtr mFrequency; nsRefPtr mDetune; - SelfReference mPlayingRef; bool mStartCalled; bool mStopped; }; From a6c6d85ac85a443d28387e1246bd0a405797f7c7 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Tue, 24 Sep 2013 13:46:30 +1200 Subject: [PATCH 019/160] b=914033 use AudioContext::RegisterActiveNode() in ScriptProcessorNode r=ehsan Storing references on the AudioContext instead of on the AudioNodes will allow the AudioContext to report them to the cycle collector until offline rendering starts. --HG-- extra : transplant_source : %CD%5Els2%7F/%DD%5E%07%08%FE%29%5B%98%95%F3%11G%E6 --- content/media/webaudio/AudioContext.cpp | 14 ------ content/media/webaudio/AudioContext.h | 4 -- content/media/webaudio/AudioNode.h | 46 ++++--------------- .../media/webaudio/ScriptProcessorNode.cpp | 20 +------- content/media/webaudio/ScriptProcessorNode.h | 15 ++---- 5 files changed, 13 insertions(+), 86 deletions(-) diff --git a/content/media/webaudio/AudioContext.cpp b/content/media/webaudio/AudioContext.cpp index 8c5e49862a44..f70a25603920 100644 --- a/content/media/webaudio/AudioContext.cpp +++ b/content/media/webaudio/AudioContext.cpp @@ -249,7 +249,6 @@ AudioContext::CreateScriptProcessor(uint32_t aBufferSize, nsRefPtr scriptProcessor = new ScriptProcessorNode(this, aBufferSize, aNumberOfInputChannels, aNumberOfOutputChannels); - mScriptProcessorNodes.PutEntry(scriptProcessor); return scriptProcessor.forget(); } @@ -473,12 +472,6 @@ AudioContext::UnregisterPannerNode(PannerNode* aNode) } } -void -AudioContext::UnregisterScriptProcessorNode(ScriptProcessorNode* aNode) -{ - mScriptProcessorNodes.RemoveEntry(aNode); -} - static PLDHashOperator FindConnectedSourcesOn(nsPtrHashKey* aEntry, void* aData) { @@ -559,13 +552,6 @@ AudioContext::Shutdown() ErrorResult rv; sourceNodes[i]->Stop(0.0, rv, true); } - // Stop all script processor nodes, to make sure that they release - // their self-references. - nsTArray spNodes; - GetHashtableElements(mScriptProcessorNodes, spNodes); - for (uint32_t i = 0; i < spNodes.Length(); ++i) { - spNodes[i]->Stop(); - } // For offline contexts, we can destroy the MediaStreamGraph at this point. if (mIsOffline && mDestination) { diff --git a/content/media/webaudio/AudioContext.h b/content/media/webaudio/AudioContext.h index ec72ebbabcb8..d699942925d8 100644 --- a/content/media/webaudio/AudioContext.h +++ b/content/media/webaudio/AudioContext.h @@ -229,7 +229,6 @@ public: void UnregisterAudioBufferSourceNode(AudioBufferSourceNode* aNode); void UnregisterPannerNode(PannerNode* aNode); - void UnregisterScriptProcessorNode(ScriptProcessorNode* aNode); void UpdatePannerSource(); uint32_t MaxChannelCount() const; @@ -261,9 +260,6 @@ private: // These are all weak pointers. nsTHashtable > mPannerNodes; nsTHashtable > mAudioBufferSourceNodes; - // Hashset containing all ScriptProcessorNodes in order to stop them. - // These are all weak pointers. - nsTHashtable > mScriptProcessorNodes; // Number of channels passed in the OfflineAudioContext ctor. uint32_t mNumberOfChannels; bool mIsOffline; diff --git a/content/media/webaudio/AudioNode.h b/content/media/webaudio/AudioNode.h index 93e6ce2884cd..5e2be2ef505f 100644 --- a/content/media/webaudio/AudioNode.h +++ b/content/media/webaudio/AudioNode.h @@ -57,44 +57,6 @@ private: bool mHeld; }; -template -class SelfCountedReference { -public: - SelfCountedReference() : mRefCnt(0) {} - ~SelfCountedReference() - { - NS_ASSERTION(mRefCnt == 0, "Forgot to drop the self reference?"); - } - - void Take(T* t) - { - if (mRefCnt++ == 0) { - t->AddRef(); - } - } - void Drop(T* t) - { - if (mRefCnt > 0) { - --mRefCnt; - if (mRefCnt == 0) { - t->Release(); - } - } - } - void ForceDrop(T* t) - { - if (mRefCnt > 0) { - mRefCnt = 0; - t->Release(); - } - } - - operator bool() const { return mRefCnt > 0; } - -private: - nsrefcnt mRefCnt; -}; - /** * The DOM object representing a Web Audio AudioNode. * @@ -212,6 +174,14 @@ public: { return mInputNodes; } + const nsTArray >& OutputNodes() const + { + return mOutputNodes; + } + const nsTArray >& OutputParams() const + { + return mOutputParams; + } void RemoveOutputParam(AudioParam* aParam); diff --git a/content/media/webaudio/ScriptProcessorNode.cpp b/content/media/webaudio/ScriptProcessorNode.cpp index e6fb3a260692..5b31c878e1da 100644 --- a/content/media/webaudio/ScriptProcessorNode.cpp +++ b/content/media/webaudio/ScriptProcessorNode.cpp @@ -24,22 +24,7 @@ namespace dom { // buffers. static const float MAX_LATENCY_S = 0.5; -NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptProcessorNode) - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptProcessorNode) - if (tmp->Context()) { - tmp->Context()->UnregisterScriptProcessorNode(tmp); - } -NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(AudioNode) - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ScriptProcessorNode, AudioNode) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ScriptProcessorNode) -NS_INTERFACE_MAP_END_INHERITING(AudioNode) - -NS_IMPL_ADDREF_INHERITED(ScriptProcessorNode, AudioNode) -NS_IMPL_RELEASE_INHERITED(ScriptProcessorNode, AudioNode) +NS_IMPL_ISUPPORTS_INHERITED0(ScriptProcessorNode, AudioNode) // This class manages a queue of output buffers shared between // the main thread and the Media Stream Graph thread. @@ -424,9 +409,6 @@ ScriptProcessorNode::ScriptProcessorNode(AudioContext* aContext, ScriptProcessorNode::~ScriptProcessorNode() { - if (Context()) { - Context()->UnregisterScriptProcessorNode(this); - } } JSObject* diff --git a/content/media/webaudio/ScriptProcessorNode.h b/content/media/webaudio/ScriptProcessorNode.h index efda98864cb0..0d9ed3dc3e60 100644 --- a/content/media/webaudio/ScriptProcessorNode.h +++ b/content/media/webaudio/ScriptProcessorNode.h @@ -26,7 +26,6 @@ public: virtual ~ScriptProcessorNode(); NS_DECL_ISUPPORTS_INHERITED - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ScriptProcessorNode, AudioNode) IMPL_EVENT_HANDLER(audioprocess) @@ -38,7 +37,7 @@ public: { AudioNode::Connect(aDestination, aOutput, aInput, aRv); if (!aRv.Failed()) { - mPlayingRef.Take(this); + MarkActive(); } } @@ -47,15 +46,15 @@ public: { AudioNode::Connect(aDestination, aOutput, aRv); if (!aRv.Failed()) { - mPlayingRef.Take(this); + MarkActive(); } } virtual void Disconnect(uint32_t aOutput, ErrorResult& aRv) MOZ_OVERRIDE { AudioNode::Disconnect(aOutput, aRv); - if (!aRv.Failed()) { - mPlayingRef.Drop(this); + if (!aRv.Failed() && OutputNodes().IsEmpty() && OutputParams().IsEmpty()) { + MarkInactive(); } } @@ -91,16 +90,10 @@ public: using nsDOMEventTargetHelper::DispatchTrustedEvent; - void Stop() - { - mPlayingRef.ForceDrop(this); - } - private: nsAutoPtr mSharedBuffers; const uint32_t mBufferSize; const uint32_t mNumberOfOutputChannels; - SelfCountedReference mPlayingRef; // a reference to self while planing }; } From fd76422dd6c96e7511e157d565e6474e4ed02474 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Tue, 24 Sep 2013 13:47:00 +1200 Subject: [PATCH 020/160] b=914033 use AudioContext::RegisterActiveNode() in AudioBufferSourceNode r=ehsan Storing references on the AudioContext instead of on the AudioNodes will allow the AudioContext to report them to the cycle collector until offline rendering starts. --HG-- extra : transplant_source : %13%87%97%9F%CD%D8V%16%D2%D4%B5%84D%0A%D6%02%9BNj%FC --- .../media/webaudio/AudioBufferSourceNode.cpp | 12 +++---- .../media/webaudio/AudioBufferSourceNode.h | 3 +- content/media/webaudio/AudioContext.cpp | 31 ------------------- content/media/webaudio/AudioContext.h | 6 ++-- 4 files changed, 8 insertions(+), 44 deletions(-) diff --git a/content/media/webaudio/AudioBufferSourceNode.cpp b/content/media/webaudio/AudioBufferSourceNode.cpp index 95c76a18644d..6d2751a487c1 100644 --- a/content/media/webaudio/AudioBufferSourceNode.cpp +++ b/content/media/webaudio/AudioBufferSourceNode.cpp @@ -513,8 +513,7 @@ AudioBufferSourceNode::Start(double aWhen, double aOffset, ns->SetStreamTimeParameter(START, Context()->DestinationStream(), aWhen); } - MOZ_ASSERT(!mPlayingRef, "We can only accept a successful start() call once"); - mPlayingRef.Take(this); + MarkActive(); } void @@ -573,7 +572,7 @@ AudioBufferSourceNode::SendOffsetAndDurationParametersToStream(AudioNodeStream* } void -AudioBufferSourceNode::Stop(double aWhen, ErrorResult& aRv, bool aShuttingDown) +AudioBufferSourceNode::Stop(double aWhen, ErrorResult& aRv) { if (!WebAudioUtils::IsTimeValid(aWhen)) { aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); @@ -585,11 +584,10 @@ AudioBufferSourceNode::Stop(double aWhen, ErrorResult& aRv, bool aShuttingDown) return; } - if (!mBuffer || aShuttingDown) { + if (!mBuffer) { // We don't have a buffer, so the stream is never marked as finished. - // This can also happen if the AudioContext is being shut down. // Therefore we need to drop our playing ref right now. - mPlayingRef.Drop(this); + MarkInactive(); } AudioNodeStream* ns = static_cast(mStream.get()); @@ -633,7 +631,7 @@ AudioBufferSourceNode::NotifyMainThreadStateChanged() // Drop the playing reference // Warning: The below line might delete this. - mPlayingRef.Drop(this); + MarkInactive(); } } diff --git a/content/media/webaudio/AudioBufferSourceNode.h b/content/media/webaudio/AudioBufferSourceNode.h index 0f2b30f40922..a53097afdba2 100644 --- a/content/media/webaudio/AudioBufferSourceNode.h +++ b/content/media/webaudio/AudioBufferSourceNode.h @@ -56,7 +56,7 @@ public: duration.Construct(aDuration); Start(aWhen, aOffset, duration, aRv); } - void Stop(double aWhen, ErrorResult& aRv, bool aShuttingDown = false); + void Stop(double aWhen, ErrorResult& aRv); void NoteOff(double aWhen, ErrorResult& aRv) { Stop(aWhen, aRv); @@ -141,7 +141,6 @@ private: double mDuration; nsRefPtr mBuffer; nsRefPtr mPlaybackRate; - SelfReference mPlayingRef; // a reference to self while playing bool mLoop; bool mStartCalled; bool mStopped; diff --git a/content/media/webaudio/AudioContext.cpp b/content/media/webaudio/AudioContext.cpp index f70a25603920..a3b7a5565e5c 100644 --- a/content/media/webaudio/AudioContext.cpp +++ b/content/media/webaudio/AudioContext.cpp @@ -137,7 +137,6 @@ AudioContext::CreateBufferSource() { nsRefPtr bufferNode = new AudioBufferSourceNode(this); - mAudioBufferSourceNodes.PutEntry(bufferNode); return bufferNode.forget(); } @@ -459,7 +458,6 @@ AudioContext::UnregisterActiveNode(AudioNode* aNode) void AudioContext::UnregisterAudioBufferSourceNode(AudioBufferSourceNode* aNode) { - mAudioBufferSourceNodes.RemoveEntry(aNode); UpdatePannerSource(); } @@ -512,22 +510,6 @@ AudioContext::CurrentTime() const return MediaTimeToSeconds(Destination()->Stream()->GetCurrentTime()); } -template -static PLDHashOperator -GetHashtableEntry(nsPtrHashKey* aEntry, void* aData) -{ - nsTArray* array = static_cast*>(aData); - array->AppendElement(aEntry->GetKey()); - return PL_DHASH_NEXT; -} - -template -static void -GetHashtableElements(nsTHashtable >& aHashtable, nsTArray& aArray) -{ - aHashtable.EnumerateEntries(&GetHashtableEntry, &aArray); -} - void AudioContext::Shutdown() { @@ -540,19 +522,6 @@ AudioContext::Shutdown() // Node is already unregistered. mActiveNodes.Clear(); - // Stop all audio buffer source nodes, to make sure that they release - // their self-references. - // We first gather an array of the nodes and then call Stop on each one, - // since Stop may delete the object and therefore trigger a re-entrant - // hashtable call to remove the pointer from the hashtable, which is - // not safe. - nsTArray sourceNodes; - GetHashtableElements(mAudioBufferSourceNodes, sourceNodes); - for (uint32_t i = 0; i < sourceNodes.Length(); ++i) { - ErrorResult rv; - sourceNodes[i]->Stop(0.0, rv, true); - } - // For offline contexts, we can destroy the MediaStreamGraph at this point. if (mIsOffline && mDestination) { mDestination->OfflineShutdown(); diff --git a/content/media/webaudio/AudioContext.h b/content/media/webaudio/AudioContext.h index d699942925d8..c5a9d68ed796 100644 --- a/content/media/webaudio/AudioContext.h +++ b/content/media/webaudio/AudioContext.h @@ -255,11 +255,9 @@ private: // See RegisterActiveNode. These will keep the AudioContext alive while it // is rendering and the window remains alive. nsTHashtable > mActiveNodes; - // Two hashsets containing all the PannerNodes and AudioBufferSourceNodes, - // to compute the doppler shift, and also to stop AudioBufferSourceNodes. - // These are all weak pointers. + // Hashsets containing all the PannerNodes, to compute the doppler shift. + // These are weak pointers. nsTHashtable > mPannerNodes; - nsTHashtable > mAudioBufferSourceNodes; // Number of channels passed in the OfflineAudioContext ctor. uint32_t mNumberOfChannels; bool mIsOffline; From 9c5c00238e630a681a7b6a5c7abf7a01de14d47c Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Tue, 24 Sep 2013 13:47:30 +1200 Subject: [PATCH 021/160] b=914033 add cycle collection helpers for nsTHashtable and nsRefPtrHashKey r=khuey --HG-- extra : transplant_source : %5D%26%5C%A8%0A%AAg%FE%B57%F6%BChvl%FFg%F8%9E%C6 --- xpcom/glue/nsHashKeys.h | 10 ++++++++ xpcom/glue/nsTHashtable.h | 52 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/xpcom/glue/nsHashKeys.h b/xpcom/glue/nsHashKeys.h index d1e13a323b95..89bb2b5c017b 100644 --- a/xpcom/glue/nsHashKeys.h +++ b/xpcom/glue/nsHashKeys.h @@ -310,6 +310,16 @@ private: nsRefPtr mKey; }; +template +inline void +ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, + nsRefPtrHashKey& aField, + const char* aName, + uint32_t aFlags = 0) +{ + CycleCollectionNoteChild(aCallback, aField.GetKey(), aName, aFlags); +} + /** * hashkey wrapper using T* KeyType * diff --git a/xpcom/glue/nsTHashtable.h b/xpcom/glue/nsTHashtable.h index ed51972c90cb..ea828a3db09f 100644 --- a/xpcom/glue/nsTHashtable.h +++ b/xpcom/glue/nsTHashtable.h @@ -490,4 +490,56 @@ nsTHashtable::s_SizeOfStub(PLDHashEntryHdr *entry, reinterpret_cast(arg)->userArg); } +class nsCycleCollectionTraversalCallback; + +struct MOZ_STACK_CLASS nsTHashtableCCTraversalData +{ + nsTHashtableCCTraversalData(nsCycleCollectionTraversalCallback& aCallback, + const char* aName, + uint32_t aFlags) + : mCallback(aCallback), + mName(aName), + mFlags(aFlags) + { + } + + nsCycleCollectionTraversalCallback& mCallback; + const char* mName; + uint32_t mFlags; +}; + +template +PLDHashOperator +ImplCycleCollectionTraverse_EnumFunc(EntryType *aEntry, + void* aUserData) +{ + auto userData = static_cast(aUserData); + + ImplCycleCollectionTraverse(userData->mCallback, + *aEntry, + userData->mName, + userData->mFlags); + return PL_DHASH_NEXT; +} + +template +inline void +ImplCycleCollectionUnlink(nsTHashtable& aField) +{ + aField.Clear(); +} + +template +inline void +ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, + nsTHashtable& aField, + const char* aName, + uint32_t aFlags = 0) +{ + nsTHashtableCCTraversalData userData(aCallback, aName, aFlags); + + aField.EnumerateEntries(ImplCycleCollectionTraverse_EnumFunc, + &userData); +} + #endif // nsTHashtable_h__ From dda34e40518921aecdec2e09805923a16190bdc2 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Tue, 24 Sep 2013 13:47:30 +1200 Subject: [PATCH 022/160] b=914033 add active nodes to CC traversal of AudioContext when the context is not rendering r=ehsan An OfflineAudioContext needs to keep references to nodes that will be used if startRendering() is called. If, however, the last reference to the Context is removed, then startRendering() will not be called and so the nodes will not be used and can be unlinked now. --HG-- extra : transplant_source : %D4%91%0B%99K%2A%3E%906%1D%08%5D%60%84%B8%25O%3C%08D --- content/media/webaudio/AudioContext.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/content/media/webaudio/AudioContext.cpp b/content/media/webaudio/AudioContext.cpp index a3b7a5565e5c..e9361a14079e 100644 --- a/content/media/webaudio/AudioContext.cpp +++ b/content/media/webaudio/AudioContext.cpp @@ -38,8 +38,25 @@ namespace mozilla { namespace dom { -NS_IMPL_CYCLE_COLLECTION_INHERITED_2(AudioContext, nsDOMEventTargetHelper, - mDestination, mListener) +NS_IMPL_CYCLE_COLLECTION_CLASS(AudioContext) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AudioContext) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mDestination) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mListener) + if (!tmp->mIsStarted) { + NS_IMPL_CYCLE_COLLECTION_UNLINK(mActiveNodes) + } +NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(nsDOMEventTargetHelper) + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(AudioContext, nsDOMEventTargetHelper) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDestination) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mListener) + if (!tmp->mIsStarted) { + MOZ_ASSERT(tmp->mIsOffline, + "Online AudioContexts should always be started"); + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mActiveNodes) + } +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_ADDREF_INHERITED(AudioContext, nsDOMEventTargetHelper) NS_IMPL_RELEASE_INHERITED(AudioContext, nsDOMEventTargetHelper) From 718572341354cfbfa34eba541e65b6489a7359fd Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Tue, 24 Sep 2013 13:47:30 +1200 Subject: [PATCH 023/160] b=918212 make OscillatorNode a MainThreadListener for its stream so that ended is dispatched r=ehsan --HG-- extra : transplant_source : %9D%B8%82%B3%B1%99%C6%CE%1C%E1%DDs%D1%40%EA%E3%DD%D2%01%A4 --- content/media/test/crashtests/crashtests.list | 1 + .../media/test/crashtests/oscillator-ended-1.html | 15 +++++++++++++++ content/media/webaudio/OscillatorNode.cpp | 1 + 3 files changed, 17 insertions(+) create mode 100644 content/media/test/crashtests/oscillator-ended-1.html diff --git a/content/media/test/crashtests/crashtests.list b/content/media/test/crashtests/crashtests.list index de3c86cba68d..5d34d3ccc81f 100644 --- a/content/media/test/crashtests/crashtests.list +++ b/content/media/test/crashtests/crashtests.list @@ -56,3 +56,4 @@ load 907986-2.html load 907986-3.html load 907986-4.html load 910171-1.html +load oscillator-ended-1.html diff --git a/content/media/test/crashtests/oscillator-ended-1.html b/content/media/test/crashtests/oscillator-ended-1.html new file mode 100644 index 000000000000..831111261c16 --- /dev/null +++ b/content/media/test/crashtests/oscillator-ended-1.html @@ -0,0 +1,15 @@ + + + diff --git a/content/media/webaudio/OscillatorNode.cpp b/content/media/webaudio/OscillatorNode.cpp index c171e3437355..251eb61607c3 100644 --- a/content/media/webaudio/OscillatorNode.cpp +++ b/content/media/webaudio/OscillatorNode.cpp @@ -506,6 +506,7 @@ OscillatorNode::OscillatorNode(AudioContext* aContext) OscillatorNodeEngine* engine = new OscillatorNodeEngine(this, aContext->Destination()); mStream = aContext->Graph()->CreateAudioNodeStream(engine, MediaStreamGraph::SOURCE_STREAM); engine->SetSourceStream(static_cast (mStream.get())); + mStream->AddMainThreadListener(this); } OscillatorNode::~OscillatorNode() From 1eaf6984965cdbb4baa86d562fb22c130ca917e9 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Tue, 24 Sep 2013 13:48:35 +1200 Subject: [PATCH 024/160] b=918213 dispatch onended from OscillatorNode even when stop time is before start r=ehsan This makes OscillatorNode consistent with AudioBufferSourceNode --HG-- extra : transplant_source : %AE8%3B%B4%E5M%60%03%CBN.%21%BD%FF%60%A6%F2a%BDi --- content/media/test/crashtests/crashtests.list | 1 + .../media/test/crashtests/oscillator-ended-2.html | 15 +++++++++++++++ content/media/webaudio/OscillatorNode.cpp | 10 +++++----- 3 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 content/media/test/crashtests/oscillator-ended-2.html diff --git a/content/media/test/crashtests/crashtests.list b/content/media/test/crashtests/crashtests.list index 5d34d3ccc81f..53ac02f49ec2 100644 --- a/content/media/test/crashtests/crashtests.list +++ b/content/media/test/crashtests/crashtests.list @@ -57,3 +57,4 @@ load 907986-3.html load 907986-4.html load 910171-1.html load oscillator-ended-1.html +load oscillator-ended-2.html diff --git a/content/media/test/crashtests/oscillator-ended-2.html b/content/media/test/crashtests/oscillator-ended-2.html new file mode 100644 index 000000000000..ee9b8cf30084 --- /dev/null +++ b/content/media/test/crashtests/oscillator-ended-2.html @@ -0,0 +1,15 @@ + + + diff --git a/content/media/webaudio/OscillatorNode.cpp b/content/media/webaudio/OscillatorNode.cpp index 251eb61607c3..7e211c4aa5d4 100644 --- a/content/media/webaudio/OscillatorNode.cpp +++ b/content/media/webaudio/OscillatorNode.cpp @@ -424,17 +424,17 @@ public: return; } - if (ticks + WEBAUDIO_BLOCK_SIZE < mStart) { - // We're not playing yet. - ComputeSilence(aOutput); - return; - } if (ticks >= mStop) { // We've finished playing. ComputeSilence(aOutput); *aFinished = true; return; } + if (ticks + WEBAUDIO_BLOCK_SIZE < mStart) { + // We're not playing yet. + ComputeSilence(aOutput); + return; + } AllocateAudioBlock(1, aOutput); float* output = static_cast( From 4775d608a9d1d3ca5b0af827a64eac119f8629cf Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Tue, 24 Sep 2013 13:48:56 +1200 Subject: [PATCH 025/160] b=918221 don't remove OscillatorNode playing ref on stop() but wait until finished r=ehsan --HG-- extra : transplant_source : %A6%90%DB%00%FD5.%40%ED%F6l%17%E69E%D6%40%B5%EA%2A --- content/media/webaudio/OscillatorNode.cpp | 2 - content/media/webaudio/test/Makefile.in | 1 + .../webaudio/test/test_oscillatorNode2.html | 53 +++++++++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 content/media/webaudio/test/test_oscillatorNode2.html diff --git a/content/media/webaudio/OscillatorNode.cpp b/content/media/webaudio/OscillatorNode.cpp index 7e211c4aa5d4..ca6d3b0ab0f5 100644 --- a/content/media/webaudio/OscillatorNode.cpp +++ b/content/media/webaudio/OscillatorNode.cpp @@ -598,8 +598,6 @@ OscillatorNode::Stop(double aWhen, ErrorResult& aRv) return; } - MarkInactive(); - AudioNodeStream* ns = static_cast(mStream.get()); if (!ns || !Context()) { // We've already stopped and had our stream shut down diff --git a/content/media/webaudio/test/Makefile.in b/content/media/webaudio/test/Makefile.in index d664763ed7ee..371b73fc3590 100644 --- a/content/media/webaudio/test/Makefile.in +++ b/content/media/webaudio/test/Makefile.in @@ -75,6 +75,7 @@ MOCHITEST_FILES := \ test_offlineDestinationChannelCountLess.html \ test_offlineDestinationChannelCountMore.html \ test_oscillatorNode.html \ + test_oscillatorNode2.html \ test_oscillatorNodeStart.html \ test_pannerNode.html \ test_pannerNodeAbove.html \ diff --git a/content/media/webaudio/test/test_oscillatorNode2.html b/content/media/webaudio/test/test_oscillatorNode2.html new file mode 100644 index 000000000000..1ddae937c653 --- /dev/null +++ b/content/media/webaudio/test/test_oscillatorNode2.html @@ -0,0 +1,53 @@ + + + + Test OscillatorNode lifetime and sine phase + + + + +
    +
    +
    +
    + + From 4e8fd65215089ded68e09bb4a0b5bf1fdbe3a0bf Mon Sep 17 00:00:00 2001 From: Quentin Glidic Date: Sat, 14 Sep 2013 13:43:26 +0200 Subject: [PATCH 026/160] Bug 884708 - Port GTK2 to GTK3 - build failures r=karlt --HG-- extra : transplant_source : %82%22%F3%3FX%EE%80%ED%AA%14%28%92R6%0Cn%85%93%C8%3C --- .../components/jsdownloads/src/DownloadPlatform.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/toolkit/components/jsdownloads/src/DownloadPlatform.cpp b/toolkit/components/jsdownloads/src/DownloadPlatform.cpp index a7a2c7eb89c2..d59d91b84b5b 100644 --- a/toolkit/components/jsdownloads/src/DownloadPlatform.cpp +++ b/toolkit/components/jsdownloads/src/DownloadPlatform.cpp @@ -25,7 +25,7 @@ #include "AndroidBridge.h" #endif -#ifdef MOZ_WIDGET_GTK2 +#ifdef MOZ_WIDGET_GTK #include #endif @@ -43,7 +43,7 @@ DownloadPlatform* DownloadPlatform::GetDownloadPlatform() NS_ADDREF(gDownloadPlatformService); -#if defined(MOZ_WIDGET_GTK2) +#if defined(MOZ_WIDGET_GTK) g_type_init(); #endif @@ -67,10 +67,10 @@ static void gio_set_metadata_done(GObject *source_obj, GAsyncResult *res, gpoint nsresult DownloadPlatform::DownloadDone(nsIURI* aSource, nsIFile* aTarget, const nsACString& aContentType, bool aIsPrivate) { -#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK2) +#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK) nsAutoString path; if (aTarget && NS_SUCCEEDED(aTarget->GetPath(path))) { -#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK2) +#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) // On Windows and Gtk, add the download to the system's "recent documents" // list, with a pref to disable. { @@ -78,7 +78,7 @@ nsresult DownloadPlatform::DownloadDone(nsIURI* aSource, nsIFile* aTarget, if (addToRecentDocs && !aIsPrivate) { #ifdef XP_WIN ::SHAddToRecentDocs(SHARD_PATHW, path.get()); -#elif defined(MOZ_WIDGET_GTK2) +#elif defined(MOZ_WIDGET_GTK) GtkRecentManager* manager = gtk_recent_manager_get_default(); gchar* uri = g_filename_to_uri(NS_ConvertUTF16toUTF8(path).get(), From 90b6bec06ad2185e571c3fd54493522a419dd58e Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Thu, 22 Aug 2013 14:04:41 -0400 Subject: [PATCH 027/160] b=908306 revert 9df04b16a655 and 2e7089db4e86 to re-enable some b2g webaudio crashtests --HG-- extra : transplant_source : %F8%7E%F0%9Dr%2AV%09g%D4%2AX%D0iC%81n%22D%A5 --- content/media/test/crashtests/crashtests.list | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/content/media/test/crashtests/crashtests.list b/content/media/test/crashtests/crashtests.list index 53ac02f49ec2..15aaf9dba5b4 100644 --- a/content/media/test/crashtests/crashtests.list +++ b/content/media/test/crashtests/crashtests.list @@ -24,29 +24,29 @@ load 874952.html load 875144.html load 875596.html load 875911.html -skip-if(B2G) load 876024-1.html # timeout-prone, bug 908306 +load 876024-1.html load 876024-2.html -skip-if(B2G) load 876118.html # timeout-prone, bug 908306 +load 876118.html load 876207.html load 876215.html load 876249.html -skip-if(B2G) load 876252.html # timeout-prone, bug 908306 +load 876252.html load 876834.html -skip-if(B2G) load 877820.html # timeout-prone, bug 908306 -skip-if(B2G) load 878014.html # timeout-prone, bug 908306 +load 877820.html +load 878014.html load 878328.html load 878407.html -skip-if(B2G) load 878478.html # timeout-prone, bug 908306 +load 878478.html load 877527.html load 880129.html skip-if(B2G) test-pref(media.webaudio.enabled,true) load 880202.html # load failed, bug 908306 for B2G -skip-if(B2G) load 880342-1.html # timeout-prone, bug 908306 +load 880342-1.html load 880342-2.html load 880384.html -skip-if(B2G) load 880404.html # timeout-prone, bug 908306 -skip-if(B2G) load 880724.html # timeout-prone, bug 908306 +load 880404.html +load 880724.html load 881775.html -skip-if(B2G) load 882956.html # timeout-prone, bug 908306 +load 882956.html test-pref(media.webvtt.enabled,true) load 882549.html load 884459.html load 889042.html From 76191ed681f7a274a7d7eeb90a9b255a760babd4 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 23 Sep 2013 23:11:44 -0400 Subject: [PATCH 028/160] Bug 919103. Remove no longer needed goop that was making sure we set up expandos on the window with stub get/set hooks. Now we get that for free. r=bholley --- dom/base/nsDOMClassInfo.cpp | 65 ++----------------------------------- 1 file changed, 2 insertions(+), 63 deletions(-) diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 59859940534a..fe3ab8f9a8d0 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -3725,69 +3725,8 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, } } - rv = nsDOMGenericSH::NewResolve(wrapper, cx, obj, id, flags, objp, - _retval); - - if (NS_FAILED(rv) || *objp) { - // Something went wrong, or the property got resolved. Return. - return rv; - } - - // Make a fast expando if we're assigning to (not declaring or - // binding a name) a new undefined property that's not already - // defined on our prototype chain. This way we can access this - // expando w/o ever getting back into XPConnect. - if (flags & JSRESOLVE_ASSIGNING) { - JS::Rooted realObj(cx, wrapper->GetJSObject()); - - if (obj == realObj) { - JS::Rooted proto(cx); - if (!js::GetObjectProto(cx, obj, &proto)) { - *_retval = false; - return NS_OK; - } - if (proto) { - JS::Rooted pobj(cx); - JS::Rooted val(cx); - - if (!::JS_LookupPropertyWithFlagsById(cx, proto, id, flags, - pobj.address(), &val)) { - *_retval = false; - - return NS_OK; - } - - if (pobj) { - // A property was found on the prototype chain. - *objp = pobj; - return NS_OK; - } - } - - // Define a fast expando. The key here is to use JS_PropertyStub as the - // getter/setter, which makes us stay out of XPConnect when using this - // property. - // - // We're adding a new property here, so we don't need to worry about - // conflicting with any existing ones. - // - // Since we always create the undeclared property here, shortcutting the - // normal process, we go out of our way to tell the JS engine to report - // strict warnings/errors using js::ReportIfUndeclaredVarAssignment. - JS::Rooted str(cx, JSID_TO_STRING(id)); - if (!js::ReportIfUndeclaredVarAssignment(cx, str) || - !::JS_DefinePropertyById(cx, obj, id, JSVAL_VOID, JS_PropertyStub, - JS_StrictPropertyStub, JSPROP_ENUMERATE)) { - *_retval = false; - - return NS_OK; - } - - *objp = obj; - } - } - - return NS_OK; + return nsDOMGenericSH::NewResolve(wrapper, cx, obj, id, flags, objp, + _retval); } NS_IMETHODIMP From 9c0337475f2fd77f0135e67b507d7579aa447a02 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 23 Sep 2013 23:11:45 -0400 Subject: [PATCH 029/160] Bug 919114. ClientRectList should be [ArrayClass]. r=smaug --- dom/tests/mochitest/general/test_clientRects.html | 5 +++++ dom/webidl/ClientRectList.webidl | 1 + 2 files changed, 6 insertions(+) diff --git a/dom/tests/mochitest/general/test_clientRects.html b/dom/tests/mochitest/general/test_clientRects.html index de4a8bdfbb89..9fb5c63213cd 100644 --- a/dom/tests/mochitest/general/test_clientRects.html +++ b/dom/tests/mochitest/general/test_clientRects.html @@ -29,6 +29,11 @@ function doc(id) { function checkElement(id, list, eps, doc) { var e = (doc || document).getElementById(id); var clientRects = e.getClientRects(); + ok(clientRects instanceof e.ownerDocument.defaultView.Array, + "getClientRects retval should have Array.prototype on its proto chain"); + clientRects.map(function(rect) { + ok(rect instanceof ClientRect, "Should have a ClientRect here"); + }); is(clientRects.length, list.length, "getClientRects().length for element '" + id + "'"); var bounds = list.length > 0 ? list[0] : [0,0,0,0]; for (var i = 0; i < clientRects.length && i < list.length; ++i) { diff --git a/dom/webidl/ClientRectList.webidl b/dom/webidl/ClientRectList.webidl index 964425bd0f80..72e2786d3a6b 100644 --- a/dom/webidl/ClientRectList.webidl +++ b/dom/webidl/ClientRectList.webidl @@ -4,6 +4,7 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ +[ArrayClass] interface ClientRectList { readonly attribute unsigned long length; getter ClientRect? item(unsigned long index); From 283a0900a5cf6bed92b6ffb8f93e67d9ce182f9d Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 23 Sep 2013 23:11:45 -0400 Subject: [PATCH 030/160] Bug 919705. Don't ever claim that jsImplemented things are single-operation interfaces. r=mccr8 --- dom/bindings/parser/WebIDL.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index 6ee6b7b382a5..b47d985e3470 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -807,6 +807,9 @@ class IDLInterface(IDLObjectWithScope): def isSingleOperationInterface(self): assert self.isCallback() or self.isJSImplemented() return ( + # JS-implemented things should never need the + # this-handling weirdness of single-operation interfaces. + not self.isJSImplemented() and # Not inheriting from another interface not self.parent and # No consequential interfaces From 3491cda56060eed07c02d4f546f2aaeaefea6c60 Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Tue, 24 Sep 2013 12:55:46 +0900 Subject: [PATCH 031/160] Backout changeset 28aab9d91f12 (Bug 916071) --- layout/reftests/bugs/reftest.list | 2 +- layout/reftests/font-features/reftest.list | 2 +- layout/tools/reftest/reftest.js | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 1588b78325e1..fb011c824386 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1715,7 +1715,7 @@ skip-if(B2G) == 751012-1a.html 751012-1-ref.html skip-if(B2G) == 751012-1b.html 751012-1-ref.html random-if(Android) == 753329-1.html about:blank == 758561-1.html 758561-1-ref.html -fuzzy-if(true,1,19) fails-if(d2d&&!remoteFX) random-if(Android&&AndroidVersion<15) == 759036-1.html 759036-1-ref.html +fuzzy-if(true,1,19) fails-if(d2d) random-if(Android&&AndroidVersion<15) == 759036-1.html 759036-1-ref.html fuzzy-if(true,17,5860) random-if(Android&&AndroidVersion<15) == 759036-2.html 759036-2-ref.html == 776265-1a.html 776265-1-ref.html == 776265-1b.html 776265-1-ref.html diff --git a/layout/reftests/font-features/reftest.list b/layout/reftests/font-features/reftest.list index 73f01d7cc53f..7eebffa70f35 100644 --- a/layout/reftests/font-features/reftest.list +++ b/layout/reftests/font-features/reftest.list @@ -15,7 +15,7 @@ HTTP(..) != font-features-hlig.html font-features-ref.html # compare Turkish rendering with reference using ZWNJ to break the ligature # (also works via Pango) -fails-if(d2d&&!remoteFX) HTTP(..) == font-features-turkish.html font-features-turkish-ref.html +fails-if(d2d) HTTP(..) == font-features-turkish.html font-features-turkish-ref.html # compare Turkish rendering with explicitly disabled ligatures HTTP(..) == font-features-turkish.html font-features-noliga.html diff --git a/layout/tools/reftest/reftest.js b/layout/tools/reftest/reftest.js index f76c16cc9b43..85496601a856 100644 --- a/layout/tools/reftest/reftest.js +++ b/layout/tools/reftest/reftest.js @@ -584,7 +584,6 @@ function BuildConditionSandbox(aURL) { sandbox.azureQuartz = info.AzureCanvasBackend == "quartz"; sandbox.azureSkia = info.AzureCanvasBackend == "skia"; sandbox.azureSkiaGL = info.AzureSkiaAccelerated; // FIXME: assumes GL right now - sandbox.remoteFX = gfxInfo.adapterVendorID == "0x1414"; // true if we are using the same Azure backend for rendering canvas and content sandbox.contentSameGfxBackendAsCanvas = info.AzureContentBackend == info.AzureCanvasBackend || (info.AzureContentBackend == "none" && info.AzureCanvasBackend == "cairo"); From f0029d8a395d20e1ed50e304323271aa8b1f6c5b Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Mon, 23 Sep 2013 21:04:08 -0700 Subject: [PATCH 032/160] (no bug) Replace two c-style casts in nsFrame.cpp with const_cast<>. (no review; trivial/non-functional) --- layout/generic/nsFrame.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 4ba20a8dcf85..3cfda53e9b6d 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -2507,7 +2507,7 @@ nsFrame::IsSelectable(bool* aSelectable, uint8_t* aSelectStyle) const // AUTO -> CELL -> TEXT -> AUTO, the returned value is TEXT // uint8_t selectStyle = NS_STYLE_USER_SELECT_AUTO; - nsIFrame* frame = (nsIFrame*)this; + nsIFrame* frame = const_cast(this); while (frame) { const nsStyleUIReset* userinterface = frame->StyleUIReset(); @@ -4518,7 +4518,7 @@ NS_IMETHODIMP nsFrame::GetOffsetFromView(nsPoint& aOffset, nsView** aView) const { NS_PRECONDITION(nullptr != aView, "null OUT parameter pointer"); - nsIFrame* frame = (nsIFrame*)this; + nsIFrame* frame = const_cast(this); *aView = nullptr; aOffset.MoveTo(0, 0); From 748068529412958ec15eb6fcb7d210186d9b9588 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 24 Sep 2013 00:04:36 -0400 Subject: [PATCH 033/160] Bug 916535. Avoid using repeating gradients for tiling when it won't work. r=roc Avoiding normalization introduced in bug 895135 caused gradientStart/Stop to not correspond to the firstStop and lastStop. This can cause us to incorrectly decide to use the repeat fast path. This patch switches takes us back to the same condition as we had before the regression. --HG-- extra : rebase_source : f335e1db9166213115354eb14dbe90b09127a68b --- layout/base/nsCSSRendering.cpp | 11 +++++--- ...g-916535-background-repeat-linear-ref.html | 24 ++++++++++++++++++ .../bug-916535-background-repeat-linear.html | 25 +++++++++++++++++++ layout/reftests/css-gradients/reftest.list | 1 + 4 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 layout/reftests/css-gradients/bug-916535-background-repeat-linear-ref.html create mode 100644 layout/reftests/css-gradients/bug-916535-background-repeat-linear.html diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index a6b17bf1962e..cc0e5ed939d1 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -2354,6 +2354,8 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext, // stops have been normalized. gfxPoint gradientStart = lineStart + (lineEnd - lineStart)*stopOrigin; gfxPoint gradientEnd = lineStart + (lineEnd - lineStart)*stopEnd; + gfxPoint gradientStopStart = lineStart + (lineEnd - lineStart)*firstStop; + gfxPoint gradientStopEnd = lineStart + (lineEnd - lineStart)*lastStop; if (stopDelta == 0.0) { // Stops are all at the same place. For repeating gradients, this will @@ -2363,6 +2365,7 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext, // our stops will be at 0.0; we just need to set the direction vector // correctly. gradientEnd = gradientStart + (lineEnd - lineStart); + gradientStopEnd = gradientStopStart + (lineEnd - lineStart); } gradientPattern = new gfxPattern(gradientStart.x, gradientStart.y, @@ -2372,10 +2375,10 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext, // to the right edge of a tile, then we can repeat by just repeating the // gradient. if (!cellContainsFill && - ((gradientStart.y == gradientEnd.y && gradientStart.x == 0 && - gradientEnd.x == oneCellArea.width) || - (gradientStart.x == gradientEnd.x && gradientStart.y == 0 && - gradientEnd.y == oneCellArea.height))) { + ((gradientStopStart.y == gradientStopEnd.y && gradientStopStart.x == 0 && + gradientStopEnd.x == oneCellArea.width) || + (gradientStopStart.x == gradientStopEnd.x && gradientStopStart.y == 0 && + gradientStopEnd.y == oneCellArea.height))) { forceRepeatToCoverTiles = true; } } else { diff --git a/layout/reftests/css-gradients/bug-916535-background-repeat-linear-ref.html b/layout/reftests/css-gradients/bug-916535-background-repeat-linear-ref.html new file mode 100644 index 000000000000..c4c0a8b9cde8 --- /dev/null +++ b/layout/reftests/css-gradients/bug-916535-background-repeat-linear-ref.html @@ -0,0 +1,24 @@ + + + + + + Grid + + + + +
    +
    +
    +
    +
    +
    + + diff --git a/layout/reftests/css-gradients/bug-916535-background-repeat-linear.html b/layout/reftests/css-gradients/bug-916535-background-repeat-linear.html new file mode 100644 index 000000000000..995c9e04100a --- /dev/null +++ b/layout/reftests/css-gradients/bug-916535-background-repeat-linear.html @@ -0,0 +1,25 @@ + + + + + + Grid + + + + +
    + + diff --git a/layout/reftests/css-gradients/reftest.list b/layout/reftests/css-gradients/reftest.list index aed1a8a20aad..62c121395b1a 100644 --- a/layout/reftests/css-gradients/reftest.list +++ b/layout/reftests/css-gradients/reftest.list @@ -136,3 +136,4 @@ fuzzy-if(d2d,47,400) == linear-onestopposition-1.html linear-onestopposition-1-r == repeating-radial-onestopposition-1a.html orange-square.html == repeating-radial-onestopposition-1b.html orange-square.html == repeating-radial-onestopposition-1c.html orange-square.html +== bug-916535-background-repeat-linear.html bug-916535-background-repeat-linear-ref.html From db212c03af9b67775a1734bca92bc490a75c9531 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Tue, 24 Sep 2013 01:30:27 -0500 Subject: [PATCH 034/160] Bug 862602. Turn on image visibility for android so we don't keep all images in foreground tab locked. r=kats --- mobile/android/app/mobile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index d089e4bea51e..000e442e88da 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -719,7 +719,7 @@ pref("app.orientation.default", ""); // back to the system. pref("memory.free_dirty_pages", true); -pref("layout.imagevisibility.enabled", false); +pref("layout.imagevisibility.enabled", true); pref("layout.imagevisibility.numscrollportwidths", 1); pref("layout.imagevisibility.numscrollportheights", 1); From ab5d701cfb478e5d7d2c4b28246801c27b8a6f69 Mon Sep 17 00:00:00 2001 From: Victor Porof Date: Mon, 23 Sep 2013 20:00:03 +0300 Subject: [PATCH 035/160] Bug 860349 - Don't do a thread dispatch when performing the test in browser_dbg_chrome-create, r=me --- .../test/browser_dbg_chrome-create.js | 64 +++++++++---------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/browser/devtools/debugger/test/browser_dbg_chrome-create.js b/browser/devtools/debugger/test/browser_dbg_chrome-create.js index 50cbadb24ba2..b704943d2389 100644 --- a/browser/devtools/debugger/test/browser_dbg_chrome-create.js +++ b/browser/devtools/debugger/test/browser_dbg_chrome-create.js @@ -23,46 +23,44 @@ function test() { } function performTest() { - Services.tm.currentThread.dispatch({ run: function() { - ok(gProcess._dbgProcess, - "The remote debugger process wasn't created properly!"); - ok(gProcess._dbgProcess.isRunning, - "The remote debugger process isn't running!"); - is(typeof gProcess._dbgProcess.pid, "number", - "The remote debugger process doesn't have a pid (?!)"); + ok(gProcess._dbgProcess, + "The remote debugger process wasn't created properly!"); + ok(gProcess._dbgProcess.isRunning, + "The remote debugger process isn't running!"); + is(typeof gProcess._dbgProcess.pid, "number", + "The remote debugger process doesn't have a pid (?!)"); - info("process location: " + gProcess._dbgProcess.location); - info("process pid: " + gProcess._dbgProcess.pid); - info("process name: " + gProcess._dbgProcess.processName); - info("process sig: " + gProcess._dbgProcess.processSignature); + info("process location: " + gProcess._dbgProcess.location); + info("process pid: " + gProcess._dbgProcess.pid); + info("process name: " + gProcess._dbgProcess.processName); + info("process sig: " + gProcess._dbgProcess.processSignature); - ok(gProcess._dbgProfile, - "The remote debugger profile wasn't created properly!"); - ok(gProcess._dbgProfile.localDir, - "The remote debugger profile doesn't have a localDir..."); - ok(gProcess._dbgProfile.rootDir, - "The remote debugger profile doesn't have a rootDir..."); - ok(gProcess._dbgProfile.name, - "The remote debugger profile doesn't have a name..."); + ok(gProcess._dbgProfile, + "The remote debugger profile wasn't created properly!"); + ok(gProcess._dbgProfile.localDir, + "The remote debugger profile doesn't have a localDir..."); + ok(gProcess._dbgProfile.rootDir, + "The remote debugger profile doesn't have a rootDir..."); + ok(gProcess._dbgProfile.name, + "The remote debugger profile doesn't have a name..."); - info("profile localDir: " + gProcess._dbgProfile.localDir.path); - info("profile rootDir: " + gProcess._dbgProfile.rootDir.path); - info("profile name: " + gProcess._dbgProfile.name); + info("profile localDir: " + gProcess._dbgProfile.localDir.path); + info("profile rootDir: " + gProcess._dbgProfile.rootDir.path); + info("profile name: " + gProcess._dbgProfile.name); - let profileService = Cc["@mozilla.org/toolkit/profile-service;1"] - .createInstance(Ci.nsIToolkitProfileService); + let profileService = Cc["@mozilla.org/toolkit/profile-service;1"] + .createInstance(Ci.nsIToolkitProfileService); - let profile = profileService.getProfileByName(gProcess._dbgProfile.name); + let profile = profileService.getProfileByName(gProcess._dbgProfile.name); - ok(profile, - "The remote debugger profile wasn't *actually* created properly!"); - is(profile.localDir.path, gProcess._dbgProfile.localDir.path, - "The remote debugger profile doesn't have the correct localDir!"); - is(profile.rootDir.path, gProcess._dbgProfile.rootDir.path, - "The remote debugger profile doesn't have the correct rootDir!"); + ok(profile, + "The remote debugger profile wasn't *actually* created properly!"); + is(profile.localDir.path, gProcess._dbgProfile.localDir.path, + "The remote debugger profile doesn't have the correct localDir!"); + is(profile.rootDir.path, gProcess._dbgProfile.rootDir.path, + "The remote debugger profile doesn't have the correct rootDir!"); - gProcess.close(); - }}, 0); + gProcess.close(); } function aOnClose() { From 34c888b0809e7c918839155d4c116e84b966dc9c Mon Sep 17 00:00:00 2001 From: Victor Porof Date: Tue, 24 Sep 2013 11:11:17 +0300 Subject: [PATCH 036/160] Bug 916747 - Request longer timeout for browser_dbg_breakpoints-contextmenu.js, r=me --- .../debugger/test/browser_dbg_breakpoints-contextmenu.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu.js b/browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu.js index 17ed9406d9e3..9e32b3132c1e 100644 --- a/browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu.js +++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu.js @@ -8,6 +8,9 @@ const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; function test() { + // Debug test slaves are a bit slow at this test. + requestLongerTimeout(2); + let gTab, gDebuggee, gPanel, gDebugger; let gEditor, gSources, gBreakpoints; From 1fc20ea7ab1347b59c45c3cc00d32d5a6f3cf634 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Tue, 24 Sep 2013 10:26:07 +0200 Subject: [PATCH 037/160] Backed out changeset f9fd3a1b03ed (bug 911678) for suspicion of causing nearly perma-orange on OSX Mochi-Browser Chome Tests --- browser/devtools/inspector/inspector-panel.js | 9 -- .../test/browser_inspector_changes.js | 95 +++-------- browser/devtools/markupview/markup-view.js | 10 -- browser/devtools/styleinspector/rule-view.js | 4 +- .../test/browser_ruleview_update.js | 150 ++++++++---------- 5 files changed, 84 insertions(+), 184 deletions(-) diff --git a/browser/devtools/inspector/inspector-panel.js b/browser/devtools/inspector/inspector-panel.js index 600b750295fd..d72fc2a16844 100644 --- a/browser/devtools/inspector/inspector-panel.js +++ b/browser/devtools/inspector/inspector-panel.js @@ -729,15 +729,6 @@ InspectorPanel.prototype = { } }, - /** - * Trigger a high-priority layout change for things that need to be - * updated immediately - */ - immediateLayoutChange: function Inspector_immediateLayoutChange() - { - this.emit("layout-change"); - }, - /** * Schedule a low-priority change event for things like paint * and resize. diff --git a/browser/devtools/inspector/test/browser_inspector_changes.js b/browser/devtools/inspector/test/browser_inspector_changes.js index 487666bc658b..268712426382 100644 --- a/browser/devtools/inspector/test/browser_inspector_changes.js +++ b/browser/devtools/inspector/test/browser_inspector_changes.js @@ -17,7 +17,7 @@ function test() { } - function getInspectorComputedProp(aName) + function getInspectorProp(aName) { let computedview = inspector.sidebar.getWindowForTab("computedview").computedview.view; for each (let view in computedview.propertyViews) { @@ -27,18 +27,6 @@ function test() { } return null; } - function getInspectorRuleProp(aName) - { - let ruleview = inspector.sidebar.getWindowForTab("ruleview").ruleview.view; - let inlineStyles = ruleview._elementStyle.rules[0]; - - for each (let prop in inlineStyles.textProps) { - if (prop.name == aName) { - return prop; - } - } - return null; - } function runInspectorTests(aInspector) { @@ -52,93 +40,50 @@ function test() { testDiv.style.fontSize = "10px"; // Start up the style inspector panel... - inspector.once("computed-view-refreshed", computedStylePanelTests); + inspector.once("computed-view-refreshed", stylePanelTests); inspector.selection.setNode(testDiv); }); } - function computedStylePanelTests() + function stylePanelTests() { let computedview = inspector.sidebar.getWindowForTab("computedview").computedview; ok(computedview, "Style Panel has a cssHtmlTree"); - let propView = getInspectorComputedProp("font-size"); + let propView = getInspectorProp("font-size"); is(propView.value, "10px", "Style inspector should be showing the correct font size."); - inspector.once("computed-view-refreshed", computedStylePanelAfterChange); + inspector.once("computed-view-refreshed", stylePanelAfterChange); - testDiv.style.cssText = "font-size: 15px; color: red;"; + testDiv.style.fontSize = "15px"; + inspector.emit("layout-change"); } - function computedStylePanelAfterChange() + function stylePanelAfterChange() { - let propView = getInspectorComputedProp("font-size"); + let propView = getInspectorProp("font-size"); is(propView.value, "15px", "Style inspector should be showing the new font size."); - let propView = getInspectorComputedProp("color"); - is(propView.value, "#F00", "Style inspector should be showing the new color."); - - computedStylePanelNotActive(); + stylePanelNotActive(); } - function computedStylePanelNotActive() + function stylePanelNotActive() { // Tests changes made while the style panel is not active. inspector.sidebar.select("ruleview"); - testDiv.style.fontSize = "20px"; - testDiv.style.color = "blue"; - testDiv.style.textAlign = "center"; - inspector.once("computed-view-refreshed", computedStylePanelAfterSwitch); - inspector.sidebar.select("computedview"); + + executeSoon(function() { + inspector.once("computed-view-refreshed", stylePanelAfterSwitch); + testDiv.style.fontSize = "20px"; + inspector.sidebar.select("computedview"); + }); } - function computedStylePanelAfterSwitch() + function stylePanelAfterSwitch() { - let propView = getInspectorComputedProp("font-size"); - is(propView.value, "20px", "Style inspector should be showing the new font size."); - - let propView = getInspectorComputedProp("color"); - is(propView.value, "#00F", "Style inspector should be showing the new color."); - - let propView = getInspectorComputedProp("text-align"); - is(propView.value, "center", "Style inspector should be showing the new text align."); - - rulePanelTests(); - } - - function rulePanelTests() - { - inspector.sidebar.select("ruleview"); - let ruleview = inspector.sidebar.getWindowForTab("ruleview").ruleview; - ok(ruleview, "Style Panel has a ruleview"); - - let propView = getInspectorRuleProp("text-align"); - is(propView.value, "center", "Style inspector should be showing the new text align."); - - testDiv.style.textAlign = "right"; - testDiv.style.color = "lightgoldenrodyellow"; - testDiv.style.fontSize = "3em"; - testDiv.style.textTransform = "uppercase"; - - - inspector.once("rule-view-refreshed", rulePanelAfterChange); - - } - - function rulePanelAfterChange() - { - let propView = getInspectorRuleProp("text-align"); - is(propView.value, "right", "Style inspector should be showing the new text align."); - - let propView = getInspectorRuleProp("color"); - is(propView.value, "#FAFAD2", "Style inspector should be showing the new color.") - - let propView = getInspectorRuleProp("font-size"); - is(propView.value, "3em", "Style inspector should be showing the new font size."); - - let propView = getInspectorRuleProp("text-transform"); - is(propView.value, "uppercase", "Style inspector should be showing the new text transform."); + let propView = getInspectorProp("font-size"); + is(propView.value, "20px", "Style inspector should be showing the newest font size."); finishTest(); } diff --git a/browser/devtools/markupview/markup-view.js b/browser/devtools/markupview/markup-view.js index 23d6b33f4bfb..c11e499cd107 100644 --- a/browser/devtools/markupview/markup-view.js +++ b/browser/devtools/markupview/markup-view.js @@ -397,7 +397,6 @@ MarkupView.prototype = { */ _mutationObserver: function MT__mutationObserver(aMutations) { - let requiresLayoutChange = false; for (let mutation of aMutations) { let type = mutation.type; let target = mutation.target; @@ -420,11 +419,6 @@ MarkupView.prototype = { } if (type === "attributes" || type === "characterData") { container.update(false); - - // Auto refresh style properties on selected node when they change. - if (type === "attributes" && container.selected) { - requiresLayoutChange = true; - } } else if (type === "childList") { container.childrenDirty = true; // Update the children to take care of changes in the DOM @@ -433,10 +427,6 @@ MarkupView.prototype = { this._updateChildren(container, {flash: true}); } } - - if (requiresLayoutChange) { - this._inspector.immediateLayoutChange(); - } this._waitForChildren().then(() => { this._flashMutatedNodes(aMutations); this._inspector.emit("markupmutation"); diff --git a/browser/devtools/styleinspector/rule-view.js b/browser/devtools/styleinspector/rule-view.js index 3c09c2362e39..82141940ffdc 100644 --- a/browser/devtools/styleinspector/rule-view.js +++ b/browser/devtools/styleinspector/rule-view.js @@ -1283,13 +1283,13 @@ CssRuleView.prototype = { { // Ignore refreshes during editing or when no element is selected. if (this.isEditing || !this._elementStyle) { - return; + return promise.resolve(null); } this._clearRules(); // Repopulate the element style. - this._populate(); + return this._populate(); }, _populate: function() { diff --git a/browser/devtools/styleinspector/test/browser_ruleview_update.js b/browser/devtools/styleinspector/test/browser_ruleview_update.js index d4b6dc0bcc97..92a3d557cbab 100644 --- a/browser/devtools/styleinspector/test/browser_ruleview_update.js +++ b/browser/devtools/styleinspector/test/browser_ruleview_update.js @@ -7,7 +7,6 @@ let doc; let inspector; let ruleView; let testElement; -let rule; function startTest(aInspector, aRuleView) { @@ -44,29 +43,25 @@ function testRuleChanges() is(selectors[2].textContent.indexOf(".testclass"), 0, "Third item is class rule."); // Change the id and refresh. - inspector.once("rule-view-refreshed", testRuleChange1); testElement.setAttribute("id", "differentid"); -} + promiseDone(ruleView.nodeChanged().then(() => { + let selectors = ruleView.doc.querySelectorAll(".ruleview-selector"); + is(selectors.length, 2, "Two rules visible."); + is(selectors[0].textContent.indexOf("element"), 0, "First item is inline style."); + is(selectors[1].textContent.indexOf(".testclass"), 0, "Second item is class rule."); -function testRuleChange1() -{ - let selectors = ruleView.doc.querySelectorAll(".ruleview-selector"); - is(selectors.length, 2, "Two rules visible."); - is(selectors[0].textContent.indexOf("element"), 0, "First item is inline style."); - is(selectors[1].textContent.indexOf(".testclass"), 0, "Second item is class rule."); + testElement.setAttribute("id", "testid"); + return ruleView.nodeChanged(); + }).then(() => { + // Put the id back. + let selectors = ruleView.doc.querySelectorAll(".ruleview-selector"); + is(selectors.length, 3, "Three rules visible."); + is(selectors[0].textContent.indexOf("element"), 0, "First item is inline style."); + is(selectors[1].textContent.indexOf("#testid"), 0, "Second item is id rule."); + is(selectors[2].textContent.indexOf(".testclass"), 0, "Third item is class rule."); - inspector.once("rule-view-refreshed", testRuleChange2); - testElement.setAttribute("id", "testid"); -} -function testRuleChange2() -{ - let selectors = ruleView.doc.querySelectorAll(".ruleview-selector"); - is(selectors.length, 3, "Three rules visible."); - is(selectors[0].textContent.indexOf("element"), 0, "First item is inline style."); - is(selectors[1].textContent.indexOf("#testid"), 0, "Second item is id rule."); - is(selectors[2].textContent.indexOf(".testclass"), 0, "Third item is class rule."); - - testPropertyChanges(); + testPropertyChanges(); + })); } function validateTextProp(aProp, aEnabled, aName, aValue, aDesc) @@ -82,86 +77,65 @@ function validateTextProp(aProp, aEnabled, aName, aValue, aDesc) function testPropertyChanges() { - rule = ruleView._elementStyle.rules[0]; - let ruleEditor = ruleView._elementStyle.rules[0].editor; - inspector.once("rule-view-refreshed", testPropertyChange0); - // Add a second margin-top value, just to make things interesting. + let rule = ruleView._elementStyle.rules[0]; + let ruleEditor = ruleView._elementStyle.rules[0].editor; ruleEditor.addProperty("margin-top", "5px", ""); -} + promiseDone(expectRuleChange(rule).then(() => { + // Set the element style back to a 1px margin-top. + testElement.setAttribute("style", "margin-top: 1px; padding-top: 5px"); + return ruleView.nodeChanged(); + }).then(() => { + is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties"); + validateTextProp(rule.textProps[0], true, "margin-top", "1px", "First margin property re-enabled"); + validateTextProp(rule.textProps[2], false, "margin-top", "5px", "Second margin property disabled"); -function testPropertyChange0() -{ - validateTextProp(rule.textProps[0], false, "margin-top", "1px", "Original margin property active"); + // Now set it back to 5px, the 5px value should be re-enabled. + testElement.setAttribute("style", "margin-top: 5px; padding-top: 5px;"); + return ruleView.nodeChanged(); - inspector.once("rule-view-refreshed", testPropertyChange1); - testElement.setAttribute("style", "margin-top: 1px; padding-top: 5px"); -} -function testPropertyChange1() -{ - is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties"); - validateTextProp(rule.textProps[0], true, "margin-top", "1px", "First margin property re-enabled"); - validateTextProp(rule.textProps[2], false, "margin-top", "5px", "Second margin property disabled"); + }).then(() => { + is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties"); + validateTextProp(rule.textProps[0], false, "margin-top", "1px", "First margin property re-enabled"); + validateTextProp(rule.textProps[2], true, "margin-top", "5px", "Second margin property disabled"); - inspector.once("rule-view-refreshed", testPropertyChange2); + // Set the margin property to a value that doesn't exist in the editor. + // Should reuse the currently-enabled element (the second one.) + testElement.setAttribute("style", "margin-top: 15px; padding-top: 5px;"); + return ruleView.nodeChanged(); + }).then(() => { + is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties"); + validateTextProp(rule.textProps[0], false, "margin-top", "1px", "First margin property re-enabled"); + validateTextProp(rule.textProps[2], true, "margin-top", "15px", "Second margin property disabled"); - // Now set it back to 5px, the 5px value should be re-enabled. - testElement.setAttribute("style", "margin-top: 5px; padding-top: 5px;"); -} -function testPropertyChange2() -{ - is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties"); - validateTextProp(rule.textProps[0], false, "margin-top", "1px", "First margin property re-enabled"); - validateTextProp(rule.textProps[2], true, "margin-top", "5px", "Second margin property disabled"); + // Remove the padding-top attribute. Should disable the padding property but not remove it. + testElement.setAttribute("style", "margin-top: 5px;"); + return ruleView.nodeChanged(); + }).then(() => { + is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties"); + validateTextProp(rule.textProps[1], false, "padding-top", "5px", "Padding property disabled"); - inspector.once("rule-view-refreshed", testPropertyChange3); + // Put the padding-top attribute back in, should re-enable the padding property. + testElement.setAttribute("style", "margin-top: 5px; padding-top: 25px"); + return ruleView.nodeChanged(); + }).then(() => { + is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties"); + validateTextProp(rule.textProps[1], true, "padding-top", "25px", "Padding property enabled"); - // Set the margin property to a value that doesn't exist in the editor. - // Should reuse the currently-enabled element (the second one.) - testElement.setAttribute("style", "margin-top: 15px; padding-top: 5px;"); -} -function testPropertyChange3() -{ - is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties"); - validateTextProp(rule.textProps[0], false, "margin-top", "1px", "First margin property re-enabled"); - validateTextProp(rule.textProps[2], true, "margin-top", "15px", "Second margin property disabled"); + // Add an entirely new property. + testElement.setAttribute("style", "margin-top: 5px; padding-top: 25px; padding-left: 20px;"); + return ruleView.nodeChanged(); + }).then(() => { + is(rule.editor.element.querySelectorAll(".ruleview-property").length, 4, "Added a property"); + validateTextProp(rule.textProps[3], true, "padding-left", "20px", "Padding property enabled"); - inspector.once("rule-view-refreshed", testPropertyChange4); - - // Remove the padding-top attribute. Should disable the padding property but not remove it. - testElement.setAttribute("style", "margin-top: 5px;"); -} -function testPropertyChange4() -{ - is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties"); - validateTextProp(rule.textProps[1], false, "padding-top", "5px", "Padding property disabled"); - - inspector.once("rule-view-refreshed", testPropertyChange5); - - // Put the padding-top attribute back in, should re-enable the padding property. - testElement.setAttribute("style", "margin-top: 5px; padding-top: 25px"); -} -function testPropertyChange5() -{ - is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties"); - validateTextProp(rule.textProps[1], true, "padding-top", "25px", "Padding property enabled"); - - inspector.once("rule-view-refreshed", testPropertyChange6); - - // Add an entirely new property - testElement.setAttribute("style", "margin-top: 5px; padding-top: 25px; padding-left: 20px;"); -} -function testPropertyChange6() -{ - is(rule.editor.element.querySelectorAll(".ruleview-property").length, 4, "Added a property"); - validateTextProp(rule.textProps[3], true, "padding-left", "20px", "Padding property enabled"); - - finishTest(); + finishTest(); + })); } function finishTest() { - inspector = ruleView = rule = null; + inspector = ruleView = null; doc = null; gBrowser.removeCurrentTab(); finish(); From 6fb25a94f8f611d898175d3e57b26a9c7fc813dc Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 24 Sep 2013 10:39:58 +0200 Subject: [PATCH 038/160] Bug 919479 - cairo fails to compile on mingw r=BenWa --- gfx/cairo/cairo/src/cairo-win32-surface.c | 2 +- gfx/cairo/cairo/src/cairo-win32.h | 1 + gfx/cairo/win32-d3dsurface9.patch | 7 ++++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c index 7358cd62265e..e14705b22355 100644 --- a/gfx/cairo/cairo/src/cairo-win32-surface.c +++ b/gfx/cairo/cairo/src/cairo-win32-surface.c @@ -59,7 +59,7 @@ #include "cairo-private.h" #include #include -#include +#include #if defined(__MINGW32__) && !defined(ETO_PDY) # define ETO_PDY 0x2000 diff --git a/gfx/cairo/cairo/src/cairo-win32.h b/gfx/cairo/cairo/src/cairo-win32.h index 5330a954d1ac..07f7cc8e47bc 100644 --- a/gfx/cairo/cairo/src/cairo-win32.h +++ b/gfx/cairo/cairo/src/cairo-win32.h @@ -147,6 +147,7 @@ cairo_dwrite_get_cleartype_rendering_mode(); #endif /* CAIRO_HAS_DWRITE_FONT */ +struct IDirect3DSurface9; cairo_public cairo_surface_t * cairo_win32_surface_create_with_d3dsurface9 (struct IDirect3DSurface9 *surface); diff --git a/gfx/cairo/win32-d3dsurface9.patch b/gfx/cairo/win32-d3dsurface9.patch index 92d0244be290..b0e80252fc5e 100644 --- a/gfx/cairo/win32-d3dsurface9.patch +++ b/gfx/cairo/win32-d3dsurface9.patch @@ -74,7 +74,7 @@ diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cai #include "cairo-private.h" #include #include -+#include ++#include #if defined(__MINGW32__) && !defined(ETO_PDY) # define ETO_PDY 0x2000 @@ -423,7 +423,7 @@ diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cai diff --git a/gfx/cairo/cairo/src/cairo-win32.h b/gfx/cairo/cairo/src/cairo-win32.h --- a/gfx/cairo/cairo/src/cairo-win32.h +++ b/gfx/cairo/cairo/src/cairo-win32.h -@@ -59,17 +59,16 @@ cairo_win32_surface_create_with_ddb (HDC +@@ -59,17 +59,16 @@ cairo_win32_surface_create_with_ddb (HDC hdc, cairo_format_t format, int width, int height); @@ -441,7 +441,7 @@ diff --git a/gfx/cairo/cairo/src/cairo-win32.h b/gfx/cairo/cairo/src/cairo-win32 cairo_public cairo_surface_t * cairo_win32_surface_get_image (cairo_surface_t *surface); -@@ -143,16 +142,20 @@ cairo_dwrite_scaled_font_get_force_GDI_c +@@ -143,16 +142,21 @@ cairo_dwrite_scaled_font_get_force_GDI_classic(cairo_scaled_font_t *dwrite_scale void cairo_dwrite_set_cleartype_params(FLOAT gamma, FLOAT contrast, FLOAT level, int geometry, int mode); @@ -450,6 +450,7 @@ diff --git a/gfx/cairo/cairo/src/cairo-win32.h b/gfx/cairo/cairo/src/cairo-win32 #endif /* CAIRO_HAS_DWRITE_FONT */ ++struct IDirect3DSurface9; +cairo_public cairo_surface_t * +cairo_win32_surface_create_with_d3dsurface9 (struct IDirect3DSurface9 *surface); + From 9b7c9a242a67a33a5400ae0fa54e84152705071c Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 24 Sep 2013 10:40:25 +0200 Subject: [PATCH 039/160] Bug 883522 - undef GetMessage in nsIDOMGeoPositionError.idl to avoid conflicts with PSDK headers. --- dom/interfaces/geolocation/nsIDOMGeoPositionError.idl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dom/interfaces/geolocation/nsIDOMGeoPositionError.idl b/dom/interfaces/geolocation/nsIDOMGeoPositionError.idl index f01aa8dd5258..2dedc0ebc32c 100644 --- a/dom/interfaces/geolocation/nsIDOMGeoPositionError.idl +++ b/dom/interfaces/geolocation/nsIDOMGeoPositionError.idl @@ -5,6 +5,13 @@ #include "domstubs.idl" +// undef the GetMessage macro defined in winuser.h from the MS Platform SDK +%{C++ +#ifdef GetMessage +#undef GetMessage +#endif +%} + [scriptable, uuid(85255CC3-07BA-49FD-BC9B-18D2963DAF7F)] interface nsIDOMGeoPositionError : nsISupports { From a78e1fb9badee756e73072e558056124dfcc63a6 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 24 Sep 2013 10:41:00 +0200 Subject: [PATCH 040/160] Bug 919513 - content/media/directshow fails to compile on GCC. r=cpearce --- content/media/directshow/DirectShowReader.h | 2 +- content/media/directshow/DirectShowUtils.cpp | 6 +++--- content/media/directshow/SourceFilter.cpp | 11 +++++++++-- content/media/directshow/SourceFilter.h | 5 +++++ .../webrtc/modules/video_capture/windows/BaseFilter.h | 9 +++++++++ .../webrtc/modules/video_capture/windows/BasePin.h | 9 +++++++++ 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/content/media/directshow/DirectShowReader.h b/content/media/directshow/DirectShowReader.h index 5d02134fe62e..bece4ed811a9 100644 --- a/content/media/directshow/DirectShowReader.h +++ b/content/media/directshow/DirectShowReader.h @@ -7,7 +7,7 @@ #if !defined(DirectShowReader_h_) #define DirectShowReader_h_ -#include "Windows.h" // HRESULT, DWORD +#include "windows.h" // HRESULT, DWORD #include "MediaDecoderReader.h" #include "mozilla/RefPtr.h" #include "MP3FrameParser.h" diff --git a/content/media/directshow/DirectShowUtils.cpp b/content/media/directshow/DirectShowUtils.cpp index 9e519f6cfe52..bf99089d4afa 100644 --- a/content/media/directshow/DirectShowUtils.cpp +++ b/content/media/directshow/DirectShowUtils.cpp @@ -4,9 +4,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "dshow.h" -#include "Dmodshow.h" -#include "Wmcodecdsp.h" -#include "Dmoreg.h" +#include "dmodshow.h" +#include "wmcodecdsp.h" +#include "dmoreg.h" #include "DirectShowUtils.h" #include "nsAutoPtr.h" #include "mozilla/RefPtr.h" diff --git a/content/media/directshow/SourceFilter.cpp b/content/media/directshow/SourceFilter.cpp index d51d2842d36e..e1f1a81ed779 100644 --- a/content/media/directshow/SourceFilter.cpp +++ b/content/media/directshow/SourceFilter.cpp @@ -222,6 +222,13 @@ private: }; +// For mingw __uuidof support +#ifdef __CRT_UUID_DECL +} +__CRT_UUID_DECL(mozilla::OutputPin, 0x18e5cfb2,0x1015,0x440c,0xa6,0x5c,0xe6,0x38,0x53,0x23,0x58,0x94); +namespace mozilla { +#endif + OutputPin::OutputPin(MediaResource* aResource, SourceFilter* aParent, CriticalSection& aFilterLock, @@ -402,7 +409,7 @@ OutputPin::Request(IMediaSample* aSample, DWORD_PTR aDwUser) if (!aSample) return E_FAIL; CriticalSectionAutoEnter lock(*mLock); - NS_ASSERTION(!mFlushCount, __FUNCTION__"() while flushing"); + NS_ASSERTION(!mFlushCount, "Request() while flushing"); if (mFlushCount) return VFW_E_WRONG_STATE; @@ -463,7 +470,7 @@ OutputPin::WaitForNext(DWORD aTimeout, mSignal.Wait(); } - nsAutoPtr request = reinterpret_cast(mPendingReads.PopFront()); + nsAutoPtr request(reinterpret_cast(mPendingReads.PopFront())); if (!request) return VFW_E_WRONG_STATE; diff --git a/content/media/directshow/SourceFilter.h b/content/media/directshow/SourceFilter.h index f54a74ba70fe..36034f6a1fa1 100644 --- a/content/media/directshow/SourceFilter.h +++ b/content/media/directshow/SourceFilter.h @@ -68,4 +68,9 @@ protected: } // namespace mozilla +// For mingw __uuidof support +#ifdef __CRT_UUID_DECL +__CRT_UUID_DECL(mozilla::SourceFilter, 0x5c2a7ad0,0xba82,0x4659,0x91,0x78,0xc4,0x71,0x9a,0x27,0x65,0xd6); +#endif + #endif diff --git a/media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseFilter.h b/media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseFilter.h index a2b82b865a46..d6e5f47ee44b 100644 --- a/media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseFilter.h +++ b/media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseFilter.h @@ -151,6 +151,15 @@ protected: unsigned long mRefCnt; }; +// For mingw __uuidof support +#ifdef __CRT_UUID_DECL +} +} +__CRT_UUID_DECL(mozilla::media::BaseFilter, 0x4debd354,0xb0c6,0x44ab,0x93,0xcf,0x49,0xf6,0x4e,0xd3,0x6a,0xb8); +namespace mozilla { +namespace media { +#endif + _COM_SMARTPTR_TYPEDEF(BaseFilter, __uuidof(BaseFilter)); } diff --git a/media/webrtc/trunk/webrtc/modules/video_capture/windows/BasePin.h b/media/webrtc/trunk/webrtc/modules/video_capture/windows/BasePin.h index 47c69a5cc884..7da9012e20c3 100644 --- a/media/webrtc/trunk/webrtc/modules/video_capture/windows/BasePin.h +++ b/media/webrtc/trunk/webrtc/modules/video_capture/windows/BasePin.h @@ -198,6 +198,15 @@ protected: IEnumMediaTypes *aEnum); }; +// For mingw __uuidof support +#ifdef __CRT_UUID_DECL +} +} +__CRT_UUID_DECL(mozilla::media::BasePin, 0x199669c6,0x672a,0x4130,0xb1,0x3e,0x57,0xaa,0x83,0x0e,0xae,0x55); +namespace mozilla { +namespace media { +#endif + _COM_SMARTPTR_TYPEDEF(BasePin, __uuidof(BasePin)); } From a9d324a31676fb55d75827947e8233ebce34fa9b Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Tue, 24 Sep 2013 10:03:32 +0100 Subject: [PATCH 041/160] Bug 912567 - Split HashMap/HashSet::rekey() into rekey() and rekeyIfMoved() r=terrence --- js/ipc/JavaScriptShared.cpp | 2 +- js/public/HashTable.h | 30 ++++++++++++++++++++---------- js/src/ctypes/CTypes.cpp | 2 +- js/src/gc/StoreBuffer.h | 2 +- js/xpconnect/src/XPCMaps.h | 4 ++-- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/js/ipc/JavaScriptShared.cpp b/js/ipc/JavaScriptShared.cpp index 45b7f7e7f9f8..875922cfaec9 100644 --- a/js/ipc/JavaScriptShared.cpp +++ b/js/ipc/JavaScriptShared.cpp @@ -105,7 +105,7 @@ ObjectIdCache::keyMarkCallback(JSTracer *trc, void *k, void *d) { ObjectIdCache* self = static_cast(d); JSObject *prior = key; JS_CallObjectTracer(trc, &key, "ObjectIdCache::table_ key"); - self->table_.rekey(prior, key); + self->table_.rekeyIfMoved(prior, key); } void diff --git a/js/public/HashTable.h b/js/public/HashTable.h index 12c56cc06d06..9b0d32d87d51 100644 --- a/js/public/HashTable.h +++ b/js/public/HashTable.h @@ -250,12 +250,17 @@ class HashMap remove(p); } + // Infallibly rekey one entry, if necessary. + // Requires template parameters Key and HashPolicy::Lookup to be the same type. + void rekeyIfMoved(const Key &old_key, const Key &new_key) { + if (old_key != new_key) + rekeyAs(old_key, new_key, new_key); + } + // Infallibly rekey one entry, if present. - void rekey(const Lookup &old_key, const Key &new_key) { - if (old_key != new_key) { - if (Ptr p = lookup(old_key)) - impl.rekeyAndMaybeRehash(p, new_key, new_key); - } + void rekeyAs(const Lookup &old_lookup, const Lookup &new_lookup, const Key &new_key) { + if (Ptr p = lookup(old_lookup)) + impl.rekeyAndMaybeRehash(p, new_lookup, new_key); } // HashMap is movable @@ -450,11 +455,16 @@ class HashSet } // Infallibly rekey one entry, if present. - void rekey(const Lookup &old_key, const T &new_key) { - if (old_key != new_key) { - if (Ptr p = lookup(old_key)) - impl.rekeyAndMaybeRehash(p, new_key, new_key); - } + // Requires template parameters T and HashPolicy::Lookup to be the same type. + void rekeyIfMoved(const Lookup &old_value, const T &new_value) { + if (old_value != new_value) + rekeyAs(old_value, new_value, new_value); + } + + // Infallibly rekey one entry, if present. + void rekeyAs(const Lookup &old_lookup, const Lookup &new_lookup, const T &new_value) { + if (Ptr p = lookup(old_lookup)) + impl.rekeyAndMaybeRehash(p, new_lookup, new_value); } // HashSet is movable diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index f567d2786265..e3cd844e4a66 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -4744,7 +4744,7 @@ PostBarrierCallback(JSTracer *trc, void *k, void *d) FieldInfoHash *table = static_cast(d); JSString *key = prior; JS_CallStringTracer(trc, &key, "CType fieldName"); - table->rekey(JS_ASSERT_STRING_IS_FLAT(prior), JS_ASSERT_STRING_IS_FLAT(key)); + table->rekeyIfMoved(JS_ASSERT_STRING_IS_FLAT(prior), JS_ASSERT_STRING_IS_FLAT(key)); } bool diff --git a/js/src/gc/StoreBuffer.h b/js/src/gc/StoreBuffer.h index fa5196b0d3d8..52c4f4e88277 100644 --- a/js/src/gc/StoreBuffer.h +++ b/js/src/gc/StoreBuffer.h @@ -59,7 +59,7 @@ class HashKeyRef : public BufferableRef return; JS_SET_TRACING_LOCATION(trc, (void*)&*p); Mark(trc, &key, "HashKeyRef"); - map->rekey(prior, key); + map->rekeyIfMoved(prior, key); } }; diff --git a/js/xpconnect/src/XPCMaps.h b/js/xpconnect/src/XPCMaps.h index 0700b901de7c..244dce7fb66f 100644 --- a/js/xpconnect/src/XPCMaps.h +++ b/js/xpconnect/src/XPCMaps.h @@ -90,7 +90,7 @@ private: JSObject2WrappedJSMap* self = static_cast(d); JSObject *prior = key; JS_CallObjectTracer(trc, &key, "XPCJSRuntime::mWrappedJSMap key"); - self->mTable.rekey(prior, key); + self->mTable.rekeyIfMoved(prior, key); } Map mTable; @@ -699,7 +699,7 @@ private: JSObject2JSObjectMap *self = static_cast(d); JSObject *prior = key; JS_CallObjectTracer(trc, &key, "XPCWrappedNativeScope::mWaiverWrapperMap key"); - self->mTable.rekey(prior, key); + self->mTable.rekeyIfMoved(prior, key); } Map mTable; From 38b17c9cb28426aaa096409280f22f5d609d96cb Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Tue, 24 Sep 2013 10:03:57 +0100 Subject: [PATCH 042/160] Bug 912567 - Add post barrier for newTypeObjects r=bhackett --- js/src/jsinfer.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++-- js/src/jsinfer.h | 15 +++++++++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 16197aa137c2..78d433e1f697 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -3487,14 +3487,14 @@ JSObject::makeLazyType(JSContext *cx, HandleObject obj) /* static */ inline HashNumber TypeObjectEntry::hash(const Lookup &lookup) { - return PointerHasher::hash(lookup.proto.raw()) ^ + return PointerHasher::hash(lookup.hashProto.raw()) ^ PointerHasher::hash(lookup.clasp); } /* static */ inline bool TypeObjectEntry::match(TypeObject *key, const Lookup &lookup) { - return key->proto == lookup.proto.raw() && key->clasp == lookup.clasp; + return key->proto == lookup.matchProto.raw() && key->clasp == lookup.clasp; } #ifdef DEBUG @@ -3531,6 +3531,39 @@ JSObject::setNewTypeUnknown(JSContext *cx, const Class *clasp, HandleObject obj) return true; } +#ifdef JSGC_GENERATIONAL +/* + * This class is used to add a post barrier on the newTypeObjects set, as the + * key is calculated from a prototype object which may be moved by generational + * GC. + */ +class NewTypeObjectsSetRef : public BufferableRef +{ + TypeObjectSet *set; + TypeObject *typeObject; + JSObject *proto; + + public: + NewTypeObjectsSetRef(TypeObjectSet *s, TypeObject *t, JSObject *p) + : set(s), typeObject(t), proto(p) {} + + void mark(JSTracer *trc) { + const Class *clasp = typeObject->clasp; + JSObject *prior = proto; + JS_SET_TRACING_LOCATION(trc, (void*)&*prior); + Mark(trc, &proto, "newTypeObjects set prototype"); + if (prior == proto) + return; + + TypeObjectSet::Ptr p = set->lookup(TypeObjectSet::Lookup(clasp, prior, proto)); + JS_ASSERT(p); // newTypeObjects set must still contain original entry. + + set->rekeyAs(TypeObjectSet::Lookup(clasp, prior, proto), + TypeObjectSet::Lookup(clasp, proto), typeObject); + } +}; +#endif + TypeObject * ExclusiveContext::getNewType(const Class *clasp, TaggedProto proto_, JSFunction *fun_) { @@ -3547,6 +3580,8 @@ ExclusiveContext::getNewType(const Class *clasp, TaggedProto proto_, JSFunction uint64_t originalGcNumber = gcNumber(); if (p) { TypeObject *type = *p; + JS_ASSERT(type->clasp == clasp); + JS_ASSERT(type->proto.get() == proto_.raw()); /* * If set, the type's newScript indicates the script used to create @@ -3591,6 +3626,13 @@ ExclusiveContext::getNewType(const Class *clasp, TaggedProto proto_, JSFunction if (!added) return NULL; +#ifdef JSGC_GENERATIONAL + if (proto.isObject() && hasNursery() && nursery().isInside(proto.toObject())) { + asJSContext()->runtime()->gcStoreBuffer.putGeneric( + NewTypeObjectsSetRef(&newTypeObjects, type.get(), proto.toObject())); + } +#endif + if (!typeInferenceEnabled()) return type; diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index a5702f7ca09d..bfd61fcde72d 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -1206,9 +1206,20 @@ struct TypeObjectEntry : DefaultHasher > { struct Lookup { const Class *clasp; - TaggedProto proto; + TaggedProto hashProto; + TaggedProto matchProto; - Lookup(const Class *clasp, TaggedProto proto) : clasp(clasp), proto(proto) {} + Lookup(const Class *clasp, TaggedProto proto) + : clasp(clasp), hashProto(proto), matchProto(proto) {} + +#ifdef JSGC_GENERATIONAL + /* + * For use by generational post barriers only. Look up an entry whose + * proto has been moved, but was hashed with the original value. + */ + Lookup(const Class *clasp, TaggedProto hashProto, TaggedProto matchProto) + : clasp(clasp), hashProto(hashProto), matchProto(matchProto) {} +#endif }; static inline HashNumber hash(const Lookup &lookup); From ff95dc15cdb9f416cfd3434302c4bd5096972584 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Tue, 24 Sep 2013 10:08:35 +0100 Subject: [PATCH 043/160] Bug 906091 - Post-barrier globals, but only add to the store buffer on first write r=terrence --- js/src/gc/RootMarking.cpp | 30 +++--------------------------- js/src/jit/CodeGenerator.cpp | 8 ++++++-- js/src/jit/IonBuilder.cpp | 4 +--- js/src/jit/VMFunctions.cpp | 10 ++++++++++ js/src/jit/VMFunctions.h | 1 + js/src/jscompartment.cpp | 1 + js/src/jscompartment.h | 9 +++++++++ 7 files changed, 31 insertions(+), 32 deletions(-) diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index 67c983a880b1..28171bfad725 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -619,30 +619,6 @@ JSPropertyDescriptor::trace(JSTracer *trc) } } -static inline void -MarkGlobalForMinorGC(JSTracer *trc, JSCompartment *compartment) -{ -#ifdef JS_ION - /* - * Named properties of globals which have had Ion activity are treated as - * roots during minor GCs. This allows writes to globals to occur without - * needing a write barrier. - */ - JS_ASSERT(trc->runtime->isHeapMinorCollecting()); - - if (!compartment->ionCompartment()) - return; - - GlobalObject *global = compartment->maybeGlobal(); - if (!global) - return; - - /* Global reserved slots never hold nursery things. */ - for (size_t i = JSCLASS_RESERVED_SLOTS(global->getClass()); i < global->slotSpan(); ++i) - MarkValueRoot(trc, global->nativeGetSlotRef(i).unsafeGet(), "MinorGlobalRoot"); -#endif /* JS_ION */ -} - void js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots) { @@ -726,12 +702,12 @@ js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots) /* We can't use GCCompartmentsIter if we're called from TraceRuntime. */ for (CompartmentsIter c(rt); !c.done(); c.next()) { + if (trc->runtime->isHeapMinorCollecting()) + c->globalWriteBarriered = false; + if (IS_GC_MARKING_TRACER(trc) && !c->zone()->isCollecting()) continue; - if (trc->runtime->isHeapMinorCollecting()) - MarkGlobalForMinorGC(trc, c); - /* During a GC, these are treated as weak pointers. */ if (!IS_GC_MARKING_TRACER(trc)) { if (c->watchpointMap) diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index d1a44d0e0c25..99e47c095f7c 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -1440,9 +1440,12 @@ CodeGenerator::visitOutOfLineCallPostWriteBarrier(OutOfLineCallPostWriteBarrier regs.add(CallTempReg2); Register objreg; + bool isGlobal = false; if (obj->isConstant()) { + JSObject *object = &obj->toConstant()->toObject(); + isGlobal = object->is(); objreg = regs.takeAny(); - masm.movePtr(ImmGCPtr(&obj->toConstant()->toObject()), objreg); + masm.movePtr(ImmGCPtr(object), objreg); } else { objreg = ToRegister(obj); regs.takeUnchecked(objreg); @@ -1451,10 +1454,11 @@ CodeGenerator::visitOutOfLineCallPostWriteBarrier(OutOfLineCallPostWriteBarrier Register runtimereg = regs.takeAny(); masm.mov(ImmPtr(GetIonContext()->runtime), runtimereg); + void (*fun)(JSRuntime*, JSObject*) = isGlobal ? PostGlobalWriteBarrier : PostWriteBarrier; masm.setupUnalignedABICall(2, regs.takeAny()); masm.passABIArg(runtimereg); masm.passABIArg(objreg); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, PostWriteBarrier)); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, fun)); restoreLive(ool->lir()); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 466ffcef744b..5e7b19ba4e5c 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -6423,9 +6423,7 @@ IonBuilder::setStaticName(JSObject *staticObject, PropertyName *name) if (!propertyTypes) obj = addShapeGuard(obj, staticObject->lastProperty(), Bailout_ShapeGuard); - // Note: we do not use a post barrier when writing to the global object. - // Slots in the global object will be treated as roots during a minor GC. - if (!staticObject->is() && NeedsPostBarrier(info(), value)) + if (NeedsPostBarrier(info(), value)) current->add(MPostWriteBarrier::New(obj, value)); // If the property has a known type, we may be able to optimize typed stores by not diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 3a6a10585106..618c6a945478 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -631,6 +631,16 @@ PostWriteBarrier(JSRuntime *rt, JSObject *obj) JS_ASSERT(!IsInsideNursery(rt, obj)); rt->gcStoreBuffer.putWholeCell(obj); } + +void +PostGlobalWriteBarrier(JSRuntime *rt, JSObject *obj) +{ + JS_ASSERT(obj->is()); + if (!obj->compartment()->globalWriteBarriered) { + PostWriteBarrier(rt, obj); + obj->compartment()->globalWriteBarriered = true; + } +} #endif uint32_t diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h index d50c2cc9b872..2516ea28e754 100644 --- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -641,6 +641,7 @@ bool FilterArguments(JSContext *cx, JSString *str); #ifdef JSGC_GENERATIONAL void PostWriteBarrier(JSRuntime *rt, JSObject *obj); +void PostGlobalWriteBarrier(JSRuntime *rt, JSObject *obj); #endif uint32_t GetIndexFromString(JSString *str); diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index 7ddfec03cf12..688c11bf4f5c 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -52,6 +52,7 @@ JSCompartment::JSCompartment(Zone *zone, const JS::CompartmentOptions &options = lastAnimationTime(0), regExps(runtime_), typeReprs(runtime_), + globalWriteBarriered(false), propertyTree(thisForCtor()), gcIncomingGrayPointers(NULL), gcLiveArrayBuffers(NULL), diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index dc00edff58cd..114080777bc3 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -206,6 +206,15 @@ struct JSCompartment /* Set of all currently living type representations. */ js::TypeRepresentationHash typeReprs; + /* + * For generational GC, record whether a write barrier has added this + * compartment's global to the store buffer since the last minor GC. + * + * This is used to avoid adding it to the store buffer on every write, which + * can quickly fill the buffer and also cause performance problems. + */ + bool globalWriteBarriered; + private: void sizeOfTypeInferenceData(JS::TypeInferenceSizes *stats, mozilla::MallocSizeOf mallocSizeOf); From 0fbfe07d7efd9b771540d99165056da38e224baf Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 24 Sep 2013 19:04:14 +0900 Subject: [PATCH 044/160] Bug 912956 part.2 Rename nsEvent.h to mozilla/EventForwards.h and sort out it r=roc --HG-- rename : widget/nsEvent.h => widget/EventForwards.h --- content/base/public/Element.h | 2 +- content/base/public/nsContentUtils.h | 4 +- content/events/public/nsEventDispatcher.h | 2 +- content/events/public/nsIPrivateTextEvent.h | 1 - content/events/src/TextComposition.h | 2 +- content/events/src/Touch.h | 2 +- content/events/src/nsContentEventHandler.h | 3 +- content/events/src/nsDOMUIEvent.h | 1 - content/events/src/nsEventStateManager.h | 2 - content/events/src/nsIMEStateManager.h | 2 +- content/svg/content/src/SVGZoomEvent.h | 2 +- docshell/base/nsILinkHandler.h | 2 +- dom/base/nsDOMWindowUtils.h | 1 - dom/base/nsIScriptGlobalObject.h | 3 +- dom/base/nsPIDOMWindow.h | 7 + dom/base/nsQueryContentEventResult.h | 2 +- dom/interfaces/events/nsIDOMEvent.idl | 5 +- dom/interfaces/events/nsIDOMEventTarget.idl | 2 +- dom/plugins/base/nsIPluginInstanceOwner.idl | 2 +- dom/plugins/ipc/PluginLibrary.h | 2 +- editor/libeditor/base/nsEditor.cpp | 1 - editor/libeditor/base/nsEditor.h | 2 +- gfx/layers/Layers.h | 2 +- gfx/layers/composite/APZCTreeManager.h | 3 +- gfx/layers/ipc/AsyncPanZoomController.cpp | 1 - gfx/layers/ipc/AsyncPanZoomController.h | 2 +- gfx/layers/ipc/GestureEventListener.h | 2 +- layout/base/PositionedEventTargeting.h | 2 +- layout/base/nsIPresShell.h | 2 +- layout/forms/nsRangeFrame.h | 2 +- layout/generic/nsCanvasFrame.h | 2 +- layout/generic/nsFrameSetFrame.h | 1 - parser/html/nsHtml5TreeBuilderCppSupplement.h | 2 - view/public/nsView.h | 2 +- view/public/nsViewManager.h | 2 +- widget/{nsEvent.h => EventForwards.h} | 161 +++++++++--------- widget/InputData.h | 3 +- widget/cocoa/TextInputHandler.h | 3 +- widget/cocoa/nsCocoaUtils.h | 3 +- widget/cocoa/nsMenuUtilsX.h | 1 - widget/cocoa/nsStandaloneNativeMenu.mm | 1 - widget/gonk/GonkKeyMapping.h | 2 +- widget/gtk/nsGtkKeyUtils.h | 2 +- widget/moz.build | 2 +- widget/nsGUIEvent.h | 25 +-- widget/nsINativeKeyBindings.h | 2 +- widget/nsIWidget.h | 3 +- widget/nsIWidgetListener.h | 21 +++ widget/qt/nsQtKeyUtils.h | 2 +- widget/shared/WidgetUtils.h | 2 +- widget/windows/KeyboardLayout.h | 2 +- widget/windows/WinIMEHandler.h | 1 - widget/windows/WinMouseScrollHandler.h | 2 +- widget/windows/nsTextStore.h | 1 - widget/windows/nsWindow.h | 2 +- widget/windows/winrt/MetroInput.h | 4 +- widget/xpwidgets/nsBaseWidget.h | 2 + xpfe/appshell/src/nsWebShellWindow.h | 1 - xpfe/appshell/src/nsXULWindow.h | 2 +- 59 files changed, 164 insertions(+), 163 deletions(-) rename widget/{nsEvent.h => EventForwards.h} (55%) diff --git a/content/base/public/Element.h b/content/base/public/Element.h index 3ae358e2cb2f..655200e68566 100644 --- a/content/base/public/Element.h +++ b/content/base/public/Element.h @@ -33,8 +33,8 @@ #include "mozilla/dom/Attr.h" #include "nsISMILAttr.h" #include "nsClientRect.h" -#include "nsEvent.h" #include "nsAttrValue.h" +#include "mozilla/EventForwards.h" #include "mozilla/dom/BindingDeclarations.h" #include "Units.h" diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 5067c0067ec1..5e590a7c7a05 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -21,6 +21,7 @@ #include "js/TypeDecls.h" #include "js/RootingAPI.h" #include "mozilla/Assertions.h" +#include "mozilla/EventForwards.h" #include "mozilla/GuardObjects.h" #include "mozilla/TimeStamp.h" #include "nsContentListDeclarations.h" @@ -34,8 +35,6 @@ class imgIRequest; class imgLoader; class imgRequestProxy; class nsAutoScriptBlockerSuppressNodeRemoved; -class nsDragEvent; -class nsEvent; class nsEventListenerManager; class nsHtml5StringParser; class nsIChannel; @@ -84,7 +83,6 @@ class nsIWidget; class nsIWordBreaker; class nsIXPConnect; class nsIXPConnectJSObjectHolder; -class nsKeyEvent; class nsNodeInfoManager; class nsPIDOMWindow; class nsPresContext; diff --git a/content/events/public/nsEventDispatcher.h b/content/events/public/nsEventDispatcher.h index 8b84612bf88e..1ba5857cdc7b 100644 --- a/content/events/public/nsEventDispatcher.h +++ b/content/events/public/nsEventDispatcher.h @@ -7,8 +7,8 @@ #ifndef nsEventDispatcher_h___ #define nsEventDispatcher_h___ +#include "mozilla/EventForwards.h" #include "nsCOMPtr.h" -#include "nsEvent.h" class nsEventTargetChainItem; class nsIDOMEvent; diff --git a/content/events/public/nsIPrivateTextEvent.h b/content/events/public/nsIPrivateTextEvent.h index d767a85fbf82..e17d793d0014 100644 --- a/content/events/public/nsIPrivateTextEvent.h +++ b/content/events/public/nsIPrivateTextEvent.h @@ -6,7 +6,6 @@ #ifndef nsIPrivateTextEvent_h__ #define nsIPrivateTextEvent_h__ -#include "nsEvent.h" #include "nsISupports.h" #include "nsIPrivateTextRange.h" diff --git a/content/events/src/TextComposition.h b/content/events/src/TextComposition.h index fd25793f01e7..8d9307e9e349 100644 --- a/content/events/src/TextComposition.h +++ b/content/events/src/TextComposition.h @@ -8,12 +8,12 @@ #define mozilla_TextComposition_h #include "nsCOMPtr.h" -#include "nsEvent.h" #include "nsINode.h" #include "nsIWidget.h" #include "nsTArray.h" #include "nsThreadUtils.h" #include "mozilla/Attributes.h" +#include "mozilla/EventForwards.h" class nsDispatchingCallback; class nsIMEStateManager; diff --git a/content/events/src/Touch.h b/content/events/src/Touch.h index 1d55beeeb5dc..58b262e6109e 100644 --- a/content/events/src/Touch.h +++ b/content/events/src/Touch.h @@ -7,12 +7,12 @@ #define mozilla_dom_Touch_h #include "mozilla/Attributes.h" +#include "mozilla/EventForwards.h" #include "nsWrapperCache.h" #include "nsAutoPtr.h" #include "Units.h" class nsPresContext; -class nsEvent; namespace mozilla { namespace dom { diff --git a/content/events/src/nsContentEventHandler.h b/content/events/src/nsContentEventHandler.h index 0eb208d64ee6..725c43d1f314 100644 --- a/content/events/src/nsContentEventHandler.h +++ b/content/events/src/nsContentEventHandler.h @@ -10,11 +10,10 @@ #include "nsISelection.h" #include "nsRange.h" +#include "mozilla/EventForwards.h" class nsCaret; class nsPresContext; -class nsQueryContentEvent; -class nsSelectionEvent; struct nsRect; diff --git a/content/events/src/nsDOMUIEvent.h b/content/events/src/nsDOMUIEvent.h index a54b8d488f52..6057331a49a0 100644 --- a/content/events/src/nsDOMUIEvent.h +++ b/content/events/src/nsDOMUIEvent.h @@ -10,7 +10,6 @@ #include "nsIDOMUIEvent.h" #include "nsDOMEvent.h" #include "nsLayoutUtils.h" -#include "nsEvent.h" #include "mozilla/dom/UIEventBinding.h" #include "nsPresContext.h" #include "nsDeviceContext.h" diff --git a/content/events/src/nsEventStateManager.h b/content/events/src/nsEventStateManager.h index d8a13a6eef85..95a8d7d71a12 100644 --- a/content/events/src/nsEventStateManager.h +++ b/content/events/src/nsEventStateManager.h @@ -8,7 +8,6 @@ #include "mozilla/TypedEnum.h" -#include "nsEvent.h" #include "nsGUIEvent.h" #include "nsIObserver.h" #include "nsWeakReference.h" @@ -28,7 +27,6 @@ class nsIDocShellTreeItem; class imgIContainer; class nsDOMDataTransfer; class MouseEnterLeaveDispatcher; -class nsEventStates; class nsIMarkupDocumentViewer; class nsIScrollableFrame; class nsITimer; diff --git a/content/events/src/nsIMEStateManager.h b/content/events/src/nsIMEStateManager.h index 78a8d6786ad2..0dca8b1c68db 100644 --- a/content/events/src/nsIMEStateManager.h +++ b/content/events/src/nsIMEStateManager.h @@ -6,7 +6,7 @@ #ifndef nsIMEStateManager_h__ #define nsIMEStateManager_h__ -#include "nsEvent.h" +#include "mozilla/EventForwards.h" #include "nsIWidget.h" class nsDispatchingCallback; diff --git a/content/svg/content/src/SVGZoomEvent.h b/content/svg/content/src/SVGZoomEvent.h index 6d99fc3848bc..878cfc17ec68 100644 --- a/content/svg/content/src/SVGZoomEvent.h +++ b/content/svg/content/src/SVGZoomEvent.h @@ -9,9 +9,9 @@ #include "nsAutoPtr.h" #include "nsDOMUIEvent.h" #include "DOMSVGPoint.h" +#include "mozilla/EventForwards.h" #include "mozilla/dom/SVGZoomEventBinding.h" -class nsGUIEvent; class nsISVGPoint; class nsPresContext; diff --git a/docshell/base/nsILinkHandler.h b/docshell/base/nsILinkHandler.h index 4408d49baf9f..0194e20995e3 100644 --- a/docshell/base/nsILinkHandler.h +++ b/docshell/base/nsILinkHandler.h @@ -6,8 +6,8 @@ #define nsILinkHandler_h___ #include "nsISupports.h" +#include "mozilla/EventForwards.h" -class nsGUIEvent; class nsIContent; class nsIDocShell; class nsIInputStream; diff --git a/dom/base/nsDOMWindowUtils.h b/dom/base/nsDOMWindowUtils.h index f1402aa5c19f..2b1f4d8029bb 100644 --- a/dom/base/nsDOMWindowUtils.h +++ b/dom/base/nsDOMWindowUtils.h @@ -9,7 +9,6 @@ #include "nsWeakReference.h" #include "nsIDOMWindowUtils.h" -#include "nsEvent.h" #include "mozilla/Attributes.h" class nsGlobalWindow; diff --git a/dom/base/nsIScriptGlobalObject.h b/dom/base/nsIScriptGlobalObject.h index 9fb55bd2c021..766c8b7cbf34 100644 --- a/dom/base/nsIScriptGlobalObject.h +++ b/dom/base/nsIScriptGlobalObject.h @@ -8,12 +8,11 @@ #define nsIScriptGlobalObject_h__ #include "nsISupports.h" -#include "nsEvent.h" #include "nsIGlobalObject.h" #include "js/TypeDecls.h" +#include "mozilla/EventForwards.h" class nsIScriptContext; -class nsScriptErrorEvent; class nsIScriptGlobalObject; // A helper function for nsIScriptGlobalObject implementations to use diff --git a/dom/base/nsPIDOMWindow.h b/dom/base/nsPIDOMWindow.h index 2bb1006cb3f5..580e420848a3 100644 --- a/dom/base/nsPIDOMWindow.h +++ b/dom/base/nsPIDOMWindow.h @@ -52,6 +52,13 @@ enum PopupControlState { openOverridden // disallow window open }; +enum UIStateChangeType +{ + UIStateChangeType_NoChange, + UIStateChangeType_Set, + UIStateChangeType_Clear +}; + #define NS_PIDOMWINDOW_IID \ { 0x4f4eadf9, 0xe795, 0x48e5, \ { 0x89, 0x4b, 0x04, 0x40, 0xb2, 0x5d, 0xa6, 0xfa } } diff --git a/dom/base/nsQueryContentEventResult.h b/dom/base/nsQueryContentEventResult.h index 5bbabbd32bc2..c265a3df29a3 100644 --- a/dom/base/nsQueryContentEventResult.h +++ b/dom/base/nsQueryContentEventResult.h @@ -7,8 +7,8 @@ #include "nsString.h" #include "nsRect.h" #include "mozilla/Attributes.h" +#include "mozilla/EventForwards.h" -class nsQueryContentEvent; class nsIWidget; class nsQueryContentEventResult MOZ_FINAL : public nsIQueryContentEventResult diff --git a/dom/interfaces/events/nsIDOMEvent.idl b/dom/interfaces/events/nsIDOMEvent.idl index 63f2f2ab031b..84574a50162e 100644 --- a/dom/interfaces/events/nsIDOMEvent.idl +++ b/dom/interfaces/events/nsIDOMEvent.idl @@ -17,17 +17,14 @@ interface nsIDOMEventTarget; #undef ERROR #endif -class nsEvent; +#include "mozilla/EventForwards.h" class nsDOMEvent; -class nsCommandEvent; class nsPresContext; class nsInvalidateRequestList; namespace IPC { class Message; } namespace mozilla { -class WheelEvent; - namespace dom { class EventTarget; } // namespace dom diff --git a/dom/interfaces/events/nsIDOMEventTarget.idl b/dom/interfaces/events/nsIDOMEventTarget.idl index bb00563295dd..e25700b1a7d0 100644 --- a/dom/interfaces/events/nsIDOMEventTarget.idl +++ b/dom/interfaces/events/nsIDOMEventTarget.idl @@ -6,7 +6,7 @@ #include "domstubs.idl" %{C++ -#include "nsEvent.h" +#include "mozilla/EventForwards.h" #include "mozilla/dom/Nullable.h" #include "js/TypeDecls.h" diff --git a/dom/plugins/base/nsIPluginInstanceOwner.idl b/dom/plugins/base/nsIPluginInstanceOwner.idl index 58e109cd47fe..49a0f1faabfe 100644 --- a/dom/plugins/base/nsIPluginInstanceOwner.idl +++ b/dom/plugins/base/nsIPluginInstanceOwner.idl @@ -11,8 +11,8 @@ interface nsIDocument; %{C++ #include "npapi.h" +#include "mozilla/EventForwards.h" class nsNPAPIPluginInstance; -class nsPluginEvent; %} [ptr] native nsNPAPIPluginInstancePtr(nsNPAPIPluginInstance); diff --git a/dom/plugins/ipc/PluginLibrary.h b/dom/plugins/ipc/PluginLibrary.h index f981a92bda79..d012e2366166 100644 --- a/dom/plugins/ipc/PluginLibrary.h +++ b/dom/plugins/ipc/PluginLibrary.h @@ -13,6 +13,7 @@ #include "nscore.h" #include "nsTArray.h" #include "nsError.h" +#include "mozilla/EventForwards.h" class gfxASurface; class gfxContext; @@ -20,7 +21,6 @@ class nsCString; struct nsIntRect; struct nsIntSize; class nsNPAPIPlugin; -class nsGUIEvent; namespace mozilla { namespace layers { diff --git a/editor/libeditor/base/nsEditor.cpp b/editor/libeditor/base/nsEditor.cpp index f39aa176fcb8..ccf7ea28396c 100644 --- a/editor/libeditor/base/nsEditor.cpp +++ b/editor/libeditor/base/nsEditor.cpp @@ -44,7 +44,6 @@ #include "nsEditorEventListener.h" // for nsEditorEventListener #include "nsEditorUtils.h" // for nsAutoRules, etc #include "nsError.h" // for NS_OK, etc -#include "nsEvent.h" // for nsEventStatus, etc #include "nsFocusManager.h" // for nsFocusManager #include "nsFrameSelection.h" // for nsFrameSelection #include "nsGUIEvent.h" // for nsKeyEvent, nsEvent, etc diff --git a/editor/libeditor/base/nsEditor.h b/editor/libeditor/base/nsEditor.h index 30e9efafb32c..b9b9a6ee0a68 100644 --- a/editor/libeditor/base/nsEditor.h +++ b/editor/libeditor/base/nsEditor.h @@ -7,6 +7,7 @@ #define __editor_h__ #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc. +#include "mozilla/EventForwards.h" // for nsKeyEvent #include "mozilla/TypedEnum.h" // for MOZ_BEGIN_ENUM_CLASS, etc. #include "nsAutoPtr.h" // for nsRefPtr #include "nsCOMArray.h" // for nsCOMArray @@ -63,7 +64,6 @@ class nsISelection; class nsISupports; class nsITransaction; class nsIWidget; -class nsKeyEvent; class nsRange; class nsString; class nsTransactionManager; diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 54e5e56d2c41..8311aba4b067 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -21,6 +21,7 @@ #include "gfxRect.h" // for gfxRect #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2, etc #include "mozilla/DebugOnly.h" // for DebugOnly +#include "mozilla/EventForwards.h" // for nsPaintEvent #include "mozilla/RefPtr.h" // for TemporaryRef #include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration #include "mozilla/gfx/BaseMargin.h" // for BaseMargin @@ -47,7 +48,6 @@ class gfxContext; -class nsPaintEvent; extern uint8_t gLayerManagerLayerBuilder; diff --git a/gfx/layers/composite/APZCTreeManager.h b/gfx/layers/composite/APZCTreeManager.h index f20c2d1bbe14..1bdc4bd07cbc 100644 --- a/gfx/layers/composite/APZCTreeManager.h +++ b/gfx/layers/composite/APZCTreeManager.h @@ -12,15 +12,14 @@ #include "gfxPoint.h" // for gfxPoint #include "gfx3DMatrix.h" // for gfx3DMatrix #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 +#include "mozilla/EventForwards.h" // for nsInputEvent, nsEventStatus #include "mozilla/Monitor.h" // for Monitor #include "nsAutoPtr.h" // for nsRefPtr #include "nsCOMPtr.h" // for already_AddRefed -#include "nsEvent.h" // for nsEventStatus #include "nsISupportsImpl.h" #include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc class gfx3DMatrix; -class nsInputEvent; template class nsTArray; namespace mozilla { diff --git a/gfx/layers/ipc/AsyncPanZoomController.cpp b/gfx/layers/ipc/AsyncPanZoomController.cpp index 6027a7ec01c0..e489259a97d0 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.cpp +++ b/gfx/layers/ipc/AsyncPanZoomController.cpp @@ -41,7 +41,6 @@ #include "nsAutoPtr.h" // for nsRefPtr #include "nsCOMPtr.h" // for already_AddRefed #include "nsDebug.h" // for NS_WARNING -#include "nsEvent.h" #include "nsGUIEvent.h" // for nsInputEvent, nsTouchEvent, etc #include "nsISupportsImpl.h" #include "nsMathUtils.h" // for NS_hypot diff --git a/gfx/layers/ipc/AsyncPanZoomController.h b/gfx/layers/ipc/AsyncPanZoomController.h index 96a1a440efbd..2c0326cad3ca 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.h +++ b/gfx/layers/ipc/AsyncPanZoomController.h @@ -9,6 +9,7 @@ #include "GeckoContentController.h" #include "mozilla/Attributes.h" +#include "mozilla/EventForwards.h" #include "mozilla/Monitor.h" #include "mozilla/ReentrantMonitor.h" #include "mozilla/RefPtr.h" @@ -16,7 +17,6 @@ #include "Axis.h" #include "TaskThrottler.h" #include "gfx3DMatrix.h" -#include "nsEvent.h" #include "base/message_loop.h" diff --git a/gfx/layers/ipc/GestureEventListener.h b/gfx/layers/ipc/GestureEventListener.h index e573cea5c4d9..f25c1b6bd2ca 100644 --- a/gfx/layers/ipc/GestureEventListener.h +++ b/gfx/layers/ipc/GestureEventListener.h @@ -11,8 +11,8 @@ #include "InputData.h" // for MultiTouchInput, etc #include "Units.h" // for ScreenIntPoint #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 +#include "mozilla/EventForwards.h" // for nsEventStatus #include "nsAutoPtr.h" // for nsRefPtr -#include "nsEvent.h" // for nsEventStatus #include "nsISupportsImpl.h" #include "nsTArray.h" // for nsTArray diff --git a/layout/base/PositionedEventTargeting.h b/layout/base/PositionedEventTargeting.h index fbe92d15845a..125ce807891c 100644 --- a/layout/base/PositionedEventTargeting.h +++ b/layout/base/PositionedEventTargeting.h @@ -6,9 +6,9 @@ #define mozilla_PositionedEventTargeting_h #include +#include "mozilla/EventForwards.h" class nsIFrame; -class nsGUIEvent; struct nsPoint; namespace mozilla { diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index 3e5eacb27210..2e696968cd64 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -20,6 +20,7 @@ #ifndef nsIPresShell_h___ #define nsIPresShell_h___ +#include "mozilla/EventForwards.h" #include "mozilla/MemoryReporting.h" #include "gfxPoint.h" #include "nsTHashtable.h" @@ -28,7 +29,6 @@ #include "nsQueryFrame.h" #include "nsCoord.h" #include "nsColor.h" -#include "nsEvent.h" #include "nsCompatibility.h" #include "nsFrameManagerBase.h" #include "mozFlushType.h" diff --git a/layout/forms/nsRangeFrame.h b/layout/forms/nsRangeFrame.h index 3456f05d1f1d..ec6eb082394a 100644 --- a/layout/forms/nsRangeFrame.h +++ b/layout/forms/nsRangeFrame.h @@ -8,12 +8,12 @@ #include "mozilla/Attributes.h" #include "mozilla/Decimal.h" +#include "mozilla/EventForwards.h" #include "nsContainerFrame.h" #include "nsIAnonymousContentCreator.h" #include "nsCOMPtr.h" class nsBaseContentList; -class nsGUIEvent; class nsRangeFrame : public nsContainerFrame, public nsIAnonymousContentCreator diff --git a/layout/generic/nsCanvasFrame.h b/layout/generic/nsCanvasFrame.h index 57348480b00c..a940e6e1e9a8 100644 --- a/layout/generic/nsCanvasFrame.h +++ b/layout/generic/nsCanvasFrame.h @@ -9,13 +9,13 @@ #define nsCanvasFrame_h___ #include "mozilla/Attributes.h" +#include "mozilla/EventForwards.h" #include "nsContainerFrame.h" #include "nsIScrollPositionListener.h" #include "nsDisplayList.h" class nsPresContext; class nsRenderingContext; -class nsEvent; /** * Root frame class. diff --git a/layout/generic/nsFrameSetFrame.h b/layout/generic/nsFrameSetFrame.h index fd693ba3e5f5..fc51b3959751 100644 --- a/layout/generic/nsFrameSetFrame.h +++ b/layout/generic/nsFrameSetFrame.h @@ -19,7 +19,6 @@ struct nsHTMLReflowState; struct nsSize; class nsIAtom; class nsHTMLFramesetBorderFrame; -class nsGUIEvent; class nsHTMLFramesetFrame; #define NO_COLOR 0xFFFFFFFA diff --git a/parser/html/nsHtml5TreeBuilderCppSupplement.h b/parser/html/nsHtml5TreeBuilderCppSupplement.h index 45fc3e07c910..a2fd70495543 100644 --- a/parser/html/nsHtml5TreeBuilderCppSupplement.h +++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h @@ -6,8 +6,6 @@ #include "nsError.h" #include "nsIPresShell.h" -#include "nsEvent.h" -#include "nsGUIEvent.h" #include "nsEventDispatcher.h" #include "nsNodeUtils.h" #include "nsIFrame.h" diff --git a/view/public/nsView.h b/view/public/nsView.h index afbb64d65c62..85cb5b15ab7a 100644 --- a/view/public/nsView.h +++ b/view/public/nsView.h @@ -11,8 +11,8 @@ #include "nsPoint.h" #include "nsRegion.h" #include "nsCRT.h" -#include "nsEvent.h" #include "nsIWidgetListener.h" +#include "mozilla/EventForwards.h" class nsViewManager; class nsIWidget; diff --git a/view/public/nsViewManager.h b/view/public/nsViewManager.h index 847df011b1f9..db241d28a2c2 100644 --- a/view/public/nsViewManager.h +++ b/view/public/nsViewManager.h @@ -8,11 +8,11 @@ #include "nscore.h" #include "nsView.h" -#include "nsEvent.h" #include "nsCOMPtr.h" #include "nsCRT.h" #include "nsVoidArray.h" #include "nsDeviceContext.h" +#include "mozilla/EventForwards.h" class nsIWidget; struct nsRect; diff --git a/widget/nsEvent.h b/widget/EventForwards.h similarity index 55% rename from widget/nsEvent.h rename to widget/EventForwards.h index 80cea20c3eea..c7c571f71770 100644 --- a/widget/nsEvent.h +++ b/widget/EventForwards.h @@ -3,87 +3,37 @@ * 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 nsEvent_h__ -#define nsEvent_h__ +#ifndef mozilla_EventForwards_h__ +#define mozilla_EventForwards_h__ #include -/* - * This is in a separate header file because it needs to be included - * in many places where including nsGUIEvent.h would bring in many - * header files that are totally unnecessary. +/** + * XXX Following enums should be in BasicEvents.h. However, currently, it's + * impossible to use foward delearation for enum. */ -enum UIStateChangeType { - UIStateChangeType_NoChange, - UIStateChangeType_Set, - UIStateChangeType_Clear -}; - /** * Return status for event processors. */ - -enum nsEventStatus { - /// The event is ignored, do default processing - nsEventStatus_eIgnore, - /// The event is consumed, don't do default processing - nsEventStatus_eConsumeNoDefault, - /// The event is consumed, but do default processing - nsEventStatus_eConsumeDoDefault +enum nsEventStatus +{ + // The event is ignored, do default processing + nsEventStatus_eIgnore, + // The event is consumed, don't do default processing + nsEventStatus_eConsumeNoDefault, + // The event is consumed, but do default processing + nsEventStatus_eConsumeDoDefault }; -/** - * sizemode is an adjunct to widget size - */ -enum nsSizeMode { - nsSizeMode_Normal = 0, - nsSizeMode_Minimized, - nsSizeMode_Maximized, - nsSizeMode_Fullscreen -}; - -struct nsAlternativeCharCode; -struct nsTextRangeStyle; -struct nsTextRange; - -class nsEvent; -class nsGUIEvent; -class nsScriptErrorEvent; -class nsScrollbarEvent; -class nsScrollPortEvent; -class nsScrollAreaEvent; -class nsInputEvent; -class nsMouseEvent_base; -class nsMouseEvent; -class nsDragEvent; -class nsKeyEvent; -class nsTextEvent; -class nsCompositionEvent; -class nsMouseScrollEvent; -class nsGestureNotifyEvent; -class nsQueryContentEvent; -class nsFocusEvent; -class nsSelectionEvent; -class nsContentCommandEvent; -class nsTouchEvent; -class nsFormEvent; -class nsCommandEvent; -class nsUIEvent; -class nsSimpleGestureEvent; -class nsTransitionEvent; -class nsAnimationEvent; -class nsPluginEvent; - namespace mozilla { -struct EventFlags; - -class WheelEvent; - -// All modifier keys should be defined here. This is used for managing -// modifier states for DOM Level 3 or later. -enum Modifier { +/** + * All modifier keys should be defined here. This is used for managing + * modifier states for DOM Level 3 or later. + */ +enum Modifier +{ MODIFIER_ALT = 0x0001, MODIFIER_ALTGRAPH = 0x0002, MODIFIER_CAPSLOCK = 0x0004, @@ -102,7 +52,8 @@ typedef uint16_t Modifiers; #define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \ KEY_NAME_INDEX_##aCPPName, -enum KeyNameIndex { +enum KeyNameIndex +{ #include "nsDOMKeyNameList.h" // There shouldn't be "," at the end of enum definition, this dummy item // avoids bustage on some platforms. @@ -113,16 +64,62 @@ enum KeyNameIndex { } // namespace mozilla -#define NS_DOM_KEYNAME_ALT "Alt" -#define NS_DOM_KEYNAME_ALTGRAPH "AltGraph" -#define NS_DOM_KEYNAME_CAPSLOCK "CapsLock" -#define NS_DOM_KEYNAME_CONTROL "Control" -#define NS_DOM_KEYNAME_FN "Fn" -#define NS_DOM_KEYNAME_META "Meta" -#define NS_DOM_KEYNAME_NUMLOCK "NumLock" -#define NS_DOM_KEYNAME_SCROLLLOCK "ScrollLock" -#define NS_DOM_KEYNAME_SHIFT "Shift" -#define NS_DOM_KEYNAME_SYMBOLLOCK "SymbolLock" -#define NS_DOM_KEYNAME_OS "OS" +/** + * All header files should include this header instead of *Events.h. + */ -#endif // nsEvent_h__ +// BasicEvents.h +namespace mozilla { +struct EventFlags; +} // namespace mozilla + +class nsEvent; +class nsGUIEvent; +class nsInputEvent; +class nsUIEvent; + +// TextEvents.h +struct nsAlternativeCharCode; +struct nsTextRangeStyle; +struct nsTextRange; + +class nsKeyEvent; +class nsTextEvent; +class nsCompositionEvent; +class nsQueryContentEvent; +class nsSelectionEvent; + +// MouseEvents.h +class nsMouseEvent_base; +class nsMouseEvent; +class nsDragEvent; +class nsMouseScrollEvent; + +namespace mozilla { +class WheelEvent; +} // namespace mozilla + +// TouchEvents.h +class nsGestureNotifyEvent; +class nsTouchEvent; +class nsSimpleGestureEvent; + +// ContentEvents.h +class nsScriptErrorEvent; +class nsScrollPortEvent; +class nsScrollAreaEvent; +class nsFormEvent; +class nsClipboardEvent; +class nsFocusEvent; +class nsTransitionEvent; +class nsAnimationEvent; + +// MiscEvents.h +class nsCommandEvent; +class nsContentCommandEvent; +class nsPluginEvent; + +// content/events/public/nsMutationEvent.h +class nsMutationEvent; + +#endif // mozilla_EventForwards_h__ diff --git a/widget/InputData.h b/widget/InputData.h index 6dd7127c665a..c56abc99090c 100644 --- a/widget/InputData.h +++ b/widget/InputData.h @@ -10,9 +10,8 @@ #include "nsPoint.h" #include "nsTArray.h" #include "Units.h" +#include "mozilla/EventForwards.h" -class nsTouchEvent; -class nsMouseEvent; namespace mozilla { diff --git a/widget/cocoa/TextInputHandler.h b/widget/cocoa/TextInputHandler.h index 9c86fde58a51..a2824e58f77e 100644 --- a/widget/cocoa/TextInputHandler.h +++ b/widget/cocoa/TextInputHandler.h @@ -17,10 +17,9 @@ #include "nsITimer.h" #include "npapi.h" #include "nsTArray.h" -#include "nsEvent.h" +#include "mozilla/EventForwards.h" class nsChildView; -struct nsTextRange; namespace mozilla { namespace widget { diff --git a/widget/cocoa/nsCocoaUtils.h b/widget/cocoa/nsCocoaUtils.h index 4927f7e4c776..c16491e15605 100644 --- a/widget/cocoa/nsCocoaUtils.h +++ b/widget/cocoa/nsCocoaUtils.h @@ -10,13 +10,14 @@ #include "nsRect.h" #include "imgIContainer.h" -#include "nsEvent.h" #include "npapi.h" #include "nsTArray.h" // This must be the last include: #include "nsObjCExceptions.h" +#include "mozilla/EventForwards.h" + // Declare the backingScaleFactor method that we want to call // on NSView/Window/Screen objects, if they recognize it. @interface NSObject (BackingScaleFactorCategory) diff --git a/widget/cocoa/nsMenuUtilsX.h b/widget/cocoa/nsMenuUtilsX.h index 2d7b5c2b6e17..a71147b3898c 100644 --- a/widget/cocoa/nsMenuUtilsX.h +++ b/widget/cocoa/nsMenuUtilsX.h @@ -7,7 +7,6 @@ #define nsMenuUtilsX_h_ #include "nscore.h" -#include "nsEvent.h" #include "nsMenuBaseX.h" #import diff --git a/widget/cocoa/nsStandaloneNativeMenu.mm b/widget/cocoa/nsStandaloneNativeMenu.mm index f60329ac63f7..4287c2ecef1e 100644 --- a/widget/cocoa/nsStandaloneNativeMenu.mm +++ b/widget/cocoa/nsStandaloneNativeMenu.mm @@ -9,7 +9,6 @@ #include "nsMenuUtilsX.h" #include "nsIDOMElement.h" #include "nsIMutationObserver.h" -#include "nsEvent.h" #include "nsGUIEvent.h" #include "nsGkAtoms.h" #include "nsObjCExceptions.h" diff --git a/widget/gonk/GonkKeyMapping.h b/widget/gonk/GonkKeyMapping.h index ad70103c624e..360bbc7b3b82 100644 --- a/widget/gonk/GonkKeyMapping.h +++ b/widget/gonk/GonkKeyMapping.h @@ -16,8 +16,8 @@ #ifndef GONKKEYMAPPING_H #define GONKKEYMAPPING_H -#include "nsEvent.h" #include "libui/android_keycodes.h" +#include "mozilla/EventForwards.h" namespace mozilla { namespace widget { diff --git a/widget/gtk/nsGtkKeyUtils.h b/widget/gtk/nsGtkKeyUtils.h index 3b3c1a9d251f..b5947151637c 100644 --- a/widget/gtk/nsGtkKeyUtils.h +++ b/widget/gtk/nsGtkKeyUtils.h @@ -8,8 +8,8 @@ #ifndef __nsGdkKeyUtils_h__ #define __nsGdkKeyUtils_h__ -#include "nsEvent.h" #include "nsTArray.h" +#include "mozilla/EventForwards.h" #include diff --git a/widget/moz.build b/widget/moz.build index 78f65596ed36..93cd3f23d8d9 100644 --- a/widget/moz.build +++ b/widget/moz.build @@ -99,7 +99,6 @@ MODULE = 'widget' EXPORTS += [ 'InputData.h', - 'nsEvent.h', 'nsGUIEvent.h', 'nsIDeviceContextSpec.h', 'nsINativeKeyBindings.h', @@ -112,6 +111,7 @@ EXPORTS += [ ] EXPORTS.mozilla += [ + 'EventForwards.h', 'LookAndFeel.h', 'WidgetUtils.h', ] diff --git a/widget/nsGUIEvent.h b/widget/nsGUIEvent.h index 4b5b2acd755c..6047c1d36067 100644 --- a/widget/nsGUIEvent.h +++ b/widget/nsGUIEvent.h @@ -10,7 +10,6 @@ #include "nsPoint.h" #include "nsRect.h" -#include "nsEvent.h" #include "nsString.h" #include "nsCOMPtr.h" #include "nsIAtom.h" @@ -25,6 +24,7 @@ #include "nsITransferable.h" #include "nsStyleConsts.h" #include "nsAutoPtr.h" +#include "mozilla/EventForwards.h" #include "mozilla/dom/EventTarget.h" #include "mozilla/dom/Touch.h" #include "Units.h" @@ -477,18 +477,19 @@ enum nsEventStructType { #endif /** - * Return status for event processors, nsEventStatus, is defined in - * nsEvent.h. + * Modifier key names. */ - -/** - * different types of (top-level) window z-level positioning - */ -enum nsWindowZ { - nsWindowZTop = 0, // on top - nsWindowZBottom, // on bottom - nsWindowZRelative // just below some specified widget -}; +#define NS_DOM_KEYNAME_ALT "Alt" +#define NS_DOM_KEYNAME_ALTGRAPH "AltGraph" +#define NS_DOM_KEYNAME_CAPSLOCK "CapsLock" +#define NS_DOM_KEYNAME_CONTROL "Control" +#define NS_DOM_KEYNAME_FN "Fn" +#define NS_DOM_KEYNAME_META "Meta" +#define NS_DOM_KEYNAME_NUMLOCK "NumLock" +#define NS_DOM_KEYNAME_SCROLLLOCK "ScrollLock" +#define NS_DOM_KEYNAME_SHIFT "Shift" +#define NS_DOM_KEYNAME_SYMBOLLOCK "SymbolLock" +#define NS_DOM_KEYNAME_OS "OS" namespace mozilla { diff --git a/widget/nsINativeKeyBindings.h b/widget/nsINativeKeyBindings.h index 3d6914bb20ae..d87234e456e1 100644 --- a/widget/nsINativeKeyBindings.h +++ b/widget/nsINativeKeyBindings.h @@ -7,7 +7,7 @@ #define nsINativeKeyBindings_h_ #include "nsISupports.h" -#include "nsEvent.h" +#include "mozilla/EventForwards.h" #define NS_INATIVEKEYBINDINGS_IID \ {0xc2baecc3, 0x1758, 0x4211, {0x96, 0xbe, 0xee, 0x1b, 0x1b, 0x7c, 0xd7, 0x6d}} diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index c93bea22ded0..684208bf4beb 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -11,11 +11,11 @@ #include "nsRect.h" #include "nsString.h" -#include "nsEvent.h" #include "nsCOMPtr.h" #include "nsWidgetInitData.h" #include "nsTArray.h" #include "nsXULAppAPI.h" +#include "mozilla/EventForwards.h" #include "mozilla/layers/LayersTypes.h" #include "mozilla/RefPtr.h" #include "Units.h" @@ -26,7 +26,6 @@ class nsRenderingContext; class nsDeviceContext; struct nsFont; class nsIRollupListener; -class nsGUIEvent; class imgIContainer; class gfxASurface; class nsIContent; diff --git a/widget/nsIWidgetListener.h b/widget/nsIWidgetListener.h index cb41bc8af6e1..59176722e69c 100644 --- a/widget/nsIWidgetListener.h +++ b/widget/nsIWidgetListener.h @@ -13,6 +13,27 @@ class nsView; class nsIPresShell; +/** + * sizemode is an adjunct to widget size + */ +enum nsSizeMode +{ + nsSizeMode_Normal = 0, + nsSizeMode_Minimized, + nsSizeMode_Maximized, + nsSizeMode_Fullscreen +}; + +/** + * different types of (top-level) window z-level positioning + */ +enum nsWindowZ +{ + nsWindowZTop = 0, // on top + nsWindowZBottom, // on bottom + nsWindowZRelative // just below some specified widget +}; + class nsIWidgetListener { public: diff --git a/widget/qt/nsQtKeyUtils.h b/widget/qt/nsQtKeyUtils.h index 13d203768eb8..41338d7327c7 100644 --- a/widget/qt/nsQtKeyUtils.h +++ b/widget/qt/nsQtKeyUtils.h @@ -8,7 +8,7 @@ #ifndef __nsQtKeyUtils_h__ #define __nsQtKeyUtils_h__ -#include "nsEvent.h" +#include "mozilla/EventForwards.h" int QtKeyCodeToDOMKeyCode (int aKeysym); int DOMKeyCodeToQtKeyCode (int aKeysym); diff --git a/widget/shared/WidgetUtils.h b/widget/shared/WidgetUtils.h index 5debf916acd9..65cf04b188f4 100644 --- a/widget/shared/WidgetUtils.h +++ b/widget/shared/WidgetUtils.h @@ -9,9 +9,9 @@ #include "nsCOMPtr.h" #include "nsIWidget.h" -#include "nsEvent.h" #include "nsPIDOMWindow.h" #include "nsIDOMWindow.h" +#include "mozilla/EventForwards.h" namespace mozilla { namespace widget { diff --git a/widget/windows/KeyboardLayout.h b/widget/windows/KeyboardLayout.h index 1e4ade473387..8e02b55ea4a0 100644 --- a/widget/windows/KeyboardLayout.h +++ b/widget/windows/KeyboardLayout.h @@ -8,10 +8,10 @@ #include "nscore.h" #include "nsAutoPtr.h" -#include "nsEvent.h" #include "nsString.h" #include "nsWindowBase.h" #include "nsWindowDefs.h" +#include "mozilla/EventForwards.h" #include #define NS_NUM_OF_KEYS 70 diff --git a/widget/windows/WinIMEHandler.h b/widget/windows/WinIMEHandler.h index f42ab5fe70b7..a418a3bdf3c2 100644 --- a/widget/windows/WinIMEHandler.h +++ b/widget/windows/WinIMEHandler.h @@ -7,7 +7,6 @@ #define WinIMEHandler_h_ #include "nscore.h" -#include "nsEvent.h" #include "nsIWidget.h" #include #include diff --git a/widget/windows/WinMouseScrollHandler.h b/widget/windows/WinMouseScrollHandler.h index 4a1c857e2c94..6e853caf9daf 100644 --- a/widget/windows/WinMouseScrollHandler.h +++ b/widget/windows/WinMouseScrollHandler.h @@ -9,8 +9,8 @@ #include "nscore.h" #include "nsDebug.h" -#include "nsEvent.h" #include "mozilla/Assertions.h" +#include "mozilla/EventForwards.h" #include "mozilla/TimeStamp.h" #include diff --git a/widget/windows/nsTextStore.h b/widget/windows/nsTextStore.h index bd09a3f06373..509f14b5ec19 100644 --- a/widget/windows/nsTextStore.h +++ b/widget/windows/nsTextStore.h @@ -32,7 +32,6 @@ struct ITfDocumentMgr; struct ITfDisplayAttributeMgr; struct ITfCategoryMgr; class nsWindow; -class nsTextEvent; #ifdef MOZ_METRO class MetroWidget; #endif diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index 40f9f39b014e..b460c32d157a 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -18,12 +18,12 @@ #include "nsToolkit.h" #include "nsString.h" #include "nsTArray.h" -#include "nsEvent.h" #include "gfxWindowsSurface.h" #include "nsWindowDbg.h" #include "cairo.h" #include "nsITimer.h" #include "nsRegion.h" +#include "mozilla/EventForwards.h" #include "mozilla/TimeStamp.h" #include "nsMargin.h" diff --git a/widget/windows/winrt/MetroInput.h b/widget/windows/winrt/MetroInput.h index 4d9eb3d4ae7c..96503ad371c2 100644 --- a/widget/windows/winrt/MetroInput.h +++ b/widget/windows/winrt/MetroInput.h @@ -8,10 +8,10 @@ // Moz headers (alphabetical) #include "keyboardlayout.h" // mModifierKeyState #include "nsBaseHashtable.h" // mTouches -#include "nsGUIEvent.h" // mTouchEvent (nsTouchEvent) #include "nsHashKeys.h" // type of key for mTouches #include "mozwrlbase.h" #include "nsDeque.h" +#include "mozilla/EventForwards.h" // System headers (alphabetical) #include // EventRegistrationToken @@ -21,8 +21,6 @@ // Moz forward declarations class MetroWidget; -enum nsEventStatus; -class nsGUIEvent; struct nsIntPoint; namespace mozilla { diff --git a/widget/xpwidgets/nsBaseWidget.h b/widget/xpwidgets/nsBaseWidget.h index 354874152e0d..4ff5c764b811 100644 --- a/widget/xpwidgets/nsBaseWidget.h +++ b/widget/xpwidgets/nsBaseWidget.h @@ -16,6 +16,8 @@ #include "nsAutoPtr.h" #include "nsIRollupListener.h" #include "nsIObserver.h" +#include "nsIWidgetListener.h" +#include "nsPIDOMWindow.h" #include class nsIContent; class nsAutoRollup; diff --git a/xpfe/appshell/src/nsWebShellWindow.h b/xpfe/appshell/src/nsWebShellWindow.h index a589116021a3..89f0fc9eacb5 100644 --- a/xpfe/appshell/src/nsWebShellWindow.h +++ b/xpfe/appshell/src/nsWebShellWindow.h @@ -7,7 +7,6 @@ #define nsWebShellWindow_h__ #include "mozilla/Mutex.h" -#include "nsEvent.h" #include "nsIWebProgressListener.h" #include "nsITimer.h" #include "nsCOMPtr.h" diff --git a/xpfe/appshell/src/nsXULWindow.h b/xpfe/appshell/src/nsXULWindow.h index 30ba7170937f..cd1f4d978c0f 100644 --- a/xpfe/appshell/src/nsXULWindow.h +++ b/xpfe/appshell/src/nsXULWindow.h @@ -28,9 +28,9 @@ #include "nsIXULWindow.h" #include "nsIPrompt.h" #include "nsIAuthPrompt.h" -#include "nsGUIEvent.h" #include "nsIXULBrowserWindow.h" #include "nsIWeakReference.h" +#include "nsIWidgetListener.h" namespace mozilla { namespace dom { From c89fb38cf2fe76178aeca5874f1106b5c676b083 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 24 Sep 2013 19:04:14 +0900 Subject: [PATCH 045/160] Bug 912956 part.3 Create mozilla/BasicEvents.h r=roc --- dom/interfaces/events/nsIDOMEvent.idl | 42 +- js/xpconnect/src/event_impl_gen.py | 10 +- widget/BasicEvents.h | 904 ++++++++++++++++++++++++++ widget/EventForwards.h | 35 +- widget/moz.build | 1 + widget/nsGUIEvent.h | 845 +----------------------- 6 files changed, 943 insertions(+), 894 deletions(-) create mode 100644 widget/BasicEvents.h diff --git a/dom/interfaces/events/nsIDOMEvent.idl b/dom/interfaces/events/nsIDOMEvent.idl index 84574a50162e..be6eb5ff2b5d 100644 --- a/dom/interfaces/events/nsIDOMEvent.idl +++ b/dom/interfaces/events/nsIDOMEvent.idl @@ -237,22 +237,22 @@ nsresult NS_NewDOMUIEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsGUIEvent* aEvent); + nsGUIEvent* aEvent); nsresult NS_NewDOMMouseEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsInputEvent* aEvent); + nsInputEvent* aEvent); nsresult NS_NewDOMFocusEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsFocusEvent* aEvent); + nsFocusEvent* aEvent); nsresult NS_NewDOMMouseScrollEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsInputEvent* aEvent); + nsInputEvent* aEvent); nsresult NS_NewDOMWheelEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, @@ -262,28 +262,28 @@ nsresult NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsDragEvent* aEvent); + nsDragEvent* aEvent); nsresult NS_NewDOMClipboardEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsClipboardEvent *aEvent); + nsClipboardEvent *aEvent); nsresult NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsKeyEvent* aEvent); + nsKeyEvent* aEvent); nsresult NS_NewDOMCompositionEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsCompositionEvent* aEvent); + nsCompositionEvent* aEvent); nsresult NS_NewDOMMutationEvent(nsIDOMEvent** aResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsMutationEvent* aEvent); + nsMutationEvent* aEvent); nsresult NS_NewDOMDeviceMotionEvent(nsIDOMEvent** aResult, mozilla::dom::EventTarget* aOwner, @@ -293,7 +293,7 @@ nsresult NS_NewDOMTextEvent(nsIDOMEvent** aResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsTextEvent* aEvent); + nsTextEvent* aEvent); nsresult NS_NewDOMBeforeUnloadEvent(nsIDOMEvent** aResult, mozilla::dom::EventTarget* aOwner, @@ -303,22 +303,22 @@ nsresult NS_NewDOMSVGEvent(nsIDOMEvent** aResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsEvent* aEvent); + nsEvent* aEvent); nsresult NS_NewDOMSVGZoomEvent(nsIDOMEvent** aResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsGUIEvent* aEvent); + nsGUIEvent* aEvent); nsresult NS_NewDOMTimeEvent(nsIDOMEvent** aResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsEvent* aEvent); + nsEvent* aEvent); nsresult NS_NewDOMXULCommandEvent(nsIDOMEvent** aResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsInputEvent* aEvent); + nsInputEvent* aEvent); nsresult NS_NewDOMCommandEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, @@ -328,12 +328,12 @@ nsresult NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsEvent* aEvent); + nsEvent* aEvent); nsresult NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsEvent* aEvent); + nsEvent* aEvent); // This empties aInvalidateRequests. nsresult NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aResult, @@ -355,27 +355,27 @@ nsresult NS_NewDOMSimpleGestureEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsSimpleGestureEvent* aEvent); + nsSimpleGestureEvent* aEvent); nsresult NS_NewDOMScrollAreaEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsScrollAreaEvent* aEvent); + nsScrollAreaEvent* aEvent); nsresult NS_NewDOMTransitionEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsTransitionEvent* aEvent); + nsTransitionEvent* aEvent); nsresult NS_NewDOMAnimationEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsAnimationEvent* aEvent); + nsAnimationEvent* aEvent); nsresult NS_NewDOMTouchEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - class nsTouchEvent* aEvent); + nsTouchEvent* aEvent); nsresult NS_NewDOMMozSettingsEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, diff --git a/js/xpconnect/src/event_impl_gen.py b/js/xpconnect/src/event_impl_gen.py index 087ca68e1e67..1fe0d39cf853 100644 --- a/js/xpconnect/src/event_impl_gen.py +++ b/js/xpconnect/src/event_impl_gen.py @@ -68,10 +68,10 @@ def print_header_file(fd, conf): "#define _gen_mozilla_idl_generated_events_h_\n\n") fd.write("/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n") fd.write("#include \"nscore.h\"\n") - fd.write("class nsEvent;\n") fd.write("class nsIDOMEvent;\n") fd.write("class nsPresContext;\n") fd.write("namespace mozilla {\n"); + fd.write("class WidgetEvent;\n") fd.write("namespace dom {\n"); fd.write("class EventTarget;\n") fd.write("}\n"); @@ -80,7 +80,7 @@ def print_header_file(fd, conf): fd.write("nsresult\n") fd.write("NS_NewDOM%s(nsIDOMEvent** aInstance, " % e) fd.write("mozilla::dom::EventTarget* aOwner, ") - fd.write("nsPresContext* aPresContext, nsEvent* aEvent);\n") + fd.write("nsPresContext* aPresContext, mozilla::WidgetEvent* aEvent);\n") fd.write("\n#endif\n") @@ -150,7 +150,7 @@ def print_class_declaration(eventname, iface, fd, conf): fd.write("{\n") fd.write("public:\n") fd.write(" %s(mozilla::dom::EventTarget* aOwner, " % classname) - fd.write("nsPresContext* aPresContext = nullptr, nsEvent* aEvent = nullptr);\n"); + fd.write("nsPresContext* aPresContext = nullptr, mozilla::WidgetEvent* aEvent = nullptr);\n"); fd.write(" virtual ~%s();\n\n" % classname) fd.write(" NS_DECL_ISUPPORTS_INHERITED\n") fd.write(" NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(%s, %s)\n" % (classname, basename)) @@ -375,7 +375,7 @@ def write_cpp(eventname, iface, fd, conf): fd.write("namespace dom {\n\n") fd.write("%s::%s(mozilla::dom::EventTarget* aOwner, " % (classname, classname)) - fd.write("nsPresContext* aPresContext, nsEvent* aEvent)\n"); + fd.write("nsPresContext* aPresContext, mozilla::WidgetEvent* aEvent)\n"); fd.write(": %s(aOwner, aPresContext, aEvent)" % basename) for a in attributes: fd.write(",\n m%s(%s)" % (firstCap(a.name), init_value(a))) @@ -487,7 +487,7 @@ def write_cpp(eventname, iface, fd, conf): fd.write("nsresult\n") fd.write("NS_NewDOM%s(nsIDOMEvent** aInstance, " % eventname) - fd.write("mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext = nullptr, nsEvent* aEvent = nullptr)\n") + fd.write("mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext = nullptr, mozilla::WidgetEvent* aEvent = nullptr)\n") fd.write("{\n") fd.write(" mozilla::dom::%s* it = new mozilla::dom::%s(aOwner, aPresContext, aEvent);\n" % (classname, classname)) fd.write(" return CallQueryInterface(it, aInstance);\n") diff --git a/widget/BasicEvents.h b/widget/BasicEvents.h new file mode 100644 index 000000000000..8ad699021b78 --- /dev/null +++ b/widget/BasicEvents.h @@ -0,0 +1,904 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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_BasicEvents_h__ +#define mozilla_BasicEvents_h__ + +#include + +#include "mozilla/dom/EventTarget.h" +#include "nsCOMPtr.h" +#include "nsIAtom.h" +#include "nsIWidget.h" +#include "nsString.h" +#include "nsTraceRefcnt.h" +#include "Units.h" + +/****************************************************************************** + * Event Struct Types + * + * TODO: Move it into mozilla namespace. + ******************************************************************************/ +enum nsEventStructType +{ + // BasicEvents.h + NS_EVENT, // WidgetEvent + NS_GUI_EVENT, // WidgetGUIEvent + NS_INPUT_EVENT, // WidgetInputEvent + NS_UI_EVENT, // InternalUIEvent + + // Mouse related events + NS_MOUSE_EVENT, // nsMouseEvent + NS_MOUSE_SCROLL_EVENT, // nsMouseScrollEvent + NS_DRAG_EVENT, // nsDragEvent + NS_WHEEL_EVENT, // WheelEvent + + // Touchpad related events + NS_GESTURENOTIFY_EVENT, // nsGestureNotifyEvent + NS_SIMPLE_GESTURE_EVENT, // nsSimpleGestureEvent + NS_TOUCH_EVENT, // nsTouchEvent + + // Key or IME events + NS_KEY_EVENT, // nsKeyEvent + NS_COMPOSITION_EVENT, // nsCompositionEvent + NS_TEXT_EVENT, // nsTextEvent + + // IME related events + NS_QUERY_CONTENT_EVENT, // nsQueryContentEvent + NS_SELECTION_EVENT, // nsSelectionEvent + + // Scroll related events + NS_SCROLLPORT_EVENT, // nsScrollPortEvent + NS_SCROLLAREA_EVENT, // nsScrollAreaEvent + + // DOM events + NS_SCRIPT_ERROR_EVENT, // nsScriptErrorEvent + NS_MUTATION_EVENT, // nsMutationEvent + NS_FORM_EVENT, // nsFormEvent + NS_FOCUS_EVENT, // nsFocusEvent + NS_CLIPBOARD_EVENT, // nsClipboardEvent + + // SVG events + NS_SVGZOOM_EVENT, // GUIEvent + NS_SMIL_TIME_EVENT, // UIEvent + + // CSS events + NS_TRANSITION_EVENT, // nsTransitionEvent + NS_ANIMATION_EVENT, // nsAnimationEvent + + // Command events + NS_COMMAND_EVENT, // nsCommandEvent + NS_CONTENT_COMMAND_EVENT, // nsContentCommandEvent + + // Plugin event + NS_PLUGIN_EVENT // nsPluginEvent +}; + +/****************************************************************************** + * Messages + * + * TODO: Make them enum. + ******************************************************************************/ + +#define NS_EVENT_NULL 0 + + +#define NS_WINDOW_START 100 + +// Widget may be destroyed +#define NS_XUL_CLOSE (NS_WINDOW_START + 1) +// Key is pressed within a window +#define NS_KEY_PRESS (NS_WINDOW_START + 31) +// Key is released within a window +#define NS_KEY_UP (NS_WINDOW_START + 32) +// Key is pressed within a window +#define NS_KEY_DOWN (NS_WINDOW_START + 33) + +#define NS_RESIZE_EVENT (NS_WINDOW_START + 60) +#define NS_SCROLL_EVENT (NS_WINDOW_START + 61) + +// A plugin was clicked or otherwise focused. NS_PLUGIN_ACTIVATE should be +// used when the window is not active. NS_PLUGIN_FOCUS should be used when +// the window is active. In the latter case, the dispatcher of the event +// is expected to ensure that the plugin's widget is focused beforehand. +#define NS_PLUGIN_ACTIVATE (NS_WINDOW_START + 62) +#define NS_PLUGIN_FOCUS (NS_WINDOW_START + 63) + +#define NS_OFFLINE (NS_WINDOW_START + 64) +#define NS_ONLINE (NS_WINDOW_START + 65) + +// Indicates a resize will occur +#define NS_BEFORERESIZE_EVENT (NS_WINDOW_START + 66) + +// Indicates that the user is either idle or active +#define NS_MOZ_USER_IDLE (NS_WINDOW_START + 67) +#define NS_MOZ_USER_ACTIVE (NS_WINDOW_START + 68) + +// The resolution at which a plugin should draw has changed, for +// example as the result of changing from a HiDPI mode to a non- +// HiDPI mode. +#define NS_PLUGIN_RESOLUTION_CHANGED (NS_WINDOW_START + 69) + +#define NS_MOUSE_MESSAGE_START 300 +#define NS_MOUSE_MOVE (NS_MOUSE_MESSAGE_START) +#define NS_MOUSE_BUTTON_UP (NS_MOUSE_MESSAGE_START + 1) +#define NS_MOUSE_BUTTON_DOWN (NS_MOUSE_MESSAGE_START + 2) +#define NS_MOUSE_ENTER (NS_MOUSE_MESSAGE_START + 22) +#define NS_MOUSE_EXIT (NS_MOUSE_MESSAGE_START + 23) +#define NS_MOUSE_DOUBLECLICK (NS_MOUSE_MESSAGE_START + 24) +#define NS_MOUSE_CLICK (NS_MOUSE_MESSAGE_START + 27) +#define NS_MOUSE_ACTIVATE (NS_MOUSE_MESSAGE_START + 30) +#define NS_MOUSE_ENTER_SYNTH (NS_MOUSE_MESSAGE_START + 31) +#define NS_MOUSE_EXIT_SYNTH (NS_MOUSE_MESSAGE_START + 32) +#define NS_MOUSE_MOZHITTEST (NS_MOUSE_MESSAGE_START + 33) +#define NS_MOUSEENTER (NS_MOUSE_MESSAGE_START + 34) +#define NS_MOUSELEAVE (NS_MOUSE_MESSAGE_START + 35) + +#define NS_CONTEXTMENU_MESSAGE_START 500 +#define NS_CONTEXTMENU (NS_CONTEXTMENU_MESSAGE_START) + +#define NS_STREAM_EVENT_START 1100 +#define NS_LOAD (NS_STREAM_EVENT_START) +#define NS_PAGE_UNLOAD (NS_STREAM_EVENT_START + 1) +#define NS_HASHCHANGE (NS_STREAM_EVENT_START + 2) +#define NS_IMAGE_ABORT (NS_STREAM_EVENT_START + 3) +#define NS_LOAD_ERROR (NS_STREAM_EVENT_START + 4) +#define NS_POPSTATE (NS_STREAM_EVENT_START + 5) +#define NS_BEFORE_PAGE_UNLOAD (NS_STREAM_EVENT_START + 6) +#define NS_PAGE_RESTORE (NS_STREAM_EVENT_START + 7) +#define NS_READYSTATECHANGE (NS_STREAM_EVENT_START + 8) + +#define NS_FORM_EVENT_START 1200 +#define NS_FORM_SUBMIT (NS_FORM_EVENT_START) +#define NS_FORM_RESET (NS_FORM_EVENT_START + 1) +#define NS_FORM_CHANGE (NS_FORM_EVENT_START + 2) +#define NS_FORM_SELECTED (NS_FORM_EVENT_START + 3) +#define NS_FORM_INPUT (NS_FORM_EVENT_START + 4) +#define NS_FORM_INVALID (NS_FORM_EVENT_START + 5) + +//Need separate focus/blur notifications for non-native widgets +#define NS_FOCUS_EVENT_START 1300 +#define NS_FOCUS_CONTENT (NS_FOCUS_EVENT_START) +#define NS_BLUR_CONTENT (NS_FOCUS_EVENT_START + 1) + +#define NS_DRAGDROP_EVENT_START 1400 +#define NS_DRAGDROP_ENTER (NS_DRAGDROP_EVENT_START) +#define NS_DRAGDROP_OVER (NS_DRAGDROP_EVENT_START + 1) +#define NS_DRAGDROP_EXIT (NS_DRAGDROP_EVENT_START + 2) +#define NS_DRAGDROP_DRAGDROP (NS_DRAGDROP_EVENT_START + 3) +#define NS_DRAGDROP_GESTURE (NS_DRAGDROP_EVENT_START + 4) +#define NS_DRAGDROP_DRAG (NS_DRAGDROP_EVENT_START + 5) +#define NS_DRAGDROP_END (NS_DRAGDROP_EVENT_START + 6) +#define NS_DRAGDROP_START (NS_DRAGDROP_EVENT_START + 7) +#define NS_DRAGDROP_DROP (NS_DRAGDROP_EVENT_START + 8) +#define NS_DRAGDROP_OVER_SYNTH (NS_DRAGDROP_EVENT_START + 1) +#define NS_DRAGDROP_EXIT_SYNTH (NS_DRAGDROP_EVENT_START + 2) +#define NS_DRAGDROP_LEAVE_SYNTH (NS_DRAGDROP_EVENT_START + 9) + +// Events for popups +#define NS_XUL_EVENT_START 1500 +#define NS_XUL_POPUP_SHOWING (NS_XUL_EVENT_START) +#define NS_XUL_POPUP_SHOWN (NS_XUL_EVENT_START+1) +#define NS_XUL_POPUP_HIDING (NS_XUL_EVENT_START+2) +#define NS_XUL_POPUP_HIDDEN (NS_XUL_EVENT_START+3) +// NS_XUL_COMMAND used to be here (NS_XUL_EVENT_START+4) +#define NS_XUL_BROADCAST (NS_XUL_EVENT_START+5) +#define NS_XUL_COMMAND_UPDATE (NS_XUL_EVENT_START+6) +//@} + +// Scroll events +#define NS_MOUSE_SCROLL_START 1600 +#define NS_MOUSE_SCROLL (NS_MOUSE_SCROLL_START) +#define NS_MOUSE_PIXEL_SCROLL (NS_MOUSE_SCROLL_START + 1) + +#define NS_SCROLLPORT_START 1700 +#define NS_SCROLLPORT_UNDERFLOW (NS_SCROLLPORT_START) +#define NS_SCROLLPORT_OVERFLOW (NS_SCROLLPORT_START+1) + +// Mutation events defined elsewhere starting at 1800 + +#define NS_USER_DEFINED_EVENT 2000 + +// composition events +#define NS_COMPOSITION_EVENT_START 2200 +#define NS_COMPOSITION_START (NS_COMPOSITION_EVENT_START) +#define NS_COMPOSITION_END (NS_COMPOSITION_EVENT_START + 1) +#define NS_COMPOSITION_UPDATE (NS_COMPOSITION_EVENT_START + 2) + +// text events +#define NS_TEXT_START 2400 +#define NS_TEXT_TEXT (NS_TEXT_START) + +// UI events +#define NS_UI_EVENT_START 2500 +// this is not to be confused with NS_ACTIVATE! +#define NS_UI_ACTIVATE (NS_UI_EVENT_START) +#define NS_UI_FOCUSIN (NS_UI_EVENT_START + 1) +#define NS_UI_FOCUSOUT (NS_UI_EVENT_START + 2) + +// pagetransition events +#define NS_PAGETRANSITION_START 2700 +#define NS_PAGE_SHOW (NS_PAGETRANSITION_START + 1) +#define NS_PAGE_HIDE (NS_PAGETRANSITION_START + 2) + +// SVG events +#define NS_SVG_EVENT_START 2800 +#define NS_SVG_LOAD (NS_SVG_EVENT_START) +#define NS_SVG_UNLOAD (NS_SVG_EVENT_START + 1) +#define NS_SVG_ABORT (NS_SVG_EVENT_START + 2) +#define NS_SVG_ERROR (NS_SVG_EVENT_START + 3) +#define NS_SVG_RESIZE (NS_SVG_EVENT_START + 4) +#define NS_SVG_SCROLL (NS_SVG_EVENT_START + 5) + +// SVG Zoom events +#define NS_SVGZOOM_EVENT_START 2900 +#define NS_SVG_ZOOM (NS_SVGZOOM_EVENT_START) + +// XUL command events +#define NS_XULCOMMAND_EVENT_START 3000 +#define NS_XUL_COMMAND (NS_XULCOMMAND_EVENT_START) + +// Cut, copy, paste events +#define NS_CUTCOPYPASTE_EVENT_START 3100 +#define NS_COPY (NS_CUTCOPYPASTE_EVENT_START) +#define NS_CUT (NS_CUTCOPYPASTE_EVENT_START + 1) +#define NS_PASTE (NS_CUTCOPYPASTE_EVENT_START + 2) + +// Query the content information +#define NS_QUERY_CONTENT_EVENT_START 3200 +// Query for the selected text information, it return the selection offset, +// selection length and selected text. +#define NS_QUERY_SELECTED_TEXT (NS_QUERY_CONTENT_EVENT_START) +// Query for the text content of specified range, it returns actual lengh (if +// the specified range is too long) and the text of the specified range. +// Returns the entire text if requested length > actual length. +#define NS_QUERY_TEXT_CONTENT (NS_QUERY_CONTENT_EVENT_START + 1) +// Query for the caret rect of nth insertion point. The offset of the result is +// relative position from the top level widget. +#define NS_QUERY_CARET_RECT (NS_QUERY_CONTENT_EVENT_START + 3) +// Query for the bounding rect of a range of characters. This works on any +// valid character range given offset and length. Result is relative to top +// level widget coordinates +#define NS_QUERY_TEXT_RECT (NS_QUERY_CONTENT_EVENT_START + 4) +// Query for the bounding rect of the current focused frame. Result is relative +// to top level widget coordinates +#define NS_QUERY_EDITOR_RECT (NS_QUERY_CONTENT_EVENT_START + 5) +// Query for the current state of the content. The particular members of +// mReply that are set for each query content event will be valid on success. +#define NS_QUERY_CONTENT_STATE (NS_QUERY_CONTENT_EVENT_START + 6) +// Query for the selection in the form of a nsITransferable. +#define NS_QUERY_SELECTION_AS_TRANSFERABLE (NS_QUERY_CONTENT_EVENT_START + 7) +// Query for character at a point. This returns the character offset and its +// rect. The point is specified by Event::refPoint. +#define NS_QUERY_CHARACTER_AT_POINT (NS_QUERY_CONTENT_EVENT_START + 8) +// Query if the DOM element under Event::refPoint belongs to our widget +// or not. +#define NS_QUERY_DOM_WIDGET_HITTEST (NS_QUERY_CONTENT_EVENT_START + 9) + +// Video events +#define NS_MEDIA_EVENT_START 3300 +#define NS_LOADSTART (NS_MEDIA_EVENT_START) +#define NS_PROGRESS (NS_MEDIA_EVENT_START+1) +#define NS_SUSPEND (NS_MEDIA_EVENT_START+2) +#define NS_EMPTIED (NS_MEDIA_EVENT_START+3) +#define NS_STALLED (NS_MEDIA_EVENT_START+4) +#define NS_PLAY (NS_MEDIA_EVENT_START+5) +#define NS_PAUSE (NS_MEDIA_EVENT_START+6) +#define NS_LOADEDMETADATA (NS_MEDIA_EVENT_START+7) +#define NS_LOADEDDATA (NS_MEDIA_EVENT_START+8) +#define NS_WAITING (NS_MEDIA_EVENT_START+9) +#define NS_PLAYING (NS_MEDIA_EVENT_START+10) +#define NS_CANPLAY (NS_MEDIA_EVENT_START+11) +#define NS_CANPLAYTHROUGH (NS_MEDIA_EVENT_START+12) +#define NS_SEEKING (NS_MEDIA_EVENT_START+13) +#define NS_SEEKED (NS_MEDIA_EVENT_START+14) +#define NS_TIMEUPDATE (NS_MEDIA_EVENT_START+15) +#define NS_ENDED (NS_MEDIA_EVENT_START+16) +#define NS_RATECHANGE (NS_MEDIA_EVENT_START+17) +#define NS_DURATIONCHANGE (NS_MEDIA_EVENT_START+18) +#define NS_VOLUMECHANGE (NS_MEDIA_EVENT_START+19) +#define NS_MOZAUDIOAVAILABLE (NS_MEDIA_EVENT_START+20) + +// paint notification events +#define NS_NOTIFYPAINT_START 3400 +#define NS_AFTERPAINT (NS_NOTIFYPAINT_START) + +// Simple gesture events +#define NS_SIMPLE_GESTURE_EVENT_START 3500 +#define NS_SIMPLE_GESTURE_SWIPE_START (NS_SIMPLE_GESTURE_EVENT_START) +#define NS_SIMPLE_GESTURE_SWIPE_UPDATE (NS_SIMPLE_GESTURE_EVENT_START+1) +#define NS_SIMPLE_GESTURE_SWIPE_END (NS_SIMPLE_GESTURE_EVENT_START+2) +#define NS_SIMPLE_GESTURE_SWIPE (NS_SIMPLE_GESTURE_EVENT_START+3) +#define NS_SIMPLE_GESTURE_MAGNIFY_START (NS_SIMPLE_GESTURE_EVENT_START+4) +#define NS_SIMPLE_GESTURE_MAGNIFY_UPDATE (NS_SIMPLE_GESTURE_EVENT_START+5) +#define NS_SIMPLE_GESTURE_MAGNIFY (NS_SIMPLE_GESTURE_EVENT_START+6) +#define NS_SIMPLE_GESTURE_ROTATE_START (NS_SIMPLE_GESTURE_EVENT_START+7) +#define NS_SIMPLE_GESTURE_ROTATE_UPDATE (NS_SIMPLE_GESTURE_EVENT_START+8) +#define NS_SIMPLE_GESTURE_ROTATE (NS_SIMPLE_GESTURE_EVENT_START+9) +#define NS_SIMPLE_GESTURE_TAP (NS_SIMPLE_GESTURE_EVENT_START+10) +#define NS_SIMPLE_GESTURE_PRESSTAP (NS_SIMPLE_GESTURE_EVENT_START+11) +#define NS_SIMPLE_GESTURE_EDGE_STARTED (NS_SIMPLE_GESTURE_EVENT_START+12) +#define NS_SIMPLE_GESTURE_EDGE_CANCELED (NS_SIMPLE_GESTURE_EVENT_START+13) +#define NS_SIMPLE_GESTURE_EDGE_COMPLETED (NS_SIMPLE_GESTURE_EVENT_START+14) + +// These are used to send native events to plugins. +#define NS_PLUGIN_EVENT_START 3600 +#define NS_PLUGIN_INPUT_EVENT (NS_PLUGIN_EVENT_START) +#define NS_PLUGIN_FOCUS_EVENT (NS_PLUGIN_EVENT_START+1) + +// Events to manipulate selection (nsSelectionEvent) +#define NS_SELECTION_EVENT_START 3700 +// Clear any previous selection and set the given range as the selection +#define NS_SELECTION_SET (NS_SELECTION_EVENT_START) + +// Events of commands for the contents +#define NS_CONTENT_COMMAND_EVENT_START 3800 +#define NS_CONTENT_COMMAND_CUT (NS_CONTENT_COMMAND_EVENT_START) +#define NS_CONTENT_COMMAND_COPY (NS_CONTENT_COMMAND_EVENT_START+1) +#define NS_CONTENT_COMMAND_PASTE (NS_CONTENT_COMMAND_EVENT_START+2) +#define NS_CONTENT_COMMAND_DELETE (NS_CONTENT_COMMAND_EVENT_START+3) +#define NS_CONTENT_COMMAND_UNDO (NS_CONTENT_COMMAND_EVENT_START+4) +#define NS_CONTENT_COMMAND_REDO (NS_CONTENT_COMMAND_EVENT_START+5) +#define NS_CONTENT_COMMAND_PASTE_TRANSFERABLE (NS_CONTENT_COMMAND_EVENT_START+6) +// NS_CONTENT_COMMAND_SCROLL scrolls the nearest scrollable element to the +// currently focused content or latest DOM selection. This would normally be +// the same element scrolled by keyboard scroll commands, except that this event +// will scroll an element scrollable in either direction. I.e., if the nearest +// scrollable ancestor element can only be scrolled vertically, and horizontal +// scrolling is requested using this event, no scrolling will occur. +#define NS_CONTENT_COMMAND_SCROLL (NS_CONTENT_COMMAND_EVENT_START+7) + +// Event to gesture notification +#define NS_GESTURENOTIFY_EVENT_START 3900 + +#define NS_ORIENTATION_EVENT 4000 + +#define NS_SCROLLAREA_EVENT_START 4100 +#define NS_SCROLLEDAREACHANGED (NS_SCROLLAREA_EVENT_START) + +#define NS_TRANSITION_EVENT_START 4200 +#define NS_TRANSITION_END (NS_TRANSITION_EVENT_START) + +#define NS_ANIMATION_EVENT_START 4250 +#define NS_ANIMATION_START (NS_ANIMATION_EVENT_START) +#define NS_ANIMATION_END (NS_ANIMATION_EVENT_START + 1) +#define NS_ANIMATION_ITERATION (NS_ANIMATION_EVENT_START + 2) + +#define NS_SMIL_TIME_EVENT_START 4300 +#define NS_SMIL_BEGIN (NS_SMIL_TIME_EVENT_START) +#define NS_SMIL_END (NS_SMIL_TIME_EVENT_START + 1) +#define NS_SMIL_REPEAT (NS_SMIL_TIME_EVENT_START + 2) + +#define NS_WEBAUDIO_EVENT_START 4350 +#define NS_AUDIO_PROCESS (NS_WEBAUDIO_EVENT_START) +#define NS_AUDIO_COMPLETE (NS_WEBAUDIO_EVENT_START + 1) + +// script notification events +#define NS_NOTIFYSCRIPT_START 4500 +#define NS_BEFORE_SCRIPT_EXECUTE (NS_NOTIFYSCRIPT_START) +#define NS_AFTER_SCRIPT_EXECUTE (NS_NOTIFYSCRIPT_START+1) + +#define NS_PRINT_EVENT_START 4600 +#define NS_BEFOREPRINT (NS_PRINT_EVENT_START) +#define NS_AFTERPRINT (NS_PRINT_EVENT_START + 1) + +#define NS_MESSAGE_EVENT_START 4700 +#define NS_MESSAGE (NS_MESSAGE_EVENT_START) + +// Open and close events +#define NS_OPENCLOSE_EVENT_START 4800 +#define NS_OPEN (NS_OPENCLOSE_EVENT_START) +#define NS_CLOSE (NS_OPENCLOSE_EVENT_START+1) + +// Device motion and orientation +#define NS_DEVICE_ORIENTATION_START 4900 +#define NS_DEVICE_ORIENTATION (NS_DEVICE_ORIENTATION_START) +#define NS_DEVICE_MOTION (NS_DEVICE_ORIENTATION_START+1) +#define NS_DEVICE_PROXIMITY (NS_DEVICE_ORIENTATION_START+2) +#define NS_USER_PROXIMITY (NS_DEVICE_ORIENTATION_START+3) +#define NS_DEVICE_LIGHT (NS_DEVICE_ORIENTATION_START+4) + +#define NS_SHOW_EVENT 5000 + +// Fullscreen DOM API +#define NS_FULL_SCREEN_START 5100 +#define NS_FULLSCREENCHANGE (NS_FULL_SCREEN_START) +#define NS_FULLSCREENERROR (NS_FULL_SCREEN_START + 1) + +#define NS_TOUCH_EVENT_START 5200 +#define NS_TOUCH_START (NS_TOUCH_EVENT_START) +#define NS_TOUCH_MOVE (NS_TOUCH_EVENT_START+1) +#define NS_TOUCH_END (NS_TOUCH_EVENT_START+2) +#define NS_TOUCH_ENTER (NS_TOUCH_EVENT_START+3) +#define NS_TOUCH_LEAVE (NS_TOUCH_EVENT_START+4) +#define NS_TOUCH_CANCEL (NS_TOUCH_EVENT_START+5) + +// Pointerlock DOM API +#define NS_POINTERLOCK_START 5300 +#define NS_POINTERLOCKCHANGE (NS_POINTERLOCK_START) +#define NS_POINTERLOCKERROR (NS_POINTERLOCK_START + 1) + +#define NS_WHEEL_EVENT_START 5400 +#define NS_WHEEL_WHEEL (NS_WHEEL_EVENT_START) + +//System time is changed +#define NS_MOZ_TIME_CHANGE_EVENT 5500 + +// Network packet events. +#define NS_NETWORK_EVENT_START 5600 +#define NS_NETWORK_UPLOAD_EVENT (NS_NETWORK_EVENT_START + 1) +#define NS_NETWORK_DOWNLOAD_EVENT (NS_NETWORK_EVENT_START + 2) + +// MediaRecorder events. +#define NS_MEDIARECORDER_EVENT_START 5700 +#define NS_MEDIARECORDER_DATAAVAILABLE (NS_MEDIARECORDER_EVENT_START + 1) +#define NS_MEDIARECORDER_WARNING (NS_MEDIARECORDER_EVENT_START + 2) +#define NS_MEDIARECORDER_STOP (NS_MEDIARECORDER_EVENT_START + 3) + +#ifdef MOZ_GAMEPAD +// Gamepad input events +#define NS_GAMEPAD_START 6000 +#define NS_GAMEPAD_BUTTONDOWN (NS_GAMEPAD_START) +#define NS_GAMEPAD_BUTTONUP (NS_GAMEPAD_START+1) +#define NS_GAMEPAD_AXISMOVE (NS_GAMEPAD_START+2) +#define NS_GAMEPAD_CONNECTED (NS_GAMEPAD_START+3) +#define NS_GAMEPAD_DISCONNECTED (NS_GAMEPAD_START+4) +// Keep this defined to the same value as the event above +#define NS_GAMEPAD_END (NS_GAMEPAD_START+4) +#endif + +namespace mozilla { + +/****************************************************************************** + * mozilla::BaseEventFlags + * + * BaseEventFlags must be a POD struct for safe to use memcpy (including + * in ParamTraits). So don't make virtual methods, constructor, + * destructor and operators. + * This is necessary for VC which is NOT C++0x compiler. + ******************************************************************************/ + +struct BaseEventFlags +{ +public: + // If mIsTrusted is true, the event is a trusted event. Otherwise, it's + // an untrusted event. + bool mIsTrusted : 1; + // If mInBubblingPhase is true, the event is in bubbling phase or target + // phase. + bool mInBubblingPhase : 1; + // If mInCapturePhase is true, the event is in capture phase or target phase. + bool mInCapturePhase : 1; + // If mInSystemGroup is true, the event is being dispatched in system group. + bool mInSystemGroup: 1; + // If mCancelable is true, the event can be consumed. I.e., calling + // nsDOMEvent::PreventDefault() can prevent the default action. + bool mCancelable : 1; + // If mBubbles is true, the event can bubble. Otherwise, cannot be handled + // in bubbling phase. + bool mBubbles : 1; + // If mPropagationStopped is true, nsDOMEvent::StopPropagation() or + // nsDOMEvent::StopImmediatePropagation() has been called. + bool mPropagationStopped : 1; + // If mImmediatePropagationStopped is true, + // nsDOMEvent::StopImmediatePropagation() has been called. + // Note that mPropagationStopped must be true when this is true. + bool mImmediatePropagationStopped : 1; + // If mDefaultPrevented is true, the event has been consumed. + // E.g., nsDOMEvent::PreventDefault() has been called or + // the default action has been performed. + bool mDefaultPrevented : 1; + // If mDefaultPreventedByContent is true, the event has been + // consumed by content. + // Note that mDefaultPrevented must be true when this is true. + bool mDefaultPreventedByContent : 1; + // mMultipleActionsPrevented may be used when default handling don't want to + // be prevented, but only one of the event targets should handle the event. + // For example, when a