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
25
26 /**
27 * @file
28 * This file implements the glue code between FFmpeg's and VA API's
29 * structures for H.264 decoding.
30 */
31
32 /**
33 * Initialize an empty VA API picture.
34 *
35 * VA API requires a fixed-size reference picture array.
36 */
38 {
39 va_pic->picture_id = VA_INVALID_ID;
40 va_pic->flags = VA_PICTURE_H264_INVALID;
41 va_pic->TopFieldOrderCnt = 0;
42 va_pic->BottomFieldOrderCnt = 0;
43 }
44
45 /**
46 * Translate an FFmpeg Picture into its VA API form.
47 *
48 * @param[out] va_pic A pointer to VA API's own picture struct
49 * @param[in] pic A pointer to the FFmpeg picture struct to convert
50 * @param[in] pic_structure The picture field type (as defined in mpegvideo.h),
51 * supersedes pic's field type if nonzero.
52 */
55 int pic_structure)
56 {
57 if (pic_structure == 0)
59 pic_structure &=
PICT_FRAME;
/* PICT_TOP_FIELD|PICT_BOTTOM_FIELD */
60
63
64 va_pic->flags = 0;
66 va_pic->flags |= (pic_structure &
PICT_TOP_FIELD) ? VA_PICTURE_H264_TOP_FIELD : VA_PICTURE_H264_BOTTOM_FIELD;
68 va_pic->flags |= pic->
long_ref ? VA_PICTURE_H264_LONG_TERM_REFERENCE : VA_PICTURE_H264_SHORT_TERM_REFERENCE;
69
70 va_pic->TopFieldOrderCnt = 0;
72 va_pic->TopFieldOrderCnt = pic->
field_poc[0];
73
74 va_pic->BottomFieldOrderCnt = 0;
76 va_pic->BottomFieldOrderCnt = pic->
field_poc[1];
77 }
78
79 /** Decoded Picture Buffer (DPB). */
81 int size;
///< Current number of reference frames in the DPB
82 int max_size;
///< Max number of reference frames. This is FF_ARRAY_ELEMS(VAPictureParameterBufferH264.ReferenceFrames)
83 VAPictureH264 *
va_pics;
///< Pointer to VAPictureParameterBufferH264.ReferenceFrames array
85
86 /**
87 * Append picture to the decoded picture buffer, in a VA API form that
88 * merges the second field picture attributes with the first, if
89 * available. The decoded picture buffer's size must be large enough
90 * to receive the new VA API picture object.
91 */
93 {
94 int i;
95
97 return -1;
98
99 for (i = 0; i < dpb->
size; i++) {
100 VAPictureH264 *
const va_pic = &dpb->
va_pics[i];
102 VAPictureH264 temp_va_pic;
104
105 if ((temp_va_pic.flags ^ va_pic->flags) & (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD)) {
106 va_pic->flags |= temp_va_pic.flags & (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD);
107 /* Merge second field */
108 if (temp_va_pic.flags & VA_PICTURE_H264_TOP_FIELD) {
109 va_pic->TopFieldOrderCnt = temp_va_pic.TopFieldOrderCnt;
110 } else {
111 va_pic->BottomFieldOrderCnt = temp_va_pic.BottomFieldOrderCnt;
112 }
113 }
114 return 0;
115 }
116 }
117
119 return 0;
120 }
121
122 /** Fill in VA API reference frames array. */
125 {
127 int i;
128
131 dpb.
va_pics = pic_param->ReferenceFrames;
134
138 return -1;
139 }
140
141 for (i = 0; i < 16; i++) {
144 return -1;
145 }
146 return 0;
147 }
148
149 /**
150 * Fill in VA API reference picture lists from the FFmpeg reference
151 * picture list.
152 *
153 * @param[out] RefPicList VA API internal reference picture list
154 * @param[in] ref_list A pointer to the FFmpeg reference list
155 * @param[in] ref_count The number of reference pictures in ref_list
156 */
159 unsigned int ref_count)
160 {
161 unsigned int i,
n = 0;
162 for (i = 0; i < ref_count; i++)
163 if (ref_list[i].reference)
165
166 for (; n < 32; n++)
168 }
169
170 /**
171 * Fill in prediction weight table.
172 *
173 * VA API requires a plain prediction weight table as it does not infer
174 * any value.
175 *
176 * @param[in] h A pointer to the current H.264 context
177 * @param[in] list The reference frame list index to use
178 * @param[out] luma_weight_flag VA API plain luma weight flag
179 * @param[out] luma_weight VA API plain luma weight table
180 * @param[out] luma_offset VA API plain luma offset table
181 * @param[out] chroma_weight_flag VA API plain chroma weight flag
182 * @param[out] chroma_weight VA API plain chroma weight table
183 * @param[out] chroma_offset VA API plain chroma offset table
184 */
186 int list,
187 unsigned char *luma_weight_flag,
188 short luma_weight[32],
189 short luma_offset[32],
190 unsigned char *chroma_weight_flag,
191 short chroma_weight[32][2],
192 short chroma_offset[32][2])
193 {
194 unsigned int i, j;
195
198
199 for (i = 0; i < h->
ref_count[list]; i++) {
200 /* VA API also wants the inferred (default) values, not
201 only what is available in the bitstream (7.4.3.2). */
205 } else {
207 luma_offset[i] = 0;
208 }
209 for (j = 0; j < 2; j++) {
213 } else {
215 chroma_offset[i][j] = 0;
216 }
217 }
218 }
219 }
220
221 /** Initialize and start decoding a frame with VA API. */
225 {
228 VAPictureParameterBufferH264 *pic_param;
229 VAIQMatrixBufferH264 *iq_matrix;
230
231 av_dlog(avctx,
"vaapi_h264_start_frame()\n");
232
234
235 /* Fill in VAPictureParameterBufferH264. */
237 if (!pic_param)
238 return -1;
241 return -1;
242 pic_param->picture_width_in_mbs_minus1 = h->
mb_width - 1;
243 pic_param->picture_height_in_mbs_minus1 = h->
mb_height - 1;
247 pic_param->seq_fields.value = 0; /* reset all bits */
252 pic_param->seq_fields.bits.mb_adaptive_frame_field_flag = h->
sps.
mb_aff;
254 pic_param->seq_fields.bits.MinLumaBiPredSize8x8 = h->
sps.
level_idc >= 31;
/* A.3.3.2 */
256 pic_param->seq_fields.bits.pic_order_cnt_type = h->
sps.
poc_type;
257 pic_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = h->
sps.
log2_max_poc_lsb - 4;
261 pic_param->slice_group_change_rate_minus1 = 0; /* XXX: unimplemented in FFmpeg */
262 pic_param->pic_init_qp_minus26 = h->
pps.
init_qp - 26;
263 pic_param->pic_init_qs_minus26 = h->
pps.
init_qs - 26;
266 pic_param->pic_fields.value = 0; /* reset all bits */
267 pic_param->pic_fields.bits.entropy_coding_mode_flag = h->
pps.
cabac;
276 pic_param->pic_fields.bits.reference_pic_flag = h->
nal_ref_idc != 0;
278
279 /* Fill in VAIQMatrixBufferH264. */
281 if (!iq_matrix)
282 return -1;
283 memcpy(iq_matrix->ScalingList4x4, h->
pps.
scaling_matrix4,
sizeof(iq_matrix->ScalingList4x4));
284 memcpy(iq_matrix->ScalingList8x8[0], h->
pps.
scaling_matrix8[0],
sizeof(iq_matrix->ScalingList8x8[0]));
285 memcpy(iq_matrix->ScalingList8x8[1], h->
pps.
scaling_matrix8[3],
sizeof(iq_matrix->ScalingList8x8[0]));
286 return 0;
287 }
288
289 /** End a hardware decoding based frame. */
291 {
295
296 av_dlog(avctx,
"vaapi_h264_end_frame()\n");
298 if (ret < 0)
300
302 if (ret < 0)
304
306
310 }
311
312 /** Decode the given H.264 slice with VA API. */
316 {
318 VASliceParameterBufferH264 *slice_param;
319
320 av_dlog(avctx,
"vaapi_h264_decode_slice(): buffer %p, size %d\n",
321 buffer, size);
322
323 /* Fill in VASliceParameterBufferH264. */
325 if (!slice_param)
326 return -1;
327 slice_param->slice_data_bit_offset =
get_bits_count(&h->
gb) + 8;
/* bit buffer started beyond nal_unit_type */
340
343
345 &slice_param->luma_weight_l0_flag, slice_param->luma_weight_l0, slice_param->luma_offset_l0,
346 &slice_param->chroma_weight_l0_flag, slice_param->chroma_weight_l0, slice_param->chroma_offset_l0);
348 &slice_param->luma_weight_l1_flag, slice_param->luma_weight_l1, slice_param->luma_offset_l1,
349 &slice_param->chroma_weight_l1_flag, slice_param->chroma_weight_l1, slice_param->chroma_offset_l1);
350 return 0;
351 }
352
354 .
name =
"h264_vaapi",
361 };