1313
1414namespace mozilla {
1515
16+ extern LazyLogModule sPEMLog ;
17+
18+ #define LOG_INTERNAL (level, fmt, ...) \
19+ MOZ_LOG_FMT (sPEMLog , LogLevel::level, \
20+ " [RemoteMediaDataEncoderParent] {}: " fmt, __func__, \
21+ __VA_ARGS__)
22+ #define LOGE (fmt, ...) LOG_INTERNAL(Error, fmt, __VA_ARGS__)
23+ #define LOGW (fmt, ...) LOG_INTERNAL(Warning, fmt, __VA_ARGS__)
24+ #define LOGD (fmt, ...) LOG_INTERNAL(Debug, fmt, __VA_ARGS__)
25+ #define LOGV (fmt, ...) LOG_INTERNAL(Verbose, fmt, __VA_ARGS__)
26+
27+ #define LOGE_IF (condition, fmt, ...) \
28+ do { \
29+ if (condition) { \
30+ LOGE (fmt, __VA_ARGS__); \
31+ } \
32+ } while (0 )
33+
1634#define AUTO_MARKER (var, postfix ) \
1735 AutoWebCodecsMarker var (" RemoteMediaDataEncoderParent" , postfix);
1836
@@ -72,7 +90,6 @@ IPCResult RemoteMediaDataEncoderParent::RecvInit(InitResolver&& aResolver) {
7290 return ;
7391 }
7492
75- // TODO: Pass batch-encoding capability.
7693 nsCString hardwareReason;
7794 bool hardware = encoder->IsHardwareAccelerated (hardwareReason);
7895 resolver (EncodeInitCompletionIPDL{encoder->GetDescriptionName (),
@@ -88,75 +105,96 @@ IPCResult RemoteMediaDataEncoderParent::RecvEncode(
88105 return IPC_OK ();
89106 }
90107
91- RefPtr<MediaData> frame ;
108+ nsTArray< RefPtr<MediaData>> frames ;
92109
93110 if (mConfig .IsAudio () &&
94111 aData.type () == EncodedInputIPDL::TArrayOfRemoteAudioData) {
95112 auto remoteAudioArray = aData.get_ArrayOfRemoteAudioData ();
96- if (remoteAudioArray->Count () != 1 ) {
113+ if (remoteAudioArray->IsEmpty ()) {
114+ LOGE (" [{}] no audio frames received" , fmt::ptr (this ));
97115 aResolver (MediaResult (NS_ERROR_INVALID_ARG, __func__));
98116 return IPC_OK ();
99117 }
100118
101- frame = remoteAudioArray->ElementAt (0 ).downcast <MediaData>();
119+ LOGV (" [{}] recv {} audio frames" , fmt::ptr (this ),
120+ remoteAudioArray->Count ());
121+ for (size_t i = 0 ; i < remoteAudioArray->Count (); i++) {
122+ frames.AppendElement (
123+ remoteAudioArray->ElementAt (i).downcast <MediaData>());
124+ }
102125 } else if (mConfig .IsVideo () &&
103126 aData.type () == EncodedInputIPDL::TArrayOfRemoteVideoData) {
104127 auto remoteVideoArray = aData.get_ArrayOfRemoteVideoData ();
105- if (remoteVideoArray->Array ().Length () != 1 ) {
128+ if (remoteVideoArray->Array ().IsEmpty ()) {
129+ LOGE (" [{}] no video frames received" , fmt::ptr (this ));
106130 aResolver (MediaResult (NS_ERROR_INVALID_ARG, __func__));
107131 return IPC_OK ();
108132 }
109133
110- auto data = std::move (remoteVideoArray->Array ().LastElement ());
111- if (!data.image ().IsEmpty ()) {
112- AUTO_MARKER (marker, " .RecvEncode.TransferToImage" );
113- RefPtr<layers::Image> image =
114- data.image ().TransferToImage (mBufferRecycleBin );
115- marker.End ();
116- if (image) {
117- frame = VideoData::CreateFromImage (
118- data.display (), data.base ().offset (), data.base ().time (),
119- data.base ().duration (), image, data.base ().keyframe (),
120- data.base ().timecode ())
121- .downcast <MediaData>();
134+ LOGV (" [{}] recv {} video frames" , fmt::ptr (this ),
135+ remoteVideoArray->Array ().Length ());
136+ for (size_t i = 0 ; i < remoteVideoArray->Array ().Length (); i++) {
137+ RefPtr<MediaData> frame;
138+ auto data = std::move (remoteVideoArray->Array ().ElementAt (i));
139+ if (!data.image ().IsEmpty ()) {
140+ AUTO_MARKER (marker, " .RecvEncode.TransferToImage" );
141+ RefPtr<layers::Image> image =
142+ data.image ().TransferToImage (mBufferRecycleBin );
143+ marker.End ();
144+ LOGE_IF (!image, " [{}] failed to get image from video frame at index {}" ,
145+ fmt::ptr (this ), i);
146+ if (image) {
147+ frame = VideoData::CreateFromImage (
148+ data.display (), data.base ().offset (), data.base ().time (),
149+ data.base ().duration (), image, data.base ().keyframe (),
150+ data.base ().timecode ())
151+ .downcast <MediaData>();
152+ }
153+ } else {
154+ LOGW (" [{}] empty image in video frame at index {}" , fmt::ptr (this ), i);
155+ frame = MakeRefPtr<NullData>(data.base ().offset (), data.base ().time (),
156+ data.base ().duration ());
157+ }
158+
159+ if (NS_WARN_IF(!frame)) {
160+ LOGE (" [{}] failed to create video frame" , fmt::ptr (this ));
161+ aResolver (MediaResult (NS_ERROR_OUT_OF_MEMORY, __func__));
162+ return IPC_OK ();
122163 }
123- } else {
124- frame = MakeRefPtr<NullData>(data.base ().offset (), data.base ().time (),
125- data.base ().duration ());
164+
165+ frames.AppendElement (std::move (frame));
126166 }
127167 } else {
168+ LOGE (" [{}] invalid input data type" , fmt::ptr (this ));
128169 aResolver (MediaResult (NS_ERROR_INVALID_ARG, __func__));
129170 return IPC_OK ();
130171 }
131172
132- if (NS_WARN_IF(!frame)) {
133- aResolver (MediaResult (NS_ERROR_OUT_OF_MEMORY, __func__));
134- return IPC_OK ();
135- }
136-
137- mEncoder ->Encode (frame)->Then (
138- GetCurrentSerialEventTarget (), __func__,
139- [self = RefPtr{this }, resolver = std::move (aResolver)](
140- MediaDataEncoder::EncodePromise::ResolveOrRejectValue&& aValue) {
141- if (aValue.IsReject ()) {
142- resolver (aValue.RejectValue ());
143- return ;
144- }
173+ LOGV (" [{}] encoding {} frames" , fmt::ptr (this ), frames.Length ());
174+ mEncoder ->Encode (std::move (frames))
175+ ->Then (
176+ GetCurrentSerialEventTarget (), __func__,
177+ [self = RefPtr{this }, resolver = std::move (aResolver)](
178+ MediaDataEncoder::EncodePromise::ResolveOrRejectValue&& aValue) {
179+ if (aValue.IsReject ()) {
180+ resolver (aValue.RejectValue ());
181+ return ;
182+ }
145183
146- auto ticket = MakeRefPtr<ShmemRecycleTicket>();
147- auto samples = MakeRefPtr<ArrayOfRemoteMediaRawData>();
148- if (!samples->Fill (aValue.ResolveValue (), [&](size_t aSize) {
149- return self->AllocateBuffer (aSize, ticket);
150- })) {
151- self->ReleaseTicket (ticket);
152- resolver (MediaResult (NS_ERROR_OUT_OF_MEMORY, __func__));
153- return ;
154- }
184+ auto ticket = MakeRefPtr<ShmemRecycleTicket>();
185+ auto samples = MakeRefPtr<ArrayOfRemoteMediaRawData>();
186+ if (!samples->Fill (aValue.ResolveValue (), [&](size_t aSize) {
187+ return self->AllocateBuffer (aSize, ticket);
188+ })) {
189+ self->ReleaseTicket (ticket);
190+ resolver (MediaResult (NS_ERROR_OUT_OF_MEMORY, __func__));
191+ return ;
192+ }
155193
156- uint32_t ticketId = ++self->mTicketCounter ;
157- self->mTickets [ticketId] = std::move (ticket);
158- resolver (EncodeCompletionIPDL (samples, ticketId));
159- });
194+ uint32_t ticketId = ++self->mTicketCounter ;
195+ self->mTickets [ticketId] = std::move (ticket);
196+ resolver (EncodeCompletionIPDL (samples, ticketId));
197+ });
160198 return IPC_OK ();
161199}
162200
@@ -273,6 +311,12 @@ void RemoteMediaDataEncoderParent::ActorDestroy(ActorDestroyReason aWhy) {
273311 CleanupShmemRecycleAllocator ();
274312}
275313
314+ #undef LOGE
315+ #undef LOGW
316+ #undef LOGD
317+ #undef LOGV
318+ #undef LOGE_IF
319+ #undef LOG_INTERNAL
276320#undef AUTO_MARKER
277321
278322} // namespace mozilla
0 commit comments