Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(517)

Side by Side Diff: media/gpu/v4l2_video_decode_accelerator.cc

Issue 2398883002: Add support for multiple V4L2 video devices of the same type. (Closed)
Patch Set: Address comments, reorganize V4L2Device::Type. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698