st/va: add missing break statement
[mesa.git] / src / gallium / state_trackers / va / picture.c
1 /**************************************************************************
2 *
3 * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
4 * Copyright 2014 Advanced Micro Devices, Inc.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 **************************************************************************/
28
29 #include "pipe/p_video_codec.h"
30
31 #include "util/u_handle_table.h"
32 #include "util/u_video.h"
33
34 #include "vl/vl_vlc.h"
35 #include "vl/vl_winsys.h"
36
37 #include "va_private.h"
38
39 VAStatus
40 vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID render_target)
41 {
42 vlVaDriver *drv;
43 vlVaContext *context;
44 vlVaSurface *surf;
45
46 if (!ctx)
47 return VA_STATUS_ERROR_INVALID_CONTEXT;
48
49 drv = VL_VA_DRIVER(ctx);
50 if (!drv)
51 return VA_STATUS_ERROR_INVALID_CONTEXT;
52
53 context = handle_table_get(drv->htab, context_id);
54 if (!context)
55 return VA_STATUS_ERROR_INVALID_CONTEXT;
56
57 surf = handle_table_get(drv->htab, render_target);
58 if (!surf || !surf->buffer)
59 return VA_STATUS_ERROR_INVALID_SURFACE;
60
61 context->target = surf->buffer;
62 if (!context->decoder) {
63 /* VPP */
64 if ((context->target->buffer_format != PIPE_FORMAT_B8G8R8A8_UNORM &&
65 context->target->buffer_format != PIPE_FORMAT_R8G8B8A8_UNORM &&
66 context->target->buffer_format != PIPE_FORMAT_B8G8R8X8_UNORM &&
67 context->target->buffer_format != PIPE_FORMAT_R8G8B8X8_UNORM) ||
68 context->target->interlaced)
69 return VA_STATUS_ERROR_UNIMPLEMENTED;
70 return VA_STATUS_SUCCESS;
71 }
72
73 context->decoder->begin_frame(context->decoder, context->target, &context->desc.base);
74
75 return VA_STATUS_SUCCESS;
76 }
77
78 void
79 vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id,
80 struct pipe_video_buffer **ref_frame)
81 {
82 vlVaSurface *surf = handle_table_get(drv->htab, surface_id);
83 if (surf)
84 *ref_frame = surf->buffer;
85 else
86 *ref_frame = NULL;
87 }
88
89 static void
90 handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
91 {
92 VAPictureParameterBufferHEVC *hevc;
93 unsigned int i;
94
95 switch (u_reduce_video_profile(context->decoder->profile)) {
96 case PIPE_VIDEO_FORMAT_MPEG12:
97 vlVaHandlePictureParameterBufferMPEG12(drv, context, buf);
98 break;
99
100 case PIPE_VIDEO_FORMAT_MPEG4_AVC:
101 vlVaHandlePictureParameterBufferH264(drv, context, buf);
102 break;
103
104 case PIPE_VIDEO_FORMAT_VC1:
105 vlVaHandlePictureParameterBufferVC1(drv, context, buf);
106 break;
107
108 case PIPE_VIDEO_FORMAT_MPEG4:
109 vlVaHandlePictureParameterBufferMPEG4(drv, context, buf);
110 break;
111
112 case PIPE_VIDEO_FORMAT_HEVC:
113 assert(buf->size >= sizeof(VAPictureParameterBufferHEVC) && buf->num_elements == 1);
114 hevc = buf->data;
115 context->desc.h265.pps->sps->chroma_format_idc = hevc->pic_fields.bits.chroma_format_idc;
116 context->desc.h265.pps->sps->separate_colour_plane_flag =
117 hevc->pic_fields.bits.separate_colour_plane_flag;
118 context->desc.h265.pps->sps->pic_width_in_luma_samples = hevc->pic_width_in_luma_samples;
119 context->desc.h265.pps->sps->pic_height_in_luma_samples = hevc->pic_height_in_luma_samples;
120 context->desc.h265.pps->sps->bit_depth_luma_minus8 = hevc->bit_depth_luma_minus8;
121 context->desc.h265.pps->sps->bit_depth_chroma_minus8 = hevc->bit_depth_chroma_minus8;
122 context->desc.h265.pps->sps->log2_max_pic_order_cnt_lsb_minus4 =
123 hevc->log2_max_pic_order_cnt_lsb_minus4;
124 context->desc.h265.pps->sps->sps_max_dec_pic_buffering_minus1 =
125 hevc->sps_max_dec_pic_buffering_minus1;
126 context->desc.h265.pps->sps->log2_min_luma_coding_block_size_minus3 =
127 hevc->log2_min_luma_coding_block_size_minus3;
128 context->desc.h265.pps->sps->log2_diff_max_min_luma_coding_block_size =
129 hevc->log2_diff_max_min_luma_coding_block_size;
130 context->desc.h265.pps->sps->log2_min_transform_block_size_minus2 =
131 hevc->log2_min_transform_block_size_minus2;
132 context->desc.h265.pps->sps->log2_diff_max_min_transform_block_size =
133 hevc->log2_diff_max_min_transform_block_size;
134 context->desc.h265.pps->sps->max_transform_hierarchy_depth_inter =
135 hevc->max_transform_hierarchy_depth_inter;
136 context->desc.h265.pps->sps->max_transform_hierarchy_depth_intra =
137 hevc->max_transform_hierarchy_depth_intra;
138 context->desc.h265.pps->sps->scaling_list_enabled_flag =
139 hevc->pic_fields.bits.scaling_list_enabled_flag;
140 context->desc.h265.pps->sps->amp_enabled_flag = hevc->pic_fields.bits.amp_enabled_flag;
141 context->desc.h265.pps->sps->sample_adaptive_offset_enabled_flag =
142 hevc->slice_parsing_fields.bits.sample_adaptive_offset_enabled_flag;
143 context->desc.h265.pps->sps->pcm_enabled_flag = hevc->pic_fields.bits.pcm_enabled_flag;
144 if (hevc->pic_fields.bits.pcm_enabled_flag == 1) {
145 context->desc.h265.pps->sps->pcm_sample_bit_depth_luma_minus1 =
146 hevc->pcm_sample_bit_depth_luma_minus1;
147 context->desc.h265.pps->sps->pcm_sample_bit_depth_chroma_minus1 =
148 hevc->pcm_sample_bit_depth_chroma_minus1;
149 context->desc.h265.pps->sps->log2_min_pcm_luma_coding_block_size_minus3 =
150 hevc->log2_min_pcm_luma_coding_block_size_minus3;
151 context->desc.h265.pps->sps->log2_diff_max_min_pcm_luma_coding_block_size =
152 hevc->log2_diff_max_min_pcm_luma_coding_block_size;
153 context->desc.h265.pps->sps->pcm_loop_filter_disabled_flag =
154 hevc->pic_fields.bits.pcm_loop_filter_disabled_flag;
155 }
156 context->desc.h265.pps->sps->num_short_term_ref_pic_sets = hevc->num_short_term_ref_pic_sets;
157 context->desc.h265.pps->sps->long_term_ref_pics_present_flag =
158 hevc->slice_parsing_fields.bits.long_term_ref_pics_present_flag;
159 context->desc.h265.pps->sps->num_long_term_ref_pics_sps = hevc->num_long_term_ref_pic_sps;
160 context->desc.h265.pps->sps->sps_temporal_mvp_enabled_flag =
161 hevc->slice_parsing_fields.bits.sps_temporal_mvp_enabled_flag;
162 context->desc.h265.pps->sps->strong_intra_smoothing_enabled_flag =
163 hevc->pic_fields.bits.strong_intra_smoothing_enabled_flag;
164
165 context->desc.h265.pps->dependent_slice_segments_enabled_flag =
166 hevc->slice_parsing_fields.bits.dependent_slice_segments_enabled_flag;
167 context->desc.h265.pps->output_flag_present_flag =
168 hevc->slice_parsing_fields.bits.output_flag_present_flag;
169 context->desc.h265.pps->num_extra_slice_header_bits = hevc->num_extra_slice_header_bits;
170 context->desc.h265.pps->sign_data_hiding_enabled_flag =
171 hevc->pic_fields.bits.sign_data_hiding_enabled_flag;
172 context->desc.h265.pps->cabac_init_present_flag =
173 hevc->slice_parsing_fields.bits.cabac_init_present_flag;
174 context->desc.h265.pps->num_ref_idx_l0_default_active_minus1 =
175 hevc->num_ref_idx_l0_default_active_minus1;
176 context->desc.h265.pps->num_ref_idx_l1_default_active_minus1 =
177 hevc->num_ref_idx_l1_default_active_minus1;
178 context->desc.h265.pps->init_qp_minus26 = hevc->init_qp_minus26;
179 context->desc.h265.pps->constrained_intra_pred_flag =
180 hevc->pic_fields.bits.constrained_intra_pred_flag;
181 context->desc.h265.pps->transform_skip_enabled_flag =
182 hevc->pic_fields.bits.transform_skip_enabled_flag;
183 context->desc.h265.pps->cu_qp_delta_enabled_flag =
184 hevc->pic_fields.bits.cu_qp_delta_enabled_flag;
185 context->desc.h265.pps->diff_cu_qp_delta_depth = hevc->diff_cu_qp_delta_depth;
186 context->desc.h265.pps->pps_cb_qp_offset = hevc->pps_cb_qp_offset;
187 context->desc.h265.pps->pps_cr_qp_offset = hevc->pps_cr_qp_offset;
188 context->desc.h265.pps->pps_slice_chroma_qp_offsets_present_flag =
189 hevc->slice_parsing_fields.bits.pps_slice_chroma_qp_offsets_present_flag;
190 context->desc.h265.pps->weighted_pred_flag = hevc->pic_fields.bits.weighted_pred_flag;
191 context->desc.h265.pps->weighted_bipred_flag = hevc->pic_fields.bits.weighted_bipred_flag;
192 context->desc.h265.pps->transquant_bypass_enabled_flag =
193 hevc->pic_fields.bits.transquant_bypass_enabled_flag;
194 context->desc.h265.pps->tiles_enabled_flag = hevc->pic_fields.bits.tiles_enabled_flag;
195 context->desc.h265.pps->entropy_coding_sync_enabled_flag =
196 hevc->pic_fields.bits.entropy_coding_sync_enabled_flag;
197 if (hevc->pic_fields.bits.tiles_enabled_flag == 1) {
198 context->desc.h265.pps->num_tile_columns_minus1 = hevc->num_tile_columns_minus1;
199 context->desc.h265.pps->num_tile_rows_minus1 = hevc->num_tile_rows_minus1;
200 for (i = 0 ; i < 19 ; i++)
201 context->desc.h265.pps->column_width_minus1[i] = hevc->column_width_minus1[i];
202 for (i = 0 ; i < 21 ; i++)
203 context->desc.h265.pps->row_height_minus1[i] = hevc->row_height_minus1[i];
204 context->desc.h265.pps->loop_filter_across_tiles_enabled_flag =
205 hevc->pic_fields.bits.loop_filter_across_tiles_enabled_flag;
206 }
207 context->desc.h265.pps->pps_loop_filter_across_slices_enabled_flag =
208 hevc->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag;
209 context->desc.h265.pps->deblocking_filter_override_enabled_flag =
210 hevc->slice_parsing_fields.bits.deblocking_filter_override_enabled_flag;
211 context->desc.h265.pps->pps_deblocking_filter_disabled_flag =
212 hevc->slice_parsing_fields.bits.pps_disable_deblocking_filter_flag;
213 context->desc.h265.pps->pps_beta_offset_div2 = hevc->pps_beta_offset_div2;
214 context->desc.h265.pps->pps_tc_offset_div2 = hevc->pps_tc_offset_div2;
215 context->desc.h265.pps->lists_modification_present_flag =
216 hevc->slice_parsing_fields.bits.lists_modification_present_flag;
217 context->desc.h265.pps->log2_parallel_merge_level_minus2 =
218 hevc->log2_parallel_merge_level_minus2;
219 context->desc.h265.pps->slice_segment_header_extension_present_flag =
220 hevc->slice_parsing_fields.bits.slice_segment_header_extension_present_flag;
221
222 context->desc.h265.IDRPicFlag = hevc->slice_parsing_fields.bits.IdrPicFlag;
223 context->desc.h265.RAPPicFlag = hevc->slice_parsing_fields.bits.RapPicFlag;
224
225 context->desc.h265.CurrPicOrderCntVal = hevc->CurrPic.pic_order_cnt;
226
227 for (i = 0 ; i < 8 ; i++) {
228 context->desc.h265.RefPicSetStCurrBefore[i] = 0xFF;
229 context->desc.h265.RefPicSetStCurrAfter[i] = 0xFF;
230 context->desc.h265.RefPicSetLtCurr[i] = 0xFF;
231 }
232 context->desc.h265.NumPocStCurrBefore = 0;
233 context->desc.h265.NumPocStCurrAfter = 0;
234 context->desc.h265.NumPocLtCurr = 0;
235 unsigned int iBefore = 0;
236 unsigned int iAfter = 0;
237 unsigned int iCurr = 0;
238 for (i = 0 ; i < 15 ; i++) {
239 context->desc.h265.PicOrderCntVal[i] = hevc->ReferenceFrames[i].pic_order_cnt;
240
241 unsigned int index = hevc->ReferenceFrames[i].picture_id & 0x7F;
242
243 if (index == 0x7F)
244 continue;
245
246 vlVaGetReferenceFrame(drv, hevc->ReferenceFrames[i].picture_id, &context->desc.h265.ref[i]);
247
248 if ((hevc->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE) && (iBefore < 8)) {
249 context->desc.h265.RefPicSetStCurrBefore[iBefore++] = i;
250 context->desc.h265.NumPocStCurrBefore++;
251 }
252 if ((hevc->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_ST_CURR_AFTER) && (iAfter < 8)) {
253 context->desc.h265.RefPicSetStCurrAfter[iAfter++] = i;
254 context->desc.h265.NumPocStCurrAfter++;
255 }
256 if ((hevc->ReferenceFrames[i].flags & VA_PICTURE_HEVC_RPS_LT_CURR) && (iCurr < 8)) {
257 context->desc.h265.RefPicSetLtCurr[iCurr++] = i;
258 context->desc.h265.NumPocLtCurr++;
259 }
260 }
261 break;
262
263 default:
264 break;
265 }
266 }
267
268 static void
269 handleIQMatrixBuffer(vlVaContext *context, vlVaBuffer *buf)
270 {
271 VAIQMatrixBufferHEVC *h265;
272
273 switch (u_reduce_video_profile(context->decoder->profile)) {
274 case PIPE_VIDEO_FORMAT_MPEG12:
275 vlVaHandleIQMatrixBufferMPEG12(context, buf);
276 break;
277
278 case PIPE_VIDEO_FORMAT_MPEG4_AVC:
279 vlVaHandleIQMatrixBufferH264(context, buf);
280 break;
281
282 case PIPE_VIDEO_FORMAT_MPEG4:
283 vlVaHandleIQMatrixBufferMPEG4(context, buf);
284 break;
285
286 case PIPE_VIDEO_FORMAT_HEVC:
287 assert(buf->size >= sizeof(VAIQMatrixBufferH264) && buf->num_elements == 1);
288 h265 = buf->data;
289 memcpy(&context->desc.h265.pps->sps->ScalingList4x4, h265->ScalingList4x4, 6 * 16);
290 memcpy(&context->desc.h265.pps->sps->ScalingList8x8, h265->ScalingList8x8, 6 * 64);
291 memcpy(&context->desc.h265.pps->sps->ScalingList16x16, h265->ScalingList16x16, 6 * 64);
292 memcpy(&context->desc.h265.pps->sps->ScalingList32x32, h265->ScalingList32x32, 2 * 64);
293 memcpy(&context->desc.h265.pps->sps->ScalingListDCCoeff16x16, h265->ScalingListDC16x16, 6);
294 memcpy(&context->desc.h265.pps->sps->ScalingListDCCoeff32x32, h265->ScalingListDC32x32, 2);
295 break;
296
297 default:
298 break;
299 }
300 }
301
302 static void
303 handleSliceParameterBuffer(vlVaContext *context, vlVaBuffer *buf)
304 {
305 VASliceParameterBufferHEVC *h265;
306
307 switch (u_reduce_video_profile(context->decoder->profile)) {
308 case PIPE_VIDEO_FORMAT_MPEG4_AVC:
309 vlVaHandleSliceParameterBufferH264(context, buf);
310 break;
311
312 case PIPE_VIDEO_FORMAT_MPEG4:
313 vlVaHandleSliceParameterBufferMPEG4(context, buf);
314 break;
315
316 case PIPE_VIDEO_FORMAT_HEVC:
317 assert(buf->size >= sizeof(VASliceParameterBufferHEVC) && buf->num_elements == 1);
318 h265 = buf->data;
319 for (int i = 0 ; i < 2 ; i++) {
320 for (int j = 0 ; j < 15 ; j++)
321 context->desc.h265.RefPicList[i][j] = h265->RefPicList[i][j];
322 }
323 context->desc.h265.UseRefPicList = true;
324 break;
325 default:
326 break;
327 }
328 }
329
330 static unsigned int
331 bufHasStartcode(vlVaBuffer *buf, unsigned int code, unsigned int bits)
332 {
333 struct vl_vlc vlc = {0};
334 int i;
335
336 /* search the first 64 bytes for a startcode */
337 vl_vlc_init(&vlc, 1, (const void * const*)&buf->data, &buf->size);
338 for (i = 0; i < 64 && vl_vlc_bits_left(&vlc) >= bits; ++i) {
339 if (vl_vlc_peekbits(&vlc, bits) == code)
340 return 1;
341 vl_vlc_eatbits(&vlc, 8);
342 vl_vlc_fillbits(&vlc);
343 }
344
345 return 0;
346 }
347
348 static void
349 handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf)
350 {
351 enum pipe_video_format format;
352 unsigned num_buffers = 0;
353 void * const *buffers[2];
354 unsigned sizes[2];
355 static const uint8_t start_code_h264[] = { 0x00, 0x00, 0x01 };
356 static const uint8_t start_code_h265[] = { 0x00, 0x00, 0x01 };
357 static const uint8_t start_code_vc1[] = { 0x00, 0x00, 0x01, 0x0d };
358
359 format = u_reduce_video_profile(context->decoder->profile);
360 switch (format) {
361 case PIPE_VIDEO_FORMAT_MPEG4_AVC:
362 if (bufHasStartcode(buf, 0x000001, 24))
363 break;
364
365 buffers[num_buffers] = (void *const)&start_code_h264;
366 sizes[num_buffers++] = sizeof(start_code_h264);
367 break;
368 case PIPE_VIDEO_FORMAT_HEVC:
369 if (bufHasStartcode(buf, 0x000001, 24))
370 break;
371
372 buffers[num_buffers] = (void *const)&start_code_h265;
373 sizes[num_buffers++] = sizeof(start_code_h265);
374 break;
375 case PIPE_VIDEO_FORMAT_VC1:
376 if (bufHasStartcode(buf, 0x0000010d, 32) ||
377 bufHasStartcode(buf, 0x0000010c, 32) ||
378 bufHasStartcode(buf, 0x0000010b, 32))
379 break;
380
381 if (context->decoder->profile == PIPE_VIDEO_PROFILE_VC1_ADVANCED) {
382 buffers[num_buffers] = (void *const)&start_code_vc1;
383 sizes[num_buffers++] = sizeof(start_code_vc1);
384 }
385 break;
386 case PIPE_VIDEO_FORMAT_MPEG4:
387 if (bufHasStartcode(buf, 0x000001, 24))
388 break;
389
390 vlVaDecoderFixMPEG4Startcode(context);
391 buffers[num_buffers] = (void *)context->mpeg4.start_code;
392 sizes[num_buffers++] = context->mpeg4.start_code_size;
393 default:
394 break;
395 }
396
397 buffers[num_buffers] = buf->data;
398 sizes[num_buffers] = buf->size;
399 ++num_buffers;
400 context->decoder->decode_bitstream(context->decoder, context->target, &context->desc.base,
401 num_buffers, (const void * const*)buffers, sizes);
402 }
403
404 VAStatus
405 vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buffers, int num_buffers)
406 {
407 vlVaDriver *drv;
408 vlVaContext *context;
409 VAStatus vaStatus = VA_STATUS_SUCCESS;
410
411 unsigned i;
412
413 if (!ctx)
414 return VA_STATUS_ERROR_INVALID_CONTEXT;
415
416 drv = VL_VA_DRIVER(ctx);
417 if (!drv)
418 return VA_STATUS_ERROR_INVALID_CONTEXT;
419
420 context = handle_table_get(drv->htab, context_id);
421 if (!context)
422 return VA_STATUS_ERROR_INVALID_CONTEXT;
423
424 for (i = 0; i < num_buffers; ++i) {
425 vlVaBuffer *buf = handle_table_get(drv->htab, buffers[i]);
426 if (!buf)
427 return VA_STATUS_ERROR_INVALID_BUFFER;
428
429 switch (buf->type) {
430 case VAPictureParameterBufferType:
431 handlePictureParameterBuffer(drv, context, buf);
432 break;
433
434 case VAIQMatrixBufferType:
435 handleIQMatrixBuffer(context, buf);
436 break;
437
438 case VASliceParameterBufferType:
439 handleSliceParameterBuffer(context, buf);
440 break;
441
442 case VASliceDataBufferType:
443 handleVASliceDataBufferType(context, buf);
444 break;
445 case VAProcPipelineParameterBufferType:
446 vaStatus = vlVaHandleVAProcPipelineParameterBufferType(drv, context, buf);
447 break;
448
449 default:
450 break;
451 }
452 }
453
454 return vaStatus;
455 }
456
457 VAStatus
458 vlVaEndPicture(VADriverContextP ctx, VAContextID context_id)
459 {
460 vlVaDriver *drv;
461 vlVaContext *context;
462
463 if (!ctx)
464 return VA_STATUS_ERROR_INVALID_CONTEXT;
465
466 drv = VL_VA_DRIVER(ctx);
467 if (!drv)
468 return VA_STATUS_ERROR_INVALID_CONTEXT;
469
470 context = handle_table_get(drv->htab, context_id);
471 if (!context)
472 return VA_STATUS_ERROR_INVALID_CONTEXT;
473
474 if (!context->decoder) {
475 /* VPP */
476 return VA_STATUS_SUCCESS;
477 }
478
479 context->mpeg4.frame_num++;
480 context->decoder->end_frame(context->decoder, context->target, &context->desc.base);
481
482 return VA_STATUS_SUCCESS;
483 }