xref: /aosp_15_r20/external/virglrenderer/src/virgl_video.c (revision bbecb9d118dfdb95f99bd754f8fa9be01f189df3)
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(&param->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(&param->RefPicList0[i]);
1155         h264_init_picture(&param->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(&param->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(&param->vui_fields.bits, &desc->seq.vui_flags,
1245                  aspect_ratio_info_present_flag);
1246         ITEM_SET(&param->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(&param->seq_fields.bits, &desc->seq, chroma_format_idc);
1750     //seq_fields.bits.separate_colour_plane_flag
1751     ITEM_SET(&param->seq_fields.bits, &desc->seq, bit_depth_luma_minus8);
1752     ITEM_SET(&param->seq_fields.bits, &desc->seq, bit_depth_chroma_minus8);
1753     //seq_fields.bits.scaling_list_enabled_flag
1754     ITEM_SET(&param->seq_fields.bits, &desc->seq, strong_intra_smoothing_enabled_flag);
1755     ITEM_SET(&param->seq_fields.bits, &desc->seq, amp_enabled_flag);
1756     ITEM_SET(&param->seq_fields.bits, &desc->seq, sample_adaptive_offset_enabled_flag);
1757     ITEM_SET(&param->seq_fields.bits, &desc->seq, pcm_enabled_flag);
1758     //seq_fields.bits.pcm_loop_filter_disabled_flag
1759     ITEM_SET(&param->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(&param->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(&param->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(&param->pic_fields.bits, &desc->pic, constrained_intra_pred_flag);
1868     ITEM_SET(&param->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(&param->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(&param->ref_pic_list0[i]);
1933         h265_init_picture(&param->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(&param->slice_fields.bits, &desc->slice, cabac_init_flag);
1978     ITEM_SET(&param->slice_fields.bits, &desc->slice,
1979              slice_deblocking_filter_disabled_flag);
1980     ITEM_SET(&param->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