OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/gpu/v4l2_video_decode_accelerator.h" | 5 #include "media/gpu/v4l2_video_decode_accelerator.h" |
6 | 6 |
7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <fcntl.h> | 9 #include <fcntl.h> |
10 #include <linux/videodev2.h> | 10 #include <linux/videodev2.h> |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
171 output_streamon_(false), | 171 output_streamon_(false), |
172 output_buffer_queued_count_(0), | 172 output_buffer_queued_count_(0), |
173 output_dpb_size_(0), | 173 output_dpb_size_(0), |
174 output_planes_count_(0), | 174 output_planes_count_(0), |
175 picture_clearing_count_(0), | 175 picture_clearing_count_(0), |
176 device_poll_thread_("V4L2DevicePollThread"), | 176 device_poll_thread_("V4L2DevicePollThread"), |
177 egl_display_(egl_display), | 177 egl_display_(egl_display), |
178 get_gl_context_cb_(get_gl_context_cb), | 178 get_gl_context_cb_(get_gl_context_cb), |
179 make_context_current_cb_(make_context_current_cb), | 179 make_context_current_cb_(make_context_current_cb), |
180 video_profile_(VIDEO_CODEC_PROFILE_UNKNOWN), | 180 video_profile_(VIDEO_CODEC_PROFILE_UNKNOWN), |
181 input_format_fourcc_(0), | |
181 output_format_fourcc_(0), | 182 output_format_fourcc_(0), |
182 egl_image_format_fourcc_(0), | 183 egl_image_format_fourcc_(0), |
183 egl_image_planes_count_(0), | 184 egl_image_planes_count_(0), |
184 weak_this_factory_(this) { | 185 weak_this_factory_(this) { |
185 weak_this_ = weak_this_factory_.GetWeakPtr(); | 186 weak_this_ = weak_this_factory_.GetWeakPtr(); |
186 } | 187 } |
187 | 188 |
188 V4L2VideoDecodeAccelerator::~V4L2VideoDecodeAccelerator() { | 189 V4L2VideoDecodeAccelerator::~V4L2VideoDecodeAccelerator() { |
189 DCHECK(!decoder_thread_.IsRunning()); | 190 DCHECK(!decoder_thread_.IsRunning()); |
190 DCHECK(!device_poll_thread_.IsRunning()); | 191 DCHECK(!device_poll_thread_.IsRunning()); |
191 | 192 |
192 // These maps have members that should be manually destroyed, e.g. file | 193 // These maps have members that should be manually destroyed, e.g. file |
193 // descriptors, mmap() segments, etc. | 194 // descriptors, mmap() segments, etc. |
194 DCHECK(input_buffer_map_.empty()); | 195 DCHECK(input_buffer_map_.empty()); |
195 DCHECK(output_buffer_map_.empty()); | 196 DCHECK(output_buffer_map_.empty()); |
196 } | 197 } |
197 | 198 |
198 bool V4L2VideoDecodeAccelerator::Initialize(const Config& config, | 199 bool V4L2VideoDecodeAccelerator::Initialize(const Config& config, |
199 Client* client) { | 200 Client* client) { |
200 DVLOGF(3) << "profile: " << config.profile | 201 DVLOGF(3) << "profile: " << config.profile |
201 << ", output_mode=" << static_cast<int>(config.output_mode); | 202 << ", output_mode=" << static_cast<int>(config.output_mode); |
202 DCHECK(child_task_runner_->BelongsToCurrentThread()); | 203 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
203 DCHECK_EQ(decoder_state_, kUninitialized); | 204 DCHECK_EQ(decoder_state_, kUninitialized); |
204 | 205 |
205 if (!device_->SupportsDecodeProfileForV4L2PixelFormats( | |
206 config.profile, arraysize(supported_input_fourccs_), | |
207 supported_input_fourccs_)) { | |
208 DVLOGF(1) << "unsupported profile=" << config.profile; | |
209 return false; | |
210 } | |
211 | |
212 if (config.is_encrypted) { | 206 if (config.is_encrypted) { |
213 NOTREACHED() << "Encrypted streams are not supported for this VDA"; | 207 NOTREACHED() << "Encrypted streams are not supported for this VDA"; |
214 return false; | 208 return false; |
215 } | 209 } |
216 | 210 |
217 if (config.output_mode != Config::OutputMode::ALLOCATE && | 211 if (config.output_mode != Config::OutputMode::ALLOCATE && |
218 config.output_mode != Config::OutputMode::IMPORT) { | 212 config.output_mode != Config::OutputMode::IMPORT) { |
219 NOTREACHED() << "Only ALLOCATE and IMPORT OutputModes are supported"; | 213 NOTREACHED() << "Only ALLOCATE and IMPORT OutputModes are supported"; |
220 return false; | 214 return false; |
221 } | 215 } |
(...skipping 27 matching lines...) Expand all Loading... | |
249 #if defined(ARCH_CPU_ARMEL) | 243 #if defined(ARCH_CPU_ARMEL) |
250 if (!gl::g_driver_egl.ext.b_EGL_KHR_fence_sync) { | 244 if (!gl::g_driver_egl.ext.b_EGL_KHR_fence_sync) { |
251 LOGF(ERROR) << "context does not have EGL_KHR_fence_sync"; | 245 LOGF(ERROR) << "context does not have EGL_KHR_fence_sync"; |
252 return false; | 246 return false; |
253 } | 247 } |
254 #endif | 248 #endif |
255 } else { | 249 } else { |
256 DVLOGF(1) << "No GL callbacks provided, initializing without GL support"; | 250 DVLOGF(1) << "No GL callbacks provided, initializing without GL support"; |
257 } | 251 } |
258 | 252 |
253 input_format_fourcc_ = | |
254 V4L2Device::VideoCodecProfileToV4L2PixFmt(video_profile_, false); | |
255 | |
256 if (!device_->Open(V4L2Device::Type::kDecoder, input_format_fourcc_)) { | |
257 DVLOGF(1) << "Failed to open device for profile: " << config.profile | |
258 << " fourcc: " << std::hex << input_format_fourcc_; | |
kcwu
2016/10/07 11:19:05
0x
Pawel Osciak
2016/10/11 06:13:46
Done.
| |
259 return false; | |
260 } | |
261 | |
259 // Capabilities check. | 262 // Capabilities check. |
260 struct v4l2_capability caps; | 263 struct v4l2_capability caps; |
261 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; | 264 const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; |
262 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); | 265 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps); |
263 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { | 266 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { |
264 LOGF(ERROR) << "ioctl() failed: VIDIOC_QUERYCAP" | 267 LOGF(ERROR) << "ioctl() failed: VIDIOC_QUERYCAP" |
265 << ", caps check failed: 0x" << std::hex << caps.capabilities; | 268 << ", caps check failed: 0x" << std::hex << caps.capabilities; |
266 return false; | 269 return false; |
267 } | 270 } |
268 | 271 |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
714 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { | 717 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { |
715 DVLOGF(2); | 718 DVLOGF(2); |
716 decode_client_ = decode_client; | 719 decode_client_ = decode_client; |
717 decode_task_runner_ = decode_task_runner; | 720 decode_task_runner_ = decode_task_runner; |
718 return true; | 721 return true; |
719 } | 722 } |
720 | 723 |
721 // static | 724 // static |
722 VideoDecodeAccelerator::SupportedProfiles | 725 VideoDecodeAccelerator::SupportedProfiles |
723 V4L2VideoDecodeAccelerator::GetSupportedProfiles() { | 726 V4L2VideoDecodeAccelerator::GetSupportedProfiles() { |
724 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); | 727 scoped_refptr<V4L2Device> device = V4L2Device::Create(); |
725 if (!device) | 728 if (!device) |
726 return SupportedProfiles(); | 729 return SupportedProfiles(); |
727 | 730 |
728 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), | 731 return device->GetSupportedDecodeProfiles(arraysize(supported_input_fourccs_), |
729 supported_input_fourccs_); | 732 supported_input_fourccs_); |
730 } | 733 } |
731 | 734 |
732 void V4L2VideoDecodeAccelerator::DecodeTask( | 735 void V4L2VideoDecodeAccelerator::DecodeTask( |
733 const BitstreamBuffer& bitstream_buffer) { | 736 const BitstreamBuffer& bitstream_buffer) { |
734 DVLOGF(3) << "input_id=" << bitstream_buffer.id(); | 737 DVLOGF(3) << "input_id=" << bitstream_buffer.id(); |
(...skipping 1218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1953 } | 1956 } |
1954 | 1957 |
1955 bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat( | 1958 bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat( |
1956 const struct v4l2_format& format, | 1959 const struct v4l2_format& format, |
1957 const gfx::Size& visible_size) { | 1960 const gfx::Size& visible_size) { |
1958 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); | 1961 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); |
1959 output_planes_count_ = format.fmt.pix_mp.num_planes; | 1962 output_planes_count_ = format.fmt.pix_mp.num_planes; |
1960 coded_size_.SetSize(format.fmt.pix_mp.width, format.fmt.pix_mp.height); | 1963 coded_size_.SetSize(format.fmt.pix_mp.width, format.fmt.pix_mp.height); |
1961 visible_size_ = visible_size; | 1964 visible_size_ = visible_size; |
1962 if (image_processor_device_) { | 1965 if (image_processor_device_) { |
1963 V4L2ImageProcessor processor(image_processor_device_); | |
1964 egl_image_size_ = visible_size_; | 1966 egl_image_size_ = visible_size_; |
1965 egl_image_planes_count_ = 0; | 1967 egl_image_planes_count_ = 0; |
1966 if (!processor.TryOutputFormat(egl_image_format_fourcc_, &egl_image_size_, | 1968 if (!V4L2ImageProcessor::TryOutputFormat( |
1967 &egl_image_planes_count_)) { | 1969 output_format_fourcc_, egl_image_format_fourcc_, &egl_image_size_, |
1970 &egl_image_planes_count_)) { | |
1968 LOGF(ERROR) << "Fail to get output size and plane count of processor"; | 1971 LOGF(ERROR) << "Fail to get output size and plane count of processor"; |
1969 return false; | 1972 return false; |
1970 } | 1973 } |
1971 } else { | 1974 } else { |
1972 egl_image_size_ = coded_size_; | 1975 egl_image_size_ = coded_size_; |
1973 egl_image_planes_count_ = output_planes_count_; | 1976 egl_image_planes_count_ = output_planes_count_; |
1974 } | 1977 } |
1975 DVLOGF(3) << "new resolution: " << coded_size_.ToString() | 1978 DVLOGF(3) << "new resolution: " << coded_size_.ToString() |
1976 << ", visible size: " << visible_size_.ToString() | 1979 << ", visible size: " << visible_size_.ToString() |
1977 << ", decoder output planes count: " << output_planes_count_ | 1980 << ", decoder output planes count: " << output_planes_count_ |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2061 return true; | 2064 return true; |
2062 } | 2065 } |
2063 | 2066 |
2064 bool V4L2VideoDecodeAccelerator::SetupFormats() { | 2067 bool V4L2VideoDecodeAccelerator::SetupFormats() { |
2065 // We always run this as we prepare to initialize. | 2068 // We always run this as we prepare to initialize. |
2066 DCHECK(child_task_runner_->BelongsToCurrentThread()); | 2069 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
2067 DCHECK_EQ(decoder_state_, kUninitialized); | 2070 DCHECK_EQ(decoder_state_, kUninitialized); |
2068 DCHECK(!input_streamon_); | 2071 DCHECK(!input_streamon_); |
2069 DCHECK(!output_streamon_); | 2072 DCHECK(!output_streamon_); |
2070 | 2073 |
2071 __u32 input_format_fourcc = | |
2072 V4L2Device::VideoCodecProfileToV4L2PixFmt(video_profile_, false); | |
2073 if (!input_format_fourcc) { | |
2074 NOTREACHED(); | |
2075 return false; | |
2076 } | |
2077 | |
2078 size_t input_size; | 2074 size_t input_size; |
2079 gfx::Size max_resolution, min_resolution; | 2075 gfx::Size max_resolution, min_resolution; |
2080 device_->GetSupportedResolution(input_format_fourcc, &min_resolution, | 2076 device_->GetSupportedResolution(input_format_fourcc_, &min_resolution, |
2081 &max_resolution); | 2077 &max_resolution); |
2082 if (max_resolution.width() > 1920 && max_resolution.height() > 1088) | 2078 if (max_resolution.width() > 1920 && max_resolution.height() > 1088) |
2083 input_size = kInputBufferMaxSizeFor4k; | 2079 input_size = kInputBufferMaxSizeFor4k; |
2084 else | 2080 else |
2085 input_size = kInputBufferMaxSizeFor1080p; | 2081 input_size = kInputBufferMaxSizeFor1080p; |
2086 | 2082 |
2087 struct v4l2_fmtdesc fmtdesc; | 2083 struct v4l2_fmtdesc fmtdesc; |
2088 memset(&fmtdesc, 0, sizeof(fmtdesc)); | 2084 memset(&fmtdesc, 0, sizeof(fmtdesc)); |
2089 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 2085 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
2090 bool is_format_supported = false; | 2086 bool is_format_supported = false; |
2091 while (device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0) { | 2087 while (device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0) { |
2092 if (fmtdesc.pixelformat == input_format_fourcc) { | 2088 if (fmtdesc.pixelformat == input_format_fourcc_) { |
2093 is_format_supported = true; | 2089 is_format_supported = true; |
2094 break; | 2090 break; |
2095 } | 2091 } |
2096 ++fmtdesc.index; | 2092 ++fmtdesc.index; |
2097 } | 2093 } |
2098 | 2094 |
2099 if (!is_format_supported) { | 2095 if (!is_format_supported) { |
2100 DVLOGF(1) << "Input fourcc " << input_format_fourcc | 2096 DVLOGF(1) << "Input fourcc " << input_format_fourcc_ |
2101 << " not supported by device."; | 2097 << " not supported by device."; |
2102 return false; | 2098 return false; |
2103 } | 2099 } |
2104 | 2100 |
2105 struct v4l2_format format; | 2101 struct v4l2_format format; |
2106 memset(&format, 0, sizeof(format)); | 2102 memset(&format, 0, sizeof(format)); |
2107 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 2103 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
2108 format.fmt.pix_mp.pixelformat = input_format_fourcc; | 2104 format.fmt.pix_mp.pixelformat = input_format_fourcc_; |
2109 format.fmt.pix_mp.plane_fmt[0].sizeimage = input_size; | 2105 format.fmt.pix_mp.plane_fmt[0].sizeimage = input_size; |
2110 format.fmt.pix_mp.num_planes = 1; | 2106 format.fmt.pix_mp.num_planes = 1; |
2111 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format); | 2107 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format); |
2112 | 2108 |
2113 // We have to set up the format for output, because the driver may not allow | 2109 // We have to set up the format for output, because the driver may not allow |
2114 // changing it once we start streaming; whether it can support our chosen | 2110 // changing it once we start streaming; whether it can support our chosen |
2115 // output format or not may depend on the input format. | 2111 // output format or not may depend on the input format. |
2116 memset(&fmtdesc, 0, sizeof(fmtdesc)); | 2112 memset(&fmtdesc, 0, sizeof(fmtdesc)); |
2117 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 2113 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
2118 while (device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0) { | 2114 while (device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0) { |
2119 if (device_->CanCreateEGLImageFrom(fmtdesc.pixelformat)) { | 2115 if (device_->CanCreateEGLImageFrom(fmtdesc.pixelformat)) { |
2120 output_format_fourcc_ = fmtdesc.pixelformat; | 2116 output_format_fourcc_ = fmtdesc.pixelformat; |
2121 break; | 2117 break; |
2122 } | 2118 } |
2123 ++fmtdesc.index; | 2119 ++fmtdesc.index; |
2124 } | 2120 } |
2125 | 2121 |
2126 if (output_format_fourcc_ == 0) { | 2122 if (output_format_fourcc_ == 0) { |
2127 DVLOGF(1) << "Could not find a usable output format. Try image processor"; | 2123 DVLOGF(1) << "Could not find a usable output format. Try image processor"; |
2128 image_processor_device_ = V4L2Device::Create(V4L2Device::kImageProcessor); | 2124 if (!V4L2ImageProcessor::IsSupported()) { |
2129 if (!image_processor_device_) { | 2125 DVLOGF(1) << "Image processor not available"; |
2130 DVLOGF(1) << "No image processor device."; | |
2131 return false; | 2126 return false; |
2132 } | 2127 } |
2133 output_format_fourcc_ = FindImageProcessorInputFormat(); | 2128 output_format_fourcc_ = FindImageProcessorInputFormat(); |
2134 if (output_format_fourcc_ == 0) { | 2129 if (output_format_fourcc_ == 0) { |
2135 LOGF(ERROR) << "Can't find a usable input format from image processor"; | 2130 LOGF(ERROR) << "Can't find a usable input format from image processor"; |
2136 return false; | 2131 return false; |
2137 } | 2132 } |
2138 egl_image_format_fourcc_ = FindImageProcessorOutputFormat(); | 2133 egl_image_format_fourcc_ = FindImageProcessorOutputFormat(); |
2139 if (egl_image_format_fourcc_ == 0) { | 2134 if (egl_image_format_fourcc_ == 0) { |
2140 LOGF(ERROR) << "Can't find a usable output format from image processor"; | 2135 LOGF(ERROR) << "Can't find a usable output format from image processor"; |
2141 return false; | 2136 return false; |
2142 } | 2137 } |
2138 image_processor_device_ = V4L2Device::Create(); | |
2139 if (!image_processor_device_) { | |
2140 DVLOGF(1) << "Could not create a V4L2Device for image processor"; | |
2141 return false; | |
2142 } | |
2143 egl_image_device_ = image_processor_device_; | 2143 egl_image_device_ = image_processor_device_; |
2144 } else { | 2144 } else { |
2145 if (output_mode_ == Config::OutputMode::IMPORT) { | 2145 if (output_mode_ == Config::OutputMode::IMPORT) { |
2146 LOGF(ERROR) << "Import mode without image processor is not implemented " | 2146 LOGF(ERROR) << "Import mode without image processor is not implemented " |
2147 << "yet."; | 2147 << "yet."; |
2148 return false; | 2148 return false; |
2149 } | 2149 } |
2150 image_processor_device_ = nullptr; | |
kcwu
2016/10/07 11:19:05
DCHECK(image_processor_device_ == nullptr) at line
Pawel Osciak
2016/10/11 06:13:46
Done.
| |
2150 egl_image_format_fourcc_ = output_format_fourcc_; | 2151 egl_image_format_fourcc_ = output_format_fourcc_; |
2151 egl_image_device_ = device_; | 2152 egl_image_device_ = device_; |
2152 } | 2153 } |
2153 DVLOGF(2) << "Output format=" << output_format_fourcc_; | 2154 DVLOGF(2) << "Output format=" << output_format_fourcc_; |
2154 | 2155 |
2155 // Just set the fourcc for output; resolution, etc., will come from the | 2156 // Just set the fourcc for output; resolution, etc., will come from the |
2156 // driver once it extracts it from the stream. | 2157 // driver once it extracts it from the stream. |
2157 memset(&format, 0, sizeof(format)); | 2158 memset(&format, 0, sizeof(format)); |
2158 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 2159 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
2159 format.fmt.pix_mp.pixelformat = output_format_fourcc_; | 2160 format.fmt.pix_mp.pixelformat = output_format_fourcc_; |
2160 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format); | 2161 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format); |
2161 | 2162 |
2162 return true; | 2163 return true; |
2163 } | 2164 } |
2164 | 2165 |
2165 uint32_t V4L2VideoDecodeAccelerator::FindImageProcessorInputFormat() { | 2166 uint32_t V4L2VideoDecodeAccelerator::FindImageProcessorInputFormat() { |
2166 V4L2ImageProcessor image_processor(image_processor_device_); | |
2167 std::vector<uint32_t> processor_input_formats = | 2167 std::vector<uint32_t> processor_input_formats = |
2168 image_processor.GetSupportedInputFormats(); | 2168 V4L2ImageProcessor::GetSupportedInputFormats(); |
2169 | |
2169 struct v4l2_fmtdesc fmtdesc; | 2170 struct v4l2_fmtdesc fmtdesc; |
2170 memset(&fmtdesc, 0, sizeof(fmtdesc)); | 2171 memset(&fmtdesc, 0, sizeof(fmtdesc)); |
2171 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 2172 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
2172 while (device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0) { | 2173 while (device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0) { |
2173 if (std::find(processor_input_formats.begin(), | 2174 if (std::find(processor_input_formats.begin(), |
2174 processor_input_formats.end(), | 2175 processor_input_formats.end(), |
2175 fmtdesc.pixelformat) != processor_input_formats.end()) { | 2176 fmtdesc.pixelformat) != processor_input_formats.end()) { |
2176 DVLOGF(1) << "Image processor input format=" << fmtdesc.pixelformat; | 2177 DVLOGF(1) << "Image processor input format=" << fmtdesc.description; |
2177 return fmtdesc.pixelformat; | 2178 return fmtdesc.pixelformat; |
2178 } | 2179 } |
2179 ++fmtdesc.index; | 2180 ++fmtdesc.index; |
2180 } | 2181 } |
2181 return 0; | 2182 return 0; |
2182 } | 2183 } |
2183 | 2184 |
2184 uint32_t V4L2VideoDecodeAccelerator::FindImageProcessorOutputFormat() { | 2185 uint32_t V4L2VideoDecodeAccelerator::FindImageProcessorOutputFormat() { |
2185 // Prefer YVU420 and NV12 because ArcGpuVideoDecodeAccelerator only supports | 2186 // Prefer YVU420 and NV12 because ArcGpuVideoDecodeAccelerator only supports |
2186 // single physical plane. Prefer YVU420 over NV12 because chrome rendering | 2187 // single physical plane. Prefer YVU420 over NV12 because chrome rendering |
2187 // supports YV12 only. | 2188 // supports YV12 only. |
2188 static const uint32_t kPreferredFormats[] = {V4L2_PIX_FMT_YVU420, | 2189 static const uint32_t kPreferredFormats[] = {V4L2_PIX_FMT_YVU420, |
2189 V4L2_PIX_FMT_NV12}; | 2190 V4L2_PIX_FMT_NV12}; |
2190 auto preferred_formats_first = [](uint32_t a, uint32_t b) -> bool { | 2191 auto preferred_formats_first = [](uint32_t a, uint32_t b) -> bool { |
2191 auto iter_a = std::find(std::begin(kPreferredFormats), | 2192 auto iter_a = std::find(std::begin(kPreferredFormats), |
2192 std::end(kPreferredFormats), a); | 2193 std::end(kPreferredFormats), a); |
2193 auto iter_b = std::find(std::begin(kPreferredFormats), | 2194 auto iter_b = std::find(std::begin(kPreferredFormats), |
2194 std::end(kPreferredFormats), b); | 2195 std::end(kPreferredFormats), b); |
2195 return iter_a < iter_b; | 2196 return iter_a < iter_b; |
2196 }; | 2197 }; |
2197 | 2198 |
2198 V4L2ImageProcessor image_processor(image_processor_device_); | |
2199 std::vector<uint32_t> processor_output_formats = | 2199 std::vector<uint32_t> processor_output_formats = |
2200 image_processor.GetSupportedOutputFormats(); | 2200 V4L2ImageProcessor::GetSupportedOutputFormats(); |
2201 | 2201 |
2202 // Move the preferred formats to the front. | 2202 // Move the preferred formats to the front. |
2203 std::sort(processor_output_formats.begin(), processor_output_formats.end(), | 2203 std::sort(processor_output_formats.begin(), processor_output_formats.end(), |
2204 preferred_formats_first); | 2204 preferred_formats_first); |
2205 | 2205 |
2206 for (uint32_t processor_output_format : processor_output_formats) { | 2206 for (uint32_t processor_output_format : processor_output_formats) { |
2207 if (device_->CanCreateEGLImageFrom(processor_output_format)) { | 2207 if (device_->CanCreateEGLImageFrom(processor_output_format)) { |
2208 DVLOGF(1) << "Image processor output format=" << processor_output_format; | 2208 DVLOGF(1) << "Image processor output format=" << processor_output_format; |
2209 return processor_output_format; | 2209 return processor_output_format; |
2210 } | 2210 } |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2344 // done with this one. After we get the buffers, we'll go back into kIdle and | 2344 // done with this one. After we get the buffers, we'll go back into kIdle and |
2345 // kick off further event processing, and eventually go back into kDecoding | 2345 // kick off further event processing, and eventually go back into kDecoding |
2346 // once no more events are pending (if any). | 2346 // once no more events are pending (if any). |
2347 decoder_state_ = kAwaitingPictureBuffers; | 2347 decoder_state_ = kAwaitingPictureBuffers; |
2348 | 2348 |
2349 return true; | 2349 return true; |
2350 } | 2350 } |
2351 | 2351 |
2352 void V4L2VideoDecodeAccelerator::DestroyInputBuffers() { | 2352 void V4L2VideoDecodeAccelerator::DestroyInputBuffers() { |
2353 DVLOGF(3); | 2353 DVLOGF(3); |
2354 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); | 2354 DCHECK(!decoder_thread_.IsRunning() || |
2355 decoder_thread_.task_runner()->BelongsToCurrentThread()); | |
2355 DCHECK(!input_streamon_); | 2356 DCHECK(!input_streamon_); |
2356 | 2357 |
2358 if (input_buffer_map_.empty()) | |
2359 return; | |
2360 | |
2357 for (size_t i = 0; i < input_buffer_map_.size(); ++i) { | 2361 for (size_t i = 0; i < input_buffer_map_.size(); ++i) { |
2358 if (input_buffer_map_[i].address != NULL) { | 2362 if (input_buffer_map_[i].address != NULL) { |
2359 device_->Munmap(input_buffer_map_[i].address, | 2363 device_->Munmap(input_buffer_map_[i].address, |
2360 input_buffer_map_[i].length); | 2364 input_buffer_map_[i].length); |
2361 } | 2365 } |
2362 } | 2366 } |
2363 | 2367 |
2364 struct v4l2_requestbuffers reqbufs; | 2368 struct v4l2_requestbuffers reqbufs; |
2365 memset(&reqbufs, 0, sizeof(reqbufs)); | 2369 memset(&reqbufs, 0, sizeof(reqbufs)); |
2366 reqbufs.count = 0; | 2370 reqbufs.count = 0; |
2367 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 2371 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
2368 reqbufs.memory = V4L2_MEMORY_MMAP; | 2372 reqbufs.memory = V4L2_MEMORY_MMAP; |
2369 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); | 2373 IOCTL_OR_LOG_ERROR(VIDIOC_REQBUFS, &reqbufs); |
2370 | 2374 |
2371 input_buffer_map_.clear(); | 2375 input_buffer_map_.clear(); |
2372 free_input_buffers_.clear(); | 2376 free_input_buffers_.clear(); |
2373 } | 2377 } |
2374 | 2378 |
2375 bool V4L2VideoDecodeAccelerator::DestroyOutputBuffers() { | 2379 bool V4L2VideoDecodeAccelerator::DestroyOutputBuffers() { |
2376 DVLOGF(3); | 2380 DVLOGF(3); |
2377 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); | 2381 DCHECK(!decoder_thread_.IsRunning() || |
2382 decoder_thread_.task_runner()->BelongsToCurrentThread()); | |
2378 DCHECK(!output_streamon_); | 2383 DCHECK(!output_streamon_); |
2379 bool success = true; | 2384 bool success = true; |
2380 | 2385 |
2386 if (output_buffer_map_.empty()) | |
2387 return true; | |
2388 | |
2381 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { | 2389 for (size_t i = 0; i < output_buffer_map_.size(); ++i) { |
2382 OutputRecord& output_record = output_buffer_map_[i]; | 2390 OutputRecord& output_record = output_buffer_map_[i]; |
2383 | 2391 |
2384 if (output_record.egl_image != EGL_NO_IMAGE_KHR) { | 2392 if (output_record.egl_image != EGL_NO_IMAGE_KHR) { |
2385 child_task_runner_->PostTask( | 2393 child_task_runner_->PostTask( |
2386 FROM_HERE, | 2394 FROM_HERE, |
2387 base::Bind(base::IgnoreResult(&V4L2Device::DestroyEGLImage), device_, | 2395 base::Bind(base::IgnoreResult(&V4L2Device::DestroyEGLImage), device_, |
2388 egl_display_, output_record.egl_image)); | 2396 egl_display_, output_record.egl_image)); |
2389 } | 2397 } |
2390 | 2398 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2504 StartResolutionChange(); | 2512 StartResolutionChange(); |
2505 } | 2513 } |
2506 } | 2514 } |
2507 | 2515 |
2508 void V4L2VideoDecodeAccelerator::ImageProcessorError() { | 2516 void V4L2VideoDecodeAccelerator::ImageProcessorError() { |
2509 LOGF(ERROR) << "Image processor error"; | 2517 LOGF(ERROR) << "Image processor error"; |
2510 NOTIFY_ERROR(PLATFORM_FAILURE); | 2518 NOTIFY_ERROR(PLATFORM_FAILURE); |
2511 } | 2519 } |
2512 | 2520 |
2513 } // namespace media | 2521 } // namespace media |
OLD | NEW |