Commit e179a1de authored by Hirokazu Honda's avatar Hirokazu Honda Committed by Commit Bot

media/gpu/v4l2VEA: Add Flush() support to V4L2VEA using ImageProcessor

V4L2VEA::Flush() code doesn't work if it uses
ImageProcessor. This CL changes V4L2VEA so that
its Flush() works regardless of using ImageProcessor.

Bug: 1128768
Test: video_encode_accelerator_tests on kukui
Change-Id: Ief9fab611ecd015c0e6e17784f27821809d270bb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2537515
Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarEugene Zemtsov <eugene@chromium.org>
Reviewed-by: default avatarAlexandre Courbot <acourbot@chromium.org>
Cr-Commit-Position: refs/heads/master@{#827211}
parent cb0e3caa
......@@ -441,6 +441,7 @@ bool V4L2VideoEncodeAccelerator::CreateImageProcessor(
VLOGF(1) << "Failed initializing image processor";
return false;
}
num_frames_in_image_processor_ = 0;
// The output of image processor is the input of encoder. Output coded
// width of processor must be the same as input coded width of encoder.
......@@ -628,6 +629,10 @@ void V4L2VideoEncodeAccelerator::FrameProcessed(
encoder_input_queue_.emplace(std::move(frame), force_keyframe,
output_buffer_index);
CHECK_GT(num_frames_in_image_processor_, 0u);
num_frames_in_image_processor_--;
MaybeFlushImageProcessor();
encoder_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&V4L2VideoEncodeAccelerator::Enqueue, weak_this_));
......@@ -752,16 +757,6 @@ void V4L2VideoEncodeAccelerator::EncodeTask(scoped_refptr<VideoFrame> frame,
return;
if (image_processor_) {
if (!frame) {
DCHECK(!flush_callback_.is_null());
NOTREACHED()
<< "Flushing is not supported when using an image processor and this "
"situation should not happen for well behaved clients.";
NOTIFY_ERROR(kIllegalStateError);
child_task_runner_->PostTask(
FROM_HERE, base::BindOnce(std::move(flush_callback_), false));
return;
}
image_processor_input_queue_.emplace(std::move(frame), force_keyframe);
InputImageProcessorTask();
} else {
......@@ -859,13 +854,34 @@ bool V4L2VideoEncodeAccelerator::ReconfigureFormatIfNeeded(
return true;
}
void V4L2VideoEncodeAccelerator::MaybeFlushImageProcessor() {
DCHECK_CALLED_ON_VALID_SEQUENCE(encoder_sequence_checker_);
DCHECK(image_processor_);
if (image_processor_input_queue_.size() == 1 &&
!image_processor_input_queue_.front().frame &&
num_frames_in_image_processor_ == 0) {
// Flush the encoder once the image processor is done with its own flush.
DVLOGF(3) << "All frames to be flush have been processed by "
<< "|image_processor_|. Move the flush request to the encoder";
image_processor_input_queue_.pop();
encoder_input_queue_.emplace(nullptr, false);
}
}
void V4L2VideoEncodeAccelerator::InputImageProcessorTask() {
DCHECK_CALLED_ON_VALID_SEQUENCE(encoder_sequence_checker_);
MaybeFlushImageProcessor();
if (free_image_processor_output_buffer_indices_.empty())
return;
if (image_processor_input_queue_.empty())
return;
// The flush request is at the top. Waiting until all frames are processed by
// the image processor.
if (!image_processor_input_queue_.front().frame)
return;
const size_t output_buffer_index =
free_image_processor_output_buffer_indices_.back();
free_image_processor_output_buffer_indices_.pop_back();
......@@ -895,6 +911,8 @@ void V4L2VideoEncodeAccelerator::InputImageProcessorTask() {
NOTIFY_ERROR(kPlatformFailureError);
}
}
num_frames_in_image_processor_++;
}
void V4L2VideoEncodeAccelerator::UseOutputBitstreamBufferTask(
......
......@@ -191,6 +191,8 @@ class MEDIA_GPU_EXPORT V4L2VideoEncodeAccelerator
// |image_processor_|.
void InputImageProcessorTask();
void MaybeFlushImageProcessor();
// Change encoding parameters.
void RequestEncodingParametersChangeTask(uint32_t bitrate,
uint32_t framerate);
......@@ -335,6 +337,8 @@ class MEDIA_GPU_EXPORT V4L2VideoEncodeAccelerator
std::vector<size_t> free_image_processor_output_buffer_indices_;
// Video frames ready to be processed. Only accessed on child thread.
base::queue<InputFrameInfo> image_processor_input_queue_;
// The number of frames that are being processed by |image_processor_|.
size_t num_frames_in_image_processor_ = 0;
const scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner_;
SEQUENCE_CHECKER(encoder_sequence_checker_);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment