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 "media/gpu/vaapi_jpeg_decode_accelerator.h" | 5 #include "media/gpu/vaapi_jpeg_decode_accelerator.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <string.h> | 8 #include <string.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
(...skipping 19 matching lines...) Expand all Loading... |
30 VAAPI_ERROR = 0, | 30 VAAPI_ERROR = 0, |
31 VAJDA_DECODER_FAILURES_MAX, | 31 VAJDA_DECODER_FAILURES_MAX, |
32 }; | 32 }; |
33 | 33 |
34 static void ReportToUMA(VAJDADecoderFailure failure) { | 34 static void ReportToUMA(VAJDADecoderFailure failure) { |
35 UMA_HISTOGRAM_ENUMERATION("Media.VAJDA.DecoderFailure", failure, | 35 UMA_HISTOGRAM_ENUMERATION("Media.VAJDA.DecoderFailure", failure, |
36 VAJDA_DECODER_FAILURES_MAX + 1); | 36 VAJDA_DECODER_FAILURES_MAX + 1); |
37 } | 37 } |
38 | 38 |
39 static unsigned int VaSurfaceFormatForJpeg( | 39 static unsigned int VaSurfaceFormatForJpeg( |
40 const media::JpegFrameHeader& frame_header) { | 40 const JpegFrameHeader& frame_header) { |
41 // The range of sampling factor is [1, 4]. Pack them into integer to make the | 41 // The range of sampling factor is [1, 4]. Pack them into integer to make the |
42 // matching code simpler. For example, 0x211 means the sampling factor are 2, | 42 // matching code simpler. For example, 0x211 means the sampling factor are 2, |
43 // 1, 1 for 3 components. | 43 // 1, 1 for 3 components. |
44 unsigned int h = 0, v = 0; | 44 unsigned int h = 0, v = 0; |
45 for (int i = 0; i < frame_header.num_components; i++) { | 45 for (int i = 0; i < frame_header.num_components; i++) { |
46 DCHECK_LE(frame_header.components[i].horizontal_sampling_factor, 4); | 46 DCHECK_LE(frame_header.components[i].horizontal_sampling_factor, 4); |
47 DCHECK_LE(frame_header.components[i].vertical_sampling_factor, 4); | 47 DCHECK_LE(frame_header.components[i].vertical_sampling_factor, 4); |
48 h = h << 4 | frame_header.components[i].horizontal_sampling_factor; | 48 h = h << 4 | frame_header.components[i].horizontal_sampling_factor; |
49 v = v << 4 | frame_header.components[i].vertical_sampling_factor; | 49 v = v << 4 | frame_header.components[i].vertical_sampling_factor; |
50 } | 50 } |
(...skipping 22 matching lines...) Expand all Loading... |
73 << ", v=" << v; | 73 << ", v=" << v; |
74 | 74 |
75 return 0; | 75 return 0; |
76 } | 76 } |
77 | 77 |
78 } // namespace | 78 } // namespace |
79 | 79 |
80 VaapiJpegDecodeAccelerator::DecodeRequest::DecodeRequest( | 80 VaapiJpegDecodeAccelerator::DecodeRequest::DecodeRequest( |
81 int32_t bitstream_buffer_id, | 81 int32_t bitstream_buffer_id, |
82 std::unique_ptr<SharedMemoryRegion> shm, | 82 std::unique_ptr<SharedMemoryRegion> shm, |
83 const scoped_refptr<media::VideoFrame>& video_frame) | 83 const scoped_refptr<VideoFrame>& video_frame) |
84 : bitstream_buffer_id(bitstream_buffer_id), | 84 : bitstream_buffer_id(bitstream_buffer_id), |
85 shm(std::move(shm)), | 85 shm(std::move(shm)), |
86 video_frame(video_frame) {} | 86 video_frame(video_frame) {} |
87 | 87 |
88 VaapiJpegDecodeAccelerator::DecodeRequest::~DecodeRequest() {} | 88 VaapiJpegDecodeAccelerator::DecodeRequest::~DecodeRequest() {} |
89 | 89 |
90 void VaapiJpegDecodeAccelerator::NotifyError(int32_t bitstream_buffer_id, | 90 void VaapiJpegDecodeAccelerator::NotifyError(int32_t bitstream_buffer_id, |
91 Error error) { | 91 Error error) { |
92 DCHECK(task_runner_->BelongsToCurrentThread()); | 92 DCHECK(task_runner_->BelongsToCurrentThread()); |
93 DLOG(ERROR) << "Notifying of error " << error; | 93 DLOG(ERROR) << "Notifying of error " << error; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 return false; | 146 return false; |
147 } | 147 } |
148 decoder_task_runner_ = decoder_thread_.task_runner(); | 148 decoder_task_runner_ = decoder_thread_.task_runner(); |
149 | 149 |
150 return true; | 150 return true; |
151 } | 151 } |
152 | 152 |
153 bool VaapiJpegDecodeAccelerator::OutputPicture( | 153 bool VaapiJpegDecodeAccelerator::OutputPicture( |
154 VASurfaceID va_surface_id, | 154 VASurfaceID va_surface_id, |
155 int32_t input_buffer_id, | 155 int32_t input_buffer_id, |
156 const scoped_refptr<media::VideoFrame>& video_frame) { | 156 const scoped_refptr<VideoFrame>& video_frame) { |
157 DCHECK(decoder_task_runner_->BelongsToCurrentThread()); | 157 DCHECK(decoder_task_runner_->BelongsToCurrentThread()); |
158 | 158 |
159 TRACE_EVENT1("jpeg", "VaapiJpegDecodeAccelerator::OutputPicture", | 159 TRACE_EVENT1("jpeg", "VaapiJpegDecodeAccelerator::OutputPicture", |
160 "input_buffer_id", input_buffer_id); | 160 "input_buffer_id", input_buffer_id); |
161 | 161 |
162 DVLOG(3) << "Outputting VASurface " << va_surface_id | 162 DVLOG(3) << "Outputting VASurface " << va_surface_id |
163 << " into video_frame associated with input buffer id " | 163 << " into video_frame associated with input buffer id " |
164 << input_buffer_id; | 164 << input_buffer_id; |
165 | 165 |
166 VAImage image; | 166 VAImage image; |
(...skipping 17 matching lines...) Expand all Loading... |
184 // The component order of VAImage I420 are Y, U, and V. | 184 // The component order of VAImage I420 are Y, U, and V. |
185 DCHECK_EQ(image.num_planes, 3u); | 185 DCHECK_EQ(image.num_planes, 3u); |
186 DCHECK_GE(image.width, coded_size.width()); | 186 DCHECK_GE(image.width, coded_size.width()); |
187 DCHECK_GE(image.height, coded_size.height()); | 187 DCHECK_GE(image.height, coded_size.height()); |
188 const uint8_t* src_y = mem + image.offsets[0]; | 188 const uint8_t* src_y = mem + image.offsets[0]; |
189 const uint8_t* src_u = mem + image.offsets[1]; | 189 const uint8_t* src_u = mem + image.offsets[1]; |
190 const uint8_t* src_v = mem + image.offsets[2]; | 190 const uint8_t* src_v = mem + image.offsets[2]; |
191 size_t src_y_stride = image.pitches[0]; | 191 size_t src_y_stride = image.pitches[0]; |
192 size_t src_u_stride = image.pitches[1]; | 192 size_t src_u_stride = image.pitches[1]; |
193 size_t src_v_stride = image.pitches[2]; | 193 size_t src_v_stride = image.pitches[2]; |
194 uint8_t* dst_y = video_frame->data(media::VideoFrame::kYPlane); | 194 uint8_t* dst_y = video_frame->data(VideoFrame::kYPlane); |
195 uint8_t* dst_u = video_frame->data(media::VideoFrame::kUPlane); | 195 uint8_t* dst_u = video_frame->data(VideoFrame::kUPlane); |
196 uint8_t* dst_v = video_frame->data(media::VideoFrame::kVPlane); | 196 uint8_t* dst_v = video_frame->data(VideoFrame::kVPlane); |
197 size_t dst_y_stride = video_frame->stride(media::VideoFrame::kYPlane); | 197 size_t dst_y_stride = video_frame->stride(VideoFrame::kYPlane); |
198 size_t dst_u_stride = video_frame->stride(media::VideoFrame::kUPlane); | 198 size_t dst_u_stride = video_frame->stride(VideoFrame::kUPlane); |
199 size_t dst_v_stride = video_frame->stride(media::VideoFrame::kVPlane); | 199 size_t dst_v_stride = video_frame->stride(VideoFrame::kVPlane); |
200 | 200 |
201 if (libyuv::I420Copy(src_y, src_y_stride, // Y | 201 if (libyuv::I420Copy(src_y, src_y_stride, // Y |
202 src_u, src_u_stride, // U | 202 src_u, src_u_stride, // U |
203 src_v, src_v_stride, // V | 203 src_v, src_v_stride, // V |
204 dst_y, dst_y_stride, // Y | 204 dst_y, dst_y_stride, // Y |
205 dst_u, dst_u_stride, // U | 205 dst_u, dst_u_stride, // U |
206 dst_v, dst_v_stride, // V | 206 dst_v, dst_v_stride, // V |
207 coded_size.width(), coded_size.height())) { | 207 coded_size.width(), coded_size.height())) { |
208 DLOG(ERROR) << "I420Copy failed"; | 208 DLOG(ERROR) << "I420Copy failed"; |
209 return false; | 209 return false; |
210 } | 210 } |
211 | 211 |
212 vaapi_wrapper_->ReturnVaImage(&image); | 212 vaapi_wrapper_->ReturnVaImage(&image); |
213 | 213 |
214 task_runner_->PostTask( | 214 task_runner_->PostTask( |
215 FROM_HERE, base::Bind(&VaapiJpegDecodeAccelerator::VideoFrameReady, | 215 FROM_HERE, base::Bind(&VaapiJpegDecodeAccelerator::VideoFrameReady, |
216 weak_this_, input_buffer_id)); | 216 weak_this_, input_buffer_id)); |
217 | 217 |
218 return true; | 218 return true; |
219 } | 219 } |
220 | 220 |
221 void VaapiJpegDecodeAccelerator::DecodeTask( | 221 void VaapiJpegDecodeAccelerator::DecodeTask( |
222 const std::unique_ptr<DecodeRequest>& request) { | 222 const std::unique_ptr<DecodeRequest>& request) { |
223 DVLOG(3) << __func__; | 223 DVLOG(3) << __func__; |
224 DCHECK(decoder_task_runner_->BelongsToCurrentThread()); | 224 DCHECK(decoder_task_runner_->BelongsToCurrentThread()); |
225 TRACE_EVENT0("jpeg", "DecodeTask"); | 225 TRACE_EVENT0("jpeg", "DecodeTask"); |
226 | 226 |
227 media::JpegParseResult parse_result; | 227 JpegParseResult parse_result; |
228 if (!media::ParseJpegPicture( | 228 if (!ParseJpegPicture( |
229 reinterpret_cast<const uint8_t*>(request->shm->memory()), | 229 reinterpret_cast<const uint8_t*>(request->shm->memory()), |
230 request->shm->size(), &parse_result)) { | 230 request->shm->size(), &parse_result)) { |
231 DLOG(ERROR) << "ParseJpegPicture failed"; | 231 DLOG(ERROR) << "ParseJpegPicture failed"; |
232 NotifyErrorFromDecoderThread(request->bitstream_buffer_id, | 232 NotifyErrorFromDecoderThread(request->bitstream_buffer_id, |
233 PARSE_JPEG_FAILED); | 233 PARSE_JPEG_FAILED); |
234 return; | 234 return; |
235 } | 235 } |
236 | 236 |
237 unsigned int new_va_rt_format = | 237 unsigned int new_va_rt_format = |
238 VaSurfaceFormatForJpeg(parse_result.frame_header); | 238 VaSurfaceFormatForJpeg(parse_result.frame_header); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 if (!OutputPicture(va_surface_id_, request->bitstream_buffer_id, | 275 if (!OutputPicture(va_surface_id_, request->bitstream_buffer_id, |
276 request->video_frame)) { | 276 request->video_frame)) { |
277 LOG(ERROR) << "Output picture failed"; | 277 LOG(ERROR) << "Output picture failed"; |
278 NotifyErrorFromDecoderThread(request->bitstream_buffer_id, | 278 NotifyErrorFromDecoderThread(request->bitstream_buffer_id, |
279 PLATFORM_FAILURE); | 279 PLATFORM_FAILURE); |
280 return; | 280 return; |
281 } | 281 } |
282 } | 282 } |
283 | 283 |
284 void VaapiJpegDecodeAccelerator::Decode( | 284 void VaapiJpegDecodeAccelerator::Decode( |
285 const media::BitstreamBuffer& bitstream_buffer, | 285 const BitstreamBuffer& bitstream_buffer, |
286 const scoped_refptr<media::VideoFrame>& video_frame) { | 286 const scoped_refptr<VideoFrame>& video_frame) { |
287 DVLOG(3) << __func__; | 287 DVLOG(3) << __func__; |
288 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 288 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
289 TRACE_EVENT1("jpeg", "Decode", "input_id", bitstream_buffer.id()); | 289 TRACE_EVENT1("jpeg", "Decode", "input_id", bitstream_buffer.id()); |
290 | 290 |
291 DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id() | 291 DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id() |
292 << " size: " << bitstream_buffer.size(); | 292 << " size: " << bitstream_buffer.size(); |
293 | 293 |
294 // SharedMemoryRegion will take over the |bitstream_buffer.handle()|. | 294 // SharedMemoryRegion will take over the |bitstream_buffer.handle()|. |
295 std::unique_ptr<SharedMemoryRegion> shm( | 295 std::unique_ptr<SharedMemoryRegion> shm( |
296 new SharedMemoryRegion(bitstream_buffer, true)); | 296 new SharedMemoryRegion(bitstream_buffer, true)); |
(...skipping 16 matching lines...) Expand all Loading... |
313 decoder_task_runner_->PostTask( | 313 decoder_task_runner_->PostTask( |
314 FROM_HERE, base::Bind(&VaapiJpegDecodeAccelerator::DecodeTask, | 314 FROM_HERE, base::Bind(&VaapiJpegDecodeAccelerator::DecodeTask, |
315 base::Unretained(this), base::Passed(&request))); | 315 base::Unretained(this), base::Passed(&request))); |
316 } | 316 } |
317 | 317 |
318 bool VaapiJpegDecodeAccelerator::IsSupported() { | 318 bool VaapiJpegDecodeAccelerator::IsSupported() { |
319 return VaapiWrapper::IsJpegDecodeSupported(); | 319 return VaapiWrapper::IsJpegDecodeSupported(); |
320 } | 320 } |
321 | 321 |
322 } // namespace media | 322 } // namespace media |
OLD | NEW |