66
77#include " jsapi/RTCEncodedFrameBase.h"
88
9+ #include " api/frame_transformer_interface.h"
910#include " js/ArrayBuffer.h"
1011#include " js/GCAPI.h"
1112#include " mozilla/dom/ScriptSettings.h"
@@ -21,53 +22,63 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RTCEncodedFrameBase)
2122 NS_INTERFACE_MAP_ENTRY (nsISupports)
2223NS_INTERFACE_MAP_END
2324
24- RTCEncodedFrameBase::RTCEncodedFrameBase (
25- nsIGlobalObject* aGlobal,
26- std::unique_ptr<webrtc::TransformableFrameInterface> aFrame,
27- uint64_t aCounter)
28- : mGlobal (aGlobal),
29- mFrame (std::move(aFrame)),
30- mCounter(aCounter),
31- mTimestamp(mFrame ->GetTimestamp ()) {
25+ RTCEncodedFrameBase::RTCEncodedFrameBase (nsIGlobalObject* aGlobal,
26+ RTCEncodedFrameState& aState)
27+ : mGlobal (aGlobal), mState (aState), mData (nullptr ) {
28+ mState .mTimestamp = mState .mFrame ->GetTimestamp ();
3229 AutoJSAPI jsapi;
3330 if (NS_WARN_IF(!jsapi.Init (mGlobal ))) {
3431 return ;
3532 }
3633
3734 // Avoid a copy
3835 mData = JS::NewArrayBufferWithUserOwnedContents (
39- jsapi.cx (), mFrame ->GetData ().size (), (void *)(mFrame ->GetData ().data ()));
36+ jsapi.cx (), mState .mFrame ->GetData ().size (),
37+ (void *)(mState .mFrame ->GetData ().data ()));
4038}
4139
4240RTCEncodedFrameBase::~RTCEncodedFrameBase () = default ;
4341
44- unsigned long RTCEncodedFrameBase::Timestamp () const { return mTimestamp ; }
42+ unsigned long RTCEncodedFrameBase::Timestamp () const {
43+ return mState .mTimestamp ;
44+ }
4545
4646void RTCEncodedFrameBase::SetData (const ArrayBuffer& aData) {
4747 mData .set (aData.Obj ());
48- if (mFrame ) {
48+ if (mState . mFrame ) {
4949 aData.ProcessData ([&](const Span<uint8_t >& aData, JS::AutoCheckCannotGC&&) {
50- mFrame ->SetData (
50+ mState . mFrame ->SetData (
5151 webrtc::ArrayView<const uint8_t >(aData.Elements (), aData.Length ()));
5252 });
5353 }
5454}
5555
56- void RTCEncodedFrameBase::GetData (JSContext* aCx, JS::Rooted<JSObject*>* aObj) {
56+ void RTCEncodedFrameBase::GetData (JSContext* aCx,
57+ JS::Rooted<JSObject*>* aObj) const {
5758 aObj->set (mData );
5859}
5960
60- uint64_t RTCEncodedFrameBase::GetCounter () const { return mCounter ; }
61+ uint64_t RTCEncodedFrameBase::GetCounter () const { return mState . mCounter ; }
6162
6263std::unique_ptr<webrtc::TransformableFrameInterface>
6364RTCEncodedFrameBase::TakeFrame () {
64- AutoJSAPI jsapi;
65- if (!jsapi.Init (mGlobal )) {
66- MOZ_CRASH (" Could not init JSAPI!" );
65+ if (mState .mFrame ) {
66+ AutoJSAPI jsapi;
67+ if (!jsapi.Init (mGlobal )) {
68+ MOZ_CRASH (" Could not init JSAPI!" );
69+ }
70+ // If the JS buffer was transferred (or otherwise detached), neuter native.
71+ JS::Rooted<JSObject*> rootedData (jsapi.cx (), mData );
72+ if (rootedData && JS::IsDetachedArrayBufferObject (rootedData)) {
73+ mState .mFrame .reset ();
74+ return nullptr ;
75+ }
76+ // Still attached: detach now since we're consuming the frame.
77+ JS::DetachArrayBuffer (jsapi.cx (), rootedData);
6778 }
68- JS::Rooted<JSObject*> rootedData (jsapi.cx (), mData );
69- JS::DetachArrayBuffer (jsapi.cx (), rootedData);
70- return std::move (mFrame );
79+ return std::move (mState .mFrame );
7180}
7281
82+ RTCEncodedFrameState::~RTCEncodedFrameState () = default ;
83+
7384} // namespace mozilla::dom
0 commit comments