RTCEncodedFrameBase.cpp (3367B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 6 7 #include "jsapi/RTCEncodedFrameBase.h" 8 9 #include "api/frame_transformer_interface.h" 10 #include "js/ArrayBuffer.h" 11 #include "js/GCAPI.h" 12 #include "mozilla/dom/ScriptSettings.h" 13 #include "nsIGlobalObject.h" 14 15 namespace mozilla::dom { 16 17 NS_IMPL_CYCLE_COLLECTION_CLASS(RTCEncodedFrameBase) 18 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(RTCEncodedFrameBase) 19 using ::ImplCycleCollectionUnlink; 20 tmp->DetachData(); 21 NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal) 22 NS_IMPL_CYCLE_COLLECTION_UNLINK(mData) 23 NS_IMPL_CYCLE_COLLECTION_UNLINK_END 24 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(RTCEncodedFrameBase) 25 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal) 26 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 27 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(RTCEncodedFrameBase) 28 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBERS(mData) 29 NS_IMPL_CYCLE_COLLECTION_TRACE_END 30 31 NS_IMPL_CYCLE_COLLECTING_ADDREF(RTCEncodedFrameBase) 32 NS_IMPL_CYCLE_COLLECTING_RELEASE(RTCEncodedFrameBase) 33 34 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RTCEncodedFrameBase) 35 NS_INTERFACE_MAP_ENTRY(nsISupports) 36 NS_INTERFACE_MAP_END 37 38 RTCEncodedFrameBase::RTCEncodedFrameBase(nsIGlobalObject* aGlobal, 39 RTCEncodedFrameState& aState) 40 : mGlobal(aGlobal), mState(aState), mData(nullptr) { 41 mState.mTimestamp = mState.mFrame->GetTimestamp(); 42 AutoJSAPI jsapi; 43 if (NS_WARN_IF(!jsapi.Init(mGlobal))) { 44 return; 45 } 46 47 // Avoid a copy 48 mData = JS::NewArrayBufferWithUserOwnedContents( 49 jsapi.cx(), mState.mFrame->GetData().size(), 50 (void*)(mState.mFrame->GetData().data())); 51 } 52 53 RTCEncodedFrameState::RTCEncodedFrameState( 54 std::unique_ptr<webrtc::TransformableFrameInterface> aFrame, 55 uint64_t aCounter, unsigned long aTimestamp) 56 : mFrame(std::move(aFrame)), mCounter(aCounter), mTimestamp(aTimestamp) {} 57 58 RTCEncodedFrameBase::~RTCEncodedFrameBase() { DetachData(); } 59 60 void RTCEncodedFrameBase::DetachData() { 61 // We might have handled this in unlink already 62 if (mGlobal) { 63 AutoJSAPI jsapi; 64 if (NS_WARN_IF(!jsapi.Init(mGlobal))) { 65 return; 66 } 67 68 JS::Rooted<JSObject*> rootedData(jsapi.cx(), mData); 69 if (rootedData) { 70 JS::DetachArrayBuffer(jsapi.cx(), rootedData); 71 } 72 } 73 } 74 75 unsigned long RTCEncodedFrameBase::Timestamp() const { 76 return mState.mTimestamp; 77 } 78 79 void RTCEncodedFrameBase::SetData(const ArrayBuffer& aData) { 80 DetachData(); 81 mData.set(aData.Obj()); 82 if (mState.mFrame) { 83 aData.ProcessData([&](const Span<uint8_t>& aData, JS::AutoCheckCannotGC&&) { 84 mState.mFrame->SetData( 85 webrtc::ArrayView<const uint8_t>(aData.Elements(), aData.Length())); 86 }); 87 } 88 } 89 90 void RTCEncodedFrameBase::GetData(JSContext* aCx, 91 JS::Rooted<JSObject*>* aObj) const { 92 aObj->set(mData); 93 } 94 95 uint64_t RTCEncodedFrameBase::GetCounter() const { return mState.mCounter; } 96 97 std::unique_ptr<webrtc::TransformableFrameInterface> 98 RTCEncodedFrameBase::TakeFrame() { 99 DetachData(); 100 return std::move(mState.mFrame); 101 } 102 103 RTCEncodedFrameState::~RTCEncodedFrameState() = default; 104 105 } // namespace mozilla::dom