OSDN Git Service

Fix a typo
[android-x86/hardware-intel-common-vaapi.git] / src / gen10_hevc_enc_common.c
1 /*
2  * Copyright © 2017 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Peng Chen <peng.c.chen@intel.com>
26  *
27  */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <math.h>
33 #include <assert.h>
34
35 #include "intel_driver.h"
36 #include "intel_batchbuffer.h"
37 #include "i965_defines.h"
38 #include "i965_drv_video.h"
39 #include "i965_encoder.h"
40 #include "i965_encoder_common.h"
41 #include "i965_encoder_utils.h"
42 #include "i965_encoder_api.h"
43 #include "gen10_hcp_common.h"
44 #include "gen10_hevc_enc_common.h"
45
46 static const unsigned char default_scaling16[16] = {
47     16, 16, 16, 16,
48     16, 16, 16, 16,
49     16, 16, 16, 16,
50     16, 16, 16, 16
51 };
52
53 static const unsigned char default_scaling_intra[64] = {
54     16, 16, 16, 16, 17, 18, 21, 24,
55     16, 16, 16, 16, 17, 19, 22, 25,
56     16, 16, 17, 18, 20, 22, 25, 29,
57     16, 16, 18, 21, 24, 27, 31, 36,
58     17, 17, 20, 24, 30, 35, 41, 47,
59     18, 19, 22, 27, 35, 44, 54, 65,
60     21, 22, 25, 31, 41, 54, 70, 88,
61     24, 25, 29, 36, 47, 65, 88, 115
62 };
63
64 static const unsigned char default_scaling_inter[64] = {
65     16, 16, 16, 16, 17, 18, 20, 24,
66     16, 16, 16, 17, 18, 20, 24, 25,
67     16, 16, 17, 18, 20, 24, 25, 28,
68     16, 17, 18, 20, 24, 25, 28, 33,
69     17, 18, 20, 24, 25, 28, 33, 41,
70     18, 20, 24, 25, 28, 33, 41, 54,
71     20, 24, 25, 28, 33, 41, 54, 71,
72     24, 25, 28, 33, 41, 54, 71, 91
73 };
74
75 static void
76 hevc_init_qm_matrix(struct gen10_hevc_enc_frame_info *frame_info,
77                     VAQMatrixBufferHEVC *qm_matrix,
78                     int matrix_flag)
79 {
80     uint8_t *real_qm, real_dc_qm = 0;
81     uint16_t *real_fqm, *real_dc_fqm;
82     int comps, len;
83     int i, j, m, n;
84
85     if (matrix_flag == 0) {
86         for (m = 0; m < 4; m++) {
87             comps = (m == 3) ? 1 : 3;
88             len = (m == 0) ? 16 : 64;
89
90             for (i = 0; i < comps; i++) {
91                 for (j = 0; j < 2; j++) {
92                     real_qm = frame_info->qm_matrix[m][i][j];
93
94                     switch (m) {
95                     case 0:
96                         memcpy(real_qm, qm_matrix->scaling_lists_4x4[i][j], len);
97                         break;
98                     case 1:
99                         memcpy(real_qm, qm_matrix->scaling_lists_8x8[i][j], len);
100                         break;
101                     case 2:
102                         memcpy(real_qm, qm_matrix->scaling_lists_16x16[i][j], len);
103
104                         real_dc_qm = qm_matrix->scaling_list_dc_16x16[i][j];
105                         frame_info->qm_dc_matrix[0][i][j] = real_dc_qm;
106                         break;
107                     case 3:
108                         memcpy(real_qm, qm_matrix->scaling_lists_32x32[j], len);
109
110                         real_dc_qm = qm_matrix->scaling_list_dc_32x32[j];
111                         frame_info->qm_dc_matrix[1][i][j] = real_dc_qm;
112                         break;
113                     default:
114                         assert(0);
115                     }
116
117                     if (i == 0) {
118                         real_fqm = frame_info->fqm_matrix[m][j];
119
120                         for (n = 0; n < len; n++) {
121                             uint32_t qm_value = *(real_qm + n);
122                             uint32_t fqm_value = 0;
123
124                             fqm_value = (qm_value < 2) ? 0xFFFF : 0xFFFF / qm_value;
125
126                             *(real_fqm + n) = fqm_value;
127                         }
128
129                         if (m == 2 || m == 3) {
130                             uint32_t dc = real_dc_qm;
131
132                             real_dc_fqm = &frame_info->fqm_dc_matrix[m - 2][j];
133                             dc = (dc < 2) ? 0xFFFF : 0xFFFF / dc;
134
135                             *real_dc_fqm = dc;
136                         }
137                     }
138                 }
139             }
140         }
141     } else if (matrix_flag == 1) {
142         for (m = 0; m < 4; m++) {
143             comps = (m == 3) ? 1 : 3;
144             len = (m == 0) ? 16 : 64;
145
146             for (i = 0; i < comps; i++) {
147                 for (j = 0; j < 2; j++) {
148                     real_qm = frame_info->qm_matrix[m][i][j];
149
150                     switch (m) {
151                     case 0:
152                         memcpy(real_qm, default_scaling16, len);
153                         break;
154                     case 1:
155                     case 2:
156                     case 3:
157                         if (j == 0)
158                             memcpy(real_qm, default_scaling_intra, len);
159                         else
160                             memcpy(real_qm, default_scaling_inter, len);
161
162                         break;
163                     default:
164                         assert(0);
165                     }
166
167                     if (i == 0) {
168                         real_fqm = frame_info->fqm_matrix[m][j];
169
170                         for (n = 0; n < len; n++) {
171                             uint32_t qm_value = *(real_qm + n);
172                             uint32_t fqm_value = 0;
173
174                             fqm_value = (qm_value < 2) ? 0xFFFF : 0xFFFF / qm_value;
175
176                             *(real_fqm + n) = fqm_value;
177                         }
178                     }
179                 }
180             }
181         }
182
183         memset(&frame_info->qm_dc_matrix, 16, sizeof(frame_info->qm_dc_matrix));
184
185         for (i = 0; i < 2; i++) {
186             for (j = 0; j < 2; j++)
187                 frame_info->fqm_dc_matrix[i][j] = 0x1000;
188         }
189
190     } else if (matrix_flag == 2) {
191         memset(&frame_info->qm_matrix, 16, sizeof(frame_info->qm_matrix));
192         memset(&frame_info->qm_dc_matrix, 16, sizeof(frame_info->qm_dc_matrix));
193
194         for (m = 0; m < 4; m++) {
195             for (j = 0; j < 2; j++) {
196                 for (n = 0; n < 64; n++)
197                     frame_info->fqm_matrix[m][j][n] = 0x1000;
198             }
199         }
200
201         for (i = 0; i < 2; i++) {
202             for (j = 0; j < 2; j++)
203                 frame_info->fqm_dc_matrix[i][j] = 0x1000;
204         }
205     } else
206         assert(0);
207 }
208
209 static int
210 hevc_enc_map_pic_index(VASurfaceID id,
211                        VAPictureHEVC *pic_list,
212                        int pic_list_count)
213 {
214     int i;
215
216     if (id != VA_INVALID_ID) {
217         for (i = 0; i < pic_list_count; i++) {
218             VAPictureHEVC * const va_pic = &pic_list[i];
219
220             if (va_pic->picture_id == id &&
221                 !(va_pic->flags & VA_PICTURE_HEVC_INVALID))
222                 return i;
223         }
224     }
225
226     return -1;
227 }
228
229 static int
230 gen10_hevc_enc_get_relocation_flag(VAEncSequenceParameterBufferHEVC *cur_seq_param,
231                                    VAEncSequenceParameterBufferHEVC *last_seq_param)
232 {
233     if ((cur_seq_param->seq_fields.bits.bit_depth_luma_minus8 !=
234          last_seq_param->seq_fields.bits.bit_depth_luma_minus8) ||
235         (cur_seq_param->seq_fields.bits.bit_depth_chroma_minus8 !=
236          last_seq_param->seq_fields.bits.bit_depth_chroma_minus8) ||
237         (cur_seq_param->log2_min_luma_coding_block_size_minus3 !=
238          last_seq_param->log2_min_luma_coding_block_size_minus3) ||
239         (cur_seq_param->log2_diff_max_min_luma_coding_block_size !=
240          last_seq_param->log2_diff_max_min_luma_coding_block_size) ||
241         (cur_seq_param->pic_width_in_luma_samples !=
242          last_seq_param->pic_width_in_luma_samples) ||
243         (cur_seq_param->pic_height_in_luma_samples !=
244          last_seq_param->pic_height_in_luma_samples) ||
245         (cur_seq_param->seq_fields.bits.bit_depth_chroma_minus8 !=
246          last_seq_param->seq_fields.bits.bit_depth_chroma_minus8) ||
247         (cur_seq_param->seq_fields.bits.bit_depth_chroma_minus8 !=
248          last_seq_param->seq_fields.bits.bit_depth_chroma_minus8))
249         return 1;
250
251     return 0;
252 }
253
254 void
255 gen10_hevc_enc_init_frame_info(VADriverContextP ctx,
256                                struct encode_state *encode_state,
257                                struct intel_encoder_context *encoder_context,
258                                struct gen10_hevc_enc_frame_info *frame_info)
259 {
260     uint32_t log2_max_coding_block_size = 0, raw_ctu_bits = 0;
261     VAEncPictureParameterBufferHEVC *pic_param = NULL;
262     VAEncSequenceParameterBufferHEVC *seq_param = NULL;
263     VAEncSliceParameterBufferHEVC *slice_param = NULL;
264     int i, j;
265
266     pic_param = (VAEncPictureParameterBufferHEVC *)encode_state->pic_param_ext->buffer;
267     seq_param = (VAEncSequenceParameterBufferHEVC *)encode_state->seq_param_ext->buffer;
268     slice_param = (VAEncSliceParameterBufferHEVC *)encode_state->slice_params_ext[0]->buffer;
269
270     frame_info->bit_depth_luma_minus8 = seq_param->seq_fields.bits.bit_depth_luma_minus8;
271     frame_info->bit_depth_chroma_minus8 = seq_param->seq_fields.bits.bit_depth_chroma_minus8;
272     frame_info->cu_size = 1 << (seq_param->log2_min_luma_coding_block_size_minus3 + 3);
273     frame_info->lcu_size = 1 << (seq_param->log2_diff_max_min_luma_coding_block_size +
274                                  seq_param->log2_min_luma_coding_block_size_minus3 + 3);
275     frame_info->frame_width = (seq_param->pic_width_in_luma_samples / frame_info->cu_size) * frame_info->cu_size;
276     frame_info->frame_height = (seq_param->pic_height_in_luma_samples / frame_info->cu_size) * frame_info->cu_size;
277     frame_info->width_in_lcu  = ALIGN(frame_info->frame_width, frame_info->lcu_size) / frame_info->lcu_size;
278     frame_info->height_in_lcu = ALIGN(frame_info->frame_height, frame_info->lcu_size) / frame_info->lcu_size;
279     frame_info->width_in_cu  = ALIGN(frame_info->frame_width, frame_info->cu_size) / frame_info->cu_size;
280     frame_info->height_in_cu = ALIGN(frame_info->frame_height, frame_info->cu_size) / frame_info->cu_size;
281     frame_info->width_in_mb  = ALIGN(frame_info->frame_width, 16) / 16;
282     frame_info->height_in_mb = ALIGN(frame_info->frame_height, 16) / 16;
283
284     frame_info->picture_coding_type = slice_param->slice_type;
285
286     frame_info->ctu_max_bitsize_allowed = pic_param->ctu_max_bitsize_allowed;
287
288     log2_max_coding_block_size  = seq_param->log2_min_luma_coding_block_size_minus3 + 3 +
289                                   seq_param->log2_diff_max_min_luma_coding_block_size;
290     raw_ctu_bits = (1 << (2 * log2_max_coding_block_size + 3)) +
291                    (1 << (2 * log2_max_coding_block_size + 2));
292     raw_ctu_bits = (5 * raw_ctu_bits / 3);
293
294     if (frame_info->ctu_max_bitsize_allowed == 0 ||
295         frame_info->ctu_max_bitsize_allowed > raw_ctu_bits)
296         frame_info->ctu_max_bitsize_allowed = raw_ctu_bits;
297
298     frame_info->low_delay = 1;
299     frame_info->arbitrary_num_mb_in_slice = 0;
300
301     for (i = 0; i < encode_state->num_slice_params_ext; i++) {
302         slice_param = (VAEncSliceParameterBufferHEVC *)encode_state->slice_params_ext[i]->buffer;
303
304         if (i == 0) {
305             frame_info->is_same_ref_list = 1;
306             if (slice_param->slice_type == HEVC_SLICE_B) {
307                 if (slice_param->num_ref_idx_l0_active_minus1 >=
308                     slice_param->num_ref_idx_l1_active_minus1) {
309                     for (j = 0; j < slice_param->num_ref_idx_l1_active_minus1 + 1; j++)
310                         if (slice_param->ref_pic_list0[j].picture_id !=
311                             slice_param->ref_pic_list1[j].picture_id) {
312                             frame_info->is_same_ref_list = 0;
313                             break;
314                         }
315                 } else
316                     frame_info->is_same_ref_list = 0;
317             }
318         }
319
320         if (slice_param->slice_type == HEVC_SLICE_B && frame_info->low_delay) {
321             for (j = 0; j <= slice_param->num_ref_idx_l0_active_minus1; j++) {
322                 if (pic_param->decoded_curr_pic.pic_order_cnt <
323                     slice_param->ref_pic_list0[j].pic_order_cnt)
324                     frame_info->low_delay = 0;
325             }
326
327             for (j = 0; j <= slice_param->num_ref_idx_l1_active_minus1; j++) {
328                 if (pic_param->decoded_curr_pic.pic_order_cnt <
329                     slice_param->ref_pic_list1[j].pic_order_cnt)
330                     frame_info->low_delay = 0;
331             }
332         }
333
334         if (!frame_info->arbitrary_num_mb_in_slice &&
335             (slice_param->num_ctu_in_slice % frame_info->width_in_lcu))
336             frame_info->arbitrary_num_mb_in_slice = 1;
337     }
338
339     for (i = 0; i < 8; i++) {
340         frame_info->mapped_ref_idx_list0[i] = -1;
341         frame_info->mapped_ref_idx_list1[i] = -1;
342     }
343
344     if (slice_param->slice_type != HEVC_SLICE_I) {
345         for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++)
346             frame_info->mapped_ref_idx_list0[i] = hevc_enc_map_pic_index(slice_param->ref_pic_list0[i].picture_id,
347                                                                          pic_param->reference_frames, 8);
348
349         if (slice_param->slice_type == HEVC_SLICE_B) {
350             for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++)
351                 frame_info->mapped_ref_idx_list1[i] = hevc_enc_map_pic_index(slice_param->ref_pic_list1[i].picture_id,
352                                                                              pic_param->reference_frames, 8);
353         }
354     }
355
356     frame_info->slice_qp = pic_param->pic_init_qp + slice_param->slice_qp_delta;
357
358     if (encoder_context->is_new_sequence ||
359         memcmp(&frame_info->last_seq_param, seq_param, sizeof(*seq_param))) {
360         VAQMatrixBufferHEVC *input_matrix = NULL;
361         int matrix_flag = 0;
362
363         if (seq_param->seq_fields.bits.scaling_list_enabled_flag) {
364             if (pic_param->pic_fields.bits.scaling_list_data_present_flag) {
365                 if (encode_state->q_matrix && encode_state->q_matrix->buffer)
366                     input_matrix = (VAQMatrixBufferHEVC *)encode_state->q_matrix->buffer;
367                 else if (encode_state->iq_matrix && encode_state->iq_matrix->buffer)
368                     input_matrix = (VAQMatrixBufferHEVC *)encode_state->iq_matrix->buffer;
369
370                 matrix_flag = 0;
371             } else
372                 matrix_flag = 1;
373         } else
374             matrix_flag = 2;
375
376         hevc_init_qm_matrix(frame_info, input_matrix, matrix_flag);
377
378         frame_info->gop_size = seq_param->intra_period;
379         frame_info->gop_ref_dist = seq_param->ip_period;
380         frame_info->gop_num_p = encoder_context->brc.num_pframes_in_gop;
381         frame_info->gop_num_b[0] = encoder_context->brc.num_bframes_in_gop;
382         frame_info->gop_num_b[1] = 0;
383         frame_info->gop_num_b[2] = 0;
384
385         if (gen10_hevc_enc_get_relocation_flag(seq_param,
386                                                &frame_info->last_seq_param))
387             frame_info->reallocate_flag = 1;
388         else
389             frame_info->reallocate_flag = 0;
390
391         memcpy(&frame_info->last_seq_param, seq_param, sizeof(*seq_param));
392     } else
393         frame_info->reallocate_flag = 0;
394 }
395
396 static int
397 hevc_find_skipemulcnt(uint8_t *buf, int bits_length)
398 {
399     int skip_cnt = 0, i = 0;
400
401     if ((bits_length >> 3) < 6)
402         return 0;
403
404     for (i = 0; i < 3; i++)
405         if (buf[i] != 0)
406             break;
407
408     if (i > 1) {
409         if (buf[i] == 1)
410             skip_cnt = i + 3;
411     }
412
413     return skip_cnt;
414 }
415
416 static void
417 gen10_hevc_enc_insert_object(VADriverContextP ctx,
418                              struct intel_batchbuffer *batch,
419                              uint8_t *header_data,
420                              int length_in_bits,
421                              int end_of_slice_flag,
422                              int last_header_flag,
423                              int emulation_flag,
424                              int skip_emulation_bytes)
425 {
426     gen10_hcp_pak_insert_object_param insert_param;
427
428     memset(&insert_param, 0, sizeof(insert_param));
429
430     insert_param.dw1.bits.end_of_slice_flag = end_of_slice_flag;
431     insert_param.dw1.bits.last_header_flag = last_header_flag;
432     insert_param.dw1.bits.emulation_flag = emulation_flag;
433
434     if (emulation_flag) {
435         if (skip_emulation_bytes)
436             insert_param.dw1.bits.skip_emulation_bytes = skip_emulation_bytes;
437         else
438             insert_param.dw1.bits.skip_emulation_bytes = hevc_find_skipemulcnt((uint8_t *)header_data,
439                                                                                length_in_bits);
440     }
441
442     insert_param.dw1.bits.data_bits_in_last_dw = length_in_bits & 0x1f;
443     if (insert_param.dw1.bits.data_bits_in_last_dw == 0)
444         insert_param.dw1.bits.data_bits_in_last_dw = 32;
445
446     insert_param.inline_payload_ptr = header_data;
447     insert_param.inline_payload_bits = length_in_bits;
448
449     gen10_hcp_pak_insert_object(ctx, batch, &insert_param);
450 }
451
452 void
453 gen10_hevc_enc_insert_packed_header(VADriverContextP ctx,
454                                     struct encode_state *encode_state,
455                                     struct intel_encoder_context *encoder_context,
456                                     struct intel_batchbuffer *batch)
457 {
458     VAEncPackedHeaderParameterBuffer *param = NULL;
459     uint8_t *header_data = NULL;
460     uint32_t length_in_bits = 0;
461     int packed_type = 0;
462     int idx = 0, idx_offset = 0;
463     int i = 0;
464
465     for (i = 0; i < 4; i++) {
466         idx_offset = 0;
467         switch (i) {
468         case 0:
469             packed_type = VAEncPackedHeaderHEVC_VPS;
470             break;
471         case 1:
472             packed_type = VAEncPackedHeaderHEVC_VPS;
473             idx_offset = 1;
474             break;
475         case 2:
476             packed_type = VAEncPackedHeaderHEVC_PPS;
477             break;
478         case 3:
479             packed_type = VAEncPackedHeaderHEVC_SEI;
480             break;
481         default:
482             break;
483         }
484
485         idx = va_enc_packed_type_to_idx(packed_type) + idx_offset;
486         if (encode_state->packed_header_data[idx]) {
487             param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[idx]->buffer;
488             header_data = (uint8_t *)encode_state->packed_header_data[idx]->buffer;
489             length_in_bits = param->bit_length;
490
491             gen10_hevc_enc_insert_object(ctx, batch, header_data, length_in_bits,
492                                          0, 0, !param->has_emulation_bytes, 0);
493         }
494     }
495 }
496
497 void
498 gen10_hevc_enc_insert_slice_header(VADriverContextP ctx,
499                                    struct encode_state *encode_state,
500                                    struct intel_encoder_context *encoder_context,
501                                    struct intel_batchbuffer *batch,
502                                    int slice_index)
503 {
504     VAEncPackedHeaderParameterBuffer *param = NULL;
505     uint8_t *header_data = NULL;
506     uint32_t length_in_bits = 0;
507     int count = 0, start_index = -1;
508     int i = 0;
509
510     count = encode_state->slice_rawdata_count[slice_index];
511     start_index = encode_state->slice_rawdata_index[slice_index] &
512                   SLICE_PACKED_DATA_INDEX_MASK;
513
514     for (i = 0; i < count; i++) {
515         param = (VAEncPackedHeaderParameterBuffer *)
516                 (encode_state->packed_header_params_ext[start_index + i]->buffer);
517
518         if (param->type == VAEncPackedHeaderSlice)
519             continue;
520
521         header_data = (uint8_t *)encode_state->packed_header_data_ext[start_index]->buffer;
522         length_in_bits = param->bit_length;
523
524         gen10_hevc_enc_insert_object(ctx, batch, header_data, length_in_bits,
525                                      0, 0, !param->has_emulation_bytes, 0);
526     }
527
528     start_index = -1;
529     if (encode_state->slice_header_index[slice_index] & SLICE_PACKED_DATA_INDEX_TYPE)
530         start_index = encode_state->slice_header_index[slice_index] &
531                       SLICE_PACKED_DATA_INDEX_MASK;
532
533     if (start_index == -1) {
534         VAEncSequenceParameterBufferHEVC *seq_param = (VAEncSequenceParameterBufferHEVC *)encode_state->seq_param_ext->buffer;
535         VAEncPictureParameterBufferHEVC *pic_param = (VAEncPictureParameterBufferHEVC *)encode_state->pic_param_ext->buffer;
536         VAEncSliceParameterBufferHEVC *slice_param = (VAEncSliceParameterBufferHEVC *)encode_state->slice_params_ext[slice_index]->buffer;
537         unsigned char *slice_header = NULL;
538         int slice_header_bits = 0;
539
540         slice_header_bits = build_hevc_slice_header(seq_param,
541                                                     pic_param,
542                                                     slice_param,
543                                                     &slice_header,
544                                                     0);
545
546         gen10_hevc_enc_insert_object(ctx, batch, slice_header, slice_header_bits,
547                                      0, 1, 1, 5);
548
549         free(slice_header);
550     } else {
551         param = (VAEncPackedHeaderParameterBuffer *)
552                 (encode_state->packed_header_params_ext[start_index]->buffer);
553         header_data = (uint8_t *)encode_state->packed_header_data_ext[start_index]->buffer;
554         length_in_bits = param->bit_length;
555
556         gen10_hevc_enc_insert_object(ctx, batch, header_data, length_in_bits,
557                                      0, 1, !param->has_emulation_bytes, 0);
558     }
559 }
560
561
562 #define ALLOC_GPE_RESOURCE(RES, NAME, SIZE)                 \
563     do{                                                     \
564         i965_free_gpe_resource(&common_res->RES);           \
565         if (!i965_allocate_gpe_resource(i965->intel.bufmgr, \
566                                  &common_res->RES,          \
567                                  SIZE,                      \
568                                  NAME))                     \
569             goto FAIL;                                      \
570     } while(0);
571
572 #define ALLOC_GPE_2D_RESOURCE(RES, NAME, W, H, P)               \
573     do{                                                         \
574         i965_free_gpe_resource(&priv_ctx->RES);                 \
575         if (!i965_gpe_allocate_2d_resource(i965->intel.bufmgr,  \
576                                  &common_res->RES,              \
577                                  (ALIGN(W, 64)), H,             \
578                                  (ALIGN(P, 64)),                \
579                                  NAME))                         \
580             goto FAIL;                                          \
581     } while(0);
582
583 int
584 gen10_hevc_enc_init_common_resource(VADriverContextP ctx,
585                                     struct encode_state *encode_state,
586                                     struct intel_encoder_context *encoder_context,
587                                     struct gen10_hevc_enc_common_res *common_res,
588                                     struct gen10_hevc_enc_frame_info *frame_info,
589                                     int inter_enabled,
590                                     int vdenc_enabled)
591 {
592     struct i965_driver_data *i965 = i965_driver_data(ctx);
593     VAEncPictureParameterBufferHEVC *pic_param = NULL;
594     struct object_surface *obj_surface;
595     struct object_buffer *obj_buffer;
596     int res_size = 0, size_shift = 0;
597     int width = 0, height = 0;
598     int i = 0;
599
600     pic_param = (VAEncPictureParameterBufferHEVC *)encode_state->pic_param_ext->buffer;
601
602     obj_buffer = encode_state->coded_buf_object;
603     i965_free_gpe_resource(&common_res->compressed_bitstream.gpe_res);
604     i965_dri_object_to_buffer_gpe_resource(&common_res->compressed_bitstream.gpe_res,
605                                            obj_buffer->buffer_store->bo);
606     common_res->compressed_bitstream.offset = I965_CODEDBUFFER_HEADER_SIZE;
607     common_res->compressed_bitstream.end_offset = ALIGN(obj_buffer->size_element - 0x1000,
608                                                         0x1000);
609
610     i965_free_gpe_resource(&common_res->uncompressed_pic.gpe_res);
611     i965_object_surface_to_2d_gpe_resource(&common_res->uncompressed_pic.gpe_res,
612                                            encode_state->input_yuv_object);
613     common_res->uncompressed_pic.obj_surface = encode_state->input_yuv_object;
614     common_res->uncompressed_pic.surface_id = encoder_context->input_yuv_surface;
615
616     i965_free_gpe_resource(&common_res->reconstructed_pic.gpe_res);
617     i965_object_surface_to_2d_gpe_resource(&common_res->reconstructed_pic.gpe_res,
618                                            encode_state->reconstructed_object);
619     common_res->reconstructed_pic.obj_surface = encode_state->reconstructed_object;
620     common_res->reconstructed_pic.surface_id = pic_param->decoded_curr_pic.picture_id;
621
622     if (inter_enabled) {
623         for (i = 0; i < 15; i++) {
624             if (common_res->reference_pics[i].surface_id != VA_INVALID_ID)
625                 i965_free_gpe_resource(&common_res->reference_pics[i].gpe_res);
626
627             obj_surface = encode_state->reference_objects[i];
628             if (obj_surface && obj_surface->bo) {
629                 i965_object_surface_to_2d_gpe_resource(&common_res->reference_pics[i].gpe_res,
630                                                        obj_surface);
631
632                 common_res->reference_pics[i].obj_surface = obj_surface;
633                 common_res->reference_pics[i].surface_id = pic_param->reference_frames[i].picture_id;
634             } else {
635                 common_res->reference_pics[i].obj_surface = NULL;
636                 common_res->reference_pics[i].surface_id = VA_INVALID_ID;
637             }
638         }
639     }
640
641     if (frame_info->reallocate_flag) {
642         width = frame_info->frame_width;
643         height = frame_info->frame_height;
644         size_shift = (frame_info->bit_depth_luma_minus8 ||
645                       frame_info->bit_depth_chroma_minus8) ? 2 : 3;
646
647         res_size = ALIGN(width, 32) << (6 - size_shift);
648         ALLOC_GPE_RESOURCE(deblocking_filter_line_buffer,
649                            "Deblocking filter line buffer",
650                            res_size);
651         ALLOC_GPE_RESOURCE(deblocking_filter_tile_line_buffer,
652                            "Deblocking filter tile line buffer",
653                            res_size);
654
655         res_size = ALIGN(height +
656                          frame_info->width_in_lcu * 6, 32) << (6 - size_shift);
657         ALLOC_GPE_RESOURCE(deblocking_filter_tile_column_buffer,
658                            "Deblocking filter tile column buffer",
659                            res_size);
660
661         res_size = (((width + 15) >> 4) * 188 +
662                     frame_info->width_in_lcu * 9 + 1023) >> 3;
663         ALLOC_GPE_RESOURCE(metadata_line_buffer,
664                            "metadata line buffer",
665                            res_size);
666
667         res_size = (((width + 15) >> 4) * 172 +
668                     frame_info->width_in_lcu * 9 + 1023) >> 3;
669         ALLOC_GPE_RESOURCE(metadata_tile_line_buffer,
670                            "metadata tile line buffer",
671                            res_size);
672
673         res_size = (((height + 15) >> 4) * 176 +
674                     frame_info->height_in_lcu * 9 + 1023) >> 3;
675         ALLOC_GPE_RESOURCE(metadata_tile_column_buffer,
676                            "metadata tile column buffer",
677                            res_size);
678
679         res_size = ALIGN(((width >> 1) +
680                           frame_info->width_in_lcu * 3), 16) << (6 - size_shift);
681         ALLOC_GPE_RESOURCE(sao_line_buffer,
682                            "sao line buffer",
683                            res_size);
684
685         res_size = ALIGN(((width >> 1) +
686                           frame_info->width_in_lcu * 6), 16) << (6 - size_shift);
687         ALLOC_GPE_RESOURCE(sao_tile_line_buffer,
688                            "sao tile line buffer",
689                            res_size);
690
691         res_size = ALIGN(((height >> 1) +
692                           frame_info->height_in_lcu * 6), 16) << (6 - size_shift);
693         ALLOC_GPE_RESOURCE(sao_tile_column_buffer,
694                            "sao tile column buffer",
695                            res_size);
696
697         if (vdenc_enabled) {
698             res_size = 0x500000;
699             ALLOC_GPE_RESOURCE(streamout_data_destination_buffer,
700                                "streamout data destination buffer",
701                                res_size);
702         }
703
704         res_size = I965_MAX_NUM_SLICE * 64;
705         ALLOC_GPE_RESOURCE(picture_status_buffer,
706                            "picture status buffer",
707                            res_size);
708
709         res_size = frame_info->width_in_lcu * frame_info->height_in_lcu * 256;
710         ALLOC_GPE_RESOURCE(ildb_streamout_buffer,
711                            "ildb streamout buffer",
712                            res_size);
713
714         //res_size = frame_info->width_in_lcu * frame_info->height_in_lcu * 16;
715         width = ALIGN(frame_info->frame_width, 64) >> 3;
716         height = ALIGN(frame_info->frame_height, 64) >> 3;
717         res_size = width * height * 16 + 1024;
718         ALLOC_GPE_RESOURCE(sao_streamout_data_destination_buffer,
719                            "sao streamout date destination buffer",
720                            res_size);
721
722         res_size = ALIGN(8 * 64, 4096);
723         ALLOC_GPE_RESOURCE(frame_statics_streamout_data_destination_buffer,
724                            "frame statics streamout date destination buffer",
725                            res_size);
726
727         //res_size = (ALIGN(width, GEN10_HEVC_ENC_MAX_LCU_SIZE) + 2) * 64 * 8 * 2;
728         res_size = ALIGN(frame_info->frame_width, 64) * 1024 + 2048;
729         res_size = res_size << 1;
730         ALLOC_GPE_RESOURCE(sse_source_pixel_rowstore_buffer,
731                            "sse source pixel rowstore buffer",
732                            res_size);
733     }
734
735     return 0;
736
737 FAIL:
738     return -1;
739 }
740
741 void
742 gen10_hevc_enc_free_common_resource(struct gen10_hevc_enc_common_res *common_res)
743 {
744     int i;
745
746     i965_free_gpe_resource(&common_res->compressed_bitstream.gpe_res);
747     i965_free_gpe_resource(&common_res->uncompressed_pic.gpe_res);
748     i965_free_gpe_resource(&common_res->reconstructed_pic.gpe_res);
749
750     for (i = 0; i < 16; i++)
751         if (common_res->reference_pics[i].surface_id != VA_INVALID_ID)
752             i965_free_gpe_resource(&common_res->reference_pics[i].gpe_res);
753
754     i965_free_gpe_resource(&common_res->deblocking_filter_line_buffer);
755     i965_free_gpe_resource(&common_res->deblocking_filter_tile_line_buffer);
756     i965_free_gpe_resource(&common_res->deblocking_filter_tile_column_buffer);
757     i965_free_gpe_resource(&common_res->metadata_line_buffer);
758     i965_free_gpe_resource(&common_res->metadata_tile_line_buffer);
759     i965_free_gpe_resource(&common_res->metadata_tile_column_buffer);
760     i965_free_gpe_resource(&common_res->sao_line_buffer);
761     i965_free_gpe_resource(&common_res->sao_tile_line_buffer);
762     i965_free_gpe_resource(&common_res->sao_tile_column_buffer);
763     i965_free_gpe_resource(&common_res->streamout_data_destination_buffer);
764     i965_free_gpe_resource(&common_res->picture_status_buffer);
765     i965_free_gpe_resource(&common_res->ildb_streamout_buffer);
766     i965_free_gpe_resource(&common_res->sao_streamout_data_destination_buffer);
767     i965_free_gpe_resource(&common_res->frame_statics_streamout_data_destination_buffer);
768     i965_free_gpe_resource(&common_res->sse_source_pixel_rowstore_buffer);
769 }
770
771 void
772 gen10_hevc_enc_init_status_buffer(VADriverContextP ctx,
773                                   struct encode_state *encode_state,
774                                   struct intel_encoder_context *encoder_context,
775                                   struct gen10_hevc_enc_status_buffer *status_buffer)
776 {
777     struct i965_coded_buffer_segment *coded_buffer_segment;
778     uint32_t base_offset;
779     char *pbuffer;
780     dri_bo *bo;
781
782     bo = encode_state->coded_buf_object->buffer_store->bo;
783
784     i965_free_gpe_resource(&status_buffer->gpe_res);
785     i965_dri_object_to_buffer_gpe_resource(&status_buffer->gpe_res, bo);
786
787     status_buffer->status_size = ALIGN(sizeof(struct gen10_hevc_enc_status), 64);
788
789     status_buffer->mmio_bytes_per_frame_offset = GEN10_MMIO_HCP_ENC_BITSTREAM_BYTECOUNT_FRAME_OFFSET;
790     status_buffer->mmio_bs_frame_no_header_offset = GEN10_MMIO_HCP_ENC_BITSTREAM_BYTECOUNT_FRAME_NO_HEADER_OFFSET;
791     status_buffer->mmio_image_mask_offset = GEN10_MMIO_HCP_ENC_IMAGE_STATUS_MASK_OFFSET;
792     status_buffer->mmio_image_ctrl_offset = GEn10_MMIO_HCP_ENC_IMAGE_STATUS_CTRL_OFFSET;
793     status_buffer->mmio_qp_status_offset = GEN10_MMIO_HCP_ENC_QP_STATE_OFFSET;
794     status_buffer->mmio_bs_se_bitcount_offset = GEN10_MMIO_HCP_ENC_BITSTREAM_SE_BITCOUNT_FRAME_OFFSET;
795
796     base_offset = offsetof(struct i965_coded_buffer_segment, codec_private_data);
797     status_buffer->status_image_mask_offset = base_offset +
798                                               offsetof(struct gen10_hevc_enc_status, image_status_mask);
799     status_buffer->status_image_ctrl_offset = base_offset +
800                                               offsetof(struct gen10_hevc_enc_status, image_status_ctrl);
801     status_buffer->status_bytes_per_frame_offset = base_offset +
802                                                    offsetof(struct gen10_hevc_enc_status, bytes_per_frame);
803     status_buffer->status_pass_num_offset = base_offset +
804                                             offsetof(struct gen10_hevc_enc_status, pass_number);
805     status_buffer->status_media_state_offset = base_offset +
806                                                offsetof(struct gen10_hevc_enc_status, media_state);
807     status_buffer->status_qp_status_offset = base_offset +
808                                              offsetof(struct gen10_hevc_enc_status, qp_status);
809     status_buffer->status_bs_se_bitcount_offset = base_offset +
810                                                   offsetof(struct gen10_hevc_enc_status, bs_se_bitcount);
811
812     dri_bo_map(bo, 1);
813
814     coded_buffer_segment = (struct i965_coded_buffer_segment *)bo->virtual;
815     coded_buffer_segment->mapped = 0;
816     coded_buffer_segment->codec = encoder_context->codec;
817     coded_buffer_segment->status_support = 1;
818
819     pbuffer = bo->virtual + base_offset;
820     memset(pbuffer, 0, status_buffer->status_size);
821
822     dri_bo_unmap(bo);
823 }
824
825 void
826 gen10_hevc_enc_init_lambda_param(struct gen10_hevc_enc_lambda_param *param,
827                                  int bit_depth_luma_minus8,
828                                  int bit_depth_chroma_minus8)
829 {
830     double qp_temp, lambda_double, qp_factor;
831     int qp, qp_max[2], qp_offset[2], shift_qp = 12;
832     uint32_t lambda = 0;
833     int i;
834
835     memset(param, 0, sizeof(*param));
836
837     qp_offset[0] = 6 * bit_depth_luma_minus8;
838     qp_offset[1] = 6 * bit_depth_chroma_minus8;
839     qp_max[0] = 52 + qp_offset[0];
840     qp_max[1] = 52 + qp_offset[1];
841
842     qp_factor = 0.25 * 0.65;
843     for (i = 0; i < 2; i++) {
844         for (qp = 0; qp < qp_max[i]; qp++) {
845             qp_temp = (double)qp - qp_offset[i] - shift_qp;
846             lambda_double = qp_factor * pow(2.0, qp_temp / 3.0);
847             lambda_double = lambda_double * 16 + 0.5;
848             lambda_double = (lambda_double > 65535) ? 65535 : lambda_double;
849             lambda = (uint32_t)floor(lambda_double);
850             param->lambda_intra[i][qp] = (uint16_t)lambda;
851         }
852     }
853
854     qp_factor = 0.55;
855     for (i = 0; i < 2; i++) {
856         for (qp = 0; qp < qp_max[i]; qp++) {
857             qp_temp = (double)qp - qp_offset[i] - shift_qp;
858             lambda_double = qp_factor * pow(2.0, qp_temp / 3.0);
859             if (i == 0)
860                 lambda_double *= MAX(1.00, MIN(1.6, 1.0 + 0.6 / 12.0 * (qp_temp - 10.0)));
861             else
862                 lambda_double *= MAX(0.95, MIN(1.2, 0.25 / 12.0 * (qp_temp - 10.0) + 0.95));
863             lambda_double = lambda_double * 16 + 0.5;
864             lambda = (uint32_t)floor(lambda_double);
865             lambda_double = (lambda_double > 0xffff) ? 0xffff : lambda_double;
866             lambda = CLAMP(0, 0xffff, lambda);
867             param->lambda_inter[i][qp] = (uint16_t)lambda;
868         }
869     }
870 }
871
872 static void
873 hevc_hcp_set_qm_state(VADriverContextP ctx,
874                       struct intel_batchbuffer *batch,
875                       int size_id,
876                       int color_component,
877                       int prediction_type,
878                       int dc_coefficient,
879                       uint8_t *qm_buf,
880                       int qm_length)
881 {
882     gen10_hcp_qm_state_param param;
883
884     memset(&param, 0, sizeof(param));
885     param.dw1.prediction_type = prediction_type;
886     param.dw1.size_id = size_id;
887     param.dw1.color_component = color_component;
888     param.dw1.dc_coefficient = dc_coefficient;
889     memcpy(param.quant_matrix, qm_buf, qm_length);
890     gen10_hcp_qm_state(ctx, batch, &param);
891 }
892
893 static void
894 hevc_hcp_set_fqm_state(VADriverContextP ctx,
895                        struct intel_batchbuffer *batch,
896                        int size_id,
897                        int color_component,
898                        int prediction_type,
899                        int forward_dc_coeff,
900                        uint16_t *fqm_buf,
901                        int fqm_length)
902 {
903     gen10_hcp_fqm_state_param param;
904
905     memset(&param, 0, sizeof(param));
906     param.dw1.prediction_type = prediction_type;
907     param.dw1.size_id = size_id;
908     param.dw1.color_component = color_component;
909     param.dw1.forward_dc_coeff = forward_dc_coeff;
910     memcpy(param.forward_quant_matrix, fqm_buf, fqm_length * sizeof(uint16_t));
911     gen10_hcp_fqm_state(ctx, batch, &param);
912 }
913
914 void
915 gen10_hevc_enc_hcp_set_qm_fqm_states(VADriverContextP ctx,
916                                      struct intel_batchbuffer *batch,
917                                      struct gen10_hevc_enc_frame_info *frame_info)
918 {
919     int dc_coefficient, forward_dc_coeff;
920     uint8_t *real_qm;
921     uint16_t *real_fqm;
922     int comps, len;
923     int i , j, m;
924
925     for (m = 0; m < 4; m++) {
926         comps = (m == 3) ? 1 : 3;
927         len = (m == 0) ? 16 : 64;
928
929         for (i = 0; i < comps; i++) {
930             for (j = 0; j < 2; j++) {
931                 real_qm = frame_info->qm_matrix[m][i][j];
932
933                 if (i == 0)
934                     real_fqm = frame_info->fqm_matrix[m][j];
935
936                 if (m == 2 || m == 3) {
937                     dc_coefficient = frame_info->qm_dc_matrix[m - 2][i][j];
938
939                     if (i == 0)
940                         forward_dc_coeff = frame_info->fqm_dc_matrix[m - 2][j];
941                 } else {
942                     dc_coefficient = 0;
943                     forward_dc_coeff = 0;
944                 }
945
946                 hevc_hcp_set_qm_state(ctx, batch, m, i, j, dc_coefficient,
947                                       real_qm, len);
948
949                 if (i == 0)
950                     hevc_hcp_set_fqm_state(ctx, batch, m, i, j, forward_dc_coeff,
951                                            real_fqm, len);
952             }
953         }
954     }
955 }
956
957 static void
958 gen10_hevc_enc_hcp_set_ref_idx_state(VADriverContextP ctx,
959                                      struct intel_batchbuffer *batch,
960                                      VAEncPictureParameterBufferHEVC *pic_param,
961                                      VAEncSliceParameterBufferHEVC *slice_param,
962                                      int list_index)
963 {
964     gen10_hcp_ref_idx_state_param param;
965     VAPictureHEVC *ref_pic, *cur_pic;
966     int weighted_pred_flag;
967     int i, j;
968
969     assert(list_index < 2);
970
971     memset(&param, 0, sizeof(param));
972
973     param.dw1.ref_pic_list_num = list_index;
974     param.dw1.num_ref_idx_active_minus1 = list_index == 0 ? slice_param->num_ref_idx_l0_active_minus1 :
975                                           slice_param->num_ref_idx_l1_active_minus1;
976
977     cur_pic = &pic_param->decoded_curr_pic;
978     weighted_pred_flag = (pic_param->pic_fields.bits.weighted_pred_flag &&
979                           slice_param->slice_type == HEVC_SLICE_P) ||
980                          (pic_param->pic_fields.bits.weighted_bipred_flag &&
981                           slice_param->slice_type == HEVC_SLICE_B);
982
983     for (i = 0; i < 16; i++) {
984         if (i < MIN(param.dw1.num_ref_idx_active_minus1 + 1, 15)) {
985             if (list_index == 0)
986                 ref_pic = &slice_param->ref_pic_list0[i];
987             else
988                 ref_pic = &slice_param->ref_pic_list1[i];
989
990             j = hevc_enc_map_pic_index(ref_pic->picture_id,
991                                        pic_param->reference_frames, 8);
992             if (j >= 0) {
993                 param.ref_list_entry[i].ref_pic_tb_value = CLAMP(-128, 127,
994                                                                  cur_pic->pic_order_cnt - ref_pic->pic_order_cnt) & 0xff;
995                 param.ref_list_entry[i].ref_pic_frame_id = j;
996                 param.ref_list_entry[i].chroma_weight_flag = weighted_pred_flag;
997                 param.ref_list_entry[i].luma_weight_flag = weighted_pred_flag;
998                 param.ref_list_entry[i].long_term_ref_flag = !!(ref_pic->flags &
999                                                                 VA_PICTURE_HEVC_LONG_TERM_REFERENCE);
1000             }
1001         }
1002     }
1003
1004     gen10_hcp_ref_idx_state(ctx, batch, &param);
1005 }
1006
1007 void
1008 gen10_hevc_enc_hcp_set_ref_idx_lists(VADriverContextP ctx,
1009                                      struct intel_batchbuffer *batch,
1010                                      VAEncPictureParameterBufferHEVC *pic_param,
1011                                      VAEncSliceParameterBufferHEVC *slice_param)
1012 {
1013     gen10_hevc_enc_hcp_set_ref_idx_state(ctx, batch, pic_param, slice_param, 0);
1014     if (slice_param->slice_type == HEVC_SLICE_B)
1015         gen10_hevc_enc_hcp_set_ref_idx_state(ctx, batch, pic_param, slice_param, 1);
1016 }
1017
1018 void
1019 gen10_hevc_enc_hcp_set_weight_offsets(VADriverContextP ctx,
1020                                       struct intel_batchbuffer *batch,
1021                                       VAEncPictureParameterBufferHEVC *pic_param,
1022                                       VAEncSliceParameterBufferHEVC *slice_param)
1023 {
1024     gen10_hcp_weightoffset_state_param param;
1025     int enable;
1026     int i, j;
1027
1028     for (i = 0; i < 2; i++) {
1029         if (i == 0 &&
1030             pic_param->pic_fields.bits.weighted_pred_flag &&
1031             slice_param->slice_type == HEVC_SLICE_P)
1032             enable = 1;
1033         else if (i == 1 &&
1034                  pic_param->pic_fields.bits.weighted_bipred_flag &&
1035                  slice_param->slice_type == HEVC_SLICE_B)
1036             enable = 1;
1037         else
1038             enable = 0;
1039
1040         if (enable) {
1041             memset(&param, 0, sizeof(param));
1042
1043             param.dw1.ref_pic_list_num = i;
1044
1045             if (i == 0) {
1046                 for (j = 0; j < 15; j++) {
1047                     param.luma_offset[j].delta_luma_weight = slice_param->delta_luma_weight_l0[j];
1048                     param.luma_offset[j].luma_offset = slice_param->luma_offset_l0[j];
1049
1050                     param.chroma_offset[j].delta_chroma_weight_0 = slice_param->delta_chroma_weight_l0[j][0];
1051                     param.chroma_offset[j].chroma_offset_0 = slice_param->chroma_offset_l0[j][0];
1052                     param.chroma_offset[j].delta_chroma_weight_1 = slice_param->delta_chroma_weight_l0[j][1];
1053                     param.chroma_offset[j].chroma_offset_1 = slice_param->chroma_offset_l0[j][1];
1054                 }
1055             } else {
1056                 for (j = 0; j < 15; j++) {
1057                     param.luma_offset[j].delta_luma_weight = slice_param->delta_luma_weight_l1[j];
1058                     param.luma_offset[j].luma_offset = slice_param->luma_offset_l1[j];
1059
1060                     param.chroma_offset[j].delta_chroma_weight_0 = slice_param->delta_chroma_weight_l1[j][0];
1061                     param.chroma_offset[j].chroma_offset_0 = slice_param->chroma_offset_l1[j][0];
1062                     param.chroma_offset[j].delta_chroma_weight_1 = slice_param->delta_chroma_weight_l1[j][1];
1063                     param.chroma_offset[j].chroma_offset_1 = slice_param->chroma_offset_l1[j][1];
1064                 }
1065             }
1066
1067             gen10_hcp_weightoffset_state(ctx, batch, &param);
1068         }
1069     }
1070 }
1071
1072 VAStatus
1073 gen10_hevc_enc_ensure_surface(VADriverContextP ctx,
1074                               struct object_surface *obj_surface,
1075                               int bit_depth_minus8,
1076                               int reallocate_flag)
1077 {
1078     VAStatus va_status = VA_STATUS_SUCCESS;
1079     uint32_t fourcc = VA_FOURCC_NV12;
1080     int update = 0;
1081
1082     if (!obj_surface) {
1083         va_status = VA_STATUS_ERROR_INVALID_PARAMETER;
1084
1085         goto EXIT;
1086     }
1087
1088     if (bit_depth_minus8 > 0) {
1089         if (obj_surface->fourcc != VA_FOURCC_P010) {
1090             update = 1;
1091             fourcc = VA_FOURCC_P010;
1092         }
1093     } else if (obj_surface->fourcc != VA_FOURCC_NV12) {
1094         update = 1;
1095         fourcc = VA_FOURCC_NV12;
1096     }
1097
1098     if (!obj_surface->bo || update) {
1099         if (reallocate_flag) {
1100             struct i965_driver_data * const i965 = i965_driver_data(ctx);
1101
1102             i965_destroy_surface_storage(obj_surface);
1103
1104             va_status = i965_check_alloc_surface_bo(ctx,
1105                                                     obj_surface,
1106                                                     i965->codec_info->has_tiled_surface,
1107                                                     fourcc,
1108                                                     SUBSAMPLE_YUV420);
1109         } else
1110             va_status = VA_STATUS_ERROR_INVALID_PARAMETER;
1111     }
1112
1113 EXIT:
1114     return va_status;
1115 }
1116
1117 static void
1118 hevc_get_max_mbps(uint32_t level_idc,
1119                   uint32_t *max_bps,
1120                   uint64_t *max_bps_per_pic)
1121 {
1122     switch (level_idc) {
1123     case 30:
1124         *max_bps = 552960;
1125         *max_bps_per_pic = 36864;
1126         break;
1127     case 60:
1128         *max_bps = 3686400;
1129         *max_bps_per_pic = 122880;
1130         break;
1131     case 63:
1132         *max_bps = 7372800;
1133         *max_bps_per_pic = 245760;
1134         break;
1135     case 90:
1136         *max_bps = 16588800;
1137         *max_bps_per_pic = 552760;
1138         break;
1139     case 93:
1140         *max_bps = 33177600;
1141         *max_bps_per_pic = 983040;
1142         break;
1143     case 120:
1144         *max_bps = 66846720;
1145         *max_bps_per_pic = 2228224;
1146         break;
1147     case 123:
1148         *max_bps = 133693440;
1149         *max_bps_per_pic = 2228224;
1150         break;
1151     case 150:
1152         *max_bps = 267386880;
1153         *max_bps_per_pic = 8912896;
1154         break;
1155     case 153:
1156         *max_bps = 534773760;
1157         *max_bps_per_pic = 8912896;
1158         break;
1159     case 156:
1160         *max_bps = 1069547520;
1161         *max_bps_per_pic = 8912896;
1162         break;
1163     case 180:
1164         *max_bps = 1069547520;
1165         *max_bps_per_pic = 35651584;
1166         break;
1167     case 183:
1168         *max_bps = 2139095040;
1169         *max_bps_per_pic = 35651584;
1170         break;
1171     case 186:
1172         *max_bps = 4278190080;
1173         *max_bps_per_pic = 35651584;
1174         break;
1175     default:
1176         *max_bps = 16588800;
1177         *max_bps_per_pic = 552760;
1178         break;
1179     }
1180 }
1181
1182 uint32_t
1183 gen10_hevc_enc_get_profile_level_max_frame(VAEncSequenceParameterBufferHEVC *seq_param,
1184                                            uint32_t user_max_frame_size,
1185                                            uint32_t frame_rate)
1186 {
1187     int bit_depth_minus8 = seq_param->seq_fields.bits.bit_depth_luma_minus8;
1188     uint64_t max_byte_per_pic, max_byte_per_pic_not0;
1189     int level_idc = seq_param->general_level_idc;
1190     uint32_t profile_level_max_frame, max_mbps;
1191     double format_factor = 1.5;
1192     double min_cr_scale = 1.0;
1193     int min_cr;
1194
1195     assert(seq_param->seq_fields.bits.chroma_format_idc == 1);
1196
1197     if (level_idc == 186 || level_idc == 150)
1198         min_cr = 6;
1199     else if (level_idc > 150)
1200         min_cr = 8;
1201     else if (level_idc > 93)
1202         min_cr = 4;
1203     else
1204         min_cr = 2;
1205
1206     format_factor = bit_depth_minus8 == 2 ? 1.875 :
1207                     bit_depth_minus8 == 4 ? 2.25 : 1.5;
1208
1209     min_cr_scale *= min_cr;
1210     format_factor /= min_cr_scale;
1211
1212     hevc_get_max_mbps(level_idc, &max_mbps, &max_byte_per_pic);
1213
1214     max_byte_per_pic_not0 = (uint64_t)((((float_t)max_mbps * (float_t)100) / (float_t)frame_rate)  * format_factor);
1215
1216     if (user_max_frame_size) {
1217         profile_level_max_frame = (uint32_t)MIN(user_max_frame_size, max_byte_per_pic);
1218         profile_level_max_frame = (uint32_t)MIN(max_byte_per_pic_not0, profile_level_max_frame);
1219     } else
1220         profile_level_max_frame = (uint32_t)MIN(max_byte_per_pic_not0, max_byte_per_pic);
1221
1222     return MIN(profile_level_max_frame,
1223                seq_param->pic_width_in_luma_samples * seq_param->pic_height_in_luma_samples);
1224 }
1225
1226 uint32_t
1227 gen10_hevc_enc_get_max_num_slices(VAEncSequenceParameterBufferHEVC *seq_param)
1228 {
1229     uint32_t max_num_slices = 0;
1230
1231     switch (seq_param->general_level_idc) {
1232     case 30:
1233         max_num_slices = 16;
1234         break;
1235     case 60:
1236         max_num_slices = 16;
1237         break;
1238     case 63:
1239         max_num_slices = 20;
1240         break;
1241     case 90:
1242         max_num_slices = 30;
1243         break;
1244     case 93:
1245         max_num_slices = 40;
1246         break;
1247     case 120:
1248         max_num_slices = 75;
1249         break;
1250     case 123:
1251         max_num_slices = 75;
1252         break;
1253     case 150:
1254         max_num_slices = 200;
1255         break;
1256     case 153:
1257         max_num_slices = 200;
1258         break;
1259     case 156:
1260         max_num_slices = 200;
1261         break;
1262     case 180:
1263         max_num_slices = 600;
1264         break;
1265     case 183:
1266         max_num_slices = 600;
1267         break;
1268     case 186:
1269         max_num_slices = 600;
1270         break;
1271     default:
1272         max_num_slices = 0;
1273         break;
1274     }
1275
1276     return max_num_slices;
1277 }
1278
1279 static
1280 uint32_t gen10_hevc_get_start_code_offset(unsigned char *ptr,
1281                                           uint32_t size)
1282 {
1283     uint32_t count = 0;
1284
1285     while (count < size && *ptr != 0x01) {
1286         if (*ptr != 0)
1287             break;
1288
1289         count++;
1290         ptr++;
1291     }
1292
1293     return count + 1;
1294 }
1295
1296 static
1297 uint32_t gen10_hevc_get_emulation_num(unsigned char *ptr,
1298                                       uint32_t size)
1299 {
1300     uint32_t emulation_num = 0;
1301     uint32_t header_offset = 0;
1302     uint32_t zero_count = 0;
1303     int i = 0;
1304
1305     header_offset = gen10_hevc_get_start_code_offset(ptr, size);
1306     ptr += header_offset;
1307
1308     for (i = 0 ; i < (size - header_offset); i++, ptr++) {
1309         if (zero_count == 2 && !(*ptr & 0xFC)) {
1310             zero_count = 0;
1311             emulation_num++;
1312         }
1313
1314         if (*ptr == 0x00)
1315             zero_count++;
1316         else
1317             zero_count = 0;
1318     }
1319
1320     return emulation_num;
1321 }
1322
1323 #define HEVC_ENC_START_CODE_NAL_OFFSET                  (2)
1324
1325 uint32_t
1326 gen10_hevc_enc_get_pic_header_size(struct encode_state *encode_state)
1327 {
1328     VAEncPackedHeaderParameterBuffer *param = NULL;
1329     uint32_t header_begin = 0;
1330     uint32_t accum_size = 0;
1331     unsigned char *header_data = NULL;
1332     uint32_t length_in_bytes = 0;
1333     int packed_type = 0;
1334     int idx = 0, count = 0, idx_offset = 0;
1335     int i = 0, slice_idx = 0, start_index = 0;
1336
1337     for (i = 0; i < 4; i++) {
1338         idx_offset = 0;
1339         switch (i) {
1340         case 0:
1341             packed_type = VAEncPackedHeaderHEVC_VPS;
1342             break;
1343         case 1:
1344             packed_type = VAEncPackedHeaderHEVC_VPS;
1345             idx_offset = 1;
1346             break;
1347         case 2:
1348             packed_type = VAEncPackedHeaderHEVC_PPS;
1349             break;
1350         case 3:
1351             packed_type = VAEncPackedHeaderHEVC_SEI;
1352             break;
1353         default:
1354             break;
1355         }
1356
1357         idx = va_enc_packed_type_to_idx(packed_type) + idx_offset;
1358         if (encode_state->packed_header_data[idx]) {
1359             param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[idx]->buffer;
1360             header_data = (unsigned char *)encode_state->packed_header_data[idx]->buffer;
1361             length_in_bytes = (param->bit_length + 7) / 8;
1362
1363             header_begin = gen10_hevc_get_start_code_offset(header_data, length_in_bytes) +
1364                            HEVC_ENC_START_CODE_NAL_OFFSET;
1365
1366             accum_size += length_in_bytes;
1367             if (!param->has_emulation_bytes)
1368                 accum_size += gen10_hevc_get_emulation_num(header_data,
1369                                                            length_in_bytes);
1370         }
1371     }
1372
1373     for (slice_idx = 0; slice_idx < encode_state->num_slice_params_ext; slice_idx++) {
1374         count = encode_state->slice_rawdata_count[slice_idx];
1375         start_index = encode_state->slice_rawdata_index[slice_idx] &
1376                       SLICE_PACKED_DATA_INDEX_MASK;
1377
1378         if (start_index >= 5)
1379             break;
1380
1381         for (i = 0; i < count; i++) {
1382             param = (VAEncPackedHeaderParameterBuffer *)
1383                     (encode_state->packed_header_params_ext[start_index + i]->buffer);
1384
1385             if (param->type == VAEncPackedHeaderSlice)
1386                 continue;
1387
1388             header_data = (unsigned char *)encode_state->packed_header_data[start_index]->buffer;
1389             length_in_bytes = (param->bit_length + 7) / 8;
1390
1391             accum_size += length_in_bytes;
1392             if (!param->has_emulation_bytes)
1393                 accum_size += gen10_hevc_get_emulation_num(header_data,
1394                                                            length_in_bytes);
1395         }
1396     }
1397
1398     header_begin = MIN(header_begin, accum_size);
1399
1400     return ((accum_size - header_begin) * 8);
1401 }