From 8e61bb9037f316c6747c42704e920db2de98fabc Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Wed, 20 Jul 2022 17:31:09 +0900 Subject: [PATCH] virtio: video: decoder: ffmpeg: use zero-copy for input buffers Use the newly introduced AvBufferRef of our ffmpeg crate to give transfer ownership of the input mapping to libavcodec and avoid a copy of the input data. libavcodec will drop our input buffer when it is done with it, which will make it automatically send the NotifyEndOfInputBuffer to signal it can be reused. BUG=b:169295147 TEST=v4l2r's simple_decoder can decode a H.264 stream. Change-Id: I9322e5b236a511ba3b8f064080111cfb3133d0e5 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3782038 Commit-Queue: Keiichi Watanabe Auto-Submit: Alexandre Courbot Tested-by: Alexandre Courbot Reviewed-by: Keiichi Watanabe --- devices/src/virtio/video/decoder/backend/ffmpeg.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/devices/src/virtio/video/decoder/backend/ffmpeg.rs b/devices/src/virtio/video/decoder/backend/ffmpeg.rs index 102abac5eb..ac93887487 100644 --- a/devices/src/virtio/video/decoder/backend/ffmpeg.rs +++ b/devices/src/virtio/video/decoder/backend/ffmpeg.rs @@ -83,7 +83,7 @@ impl AvBufferSource for InputBuffer { /// Types of input job we can receive from the crosvm decoder code. enum CodecJob { - Packet(InputBuffer), + Packet(AvPacket<'static>), Flush, } @@ -214,10 +214,9 @@ impl FfmpegDecoderSession { /// input at the moment. fn try_send_packet( &mut self, - input_packet: &mut InputBuffer, + input_packet: &AvPacket<'static>, ) -> Result { - let avpacket = AvPacket::new(input_packet.bitstream_id as i64, input_packet); - match self.context.try_send_packet(&avpacket) { + match self.context.try_send_packet(input_packet) { Ok(true) => Ok(true), // The codec cannot take more input at the moment, we'll try again after we receive some // frames. @@ -452,7 +451,11 @@ impl DecoderSession for FfmpegDecoderSession { event_queue: Arc::downgrade(&self.event_queue), }; - self.codec_jobs.push_back(CodecJob::Packet(input_buffer)); + let avpacket = AvPacket::new_owned(bitstream_id as i64, input_buffer) + .context("while creating AvPacket") + .map_err(VideoError::BackendFailure)?; + + self.codec_jobs.push_back(CodecJob::Packet(avpacket)); self.try_decode() .context("while decoding")