1 /*
2 * H.264 HW decode acceleration through VA API
3 *
4 * Copyright (C) 2008-2009 Splitted-Desktop Systems
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
27
28 /**
29 * @file
30 * This file implements the glue code between FFmpeg's and VA API's
31 * structures for H.264 decoding.
32 */
33
34 /**
35 * Initialize an empty VA API picture.
36 *
37 * VA API requires a fixed-size reference picture array.
38 */
40 {
41 va_pic->picture_id = VA_INVALID_ID;
42 va_pic->flags = VA_PICTURE_H264_INVALID;
43 va_pic->TopFieldOrderCnt = 0;
44 va_pic->BottomFieldOrderCnt = 0;
45 }
46
47 /**
48 * Translate an FFmpeg Picture into its VA API form.
49 *
50 * @param[out] va_pic A pointer to VA API's own picture struct
51 * @param[in] pic A pointer to the FFmpeg picture struct to convert
52 * @param[in] pic_structure The picture field type (as defined in mpegvideo.h),
53 * supersedes pic's field type if nonzero.
54 */
57 int pic_structure)
58 {
59 if (pic_structure == 0)
61 pic_structure &=
PICT_FRAME;
/* PICT_TOP_FIELD|PICT_BOTTOM_FIELD */
62
65
66 va_pic->flags = 0;
68 va_pic->flags |= (pic_structure &
PICT_TOP_FIELD) ? VA_PICTURE_H264_TOP_FIELD : VA_PICTURE_H264_BOTTOM_FIELD;
70 va_pic->flags |= pic->
long_ref ? VA_PICTURE_H264_LONG_TERM_REFERENCE : VA_PICTURE_H264_SHORT_TERM_REFERENCE;
71
72 va_pic->TopFieldOrderCnt = 0;
74 va_pic->TopFieldOrderCnt = pic->
field_poc[0];
75
76 va_pic->BottomFieldOrderCnt = 0;
78 va_pic->BottomFieldOrderCnt = pic->
field_poc[1];
79 }
80
81 /** Decoded Picture Buffer (DPB). */
83 int size;
///< Current number of reference frames in the DPB
84 int max_size;
///< Max number of reference frames. This is FF_ARRAY_ELEMS(VAPictureParameterBufferH264.ReferenceFrames)
85 VAPictureH264 *
va_pics;
///< Pointer to VAPictureParameterBufferH264.ReferenceFrames array
87
88 /**
89 * Append picture to the decoded picture buffer, in a VA API form that
90 * merges the second field picture attributes with the first, if
91 * available. The decoded picture buffer's size must be large enough
92 * to receive the new VA API picture object.
93 */
95 {
96 int i, pic_frame_idx, merged = 0;
97
99 return -1;
100
102
103 for (
i = 0;
i < dpb->
size;
i++) {
104 VAPictureH264 *
const va_pic = &dpb->
va_pics[
i];
105 int va_pic_long_ref = !!(va_pic->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE);
108 va_pic->frame_idx == pic_frame_idx) {
109 VAPictureH264 temp_va_pic;
111
112 if ((temp_va_pic.flags ^ va_pic->flags) & (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD)) {
113 va_pic->flags |= temp_va_pic.flags & (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD);
114 /* Merge second field */
115 if (temp_va_pic.flags & VA_PICTURE_H264_TOP_FIELD) {
116 va_pic->TopFieldOrderCnt = temp_va_pic.TopFieldOrderCnt;
117 } else {
118 va_pic->BottomFieldOrderCnt = temp_va_pic.BottomFieldOrderCnt;
119 }
120 merged = 1;
121 }
122 }
123 }
124
125 if (merged)
126 return 0;
127
129 return 0;
130 }
131
132 /** Fill in VA API reference frames array. */
135 {
138
141 dpb.
va_pics = pic_param->ReferenceFrames;
144
145 for (
i = 0;
i <
h->short_ref_count;
i++) {
148 return -1;
149 }
150
151 for (
i = 0;
i < 16;
i++) {
154 return -1;
155 }
156 return 0;
157 }
158
159 /**
160 * Fill in VA API reference picture lists from the FFmpeg reference
161 * picture list.
162 *
163 * @param[out] RefPicList VA API internal reference picture list
164 * @param[in] ref_list A pointer to the FFmpeg reference list
165 * @param[in] ref_count The number of reference pictures in ref_list
166 */
169 unsigned int ref_count)
170 {
171 unsigned int i, n = 0;
172 for (
i = 0;
i < ref_count;
i++)
173 if (ref_list[
i].reference)
175 ref_list[
i].reference);
176
177 for (; n < 32; n++)
179 }
180
181 /**
182 * Fill in prediction weight table.
183 *
184 * VA API requires a plain prediction weight table as it does not infer
185 * any value.
186 *
187 * @param[in] h A pointer to the current H.264 context
188 * @param[in] list The reference frame list index to use
189 * @param[out] luma_weight_flag VA API plain luma weight flag
190 * @param[out] luma_weight VA API plain luma weight table
191 * @param[out] luma_offset VA API plain luma offset table
192 * @param[out] chroma_weight_flag VA API plain chroma weight flag
193 * @param[out] chroma_weight VA API plain chroma weight table
194 * @param[out] chroma_offset VA API plain chroma offset table
195 */
198 unsigned char *luma_weight_flag,
199 short luma_weight[32],
200 short luma_offset[32],
201 unsigned char *chroma_weight_flag,
202 short chroma_weight[32][2],
203 short chroma_offset[32][2])
204 {
207
210
212 /* VA API also wants the inferred (default) values, not
213 only what is available in the bitstream (7.4.3.2). */
217 } else {
220 }
221 for (j = 0; j < 2; j++) {
225 } else {
227 chroma_offset[
i][j] = 0;
228 }
229 }
230 }
231 }
232
233 /** Initialize and start decoding a frame with VA API. */
238 {
243 VAPictureParameterBufferH264 pic_param;
244 VAIQMatrixBufferH264 iq_matrix;
245 int err;
246
248
249 pic_param = (VAPictureParameterBufferH264) {
250 .picture_width_in_mbs_minus1 =
h->mb_width - 1,
251 .picture_height_in_mbs_minus1 =
h->mb_height - 1,
252 .bit_depth_luma_minus8 =
sps->bit_depth_luma - 8,
253 .bit_depth_chroma_minus8 =
sps->bit_depth_chroma - 8,
254 .num_ref_frames =
sps->ref_frame_count,
255 .seq_fields.bits = {
256 .chroma_format_idc =
sps->chroma_format_idc,
257 .residual_colour_transform_flag =
sps->residual_color_transform_flag,
258 .gaps_in_frame_num_value_allowed_flag =
sps->gaps_in_frame_num_allowed_flag,
259 .frame_mbs_only_flag =
sps->frame_mbs_only_flag,
260 .mb_adaptive_frame_field_flag =
sps->mb_aff,
261 .direct_8x8_inference_flag =
sps->direct_8x8_inference_flag,
262 .MinLumaBiPredSize8x8 =
sps->level_idc >= 31,
/* A.3.3.2 */
263 .log2_max_frame_num_minus4 =
sps->log2_max_frame_num - 4,
264 .pic_order_cnt_type =
sps->poc_type,
265 .log2_max_pic_order_cnt_lsb_minus4 =
sps->log2_max_poc_lsb - 4,
266 .delta_pic_order_always_zero_flag =
sps->delta_pic_order_always_zero_flag,
267 },
268 .pic_init_qp_minus26 =
pps->init_qp - 26,
269 .pic_init_qs_minus26 =
pps->init_qs - 26,
270 .chroma_qp_index_offset =
pps->chroma_qp_index_offset[0],
271 .second_chroma_qp_index_offset =
pps->chroma_qp_index_offset[1],
272 .pic_fields.bits = {
273 .entropy_coding_mode_flag =
pps->cabac,
274 .weighted_pred_flag =
pps->weighted_pred,
275 .weighted_bipred_idc =
pps->weighted_bipred_idc,
276 .transform_8x8_mode_flag =
pps->transform_8x8_mode,
277 .field_pic_flag =
h->picture_structure !=
PICT_FRAME,
278 .constrained_intra_pred_flag =
pps->constrained_intra_pred,
279 .pic_order_present_flag =
pps->pic_order_present,
280 .deblocking_filter_control_present_flag =
pps->deblocking_filter_parameters_present,
281 .redundant_pic_cnt_present_flag =
pps->redundant_pic_cnt_present,
282 .reference_pic_flag =
h->nal_ref_idc != 0,
283 },
284 .frame_num =
h->poc.frame_num,
285 };
286
289 if (err < 0)
291
293 VAPictureParameterBufferType,
294 &pic_param, sizeof(pic_param));
295 if (err < 0)
297
298 memcpy(iq_matrix.ScalingList4x4,
299 pps->scaling_matrix4,
sizeof(iq_matrix.ScalingList4x4));
300 memcpy(iq_matrix.ScalingList8x8[0],
301 pps->scaling_matrix8[0],
sizeof(iq_matrix.ScalingList8x8[0]));
302 memcpy(iq_matrix.ScalingList8x8[1],
303 pps->scaling_matrix8[3],
sizeof(iq_matrix.ScalingList8x8[0]));
304
306 VAIQMatrixBufferType,
307 &iq_matrix, sizeof(iq_matrix));
308 if (err < 0)
310
311 return 0;
312
315 return err;
316 }
317
318 /** End a hardware decoding based frame. */
320 {
325
329
331
334 }
335
336 /** Decode the given H.264 slice with VA API. */
340 {
344 VASliceParameterBufferH264 slice_param;
345 int err;
346
347 slice_param = (VASliceParameterBufferH264) {
348 .slice_data_size =
size,
349 .slice_data_offset = 0,
350 .slice_data_flag = VA_SLICE_DATA_FLAG_ALL,
358 .slice_qp_delta = sl->
qscale -
h->ps.pps->init_qp,
364 };
365
370
372 &slice_param.luma_weight_l0_flag,
373 slice_param.luma_weight_l0,
374 slice_param.luma_offset_l0,
375 &slice_param.chroma_weight_l0_flag,
376 slice_param.chroma_weight_l0,
377 slice_param.chroma_offset_l0);
379 &slice_param.luma_weight_l1_flag,
380 slice_param.luma_weight_l1,
381 slice_param.luma_offset_l1,
382 &slice_param.chroma_weight_l1_flag,
383 slice_param.chroma_weight_l1,
384 slice_param.chroma_offset_l1);
385
387 &slice_param, 1, sizeof(slice_param),
389 if (err) {
391 return err;
392 }
393
394 return 0;
395 }
396
398 .
p.
name =
"h264_vaapi",
411 };