@@ -153,9 +153,26 @@ RefPtr<MediaDataEncoder::EncodePromise> AndroidDataEncoder::Encode(
153153 RefPtr<AndroidDataEncoder> self = this ;
154154 MOZ_ASSERT (aSample != nullptr );
155155
156- RefPtr<const MediaData> sample (aSample);
156+ return InvokeAsync (
157+ mTaskQueue , __func__,
158+ [self, sample = RefPtr<MediaData>(const_cast <MediaData*>(aSample))]() {
159+ return self->ProcessEncode ({sample});
160+ });
161+ }
162+
163+ // TODO(Bug 1984936): For realtime mode, resolve the promise after the first
164+ // sample's result is available, then continue processing remaining samples.
165+ // This allows the caller to keep submitting new samples while the encoder
166+ // handles pending ones.
167+ RefPtr<MediaDataEncoder::EncodePromise> AndroidDataEncoder::Encode (
168+ nsTArray<RefPtr<MediaData>>&& aSamples) {
169+ RefPtr<AndroidDataEncoder> self = this ;
170+ MOZ_ASSERT (!aSamples.IsEmpty ());
171+
157172 return InvokeAsync (mTaskQueue , __func__,
158- [self, sample]() { return self->ProcessEncode (sample); });
173+ [self, samples = std::move (aSamples)]() mutable {
174+ return self->ProcessEncode (std::move (samples));
175+ });
159176}
160177
161178static jni::ByteBuffer::LocalRef ConvertI420ToNV12Buffer (
@@ -193,36 +210,41 @@ static jni::ByteBuffer::LocalRef ConvertI420ToNV12Buffer(
193210}
194211
195212RefPtr<MediaDataEncoder::EncodePromise> AndroidDataEncoder::ProcessEncode (
196- const RefPtr<const MediaData>& aSample ) {
213+ nsTArray< RefPtr<MediaData>>&& aSamples ) {
197214 AssertOnTaskQueue ();
198215
199216 REJECT_IF_ERROR ();
200217
201- RefPtr<const VideoData> sample (aSample->As <const VideoData>());
202- MOZ_ASSERT (sample);
203-
204- mInputSampleDuration = aSample->mDuration ;
218+ // TODO(Bug 1984936): Looping here for large batches is inefficient, as it can
219+ // take excessive shared memory and file descriptors due to passing both input
220+ // and output buffers between the content and media codec processes.
221+ for (auto & s : aSamples) {
222+ RefPtr<const VideoData> sample (s->As <const VideoData>());
223+ MOZ_ASSERT (sample);
224+
225+ mInputSampleDuration = s->mDuration ;
226+
227+ // Bug 1789846: Check with the Encoder if MediaCodec has a stride or height
228+ // value to use.
229+ jni::ByteBuffer::LocalRef buffer = ConvertI420ToNV12Buffer (
230+ sample, mYUVBuffer , mJavaEncoder ->GetInputFormatStride (),
231+ mJavaEncoder ->GetInputFormatYPlaneHeight ());
232+ if (!buffer) {
233+ return EncodePromise::CreateAndReject (NS_ERROR_ILLEGAL_INPUT, __func__);
234+ }
205235
206- // Bug 1789846: Check with the Encoder if MediaCodec has a stride or height
207- // value to use.
208- jni::ByteBuffer::LocalRef buffer = ConvertI420ToNV12Buffer (
209- sample, mYUVBuffer , mJavaEncoder -> GetInputFormatStride (),
210- mJavaEncoder -> GetInputFormatYPlaneHeight ());
211- if (!buffer) {
212- return EncodePromise::CreateAndReject (NS_ERROR_ILLEGAL_INPUT, __func__ );
213- }
236+ if (s-> mKeyframe ) {
237+ mInputBufferInfo -> Set ( 0 , AssertedCast< int32_t >( mYUVBuffer -> Length ()),
238+ s-> mTime . ToMicroseconds (),
239+ java::sdk::MediaCodec::BUFFER_FLAG_SYNC_FRAME);
240+ } else {
241+ mInputBufferInfo -> Set ( 0 , AssertedCast< int32_t >( mYUVBuffer -> Length ()),
242+ s-> mTime . ToMicroseconds (), 0 );
243+ }
214244
215- if (aSample->mKeyframe ) {
216- mInputBufferInfo ->Set (0 , AssertedCast<int32_t >(mYUVBuffer ->Length ()),
217- aSample->mTime .ToMicroseconds (),
218- java::sdk::MediaCodec::BUFFER_FLAG_SYNC_FRAME);
219- } else {
220- mInputBufferInfo ->Set (0 , AssertedCast<int32_t >(mYUVBuffer ->Length ()),
221- aSample->mTime .ToMicroseconds (), 0 );
245+ mJavaEncoder ->Input (buffer, mInputBufferInfo , nullptr );
222246 }
223247
224- mJavaEncoder ->Input (buffer, mInputBufferInfo , nullptr );
225-
226248 if (mEncodedData .Length () > 0 ) {
227249 EncodedData pending = std::move (mEncodedData );
228250 return EncodePromise::CreateAndResolve (std::move (pending), __func__);
0 commit comments