Index: media/gpu/v4l2_video_decode_accelerator.cc |
diff --git a/media/gpu/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2_video_decode_accelerator.cc |
index 86a73cc53abd88f953fe7226a31b6e94225cfa7d..2a1ce1a78e942f4577f073fbca4b70cbaff56401 100644 |
--- a/media/gpu/v4l2_video_decode_accelerator.cc |
+++ b/media/gpu/v4l2_video_decode_accelerator.cc |
@@ -178,6 +178,7 @@ V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator( |
get_gl_context_cb_(get_gl_context_cb), |
make_context_current_cb_(make_context_current_cb), |
video_profile_(VIDEO_CODEC_PROFILE_UNKNOWN), |
+ input_format_fourcc_(0), |
output_format_fourcc_(0), |
egl_image_format_fourcc_(0), |
egl_image_planes_count_(0), |
@@ -202,13 +203,6 @@ bool V4L2VideoDecodeAccelerator::Initialize(const Config& config, |
DCHECK(child_task_runner_->BelongsToCurrentThread()); |
DCHECK_EQ(decoder_state_, kUninitialized); |
- if (!device_->SupportsDecodeProfileForV4L2PixelFormats( |
- config.profile, arraysize(supported_input_fourccs_), |
- supported_input_fourccs_)) { |
- DVLOGF(1) << "unsupported profile=" << config.profile; |
- return false; |
- } |
- |
if (config.is_encrypted) { |
NOTREACHED() << "Encrypted streams are not supported for this VDA"; |
return false; |
@@ -256,6 +250,15 @@ bool V4L2VideoDecodeAccelerator::Initialize(const Config& config, |
DVLOGF(1) << "No GL callbacks provided, initializing without GL support"; |
} |
+ input_format_fourcc_ = |
+ V4L2Device::VideoCodecProfileToV4L2PixFmt(video_profile_, false); |
+ |
+ if (!device_->Open(V4L2Device::Type::kDecoder, input_format_fourcc_)) { |
+ DVLOGF(1) << "Failed to open device for profile: " << config.profile |
+ << " fourcc: " << std::hex << "0x" << input_format_fourcc_; |
+ return false; |
+ } |
+ |
// Capabilities check. |
struct v4l2_capability caps; |
const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; |
@@ -721,7 +724,7 @@ bool V4L2VideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( |
// static |
VideoDecodeAccelerator::SupportedProfiles |
V4L2VideoDecodeAccelerator::GetSupportedProfiles() { |
- scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); |
+ scoped_refptr<V4L2Device> device = V4L2Device::Create(); |
if (!device) |
return SupportedProfiles(); |
@@ -1960,11 +1963,11 @@ bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat( |
coded_size_.SetSize(format.fmt.pix_mp.width, format.fmt.pix_mp.height); |
visible_size_ = visible_size; |
if (image_processor_device_) { |
- V4L2ImageProcessor processor(image_processor_device_); |
egl_image_size_ = visible_size_; |
egl_image_planes_count_ = 0; |
- if (!processor.TryOutputFormat(egl_image_format_fourcc_, &egl_image_size_, |
- &egl_image_planes_count_)) { |
+ if (!V4L2ImageProcessor::TryOutputFormat( |
+ output_format_fourcc_, egl_image_format_fourcc_, &egl_image_size_, |
+ &egl_image_planes_count_)) { |
LOGF(ERROR) << "Fail to get output size and plane count of processor"; |
return false; |
} |
@@ -2068,16 +2071,9 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() { |
DCHECK(!input_streamon_); |
DCHECK(!output_streamon_); |
- __u32 input_format_fourcc = |
- V4L2Device::VideoCodecProfileToV4L2PixFmt(video_profile_, false); |
- if (!input_format_fourcc) { |
- NOTREACHED(); |
- return false; |
- } |
- |
size_t input_size; |
gfx::Size max_resolution, min_resolution; |
- device_->GetSupportedResolution(input_format_fourcc, &min_resolution, |
+ device_->GetSupportedResolution(input_format_fourcc_, &min_resolution, |
&max_resolution); |
if (max_resolution.width() > 1920 && max_resolution.height() > 1088) |
input_size = kInputBufferMaxSizeFor4k; |
@@ -2089,7 +2085,7 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() { |
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
bool is_format_supported = false; |
while (device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0) { |
- if (fmtdesc.pixelformat == input_format_fourcc) { |
+ if (fmtdesc.pixelformat == input_format_fourcc_) { |
is_format_supported = true; |
break; |
} |
@@ -2097,7 +2093,7 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() { |
} |
if (!is_format_supported) { |
- DVLOGF(1) << "Input fourcc " << input_format_fourcc |
+ DVLOGF(1) << "Input fourcc " << input_format_fourcc_ |
<< " not supported by device."; |
return false; |
} |
@@ -2105,7 +2101,7 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() { |
struct v4l2_format format; |
memset(&format, 0, sizeof(format)); |
format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
- format.fmt.pix_mp.pixelformat = input_format_fourcc; |
+ format.fmt.pix_mp.pixelformat = input_format_fourcc_; |
format.fmt.pix_mp.plane_fmt[0].sizeimage = input_size; |
format.fmt.pix_mp.num_planes = 1; |
IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format); |
@@ -2123,11 +2119,11 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() { |
++fmtdesc.index; |
} |
+ DCHECK(!image_processor_device_); |
if (output_format_fourcc_ == 0) { |
DVLOGF(1) << "Could not find a usable output format. Try image processor"; |
- image_processor_device_ = V4L2Device::Create(V4L2Device::kImageProcessor); |
- if (!image_processor_device_) { |
- DVLOGF(1) << "No image processor device."; |
+ if (!V4L2ImageProcessor::IsSupported()) { |
+ DVLOGF(1) << "Image processor not available"; |
return false; |
} |
output_format_fourcc_ = FindImageProcessorInputFormat(); |
@@ -2140,6 +2136,11 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() { |
LOGF(ERROR) << "Can't find a usable output format from image processor"; |
return false; |
} |
+ image_processor_device_ = V4L2Device::Create(); |
+ if (!image_processor_device_) { |
+ DVLOGF(1) << "Could not create a V4L2Device for image processor"; |
+ return false; |
+ } |
egl_image_device_ = image_processor_device_; |
} else { |
if (output_mode_ == Config::OutputMode::IMPORT) { |
@@ -2163,9 +2164,9 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() { |
} |
uint32_t V4L2VideoDecodeAccelerator::FindImageProcessorInputFormat() { |
- V4L2ImageProcessor image_processor(image_processor_device_); |
std::vector<uint32_t> processor_input_formats = |
- image_processor.GetSupportedInputFormats(); |
+ V4L2ImageProcessor::GetSupportedInputFormats(); |
+ |
struct v4l2_fmtdesc fmtdesc; |
memset(&fmtdesc, 0, sizeof(fmtdesc)); |
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
@@ -2173,7 +2174,7 @@ uint32_t V4L2VideoDecodeAccelerator::FindImageProcessorInputFormat() { |
if (std::find(processor_input_formats.begin(), |
processor_input_formats.end(), |
fmtdesc.pixelformat) != processor_input_formats.end()) { |
- DVLOGF(1) << "Image processor input format=" << fmtdesc.pixelformat; |
+ DVLOGF(1) << "Image processor input format=" << fmtdesc.description; |
return fmtdesc.pixelformat; |
} |
++fmtdesc.index; |
@@ -2195,9 +2196,8 @@ uint32_t V4L2VideoDecodeAccelerator::FindImageProcessorOutputFormat() { |
return iter_a < iter_b; |
}; |
- V4L2ImageProcessor image_processor(image_processor_device_); |
std::vector<uint32_t> processor_output_formats = |
- image_processor.GetSupportedOutputFormats(); |
+ V4L2ImageProcessor::GetSupportedOutputFormats(); |
// Move the preferred formats to the front. |
std::sort(processor_output_formats.begin(), processor_output_formats.end(), |
@@ -2351,9 +2351,13 @@ bool V4L2VideoDecodeAccelerator::CreateOutputBuffers() { |
void V4L2VideoDecodeAccelerator::DestroyInputBuffers() { |
DVLOGF(3); |
- DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); |
+ DCHECK(!decoder_thread_.IsRunning() || |
+ decoder_thread_.task_runner()->BelongsToCurrentThread()); |
DCHECK(!input_streamon_); |
+ if (input_buffer_map_.empty()) |
+ return; |
+ |
for (size_t i = 0; i < input_buffer_map_.size(); ++i) { |
if (input_buffer_map_[i].address != NULL) { |
device_->Munmap(input_buffer_map_[i].address, |
@@ -2374,10 +2378,14 @@ void V4L2VideoDecodeAccelerator::DestroyInputBuffers() { |
bool V4L2VideoDecodeAccelerator::DestroyOutputBuffers() { |
DVLOGF(3); |
- DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); |
+ DCHECK(!decoder_thread_.IsRunning() || |
+ decoder_thread_.task_runner()->BelongsToCurrentThread()); |
DCHECK(!output_streamon_); |
bool success = true; |
+ if (output_buffer_map_.empty()) |
+ return true; |
+ |
for (size_t i = 0; i < output_buffer_map_.size(); ++i) { |
OutputRecord& output_record = output_buffer_map_[i]; |