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_decoder.h" | 5 #include "media/gpu/vaapi_jpeg_decoder.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <string.h> | 8 #include <string.h> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa}, | 75 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa}, |
76 }, | 76 }, |
77 }; | 77 }; |
78 | 78 |
79 } // namespace | 79 } // namespace |
80 | 80 |
81 namespace media { | 81 namespace media { |
82 | 82 |
83 // VAAPI only support subset of JPEG profiles. This function determines a given | 83 // VAAPI only support subset of JPEG profiles. This function determines a given |
84 // parsed JPEG result is supported or not. | 84 // parsed JPEG result is supported or not. |
85 static bool IsVaapiSupportedJpeg(const media::JpegParseResult& jpeg) { | 85 static bool IsVaapiSupportedJpeg(const JpegParseResult& jpeg) { |
86 if (jpeg.frame_header.visible_width < 1 || | 86 if (jpeg.frame_header.visible_width < 1 || |
87 jpeg.frame_header.visible_height < 1) { | 87 jpeg.frame_header.visible_height < 1) { |
88 DLOG(ERROR) << "width(" << jpeg.frame_header.visible_width | 88 DLOG(ERROR) << "width(" << jpeg.frame_header.visible_width |
89 << ") and height(" << jpeg.frame_header.visible_height | 89 << ") and height(" << jpeg.frame_header.visible_height |
90 << ") should be at least 1"; | 90 << ") should be at least 1"; |
91 return false; | 91 return false; |
92 } | 92 } |
93 | 93 |
94 // Size 64k*64k is the maximum in the JPEG standard. VAAPI doesn't support | 94 // Size 64k*64k is the maximum in the JPEG standard. VAAPI doesn't support |
95 // resolutions larger than 16k*16k. | 95 // resolutions larger than 16k*16k. |
(...skipping 29 matching lines...) Expand all Loading... |
125 jpeg.frame_header.components[2].vertical_sampling_factor) { | 125 jpeg.frame_header.components[2].vertical_sampling_factor) { |
126 DLOG(ERROR) << "VAAPI doesn't supports vertical sampling factor of Y" | 126 DLOG(ERROR) << "VAAPI doesn't supports vertical sampling factor of Y" |
127 << " smaller than Cb and Cr"; | 127 << " smaller than Cb and Cr"; |
128 return false; | 128 return false; |
129 } | 129 } |
130 | 130 |
131 return true; | 131 return true; |
132 } | 132 } |
133 | 133 |
134 static void FillPictureParameters( | 134 static void FillPictureParameters( |
135 const media::JpegFrameHeader& frame_header, | 135 const JpegFrameHeader& frame_header, |
136 VAPictureParameterBufferJPEGBaseline* pic_param) { | 136 VAPictureParameterBufferJPEGBaseline* pic_param) { |
137 memset(pic_param, 0, sizeof(*pic_param)); | 137 memset(pic_param, 0, sizeof(*pic_param)); |
138 pic_param->picture_width = frame_header.coded_width; | 138 pic_param->picture_width = frame_header.coded_width; |
139 pic_param->picture_height = frame_header.coded_height; | 139 pic_param->picture_height = frame_header.coded_height; |
140 pic_param->num_components = frame_header.num_components; | 140 pic_param->num_components = frame_header.num_components; |
141 | 141 |
142 for (int i = 0; i < pic_param->num_components; i++) { | 142 for (int i = 0; i < pic_param->num_components; i++) { |
143 pic_param->components[i].component_id = frame_header.components[i].id; | 143 pic_param->components[i].component_id = frame_header.components[i].id; |
144 pic_param->components[i].h_sampling_factor = | 144 pic_param->components[i].h_sampling_factor = |
145 frame_header.components[i].horizontal_sampling_factor; | 145 frame_header.components[i].horizontal_sampling_factor; |
146 pic_param->components[i].v_sampling_factor = | 146 pic_param->components[i].v_sampling_factor = |
147 frame_header.components[i].vertical_sampling_factor; | 147 frame_header.components[i].vertical_sampling_factor; |
148 pic_param->components[i].quantiser_table_selector = | 148 pic_param->components[i].quantiser_table_selector = |
149 frame_header.components[i].quantization_table_selector; | 149 frame_header.components[i].quantization_table_selector; |
150 } | 150 } |
151 } | 151 } |
152 | 152 |
153 static void FillIQMatrix(const media::JpegQuantizationTable* q_table, | 153 static void FillIQMatrix(const JpegQuantizationTable* q_table, |
154 VAIQMatrixBufferJPEGBaseline* iq_matrix) { | 154 VAIQMatrixBufferJPEGBaseline* iq_matrix) { |
155 memset(iq_matrix, 0, sizeof(*iq_matrix)); | 155 memset(iq_matrix, 0, sizeof(*iq_matrix)); |
156 static_assert(media::kJpegMaxQuantizationTableNum == | 156 static_assert(kJpegMaxQuantizationTableNum == |
157 arraysize(iq_matrix->load_quantiser_table), | 157 arraysize(iq_matrix->load_quantiser_table), |
158 "max number of quantization table mismatched"); | 158 "max number of quantization table mismatched"); |
159 for (size_t i = 0; i < media::kJpegMaxQuantizationTableNum; i++) { | 159 for (size_t i = 0; i < kJpegMaxQuantizationTableNum; i++) { |
160 if (!q_table[i].valid) | 160 if (!q_table[i].valid) |
161 continue; | 161 continue; |
162 iq_matrix->load_quantiser_table[i] = 1; | 162 iq_matrix->load_quantiser_table[i] = 1; |
163 static_assert( | 163 static_assert( |
164 arraysize(iq_matrix->quantiser_table[i]) == arraysize(q_table[i].value), | 164 arraysize(iq_matrix->quantiser_table[i]) == arraysize(q_table[i].value), |
165 "number of quantization entries mismatched"); | 165 "number of quantization entries mismatched"); |
166 for (size_t j = 0; j < arraysize(q_table[i].value); j++) | 166 for (size_t j = 0; j < arraysize(q_table[i].value); j++) |
167 iq_matrix->quantiser_table[i][j] = q_table[i].value[j]; | 167 iq_matrix->quantiser_table[i][j] = q_table[i].value[j]; |
168 } | 168 } |
169 } | 169 } |
170 | 170 |
171 static void FillHuffmanTable(const media::JpegHuffmanTable* dc_table, | 171 static void FillHuffmanTable(const JpegHuffmanTable* dc_table, |
172 const media::JpegHuffmanTable* ac_table, | 172 const JpegHuffmanTable* ac_table, |
173 VAHuffmanTableBufferJPEGBaseline* huffman_table) { | 173 VAHuffmanTableBufferJPEGBaseline* huffman_table) { |
174 memset(huffman_table, 0, sizeof(*huffman_table)); | 174 memset(huffman_table, 0, sizeof(*huffman_table)); |
175 // Use default huffman tables if not specified in header. | 175 // Use default huffman tables if not specified in header. |
176 bool has_huffman_table = false; | 176 bool has_huffman_table = false; |
177 for (size_t i = 0; i < media::kJpegMaxHuffmanTableNumBaseline; i++) { | 177 for (size_t i = 0; i < kJpegMaxHuffmanTableNumBaseline; i++) { |
178 if (dc_table[i].valid || ac_table[i].valid) { | 178 if (dc_table[i].valid || ac_table[i].valid) { |
179 has_huffman_table = true; | 179 has_huffman_table = true; |
180 break; | 180 break; |
181 } | 181 } |
182 } | 182 } |
183 if (!has_huffman_table) { | 183 if (!has_huffman_table) { |
184 dc_table = kDefaultDcTable; | 184 dc_table = kDefaultDcTable; |
185 ac_table = kDefaultAcTable; | 185 ac_table = kDefaultAcTable; |
186 } | 186 } |
187 | 187 |
188 static_assert(media::kJpegMaxHuffmanTableNumBaseline == | 188 static_assert(kJpegMaxHuffmanTableNumBaseline == |
189 arraysize(huffman_table->load_huffman_table), | 189 arraysize(huffman_table->load_huffman_table), |
190 "max number of huffman table mismatched"); | 190 "max number of huffman table mismatched"); |
191 static_assert(sizeof(huffman_table->huffman_table[0].num_dc_codes) == | 191 static_assert(sizeof(huffman_table->huffman_table[0].num_dc_codes) == |
192 sizeof(dc_table[0].code_length), | 192 sizeof(dc_table[0].code_length), |
193 "size of huffman table code length mismatch"); | 193 "size of huffman table code length mismatch"); |
194 static_assert(sizeof(huffman_table->huffman_table[0].dc_values[0]) == | 194 static_assert(sizeof(huffman_table->huffman_table[0].dc_values[0]) == |
195 sizeof(dc_table[0].code_value[0]), | 195 sizeof(dc_table[0].code_value[0]), |
196 "size of huffman table code value mismatch"); | 196 "size of huffman table code value mismatch"); |
197 for (size_t i = 0; i < media::kJpegMaxHuffmanTableNumBaseline; i++) { | 197 for (size_t i = 0; i < kJpegMaxHuffmanTableNumBaseline; i++) { |
198 if (!dc_table[i].valid || !ac_table[i].valid) | 198 if (!dc_table[i].valid || !ac_table[i].valid) |
199 continue; | 199 continue; |
200 huffman_table->load_huffman_table[i] = 1; | 200 huffman_table->load_huffman_table[i] = 1; |
201 | 201 |
202 memcpy(huffman_table->huffman_table[i].num_dc_codes, | 202 memcpy(huffman_table->huffman_table[i].num_dc_codes, |
203 dc_table[i].code_length, | 203 dc_table[i].code_length, |
204 sizeof(huffman_table->huffman_table[i].num_dc_codes)); | 204 sizeof(huffman_table->huffman_table[i].num_dc_codes)); |
205 memcpy(huffman_table->huffman_table[i].dc_values, dc_table[i].code_value, | 205 memcpy(huffman_table->huffman_table[i].dc_values, dc_table[i].code_value, |
206 sizeof(huffman_table->huffman_table[i].dc_values)); | 206 sizeof(huffman_table->huffman_table[i].dc_values)); |
207 memcpy(huffman_table->huffman_table[i].num_ac_codes, | 207 memcpy(huffman_table->huffman_table[i].num_ac_codes, |
208 ac_table[i].code_length, | 208 ac_table[i].code_length, |
209 sizeof(huffman_table->huffman_table[i].num_ac_codes)); | 209 sizeof(huffman_table->huffman_table[i].num_ac_codes)); |
210 memcpy(huffman_table->huffman_table[i].ac_values, ac_table[i].code_value, | 210 memcpy(huffman_table->huffman_table[i].ac_values, ac_table[i].code_value, |
211 sizeof(huffman_table->huffman_table[i].ac_values)); | 211 sizeof(huffman_table->huffman_table[i].ac_values)); |
212 } | 212 } |
213 } | 213 } |
214 | 214 |
215 static void FillSliceParameters( | 215 static void FillSliceParameters( |
216 const media::JpegParseResult& parse_result, | 216 const JpegParseResult& parse_result, |
217 VASliceParameterBufferJPEGBaseline* slice_param) { | 217 VASliceParameterBufferJPEGBaseline* slice_param) { |
218 memset(slice_param, 0, sizeof(*slice_param)); | 218 memset(slice_param, 0, sizeof(*slice_param)); |
219 slice_param->slice_data_size = parse_result.data_size; | 219 slice_param->slice_data_size = parse_result.data_size; |
220 slice_param->slice_data_offset = 0; | 220 slice_param->slice_data_offset = 0; |
221 slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL; | 221 slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL; |
222 slice_param->slice_horizontal_position = 0; | 222 slice_param->slice_horizontal_position = 0; |
223 slice_param->slice_vertical_position = 0; | 223 slice_param->slice_vertical_position = 0; |
224 slice_param->num_components = parse_result.scan.num_components; | 224 slice_param->num_components = parse_result.scan.num_components; |
225 for (int i = 0; i < slice_param->num_components; i++) { | 225 for (int i = 0; i < slice_param->num_components; i++) { |
226 slice_param->components[i].component_selector = | 226 slice_param->components[i].component_selector = |
(...skipping 12 matching lines...) Expand all Loading... |
239 parse_result.frame_header.components[0].vertical_sampling_factor; | 239 parse_result.frame_header.components[0].vertical_sampling_factor; |
240 int mcu_cols = parse_result.frame_header.coded_width / (max_h_factor * 8); | 240 int mcu_cols = parse_result.frame_header.coded_width / (max_h_factor * 8); |
241 DCHECK_GT(mcu_cols, 0); | 241 DCHECK_GT(mcu_cols, 0); |
242 int mcu_rows = parse_result.frame_header.coded_height / (max_v_factor * 8); | 242 int mcu_rows = parse_result.frame_header.coded_height / (max_v_factor * 8); |
243 DCHECK_GT(mcu_rows, 0); | 243 DCHECK_GT(mcu_rows, 0); |
244 slice_param->num_mcus = mcu_rows * mcu_cols; | 244 slice_param->num_mcus = mcu_rows * mcu_cols; |
245 } | 245 } |
246 | 246 |
247 // static | 247 // static |
248 bool VaapiJpegDecoder::Decode(VaapiWrapper* vaapi_wrapper, | 248 bool VaapiJpegDecoder::Decode(VaapiWrapper* vaapi_wrapper, |
249 const media::JpegParseResult& parse_result, | 249 const JpegParseResult& parse_result, |
250 VASurfaceID va_surface) { | 250 VASurfaceID va_surface) { |
251 DCHECK_NE(va_surface, VA_INVALID_SURFACE); | 251 DCHECK_NE(va_surface, VA_INVALID_SURFACE); |
252 if (!IsVaapiSupportedJpeg(parse_result)) | 252 if (!IsVaapiSupportedJpeg(parse_result)) |
253 return false; | 253 return false; |
254 | 254 |
255 // Set picture parameters. | 255 // Set picture parameters. |
256 VAPictureParameterBufferJPEGBaseline pic_param; | 256 VAPictureParameterBufferJPEGBaseline pic_param; |
257 FillPictureParameters(parse_result.frame_header, &pic_param); | 257 FillPictureParameters(parse_result.frame_header, &pic_param); |
258 if (!vaapi_wrapper->SubmitBuffer(VAPictureParameterBufferType, | 258 if (!vaapi_wrapper->SubmitBuffer(VAPictureParameterBufferType, |
259 sizeof(pic_param), &pic_param)) | 259 sizeof(pic_param), &pic_param)) |
(...skipping 27 matching lines...) Expand all Loading... |
287 const_cast<char*>(parse_result.data))) | 287 const_cast<char*>(parse_result.data))) |
288 return false; | 288 return false; |
289 | 289 |
290 if (!vaapi_wrapper->ExecuteAndDestroyPendingBuffers(va_surface)) | 290 if (!vaapi_wrapper->ExecuteAndDestroyPendingBuffers(va_surface)) |
291 return false; | 291 return false; |
292 | 292 |
293 return true; | 293 return true; |
294 } | 294 } |
295 | 295 |
296 } // namespace media | 296 } // namespace media |
OLD | NEW |