OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "content/common/gpu/media/vaapi_jpeg_decode_accelerator.h" | 5 #include "content/common/gpu/media/vaapi_jpeg_decode_accelerator.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/thread_task_runner_handle.h" | 10 #include "base/thread_task_runner_handle.h" |
(...skipping 10 matching lines...) Expand all Loading... | |
21 // UMA errors that the VaapiJpegDecodeAccelerator class reports. | 21 // UMA errors that the VaapiJpegDecodeAccelerator class reports. |
22 enum VAJDADecoderFailure { | 22 enum VAJDADecoderFailure { |
23 VAAPI_ERROR = 0, | 23 VAAPI_ERROR = 0, |
24 VAJDA_DECODER_FAILURES_MAX, | 24 VAJDA_DECODER_FAILURES_MAX, |
25 }; | 25 }; |
26 | 26 |
27 static void ReportToUMA(VAJDADecoderFailure failure) { | 27 static void ReportToUMA(VAJDADecoderFailure failure) { |
28 UMA_HISTOGRAM_ENUMERATION("Media.VAJDA.DecoderFailure", failure, | 28 UMA_HISTOGRAM_ENUMERATION("Media.VAJDA.DecoderFailure", failure, |
29 VAJDA_DECODER_FAILURES_MAX); | 29 VAJDA_DECODER_FAILURES_MAX); |
30 } | 30 } |
31 | |
32 unsigned int VaSurfaceFormatForJpeg( | |
wuchengli
2015/07/13 07:26:22
static
kcwu
2015/07/13 07:39:40
Done.
| |
33 const media::JpegParseResult& parse_result) { | |
henryhsu
2015/07/09 06:56:26
Can we pass JpegFrameHeader directly since we don'
kcwu
2015/07/13 05:45:16
Done.
| |
34 // The range of sampling factor is [1, 4]. Pack them into integer to make the | |
35 // matching code simpler. For example, 0x211 means the sampling factor are 2, | |
36 // 1, 1 for 3 components. | |
37 unsigned int h = 0, v = 0; | |
38 for (int i = 0; i < parse_result.frame_header.num_components; i++) { | |
39 DCHECK_LE( | |
40 parse_result.frame_header.components[i].horizontal_sampling_factor, 4); | |
wuchengli
2015/07/13 07:26:22
Is this a bug or invalid jpeg? If it's an invalid
kcwu
2015/07/13 07:39:40
Invalid jpeg should already be handled by jpeg par
| |
41 DCHECK_LE(parse_result.frame_header.components[i].vertical_sampling_factor, | |
42 4); | |
43 h = h << 4 | | |
44 parse_result.frame_header.components[i].horizontal_sampling_factor; | |
45 v = v << 4 | | |
46 parse_result.frame_header.components[i].vertical_sampling_factor; | |
47 } | |
48 | |
49 switch (parse_result.frame_header.num_components) { | |
50 case 1: // Grey image | |
51 return VA_RT_FORMAT_YUV400; | |
52 | |
53 case 3: // Y Cb Cr color image | |
54 // See https://en.wikipedia.org/wiki/Chroma_subsampling for the | |
55 // definition of these numbers. | |
56 if (h == 0x211 && v == 0x211) | |
57 return VA_RT_FORMAT_YUV420; | |
58 | |
59 if (h == 0x211 && v == 0x111) | |
60 return VA_RT_FORMAT_YUV422; | |
61 | |
62 if (h == 0x111 && v == 0x111) | |
63 return VA_RT_FORMAT_YUV444; | |
64 | |
65 if (h == 0x411 && v == 0x111) | |
66 return VA_RT_FORMAT_YUV411; | |
67 } | |
wuchengli
2015/07/13 07:26:22
DVLOG the values of h and v here.
kcwu
2015/07/13 07:39:40
Done.
| |
68 | |
69 return 0; | |
70 } | |
71 | |
31 } // namespace | 72 } // namespace |
32 | 73 |
33 VaapiJpegDecodeAccelerator::DecodeRequest::DecodeRequest( | 74 VaapiJpegDecodeAccelerator::DecodeRequest::DecodeRequest( |
34 const media::BitstreamBuffer& bitstream_buffer, | 75 const media::BitstreamBuffer& bitstream_buffer, |
35 scoped_ptr<base::SharedMemory> shm, | 76 scoped_ptr<base::SharedMemory> shm, |
36 const scoped_refptr<media::VideoFrame>& video_frame) | 77 const scoped_refptr<media::VideoFrame>& video_frame) |
37 : bitstream_buffer(bitstream_buffer), | 78 : bitstream_buffer(bitstream_buffer), |
38 shm(shm.Pass()), | 79 shm(shm.Pass()), |
39 video_frame(video_frame) { | 80 video_frame(video_frame) { |
40 } | 81 } |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
183 if (!media::ParseJpegPicture( | 224 if (!media::ParseJpegPicture( |
184 reinterpret_cast<const uint8_t*>(request->shm->memory()), | 225 reinterpret_cast<const uint8_t*>(request->shm->memory()), |
185 request->bitstream_buffer.size(), &parse_result)) { | 226 request->bitstream_buffer.size(), &parse_result)) { |
186 DLOG(ERROR) << "ParseJpegPicture failed"; | 227 DLOG(ERROR) << "ParseJpegPicture failed"; |
187 NotifyErrorFromDecoderThread( | 228 NotifyErrorFromDecoderThread( |
188 request->bitstream_buffer.id(), | 229 request->bitstream_buffer.id(), |
189 media::JpegDecodeAccelerator::PARSE_JPEG_FAILED); | 230 media::JpegDecodeAccelerator::PARSE_JPEG_FAILED); |
190 return; | 231 return; |
191 } | 232 } |
192 | 233 |
234 unsigned int new_va_rt_format = VaSurfaceFormatForJpeg(parse_result); | |
235 if (!new_va_rt_format) { | |
236 DLOG(ERROR) << "Unsupported subsampling"; | |
237 NotifyErrorFromDecoderThread( | |
238 request->bitstream_buffer.id(), | |
239 media::JpegDecodeAccelerator::UNSUPPORTED_JPEG); | |
henryhsu
2015/07/09 06:56:26
You don't need "media::JpegDecodeAccelerator::" si
kcwu
2015/07/13 05:45:16
Done.
| |
240 return; | |
241 } | |
242 | |
193 // Reuse VASurface if size doesn't change. | 243 // Reuse VASurface if size doesn't change. |
194 gfx::Size new_coded_size(parse_result.frame_header.coded_width, | 244 gfx::Size new_coded_size(parse_result.frame_header.coded_width, |
195 parse_result.frame_header.coded_height); | 245 parse_result.frame_header.coded_height); |
196 if (new_coded_size != coded_size_ || va_surface_id_ == VA_INVALID_SURFACE) { | 246 if (new_coded_size != coded_size_ || va_surface_id_ == VA_INVALID_SURFACE || |
247 new_va_rt_format != va_rt_format_) { | |
197 vaapi_wrapper_->DestroySurfaces(); | 248 vaapi_wrapper_->DestroySurfaces(); |
198 va_surface_id_ = VA_INVALID_SURFACE; | 249 va_surface_id_ = VA_INVALID_SURFACE; |
250 va_rt_format_ = new_va_rt_format; | |
199 | 251 |
200 std::vector<VASurfaceID> va_surfaces; | 252 std::vector<VASurfaceID> va_surfaces; |
201 if (!vaapi_wrapper_->CreateSurfaces(new_coded_size, 1, &va_surfaces)) { | 253 if (!vaapi_wrapper_->CreateSurfaces(va_rt_format_, new_coded_size, 1, |
254 &va_surfaces)) { | |
202 LOG(ERROR) << "Create VA surface failed"; | 255 LOG(ERROR) << "Create VA surface failed"; |
203 NotifyErrorFromDecoderThread( | 256 NotifyErrorFromDecoderThread( |
204 request->bitstream_buffer.id(), | 257 request->bitstream_buffer.id(), |
205 media::JpegDecodeAccelerator::PLATFORM_FAILURE); | 258 media::JpegDecodeAccelerator::PLATFORM_FAILURE); |
206 return; | 259 return; |
207 } | 260 } |
208 va_surface_id_ = va_surfaces[0]; | 261 va_surface_id_ = va_surfaces[0]; |
209 coded_size_ = new_coded_size; | 262 coded_size_ = new_coded_size; |
210 } | 263 } |
211 | 264 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
248 | 301 |
249 scoped_ptr<DecodeRequest> request( | 302 scoped_ptr<DecodeRequest> request( |
250 new DecodeRequest(bitstream_buffer, shm.Pass(), video_frame)); | 303 new DecodeRequest(bitstream_buffer, shm.Pass(), video_frame)); |
251 | 304 |
252 decoder_task_runner_->PostTask( | 305 decoder_task_runner_->PostTask( |
253 FROM_HERE, base::Bind(&VaapiJpegDecodeAccelerator::DecodeTask, | 306 FROM_HERE, base::Bind(&VaapiJpegDecodeAccelerator::DecodeTask, |
254 base::Unretained(this), base::Passed(&request))); | 307 base::Unretained(this), base::Passed(&request))); |
255 } | 308 } |
256 | 309 |
257 } // namespace content | 310 } // namespace content |
OLD | NEW |