1 /**************************************************************************
2 *
3 * Copyright (C) 2022 Kylin Software Co., Ltd.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 **************************************************************************/
24
25 /**
26 * @file
27 * Implementation of general video codec interface.
28 *
29 * This implementation is currently based on VA-API, and other interfaces,
30 * such as VDPAU and proprietary interfaces, can also be considered in the
31 * future.
32 *
33 * Two objects are implemented here:
34 * virgl_video_buffer:
35 * Buffer for storing raw YUV formatted data. Currently, it is a wrapper
36 * for VASurface.
37 * virgl_video_codec:
38 * Represents a video encoder or decoder. It's a wrapper of VAContext and
39 * mainly provides the following methods:
40 * - virgl_video_begin_frame()
41 * It calls vaBeginPicture() to prepare for encoding and decoding. For
42 * encoding, it also needs to upload the raw picture data from the guest
43 * side into the local VASurface.
44 * - virgl_video_decode_bitstream()
45 * It constructs the decoding-related VABuffers according to the picture
46 * description information, and then calls vaRenderPicture() for decoding.
47 * - virgl_video_encode_bitstream()
48 * It constructs the encoding-related VABuffers according to the picture
49 * description information, and then calls vaRenderPicture() for encoding.
50 * - virgl_video_end_frame()
51 * It calls vaEndPicture() to end encoding and decoding. After decoding,
52 * it transmits the raw picture data from VASurface to the guest side,
53 * and after encoding, it transmits the result and the coded data in
54 * VACodedBuffer to the guest side.
55 *
56 * @author Feng Jiang <[email protected]>
57 */
58
59
60 #include <stdio.h>
61 #include <stdint.h>
62 #include <stdbool.h>
63 #include <stdlib.h>
64 #include <string.h>
65 #include <unistd.h>
66 #include <epoxy/gl.h>
67 #include <epoxy/egl.h>
68 #include <va/va.h>
69 #include <va/va_drm.h>
70 #include <va/va_drmcommon.h>
71 #include <drm_fourcc.h>
72
73 #include "pipe/p_video_state.h"
74 #include "util/u_memory.h"
75 #include "virgl_hw.h"
76 #include "virgl_video_hw.h"
77 #include "virgl_util.h"
78 #include "virgl_video.h"
79
80 /*
81 * The max size of codec buffer is approximately:
82 * num_of_macroblocks * max_size_of_per_macroblock + size_of_some_headers
83 * Now, we only support YUV420 formats, this means that we have a limit of
84 * 3200 bits(400 Bytes) per macroblock. To simplify the calculation, we
85 * directly use 512 instead of 400.
86 */
87 #define CODED_BUF_DEFAULT_SIZE(width, height) \
88 ((width) * (height) / (16 * 16) * 512)
89
90 struct virgl_video_buffer {
91 enum pipe_format format;
92 uint32_t width;
93 uint32_t height;
94 bool interlanced;
95 VASurfaceID va_sfc;
96 struct virgl_video_dma_buf *dmabuf;
97 void *opaque; /* User opaque data */
98 };
99
100
101 struct virgl_video_codec {
102 enum pipe_video_profile profile;
103 uint32_t level;
104 enum pipe_video_entrypoint entrypoint;
105 enum pipe_video_chroma_format chroma_format;
106 uint32_t width;
107 uint32_t height;
108 uint32_t max_references;
109 VAContextID va_ctx;
110 VAConfigID va_cfg;
111 struct virgl_video_buffer *buffer;
112 struct virgl_video_buffer *ref_pic_list[32]; /* Enc: reference pictures */
113 VABufferID va_coded_buf; /* Enc: VACodedBuffer */
114 void *opaque; /* User opaque data */
115 };
116
117
118 static VADisplay va_dpy;
119
120 static struct virgl_video_callbacks *callbacks = NULL;
121
pipe_profile_from_va(VAProfile profile)122 static enum pipe_video_profile pipe_profile_from_va(VAProfile profile)
123 {
124 switch (profile) {
125 case VAProfileMPEG2Simple:
126 return PIPE_VIDEO_PROFILE_MPEG2_SIMPLE;
127 case VAProfileMPEG2Main:
128 return PIPE_VIDEO_PROFILE_MPEG2_MAIN;
129 case VAProfileMPEG4Simple:
130 return PIPE_VIDEO_PROFILE_MPEG4_SIMPLE;
131 case VAProfileMPEG4AdvancedSimple:
132 return PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE;
133 case VAProfileVC1Simple:
134 return PIPE_VIDEO_PROFILE_VC1_SIMPLE;
135 case VAProfileVC1Main:
136 return PIPE_VIDEO_PROFILE_VC1_MAIN;
137 case VAProfileVC1Advanced:
138 return PIPE_VIDEO_PROFILE_VC1_ADVANCED;
139 case VAProfileH264ConstrainedBaseline:
140 return PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE;
141 case VAProfileH264Main:
142 return PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN;
143 case VAProfileH264High:
144 return PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH;
145 case VAProfileHEVCMain:
146 return PIPE_VIDEO_PROFILE_HEVC_MAIN;
147 case VAProfileHEVCMain10:
148 return PIPE_VIDEO_PROFILE_HEVC_MAIN_10;
149 case VAProfileJPEGBaseline:
150 return PIPE_VIDEO_PROFILE_JPEG_BASELINE;
151 case VAProfileVP9Profile0:
152 return PIPE_VIDEO_PROFILE_VP9_PROFILE0;
153 case VAProfileVP9Profile2:
154 return PIPE_VIDEO_PROFILE_VP9_PROFILE2;
155 case VAProfileAV1Profile0:
156 return PIPE_VIDEO_PROFILE_AV1_MAIN;
157 case VAProfileNone:
158 return PIPE_VIDEO_PROFILE_UNKNOWN;
159 default:
160 return PIPE_VIDEO_PROFILE_UNKNOWN;
161 }
162 }
163
164 /* NOTE: mesa va frontend only supports VLD and EncSlice */
pipe_entrypoint_from_va(VAEntrypoint entrypoint)165 static enum pipe_video_entrypoint pipe_entrypoint_from_va(
166 VAEntrypoint entrypoint)
167 {
168 switch (entrypoint) {
169 case VAEntrypointVLD:
170 return PIPE_VIDEO_ENTRYPOINT_BITSTREAM;
171 case VAEntrypointIDCT:
172 return PIPE_VIDEO_ENTRYPOINT_IDCT;
173 case VAEntrypointMoComp:
174 return PIPE_VIDEO_ENTRYPOINT_MC;
175 case VAEntrypointEncSlice: /* fall through */
176 case VAEntrypointEncSliceLP:
177 return PIPE_VIDEO_ENTRYPOINT_ENCODE;
178 default:
179 return PIPE_VIDEO_ENTRYPOINT_UNKNOWN;
180 }
181 }
182
pipe_format_from_va_fourcc(unsigned format)183 static enum pipe_format pipe_format_from_va_fourcc(unsigned format)
184 {
185 switch(format) {
186 case VA_FOURCC('N','V','1','2'):
187 return PIPE_FORMAT_NV12;
188 /* TODO: These are already defined in mesa, but not yet in virglrenderer
189 case VA_FOURCC('P','0','1','0'):
190 return PIPE_FORMAT_P010;
191 case VA_FOURCC('P','0','1','6'):
192 return PIPE_FORMAT_P016;
193 */
194 case VA_FOURCC('I','4','2','0'):
195 return PIPE_FORMAT_IYUV;
196 case VA_FOURCC('Y','V','1','2'):
197 return PIPE_FORMAT_YV12;
198 case VA_FOURCC('Y','U','Y','V'):
199 case VA_FOURCC('Y','U','Y','2'):
200 return PIPE_FORMAT_YUYV;
201 case VA_FOURCC('U','Y','V','Y'):
202 return PIPE_FORMAT_UYVY;
203 case VA_FOURCC('B','G','R','A'):
204 return PIPE_FORMAT_B8G8R8A8_UNORM;
205 case VA_FOURCC('R','G','B','A'):
206 return PIPE_FORMAT_R8G8B8A8_UNORM;
207 case VA_FOURCC('B','G','R','X'):
208 return PIPE_FORMAT_B8G8R8X8_UNORM;
209 case VA_FOURCC('R','G','B','X'):
210 return PIPE_FORMAT_R8G8B8X8_UNORM;
211 default:
212 return PIPE_FORMAT_NONE;
213 }
214 }
215
216
va_profile_from_pipe(enum pipe_video_profile profile)217 static VAProfile va_profile_from_pipe(enum pipe_video_profile profile)
218 {
219 switch (profile) {
220 case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
221 return VAProfileMPEG2Simple;
222 case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
223 return VAProfileMPEG2Main;
224 case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE:
225 return VAProfileMPEG4Simple;
226 case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE:
227 return VAProfileMPEG4AdvancedSimple;
228 case PIPE_VIDEO_PROFILE_VC1_SIMPLE:
229 return VAProfileVC1Simple;
230 case PIPE_VIDEO_PROFILE_VC1_MAIN:
231 return VAProfileVC1Main;
232 case PIPE_VIDEO_PROFILE_VC1_ADVANCED:
233 return VAProfileVC1Advanced;
234 case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
235 return VAProfileH264ConstrainedBaseline;
236 case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
237 return VAProfileH264Main;
238 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
239 return VAProfileH264High;
240 case PIPE_VIDEO_PROFILE_HEVC_MAIN:
241 return VAProfileHEVCMain;
242 case PIPE_VIDEO_PROFILE_HEVC_MAIN_10:
243 return VAProfileHEVCMain10;
244 case PIPE_VIDEO_PROFILE_JPEG_BASELINE:
245 return VAProfileJPEGBaseline;
246 case PIPE_VIDEO_PROFILE_VP9_PROFILE0:
247 return VAProfileVP9Profile0;
248 case PIPE_VIDEO_PROFILE_VP9_PROFILE2:
249 return VAProfileVP9Profile2;
250 case PIPE_VIDEO_PROFILE_AV1_MAIN:
251 return VAProfileAV1Profile0;
252 case PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED:
253 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10:
254 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH422:
255 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH444:
256 case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE:
257 case PIPE_VIDEO_PROFILE_HEVC_MAIN_12:
258 case PIPE_VIDEO_PROFILE_HEVC_MAIN_STILL:
259 case PIPE_VIDEO_PROFILE_HEVC_MAIN_444:
260 case PIPE_VIDEO_PROFILE_UNKNOWN:
261 return VAProfileNone;
262 default:
263 return -1;
264 }
265 }
266
267 /*
268 * There is no invalid entrypoint defined in libva,
269 * so add this definition to make the code clear
270 */
271 #define VAEntrypointNone 0
va_entrypoint_from_pipe(enum pipe_video_entrypoint entrypoint)272 static int va_entrypoint_from_pipe(enum pipe_video_entrypoint entrypoint)
273 {
274 switch (entrypoint) {
275 case PIPE_VIDEO_ENTRYPOINT_BITSTREAM:
276 return VAEntrypointVLD;
277 case PIPE_VIDEO_ENTRYPOINT_IDCT:
278 return VAEntrypointIDCT;
279 case PIPE_VIDEO_ENTRYPOINT_MC:
280 return VAEntrypointMoComp;
281 case PIPE_VIDEO_ENTRYPOINT_ENCODE:
282 return VAEntrypointEncSlice;
283 default:
284 return VAEntrypointNone;
285 }
286 }
287
va_format_from_pipe_chroma(enum pipe_video_chroma_format chroma_format)288 static uint32_t va_format_from_pipe_chroma(
289 enum pipe_video_chroma_format chroma_format)
290 {
291 switch (chroma_format) {
292 case PIPE_VIDEO_CHROMA_FORMAT_400:
293 return VA_RT_FORMAT_YUV400;
294 case PIPE_VIDEO_CHROMA_FORMAT_420:
295 return VA_RT_FORMAT_YUV420;
296 case PIPE_VIDEO_CHROMA_FORMAT_422:
297 return VA_RT_FORMAT_YUV422;
298 case PIPE_VIDEO_CHROMA_FORMAT_444:
299 return VA_RT_FORMAT_YUV444;
300 case PIPE_VIDEO_CHROMA_FORMAT_NONE:
301 default:
302 return 0;
303 }
304 }
305
drm_format_from_va_fourcc(uint32_t va_fourcc)306 static uint32_t drm_format_from_va_fourcc(uint32_t va_fourcc)
307 {
308 switch (va_fourcc) {
309 case VA_FOURCC_NV12:
310 return DRM_FORMAT_NV12;
311 case VA_FOURCC_NV21:
312 return DRM_FORMAT_NV21;
313 default:
314 return DRM_FORMAT_INVALID;
315 }
316 }
317
fill_video_dma_buf(struct virgl_video_dma_buf * dmabuf,const VADRMPRIMESurfaceDescriptor * desc)318 static void fill_video_dma_buf(struct virgl_video_dma_buf *dmabuf,
319 const VADRMPRIMESurfaceDescriptor *desc)
320 {
321 unsigned i, j, obj_idx;
322 struct virgl_video_dma_buf_plane *plane;
323
324 /*
325 virgl_log("surface: fourcc=0x%08x, size=%ux%u, num_objects=%u,
326 num_layers=%u\n", desc->fourcc, desc->width, desc->height,
327 desc->num_objects, desc->num_layers);
328
329 for (i = 0; i < desc->num_objects; i++)
330 virgl_log(" objects[%u]: fd=%d, size=%u, modifier=0x%lx\n",
331 i, desc->objects[i].fd, desc->objects[i].size,
332 desc->objects[i].drm_format_modifier);
333
334 for (i = 0; i < desc->num_layers; i++)
335 virgl_log(" layers[%u] : format=0x%08x, num_planes=%u, "
336 "obj=%u,%u,%u,%u, offset=%u,%u,%u,%u, pitch=%u,%u,%u,%u\n",
337 i, desc->layers[i].drm_format, desc->layers[i].num_planes,
338 desc->layers[i].object_index[0],
339 desc->layers[i].object_index[1],
340 desc->layers[i].object_index[2],
341 desc->layers[i].object_index[3],
342 desc->layers[i].offset[0],
343 desc->layers[i].offset[1],
344 desc->layers[i].offset[2],
345 desc->layers[i].offset[3],
346 desc->layers[i].pitch[0],
347 desc->layers[i].pitch[1],
348 desc->layers[i].pitch[2],
349 desc->layers[i].pitch[3]);
350 */
351
352 dmabuf->drm_format = drm_format_from_va_fourcc(desc->fourcc);
353 dmabuf->width = desc->width;
354 dmabuf->height = desc->height;
355
356 for (i = 0, dmabuf->num_planes = 0; i < desc->num_layers; i++) {
357 for (j = 0; j < desc->layers[i].num_planes &&
358 dmabuf->num_planes < ARRAY_SIZE(dmabuf->planes); j++) {
359
360 obj_idx = desc->layers[i].object_index[j];
361 plane = &dmabuf->planes[dmabuf->num_planes++];
362 plane->drm_format = desc->layers[i].drm_format;
363 plane->offset = desc->layers[i].offset[j];
364 plane->pitch = desc->layers[i].pitch[j];
365 plane->fd = desc->objects[obj_idx].fd;
366 plane->size = desc->objects[obj_idx].size;
367 plane->modifier = desc->objects[obj_idx].drm_format_modifier;
368 }
369 }
370 }
371
export_video_dma_buf(struct virgl_video_buffer * buffer,unsigned flags)372 static struct virgl_video_dma_buf *export_video_dma_buf(
373 struct virgl_video_buffer *buffer,
374 unsigned flags)
375 {
376 struct virgl_video_dma_buf *dmabuf;
377 uint32_t exp_flags;
378 VAStatus va_stat;
379 VADRMPRIMESurfaceDescriptor desc;
380
381 exp_flags = VA_EXPORT_SURFACE_SEPARATE_LAYERS;
382
383 if (flags & VIRGL_VIDEO_DMABUF_READ_ONLY)
384 exp_flags |= VA_EXPORT_SURFACE_READ_ONLY;
385
386 if (flags & VIRGL_VIDEO_DMABUF_WRITE_ONLY)
387 exp_flags |= VA_EXPORT_SURFACE_WRITE_ONLY;
388
389 dmabuf = calloc(1, sizeof(*dmabuf));
390 if (!dmabuf)
391 return NULL;
392
393 va_stat = vaExportSurfaceHandle(va_dpy, buffer->va_sfc,
394 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, exp_flags, &desc);
395 if (VA_STATUS_SUCCESS != va_stat) {
396 virgl_log("export surface failed, err = 0x%X\n", va_stat);
397 goto free_dmabuf;
398 }
399
400 fill_video_dma_buf(dmabuf, &desc);
401 dmabuf->flags = flags;
402 dmabuf->buf = buffer;
403
404 return dmabuf;
405
406 free_dmabuf:
407 free(dmabuf);
408 return NULL;
409 }
410
destroy_video_dma_buf(struct virgl_video_dma_buf * dmabuf)411 static void destroy_video_dma_buf(struct virgl_video_dma_buf *dmabuf)
412 {
413 unsigned i;
414
415 if (dmabuf) {
416 for (i = 0; i < dmabuf->num_planes; i++)
417 close(dmabuf->planes[i].fd);
418
419 free(dmabuf);
420 }
421 }
422
encode_upload_picture(struct virgl_video_codec * codec,struct virgl_video_buffer * buffer)423 static void encode_upload_picture(struct virgl_video_codec *codec,
424 struct virgl_video_buffer *buffer)
425 {
426 VAStatus va_stat;
427
428 if (!callbacks || !callbacks->encode_upload_picture)
429 return;
430
431 va_stat = vaSyncSurface(va_dpy, buffer->va_sfc);
432 if (VA_STATUS_SUCCESS != va_stat) {
433 virgl_log("sync surface failed, err = 0x%x\n", va_stat);
434 return;
435 }
436
437 if (!buffer->dmabuf)
438 buffer->dmabuf = export_video_dma_buf(buffer, VIRGL_VIDEO_DMABUF_WRITE_ONLY);
439
440 if (buffer->dmabuf)
441 callbacks->encode_upload_picture(codec, buffer->dmabuf);
442 }
443
encode_completed(struct virgl_video_codec * codec,struct virgl_video_buffer * buffer)444 static void encode_completed(struct virgl_video_codec *codec,
445 struct virgl_video_buffer *buffer)
446 {
447 VAStatus va_stat;
448 VACodedBufferSegment *buf, *buf_list;
449 void **coded_bufs = NULL;
450 unsigned *coded_sizes = NULL;
451 unsigned i, num_coded_bufs = 0;
452
453 if (!callbacks || !callbacks->encode_completed)
454 return;
455
456 va_stat = vaMapBuffer(va_dpy, codec->va_coded_buf, (void **)(&buf_list));
457 if (VA_STATUS_SUCCESS != va_stat) {
458 virgl_log("map coded buffer failed, err = 0x%x\n", va_stat);
459 return;
460 }
461
462 for (buf = buf_list; buf; buf = (VACodedBufferSegment *)buf->next)
463 num_coded_bufs++;
464
465 coded_bufs = calloc(num_coded_bufs, sizeof(void *));
466 coded_sizes = calloc(num_coded_bufs, sizeof(unsigned));
467 if (!coded_bufs || !coded_sizes) {
468 virgl_log("alloc memory failed, num_coded_bufs %u\n", num_coded_bufs);
469 goto fail_unmap_buffer;
470 }
471
472 for (buf = buf_list, i = 0; buf; buf = (VACodedBufferSegment *)buf->next) {
473 coded_bufs[i] = buf->buf;
474 coded_sizes[i++] = buf->size;
475 }
476
477 callbacks->encode_completed(codec, buffer->dmabuf, NULL, num_coded_bufs,
478 (const void * const*)coded_bufs, coded_sizes);
479
480 fail_unmap_buffer:
481 vaUnmapBuffer(va_dpy, codec->va_coded_buf);
482 free(coded_bufs);
483 free(coded_sizes);
484 }
485
decode_completed(struct virgl_video_codec * codec,struct virgl_video_buffer * buffer)486 static void decode_completed(struct virgl_video_codec *codec,
487 struct virgl_video_buffer *buffer)
488 {
489 if (!callbacks || !callbacks->decode_completed)
490 return;
491
492 if (!buffer->dmabuf)
493 buffer->dmabuf = export_video_dma_buf(buffer, VIRGL_VIDEO_DMABUF_READ_ONLY);
494
495 if (buffer->dmabuf)
496 callbacks->decode_completed(codec, buffer->dmabuf);
497 }
498
get_enc_ref_pic(struct virgl_video_codec * codec,uint32_t frame_num)499 static VASurfaceID get_enc_ref_pic(struct virgl_video_codec *codec,
500 uint32_t frame_num)
501 {
502 uint32_t idx;
503 struct virgl_video_create_buffer_args args;
504
505 if (frame_num == VA_INVALID_ID)
506 return VA_INVALID_ID;
507
508 idx = frame_num % ARRAY_SIZE(codec->ref_pic_list);
509
510 if (!codec->ref_pic_list[idx]) {
511 args.format = PIPE_FORMAT_NV21;
512 args.width = codec->width;
513 args.height = codec->height;
514 args.interlaced = 0;
515 args.opaque = NULL;
516 codec->ref_pic_list[idx] = virgl_video_create_buffer(&args);
517 if (!codec->ref_pic_list[idx]) {
518 virgl_log("create ref pic for frame_num %u failed\n", frame_num);
519 return VA_INVALID_ID;
520 }
521 }
522
523 return codec->ref_pic_list[idx]->va_sfc;
524 }
525
virgl_video_init(int drm_fd,struct virgl_video_callbacks * cbs,unsigned int flags)526 int virgl_video_init(int drm_fd,
527 struct virgl_video_callbacks *cbs, unsigned int flags)
528 {
529 VAStatus va_stat;
530 int major_ver, minor_ver;
531 const char *driver;
532
533 (void)flags;
534
535 if (drm_fd < 0) {
536 virgl_log("invalid drm fd: %d\n", drm_fd);
537 return -1;
538 }
539
540 va_dpy = vaGetDisplayDRM(drm_fd);
541 if (!va_dpy) {
542 virgl_log("get va display failed\n");
543 return -1;
544 }
545
546 va_stat = vaInitialize(va_dpy, &major_ver, &minor_ver);
547 if (VA_STATUS_SUCCESS != va_stat) {
548 virgl_log("init va library failed\n");
549 virgl_video_destroy();
550 return -1;
551 }
552
553 virgl_log("VA-API version: %d.%d\n", major_ver, minor_ver);
554
555 driver = vaQueryVendorString(va_dpy);
556 virgl_log("Driver version: %s\n", driver ? driver : "<unknown>");
557
558 if (!driver || !strstr(driver, "Mesa Gallium")) {
559 virgl_log("only supports mesa va drivers now\n");
560 virgl_video_destroy();
561 return -1;
562 }
563
564 callbacks = cbs;
565
566 return 0;
567 }
568
virgl_video_destroy(void)569 void virgl_video_destroy(void)
570 {
571 if (va_dpy) {
572 vaTerminate(va_dpy);
573 va_dpy = NULL;
574 }
575
576 callbacks = NULL;
577 }
578
fill_vcaps_entry(VAProfile profile,VAEntrypoint entrypoint,struct virgl_video_caps * vcaps)579 static int fill_vcaps_entry(VAProfile profile, VAEntrypoint entrypoint,
580 struct virgl_video_caps *vcaps)
581 {
582 VAConfigID cfg;
583 VASurfaceAttrib *attrs;
584 unsigned i, num_attrs;
585
586 /* FIXME: default values */
587 vcaps->profile = pipe_profile_from_va(profile);
588 vcaps->entrypoint = pipe_entrypoint_from_va(entrypoint);
589 vcaps->max_level = 0;
590 vcaps->stacked_frames = 0;
591 vcaps->max_width = 0;
592 vcaps->max_height = 0;
593 vcaps->prefered_format = PIPE_FORMAT_NONE;
594 vcaps->max_macroblocks = 1;
595 vcaps->npot_texture = 1;
596 vcaps->supports_progressive = 1;
597 vcaps->supports_interlaced = 0;
598 vcaps->prefers_interlaced = 0;
599 vcaps->max_temporal_layers = 0;
600
601 vaCreateConfig(va_dpy, profile, entrypoint, NULL, 0, &cfg);
602
603 vaQuerySurfaceAttributes(va_dpy, cfg, NULL, &num_attrs);
604 attrs = calloc(num_attrs, sizeof(VASurfaceAttrib));
605 if (!attrs)
606 return -1;
607
608 vaQuerySurfaceAttributes(va_dpy, cfg, attrs, &num_attrs);
609 for (i = 0; i < num_attrs; i++) {
610 switch (attrs[i].type) {
611 case VASurfaceAttribMaxHeight:
612 vcaps->max_height = attrs[i].value.value.i;
613 break;
614 case VASurfaceAttribMaxWidth:
615 vcaps->max_width = attrs[i].value.value.i;
616 break;
617 case VASurfaceAttribPixelFormat:
618 if (PIPE_FORMAT_NONE == vcaps->prefered_format)
619 vcaps->prefered_format = \
620 pipe_format_from_va_fourcc(attrs[i].value.value.i);
621 break;
622 default:
623 break;
624 }
625 }
626
627 free(attrs);
628
629 vaDestroyConfig(va_dpy, cfg);
630
631 return 0;
632 }
633
virgl_video_fill_caps(union virgl_caps * caps)634 int virgl_video_fill_caps(union virgl_caps *caps)
635 {
636 int i, j;
637 int num_profiles, num_entrypoints;
638 VAProfile *profiles = NULL;
639 VAEntrypoint *entrypoints = NULL;
640
641 if (!va_dpy || !caps)
642 return -1;
643
644 num_entrypoints = vaMaxNumEntrypoints(va_dpy);
645 entrypoints = calloc(num_entrypoints, sizeof(VAEntrypoint));
646 if (!entrypoints)
647 return -1;
648
649 num_profiles = vaMaxNumProfiles(va_dpy);
650 profiles = calloc(num_profiles, sizeof(VAProfile));
651 if (!profiles) {
652 free(entrypoints);
653 return -1;
654 }
655
656 vaQueryConfigProfiles(va_dpy, profiles, &num_profiles);
657 for (i = 0, caps->v2.num_video_caps = 0; i < num_profiles; i++) {
658 /* only support H.264 and H.265 now */
659 if (profiles[i] != VAProfileH264Main &&
660 profiles[i] != VAProfileH264High &&
661 profiles[i] != VAProfileH264ConstrainedBaseline &&
662 profiles[i] != VAProfileHEVCMain)
663 continue;
664
665 vaQueryConfigEntrypoints(va_dpy, profiles[i],
666 entrypoints, &num_entrypoints);
667 for (j = 0; j < num_entrypoints &&
668 caps->v2.num_video_caps < ARRAY_SIZE(caps->v2.video_caps); j++) {
669 /* support encoding and decoding */
670 if (VAEntrypointVLD != entrypoints[j] &&
671 VAEntrypointEncSlice != entrypoints[j])
672 continue;
673
674 fill_vcaps_entry(profiles[i], entrypoints[j],
675 &caps->v2.video_caps[caps->v2.num_video_caps++]);
676 }
677 }
678
679 free(profiles);
680 free(entrypoints);
681
682 return 0;
683 }
684
virgl_video_create_codec(const struct virgl_video_create_codec_args * args)685 struct virgl_video_codec *virgl_video_create_codec(
686 const struct virgl_video_create_codec_args *args)
687 {
688 VAStatus va_stat;
689 VAConfigID cfg;
690 VAContextID ctx;
691 VAConfigAttrib attr;
692 VAProfile profile;
693 VAEntrypoint entrypoint;
694 uint32_t format;
695 struct virgl_video_codec *codec;
696
697 if (!va_dpy || !args)
698 return NULL;
699
700 profile = va_profile_from_pipe(args->profile);
701 entrypoint = va_entrypoint_from_pipe(args->entrypoint);
702 format = va_format_from_pipe_chroma(args->chroma_format);
703 if (VAProfileNone == profile || VAEntrypointNone == entrypoint)
704 return NULL;
705
706 codec = (struct virgl_video_codec *)calloc(1, sizeof(*codec));
707 if (!codec)
708 return NULL;
709
710 attr.type = VAConfigAttribRTFormat;
711 vaGetConfigAttributes(va_dpy, profile, entrypoint, &attr, 1);
712 if (!(attr.value & format)) {
713 virgl_log("format 0x%x not supported, supported formats: 0x%x\n",
714 format, attr.value);
715 goto err;
716 }
717
718 va_stat = vaCreateConfig(va_dpy, profile, entrypoint, &attr, 1, &cfg);
719 if (VA_STATUS_SUCCESS != va_stat) {
720 virgl_log("create config failed, err = 0x%x\n", va_stat);
721 goto err;
722 }
723 codec->va_cfg = cfg;
724
725 va_stat = vaCreateContext(va_dpy, cfg, args->width, args->height,
726 VA_PROGRESSIVE, NULL, 0, &ctx);
727 if (VA_STATUS_SUCCESS != va_stat) {
728 virgl_log("create context failed, err = 0x%x\n", va_stat);
729 goto err;
730 }
731 codec->va_ctx = ctx;
732
733 codec->profile = args->profile;
734 codec->level = args->level;
735 codec->entrypoint = args->entrypoint;
736 codec->chroma_format = args->chroma_format;
737 codec->width = args->width;
738 codec->height = args->height;
739 codec->max_references = args->max_references;
740 codec->opaque = args->opaque;
741
742 if (entrypoint == VAEntrypointEncSlice) {
743 vaCreateBuffer(va_dpy, codec->va_ctx, VAEncCodedBufferType,
744 CODED_BUF_DEFAULT_SIZE(codec->width, codec->height),
745 1, NULL, &codec->va_coded_buf);
746 }
747
748 return codec;
749
750 err:
751 virgl_video_destroy_codec(codec);
752
753 return NULL;
754 }
755
virgl_video_destroy_codec(struct virgl_video_codec * codec)756 void virgl_video_destroy_codec(struct virgl_video_codec *codec)
757 {
758 unsigned i;
759
760 if (!va_dpy || !codec)
761 return;
762
763 if (codec->va_ctx)
764 vaDestroyContext(va_dpy, codec->va_ctx);
765
766 if (codec->va_cfg)
767 vaDestroyConfig(va_dpy, codec->va_cfg);
768
769 if (codec->va_coded_buf)
770 vaDestroyBuffer(va_dpy, codec->va_coded_buf);
771
772 for (i = 0; i < ARRAY_SIZE(codec->ref_pic_list); i++) {
773 if (codec->ref_pic_list[i])
774 free(codec->ref_pic_list[i]);
775 }
776
777 free(codec);
778 }
779
virgl_video_create_buffer(const struct virgl_video_create_buffer_args * args)780 struct virgl_video_buffer *virgl_video_create_buffer(
781 const struct virgl_video_create_buffer_args *args)
782 {
783 VAStatus va_stat;
784 VASurfaceID sfc;
785 uint32_t format;
786 struct virgl_video_buffer *buffer;
787
788 if (!va_dpy || !args)
789 return NULL;
790
791 /*
792 * FIXME: always use YUV420 now,
793 * may be use va_format_from_pipe(args->format)
794 */
795 format = VA_RT_FORMAT_YUV420;
796 if (!format) {
797 virgl_log("pipe format %d not supported\n", args->format);
798 return NULL;
799 }
800
801 buffer = (struct virgl_video_buffer *)calloc(1, sizeof(*buffer));
802 if (!buffer)
803 return NULL;
804
805 va_stat = vaCreateSurfaces(va_dpy, format,
806 args->width, args->height, &sfc, 1, NULL, 0);
807 if (VA_STATUS_SUCCESS != va_stat) {
808 free(buffer);
809 return NULL;
810 }
811
812 buffer->va_sfc = sfc;
813 buffer->format = args->format;
814 buffer->width = args->width;
815 buffer->height = args->height;
816 buffer->opaque = args->opaque;
817
818 return buffer;
819 }
820
virgl_video_destroy_buffer(struct virgl_video_buffer * buffer)821 void virgl_video_destroy_buffer(struct virgl_video_buffer *buffer)
822 {
823 if (!va_dpy || !buffer)
824 return;
825
826 if (buffer->dmabuf)
827 destroy_video_dma_buf(buffer->dmabuf);
828
829 if (buffer->va_sfc)
830 vaDestroySurfaces(va_dpy, &buffer->va_sfc, 1);
831
832 free(buffer);
833 }
834
virgl_video_codec_opaque_data(struct virgl_video_codec * codec)835 void *virgl_video_codec_opaque_data(struct virgl_video_codec *codec)
836 {
837 return codec ? codec->opaque : NULL;
838 }
839
virgl_video_codec_profile(const struct virgl_video_codec * codec)840 enum pipe_video_profile virgl_video_codec_profile(
841 const struct virgl_video_codec *codec)
842 {
843 return codec ? codec->profile : PIPE_VIDEO_PROFILE_UNKNOWN;
844 }
845
virgl_video_buffer_id(const struct virgl_video_buffer * buffer)846 uint32_t virgl_video_buffer_id(const struct virgl_video_buffer *buffer)
847 {
848 return (uint32_t)(buffer ? buffer->va_sfc : VA_INVALID_SURFACE);
849 }
850
virgl_video_buffer_opaque_data(struct virgl_video_buffer * buffer)851 void *virgl_video_buffer_opaque_data(struct virgl_video_buffer *buffer)
852 {
853 return buffer ? buffer->opaque : NULL;
854 }
855
virgl_video_begin_frame(struct virgl_video_codec * codec,struct virgl_video_buffer * target)856 int virgl_video_begin_frame(struct virgl_video_codec *codec,
857 struct virgl_video_buffer *target)
858 {
859 VAStatus va_stat;
860
861 if (!va_dpy || !codec || !target)
862 return -1;
863
864 if (codec->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE)
865 encode_upload_picture(codec, target);
866
867 codec->buffer = target;
868 va_stat = vaBeginPicture(va_dpy, codec->va_ctx, target->va_sfc);
869 if (VA_STATUS_SUCCESS != va_stat) {
870 virgl_log("begin picture failed, err = 0x%x\n", va_stat);
871 return -1;
872 }
873
874 return 0;
875 }
876
877
878 #define ITEM_SET(dest, src, member) \
879 (dest)->member = (src)->member
880
881 #define ITEM_CPY(dest, src, member) \
882 memcpy(&(dest)->member, &(src)->member, sizeof((dest)->member))
883
884
h264_init_picture(VAPictureH264 * pic)885 static void h264_init_picture(VAPictureH264 *pic)
886 {
887 pic->picture_id = VA_INVALID_SURFACE;
888 pic->frame_idx = 0;
889 pic->flags = VA_PICTURE_H264_INVALID;
890 pic->TopFieldOrderCnt = 0;
891 pic->BottomFieldOrderCnt = 0;
892 }
893
894 /*
895 * Refer to vlVaHandlePictureParameterBufferH264() in mesa,
896 * and comment out some unused parameters.
897 */
h264_fill_picture_param(struct virgl_video_codec * codec,struct virgl_video_buffer * target,const struct virgl_h264_picture_desc * desc,VAPictureParameterBufferH264 * vapp)898 static void h264_fill_picture_param(struct virgl_video_codec *codec,
899 struct virgl_video_buffer *target,
900 const struct virgl_h264_picture_desc *desc,
901 VAPictureParameterBufferH264 *vapp)
902 {
903 unsigned i;
904 VAPictureH264 *pic;
905
906 (void)codec;
907
908 /* CurrPic */
909 pic = &vapp->CurrPic;
910 pic->picture_id = target->va_sfc;
911 pic->frame_idx = desc->frame_num;
912 pic->flags = desc->is_reference ? VA_PICTURE_H264_SHORT_TERM_REFERENCE : 0;
913 if (desc->field_pic_flag)
914 pic->flags |= (desc->bottom_field_flag ? VA_PICTURE_H264_BOTTOM_FIELD
915 : VA_PICTURE_H264_TOP_FIELD);
916 pic->TopFieldOrderCnt = desc->field_order_cnt[0];
917 pic->BottomFieldOrderCnt = desc->field_order_cnt[1];
918
919
920 /* ReferenceFrames */
921 for (i = 0; i < ARRAY_SIZE(vapp->ReferenceFrames); i++)
922 h264_init_picture(&vapp->ReferenceFrames[i]);
923
924 for (i = 0; i < desc->num_ref_frames; i++) {
925 pic = &vapp->ReferenceFrames[i];
926
927 pic->picture_id = desc->buffer_id[i];
928 pic->frame_idx = desc->frame_num_list[i];
929 pic->flags = (desc->is_long_term[i]
930 ? VA_PICTURE_H264_LONG_TERM_REFERENCE
931 : VA_PICTURE_H264_SHORT_TERM_REFERENCE);
932 if (desc->top_is_reference[i] && desc->bottom_is_reference[i]) {
933 // Full frame. This block intentionally left blank. No flags set.
934 } else {
935 if (desc->top_is_reference[i])
936 pic->flags |= VA_PICTURE_H264_TOP_FIELD;
937 else
938 pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD;
939 }
940 pic->TopFieldOrderCnt = desc->field_order_cnt_list[i][0];
941 pic->BottomFieldOrderCnt = desc->field_order_cnt_list[i][1];
942 }
943
944 //vapp->picture_width_in_mbs_minus1 = (codec->width - 1) / 16;
945 //vapp->picture_height_in_mbs_minus1 = (codec->height - 1) / 16;
946 ITEM_SET(vapp, &desc->pps.sps, bit_depth_luma_minus8);
947 ITEM_SET(vapp, &desc->pps.sps, bit_depth_chroma_minus8);
948 ITEM_SET(vapp, desc, num_ref_frames);
949
950 ITEM_SET(&vapp->seq_fields.bits, &desc->pps.sps, chroma_format_idc);
951 //vapp->seq_fields.bits.residual_colour_transform_flag = 0;
952 //vapp->seq_fields.bits.gaps_in_frame_num_value_allowed_flag = 0;
953 ITEM_SET(&vapp->seq_fields.bits, &desc->pps.sps, frame_mbs_only_flag);
954 ITEM_SET(&vapp->seq_fields.bits,
955 &desc->pps.sps, mb_adaptive_frame_field_flag);
956 ITEM_SET(&vapp->seq_fields.bits, &desc->pps.sps, direct_8x8_inference_flag);
957 ITEM_SET(&vapp->seq_fields.bits, &desc->pps.sps, MinLumaBiPredSize8x8);
958 ITEM_SET(&vapp->seq_fields.bits, &desc->pps.sps, log2_max_frame_num_minus4);
959 ITEM_SET(&vapp->seq_fields.bits, &desc->pps.sps, pic_order_cnt_type);
960 ITEM_SET(&vapp->seq_fields.bits,
961 &desc->pps.sps, log2_max_pic_order_cnt_lsb_minus4);
962 ITEM_SET(&vapp->seq_fields.bits,
963 &desc->pps.sps, delta_pic_order_always_zero_flag);
964
965 //ITEM_SET(vapp, &desc->pps, num_slice_groups_minus1);
966 //ITEM_SET(vapp, &desc->pps, slice_group_map_type);
967 //ITEM_SET(vapp, &desc->pps, slice_group_change_rate_minus1);
968 ITEM_SET(vapp, &desc->pps, pic_init_qp_minus26);
969 ITEM_SET(vapp, &desc->pps, pic_init_qs_minus26);
970 ITEM_SET(vapp, &desc->pps, chroma_qp_index_offset);
971 ITEM_SET(vapp, &desc->pps, second_chroma_qp_index_offset);
972
973 ITEM_SET(&vapp->pic_fields.bits, &desc->pps, entropy_coding_mode_flag);
974 ITEM_SET(&vapp->pic_fields.bits, &desc->pps, weighted_pred_flag);
975 ITEM_SET(&vapp->pic_fields.bits, &desc->pps, weighted_bipred_idc);
976 ITEM_SET(&vapp->pic_fields.bits, &desc->pps, transform_8x8_mode_flag);
977 ITEM_SET(&vapp->pic_fields.bits, desc, field_pic_flag);
978 ITEM_SET(&vapp->pic_fields.bits, &desc->pps, constrained_intra_pred_flag);
979 vapp->pic_fields.bits.pic_order_present_flag =
980 desc->pps.bottom_field_pic_order_in_frame_present_flag;
981 ITEM_SET(&vapp->pic_fields.bits,
982 &desc->pps, deblocking_filter_control_present_flag);
983 ITEM_SET(&vapp->pic_fields.bits,
984 &desc->pps, redundant_pic_cnt_present_flag);
985 vapp->pic_fields.bits.reference_pic_flag = desc->is_reference;
986
987 ITEM_SET(vapp, desc, frame_num);
988 }
989
990
991 /* Refer to vlVaHandleIQMatrixBufferH264() in mesa */
h264_fill_iq_matrix(const struct virgl_h264_picture_desc * desc,VAIQMatrixBufferH264 * vaiqm)992 static void h264_fill_iq_matrix(const struct virgl_h264_picture_desc *desc,
993 VAIQMatrixBufferH264 *vaiqm)
994 {
995 ITEM_CPY(vaiqm, &desc->pps, ScalingList4x4);
996 ITEM_CPY(vaiqm, &desc->pps, ScalingList8x8);
997 }
998
999 /*
1000 * Refer to vlVaHandleSliceParameterBufferH264() in mesa,
1001 * and comment out some unused parameters.
1002 */
h264_fill_slice_param(const struct virgl_h264_picture_desc * desc,VASliceParameterBufferH264 * vasp)1003 static void h264_fill_slice_param(const struct virgl_h264_picture_desc *desc,
1004 VASliceParameterBufferH264 *vasp)
1005 {
1006 //vasp->slice_data_size;
1007 //vasp->slice_data_offset;
1008 //vasp->slice_data_flag;
1009 //vasp->slice_data_bit_offset;
1010 //vasp->first_mb_in_slice;
1011 //vasp->slice_type;
1012 //vasp->direct_spatial_mv_pred_flag;
1013 ITEM_SET(vasp, desc, num_ref_idx_l0_active_minus1);
1014 ITEM_SET(vasp, desc, num_ref_idx_l1_active_minus1);
1015 //vasp->cabac_init_idc;
1016 //vasp->slice_qp_delta;
1017 //vasp->disable_deblocking_filter_idc;
1018 //vasp->slice_alpha_c0_offset_div2;
1019 //vasp->slice_beta_offset_div2;
1020 //vasp->RefPicList0[32];
1021 //vasp->RefPicList1[32];
1022
1023 /* see pred_weight_table */
1024 //vasp->luma_log2_weight_denom;
1025 //vasp->chroma_log2_weight_denom;
1026 //vasp->luma_weight_l0_flag;
1027 //vasp->luma_weight_l0[32];
1028 //vasp->luma_offset_l0[32];
1029 //vasp->chroma_weight_l0_flag;
1030 //vasp->chroma_weight_l0[32][2];
1031 //vasp->chroma_offset_l0[32][2];
1032 //vasp->luma_weight_l1_flag;
1033 //vasp->luma_weight_l1[32];
1034 //vasp->luma_offset_l1[32];
1035 //vasp->chroma_weight_l1_flag;
1036 //vasp->chroma_weight_l1[32][2];
1037 //vasp->chroma_offset_l1[32][2];
1038 }
1039
1040 /*
1041 * Refer to vlVaHandleVAEncPictureParameterBufferTypeH264() in mesa,
1042 * and comment out some unused parameters.
1043 */
h264_fill_enc_picture_param(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h264_enc_picture_desc * desc,VAEncPictureParameterBufferH264 * param)1044 static void h264_fill_enc_picture_param(
1045 struct virgl_video_codec *codec,
1046 struct virgl_video_buffer *source,
1047 const struct virgl_h264_enc_picture_desc *desc,
1048 VAEncPictureParameterBufferH264 *param)
1049 {
1050 unsigned i;
1051
1052 (void)codec;
1053 (void)source;
1054
1055 /* CurrPic */
1056 param->CurrPic.picture_id = get_enc_ref_pic(codec, desc->frame_num);
1057 //CurrPic.frame_idx;
1058 //CurrPic.flags;
1059 param->CurrPic.TopFieldOrderCnt = desc->pic_order_cnt;
1060 //CurrPic.BottomFieldOrderCnt;
1061
1062 /* ReferenceFrames */
1063 for (i = 0; i < ARRAY_SIZE(param->ReferenceFrames); i++)
1064 h264_init_picture(¶m->ReferenceFrames[i]);
1065
1066 /* coded_buf */
1067 param->coded_buf = codec->va_coded_buf;
1068
1069 //pic_parameter_set_id;
1070 //seq_parameter_set_id;
1071 //last_picture;
1072 //frame_num
1073 param->pic_init_qp = desc->quant_i_frames;
1074 param->num_ref_idx_l0_active_minus1 = desc->num_ref_idx_l0_active_minus1;
1075 param->num_ref_idx_l1_active_minus1 = desc->num_ref_idx_l1_active_minus1;
1076 //chroma_qp_index_offset;
1077 //second_chroma_qp_index_offset;
1078
1079 /* pic_fields */
1080 param->pic_fields.bits.idr_pic_flag =
1081 (desc->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR);
1082 param->pic_fields.bits.reference_pic_flag = !desc->not_referenced;
1083 param->pic_fields.bits.entropy_coding_mode_flag = desc->pic_ctrl.enc_cabac_enable;
1084 //pic_fields.bits.weighted_pred_flag
1085 //pic_fields.bits.weighted_bipred_idc
1086 //pic_fields.bits.constrained_intra_pred_flag
1087 //pic_fields.bits.transform_8x8_mode_flag
1088 //pic_fields.bits.deblocking_filter_control_present_flag
1089 //pic_fields.bits.redundant_pic_cnt_present_flag
1090 //pic_fields.bits.pic_order_present_flag
1091 //pic_fields.bits.pic_scaling_matrix_present_flag
1092
1093 }
1094
1095 /*
1096 * Refer to vlVaHandleVAEncSliceParameterBufferTypeH264() in mesa,
1097 * and comment out some unused parameters.
1098 */
h264_fill_enc_slice_param(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h264_enc_picture_desc * desc,VAEncSliceParameterBufferH264 * param)1099 static void h264_fill_enc_slice_param(
1100 struct virgl_video_codec *codec,
1101 struct virgl_video_buffer *source,
1102 const struct virgl_h264_enc_picture_desc *desc,
1103 VAEncSliceParameterBufferH264 *param)
1104 {
1105 unsigned i;
1106 const struct virgl_h264_slice_descriptor *sd;
1107
1108 (void)codec;
1109 (void)source;
1110
1111 /* Get the lastest slice descriptor */
1112 if (desc->num_slice_descriptors &&
1113 desc->num_slice_descriptors <= ARRAY_SIZE(desc->slices_descriptors)) {
1114 sd = &desc->slices_descriptors[desc->num_slice_descriptors - 1];
1115 param->macroblock_address = sd->macroblock_address;
1116 param->num_macroblocks = sd->num_macroblocks;
1117 //macroblock_info;
1118 }
1119
1120 switch (desc->picture_type) {
1121 case PIPE_H2645_ENC_PICTURE_TYPE_P:
1122 param->slice_type = 0;
1123 break;
1124 case PIPE_H2645_ENC_PICTURE_TYPE_B:
1125 param->slice_type = 1;
1126 break;
1127 case PIPE_H2645_ENC_PICTURE_TYPE_I:
1128 case PIPE_H2645_ENC_PICTURE_TYPE_IDR: /* fall through */
1129 param->slice_type = 2;
1130 break;
1131 case PIPE_H2645_ENC_PICTURE_TYPE_SKIP:
1132 default:
1133 break;
1134 }
1135
1136 //pic_parameter_set_id;
1137 //idr_pic_id;
1138 //pic_order_cnt_lsb;
1139 //delta_pic_order_cnt_bottom;
1140 //delta_pic_order_cnt[2];
1141 //direct_spatial_mv_pred_flag;
1142
1143 /*
1144 * Sine num_ref_idx_l0_active_minus1 and num_ref_idx_l1_active_minus1
1145 * have been passed by VAEncPictureParameterBufferH264,
1146 * num_ref_idx_active_override_flag is always set to 0.
1147 */
1148 param->num_ref_idx_active_override_flag = 0;
1149 //num_ref_idx_l0_active_minus1
1150 //num_ref_idx_l1_active_minus1
1151
1152 /* Reference List */
1153 for (i = 0; i < 32; i++) {
1154 h264_init_picture(¶m->RefPicList0[i]);
1155 h264_init_picture(¶m->RefPicList1[i]);
1156
1157 param->RefPicList0[i].picture_id =
1158 get_enc_ref_pic(codec, desc->ref_idx_l0_list[i]);
1159 param->RefPicList1[i].picture_id =
1160 get_enc_ref_pic(codec, desc->ref_idx_l1_list[i]);
1161
1162 if (param->RefPicList0[i].picture_id != VA_INVALID_ID)
1163 param->RefPicList0[i].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE;
1164
1165 if (param->RefPicList1[i].picture_id != VA_INVALID_ID)
1166 param->RefPicList1[i].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE;
1167 }
1168
1169 //luma_log2_weight_denom;
1170 //chroma_log2_weight_denom;
1171 //luma_weight_l0_flag;
1172 //luma_weight_l0[32];
1173 //luma_offset_l0[32];
1174 //chroma_weight_l0_flag;
1175 //chroma_weight_l0[32][2];
1176 //chroma_offset_l0[32][2];
1177 //luma_weight_l1_flag;
1178 //luma_weight_l1[32];
1179 //luma_offset_l1[32];
1180 //chroma_weight_l1_flag;
1181 //chroma_weight_l1[32][2];
1182 //chroma_offset_l1[32][2];
1183 param->cabac_init_idc = desc->pic_ctrl.enc_cabac_init_idc;
1184 //slice_qp_delta;
1185 //disable_deblocking_filter_idc;
1186 //slice_alpha_c0_offset_div2;
1187 //slice_beta_offset_div2;
1188
1189 }
1190
1191 /*
1192 * Refer to vlVaHandleVAEncSequenceParameterBufferTypeH264() in mesa,
1193 * and comment out some unused parameters.
1194 */
h264_fill_enc_seq_param(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h264_enc_picture_desc * desc,VAEncSequenceParameterBufferH264 * param)1195 static void h264_fill_enc_seq_param(
1196 struct virgl_video_codec *codec,
1197 struct virgl_video_buffer *source,
1198 const struct virgl_h264_enc_picture_desc *desc,
1199 VAEncSequenceParameterBufferH264 *param)
1200 {
1201 (void)codec;
1202 (void)source;
1203
1204 //seq_parameter_set_id;
1205 param->level_idc = codec->level;
1206 //intra_period;
1207 param->intra_idr_period = desc->intra_idr_period;
1208 //ip_period;
1209 //bits_per_second;
1210 param->max_num_ref_frames = codec->max_references;
1211 //picture_width_in_mbs;
1212 //picture_height_in_mbs;
1213
1214 /* seq_fields.bits */
1215 //seq_fields.bits.chroma_format_idc
1216 //seq_fields.bits.frame_mbs_only_flag
1217 //seq_fields.bits.mb_adaptive_frame_field_flag
1218 //seq_fields.bits.seq_scaling_matrix_present_flag
1219 //seq_fields.bits.direct_8x8_inference_flag
1220 //seq_fields.bits.log2_max_frame_num_minus4
1221 ITEM_SET(¶m->seq_fields.bits, &desc->seq, pic_order_cnt_type);
1222 //seq_fields.bit.log2_max_pic_order_cnt_lsb_minus4
1223 //seq_fields.bit.delta_pic_order_always_zero_flag
1224
1225 //bit_depth_luma_minus8;
1226 //bit_depth_chroma_minus8;
1227
1228 //num_ref_frames_in_pic_order_cnt_cycle;
1229 //offset_for_non_ref_pic;
1230 //offset_for_top_to_bottom_field;
1231 //offset_for_ref_frame[256];
1232 if (desc->seq.enc_frame_cropping_flag) {
1233 param->frame_cropping_flag = desc->seq.enc_frame_cropping_flag;
1234 param->frame_crop_left_offset = desc->seq.enc_frame_crop_left_offset;
1235 param->frame_crop_right_offset = desc->seq.enc_frame_crop_right_offset;
1236 param->frame_crop_top_offset = desc->seq.enc_frame_crop_top_offset;
1237 param->frame_crop_bottom_offset = desc->seq.enc_frame_crop_bottom_offset;
1238 }
1239
1240 ITEM_SET(param, &desc->seq, vui_parameters_present_flag);
1241
1242 // vui_fields.bits
1243 if (desc->seq.vui_parameters_present_flag) {
1244 ITEM_SET(¶m->vui_fields.bits, &desc->seq.vui_flags,
1245 aspect_ratio_info_present_flag);
1246 ITEM_SET(¶m->vui_fields.bits, &desc->seq.vui_flags,
1247 timing_info_present_flag);
1248 }
1249 //vui_fields.bits.bitstream_restriction_flag
1250 //vui_fields.bits.log2_max_mv_length_horizontal
1251 //vui_fields.bits.log2_max_mv_length_vertical
1252 //vui_fields.bits.fixed_frame_rate_flag
1253 //vui_fields.bits.low_delay_hrd_flag
1254 //vui_fields.bits.motion_vectors_over_pic_boundaries_flag
1255
1256 if (desc->seq.vui_parameters_present_flag) {
1257 ITEM_SET(param, &desc->seq, aspect_ratio_idc);
1258 ITEM_SET(param, &desc->seq, sar_width);
1259 ITEM_SET(param, &desc->seq, sar_height);
1260 }
1261 ITEM_SET(param, &desc->seq, num_units_in_tick);
1262 ITEM_SET(param, &desc->seq, time_scale);
1263 }
1264
1265 /*
1266 * Refer to vlVaHandleVAEncMiscParameterTypeRateControlH264() in mesa,
1267 * and comment out some unused parameters.
1268 */
h264_fill_enc_misc_param_rate_ctrl(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h264_enc_picture_desc * desc,VAEncMiscParameterRateControl * param)1269 static void h264_fill_enc_misc_param_rate_ctrl(
1270 struct virgl_video_codec *codec,
1271 struct virgl_video_buffer *source,
1272 const struct virgl_h264_enc_picture_desc *desc,
1273 VAEncMiscParameterRateControl *param)
1274 {
1275 unsigned temporal_id = 0; /* always 0 now */
1276 const struct virgl_h264_enc_rate_control *rc = &desc->rate_ctrl[temporal_id];
1277
1278 (void)codec;
1279 (void)source;
1280
1281 param->bits_per_second = rc->peak_bitrate;
1282 if (desc->rate_ctrl[0].rate_ctrl_method !=
1283 PIPE_H2645_ENC_RATE_CONTROL_METHOD_CONSTANT) {
1284 param->target_percentage = rc->target_bitrate *
1285 param->bits_per_second / 100.0;
1286 }
1287 //window_size;
1288 //initial_qp;
1289 param->min_qp = rc->min_qp;
1290 //basic_unit_size;
1291
1292 /* rc_flags */
1293 //rc_flags.bits.reset
1294 param->rc_flags.bits.disable_frame_skip = !rc->skip_frame_enable;
1295 param->rc_flags.bits.disable_bit_stuffing = !rc->fill_data_enable;
1296 //rc_flags.bits.mb_rate_control
1297 param->rc_flags.bits.temporal_id = temporal_id;
1298 //rc_flags.bits.cfs_I_frames
1299 //rc_flags.bits.enable_parallel_brc
1300 //rc_flags.bits.enable_dynamic_scaling
1301 //rc_flags.bits.frame_tolerance_mode
1302
1303 //ICQ_quality_factor;
1304 param->max_qp = rc->max_qp;
1305 //quality_factor;
1306 //target_frame_size;
1307 }
1308
1309 /*
1310 * Refer to vlVaHandleVAEncMiscParameterTypeFrameRateH264() in mesa,
1311 * and comment out some unused parameters.
1312 */
h264_fill_enc_misc_param_frame_rate(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h264_enc_picture_desc * desc,VAEncMiscParameterFrameRate * param)1313 static void h264_fill_enc_misc_param_frame_rate(
1314 struct virgl_video_codec *codec,
1315 struct virgl_video_buffer *source,
1316 const struct virgl_h264_enc_picture_desc *desc,
1317 VAEncMiscParameterFrameRate *param)
1318 {
1319 unsigned temporal_id = 0; /* always 0 now */
1320 const struct virgl_h264_enc_rate_control *rc = &desc->rate_ctrl[temporal_id];
1321
1322 (void)codec;
1323 (void)source;
1324
1325 param->framerate = rc->frame_rate_num | (rc->frame_rate_den << 16);
1326 param->framerate_flags.bits.temporal_id = temporal_id;
1327 }
1328
h264_decode_bitstream(struct virgl_video_codec * codec,struct virgl_video_buffer * target,const struct virgl_h264_picture_desc * desc,unsigned num_buffers,const void * const * buffers,const unsigned * sizes)1329 static int h264_decode_bitstream(struct virgl_video_codec *codec,
1330 struct virgl_video_buffer *target,
1331 const struct virgl_h264_picture_desc *desc,
1332 unsigned num_buffers,
1333 const void * const *buffers,
1334 const unsigned *sizes)
1335 {
1336 unsigned i;
1337 int err = 0;
1338 VAStatus va_stat;
1339 VABufferID *slice_data_buf, pic_param_buf, iq_matrix_buf, slice_param_buf;
1340 VAPictureParameterBufferH264 pic_param;
1341 VAIQMatrixBufferH264 iq_matrix;
1342 VASliceParameterBufferH264 slice_param;
1343
1344 slice_data_buf = calloc(num_buffers, sizeof(VABufferID));
1345 if (!slice_data_buf) {
1346 virgl_log("alloc slice data buffer id failed\n");
1347 return -1;
1348 }
1349
1350 h264_fill_picture_param(codec, target, desc, &pic_param);
1351 vaCreateBuffer(va_dpy, codec->va_ctx, VAPictureParameterBufferType,
1352 sizeof(pic_param), 1, &pic_param, &pic_param_buf);
1353
1354 h264_fill_iq_matrix(desc, &iq_matrix);
1355 vaCreateBuffer(va_dpy, codec->va_ctx, VAIQMatrixBufferType,
1356 sizeof(iq_matrix), 1, &iq_matrix, &iq_matrix_buf);
1357
1358 h264_fill_slice_param(desc, &slice_param);
1359 vaCreateBuffer(va_dpy, codec->va_ctx, VASliceParameterBufferType,
1360 sizeof(slice_param), 1, &slice_param, &slice_param_buf);
1361
1362 for (i = 0; i < num_buffers; i++) {
1363 vaCreateBuffer(va_dpy, codec->va_ctx, VASliceDataBufferType,
1364 sizes[i], 1, (void *)(buffers[i]), &slice_data_buf[i]);
1365 }
1366
1367 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &pic_param_buf, 1);
1368 if (VA_STATUS_SUCCESS != va_stat) {
1369 virgl_log("render picture param failed, err = 0x%x\n", va_stat);
1370 err = -1;
1371 goto err;
1372 }
1373
1374 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &iq_matrix_buf, 1);
1375 if (VA_STATUS_SUCCESS != va_stat) {
1376 virgl_log("render iq matrix failed, err = 0x%x\n", va_stat);
1377 err = -1;
1378 goto err;
1379 }
1380
1381 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &slice_param_buf, 1);
1382 if (VA_STATUS_SUCCESS != va_stat) {
1383 virgl_log("render slice param failed, err = 0x%x\n", va_stat);
1384 err = -1;
1385 goto err;
1386 }
1387
1388 for (i = 0; i < num_buffers; i++) {
1389 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &slice_data_buf[i], 1);
1390
1391 if (VA_STATUS_SUCCESS != va_stat) {
1392 virgl_log("render slice data failed, err = 0x%x\n", va_stat);
1393 err = -1;
1394 }
1395 }
1396
1397 err:
1398 vaDestroyBuffer(va_dpy, pic_param_buf);
1399 vaDestroyBuffer(va_dpy, iq_matrix_buf);
1400 vaDestroyBuffer(va_dpy, slice_param_buf);
1401 for (i = 0; i < num_buffers; i++)
1402 vaDestroyBuffer(va_dpy, slice_data_buf[i]);
1403 free(slice_data_buf);
1404
1405 return err;
1406 }
1407
h264_encode_render_sequence(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h264_enc_picture_desc * desc)1408 static int h264_encode_render_sequence(
1409 struct virgl_video_codec *codec,
1410 struct virgl_video_buffer *source,
1411 const struct virgl_h264_enc_picture_desc *desc)
1412 {
1413 int err = 0;
1414 VAStatus va_stat;
1415 VAEncSequenceParameterBufferH264 seq_param;
1416 VAEncMiscParameterBuffer *misc_param;
1417 VABufferID seq_param_buf, rc_param_buf, fr_param_buf;
1418
1419 memset(&seq_param, 0, sizeof(seq_param));
1420 h264_fill_enc_seq_param(codec, source, desc, &seq_param);
1421 vaCreateBuffer(va_dpy, codec->va_ctx, VAEncSequenceParameterBufferType,
1422 sizeof(seq_param), 1, &seq_param, &seq_param_buf);
1423
1424 vaCreateBuffer(va_dpy, codec->va_ctx, VAEncMiscParameterBufferType,
1425 sizeof(VAEncMiscParameterBuffer) +
1426 sizeof(VAEncMiscParameterRateControl), 1, NULL, &rc_param_buf);
1427 vaMapBuffer(va_dpy, rc_param_buf, (void **)&misc_param);
1428 misc_param->type = VAEncMiscParameterTypeRateControl;
1429 h264_fill_enc_misc_param_rate_ctrl(codec, source, desc,
1430 (VAEncMiscParameterRateControl *)misc_param->data);
1431 vaUnmapBuffer(va_dpy, rc_param_buf);
1432
1433 vaCreateBuffer(va_dpy, codec->va_ctx, VAEncMiscParameterBufferType,
1434 sizeof(VAEncMiscParameterBuffer) +
1435 sizeof(VAEncMiscParameterFrameRate), 1, NULL, &fr_param_buf);
1436 vaMapBuffer(va_dpy, fr_param_buf, (void **)&misc_param);
1437 misc_param->type = VAEncMiscParameterTypeFrameRate;
1438 h264_fill_enc_misc_param_frame_rate(codec, source, desc,
1439 (VAEncMiscParameterFrameRate *)misc_param->data);
1440 vaUnmapBuffer(va_dpy, fr_param_buf);
1441
1442 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &seq_param_buf, 1);
1443 if (VA_STATUS_SUCCESS != va_stat) {
1444 virgl_log("render h264 sequence param failed, err = 0x%x\n", va_stat);
1445 err = -1;
1446 goto error;
1447 }
1448
1449 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &rc_param_buf, 1);
1450 if (VA_STATUS_SUCCESS != va_stat) {
1451 virgl_log("render h264 rate control param failed, err = 0x%x\n", va_stat);
1452 err = -1;
1453 goto error;
1454 }
1455
1456 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &fr_param_buf, 1);
1457 if (VA_STATUS_SUCCESS != va_stat) {
1458 virgl_log("render h264 frame rate param failed, err = 0x%x\n", va_stat);
1459 err = -1;
1460 goto error;
1461 }
1462
1463 error:
1464 vaDestroyBuffer(va_dpy, seq_param_buf);
1465 vaDestroyBuffer(va_dpy, rc_param_buf);
1466 vaDestroyBuffer(va_dpy, fr_param_buf);
1467
1468 return err;
1469 }
1470
h264_encode_render_picture(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h264_enc_picture_desc * desc)1471 static int h264_encode_render_picture(
1472 struct virgl_video_codec *codec,
1473 struct virgl_video_buffer *source,
1474 const struct virgl_h264_enc_picture_desc *desc)
1475 {
1476 VAStatus va_stat;
1477 VABufferID pic_param_buf;
1478 VAEncPictureParameterBufferH264 pic_param;
1479
1480 memset(&pic_param, 0, sizeof(pic_param));
1481 h264_fill_enc_picture_param(codec, source, desc, &pic_param);
1482 vaCreateBuffer(va_dpy, codec->va_ctx, VAEncPictureParameterBufferType,
1483 sizeof(pic_param), 1, &pic_param, &pic_param_buf);
1484
1485 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &pic_param_buf, 1);
1486 vaDestroyBuffer(va_dpy, pic_param_buf);
1487
1488 if (VA_STATUS_SUCCESS != va_stat) {
1489 virgl_log("render h264 picture param failed, err = 0x%x\n", va_stat);
1490 return -1;
1491 }
1492
1493 return 0;
1494 }
1495
h264_encode_render_slice(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h264_enc_picture_desc * desc)1496 static int h264_encode_render_slice(
1497 struct virgl_video_codec *codec,
1498 struct virgl_video_buffer *source,
1499 const struct virgl_h264_enc_picture_desc *desc)
1500 {
1501 VAStatus va_stat;
1502 VABufferID slice_param_buf;
1503 VAEncSliceParameterBufferH264 slice_param;
1504
1505 memset(&slice_param, 0, sizeof(slice_param));
1506 h264_fill_enc_slice_param(codec, source, desc, &slice_param);
1507 vaCreateBuffer(va_dpy, codec->va_ctx, VAEncSliceParameterBufferType,
1508 sizeof(slice_param), 1, &slice_param, &slice_param_buf);
1509
1510 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &slice_param_buf, 1);
1511 vaDestroyBuffer(va_dpy, slice_param_buf);
1512
1513 if (VA_STATUS_SUCCESS != va_stat) {
1514 virgl_log("render h264 slice param failed, err = 0x%x\n", va_stat);
1515 return -1;
1516 }
1517
1518 return 0;
1519 }
1520
h264_encode_bitstream(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h264_enc_picture_desc * desc)1521 static int h264_encode_bitstream(
1522 struct virgl_video_codec *codec,
1523 struct virgl_video_buffer *source,
1524 const struct virgl_h264_enc_picture_desc *desc)
1525 {
1526 if (desc->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR) {
1527 h264_encode_render_sequence(codec, source, desc);
1528 }
1529
1530 h264_encode_render_picture(codec, source, desc);
1531 h264_encode_render_slice(codec, source, desc);
1532
1533 return 0;
1534 }
1535
h265_init_picture(VAPictureHEVC * pic)1536 static void h265_init_picture(VAPictureHEVC *pic)
1537 {
1538 pic->picture_id = VA_INVALID_SURFACE;
1539 pic->pic_order_cnt = 0;
1540 pic->flags = VA_PICTURE_HEVC_INVALID;
1541 }
1542
1543 /*
1544 * Refer to vlVaHandlePictureParameterBufferHEVC() in mesa,
1545 * and comment out some unused parameters.
1546 */
h265_fill_picture_param(struct virgl_video_codec * codec,struct virgl_video_buffer * target,const struct virgl_h265_picture_desc * desc,VAPictureParameterBufferHEVC * vapp)1547 static void h265_fill_picture_param(struct virgl_video_codec *codec,
1548 struct virgl_video_buffer *target,
1549 const struct virgl_h265_picture_desc *desc,
1550 VAPictureParameterBufferHEVC *vapp)
1551 {
1552 unsigned i;
1553
1554 (void)codec;
1555 (void)target;
1556
1557 //vapp->CurrPic.picture_id
1558 vapp->CurrPic.pic_order_cnt = desc->CurrPicOrderCntVal;
1559 //vapp->CurrPic.flags
1560
1561 for (i = 0; i < 15; i++) {
1562 vapp->ReferenceFrames[i].pic_order_cnt = desc->PicOrderCntVal[i];
1563 vapp->ReferenceFrames[i].picture_id = desc->ref[i];
1564 vapp->ReferenceFrames[i].flags = VA_INVALID_SURFACE == desc->ref[i]
1565 ? VA_PICTURE_HEVC_INVALID : 0;
1566 }
1567 for (i = 0; i < desc->NumPocStCurrBefore; i++)
1568 vapp->ReferenceFrames[desc->RefPicSetStCurrBefore[i]].flags |= \
1569 VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE;
1570 for (i = 0; i < desc->NumPocStCurrAfter; i++)
1571 vapp->ReferenceFrames[desc->RefPicSetStCurrAfter[i]].flags |= \
1572 VA_PICTURE_HEVC_RPS_ST_CURR_AFTER;
1573 for (i = 0; i < desc->NumPocLtCurr; i++)
1574 vapp->ReferenceFrames[desc->RefPicSetLtCurr[i]].flags |= \
1575 VA_PICTURE_HEVC_RPS_LT_CURR;
1576
1577 ITEM_SET(vapp, &desc->pps.sps, pic_width_in_luma_samples);
1578 ITEM_SET(vapp, &desc->pps.sps, pic_height_in_luma_samples);
1579
1580 ITEM_SET(&vapp->pic_fields.bits, &desc->pps.sps, chroma_format_idc);
1581 ITEM_SET(&vapp->pic_fields.bits,
1582 &desc->pps.sps, separate_colour_plane_flag);
1583 ITEM_SET(&vapp->pic_fields.bits, &desc->pps.sps, pcm_enabled_flag);
1584 ITEM_SET(&vapp->pic_fields.bits,
1585 &desc->pps.sps, scaling_list_enabled_flag);
1586 ITEM_SET(&vapp->pic_fields.bits,
1587 &desc->pps, transform_skip_enabled_flag);
1588 ITEM_SET(&vapp->pic_fields.bits, &desc->pps.sps, amp_enabled_flag);
1589 ITEM_SET(&vapp->pic_fields.bits,
1590 &desc->pps.sps, strong_intra_smoothing_enabled_flag);
1591 ITEM_SET(&vapp->pic_fields.bits, &desc->pps, sign_data_hiding_enabled_flag);
1592 ITEM_SET(&vapp->pic_fields.bits, &desc->pps, constrained_intra_pred_flag);
1593 ITEM_SET(&vapp->pic_fields.bits, &desc->pps, cu_qp_delta_enabled_flag);
1594 ITEM_SET(&vapp->pic_fields.bits, &desc->pps, weighted_pred_flag);
1595 ITEM_SET(&vapp->pic_fields.bits, &desc->pps, weighted_bipred_flag);
1596 ITEM_SET(&vapp->pic_fields.bits,
1597 &desc->pps, transquant_bypass_enabled_flag);
1598 ITEM_SET(&vapp->pic_fields.bits, &desc->pps, tiles_enabled_flag);
1599 ITEM_SET(&vapp->pic_fields.bits,
1600 &desc->pps, entropy_coding_sync_enabled_flag);
1601 ITEM_SET(&vapp->pic_fields.bits, &desc->pps,
1602 pps_loop_filter_across_slices_enabled_flag);
1603 if (desc->pps.tiles_enabled_flag)
1604 ITEM_SET(&vapp->pic_fields.bits,
1605 &desc->pps, loop_filter_across_tiles_enabled_flag);
1606 if (desc->pps.sps.pcm_enabled_flag)
1607 ITEM_SET(&vapp->pic_fields.bits,
1608 &desc->pps.sps, pcm_loop_filter_disabled_flag);
1609 //ITEM_SET(vapp->pic_fields.bits, desc->pps.sps, NoPicReorderingFlag);
1610 //ITEM_SET(vapp->pic_fields.bits, desc->pps.sps, NoBiPredFlag);
1611
1612 ITEM_SET(vapp, &desc->pps.sps, sps_max_dec_pic_buffering_minus1);
1613 ITEM_SET(vapp, &desc->pps.sps, bit_depth_luma_minus8);
1614 ITEM_SET(vapp, &desc->pps.sps, bit_depth_chroma_minus8);
1615 if (desc->pps.sps.pcm_enabled_flag) {
1616 ITEM_SET(vapp, &desc->pps.sps, pcm_sample_bit_depth_luma_minus1);
1617 ITEM_SET(vapp, &desc->pps.sps, pcm_sample_bit_depth_chroma_minus1);
1618 }
1619 ITEM_SET(vapp, &desc->pps.sps, log2_min_luma_coding_block_size_minus3);
1620 ITEM_SET(vapp, &desc->pps.sps, log2_diff_max_min_luma_coding_block_size);
1621 ITEM_SET(vapp, &desc->pps.sps, log2_min_transform_block_size_minus2);
1622 ITEM_SET(vapp, &desc->pps.sps, log2_diff_max_min_transform_block_size);
1623 if (desc->pps.sps.pcm_enabled_flag) {
1624 ITEM_SET(vapp, &desc->pps.sps,
1625 log2_min_pcm_luma_coding_block_size_minus3);
1626 ITEM_SET(vapp, &desc->pps.sps,
1627 log2_diff_max_min_pcm_luma_coding_block_size);
1628 }
1629 ITEM_SET(vapp, &desc->pps.sps, max_transform_hierarchy_depth_intra);
1630 ITEM_SET(vapp, &desc->pps.sps, max_transform_hierarchy_depth_inter);
1631 ITEM_SET(vapp, &desc->pps, init_qp_minus26);
1632 ITEM_SET(vapp, &desc->pps, diff_cu_qp_delta_depth);
1633 ITEM_SET(vapp, &desc->pps, pps_cb_qp_offset);
1634 ITEM_SET(vapp, &desc->pps, pps_cr_qp_offset);
1635 ITEM_SET(vapp, &desc->pps, log2_parallel_merge_level_minus2);
1636 if (desc->pps.tiles_enabled_flag) {
1637 ITEM_SET(vapp, &desc->pps, num_tile_columns_minus1);
1638 ITEM_SET(vapp, &desc->pps, num_tile_rows_minus1);
1639 ITEM_CPY(vapp, &desc->pps, column_width_minus1);
1640 ITEM_CPY(vapp, &desc->pps, row_height_minus1);
1641 }
1642
1643 ITEM_SET(&vapp->slice_parsing_fields.bits,
1644 &desc->pps, lists_modification_present_flag);
1645 ITEM_SET(&vapp->slice_parsing_fields.bits,
1646 &desc->pps.sps, long_term_ref_pics_present_flag);
1647 ITEM_SET(&vapp->slice_parsing_fields.bits,
1648 &desc->pps.sps, sps_temporal_mvp_enabled_flag);
1649 ITEM_SET(&vapp->slice_parsing_fields.bits,
1650 &desc->pps, cabac_init_present_flag);
1651 ITEM_SET(&vapp->slice_parsing_fields.bits,
1652 &desc->pps, output_flag_present_flag);
1653 ITEM_SET(&vapp->slice_parsing_fields.bits,
1654 &desc->pps, dependent_slice_segments_enabled_flag);
1655 ITEM_SET(&vapp->slice_parsing_fields.bits,
1656 &desc->pps, pps_slice_chroma_qp_offsets_present_flag);
1657 ITEM_SET(&vapp->slice_parsing_fields.bits,
1658 &desc->pps.sps, sample_adaptive_offset_enabled_flag);
1659 ITEM_SET(&vapp->slice_parsing_fields.bits,
1660 &desc->pps, deblocking_filter_override_enabled_flag);
1661 vapp->slice_parsing_fields.bits.pps_disable_deblocking_filter_flag = \
1662 desc->pps.pps_deblocking_filter_disabled_flag;
1663 ITEM_SET(&vapp->slice_parsing_fields.bits,
1664 &desc->pps, slice_segment_header_extension_present_flag);
1665 vapp->slice_parsing_fields.bits.RapPicFlag = desc->RAPPicFlag;
1666 vapp->slice_parsing_fields.bits.IdrPicFlag = desc->IDRPicFlag;
1667 //vapp->slice_parsing_fields.bits.IntraPicFlag
1668
1669 ITEM_SET(vapp, &desc->pps.sps, log2_max_pic_order_cnt_lsb_minus4);
1670 ITEM_SET(vapp, &desc->pps.sps, num_short_term_ref_pic_sets);
1671 vapp->num_long_term_ref_pic_sps = desc->pps.sps.num_long_term_ref_pics_sps;
1672 ITEM_SET(vapp, &desc->pps, num_ref_idx_l0_default_active_minus1);
1673 ITEM_SET(vapp, &desc->pps, num_ref_idx_l1_default_active_minus1);
1674 ITEM_SET(vapp, &desc->pps, pps_beta_offset_div2);
1675 ITEM_SET(vapp, &desc->pps, pps_tc_offset_div2);
1676 ITEM_SET(vapp, &desc->pps, num_extra_slice_header_bits);
1677
1678 ITEM_SET(vapp, &desc->pps, st_rps_bits);
1679 }
1680
1681 /*
1682 * Refer to vlVaHandleSliceParameterBufferHEVC() in mesa,
1683 * and comment out some unused parameters.
1684 */
h265_fill_slice_param(const struct virgl_h265_picture_desc * desc,VASliceParameterBufferHEVC * vapp)1685 static void h265_fill_slice_param(const struct virgl_h265_picture_desc *desc,
1686 VASliceParameterBufferHEVC *vapp)
1687 {
1688 unsigned i, j;
1689
1690 //slice_data_size;
1691 //slice_data_offset;
1692 //slice_data_flag;
1693 //slice_data_byte_offset;
1694 //slice_segment_address;
1695 for (i = 0; i < 2; i++) {
1696 for (j = 0; j < 15; j++)
1697 vapp->RefPicList[i][j] = desc->RefPicList[i][j];
1698 }
1699 //LongSliceFlags;
1700 //collocated_ref_idx;
1701 //num_ref_idx_l0_active_minus1;
1702 //num_ref_idx_l1_active_minus1;
1703 //slice_qp_delta;
1704 //slice_cb_qp_offset;
1705 //slice_cr_qp_offset;
1706 //slice_beta_offset_div2;
1707 //slice_tc_offset_div2;
1708 //luma_log2_weight_denom;
1709 //delta_chroma_log2_weight_denom;
1710 //delta_luma_weight_l0[15];
1711 //luma_offset_l0[15];
1712 //delta_chroma_weight_l0[15][2];
1713 //ChromaOffsetL0[15][2];
1714 //delta_luma_weight_l1[15];
1715 //luma_offset_l1[15];
1716 //delta_chroma_weight_l1[15][2];
1717 //ChromaOffsetL1[15][2];
1718 //five_minus_max_num_merge_cand;
1719 //num_entry_point_offsets;
1720 //entry_offset_to_subset_array;
1721 //slice_data_num_emu_prevn_bytes;
1722 //va_reserved[VA_PADDING_LOW - 2];
1723 }
1724
1725 /*
1726 * Refer to vlVaHandleVAEncSequenceParameterBufferTypeHEVC() in mesa,
1727 * and comment out some unused parameters.
1728 */
h265_fill_enc_seq_param(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h265_enc_picture_desc * desc,VAEncSequenceParameterBufferHEVC * param)1729 static void h265_fill_enc_seq_param(
1730 struct virgl_video_codec *codec,
1731 struct virgl_video_buffer *source,
1732 const struct virgl_h265_enc_picture_desc *desc,
1733 VAEncSequenceParameterBufferHEVC *param)
1734 {
1735 (void)codec;
1736 (void)source;
1737
1738 ITEM_SET(param, &desc->seq, general_profile_idc);
1739 ITEM_SET(param, &desc->seq, general_level_idc);
1740 ITEM_SET(param, &desc->seq, general_tier_flag);
1741 ITEM_SET(param, &desc->seq, intra_period);
1742 //intra_idr_period
1743 ITEM_SET(param, &desc->seq, ip_period);
1744 //bits_per_second
1745 ITEM_SET(param, &desc->seq, pic_width_in_luma_samples);
1746 ITEM_SET(param, &desc->seq, pic_height_in_luma_samples);
1747
1748 /* seq_fields.bits */
1749 ITEM_SET(¶m->seq_fields.bits, &desc->seq, chroma_format_idc);
1750 //seq_fields.bits.separate_colour_plane_flag
1751 ITEM_SET(¶m->seq_fields.bits, &desc->seq, bit_depth_luma_minus8);
1752 ITEM_SET(¶m->seq_fields.bits, &desc->seq, bit_depth_chroma_minus8);
1753 //seq_fields.bits.scaling_list_enabled_flag
1754 ITEM_SET(¶m->seq_fields.bits, &desc->seq, strong_intra_smoothing_enabled_flag);
1755 ITEM_SET(¶m->seq_fields.bits, &desc->seq, amp_enabled_flag);
1756 ITEM_SET(¶m->seq_fields.bits, &desc->seq, sample_adaptive_offset_enabled_flag);
1757 ITEM_SET(¶m->seq_fields.bits, &desc->seq, pcm_enabled_flag);
1758 //seq_fields.bits.pcm_loop_filter_disabled_flag
1759 ITEM_SET(¶m->seq_fields.bits, &desc->seq, sps_temporal_mvp_enabled_flag);
1760 //seq_fields.bits.low_delay_seq
1761 //seq_fields.bits.hierachical_flag
1762 //seq_fields.bits.reserved_bits
1763
1764 ITEM_SET(param, &desc->seq, log2_min_luma_coding_block_size_minus3);
1765 ITEM_SET(param, &desc->seq, log2_diff_max_min_luma_coding_block_size);
1766 ITEM_SET(param, &desc->seq, log2_min_transform_block_size_minus2);
1767 ITEM_SET(param, &desc->seq, log2_diff_max_min_transform_block_size);
1768 ITEM_SET(param, &desc->seq, max_transform_hierarchy_depth_inter);
1769 ITEM_SET(param, &desc->seq, max_transform_hierarchy_depth_intra);
1770 //pcm_sample_bit_depth_luma_minus1
1771 //pcm_sample_bit_depth_chroma_minus1
1772 //log2_min_pcm_luma_coding_block_size_minus3
1773 //log2_max_pcm_luma_coding_block_size_minus3
1774 ITEM_SET(param, &desc->seq, vui_parameters_present_flag);
1775
1776 /* vui_fields.bits */
1777 if (desc->seq.vui_parameters_present_flag) {
1778 ITEM_SET(¶m->vui_fields.bits, &desc->seq.vui_flags,
1779 aspect_ratio_info_present_flag);
1780 }
1781 //vui_fields.bits.neutral_chroma_indication_flag
1782 //vui_fields.bits.field_seq_flag
1783 if (desc->seq.vui_parameters_present_flag) {
1784 param->vui_fields.bits.vui_timing_info_present_flag =
1785 desc->seq.vui_flags.timing_info_present_flag;
1786 }
1787 //vui_fields.bits.bitstream_restriction_flag
1788 //vui_fields.bits.tiles_fixed_structure_flag
1789 //vui_fields.bits.motion_vectors_over_pic_boundaries_flag
1790 //vui_fields.bits.restricted_ref_pic_lists_flag
1791 //vui_fields.bits.log2_max_mv_length_horizontal
1792 //vui_fields.bits.log2_max_mv_length_vertical
1793
1794 if (desc->seq.vui_parameters_present_flag) {
1795 ITEM_SET(param, &desc->seq, aspect_ratio_idc);
1796 ITEM_SET(param, &desc->seq, sar_width);
1797 ITEM_SET(param, &desc->seq, sar_height);
1798 }
1799 param->vui_num_units_in_tick = desc->seq.num_units_in_tick;
1800 param->vui_time_scale = desc->seq.time_scale;
1801 //min_spatial_segmentation_idc
1802 //max_bytes_per_pic_denom
1803 //max_bits_per_min_cu_denom
1804
1805 //scc_fields.bits.palette_mode_enabled_flag
1806 }
1807
1808 /*
1809 * Refer to vlVaHandleVAEncPictureParameterBufferTypeHEVC() in mesa,
1810 * and comment out some unused parameters.
1811 */
h265_fill_enc_picture_param(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h265_enc_picture_desc * desc,VAEncPictureParameterBufferHEVC * param)1812 static void h265_fill_enc_picture_param(
1813 struct virgl_video_codec *codec,
1814 struct virgl_video_buffer *source,
1815 const struct virgl_h265_enc_picture_desc *desc,
1816 VAEncPictureParameterBufferHEVC *param)
1817 {
1818 unsigned i;
1819
1820 (void)source;
1821
1822 param->decoded_curr_pic.picture_id = get_enc_ref_pic(codec, desc->frame_num);
1823 param->decoded_curr_pic.pic_order_cnt = desc->pic_order_cnt;
1824
1825 for (i = 0; i < 15; i++) {
1826 h265_init_picture(¶m->reference_frames[i]);
1827 }
1828
1829 param->coded_buf = codec->va_coded_buf;
1830 //collocated_ref_pic_index
1831 //last_picture
1832 param->pic_init_qp = desc->rc.quant_i_frames;
1833 //diff_cu_qp_delta_depth
1834 //pps_cb_qp_offset
1835 //pps_cr_qp_offset
1836 //num_tile_columns_minus1
1837 //num_tile_rows_minus1
1838 //column_width_minus1[19]
1839 //row_height_minus1[21]
1840 ITEM_SET(param, &desc->pic, log2_parallel_merge_level_minus2);
1841 //ctu_max_bitsize_allowed
1842 param->num_ref_idx_l0_default_active_minus1 = desc->num_ref_idx_l0_active_minus1;
1843 param->num_ref_idx_l1_default_active_minus1 = desc->num_ref_idx_l1_active_minus1;
1844 //slice_pic_parameter_set_id
1845 ITEM_SET(param, &desc->pic, nal_unit_type);
1846
1847 param->pic_fields.bits.idr_pic_flag =
1848 (desc->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR);
1849 switch (desc->picture_type) {
1850 case PIPE_H2645_ENC_PICTURE_TYPE_IDR: /* fallthrough */
1851 case PIPE_H2645_ENC_PICTURE_TYPE_I:
1852 param->pic_fields.bits.coding_type = 1;
1853 break;
1854 case PIPE_H2645_ENC_PICTURE_TYPE_P:
1855 param->pic_fields.bits.coding_type = 2;
1856 break;
1857 case PIPE_H2645_ENC_PICTURE_TYPE_B:
1858 param->pic_fields.bits.coding_type = 3;
1859 break;
1860 default:
1861 break;
1862 }
1863
1864 param->pic_fields.bits.reference_pic_flag = !desc->not_referenced;
1865 //pic_fields.bits.dependent_slice_segments_enabled_flag
1866 //pic_fields.bits.sign_data_hiding_enabled_flag
1867 ITEM_SET(¶m->pic_fields.bits, &desc->pic, constrained_intra_pred_flag);
1868 ITEM_SET(¶m->pic_fields.bits, &desc->pic, transform_skip_enabled_flag);
1869 //pic_fields.bits.cu_qp_delta_enabled_flag
1870 //pic_fields.bits.weighted_pred_flag
1871 //pic_fields.bits.weighted_bipred_flag
1872 //pic_fields.bits.transquant_bypass_enabled_flag
1873 //pic_fields.bits.tiles_enabled_flag
1874 //pic_fields.bits.entropy_coding_sync_enabled_flag
1875 //pic_fields.bits.loop_filter_across_tiles_enabled_flag
1876 ITEM_SET(¶m->pic_fields.bits, &desc->pic,
1877 pps_loop_filter_across_slices_enabled_flag);
1878 //pic_fields.bits.scaling_list_data_present_flag
1879 //pic_fields.bits.screen_content_flag
1880 //pic_fields.bits.enable_gpu_weighted_prediction
1881 //pic_fields.bits.no_output_of_prior_pics_flag
1882
1883 //hierarchical_level_plus1
1884 //scc_fields.bits.pps_curr_pic_ref_enabled_flag
1885 }
1886
1887 /*
1888 * Refer to vlVaHandleVAEncSliceParameterBufferTypeHEVC() in mesa,
1889 * and comment out some unused parameters.
1890 */
h265_fill_enc_slice_param(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h265_enc_picture_desc * desc,VAEncSliceParameterBufferHEVC * param)1891 static void h265_fill_enc_slice_param(
1892 struct virgl_video_codec *codec,
1893 struct virgl_video_buffer *source,
1894 const struct virgl_h265_enc_picture_desc *desc,
1895 VAEncSliceParameterBufferHEVC *param)
1896 {
1897 unsigned i;
1898 const struct virgl_h265_slice_descriptor *sd;
1899
1900 (void)source;
1901
1902 /* Get the lastest slice descriptor */
1903 if (desc->num_slice_descriptors &&
1904 desc->num_slice_descriptors <= ARRAY_SIZE(desc->slices_descriptors)) {
1905 sd = &desc->slices_descriptors[desc->num_slice_descriptors - 1];
1906 ITEM_SET(param, sd, slice_segment_address);
1907 ITEM_SET(param, sd, num_ctu_in_slice);
1908 }
1909
1910 switch (desc->picture_type) {
1911 case PIPE_H2645_ENC_PICTURE_TYPE_P:
1912 param->slice_type = 0;
1913 break;
1914 case PIPE_H2645_ENC_PICTURE_TYPE_B:
1915 param->slice_type = 1;
1916 break;
1917 case PIPE_H2645_ENC_PICTURE_TYPE_I:
1918 case PIPE_H2645_ENC_PICTURE_TYPE_IDR: /* fall through */
1919 param->slice_type = 2;
1920 break;
1921 case PIPE_H2645_ENC_PICTURE_TYPE_SKIP:
1922 default:
1923 break;
1924 }
1925
1926 //slice_pic_parameter_set_id
1927
1928 //num_ref_idx_l0_active_minus1
1929 //num_ref_idx_l1_active_minus1
1930
1931 for (i = 0; i < 15; i++) {
1932 h265_init_picture(¶m->ref_pic_list0[i]);
1933 h265_init_picture(¶m->ref_pic_list1[i]);
1934
1935 param->ref_pic_list0[i].picture_id =
1936 get_enc_ref_pic(codec, desc->ref_idx_l0_list[i]);
1937 param->ref_pic_list1[i].picture_id =
1938 get_enc_ref_pic(codec, desc->ref_idx_l1_list[i]);
1939
1940 if (param->ref_pic_list0[i].picture_id != VA_INVALID_ID)
1941 param->ref_pic_list0[i].flags = VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE;
1942
1943 if (param->ref_pic_list1[i].picture_id != VA_INVALID_ID)
1944 param->ref_pic_list1[i].flags = VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE;
1945 }
1946
1947 //luma_log2_weight_denom
1948 //delta_chroma_log2_weight_denom
1949 //delta_luma_weight_l0[15]
1950 //luma_offset_l0[15]
1951 //delta_chroma_weight_l0[15][2]
1952 //chroma_offset_l0[15][2]
1953 //delta_luma_weight_l1[15]
1954 //luma_offset_l1[15]
1955 //delta_chroma_weight_l1[15][2]
1956 //chroma_offset_l1[15][2]
1957 ITEM_SET(param, &desc->slice, max_num_merge_cand);
1958 //slice_qp_delta
1959 ITEM_SET(param, &desc->slice, slice_cb_qp_offset);
1960 ITEM_SET(param, &desc->slice, slice_cr_qp_offset);
1961 ITEM_SET(param, &desc->slice, slice_beta_offset_div2);
1962 ITEM_SET(param, &desc->slice, slice_tc_offset_div2);
1963
1964 //slice_fields.bits.last_slice_of_pic_flag
1965 //slice_fields.bits.dependent_slice_segment_flag
1966 //slice_fields.bits.colour_plane_id
1967 //slice_fields.bits.slice_temporal_mvp_enabled_flag
1968 //slice_fields.bits.slice_sao_luma_flag
1969 //slice_fields.bits.slice_sao_chroma_flag
1970 /*
1971 * Sine num_ref_idx_l0_active_minus1 and num_ref_idx_l1_active_minus1
1972 * have been passed by VAEncPictureParameterBufferHEVC,
1973 * num_ref_idx_active_override_flag is always set to 0.
1974 */
1975 param->slice_fields.bits.num_ref_idx_active_override_flag = 0;
1976 //slice_fields.bits.mvd_l1_zero_flag
1977 ITEM_SET(¶m->slice_fields.bits, &desc->slice, cabac_init_flag);
1978 ITEM_SET(¶m->slice_fields.bits, &desc->slice,
1979 slice_deblocking_filter_disabled_flag);
1980 ITEM_SET(¶m->slice_fields.bits,
1981 &desc->slice, slice_loop_filter_across_slices_enabled_flag);
1982 //slice_fields.bits.collocated_from_l0_flag
1983
1984 //pred_weight_table_bit_offset
1985 //pred_weight_table_bit_length;
1986 }
1987
1988 /*
1989 * Refer to vlVaHandleVAEncMiscParameterTypeRateControlHEVC() in mesa,
1990 * and comment out some unused parameters.
1991 */
h265_fill_enc_misc_param_rate_ctrl(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h265_enc_picture_desc * desc,VAEncMiscParameterRateControl * param)1992 static void h265_fill_enc_misc_param_rate_ctrl(
1993 struct virgl_video_codec *codec,
1994 struct virgl_video_buffer *source,
1995 const struct virgl_h265_enc_picture_desc *desc,
1996 VAEncMiscParameterRateControl *param)
1997 {
1998 (void)codec;
1999 (void)source;
2000
2001 param->bits_per_second = desc->rc.peak_bitrate;
2002 if (desc->rc.rate_ctrl_method !=
2003 PIPE_H2645_ENC_RATE_CONTROL_METHOD_CONSTANT) {
2004 param->target_percentage = desc->rc.target_bitrate *
2005 param->bits_per_second / 100.0;
2006 }
2007 //window_size;
2008 //initial_qp;
2009 param->min_qp = desc->rc.min_qp;
2010 //basic_unit_size;
2011
2012 /* rc_flags */
2013 //rc_flags.bits.reset
2014 param->rc_flags.bits.disable_frame_skip = !desc->rc.skip_frame_enable;
2015 param->rc_flags.bits.disable_bit_stuffing = !desc->rc.fill_data_enable;
2016 //rc_flags.bits.mb_rate_control
2017 //rc_flags.bits.temporal_id
2018 //rc_flags.bits.cfs_I_frames
2019 //rc_flags.bits.enable_parallel_brc
2020 //rc_flags.bits.enable_dynamic_scaling
2021 //rc_flags.bits.frame_tolerance_mode
2022
2023 //ICQ_quality_factor;
2024 param->max_qp = desc->rc.max_qp;
2025 //quality_factor;
2026 //target_frame_size;
2027 }
2028
2029 /*
2030 * Refer to vlVaHandleVAEncMiscParameterTypeFrameRateHEVC() in mesa,
2031 * and comment out some unused parameters.
2032 */
h265_fill_enc_misc_param_frame_rate(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h265_enc_picture_desc * desc,VAEncMiscParameterFrameRate * param)2033 static void h265_fill_enc_misc_param_frame_rate(
2034 struct virgl_video_codec *codec,
2035 struct virgl_video_buffer *source,
2036 const struct virgl_h265_enc_picture_desc *desc,
2037 VAEncMiscParameterFrameRate *param)
2038 {
2039 (void)codec;
2040 (void)source;
2041
2042 param->framerate = desc->rc.frame_rate_num | (desc->rc.frame_rate_den << 16);
2043 //framerate_flags
2044 }
2045
h265_decode_bitstream(struct virgl_video_codec * codec,struct virgl_video_buffer * target,const struct virgl_h265_picture_desc * desc,unsigned num_buffers,const void * const * buffers,const unsigned * sizes)2046 static int h265_decode_bitstream(struct virgl_video_codec *codec,
2047 struct virgl_video_buffer *target,
2048 const struct virgl_h265_picture_desc *desc,
2049 unsigned num_buffers,
2050 const void * const *buffers,
2051 const unsigned *sizes)
2052 {
2053 unsigned i;
2054 int err = 0;
2055 VAStatus va_stat;
2056 VABufferID *slice_data_buf, pic_param_buf, slice_param_buf;
2057 VAPictureParameterBufferHEVC pic_param = {0};
2058 VASliceParameterBufferHEVC slice_param = {0};
2059
2060 slice_data_buf = calloc(num_buffers, sizeof(VABufferID));
2061 if (!slice_data_buf) {
2062 virgl_log("alloc slice data buffer id failed\n");
2063 return -1;
2064 }
2065
2066 h265_fill_picture_param(codec, target, desc, &pic_param);
2067 vaCreateBuffer(va_dpy, codec->va_ctx, VAPictureParameterBufferType,
2068 sizeof(pic_param), 1, &pic_param, &pic_param_buf);
2069
2070 h265_fill_slice_param(desc, &slice_param);
2071 vaCreateBuffer(va_dpy, codec->va_ctx, VASliceParameterBufferType,
2072 sizeof(slice_param), 1, &slice_param, &slice_param_buf);
2073
2074 for (i = 0; i < num_buffers; i++) {
2075 vaCreateBuffer(va_dpy, codec->va_ctx, VASliceDataBufferType,
2076 sizes[i], 1, (void *)(buffers[i]), &slice_data_buf[i]);
2077 }
2078
2079 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &pic_param_buf, 1);
2080 if (VA_STATUS_SUCCESS != va_stat) {
2081 virgl_log("render picture param failed, err = 0x%x\n", va_stat);
2082 err = -1;
2083 goto err;
2084 }
2085
2086 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &slice_param_buf, 1);
2087 if (VA_STATUS_SUCCESS != va_stat) {
2088 virgl_log("render slice param failed, err = 0x%x\n", va_stat);
2089 err = -1;
2090 goto err;
2091 }
2092
2093 for (i = 0; i < num_buffers; i++) {
2094 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &slice_data_buf[i], 1);
2095
2096 if (VA_STATUS_SUCCESS != va_stat) {
2097 virgl_log("render slice data failed, err = 0x%x\n", va_stat);
2098 err = -1;
2099 }
2100 }
2101
2102 err:
2103 vaDestroyBuffer(va_dpy, pic_param_buf);
2104 vaDestroyBuffer(va_dpy, slice_param_buf);
2105 for (i = 0; i < num_buffers; i++)
2106 vaDestroyBuffer(va_dpy, slice_data_buf[i]);
2107 free(slice_data_buf);
2108
2109 return err;
2110 }
2111
h265_encode_render_sequence(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h265_enc_picture_desc * desc)2112 static int h265_encode_render_sequence(
2113 struct virgl_video_codec *codec,
2114 struct virgl_video_buffer *source,
2115 const struct virgl_h265_enc_picture_desc *desc)
2116 {
2117 int err = 0;
2118 VAStatus va_stat;
2119 VAEncSequenceParameterBufferHEVC seq_param;
2120 VAEncMiscParameterBuffer *misc_param;
2121 VABufferID seq_param_buf, rc_param_buf, fr_param_buf;
2122
2123 memset(&seq_param, 0, sizeof(seq_param));
2124 h265_fill_enc_seq_param(codec, source, desc, &seq_param);
2125 vaCreateBuffer(va_dpy, codec->va_ctx, VAEncSequenceParameterBufferType,
2126 sizeof(seq_param), 1, &seq_param, &seq_param_buf);
2127
2128 vaCreateBuffer(va_dpy, codec->va_ctx, VAEncMiscParameterBufferType,
2129 sizeof(VAEncMiscParameterBuffer) +
2130 sizeof(VAEncMiscParameterRateControl), 1, NULL, &rc_param_buf);
2131 vaMapBuffer(va_dpy, rc_param_buf, (void **)&misc_param);
2132 misc_param->type = VAEncMiscParameterTypeRateControl;
2133 h265_fill_enc_misc_param_rate_ctrl(codec, source, desc,
2134 (VAEncMiscParameterRateControl *)misc_param->data);
2135 vaUnmapBuffer(va_dpy, rc_param_buf);
2136
2137 vaCreateBuffer(va_dpy, codec->va_ctx, VAEncMiscParameterBufferType,
2138 sizeof(VAEncMiscParameterBuffer) +
2139 sizeof(VAEncMiscParameterFrameRate), 1, NULL, &fr_param_buf);
2140 vaMapBuffer(va_dpy, fr_param_buf, (void **)&misc_param);
2141 misc_param->type = VAEncMiscParameterTypeFrameRate;
2142 h265_fill_enc_misc_param_frame_rate(codec, source, desc,
2143 (VAEncMiscParameterFrameRate *)misc_param->data);
2144 vaUnmapBuffer(va_dpy, fr_param_buf);
2145
2146 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &seq_param_buf, 1);
2147 if (VA_STATUS_SUCCESS != va_stat) {
2148 virgl_log("render h265 sequence param failed, err = 0x%x\n", va_stat);
2149 err = -1;
2150 goto error;
2151 }
2152
2153 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &rc_param_buf, 1);
2154 if (VA_STATUS_SUCCESS != va_stat) {
2155 virgl_log("render h265 rate control param failed, err = 0x%x\n", va_stat);
2156 err = -1;
2157 goto error;
2158 }
2159
2160 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &fr_param_buf, 1);
2161 if (VA_STATUS_SUCCESS != va_stat) {
2162 virgl_log("render h265 frame rate param failed, err = 0x%x\n", va_stat);
2163 err = -1;
2164 goto error;
2165 }
2166
2167 error:
2168 vaDestroyBuffer(va_dpy, seq_param_buf);
2169 vaDestroyBuffer(va_dpy, rc_param_buf);
2170 vaDestroyBuffer(va_dpy, fr_param_buf);
2171
2172 return err;
2173 }
2174
h265_encode_render_picture(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h265_enc_picture_desc * desc)2175 static int h265_encode_render_picture(
2176 struct virgl_video_codec *codec,
2177 struct virgl_video_buffer *source,
2178 const struct virgl_h265_enc_picture_desc *desc)
2179 {
2180 VAStatus va_stat;
2181 VABufferID pic_param_buf;
2182 VAEncPictureParameterBufferHEVC pic_param;
2183
2184 memset(&pic_param, 0, sizeof(pic_param));
2185 h265_fill_enc_picture_param(codec, source, desc, &pic_param);
2186 vaCreateBuffer(va_dpy, codec->va_ctx, VAEncPictureParameterBufferType,
2187 sizeof(pic_param), 1, &pic_param, &pic_param_buf);
2188
2189 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &pic_param_buf, 1);
2190 vaDestroyBuffer(va_dpy, pic_param_buf);
2191
2192 if (VA_STATUS_SUCCESS != va_stat) {
2193 virgl_log("render h265 picture param failed, err = 0x%x\n", va_stat);
2194 return -1;
2195 }
2196
2197 return 0;
2198 }
2199
h265_encode_render_slice(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h265_enc_picture_desc * desc)2200 static int h265_encode_render_slice(
2201 struct virgl_video_codec *codec,
2202 struct virgl_video_buffer *source,
2203 const struct virgl_h265_enc_picture_desc *desc)
2204 {
2205 VAStatus va_stat;
2206 VABufferID slice_param_buf;
2207 VAEncSliceParameterBufferHEVC slice_param;
2208
2209 memset(&slice_param, 0, sizeof(slice_param));
2210 h265_fill_enc_slice_param(codec, source, desc, &slice_param);
2211 vaCreateBuffer(va_dpy, codec->va_ctx, VAEncSliceParameterBufferType,
2212 sizeof(slice_param), 1, &slice_param, &slice_param_buf);
2213
2214 va_stat = vaRenderPicture(va_dpy, codec->va_ctx, &slice_param_buf, 1);
2215 vaDestroyBuffer(va_dpy, slice_param_buf);
2216
2217 if (VA_STATUS_SUCCESS != va_stat) {
2218 virgl_log("render h265 slice param failed, err = 0x%x\n", va_stat);
2219 return -1;
2220 }
2221
2222 return 0;
2223 }
2224
h265_encode_bitstream(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const struct virgl_h265_enc_picture_desc * desc)2225 static int h265_encode_bitstream(
2226 struct virgl_video_codec *codec,
2227 struct virgl_video_buffer *source,
2228 const struct virgl_h265_enc_picture_desc *desc)
2229 {
2230 if (desc->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR) {
2231 h265_encode_render_sequence(codec, source, desc);
2232 }
2233
2234 h265_encode_render_picture(codec, source, desc);
2235 h265_encode_render_slice(codec, source, desc);
2236
2237 return 0;
2238 }
2239
virgl_video_decode_bitstream(struct virgl_video_codec * codec,struct virgl_video_buffer * target,const union virgl_picture_desc * desc,unsigned num_buffers,const void * const * buffers,const unsigned * sizes)2240 int virgl_video_decode_bitstream(struct virgl_video_codec *codec,
2241 struct virgl_video_buffer *target,
2242 const union virgl_picture_desc *desc,
2243 unsigned num_buffers,
2244 const void * const *buffers,
2245 const unsigned *sizes)
2246 {
2247
2248 if (!va_dpy || !codec || !target || !desc
2249 || !num_buffers || !buffers || !sizes)
2250 return -1;
2251
2252 if (desc->base.profile != codec->profile) {
2253 virgl_log("profiles not matched, picture: %d, codec: %d\n",
2254 desc->base.profile, codec->profile);
2255 return -1;
2256 }
2257
2258 switch (codec->profile) {
2259 case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
2260 case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE:
2261 case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
2262 case PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED:
2263 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
2264 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10:
2265 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH422:
2266 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH444:
2267 return h264_decode_bitstream(codec, target, &desc->h264,
2268 num_buffers, buffers, sizes);
2269 case PIPE_VIDEO_PROFILE_HEVC_MAIN:
2270 case PIPE_VIDEO_PROFILE_HEVC_MAIN_10:
2271 case PIPE_VIDEO_PROFILE_HEVC_MAIN_STILL:
2272 case PIPE_VIDEO_PROFILE_HEVC_MAIN_12:
2273 case PIPE_VIDEO_PROFILE_HEVC_MAIN_444:
2274 return h265_decode_bitstream(codec, target, &desc->h265,
2275 num_buffers, buffers, sizes);
2276 default:
2277 break;
2278 }
2279
2280 return -1;
2281 }
2282
virgl_video_encode_bitstream(struct virgl_video_codec * codec,struct virgl_video_buffer * source,const union virgl_picture_desc * desc)2283 int virgl_video_encode_bitstream(struct virgl_video_codec *codec,
2284 struct virgl_video_buffer *source,
2285 const union virgl_picture_desc *desc)
2286 {
2287 if (!va_dpy || !codec || !source || !desc)
2288 return -1;
2289
2290 if (desc->base.profile != codec->profile) {
2291 virgl_log("profiles not matched, picture: %d, codec: %d\n",
2292 desc->base.profile, codec->profile);
2293 return -1;
2294 }
2295
2296 switch (codec->profile) {
2297 case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
2298 case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE:
2299 case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
2300 case PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED:
2301 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
2302 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10:
2303 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH422:
2304 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH444:
2305 return h264_encode_bitstream(codec, source, &desc->h264_enc);
2306 case PIPE_VIDEO_PROFILE_HEVC_MAIN:
2307 case PIPE_VIDEO_PROFILE_HEVC_MAIN_10:
2308 case PIPE_VIDEO_PROFILE_HEVC_MAIN_STILL:
2309 case PIPE_VIDEO_PROFILE_HEVC_MAIN_12:
2310 case PIPE_VIDEO_PROFILE_HEVC_MAIN_444:
2311 return h265_encode_bitstream(codec, source, &desc->h265_enc);
2312 default:
2313 break;
2314 }
2315
2316 return -1;
2317 }
2318
virgl_video_end_frame(struct virgl_video_codec * codec,struct virgl_video_buffer * target)2319 int virgl_video_end_frame(struct virgl_video_codec *codec,
2320 struct virgl_video_buffer *target)
2321 {
2322 VAStatus va_stat;
2323
2324 if (!va_dpy || !codec || !target)
2325 return -1;
2326
2327 va_stat = vaEndPicture(va_dpy, codec->va_ctx);
2328 if (VA_STATUS_SUCCESS != va_stat) {
2329 virgl_log("end picture failed, err = 0x%x\n", va_stat);
2330 return -1;
2331 }
2332
2333 va_stat = vaSyncSurface(va_dpy, target->va_sfc);
2334 if (VA_STATUS_SUCCESS != va_stat) {
2335 virgl_log("sync surface failed, err = 0x%x\n", va_stat);
2336 return -1;
2337 }
2338
2339 if (codec->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) {
2340 decode_completed(codec, target);
2341 } else {
2342 encode_completed(codec, target);
2343 }
2344
2345 return 0;
2346 }
2347
2348