Re: [Mesa-dev] [PATCH] st/va: use provided sizes and coords for vlVaGetImage
On 2018-10-09 04:09 PM, Ilia Mirkin wrote: On Tue, Oct 9, 2018 at 4:03 PM wrote: From: Boyuan Zhang vlVaGetImage should respect the width, height, and coordinates x and y that passed in. Therefore, pipe_box should be created with the passed in values instead of surface width/height. v2: add input size check, return error when size out of bounds Signed-off-by: Boyuan Zhang Cc: "18.2" Reviewed-by: Leo Liu --- src/gallium/state_trackers/va/image.c | 26 +++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c index 3f892c9..449ae86 100644 --- a/src/gallium/state_trackers/va/image.c +++ b/src/gallium/state_trackers/va/image.c @@ -353,6 +353,23 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y, return VA_STATUS_ERROR_INVALID_IMAGE; } + if (x < 0 || y < 0) { + mtx_unlock(>mutex); + return VA_STATUS_ERROR_INVALID_PARAMETER; + } + + if (x + width > surf->templat.width || + y + height > surf->templat.height) { + mtx_unlock(>mutex); + return VA_STATUS_ERROR_INVALID_PARAMETER; + } + + if (x + width > vaimage->width || + y + height > vaimage->height) { I believe the x/y offset is only meant for the surface, not for the image. e.g. x=100,y=100,width=100,height=100 would be able to work with a 100x100 image destination. I just checked the doc(va.h) again, it says x/y are the coordinates of the upper left source pixel. I guess "source" here means surface, so I believe you are right. Boyuan + mtx_unlock(>mutex); + return VA_STATUS_ERROR_INVALID_PARAMETER; + } + img_buf = handle_table_get(drv->htab, vaimage->buf); if (!img_buf) { mtx_unlock(>mutex); @@ -400,11 +417,14 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y, } for (i = 0; i < vaimage->num_planes; i++) { - unsigned width, height; + unsigned w = align(width, 2); + unsigned h = align(height, 2); if (!views[i]) continue; - vlVaVideoSurfaceSize(surf, i, , ); + vl_video_buffer_adjust_size(, , i, + surf->templat.chroma_format, + surf->templat.interlaced); for (j = 0; j < views[i]->texture->array_size; ++j) { - struct pipe_box box = {0, 0, j, width, height, 1}; + struct pipe_box box = {x, y, j, w, h, 1}; struct pipe_transfer *transfer; uint8_t *map; map = drv->pipe->transfer_map(drv->pipe, views[i]->texture, 0, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH] st/va: use provided sizes and coords for getimage
Thanks for the explanation ilia. I'm curious too here that if it's legal for player to not respect the image size when calling vlVaGetImage. If player already know the size of image is 100x100, then why should it still call vlVaGetImage with width/height=600? I mean when VA-API player calls to create image and create surface, it should behave itself, or will be considered a player bug. If player calls something out of range, even the driver have the size clipped(driver trying to fix player bug), but player still won't get expected stuff, since the requested size have been clipped by driver. Does this make sense? Regards, Boyuan On 2018-10-09 02:10 PM, Ilia Mirkin wrote: On Tue, Oct 9, 2018 at 1:59 PM Boyuan Zhang wrote: Hi ilia, I saw the function u_box_clip_2d(https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/auxiliary/util/u_box.h#n74). But I still don't quite understand why we need to do this? Or say, what will happen if we don't do this box clipping here? Can you provide more information about this please? Sure. Let's say you have: 1000x1000 video surface 500x500 image Then you call vlVaGetImage(surface, x=600, y=600, width=600, height=600, image) Ideally you would retrieve the 400x400 "valid" area (from 600x600 at the surface) and stick it into the image starting at 0,0. Then let's say you have 1000x1000 video surface 100x100 image Then you call vlVaGetImage(surface, x=600, y=600, width=600, height=600, image) Ideally the image would be filled with a 100x100 square from the surface starting at 600x600 and ending at 700x700. I haven't deeply dived into the VA docs. Perhaps some or all of these are illegal. In which case the x/y/w/h need to be checked and errors returned. Cheers, -ilia ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH] st/va: use provided sizes and coords for getimage
Hi ilia, I saw the function u_box_clip_2d(https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/auxiliary/util/u_box.h#n74). But I still don't quite understand why we need to do this? Or say, what will happen if we don't do this box clipping here? Can you provide more information about this please? Regards, Boyuan On 2018-10-05 12:11 PM, Ilia Mirkin wrote: This is an improvement, but I think you need to clip the box to 1. Size of the surface 2. Size of the image I think that there are clipping helpers available to do that (maybe pipe_box_clip or so? I forget, check the auxiliary dir). Christian - does that make sense to you? Cheers, -ilia On Fri, Oct 5, 2018 at 12:01 PM wrote: From: Boyuan Zhang vlVaGetImage should respect the width, height, and coordinates x and y that passed in. Therefore, pipe_box should be created with the passed in values instead of surface width/height. Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/image.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c index 3f892c9..c9f6f18 100644 --- a/src/gallium/state_trackers/va/image.c +++ b/src/gallium/state_trackers/va/image.c @@ -400,11 +400,14 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y, } for (i = 0; i < vaimage->num_planes; i++) { - unsigned width, height; + unsigned w = align(width, 2); + unsigned h = align(height, 2); if (!views[i]) continue; - vlVaVideoSurfaceSize(surf, i, , ); + vl_video_buffer_adjust_size(, , i, + surf->templat.chroma_format, + surf->templat.interlaced); for (j = 0; j < views[i]->texture->array_size; ++j) { - struct pipe_box box = {0, 0, j, width, height, 1}; + struct pipe_box box = {x, y, j, w, h, 1}; struct pipe_transfer *transfer; uint8_t *map; map = drv->pipe->transfer_map(drv->pipe, views[i]->texture, 0, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH] radeon/uvd: use bitstream coded number for symbols of Huffman tables
Patch is Reviewed-by: Boyuan Zhang On 2018-09-19 09:40 AM, Leo Liu wrote: Signed-off-by: Leo Liu Fixes: 130d1f456(radeon/uvd: reconstruct MJPEG bitstream) Cc: "18.2" --- src/gallium/drivers/radeon/radeon_uvd.c | 18 ++ 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c index 923216d77f1..a7ef4252ee0 100644 --- a/src/gallium/drivers/radeon/radeon_uvd.c +++ b/src/gallium/drivers/radeon/radeon_uvd.c @@ -1003,25 +1003,35 @@ static void get_mjpeg_slice_header(struct ruvd_decoder *dec, struct pipe_mjpeg_p size++; for (i = 0; i < 2; ++i) { + int num = 0, j; + if (pic->huffman_table.load_huffman_table[i] == 0) continue; buf[size++] = 0x00 | i; memcpy((buf + size), >huffman_table.table[i].num_dc_codes, 16); size += 16; - memcpy((buf + size), >huffman_table.table[i].dc_values, 12); - size += 12; + for (j = 0; j < 16; ++j) + num += pic->huffman_table.table[i].num_dc_codes[j]; + assert(num <= 12); + memcpy((buf + size), >huffman_table.table[i].dc_values, num); + size += num; } for (i = 0; i < 2; ++i) { + int num = 0, j; + if (pic->huffman_table.load_huffman_table[i] == 0) continue; buf[size++] = 0x10 | i; memcpy((buf + size), >huffman_table.table[i].num_ac_codes, 16); size += 16; - memcpy((buf + size), >huffman_table.table[i].ac_values, 162); - size += 162; + for (j = 0; j < 16; ++j) + num += pic->huffman_table.table[i].num_ac_codes[j]; + assert(num <= 162); + memcpy((buf + size), >huffman_table.table[i].ac_values, num); + size += num; } bs = (uint16_t*)[len_pos]; ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 12/13] winsys/amdgpu: add vcn jpeg cs support
On 2018-08-16 01:41 PM, Leo Liu wrote: On 08/16/2018 12:06 PM, boyuan.zh...@amd.com wrote: From: Boyuan Zhang Add vcn jpeg cs support, align cs by no-op. Signed-off-by: Boyuan Zhang --- src/gallium/winsys/amdgpu/drm/amdgpu_cs.c | 12 1 file changed, 12 insertions(+) diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c index a3feeb9..5092f49 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c @@ -840,6 +840,10 @@ static bool amdgpu_init_cs_context(struct amdgpu_cs_context *cs, cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_VCN_ENC; break; + case RING_VCN_JPEG: + cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_VCN_JPEG; + break; + default: case RING_GFX: cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_GFX; @@ -1545,6 +1549,14 @@ static int amdgpu_cs_flush(struct radeon_winsys_cs *rcs, while (rcs->current.cdw & 15) radeon_emit(rcs, 0x8000); /* type2 nop packet */ break; + case RING_VCN_JPEG: + if (rcs->current.cdw % 2) + assert(0); + while (rcs->current.cdw & 15) { + radeon_emit(rcs, 0x6000); /* nop packet */ + radeon_emit(rcs, 0x); + } + break; case RING_VCN_DEC: while (rcs->current.cdw & 15) radeon_emit(rcs, 0x81ff); /* nop packet */ The patch is: Reviewed-by: Leo Liu BTW, if you got chance, please fix the NOP for VCN DEC here in the same way. i.e 0x81ff and 0. Regards, Leo Sure, I will prepare a separate patch for that. Regards, Boyuan ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 07/13] st/va: get mjpeg slice header
On 2018-08-16 01:26 PM, Leo Liu wrote: On 08/16/2018 12:06 PM, boyuan.zh...@amd.com wrote: From: Boyuan Zhang Move the previous get_mjpeg_slice_header function from radeon/vcn to st/va. Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c | 3 + src/gallium/state_trackers/va/picture_mjpeg.c | 132 ++ src/gallium/state_trackers/va/va_private.h | 3 + 3 files changed, 138 insertions(+) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index f2e9ba8..d326ed4 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -293,6 +293,9 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) sizes[num_buffers++] = context->mpeg4.start_code_size; break; case PIPE_VIDEO_FORMAT_JPEG: + vlVaGetJpegSliceHeader(context); + buffers[num_buffers] = (void *)context->mjpeg.slice_header; + sizes[num_buffers++] = context->mjpeg.slice_header_size; break; default: break; diff --git a/src/gallium/state_trackers/va/picture_mjpeg.c b/src/gallium/state_trackers/va/picture_mjpeg.c index 396b743..f1292ea 100644 --- a/src/gallium/state_trackers/va/picture_mjpeg.c +++ b/src/gallium/state_trackers/va/picture_mjpeg.c @@ -114,3 +114,135 @@ void vlVaHandleSliceParameterBufferMJPEG(vlVaContext *context, vlVaBuffer *buf) context->desc.mjpeg.slice_parameter.restart_interval = mjpeg->restart_interval; context->desc.mjpeg.slice_parameter.num_mcus = mjpeg->num_mcus; } + +void vlVaGetJpegSliceHeader(vlVaContext *context) +{ + int size = 0, saved_size, len_pos, i; + uint16_t *bs; + uint8_t *p = context->mjpeg.slice_header; + + /* SOI */ + p[size++] = 0xff; + p[size++] = 0xd8; + + /* DQT */ + p[size++] = 0xff; + p[size++] = 0xdb; + + len_pos = size++; + size++; + + for (i = 0; i < 4; ++i) { + if (context->desc.mjpeg.quantization_table.load_quantiser_table[i] == 0) + continue; + + p[size++] = i; + memcpy((p + size), >desc.mjpeg.quantization_table.quantiser_table[i], 64); + size += 64; + } + + bs = (uint16_t*)[len_pos]; + *bs = util_bswap16(size - 4); + + saved_size = size; + + /* DHT */ + p[size++] = 0xff; + p[size++] = 0xc4; + + len_pos = size++; + size++; + + for (i = 0; i < 2; ++i) { + if (context->desc.mjpeg.huffman_table.load_huffman_table[i] == 0) + continue; + + p[size++] = 0x00 | i; + memcpy((p + size), >desc.mjpeg.huffman_table.table[i].num_dc_codes, 16); + size += 16; + memcpy((p + size), >desc.mjpeg.huffman_table.table[i].dc_values, 12); + size += 12; + } + + for (i = 0; i < 2; ++i) { + if (context->desc.mjpeg.huffman_table.load_huffman_table[i] == 0) + continue; + + p[size++] = 0x10 | i; + memcpy((p + size), >desc.mjpeg.huffman_table.table[i].num_ac_codes, 16); + size += 16; + memcpy((p + size), >desc.mjpeg.huffman_table.table[i].ac_values, 162); + size += 162; + } + + bs = (uint16_t*)[len_pos]; + *bs = util_bswap16(size - saved_size - 2); + + saved_size = size; + + /* DRI */ + if (context->desc.mjpeg.slice_parameter.restart_interval) { + p[size++] = 0xff; + p[size++] = 0xdd; + p[size++] = 0x00; + p[size++] = 0x04; + bs = (uint16_t*)[size++]; + *bs = util_bswap16(context->desc.mjpeg.slice_parameter.restart_interval); + saved_size = ++size; + } + + /* SOF */ + p[size++] = 0xff; + p[size++] = 0xc0; + + len_pos = size++; + size++; + + p[size++] = 0x08; + + bs = (uint16_t*)[size++]; + *bs = util_bswap16(context->desc.mjpeg.picture_parameter.picture_height); + size++; + + bs = (uint16_t*)[size++]; + *bs = util_bswap16(context->desc.mjpeg.picture_parameter.picture_width); + size++; + + p[size++] = context->desc.mjpeg.picture_parameter.num_components; + + for (i = 0; i < context->desc.mjpeg.picture_parameter.num_components; ++i) { + p[size++] = context->desc.mjpeg.picture_parameter.components[i].component_id; + p[size++] = context->desc.mjpeg.picture_parameter.components[i].h_sampling_factor << 4 | + context->desc.mjpeg.picture_parameter.components[i].v_sampling_factor; + p[size++] = context->desc.mjpeg.picture_parameter.components[i].quantiser_table_selector; + } + + bs = (uint16_t*)[len_pos]; + *bs = util_bswap16(size - saved_size - 2); + + saved_size = size; + + /* SOS */ + p[size++] = 0xff; + p[size++] = 0xda; + + len_pos = size++; + size++; + + p[size++] = context->desc.mjpeg.slice_parameter.num_components; + + for (i = 0; i < context->desc.mjpeg.slice_parameter.num_components; ++i) { + p[size++] = context->desc.mjpeg.slice_parameter.components[i].component_selector
Re: [Mesa-dev] [PATCH 06/13] radeon/vcn: add jpeg decode implementation
On 2018-08-16 01:19 PM, Leo Liu wrote: On 08/16/2018 12:06 PM, boyuan.zh...@amd.com wrote: From: Boyuan Zhang Add a new file to handle VCN Jpeg decode specific functions. Use Jpeg specific cmd sending function in end_frame call. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/Makefile.sources | 1 + src/gallium/drivers/radeon/meson.build | 1 + src/gallium/drivers/radeon/radeon_vcn_dec.c | 32 ++-- src/gallium/drivers/radeon/radeon_vcn_dec.h | 4 + src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c | 99 5 files changed, 130 insertions(+), 7 deletions(-) create mode 100644 src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c diff --git a/src/gallium/drivers/radeon/Makefile.sources b/src/gallium/drivers/radeon/Makefile.sources index f8ee860..e3ee82c 100644 --- a/src/gallium/drivers/radeon/Makefile.sources +++ b/src/gallium/drivers/radeon/Makefile.sources @@ -10,6 +10,7 @@ C_SOURCES := \ r600_texture.c \ radeon_uvd.c \ radeon_uvd.h \ + radeon_vcn_dec_jpeg.c \ radeon_vcn_dec.c \ radeon_vcn_dec.h \ radeon_vcn_enc_1_2.c \ diff --git a/src/gallium/drivers/radeon/meson.build b/src/gallium/drivers/radeon/meson.build index 582a5ff..c984a75 100644 --- a/src/gallium/drivers/radeon/meson.build +++ b/src/gallium/drivers/radeon/meson.build @@ -33,6 +33,7 @@ files_libradeon = files( 'radeon_vcn_enc_1_2.c', 'radeon_vcn_enc.c', 'radeon_vcn_enc.h', + 'radeon_vcn_dec_jpeg.c', 'radeon_vcn_dec.c', 'radeon_vcn_dec.h', 'radeon_uvd_enc_1_1.c', diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.c b/src/gallium/drivers/radeon/radeon_vcn_dec.c index 30a8952..861a40e 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeon/radeon_vcn_dec.c @@ -991,6 +991,10 @@ static unsigned calc_dpb_size(struct radeon_decoder *dec) dpb_size = MAX2(dpb_size, 30 * 1024 * 1024); break; + case PIPE_VIDEO_FORMAT_JPEG: + dpb_size = 0; + break; + default: // something is missing here assert(0); @@ -1078,6 +1082,7 @@ static void radeon_dec_decode_bitstream(struct pipe_video_codec *decoder, const unsigned *sizes) { struct radeon_decoder *dec = (struct radeon_decoder*)decoder; + enum pipe_video_format format = u_reduce_video_profile(picture->profile); unsigned i; assert(decoder); @@ -1089,6 +1094,9 @@ static void radeon_dec_decode_bitstream(struct pipe_video_codec *decoder, struct rvid_buffer *buf = >bs_buffers[dec->cur_buffer]; unsigned new_size = dec->bs_size + sizes[i]; + if (format == PIPE_VIDEO_FORMAT_JPEG) + new_size += 2; /* save for EOI */ + if (new_size > buf->res->buf->size) { dec->ws->buffer_unmap(buf->res->buf); if (!si_vid_resize_buffer(dec->screen, dec->cs, buf, new_size)) { @@ -1108,6 +1116,13 @@ static void radeon_dec_decode_bitstream(struct pipe_video_codec *decoder, dec->bs_size += sizes[i]; dec->bs_ptr += sizes[i]; } + + if (format == PIPE_VIDEO_FORMAT_JPEG) { + ((uint8_t *)dec->bs_ptr)[0] = 0xff; /* EOI */ + ((uint8_t *)dec->bs_ptr)[1] = 0xd9; + dec->bs_size += 2; + dec->bs_ptr += 2; + } Can this also be moved to ST? With handleVASliceDataBufferType() after buffers[num_buffers] = buf->data; sizes[num_buffers] = buf->size; ++num_buffers; by increasing the buffers size to 3. Regards, Leo Agree! This part should be moved to ST as well. Please see the new patches #6 #7 #8 with this changes. Regards, Boyuan } /** @@ -1270,14 +1285,14 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, } dpb_size = calc_dpb_size(dec); - - if (!si_vid_create_buffer(dec->screen, >dpb, dpb_size, PIPE_USAGE_DEFAULT)) { - RVID_ERR("Can't allocated dpb.\n"); - goto error; + if (dpb_size) { + if (!si_vid_create_buffer(dec->screen, >dpb, dpb_size, PIPE_USAGE_DEFAULT)) { + RVID_ERR("Can't allocated dpb.\n"); + goto error; + } + si_vid_clear_buffer(context, >dpb); } - si_vid_clear_buffer(context, >dpb); - if (dec->stream_type == RDECODE_CODEC_H264_PERF) { unsigned ctx_size = calc_ctx_size_h264_perf(dec); if (!si_vid_create_buffer(dec->screen, >ctx, ctx_size, PIPE_USAGE_DEFAULT)) { @@ -1304,7 +1319,10 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, next_buffer(dec); - dec->send_cmd = send_cmd_dec; + if (stream_type == RDECODE_CODEC_JPEG) + dec->send_cmd = send_cmd_jpeg; + else + dec->send_cmd = send_cmd_dec; return >base; diff --git a/src/gallium/drivers/ra
Re: [Mesa-dev] [PATCH] radeon/vcn: use enc profile instead of pic profile
On 2018-02-28 08:44 AM, Leo Liu wrote: Boyuan, please also make sure whether this patch along with other one are needed to Cc stable or not. Regards, Leo Thanks. I double checked the 18.0 and 17.3 branch, the previous hevc encode related patch sets are not in there yet. So seems we don't need to Cc stable for these patches. Regards, Boyuan On 02/28/2018 03:03 AM, Christian König wrote: Am 28.02.2018 um 00:56 schrieb boyuan.zh...@amd.com: From: Boyuan Zhang <boyuan.zh...@amd.com> Picture profile might not be set in some cases. Therefore, better to use the profile stored in encoder base. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> NAK, when the picture profile isn't set the picture structure isn't valid. Please fix the case where we forget to set the picture->profile instead. Christian. --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 4 ++-- src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c | 16 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index 388a333..dcc25f2 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -40,7 +40,7 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_picture_desc *picture) { - if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { + if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { struct pipe_h264_enc_picture_desc *pic = (struct pipe_h264_enc_picture_desc *)picture; enc->enc_pic.picture_type = pic->picture_type; enc->enc_pic.frame_num = pic->frame_num; @@ -54,7 +54,7 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_pic enc->enc_pic.crop_right = (align(enc->base.width, 16) - enc->base.width) / 2; enc->enc_pic.crop_top = 0; enc->enc_pic.crop_bottom = (align(enc->base.height, 16) - enc->base.height) / 2; - } else if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_HEVC) { + } else if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) { struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture; enc->enc_pic.picture_type = pic->picture_type; enc->enc_pic.frame_num = pic->frame_num; diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c index 07493d8..9adf40f 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c @@ -341,7 +341,7 @@ static void radeon_enc_spec_misc_hevc(struct radeon_encoder *enc, struct pipe_pi static void radeon_enc_rc_session_init(struct radeon_encoder *enc, struct pipe_picture_desc *picture) { - if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { + if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { struct pipe_h264_enc_picture_desc *pic = (struct pipe_h264_enc_picture_desc *)picture; enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rate_ctrl.vbv_buf_lv; switch(pic->rate_ctrl.rate_ctrl_method) { @@ -359,7 +359,7 @@ static void radeon_enc_rc_session_init(struct radeon_encoder *enc, struct pipe_p default: enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE; } - } else if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_HEVC) { + } else if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) { struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture; enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rc.vbv_buf_lv; switch(pic->rc.rate_ctrl_method) { @@ -387,7 +387,7 @@ static void radeon_enc_rc_session_init(struct radeon_encoder *enc, struct pipe_p static void radeon_enc_rc_layer_init(struct radeon_encoder *enc, struct pipe_picture_desc *picture) { - if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { + if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { struct pipe_h264_enc_picture_desc *pic = (struct pipe_h264_enc_picture_desc *)picture; enc->enc_pic.rc_layer_init.target_bit_rate = pic->rate_ctrl.target_bitrate; enc->enc_pic.rc_layer_init.peak_bit_rate = pic->rate_ctrl.peak_bitrate; @@ -397,7 +397,7 @@ static void radeon_enc_rc_layer_init(struct radeon_encoder *enc, struct pipe_pic enc->enc_pic.rc_layer_init.avg_target_bits_per_picture = pic->rate_ctrl.target_bits_picture; enc->enc_pic.rc_layer_init.peak_bits_per_picture_integer = pic->rate_c
Re: [Mesa-dev] [PATCH] radeon/vcn: use enc profile instead of pic profile
Agree, I added the missing profile and entry_point to st/omx. Please see the attached patch below. On radeon driver side, do you think we should still check the profile in encoder instead since profile shouldn't been changed during encoding. Or we can just leave it with picture profile with this fix? From: Boyuan Zhang <boyuan.zh...@amd.com> Profile and entry point were missing in the picture structure. Therefore, add them back. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/omx_bellagio/vid_enc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gallium/state_trackers/omx_bellagio/vid_enc.c b/src/gallium/state_trackers/omx_bellagio/vid_enc.c index 1a4fb62..162ec1f 100644 --- a/src/gallium/state_trackers/omx_bellagio/vid_enc.c +++ b/src/gallium/state_trackers/omx_bellagio/vid_enc.c @@ -1098,6 +1098,8 @@ static void enc_HandleTask(omx_base_PortType *port, struct encode_task *task, picture.picture_type = picture_type; picture.pic_order_cnt = task->pic_order_cnt; + picture.base.profile = enc_TranslateOMXProfileToPipe(priv->profile_level.eProfile); + picture.base.entry_point = PIPE_VIDEO_ENTRYPOINT_ENCODE; if (priv->restricted_b_frames && picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) picture.not_referenced = true; enc_ControlPicture(port, ); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH v2 4/8] radeon/uvd:add uvd hevc enc hw ib implementation
On 2018-02-08 05:13 PM, Mark Thompson wrote: On 06/02/18 20:05, James Zhu wrote: Implement required IBs for UVD HEVC encode. Signed-off-by: James Zhu--- src/gallium/drivers/radeon/radeon_uvd_enc_1_1.c | 1115 +++ 1 file changed, 1115 insertions(+) create mode 100644 src/gallium/drivers/radeon/radeon_uvd_enc_1_1.c diff --git a/src/gallium/drivers/radeon/radeon_uvd_enc_1_1.c b/src/gallium/drivers/radeon/radeon_uvd_enc_1_1.c new file mode 100644 index 000..17a39c2 --- /dev/null +++ b/src/gallium/drivers/radeon/radeon_uvd_enc_1_1.c @@ -0,0 +1,1115 @@ +/** + * + * Copyright 2018 Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **/ + +#include + +#include "pipe/p_video_codec.h" + +#include "util/u_video.h" +#include "util/u_memory.h" + +#include "vl/vl_video_buffer.h" +#include "radeonsi/si_pipe.h" +#include "radeon_video.h" +#include "radeon_uvd_enc.h" + +#define RADEON_ENC_CS(value) (enc->cs->current.buf[enc->cs->current.cdw++] = (value)) +#define RADEON_ENC_BEGIN(cmd) { \ + uint32_t *begin = >cs->current.buf[enc->cs->current.cdw++]; \ +RADEON_ENC_CS(cmd) +#define RADEON_ENC_READ(buf, domain, off) radeon_uvd_enc_add_buffer(enc, (buf), RADEON_USAGE_READ, (domain), (off)) +#define RADEON_ENC_WRITE(buf, domain, off) radeon_uvd_enc_add_buffer(enc, (buf), RADEON_USAGE_WRITE, (domain), (off)) +#define RADEON_ENC_READWRITE(buf, domain, off) radeon_uvd_enc_add_buffer(enc, (buf), RADEON_USAGE_READWRITE, (domain), (off)) +#define RADEON_ENC_END() *begin = (>cs->current.buf[enc->cs->current.cdw] - begin) * 4; \ + enc->total_task_size += *begin;} + +static const unsigned profiles[7] = { 66, 77, 88, 100, 110, 122, 244 }; This looks very suspicious in an H.265 file, because those are H.264 profile values... Seems that this line is copied from VCN h.264 encode. Not being used anywhere, and should be removed. @James, can you remove this line please? +static const unsigned index_to_shifts[4] = { 24, 16, 8, 0 }; + ... + +static void +radeon_uvd_enc_session_init_hevc(struct radeon_uvd_encoder *enc) +{ + enc->enc_pic.session_init.aligned_picture_width = + align(enc->base.width, 64); Do you really need to pad width to 64 rather than the MinCbSizeY? Yes, this is based on the spec as well as hardware requirement. + enc->enc_pic.session_init.aligned_picture_height = + align(enc->base.height, 16); + enc->enc_pic.session_init.padding_width = + enc->enc_pic.session_init.aligned_picture_width - enc->base.width; + enc->enc_pic.session_init.padding_height = + enc->enc_pic.session_init.aligned_picture_height - enc->base.height; + enc->enc_pic.session_init.pre_encode_mode = RENC_UVD_PREENCODE_MODE_NONE; + enc->enc_pic.session_init.pre_encode_chroma_enabled = false; + + RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_SESSION_INIT); + RADEON_ENC_CS(enc->enc_pic.session_init.aligned_picture_width); + RADEON_ENC_CS(enc->enc_pic.session_init.aligned_picture_height); + RADEON_ENC_CS(enc->enc_pic.session_init.padding_width); + RADEON_ENC_CS(enc->enc_pic.session_init.padding_height); + RADEON_ENC_CS(enc->enc_pic.session_init.pre_encode_mode); + RADEON_ENC_CS(enc->enc_pic.session_init.pre_encode_chroma_enabled); + RADEON_ENC_END(); +} + ... + +static void +radeon_uvd_enc_nalu_sps_hevc(struct radeon_uvd_encoder *enc) +{ + RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_INSERT_NALU_BUFFER); + RADEON_ENC_CS(RENC_UVD_NALU_TYPE_SPS); + uint32_t *size_in_bytes = >cs->current.buf[enc->cs->current.cdw++]; + int i; + + radeon_uvd_enc_reset(enc); + radeon_uvd_enc_set_emulation_prevention(enc, false); + radeon_uvd_enc_code_fixed_bits(enc, 0x0001, 32); +
Re: [Mesa-dev] [PATCH v2 5/8] radeon/uvd:add uvd hevc enc functions
Better to add it to Makefile.source and Meson in this patch. Other than this, this patch is Reviewed-by: Boyuan Zhang <boyuan.zh...@amd.com> On 2018-02-06 03:05 PM, James Zhu wrote: Implement UVD hevc encode functions Signed-off-by: James Zhu <james@amd.com> --- src/gallium/drivers/radeon/radeon_uvd_enc.c | 370 1 file changed, 370 insertions(+) create mode 100644 src/gallium/drivers/radeon/radeon_uvd_enc.c diff --git a/src/gallium/drivers/radeon/radeon_uvd_enc.c b/src/gallium/drivers/radeon/radeon_uvd_enc.c new file mode 100644 index 000..f162589 --- /dev/null +++ b/src/gallium/drivers/radeon/radeon_uvd_enc.c @@ -0,0 +1,370 @@ +/** + * + * Copyright 2018 Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **/ + +#include + +#include "pipe/p_video_codec.h" + +#include "util/u_video.h" +#include "util/u_memory.h" + +#include "vl/vl_video_buffer.h" + +#include "radeonsi/si_pipe.h" +#include "radeon_video.h" +#include "radeon_uvd_enc.h" + +static void +radeon_uvd_enc_get_param(struct radeon_uvd_encoder *enc, + struct pipe_h265_enc_picture_desc *pic) +{ + enc->enc_pic.picture_type = pic->picture_type; + enc->enc_pic.frame_num = pic->frame_num; + enc->enc_pic.pic_order_cnt = pic->pic_order_cnt; + enc->enc_pic.pic_order_cnt_type = pic->pic_order_cnt_type; + enc->enc_pic.ref_idx_l0 = pic->ref_idx_l0; + enc->enc_pic.ref_idx_l1 = pic->ref_idx_l1; + enc->enc_pic.not_referenced = pic->not_referenced; + enc->enc_pic.is_idr = (pic->picture_type == PIPE_H265_ENC_PICTURE_TYPE_IDR) + || (pic->picture_type == PIPE_H265_ENC_PICTURE_TYPE_I); + enc->enc_pic.crop_left = 0; + enc->enc_pic.crop_right = + (align(enc->base.width, 16) - enc->base.width) / 2; + enc->enc_pic.crop_top = 0; + enc->enc_pic.crop_bottom = + (align(enc->base.height, 16) - enc->base.height) / 2; + enc->enc_pic.general_tier_flag = pic->seq.general_tier_flag; + enc->enc_pic.general_profile_idc = pic->seq.general_profile_idc; + enc->enc_pic.general_level_idc = pic->seq.general_level_idc; + enc->enc_pic.max_poc = pic->seq.intra_period; + enc->enc_pic.log2_max_poc = 0; + for (int i = enc->enc_pic.max_poc; i != 0; enc->enc_pic.log2_max_poc++) + i = (i >> 1); + enc->enc_pic.chroma_format_idc = pic->seq.chroma_format_idc; + enc->enc_pic.pic_width_in_luma_samples = + pic->seq.pic_width_in_luma_samples; + enc->enc_pic.pic_height_in_luma_samples = + pic->seq.pic_height_in_luma_samples; + enc->enc_pic.log2_diff_max_min_luma_coding_block_size = + pic->seq.log2_diff_max_min_luma_coding_block_size; + enc->enc_pic.log2_min_transform_block_size_minus2 = + pic->seq.log2_min_transform_block_size_minus2; + enc->enc_pic.log2_diff_max_min_transform_block_size = + pic->seq.log2_diff_max_min_transform_block_size; + enc->enc_pic.max_transform_hierarchy_depth_inter = + pic->seq.max_transform_hierarchy_depth_inter; + enc->enc_pic.max_transform_hierarchy_depth_intra = + pic->seq.max_transform_hierarchy_depth_intra; + enc->enc_pic.log2_parallel_merge_level_minus2 = + pic->pic.log2_parallel_merge_level_minus2; + enc->enc_pic.bit_depth_luma_minus8 = pic->seq.bit_depth_luma_minus8; + enc->enc_pic.bit_depth_chroma_minus8 = pic->seq.bit_depth_chroma_minus8; + enc->enc_pic.nal_unit_type = pic->pic.nal_unit_type; + enc->
Re: [Mesa-dev] [PATCH v2 4/8] radeon/uvd:add uvd hevc enc hw ib implementation
Better to add it to Makefile.source and Meson in this patch. Other than this, this patch is Reviewed-by: Boyuan Zhang <boyuan.zh...@amd.com> On 2018-02-06 03:05 PM, James Zhu wrote: Implement required IBs for UVD HEVC encode. Signed-off-by: James Zhu <james@amd.com> --- src/gallium/drivers/radeon/radeon_uvd_enc_1_1.c | 1115 +++ 1 file changed, 1115 insertions(+) create mode 100644 src/gallium/drivers/radeon/radeon_uvd_enc_1_1.c diff --git a/src/gallium/drivers/radeon/radeon_uvd_enc_1_1.c b/src/gallium/drivers/radeon/radeon_uvd_enc_1_1.c new file mode 100644 index 000..17a39c2 --- /dev/null +++ b/src/gallium/drivers/radeon/radeon_uvd_enc_1_1.c @@ -0,0 +1,1115 @@ +/** + * + * Copyright 2018 Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **/ + +#include + +#include "pipe/p_video_codec.h" + +#include "util/u_video.h" +#include "util/u_memory.h" + +#include "vl/vl_video_buffer.h" +#include "radeonsi/si_pipe.h" +#include "radeon_video.h" +#include "radeon_uvd_enc.h" + +#define RADEON_ENC_CS(value) (enc->cs->current.buf[enc->cs->current.cdw++] = (value)) +#define RADEON_ENC_BEGIN(cmd) { \ + uint32_t *begin = >cs->current.buf[enc->cs->current.cdw++]; \ +RADEON_ENC_CS(cmd) +#define RADEON_ENC_READ(buf, domain, off) radeon_uvd_enc_add_buffer(enc, (buf), RADEON_USAGE_READ, (domain), (off)) +#define RADEON_ENC_WRITE(buf, domain, off) radeon_uvd_enc_add_buffer(enc, (buf), RADEON_USAGE_WRITE, (domain), (off)) +#define RADEON_ENC_READWRITE(buf, domain, off) radeon_uvd_enc_add_buffer(enc, (buf), RADEON_USAGE_READWRITE, (domain), (off)) +#define RADEON_ENC_END() *begin = (>cs->current.buf[enc->cs->current.cdw] - begin) * 4; \ + enc->total_task_size += *begin;} + +static const unsigned profiles[7] = { 66, 77, 88, 100, 110, 122, 244 }; +static const unsigned index_to_shifts[4] = { 24, 16, 8, 0 }; + +static void +radeon_uvd_enc_add_buffer(struct radeon_uvd_encoder *enc, + struct pb_buffer *buf, enum radeon_bo_usage usage, + enum radeon_bo_domain domain, signed offset) +{ + enc->ws->cs_add_buffer(enc->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED, + domain, RADEON_PRIO_VCE); + uint64_t addr; + addr = enc->ws->buffer_get_virtual_address(buf); + addr = addr + offset; + RADEON_ENC_CS(addr >> 32); + RADEON_ENC_CS(addr); +} + +static void +radeon_uvd_enc_set_emulation_prevention(struct radeon_uvd_encoder *enc, +bool set) +{ + if (set != enc->emulation_prevention) { + enc->emulation_prevention = set; + enc->num_zeros = 0; + } +} + +static void +radeon_uvd_enc_output_one_byte(struct radeon_uvd_encoder *enc, + unsigned char byte) +{ + if (enc->byte_index == 0) + enc->cs->current.buf[enc->cs->current.cdw] = 0; + enc->cs->current.buf[enc->cs->current.cdw] |= + ((unsigned int) (byte) << index_to_shifts[enc->byte_index]); + enc->byte_index++; + + if (enc->byte_index >= 4) { + enc->byte_index = 0; + enc->cs->current.cdw++; + } +} + +static void +radeon_uvd_enc_emulation_prevention(struct radeon_uvd_encoder *enc, +unsigned char byte) +{ + if (enc->emulation_prevention) { + if ((enc->num_zeros >= 2) + && ((byte == 0x00) || (byte == 0x01) || (byte == 0x03))) { + radeon_uvd_enc_output_o
Re: [Mesa-dev] [PATCH v2 3/8] radeon/uvd:add uvd hevc enc hw interface header
Better to add it to Makefile.source and Meson in this patch. Other than this, this patch is Reviewed-by: Boyuan Zhang <boyuan.zh...@amd.com> On 2018-02-06 03:05 PM, James Zhu wrote: Add hevc encode hardware interface for UVD Signed-off-by: James Zhu <james@amd.com> --- src/gallium/drivers/radeon/radeon_uvd_enc.h | 471 1 file changed, 471 insertions(+) create mode 100644 src/gallium/drivers/radeon/radeon_uvd_enc.h diff --git a/src/gallium/drivers/radeon/radeon_uvd_enc.h b/src/gallium/drivers/radeon/radeon_uvd_enc.h new file mode 100644 index 000..1cca0d2 --- /dev/null +++ b/src/gallium/drivers/radeon/radeon_uvd_enc.h @@ -0,0 +1,471 @@ +/** + * + * Copyright 2018 Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **/ + +#ifndef _RADEON_UVD_ENC_H +#define _RADEON_UVD_ENC_H + +#define RENC_UVD_FW_INTERFACE_MAJOR_VERSION 1 +#define RENC_UVD_FW_INTERFACE_MINOR_VERSION 1 + +#define RENC_UVD_IB_PARAM_SESSION_INFO 0x0001 +#define RENC_UVD_IB_PARAM_TASK_INFO 0x0002 +#define RENC_UVD_IB_PARAM_SESSION_INIT 0x0003 +#define RENC_UVD_IB_PARAM_LAYER_CONTROL 0x0004 +#define RENC_UVD_IB_PARAM_LAYER_SELECT 0x0005 +#define RENC_UVD_IB_PARAM_SLICE_CONTROL 0x0006 +#define RENC_UVD_IB_PARAM_SPEC_MISC 0x0007 +#define RENC_UVD_IB_PARAM_RATE_CONTROL_SESSION_INIT 0x0008 +#define RENC_UVD_IB_PARAM_RATE_CONTROL_LAYER_INIT 0x0009 +#define RENC_UVD_IB_PARAM_RATE_CONTROL_PER_PICTURE 0x000a +#define RENC_UVD_IB_PARAM_SLICE_HEADER 0x000b +#define RENC_UVD_IB_PARAM_ENCODE_PARAMS 0x000c +#define RENC_UVD_IB_PARAM_QUALITY_PARAMS0x000d +#define RENC_UVD_IB_PARAM_DEBLOCKING_FILTER 0x000e +#define RENC_UVD_IB_PARAM_INTRA_REFRESH 0x000f +#define RENC_UVD_IB_PARAM_ENCODE_CONTEXT_BUFFER 0x0010 +#define RENC_UVD_IB_PARAM_VIDEO_BITSTREAM_BUFFER0x0011 +#define RENC_UVD_IB_PARAM_FEEDBACK_BUFFER 0x0012 +#define RENC_UVD_IB_PARAM_INSERT_NALU_BUFFER0x0013 +#define RENC_UVD_IB_PARAM_FEEDBACK_BUFFER_ADDITIONAL0x0014 + +#define RENC_UVD_IB_OP_INITIALIZE 0x0801 +#define RENC_UVD_IB_OP_CLOSE_SESSION0x0802 +#define RENC_UVD_IB_OP_ENCODE 0x0803 +#define RENC_UVD_IB_OP_INIT_RC 0x0804 +#define RENC_UVD_IB_OP_INIT_RC_VBV_BUFFER_LEVEL 0x0805 +#define RENC_UVD_IB_OP_SET_SPEED_ENCODING_MODE 0x0806 +#define RENC_UVD_IB_OP_SET_BALANCE_ENCODING_MODE0x0807 +#define RENC_UVD_IB_OP_SET_QUALITY_ENCODING_MODE0x0808 + +#define RENC_UVD_IF_MAJOR_VERSION_MASK 0x +#define RENC_UVD_IF_MAJOR_VERSION_SHIFT 16 +#define RENC_UVD_IF_MINOR_VERSION_MASK 0x +#define RENC_UVD_IF_MINOR_VERSION_SHIFT 0 + +#define RENC_UVD_PREENCODE_MODE_NONE0x +#define RENC_UVD_PREENCODE_MODE_1X 0x0001 +#define RENC_UVD_PREENCODE_MODE_2X 0x0002 +#define RENC_UVD_PREENCODE_MODE_4X 0x0004 + +#define RENC_UVD_SLICE_CONTROL_MODE_FIXED_CTBS 0x +#define RENC_UVD_SLICE_CONTROL_MODE_FIXED_BITS 0x0001 + +#define RENC_UVD_RATE_CONTROL_METHOD_NONE 0x +#define RENC_UVD_RATE_CONTROL_METHOD_LATENCY_CONSTR
Re: [Mesa-dev] [PATCH v2 7/8] radeonsi:create uvd hevc enc entry
This patch is Reviewed-by: Boyuan Zhang <boyuan.zh...@amd.com> On 2018-02-06 03:05 PM, James Zhu wrote: Add UVD hevc encode pipe video codec creation entry Signed-off-by: James Zhu <james@amd.com> --- src/gallium/drivers/radeonsi/si_uvd.c | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_uvd.c b/src/gallium/drivers/radeonsi/si_uvd.c index 64f2f8e..3906bbd 100644 --- a/src/gallium/drivers/radeonsi/si_uvd.c +++ b/src/gallium/drivers/radeonsi/si_uvd.c @@ -31,6 +31,8 @@ #include "radeon/radeon_vce.h" #include "radeon/radeon_vcn_dec.h" #include "radeon/radeon_vcn_enc.h" +#include "radeon/radeon_uvd_enc.h" +#include "util/u_video.h" /** * creates an video buffer with an UVD compatible memory layout @@ -146,9 +148,16 @@ struct pipe_video_codec *si_uvd_create_decoder(struct pipe_context *context, struct si_context *ctx = (struct si_context *)context; bool vcn = (ctx->b.family == CHIP_RAVEN) ? true : false; - if (templ->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) - return (vcn) ? radeon_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer) : - si_vce_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); + if (templ->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + if (vcn) { + radeon_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); + } else { + if (u_reduce_video_profile(templ->profile) == PIPE_VIDEO_FORMAT_HEVC) + return radeon_uvd_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); + else + return si_vce_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); + } + } return (vcn) ? radeon_create_decoder(context, templ) : si_common_uvd_create_decoder(context, templ, si_uvd_set_dtb); ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 8/8] drivers/radeonsi: enable uvd encode for HEVC main
this patch is Reviewed-by: Boyuan Zhang <boyuan.zh...@amd.com> On 2018-02-05 12:16 PM, James Zhu wrote: Enable UVD encode for HEVC main profile Signed-off-by: James Zhu <james@amd.com> --- src/gallium/drivers/radeonsi/si_get.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeonsi/si_get.c b/src/gallium/drivers/radeonsi/si_get.c index 8002362..64f76b4 100644 --- a/src/gallium/drivers/radeonsi/si_get.c +++ b/src/gallium/drivers/radeonsi/si_get.c @@ -24,6 +24,7 @@ #include "si_pipe.h" #include "radeon/radeon_video.h" #include "radeon/radeon_vce.h" +#include "radeon/radeon_uvd_enc.h" #include "ac_llvm_util.h" #include "vl/vl_decoder.h" #include "vl/vl_video_buffer.h" @@ -587,7 +588,8 @@ static int si_get_video_param(struct pipe_screen *screen, (si_vce_is_fw_version_supported(sscreen) || sscreen->info.family == CHIP_RAVEN)) || (profile == PIPE_VIDEO_PROFILE_HEVC_MAIN && - sscreen->info.family == CHIP_RAVEN); + (sscreen->info.family == CHIP_RAVEN || + si_radeon_uvd_enc_supported(sscreen))); case PIPE_VIDEO_CAP_NPOT_TEXTURES: return 1; case PIPE_VIDEO_CAP_MAX_WIDTH: ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 5/8] drivers/radeon:add uvd hevc enc functions
On 2018-02-05 02:41 PM, James Zhu wrote: Implement UVD hevc encode functions Signed-off-by: James Zhu--- src/gallium/drivers/radeon/radeon_uvd_enc.c | 340 1 file changed, 340 insertions(+) create mode 100644 src/gallium/drivers/radeon/radeon_uvd_enc.c diff --git a/src/gallium/drivers/radeon/radeon_uvd_enc.c b/src/gallium/drivers/radeon/radeon_uvd_enc.c new file mode 100644 index 000..6eb6cda --- /dev/null +++ b/src/gallium/drivers/radeon/radeon_uvd_enc.c @@ -0,0 +1,340 @@ +/** + * + * Copyright 2018 Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **/ + +#include + +#include "pipe/p_video_codec.h" + +#include "util/u_video.h" +#include "util/u_memory.h" + +#include "vl/vl_video_buffer.h" + +#include "radeonsi/si_pipe.h" +#include "radeon_video.h" +#include "radeon_uvd_enc.h" + +static void radeon_uvd_enc_get_param(struct radeon_uvd_encoder *enc, struct pipe_h265_enc_picture_desc *picture) +{ + struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture; This line is unnecessary. Same type on both sides. + enc->enc_pic.picture_type = pic->picture_type; + enc->enc_pic.frame_num = pic->frame_num; + enc->enc_pic.pic_order_cnt = pic->pic_order_cnt; + enc->enc_pic.pic_order_cnt_type = pic->pic_order_cnt_type; + enc->enc_pic.ref_idx_l0 = pic->ref_idx_l0; + enc->enc_pic.ref_idx_l1 = pic->ref_idx_l1; + enc->enc_pic.not_referenced = pic->not_referenced; + enc->enc_pic.is_idr = (pic->picture_type == PIPE_H265_ENC_PICTURE_TYPE_IDR) || +(pic->picture_type == PIPE_H265_ENC_PICTURE_TYPE_I); + enc->enc_pic.crop_left = 0; + enc->enc_pic.crop_right = (align(enc->base.width, 16) - enc->base.width) / 2; + enc->enc_pic.crop_top = 0; + enc->enc_pic.crop_bottom = (align(enc->base.height, 16) - enc->base.height) / 2; + enc->enc_pic.general_tier_flag = pic->seq.general_tier_flag; + enc->enc_pic.general_profile_idc = pic->seq.general_profile_idc; + enc->enc_pic.general_level_idc = pic->seq.general_level_idc; + enc->enc_pic.max_poc = pic->seq.intra_period; + enc->enc_pic.log2_max_poc = 0; + for (int i = enc->enc_pic.max_poc; i != 0; enc->enc_pic.log2_max_poc++) + i = (i >> 1); + enc->enc_pic.chroma_format_idc = pic->seq.chroma_format_idc; + enc->enc_pic.pic_width_in_luma_samples = pic->seq.pic_width_in_luma_samples; + enc->enc_pic.pic_height_in_luma_samples = pic->seq.pic_height_in_luma_samples; + enc->enc_pic.log2_diff_max_min_luma_coding_block_size = pic->seq.log2_diff_max_min_luma_coding_block_size; + enc->enc_pic.log2_min_transform_block_size_minus2 = pic->seq.log2_min_transform_block_size_minus2; + enc->enc_pic.log2_diff_max_min_transform_block_size = pic->seq.log2_diff_max_min_transform_block_size; + enc->enc_pic.max_transform_hierarchy_depth_inter = pic->seq.max_transform_hierarchy_depth_inter; + enc->enc_pic.max_transform_hierarchy_depth_intra = pic->seq.max_transform_hierarchy_depth_intra; + enc->enc_pic.log2_parallel_merge_level_minus2 = pic->pic.log2_parallel_merge_level_minus2; + enc->enc_pic.bit_depth_luma_minus8 = pic->seq.bit_depth_luma_minus8; + enc->enc_pic.bit_depth_chroma_minus8 = pic->seq.bit_depth_chroma_minus8; + enc->enc_pic.nal_unit_type = pic->pic.nal_unit_type; + enc->enc_pic.max_num_merge_cand = pic->slice.max_num_merge_cand; + enc->enc_pic.sample_adaptive_offset_enabled_flag = pic->seq.sample_adaptive_offset_enabled_flag; + enc->enc_pic.pcm_enabled_flag = pic->seq.pcm_enabled_flag; +
Re: [Mesa-dev] [PATCH 2/8] amdgpu/drm:add uvd hevc enc support in amdgpu cs
On 2018-02-05 12:16 PM, James Zhu wrote: Signed-off-by: James Zhu <james@amd.com> --- src/gallium/winsys/amdgpu/drm/amdgpu_cs.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c index 1927a3a..6f305b7 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c @@ -376,6 +376,7 @@ static bool amdgpu_cs_has_user_fence(struct amdgpu_cs_context *cs) { return cs->ib[IB_MAIN].ip_type != AMDGPU_HW_IP_UVD && cs->ib[IB_MAIN].ip_type != AMDGPU_HW_IP_VCE && + cs->ib[IB_MAIN].ip_type != AMDGPU_HW_IP_UVD_ENC && cs->ib[IB_MAIN].ip_type != AMDGPU_HW_IP_VCN_DEC && cs->ib[IB_MAIN].ip_type != AMDGPU_HW_IP_VCN_ENC; } @@ -818,6 +819,10 @@ static bool amdgpu_init_cs_context(struct amdgpu_cs_context *cs, cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_UVD; break; + case RING_UVD_ENC: + cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_UVD_ENC; + break; + Please follow previous indentation, use space instead of tab here. Also, the patch name might better be changed to winsys/amdgpu. With those fixed, this patch is Reviewed-by: Boyuan Zhang <boyuan.zh...@amd.com> Thanks, Boyuan case RING_VCE: cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_VCE; break; @@ -1533,6 +1538,7 @@ static int amdgpu_cs_flush(struct radeon_winsys_cs *rcs, ws->gfx_ib_size_counter += (rcs->prev_dw + rcs->current.cdw) * 4; break; case RING_UVD: + case RING_UVD_ENC: while (rcs->current.cdw & 15) radeon_emit(rcs, 0x8000); /* type2 nop packet */ break; ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 1/8] amd/common:add uvd hevc enc support check in hw query
On 2018-02-05 12:16 PM, James Zhu wrote: Based on amdgpu hardware query information to check if UVD hevc enc support Signed-off-by: James Zhu <james@amd.com> --- src/amd/common/ac_gpu_info.c | 10 +- src/amd/common/ac_gpu_info.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/amd/common/ac_gpu_info.c b/src/amd/common/ac_gpu_info.c index 6d9dcb5..2494967 100644 --- a/src/amd/common/ac_gpu_info.c +++ b/src/amd/common/ac_gpu_info.c @@ -98,7 +98,7 @@ bool ac_query_gpu_info(int fd, amdgpu_device_handle dev, { struct amdgpu_buffer_size_alignments alignment_info = {}; struct amdgpu_heap_info vram, vram_vis, gtt; - struct drm_amdgpu_info_hw_ip dma = {}, compute = {}, uvd = {}, vce = {}, vcn_dec = {}, vcn_enc = {}; + struct drm_amdgpu_info_hw_ip dma = {}, compute = {}, uvd = {}, uvd_enc = {}, vce = {}, vcn_dec = {}, vcn_enc = {}; uint32_t vce_version = 0, vce_feature = 0, uvd_version = 0, uvd_feature = 0; int r, i, j; drmDevicePtr devinfo; @@ -166,6 +166,12 @@ bool ac_query_gpu_info(int fd, amdgpu_device_handle dev, return false; } + r = amdgpu_query_hw_ip_info(dev, AMDGPU_HW_IP_UVD_ENC, 0, _enc); + if (r) { + fprintf(stderr, "amdgpu: amdgpu_query_hw_ip_info(uvd_enc) failed.\n"); + return false; + } + if (info->drm_major == 3 && info->drm_minor >= 17) { r = amdgpu_query_hw_ip_info(dev, AMDGPU_HW_IP_VCN_DEC, 0, _dec); if (r) { @@ -275,6 +281,8 @@ bool ac_query_gpu_info(int fd, amdgpu_device_handle dev, uvd.available_rings ? uvd_version : 0; info->vce_fw_version = vce.available_rings ? vce_version : 0; + info->uvd_enc_supported = + uvd_enc.available_rings ? true : false; info->has_userptr = true; info->has_syncobj = has_syncobj(fd); info->has_syncobj_wait_for_submit = info->has_syncobj && info->drm_minor >= 20; diff --git a/src/amd/common/ac_gpu_info.h b/src/amd/common/ac_gpu_info.h index cca3e98..6b120d1 100644 --- a/src/amd/common/ac_gpu_info.h +++ b/src/amd/common/ac_gpu_info.h @@ -65,6 +65,7 @@ struct radeon_info { uint32_tnum_compute_rings; uint32_tuvd_fw_version; uint32_tvce_fw_version; + booluvd_enc_supported; White space/tab length seems not correct here. With that fixed, this patch is Reviewed-by: Boyuan Zhang <boyuan.zh...@amd.com> Thanks, Boyuan uint32_tme_fw_version; uint32_tme_fw_feature; uint32_tpfp_fw_version; ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 7/8] drivers/radeonsi:create uvd hevc enc entry
On 2018-02-05 12:16 PM, James Zhu wrote: Add UVD hevc encode pipe video codec creation entry Signed-off-by: James Zhu--- src/gallium/drivers/radeonsi/si_uvd.c | 13 + 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_uvd.c b/src/gallium/drivers/radeonsi/si_uvd.c index 64f2f8e..fa43a96 100644 --- a/src/gallium/drivers/radeonsi/si_uvd.c +++ b/src/gallium/drivers/radeonsi/si_uvd.c @@ -31,7 +31,8 @@ #include "radeon/radeon_vce.h" #include "radeon/radeon_vcn_dec.h" #include "radeon/radeon_vcn_enc.h" - +#include "radeon/radeon_uvd_enc.h" +#include "util/u_video.h" Could you add back the blank line please? /** * creates an video buffer with an UVD compatible memory layout */ @@ -146,9 +147,13 @@ struct pipe_video_codec *si_uvd_create_decoder(struct pipe_context *context, struct si_context *ctx = (struct si_context *)context; bool vcn = (ctx->b.family == CHIP_RAVEN) ? true : false; - if (templ->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) - return (vcn) ? radeon_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer) : - si_vce_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); + if (templ->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + if (u_reduce_video_profile(templ->profile) == PIPE_VIDEO_FORMAT_HEVC) { + return (vcn) ? radeon_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer) : + radeon_uvd_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); + } else + return si_vce_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); + } It seems that this change will break the original logic for vcn h.264 encode case, please fix it. Thanks, Boyuan return (vcn) ? radeon_create_decoder(context, templ) : si_common_uvd_create_decoder(context, templ, si_uvd_set_dtb); ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 1/2] st/va: enable dual instances encode by sync surface
This patch improves the performance of Vaapi Encode by enabling dual instances encoding. flush function is not called after each end_frame call. radeon/vce will do flush whenever 2 frames are submitted for encoding. Implement sync surface function to flush only if the frame hasn't been flushed yet. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> Reviewed-by: Christian König <christian.koe...@amd.com> --- src/gallium/state_trackers/va/picture.c| 12 --- src/gallium/state_trackers/va/surface.c| 32 ++ src/gallium/state_trackers/va/va_private.h | 5 + 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index b187452..87567be 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -62,6 +62,8 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende if (!surf || !surf->buffer) return VA_STATUS_ERROR_INVALID_SURFACE; + context->target_id = render_target; + surf->ctx = context_id; context->target = surf->buffer; if (!context->decoder) { @@ -536,6 +538,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) vlVaDriver *drv; vlVaContext *context; vlVaBuffer *coded_buf; + vlVaSurface *surf; unsigned int coded_size; void *feedback; @@ -560,6 +563,8 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) return VA_STATUS_SUCCESS; } + pipe_mutex_lock(drv->mutex); + surf = handle_table_get(drv->htab, context->target_id); context->mpeg4.frame_num++; if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { @@ -568,13 +573,14 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) context->decoder->begin_frame(context->decoder, context->target, >desc.base); context->decoder->encode_bitstream(context->decoder, context->target, coded_buf->derived_surface.resource, ); + surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; + surf->feedback = feedback; + surf->coded_buf = coded_buf; context->decoder->end_frame(context->decoder, context->target, >desc.base); - context->decoder->flush(context->decoder); - context->decoder->get_feedback(context->decoder, feedback, _size); - coded_buf->coded_size = coded_size; } else context->decoder->end_frame(context->decoder, context->target, >desc.base); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c index 63727b6..012e48e 100644 --- a/src/gallium/state_trackers/va/surface.c +++ b/src/gallium/state_trackers/va/surface.c @@ -91,9 +91,41 @@ vlVaDestroySurfaces(VADriverContextP ctx, VASurfaceID *surface_list, int num_sur VAStatus vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target) { + vlVaDriver *drv; + vlVaContext *context; + vlVaSurface *surf; + void *pbuff; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + pipe_mutex_lock(drv->mutex); + surf = handle_table_get(drv->htab, render_target); + + if (!surf || !surf->buffer) + return VA_STATUS_ERROR_INVALID_SURFACE; + + context = handle_table_get(drv->htab, surf->ctx); + if (!context) { + pipe_mutex_unlock(drv->mutex); + return VA_STATUS_ERROR_INVALID_CONTEXT; + } + + if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + int frame_diff; + if (context->desc.h264enc.frame_num_cnt > surf->frame_num_cnt) + frame_diff = context->desc.h264enc.frame_num_cnt - surf->frame_num_cnt; + else + frame_diff = 0x - surf->frame_num_cnt + 1 + context->desc.h264enc.frame_num_cnt; + if (frame_diff < 2) + context->decoder->flush(context->decoder); + context->decoder->get_feedback(context->decoder, surf->feedback, &(surf->coded_buf->coded_size)); + } + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index 6d3ac38..bfcea6d 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -243,6 +243,7 @@ typedef struct { struct vl_deint_filter *deint; struct vlVaBuffer *coded_buf; + int target_id; } vlVaContext; typedef struct { @@ -268,6 +269,10 @@ typedef struct { typedef struct { struct pipe_video_buffer templat, *buffer; struct util_dynarray subpics; /*
[Mesa-dev] [PATCH 2/2] radeon/vce: set flag based on dual instance enablement
Set the flag on when dual instance encoding is supported, otherwise set it to off Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/drivers/radeon/radeon_vce_52.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vce_52.c b/src/gallium/drivers/radeon/radeon_vce_52.c index 136f080..5db01fe 100644 --- a/src/gallium/drivers/radeon/radeon_vce_52.c +++ b/src/gallium/drivers/radeon/radeon_vce_52.c @@ -158,13 +158,15 @@ void radeon_vce_52_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_pict enc->enc_pic.ref_idx_l0 = pic->ref_idx_l0; enc->enc_pic.ref_idx_l1 = pic->ref_idx_l1; enc->enc_pic.not_referenced = pic->not_referenced; - enc->enc_pic.addrmode_arraymode_disrdo_distwoinstants = pic->ref_pic_mode; + if (enc->dual_inst) + enc->enc_pic.addrmode_arraymode_disrdo_distwoinstants = 0x0201; + else + enc->enc_pic.addrmode_arraymode_disrdo_distwoinstants = 0x01000201; enc->enc_pic.is_idr = pic->is_idr; } static void create(struct rvce_encoder *enc) { - enc->enc_pic.addrmode_arraymode_disrdo_distwoinstants = 0x0201; enc->task_info(enc, 0x, 0, 0, 0); RVCE_BEGIN(0x0101); // create cmd -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 6/9] st/va: add preset values for VAAPI encode
Add some hardcoded values hardware needs mainly for rate control purpose. With previously hardcoded values for OMX, the rate control result is not correct. This change fixed the rate control result by setting correct values for Vaapi. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/picture.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 4bb60f2..4abf155 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -95,6 +95,32 @@ vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id, *ref_frame = NULL; } +static void +getEncParamPreset(vlVaContext *context) +{ + //motion estimation preset + context->desc.h264enc.motion_est.motion_est_quarter_pixel = 0x0001; + context->desc.h264enc.motion_est.lsmvert = 0x0002; + context->desc.h264enc.motion_est.enc_disable_sub_mode = 0x0078; + context->desc.h264enc.motion_est.enc_en_ime_overw_dis_subm = 0x0001; + context->desc.h264enc.motion_est.enc_ime_overw_dis_subm_no = 0x0001; + context->desc.h264enc.motion_est.enc_ime2_search_range_x = 0x0004; + context->desc.h264enc.motion_est.enc_ime2_search_range_y = 0x0004; + + //pic control preset + context->desc.h264enc.pic_ctrl.enc_cabac_enable = 0x0001; + context->desc.h264enc.pic_ctrl.enc_constraint_set_flags = 0x0040; + + //rate control + context->desc.h264enc.rate_ctrl.vbv_buffer_size = 2000; + context->desc.h264enc.rate_ctrl.vbv_buf_lv = 48; + context->desc.h264enc.rate_ctrl.fill_data_enable = 1; + context->desc.h264enc.rate_ctrl.enforce_hrd = 1; + context->desc.h264enc.enable_vui = false; + + context->desc.h264enc.ref_pic_mode = 0x0201; +} + static VAStatus handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) { @@ -524,6 +550,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { coded_buf = context->coded_buf; + getEncParamPreset(context); context->decoder->begin_frame(context->decoder, context->target, >desc.base); context->decoder->encode_bitstream(context->decoder, context->target, coded_buf->derived_surface.resource, ); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 3/9] st/va: add conversion for yv12 to nv12in putimage
For putimage call, if image format is yv12 (or IYUV with U V field swap) and surface format is nv12, then we need to convert yv12 to nv12 and then copy the converted data from image to surface. We can't use the existing logic where surface is destroyed and re-created with yv12 format. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/image.c | 33 ++--- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c index 1b956e3..d966cde 100644 --- a/src/gallium/state_trackers/va/image.c +++ b/src/gallium/state_trackers/va/image.c @@ -471,7 +471,9 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, return VA_STATUS_ERROR_OPERATION_FAILED; } - if (format != surf->buffer->buffer_format) { + if ((format != surf->buffer->buffer_format) && + ((format != PIPE_FORMAT_YV12) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12)) && + ((format != PIPE_FORMAT_IYUV) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12))) { struct pipe_video_buffer *tmp_buf; struct pipe_video_buffer templat = surf->templat; @@ -513,12 +515,29 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, unsigned width, height; if (!views[i]) continue; vlVaVideoSurfaceSize(surf, i, , ); - for (j = 0; j < views[i]->texture->array_size; ++j) { - struct pipe_box dst_box = {0, 0, j, width, height, 1}; - drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0, -PIPE_TRANSFER_WRITE, _box, -data[i] + pitches[i] * j, -pitches[i] * views[i]->texture->array_size, 0); + if ((format == PIPE_FORMAT_YV12) || (format == PIPE_FORMAT_IYUV) && +(surf->buffer->buffer_format == PIPE_FORMAT_NV12)) { + struct pipe_transfer *transfer = NULL; + uint8_t *map = NULL; + struct pipe_box dst_box_1 = {0, 0, 0, width, height, 1}; + map = drv->pipe->transfer_map(drv->pipe, + views[i]->texture, + 0, + PIPE_TRANSFER_DISCARD_RANGE, + _box_1, ); + if (map == NULL) +return VA_STATUS_ERROR_OPERATION_FAILED; + + u_copy_yv12_img_to_nv12_surf (data, map, width, height, pitches[i], transfer->stride, i); + pipe_transfer_unmap(drv->pipe, transfer); + } else { + for (j = 0; j < views[i]->texture->array_size; ++j) { +struct pipe_box dst_box = {0, 0, j, width, height, 1}; +drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0, + PIPE_TRANSFER_WRITE, _box, + data[i] + pitches[i] * j, + pitches[i] * views[i]->texture->array_size, 0); + } } } pipe_mutex_unlock(drv->mutex); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 4/9] st/va: get rate control method from configattrib
Rate control method is passed from app to driver through config attrib list. That is why we need to store this rate control method to config. And later on, we will pass this value to context->desc.h264enc.rate_ctrl.rate_ctrl_method. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 11 +++ src/gallium/state_trackers/va/context.c| 2 ++ src/gallium/state_trackers/va/va_private.h | 1 + 3 files changed, 14 insertions(+) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 3aacc63..be151c8 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -176,6 +176,17 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin config->profile = p; + for (int i = 0; i rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT; + else if (attrib_list[i].value == VA_RC_VBR) +config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE; + else +config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE; + } + } + pipe_mutex_lock(drv->mutex); *config_id = handle_table_add(drv->htab, config); pipe_mutex_unlock(drv->mutex); diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index 8882cba..65ba7db 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -276,6 +276,8 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, context->desc.base.profile = config->profile; context->desc.base.entry_point = config->entrypoint; + if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) + context->desc.h264enc.rate_ctrl.rate_ctrl_method = config->rc; pipe_mutex_lock(drv->mutex); *context_id = handle_table_add(drv->htab, context); diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index 723983d..ad9010a 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -246,6 +246,7 @@ typedef struct { typedef struct { VAEntrypoint entrypoint; enum pipe_video_profile profile; + enum pipe_h264_enc_rate_control_method rc; } vlVaConfig; typedef struct { -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 5/9] st/va: add functions for VAAPI encode
Add necessary functions/changes for VAAPI encoding to buffer and picture. These changes will allow driver to handle all Vaapi encode related operations. This patch doesn't change the Vaapi decode behaviour. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/buffer.c | 6 + src/gallium/state_trackers/va/picture.c| 172 - src/gallium/state_trackers/va/va_private.h | 3 + 3 files changed, 179 insertions(+), 2 deletions(-) diff --git a/src/gallium/state_trackers/va/buffer.c b/src/gallium/state_trackers/va/buffer.c index 7d3167b..dfcebbe 100644 --- a/src/gallium/state_trackers/va/buffer.c +++ b/src/gallium/state_trackers/va/buffer.c @@ -133,6 +133,12 @@ vlVaMapBuffer(VADriverContextP ctx, VABufferID buf_id, void **pbuff) if (!buf->derived_surface.transfer || !*pbuff) return VA_STATUS_ERROR_INVALID_BUFFER; + if (buf->type == VAEncCodedBufferType) { + ((VACodedBufferSegment*)buf->data)->buf = *pbuff; + ((VACodedBufferSegment*)buf->data)->size = buf->coded_size; + ((VACodedBufferSegment*)buf->data)->next = NULL; + *pbuff = buf->data; + } } else { pipe_mutex_unlock(drv->mutex); *pbuff = buf->data; diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 89ac024..4bb60f2 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -78,7 +78,8 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende return VA_STATUS_SUCCESS; } - context->decoder->begin_frame(context->decoder, context->target, >desc.base); + if (context->decoder->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) + context->decoder->begin_frame(context->decoder, context->target, >desc.base); return VA_STATUS_SUCCESS; } @@ -278,6 +279,142 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) num_buffers, (const void * const*)buffers, sizes); } +static VAStatus +handleVAEncMiscParameterTypeRateControl(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAEncMiscParameterRateControl *rc = (VAEncMiscParameterRateControl *)misc->data; + if (context->desc.h264enc.rate_ctrl.rate_ctrl_method == + PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT) + context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second; + else + context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second * rc->target_percentage; + context->desc.h264enc.rate_ctrl.peak_bitrate = rc->bits_per_second; + if (context->desc.h264enc.rate_ctrl.target_bitrate < 200) + context->desc.h264enc.rate_ctrl.vbv_buffer_size = MIN2((context->desc.h264enc.rate_ctrl.target_bitrate * 2.75), 200); + else + context->desc.h264enc.rate_ctrl.vbv_buffer_size = context->desc.h264enc.rate_ctrl.target_bitrate; + context->desc.h264enc.rate_ctrl.target_bits_picture = + context->desc.h264enc.rate_ctrl.target_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_integer = + context->desc.h264enc.rate_ctrl.peak_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_fraction = 0; + + return VA_STATUS_SUCCESS; +} + +static VAStatus +handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + VAEncSequenceParameterBufferH264 *h264 = (VAEncSequenceParameterBufferH264 *)buf->data; + if (!context->decoder) { + context->templat.max_references = h264->max_num_ref_frames; + context->templat.level = h264->level_idc; + context->decoder = drv->pipe->create_video_codec(drv->pipe, >templat); + if (!context->decoder) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + context->desc.h264enc.gop_size = h264->intra_idr_period; + context->desc.h264enc.rate_ctrl.frame_rate_num = h264->time_scale / 2; + context->desc.h264enc.rate_ctrl.frame_rate_den = 1; + return VA_STATUS_SUCCESS; +} + +static VAStatus +handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) +{ + VAStatus vaStatus = VA_STATUS_SUCCESS; + VAEncMiscParameterBuffer *misc; + misc = buf->data; + + switch (misc->type) { + case VAEncMiscParameterTypeRateControl: + vaStatus = handleVAEncMiscParameterTypeRateControl(context, misc); + break; + + default: + break; + } + + return vaStatus; +} + +static VAStatus +handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + VAEncPictureParameterBufferH264 *h264; + vlVaBuffer *coded_buf; + + h264 = buf->data; + context->desc.h264
[Mesa-dev] [PATCH 7/9] st/va: add enviromental variable to disable interlace
Add environmental variable to disable interlace mode. At VAAPI decoding stage, driver can not distinguish b/w pure decoding case and transcoding case. And since interlace encoding is not supported, we have to disable interlace for transcoding case. The temporary solution is to use enviromental variable to disable interlace mode. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/surface.c | 4 1 file changed, 4 insertions(+) diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c index 8ce4143..63727b6 100644 --- a/src/gallium/state_trackers/va/surface.c +++ b/src/gallium/state_trackers/va/surface.c @@ -43,6 +43,8 @@ #include "va_private.h" +DEBUG_GET_ONCE_BOOL_OPTION(nointerlace, "VAAPI_DISABLE_INTERLACE", FALSE); + #include static const enum pipe_format vpp_surface_formats[] = { @@ -620,6 +622,8 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format, templat.width = width; templat.height = height; + if (debug_get_option_nointerlace()) + templat.interlaced = false; memset(surfaces, VA_INVALID_ID, num_surfaces * sizeof(VASurfaceID)); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 8/9] st/va: add function to handle misc param type frame rate
Frame rate can be passed to driver either through VAEncSequenceParameterBufferType or VAEncMiscParameterTypeFrameRate. Previous code only implement the former one, which is used by Gstreamer-Vaapi. Now adding implementation for VAEncMiscParameterTypeFrameRate. Also adding default frame rate as 30 just in case application never provides frame rate information to driver. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/picture.c | 24 +++- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 4abf155..b187452 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -117,6 +117,13 @@ getEncParamPreset(vlVaContext *context) context->desc.h264enc.rate_ctrl.fill_data_enable = 1; context->desc.h264enc.rate_ctrl.enforce_hrd = 1; context->desc.h264enc.enable_vui = false; + if (context->desc.h264enc.rate_ctrl.frame_rate_num == 0) + context->desc.h264enc.rate_ctrl.frame_rate_num = 30; + context->desc.h264enc.rate_ctrl.target_bits_picture = + context->desc.h264enc.rate_ctrl.target_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_integer = + context->desc.h264enc.rate_ctrl.peak_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_fraction = 0; context->desc.h264enc.ref_pic_mode = 0x0201; } @@ -319,16 +326,19 @@ handleVAEncMiscParameterTypeRateControl(vlVaContext *context, VAEncMiscParameter context->desc.h264enc.rate_ctrl.vbv_buffer_size = MIN2((context->desc.h264enc.rate_ctrl.target_bitrate * 2.75), 200); else context->desc.h264enc.rate_ctrl.vbv_buffer_size = context->desc.h264enc.rate_ctrl.target_bitrate; - context->desc.h264enc.rate_ctrl.target_bits_picture = - context->desc.h264enc.rate_ctrl.target_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; - context->desc.h264enc.rate_ctrl.peak_bits_picture_integer = - context->desc.h264enc.rate_ctrl.peak_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; - context->desc.h264enc.rate_ctrl.peak_bits_picture_fraction = 0; return VA_STATUS_SUCCESS; } static VAStatus +handleVAEncMiscParameterTypeFrameRate(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAEncMiscParameterFrameRate *fr = (VAEncMiscParameterFrameRate *)misc->data; + context->desc.h264enc.rate_ctrl.frame_rate_num = fr->framerate; + return VA_STATUS_SUCCESS; +} + +static VAStatus handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) { VAEncSequenceParameterBufferH264 *h264 = (VAEncSequenceParameterBufferH264 *)buf->data; @@ -357,6 +367,10 @@ handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) vaStatus = handleVAEncMiscParameterTypeRateControl(context, misc); break; + case VAEncMiscParameterTypeFrameRate: + vaStatus = handleVAEncMiscParameterTypeFrameRate(context, misc); + break; + default: break; } -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 9/9] st/va: enable h264 VAAPI encode
Enable H.264 VAAPI encoding through config. Currently only H.264 baseline is supported. Encode entrypoint is not accepted by driver. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 34 ++ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index be151c8..aab01a0 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -74,6 +74,7 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, { struct pipe_screen *pscreen; enum pipe_video_profile p; + int va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; @@ -90,12 +91,18 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + va_status = VA_STATUS_SUCCESS; + } + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED) && + p == PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncSlice; + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncPicture; + va_status = VA_STATUS_SUCCESS; + } - return VA_STATUS_SUCCESS; + return va_status;; } VAStatus @@ -114,7 +121,7 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en value = VA_RT_FORMAT_YUV420; break; case VAConfigAttribRateControl: - value = VA_RC_NONE; + value = VA_RC_CQP | VA_RC_CBR; break; default: value = VA_ATTRIB_NOT_SUPPORTED; @@ -161,17 +168,20 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - if (entrypoint != VAEntrypointVLD) + if (entrypoint == VAEntrypointVLD) { + if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + else if (entrypoint == VAEntrypointEncSlice) { + if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED)) + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + else return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; -#if 0 if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncPicture) config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE; else -#endif config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM; config->profile = p; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 2/9] vl/util: add copy func for yv12image to nv12surface
Add function to copy from yv12 image to nv12 surface for VAAPI putimage call. We need this function in VaPutImage call where copying from yv12 image to nv12 surface for encoding. Existing function can't be used because it only work for copying from yv12 surface to nv12 image in Vaapi. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/auxiliary/util/u_video.h | 37 1 file changed, 37 insertions(+) diff --git a/src/gallium/auxiliary/util/u_video.h b/src/gallium/auxiliary/util/u_video.h index 9196afc..86a7adc 100644 --- a/src/gallium/auxiliary/util/u_video.h +++ b/src/gallium/auxiliary/util/u_video.h @@ -130,6 +130,43 @@ u_copy_yv12_to_nv12(void *const *destination_data, } static inline void +u_copy_yv12_img_to_nv12_surf(ubyte *const *src, + ubyte *dst, + unsigned width, + unsigned height, + unsigned src_stride, + unsigned dst_stride, + int field) +{ + if (field == 0) { + ubyte *src_0 = src[field]; + for (int i = 0; i < height ; i++) { + memcpy(dst, src_0, width); + dst += dst_stride; + src_0 += src_stride; + } + } else if (field == 1) { + ubyte *src_1 = src[field]; + ubyte *src_2 = src[field+1]; + bool odd = false; + for (int i = 0; i < height ; i++) { + for (int j = 0; j < width*2 ; j++) { +if (odd == false) { + dst[j] = src_1[j/2]; + odd = true; +} else { + dst[j] = src_2[j/2]; + odd = false; +} + } + dst += dst_stride; + src_1 += src_stride; + src_2 += src_stride; + } + } +} + +static inline void u_copy_swap422_packed(void *const *destination_data, uint32_t const *destination_pitches, int src_plane, int src_field, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 1/9] st/va: add encode entrypoint
VAAPI passes PIPE_VIDEO_ENTRYPOINT_ENCODE as entry point for encoding case. We will save this encode entry point in config. config_id was used as profile previously. Now, config has both profile and entrypoint field, and config_id is used to get the config object. Later on, we pass this entrypoint to context->templat.entrypoint instead of always hardcoded to PIPE_VIDEO_ENTRYPOINT_BITSTREAM for decoding case previously. Encode entrypoint is not accepted by driver until we enable Vaapi encode in later patch. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 71 +++--- src/gallium/state_trackers/va/context.c| 59 +++-- src/gallium/state_trackers/va/surface.c| 14 -- src/gallium/state_trackers/va/va_private.h | 5 +++ 4 files changed, 117 insertions(+), 32 deletions(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 9ca0aa8..3aacc63 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -34,6 +34,8 @@ #include "va_private.h" +#include "util/u_handle_table.h" + DEBUG_GET_ONCE_BOOL_OPTION(mpeg4, "VAAPI_MPEG4_ENABLED", false) VAStatus @@ -128,14 +130,29 @@ VAStatus vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id) { + vlVaDriver *drv; + vlVaConfig *config; struct pipe_screen *pscreen; enum pipe_video_profile p; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = CALLOC(1, sizeof(vlVaConfig)); + if (!config) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + if (profile == VAProfileNone && entrypoint == VAEntrypointVideoProc) { - *config_id = PIPE_VIDEO_PROFILE_UNKNOWN; + config->entrypoint = VAEntrypointVideoProc; + config->profile = PIPE_VIDEO_PROFILE_UNKNOWN; + pipe_mutex_lock(drv->mutex); + *config_id = handle_table_add(drv->htab, config); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -150,7 +167,18 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin if (entrypoint != VAEntrypointVLD) return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; - *config_id = p; +#if 0 + if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncPicture) + config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE; + else +#endif + config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM; + + config->profile = p; + + pipe_mutex_lock(drv->mutex); + *config_id = handle_table_add(drv->htab, config); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -158,9 +186,27 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin VAStatus vlVaDestroyConfig(VADriverContextP ctx, VAConfigID config_id) { + vlVaDriver *drv; + vlVaConfig *config; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + pipe_mutex_lock(drv->mutex); + config = handle_table_get(drv->htab, config_id); + + if (!config) + return VA_STATUS_ERROR_INVALID_CONFIG; + + FREE(config); + handle_table_remove(drv->htab, config_id); + pipe_mutex_unlock(drv->mutex); + return VA_STATUS_SUCCESS; } @@ -168,18 +214,33 @@ VAStatus vlVaQueryConfigAttributes(VADriverContextP ctx, VAConfigID config_id, VAProfile *profile, VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list, int *num_attribs) { + vlVaDriver *drv; + vlVaConfig *config; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - *profile = PipeToProfile(config_id); + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + pipe_mutex_lock(drv->mutex); + config = handle_table_get(drv->htab, config_id); + pipe_mutex_unlock(drv->mutex); + + if (!config) + return VA_STATUS_ERROR_INVALID_CONFIG; + + *profile = PipeToProfile(config->profile); - if (config_id == PIPE_VIDEO_PROFILE_UNKNOWN) { + if (config->profile == PIPE_VIDEO_PROFILE_UNKNOWN) { *entrypoint = VAEntrypointVideoProc; *num_attribs = 0; return VA_STATUS_SUCCESS; } - *entrypoint = VAEntrypointVLD; + *entrypoint = config->entrypoint; *num_attribs = 1; attrib_list[0].type = VAConfigAttribRTFormat; diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index 402fbb2..8882cba 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -195,18 +195,23 @@ vlVaCreateC
[Mesa-dev] [PATCH 05/12] st/va: add encode entrypoint
VAAPI passes PIPE_VIDEO_ENTRYPOINT_ENCODE as entry point for encoding case. We will save this encode entry point in config. config_id was used as profile previously. Now, config has both profile and entrypoint field, and config_id is used to get the config object. Later on, we pass this entrypoint to context->templat.entrypoint instead of always hardcoded to PIPE_VIDEO_ENTRYPOINT_BITSTREAM for decoding case previously. Encode entrypoint is not accepted by driver until we enable Vaapi encode in later patch. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 71 +++--- src/gallium/state_trackers/va/context.c| 59 +++-- src/gallium/state_trackers/va/surface.c| 14 -- src/gallium/state_trackers/va/va_private.h | 5 +++ 4 files changed, 117 insertions(+), 32 deletions(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 9ca0aa8..3aacc63 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -34,6 +34,8 @@ #include "va_private.h" +#include "util/u_handle_table.h" + DEBUG_GET_ONCE_BOOL_OPTION(mpeg4, "VAAPI_MPEG4_ENABLED", false) VAStatus @@ -128,14 +130,29 @@ VAStatus vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id) { + vlVaDriver *drv; + vlVaConfig *config; struct pipe_screen *pscreen; enum pipe_video_profile p; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = CALLOC(1, sizeof(vlVaConfig)); + if (!config) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + if (profile == VAProfileNone && entrypoint == VAEntrypointVideoProc) { - *config_id = PIPE_VIDEO_PROFILE_UNKNOWN; + config->entrypoint = VAEntrypointVideoProc; + config->profile = PIPE_VIDEO_PROFILE_UNKNOWN; + pipe_mutex_lock(drv->mutex); + *config_id = handle_table_add(drv->htab, config); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -150,7 +167,18 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin if (entrypoint != VAEntrypointVLD) return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; - *config_id = p; +#if 0 + if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncPicture) + config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE; + else +#endif + config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM; + + config->profile = p; + + pipe_mutex_lock(drv->mutex); + *config_id = handle_table_add(drv->htab, config); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -158,9 +186,27 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin VAStatus vlVaDestroyConfig(VADriverContextP ctx, VAConfigID config_id) { + vlVaDriver *drv; + vlVaConfig *config; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + pipe_mutex_lock(drv->mutex); + config = handle_table_get(drv->htab, config_id); + + if (!config) + return VA_STATUS_ERROR_INVALID_CONFIG; + + FREE(config); + handle_table_remove(drv->htab, config_id); + pipe_mutex_unlock(drv->mutex); + return VA_STATUS_SUCCESS; } @@ -168,18 +214,33 @@ VAStatus vlVaQueryConfigAttributes(VADriverContextP ctx, VAConfigID config_id, VAProfile *profile, VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list, int *num_attribs) { + vlVaDriver *drv; + vlVaConfig *config; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - *profile = PipeToProfile(config_id); + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + pipe_mutex_lock(drv->mutex); + config = handle_table_get(drv->htab, config_id); + pipe_mutex_unlock(drv->mutex); + + if (!config) + return VA_STATUS_ERROR_INVALID_CONFIG; + + *profile = PipeToProfile(config->profile); - if (config_id == PIPE_VIDEO_PROFILE_UNKNOWN) { + if (config->profile == PIPE_VIDEO_PROFILE_UNKNOWN) { *entrypoint = VAEntrypointVideoProc; *num_attribs = 0; return VA_STATUS_SUCCESS; } - *entrypoint = VAEntrypointVLD; + *entrypoint = config->entrypoint; *num_attribs = 1; attrib_list[0].type = VAConfigAttribRTFormat; diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index 402fbb2..8882cba 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -195,18 +195,23 @@ vlVaCreateC
[Mesa-dev] [PATCH 08/12] st/va: get rate control method from configattrib
Rate control method is passed from app to driver through config attrib list. That is why we need to store this rate control method to config. And later on, we will pass this value to context->desc.h264enc.rate_ctrl.rate_ctrl_method. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 11 +++ src/gallium/state_trackers/va/context.c| 2 ++ src/gallium/state_trackers/va/va_private.h | 1 + 3 files changed, 14 insertions(+) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 3aacc63..be151c8 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -176,6 +176,17 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin config->profile = p; + for (int i = 0; i rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT; + else if (attrib_list[i].value == VA_RC_VBR) +config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE; + else +config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE; + } + } + pipe_mutex_lock(drv->mutex); *config_id = handle_table_add(drv->htab, config); pipe_mutex_unlock(drv->mutex); diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index 8882cba..65ba7db 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -276,6 +276,8 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, context->desc.base.profile = config->profile; context->desc.base.entry_point = config->entrypoint; + if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) + context->desc.h264enc.rate_ctrl.rate_ctrl_method = config->rc; pipe_mutex_lock(drv->mutex); *context_id = handle_table_add(drv->htab, context); diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index 723983d..ad9010a 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -246,6 +246,7 @@ typedef struct { typedef struct { VAEntrypoint entrypoint; enum pipe_video_profile profile; + enum pipe_h264_enc_rate_control_method rc; } vlVaConfig; typedef struct { -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 12/12] st/va: enable h264 VAAPI encode
Enable H.264 VAAPI encoding through config. Currently only H.264 baseline is supported. Encode entrypoint is not accepted by driver. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 34 ++ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index be151c8..aab01a0 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -74,6 +74,7 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, { struct pipe_screen *pscreen; enum pipe_video_profile p; + int va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; @@ -90,12 +91,18 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + va_status = VA_STATUS_SUCCESS; + } + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED) && + p == PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncSlice; + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncPicture; + va_status = VA_STATUS_SUCCESS; + } - return VA_STATUS_SUCCESS; + return va_status;; } VAStatus @@ -114,7 +121,7 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en value = VA_RT_FORMAT_YUV420; break; case VAConfigAttribRateControl: - value = VA_RC_NONE; + value = VA_RC_CQP | VA_RC_CBR; break; default: value = VA_ATTRIB_NOT_SUPPORTED; @@ -161,17 +168,20 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - if (entrypoint != VAEntrypointVLD) + if (entrypoint == VAEntrypointVLD) { + if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + else if (entrypoint == VAEntrypointEncSlice) { + if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED)) + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + else return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; -#if 0 if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncPicture) config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE; else -#endif config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM; config->profile = p; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 10/12] st/va: add preset values for VAAPI encode
Add some hardcoded values hardware needs mainly for rate control purpose. With previously hardcoded values for OMX, the rate control result is not correct. This change fixed the rate control result by setting correct values for Vaapi. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/picture.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 4bb60f2..4abf155 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -95,6 +95,32 @@ vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id, *ref_frame = NULL; } +static void +getEncParamPreset(vlVaContext *context) +{ + //motion estimation preset + context->desc.h264enc.motion_est.motion_est_quarter_pixel = 0x0001; + context->desc.h264enc.motion_est.lsmvert = 0x0002; + context->desc.h264enc.motion_est.enc_disable_sub_mode = 0x0078; + context->desc.h264enc.motion_est.enc_en_ime_overw_dis_subm = 0x0001; + context->desc.h264enc.motion_est.enc_ime_overw_dis_subm_no = 0x0001; + context->desc.h264enc.motion_est.enc_ime2_search_range_x = 0x0004; + context->desc.h264enc.motion_est.enc_ime2_search_range_y = 0x0004; + + //pic control preset + context->desc.h264enc.pic_ctrl.enc_cabac_enable = 0x0001; + context->desc.h264enc.pic_ctrl.enc_constraint_set_flags = 0x0040; + + //rate control + context->desc.h264enc.rate_ctrl.vbv_buffer_size = 2000; + context->desc.h264enc.rate_ctrl.vbv_buf_lv = 48; + context->desc.h264enc.rate_ctrl.fill_data_enable = 1; + context->desc.h264enc.rate_ctrl.enforce_hrd = 1; + context->desc.h264enc.enable_vui = false; + + context->desc.h264enc.ref_pic_mode = 0x0201; +} + static VAStatus handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) { @@ -524,6 +550,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { coded_buf = context->coded_buf; + getEncParamPreset(context); context->decoder->begin_frame(context->decoder, context->target, >desc.base); context->decoder->encode_bitstream(context->decoder, context->target, coded_buf->derived_surface.resource, ); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 11/12] st/va: add enviromental variable to disable interlace
Add environmental variable to disable interlace mode. At VAAPI decoding stage, driver can not distinguish b/w pure decoding case and transcoding case. And since interlace encoding is not supported, we have to disable interlace for transcoding case. The temporary solution is to use enviromental variable to disable interlace mode. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/surface.c | 4 1 file changed, 4 insertions(+) diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c index 8ce4143..63727b6 100644 --- a/src/gallium/state_trackers/va/surface.c +++ b/src/gallium/state_trackers/va/surface.c @@ -43,6 +43,8 @@ #include "va_private.h" +DEBUG_GET_ONCE_BOOL_OPTION(nointerlace, "VAAPI_DISABLE_INTERLACE", FALSE); + #include static const enum pipe_format vpp_surface_formats[] = { @@ -620,6 +622,8 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format, templat.width = width; templat.height = height; + if (debug_get_option_nointerlace()) + templat.interlaced = false; memset(surfaces, VA_INVALID_ID, num_surfaces * sizeof(VASurfaceID)); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 09/12] st/va: add functions for VAAPI encode
Add necessary functions/changes for VAAPI encoding to buffer and picture. These changes will allow driver to handle all Vaapi encode related operations. This patch doesn't change the Vaapi decode behaviour. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/buffer.c | 6 + src/gallium/state_trackers/va/picture.c| 172 - src/gallium/state_trackers/va/va_private.h | 3 + 3 files changed, 179 insertions(+), 2 deletions(-) diff --git a/src/gallium/state_trackers/va/buffer.c b/src/gallium/state_trackers/va/buffer.c index 7d3167b..dfcebbe 100644 --- a/src/gallium/state_trackers/va/buffer.c +++ b/src/gallium/state_trackers/va/buffer.c @@ -133,6 +133,12 @@ vlVaMapBuffer(VADriverContextP ctx, VABufferID buf_id, void **pbuff) if (!buf->derived_surface.transfer || !*pbuff) return VA_STATUS_ERROR_INVALID_BUFFER; + if (buf->type == VAEncCodedBufferType) { + ((VACodedBufferSegment*)buf->data)->buf = *pbuff; + ((VACodedBufferSegment*)buf->data)->size = buf->coded_size; + ((VACodedBufferSegment*)buf->data)->next = NULL; + *pbuff = buf->data; + } } else { pipe_mutex_unlock(drv->mutex); *pbuff = buf->data; diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 89ac024..4bb60f2 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -78,7 +78,8 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende return VA_STATUS_SUCCESS; } - context->decoder->begin_frame(context->decoder, context->target, >desc.base); + if (context->decoder->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) + context->decoder->begin_frame(context->decoder, context->target, >desc.base); return VA_STATUS_SUCCESS; } @@ -278,6 +279,142 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) num_buffers, (const void * const*)buffers, sizes); } +static VAStatus +handleVAEncMiscParameterTypeRateControl(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAEncMiscParameterRateControl *rc = (VAEncMiscParameterRateControl *)misc->data; + if (context->desc.h264enc.rate_ctrl.rate_ctrl_method == + PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT) + context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second; + else + context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second * rc->target_percentage; + context->desc.h264enc.rate_ctrl.peak_bitrate = rc->bits_per_second; + if (context->desc.h264enc.rate_ctrl.target_bitrate < 200) + context->desc.h264enc.rate_ctrl.vbv_buffer_size = MIN2((context->desc.h264enc.rate_ctrl.target_bitrate * 2.75), 200); + else + context->desc.h264enc.rate_ctrl.vbv_buffer_size = context->desc.h264enc.rate_ctrl.target_bitrate; + context->desc.h264enc.rate_ctrl.target_bits_picture = + context->desc.h264enc.rate_ctrl.target_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_integer = + context->desc.h264enc.rate_ctrl.peak_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_fraction = 0; + + return VA_STATUS_SUCCESS; +} + +static VAStatus +handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + VAEncSequenceParameterBufferH264 *h264 = (VAEncSequenceParameterBufferH264 *)buf->data; + if (!context->decoder) { + context->templat.max_references = h264->max_num_ref_frames; + context->templat.level = h264->level_idc; + context->decoder = drv->pipe->create_video_codec(drv->pipe, >templat); + if (!context->decoder) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + context->desc.h264enc.gop_size = h264->intra_idr_period; + context->desc.h264enc.rate_ctrl.frame_rate_num = h264->time_scale / 2; + context->desc.h264enc.rate_ctrl.frame_rate_den = 1; + return VA_STATUS_SUCCESS; +} + +static VAStatus +handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) +{ + VAStatus vaStatus = VA_STATUS_SUCCESS; + VAEncMiscParameterBuffer *misc; + misc = buf->data; + + switch (misc->type) { + case VAEncMiscParameterTypeRateControl: + vaStatus = handleVAEncMiscParameterTypeRateControl(context, misc); + break; + + default: + break; + } + + return vaStatus; +} + +static VAStatus +handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + VAEncPictureParameterBufferH264 *h264; + vlVaBuffer *coded_buf; + + h264 = buf->data; + context->desc.h264
[Mesa-dev] [PATCH 06/12] vl/util: add copy func for yv12image to nv12surface
Add function to copy from yv12 image to nv12 surface for VAAPI putimage call. We need this function in VaPutImage call where copying from yv12 image to nv12 surface for encoding. Existing function can't be used because it only work for copying from yv12 surface to nv12 image in Vaapi. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/auxiliary/util/u_video.h | 23 +++ 1 file changed, 23 insertions(+) diff --git a/src/gallium/auxiliary/util/u_video.h b/src/gallium/auxiliary/util/u_video.h index 9196afc..d147295 100644 --- a/src/gallium/auxiliary/util/u_video.h +++ b/src/gallium/auxiliary/util/u_video.h @@ -130,6 +130,29 @@ u_copy_yv12_to_nv12(void *const *destination_data, } static inline void +u_copy_yv12_img_to_nv12_surf(uint8_t *const *src, + uint8_t *dest, + int *offset, + int field) +{ + if (field == 0) { + for (int i = 0; i < offset[1] ; i++) + dest[i] = src[field][i]; + } else if (field == 1) { + bool odd = false; + for (int i = 0; i < (offset[1]/2) ; i++){ + if (odd == false) { +dest[i] = src[field][i/2]; +odd = true; + } else { +dest[i] = src[field+1][i/2]; +odd = false; + } + } + } +} + +static inline void u_copy_swap422_packed(void *const *destination_data, uint32_t const *destination_pitches, int src_plane, int src_field, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 07/12] st/va: add conversion for yv12 to nv12in putimage
For putimage call, if image format is yv12 (or IYUV with U V field swap) and surface format is nv12, then we need to convert yv12 to nv12 and then copy the converted data from image to surface. We can't use the existing logic where surface is destroyed and re-created with yv12 format. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/image.c | 33 ++--- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c index 1b956e3..47895ee 100644 --- a/src/gallium/state_trackers/va/image.c +++ b/src/gallium/state_trackers/va/image.c @@ -471,7 +471,9 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, return VA_STATUS_ERROR_OPERATION_FAILED; } - if (format != surf->buffer->buffer_format) { + if ((format != surf->buffer->buffer_format) && + ((format != PIPE_FORMAT_YV12) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12)) && + ((format != PIPE_FORMAT_IYUV) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12))) { struct pipe_video_buffer *tmp_buf; struct pipe_video_buffer templat = surf->templat; @@ -513,12 +515,29 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, unsigned width, height; if (!views[i]) continue; vlVaVideoSurfaceSize(surf, i, , ); - for (j = 0; j < views[i]->texture->array_size; ++j) { - struct pipe_box dst_box = {0, 0, j, width, height, 1}; - drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0, -PIPE_TRANSFER_WRITE, _box, -data[i] + pitches[i] * j, -pitches[i] * views[i]->texture->array_size, 0); + if ((format == PIPE_FORMAT_YV12) || (format == PIPE_FORMAT_IYUV) && +(surf->buffer->buffer_format == PIPE_FORMAT_NV12)) { + struct pipe_transfer *transfer = NULL; + uint8_t *map = NULL; + struct pipe_box dst_box_1 = {0, 0, 0, width, height, 1}; + map = drv->pipe->transfer_map(drv->pipe, + views[i]->texture, + 0, + PIPE_TRANSFER_DISCARD_RANGE, + _box_1, ); + if (map == NULL) +return VA_STATUS_ERROR_OPERATION_FAILED; + + u_copy_yv12_img_to_nv12_surf (data, map, vaimage->offsets, i); + pipe_transfer_unmap(drv->pipe, transfer); + } else { + for (j = 0; j < views[i]->texture->array_size; ++j) { +struct pipe_box dst_box = {0, 0, j, width, height, 1}; +drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0, + PIPE_TRANSFER_WRITE, _box, + data[i] + pitches[i] * j, + pitches[i] * views[i]->texture->array_size, 0); + } } } pipe_mutex_unlock(drv->mutex); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 10/12] st/va: add preset values for VAAPI encode
Add some hardcoded values hardware needs mainly for rate control purpose. With previously hardcoded values for OMX, the rate control result is not correct. This change fixed the rate control result by setting correct values for Vaapi. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/picture.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 4793194..518831f 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -95,6 +95,32 @@ vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id, *ref_frame = NULL; } +static void +getEncParamPreset(vlVaContext *context) +{ + //motion estimation preset + context->desc.h264enc.motion_est.motion_est_quarter_pixel = 0x0001; + context->desc.h264enc.motion_est.lsmvert = 0x0002; + context->desc.h264enc.motion_est.enc_disable_sub_mode = 0x0078; + context->desc.h264enc.motion_est.enc_en_ime_overw_dis_subm = 0x0001; + context->desc.h264enc.motion_est.enc_ime_overw_dis_subm_no = 0x0001; + context->desc.h264enc.motion_est.enc_ime2_search_range_x = 0x0004; + context->desc.h264enc.motion_est.enc_ime2_search_range_y = 0x0004; + + //pic control preset + context->desc.h264enc.pic_ctrl.enc_cabac_enable = 0x0001; + context->desc.h264enc.pic_ctrl.enc_constraint_set_flags = 0x0040; + + //rate control + context->desc.h264enc.rate_ctrl.vbv_buffer_size = 2000; + context->desc.h264enc.rate_ctrl.vbv_buf_lv = 48; + context->desc.h264enc.rate_ctrl.fill_data_enable = 1; + context->desc.h264enc.rate_ctrl.enforce_hrd = 1; + context->desc.h264enc.enable_vui = false; + + context->desc.h264enc.ref_pic_mode = 0x0201; +} + static VAStatus handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) { @@ -521,6 +547,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { coded_buf = context->coded_buf; + getEncParamPreset(context); context->decoder->begin_frame(context->decoder, context->target, >desc.base); context->decoder->encode_bitstream(context->decoder, context->target, coded_buf->derived_surface.resource, ); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 12/12] st/va: enable h264 VAAPI encode
Enable H.264 VAAPI encoding through config. Currently only H.264 baseline is supported. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 32 ++-- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 6a36fb3..668c89d 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -74,6 +74,7 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, { struct pipe_screen *pscreen; enum pipe_video_profile p; + int va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; @@ -90,12 +91,18 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + va_status = VA_STATUS_SUCCESS; + } + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED) && + p == PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncSlice; + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncPicture; + va_status = VA_STATUS_SUCCESS; + } - return VA_STATUS_SUCCESS; + return va_status; } VAStatus @@ -114,7 +121,7 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en value = VA_RT_FORMAT_YUV420; break; case VAConfigAttribRateControl: - value = VA_RC_NONE; + value = VA_RC_CQP | VA_RC_CBR; break; default: value = VA_ATTRIB_NOT_SUPPORTED; @@ -161,10 +168,15 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - if (entrypoint != VAEntrypointVLD) + if (entrypoint == VAEntrypointVLD) { + if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + else if (entrypoint == VAEntrypointEncSlice) { + if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED)) + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + else return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncPicture) -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 11/12] st/va: add environmental variable to disable interlace
Add environmental variable to disable interlace mode. At VAAPI decoding stage, driver can not distinguish b/w pure decoding case and transcoding case. And since interlace encoding is not supported, we have to disable interlace for transcoding case. The temporary solution is to use enviromental variable to disable interlace mode. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/surface.c | 4 1 file changed, 4 insertions(+) diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c index 8ce4143..d1296b0 100644 --- a/src/gallium/state_trackers/va/surface.c +++ b/src/gallium/state_trackers/va/surface.c @@ -43,6 +43,8 @@ #include "va_private.h" +DEBUG_GET_ONCE_BOOL_OPTION(nointerlace, "DISABLE_INTERLACE", FALSE); + #include static const enum pipe_format vpp_surface_formats[] = { @@ -620,6 +622,8 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format, templat.width = width; templat.height = height; + if (debug_get_option_nointerlace()) + templat.interlaced = false; memset(surfaces, VA_INVALID_ID, num_surfaces * sizeof(VASurfaceID)); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 08/12] st/va: get rate control method from configattrib
Rate control method is passed from app to driver through config attrib list. That is why we need to store this rate control method to config. And later on, we will pass this value to context->desc.h264enc.rate_ctrl.rate_ctrl_method. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 11 +++ src/gallium/state_trackers/va/context.c| 2 ++ src/gallium/state_trackers/va/va_private.h | 1 + 3 files changed, 14 insertions(+) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 7ea7e24..6a36fb3 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -174,6 +174,17 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin config->profile = p; + for (int i = 0; i rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT; + else if (attrib_list[i].value == VA_RC_VBR) +config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE; + else +config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE; + } + } + pipe_mutex_lock(drv->mutex); *config_id = handle_table_add(drv->htab, config); pipe_mutex_unlock(drv->mutex); diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index 8882cba..65ba7db 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -276,6 +276,8 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, context->desc.base.profile = config->profile; context->desc.base.entry_point = config->entrypoint; + if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) + context->desc.h264enc.rate_ctrl.rate_ctrl_method = config->rc; pipe_mutex_lock(drv->mutex); *context_id = handle_table_add(drv->htab, context); diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index 723983d..ad9010a 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -246,6 +246,7 @@ typedef struct { typedef struct { VAEntrypoint entrypoint; enum pipe_video_profile profile; + enum pipe_h264_enc_rate_control_method rc; } vlVaConfig; typedef struct { -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 06/12] vl/util: add copy func for yv12image to nv12surface
Add function to copy from yv12 image to nv12 surface for VAAPI putimage call. We need this function in VaPutImage call where copying from yv12 image to nv12 surface for encoding. Existing function can't be used because it only work for copying from yv12 surface to nv12 image in Vaapi. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/auxiliary/util/u_video.h | 23 +++ 1 file changed, 23 insertions(+) diff --git a/src/gallium/auxiliary/util/u_video.h b/src/gallium/auxiliary/util/u_video.h index 9196afc..d147295 100644 --- a/src/gallium/auxiliary/util/u_video.h +++ b/src/gallium/auxiliary/util/u_video.h @@ -130,6 +130,29 @@ u_copy_yv12_to_nv12(void *const *destination_data, } static inline void +u_copy_yv12_img_to_nv12_surf(uint8_t *const *src, + uint8_t *dest, + int *offset, + int field) +{ + if (field == 0) { + for (int i = 0; i < offset[1] ; i++) + dest[i] = src[field][i]; + } else if (field == 1) { + bool odd = false; + for (int i = 0; i < (offset[1]/2) ; i++){ + if (odd == false) { +dest[i] = src[field][i/2]; +odd = true; + } else { +dest[i] = src[field+1][i/2]; +odd = false; + } + } + } +} + +static inline void u_copy_swap422_packed(void *const *destination_data, uint32_t const *destination_pitches, int src_plane, int src_field, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 09/12] st/va: add functions for VAAPI encode
Add necessary functions/changes for VAAPI encoding to buffer and picture. These changes will allow driver to handle all Vaapi encode related operations. This patch doesn't change the Vaapi decode behaviour. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/buffer.c | 6 + src/gallium/state_trackers/va/picture.c| 169 - src/gallium/state_trackers/va/va_private.h | 3 + 3 files changed, 176 insertions(+), 2 deletions(-) diff --git a/src/gallium/state_trackers/va/buffer.c b/src/gallium/state_trackers/va/buffer.c index 7d3167b..dfcebbe 100644 --- a/src/gallium/state_trackers/va/buffer.c +++ b/src/gallium/state_trackers/va/buffer.c @@ -133,6 +133,12 @@ vlVaMapBuffer(VADriverContextP ctx, VABufferID buf_id, void **pbuff) if (!buf->derived_surface.transfer || !*pbuff) return VA_STATUS_ERROR_INVALID_BUFFER; + if (buf->type == VAEncCodedBufferType) { + ((VACodedBufferSegment*)buf->data)->buf = *pbuff; + ((VACodedBufferSegment*)buf->data)->size = buf->coded_size; + ((VACodedBufferSegment*)buf->data)->next = NULL; + *pbuff = buf->data; + } } else { pipe_mutex_unlock(drv->mutex); *pbuff = buf->data; diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 89ac024..4793194 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -78,7 +78,8 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende return VA_STATUS_SUCCESS; } - context->decoder->begin_frame(context->decoder, context->target, >desc.base); + if (context->decoder->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) + context->decoder->begin_frame(context->decoder, context->target, >desc.base); return VA_STATUS_SUCCESS; } @@ -278,6 +279,139 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) num_buffers, (const void * const*)buffers, sizes); } +static VAStatus +handleVAEncMiscParameterTypeRateControl(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAEncMiscParameterRateControl *rc = (VAEncMiscParameterRateControl *)misc->data; + if (context->desc.h264enc.rate_ctrl.rate_ctrl_method == + PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT) + context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second; + else + context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second * rc->target_percentage; + context->desc.h264enc.rate_ctrl.peak_bitrate = rc->bits_per_second; + if (context->desc.h264enc.rate_ctrl.target_bitrate < 200) + context->desc.h264enc.rate_ctrl.vbv_buffer_size = MIN2((context->desc.h264enc.rate_ctrl.target_bitrate * 2.75), 200); + else + context->desc.h264enc.rate_ctrl.vbv_buffer_size = context->desc.h264enc.rate_ctrl.target_bitrate; + context->desc.h264enc.rate_ctrl.target_bits_picture = + context->desc.h264enc.rate_ctrl.target_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_integer = + context->desc.h264enc.rate_ctrl.peak_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_fraction = 0; + + return VA_STATUS_SUCCESS; +} + +static VAStatus +handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + VAEncSequenceParameterBufferH264 *h264 = (VAEncSequenceParameterBufferH264 *)buf->data; + if (!context->decoder) { + context->templat.max_references = h264->max_num_ref_frames; + context->templat.level = h264->level_idc; + context->decoder = drv->pipe->create_video_codec(drv->pipe, >templat); + if (!context->decoder) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + context->desc.h264enc.gop_size = h264->intra_idr_period; + context->desc.h264enc.rate_ctrl.frame_rate_num = h264->time_scale / 2; + context->desc.h264enc.rate_ctrl.frame_rate_den = 1; + return VA_STATUS_SUCCESS; +} + +static VAStatus +handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) +{ + VAStatus vaStatus = VA_STATUS_SUCCESS; + VAEncMiscParameterBuffer *misc; + misc = buf->data; + + switch (misc->type) { + case VAEncMiscParameterTypeRateControl: + vaStatus = handleVAEncMiscParameterTypeRateControl(context, misc); + break; + + default: + break; + } + + return vaStatus; +} + +static VAStatus +handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + VAEncPictureParameterBufferH264 *h264; + vlVaBuffer *coded_buf; + + h264 = buf->data; + context->desc.h264
[Mesa-dev] [PATCH 07/12] st/va: add conversion for yv12 to nv12in putimage
For putimage call, if image format is yv12 (or IYUV with U V field swap) and surface format is nv12, then we need to convert yv12 to nv12 and then copy the converted data from image to surface. We can't use the existing logic where surface is destroyed and re-created with yv12 format. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/image.c | 33 ++--- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c index 1b956e3..47895ee 100644 --- a/src/gallium/state_trackers/va/image.c +++ b/src/gallium/state_trackers/va/image.c @@ -471,7 +471,9 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, return VA_STATUS_ERROR_OPERATION_FAILED; } - if (format != surf->buffer->buffer_format) { + if ((format != surf->buffer->buffer_format) && + ((format != PIPE_FORMAT_YV12) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12)) && + ((format != PIPE_FORMAT_IYUV) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12))) { struct pipe_video_buffer *tmp_buf; struct pipe_video_buffer templat = surf->templat; @@ -513,12 +515,29 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, unsigned width, height; if (!views[i]) continue; vlVaVideoSurfaceSize(surf, i, , ); - for (j = 0; j < views[i]->texture->array_size; ++j) { - struct pipe_box dst_box = {0, 0, j, width, height, 1}; - drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0, -PIPE_TRANSFER_WRITE, _box, -data[i] + pitches[i] * j, -pitches[i] * views[i]->texture->array_size, 0); + if ((format == PIPE_FORMAT_YV12) || (format == PIPE_FORMAT_IYUV) && +(surf->buffer->buffer_format == PIPE_FORMAT_NV12)) { + struct pipe_transfer *transfer = NULL; + uint8_t *map = NULL; + struct pipe_box dst_box_1 = {0, 0, 0, width, height, 1}; + map = drv->pipe->transfer_map(drv->pipe, + views[i]->texture, + 0, + PIPE_TRANSFER_DISCARD_RANGE, + _box_1, ); + if (map == NULL) +return VA_STATUS_ERROR_OPERATION_FAILED; + + u_copy_yv12_img_to_nv12_surf (data, map, vaimage->offsets, i); + pipe_transfer_unmap(drv->pipe, transfer); + } else { + for (j = 0; j < views[i]->texture->array_size; ++j) { +struct pipe_box dst_box = {0, 0, j, width, height, 1}; +drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0, + PIPE_TRANSFER_WRITE, _box, + data[i] + pitches[i] * j, + pitches[i] * views[i]->texture->array_size, 0); + } } } pipe_mutex_unlock(drv->mutex); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 05/12] st/va: add encode entrypoint
VAAPI passes PIPE_VIDEO_ENTRYPOINT_ENCODE as entry point for encoding case. We will save this encode entry point in config. config_id was used as profile previously. Now, config has both profile and entrypoint field, and config_id is used to get the config object. Later on, we pass this entrypoint to context->templat.entrypoint instead of always hardcoded to PIPE_VIDEO_ENTRYPOINT_BITSTREAM for decoding case previously. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 69 +++--- src/gallium/state_trackers/va/context.c| 59 ++--- src/gallium/state_trackers/va/surface.c| 14 -- src/gallium/state_trackers/va/va_private.h | 5 +++ 4 files changed, 115 insertions(+), 32 deletions(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 9ca0aa8..7ea7e24 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -34,6 +34,8 @@ #include "va_private.h" +#include "util/u_handle_table.h" + DEBUG_GET_ONCE_BOOL_OPTION(mpeg4, "VAAPI_MPEG4_ENABLED", false) VAStatus @@ -128,14 +130,29 @@ VAStatus vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id) { + vlVaDriver *drv; + vlVaConfig *config; struct pipe_screen *pscreen; enum pipe_video_profile p; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = CALLOC(1, sizeof(vlVaConfig)); + if (!config) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + if (profile == VAProfileNone && entrypoint == VAEntrypointVideoProc) { - *config_id = PIPE_VIDEO_PROFILE_UNKNOWN; + config->entrypoint = VAEntrypointVideoProc; + config->profile = PIPE_VIDEO_PROFILE_UNKNOWN; + pipe_mutex_lock(drv->mutex); + *config_id = handle_table_add(drv->htab, config); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -150,7 +167,16 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin if (entrypoint != VAEntrypointVLD) return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; - *config_id = p; + if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncPicture) + config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE; + else + config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM; + + config->profile = p; + + pipe_mutex_lock(drv->mutex); + *config_id = handle_table_add(drv->htab, config); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -158,9 +184,27 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin VAStatus vlVaDestroyConfig(VADriverContextP ctx, VAConfigID config_id) { + vlVaDriver *drv; + vlVaConfig *config; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + pipe_mutex_lock(drv->mutex); + config = handle_table_get(drv->htab, config_id); + + if (!config) + return VA_STATUS_ERROR_INVALID_CONFIG; + + FREE(config); + handle_table_remove(drv->htab, config_id); + pipe_mutex_unlock(drv->mutex); + return VA_STATUS_SUCCESS; } @@ -168,18 +212,33 @@ VAStatus vlVaQueryConfigAttributes(VADriverContextP ctx, VAConfigID config_id, VAProfile *profile, VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list, int *num_attribs) { + vlVaDriver *drv; + vlVaConfig *config; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - *profile = PipeToProfile(config_id); + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + pipe_mutex_lock(drv->mutex); + config = handle_table_get(drv->htab, config_id); + pipe_mutex_unlock(drv->mutex); + + if (!config) + return VA_STATUS_ERROR_INVALID_CONFIG; + + *profile = PipeToProfile(config->profile); - if (config_id == PIPE_VIDEO_PROFILE_UNKNOWN) { + if (config->profile == PIPE_VIDEO_PROFILE_UNKNOWN) { *entrypoint = VAEntrypointVideoProc; *num_attribs = 0; return VA_STATUS_SUCCESS; } - *entrypoint = VAEntrypointVLD; + *entrypoint = config->entrypoint; *num_attribs = 1; attrib_list[0].type = VAConfigAttribRTFormat; diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index 402fbb2..8882cba 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -195,18 +195,23 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, { vl
[Mesa-dev] [PATCH 02/12] vl: add entry point
Add entrypoint to distinguish H.264 decode and encode. For example, in patch 5/11 when is calling "VaCreateContext", "pps" and "sps" shouldn't be allocated for H.264 encoding. So we need to use the entry_point to determine this is H.264 decode or H.264 encode. We can use config to determine the entrypoint since config_id is passed to us for VaCreateContext call. However, for VaDestoyContext call, only context_id is passed to us. So we need to know the entrypoint in order to not free the pps/sps for encoding case. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/include/pipe/p_video_state.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 754d013..39b3905 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -131,6 +131,7 @@ enum pipe_h264_enc_rate_control_method struct pipe_picture_desc { enum pipe_video_profile profile; + enum pipe_video_entrypoint entry_point; }; struct pipe_quant_matrix -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 10/11] st/va: add preset values for VAAPI encode
Add some hardcoded values hardware needs mainly for rate control purpose. With previously hardcoded values for OMX, the rate control result is not correct. This change fixed the rate control result by setting correct values for Vaapi. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/picture.c | 36 + 1 file changed, 36 insertions(+) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index c244619..275250f 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -95,6 +95,41 @@ vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id, *ref_frame = NULL; } +static void +getEncParamPreset(vlVaContext *context) +{ + //motion estimation preset + context->desc.h264enc.motion_est.motion_est_quarter_pixel = 0x0001; + context->desc.h264enc.motion_est.lsmvert = 0x0002; + context->desc.h264enc.motion_est.enc_disable_sub_mode = 0x0078; + context->desc.h264enc.motion_est.enc_en_ime_overw_dis_subm = 0x0001; + context->desc.h264enc.motion_est.enc_ime_overw_dis_subm_no = 0x0001; + context->desc.h264enc.motion_est.enc_ime2_search_range_x = 0x0004; + context->desc.h264enc.motion_est.enc_ime2_search_range_y = 0x0004; + + //pic control preset + context->desc.h264enc.pic_ctrl.enc_cabac_enable = 0x0001; + context->desc.h264enc.pic_ctrl.enc_constraint_set_flags = 0x0040; + + //rate control + context->desc.h264enc.rate_ctrl.vbv_buffer_size = 2000; + if (context->desc.h264enc.rate_ctrl.frame_rate_num == 0) { + context->desc.h264enc.rate_ctrl.frame_rate_num = 30; + context->desc.h264enc.rate_ctrl.frame_rate_den = 1; + } + context->desc.h264enc.rate_ctrl.vbv_buf_lv = 48; + context->desc.h264enc.rate_ctrl.fill_data_enable = 1; + context->desc.h264enc.rate_ctrl.enforce_hrd = 1; + context->desc.h264enc.enable_vui = false; + context->desc.h264enc.rate_ctrl.target_bits_picture = + context->desc.h264enc.rate_ctrl.target_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_integer = + context->desc.h264enc.rate_ctrl.peak_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_fraction = 0; + + context->desc.h264enc.ref_pic_mode = 0x0201; +} + static VAStatus handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) { @@ -514,6 +549,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { coded_buf = context->coded_buf; + getEncParamPreset(context); context->decoder->begin_frame(context->decoder, context->target, >desc.base); context->decoder->encode_bitstream(context->decoder, context->target, coded_buf->derived_surface.resource, ); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 08/11] st/va: get rate control method from configattrib
Rate control method is passed from app to driver through config attrib list. That is why we need to store this rate control method to config. And later on, we will pass this value to context->desc.h264enc.rate_ctrl.rate_ctrl_method. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 11 +++ src/gallium/state_trackers/va/context.c| 3 ++- src/gallium/state_trackers/va/va_private.h | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 73704a1..ea838c0 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -172,6 +172,17 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin config->profile = p; + for (int i = 0; i rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT; + else if (attrib_list[i].value == VA_RC_VBR) +config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE; + else +config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE; + } + } + *config_id = handle_table_add(drv->htab, config); return VA_STATUS_SUCCESS; diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index b4334f4..c67ed1f 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -274,7 +274,8 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, context->desc.base.profile = config->profile; context->desc.base.entry_point = config->entrypoint; - + if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) + context->desc.h264enc.rate_ctrl.rate_ctrl_method = config->rc; pipe_mutex_lock(drv->mutex); *context_id = handle_table_add(drv->htab, context); pipe_mutex_unlock(drv->mutex); diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index 723983d..ad9010a 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -246,6 +246,7 @@ typedef struct { typedef struct { VAEntrypoint entrypoint; enum pipe_video_profile profile; + enum pipe_h264_enc_rate_control_method rc; } vlVaConfig; typedef struct { -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 11/11] st/va: enable h264 VAAPI encode
Enable H.264 VAAPI encoding through config. Currently only H.264 baseline is supported. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 32 ++-- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index ea838c0..04d214d 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -74,6 +74,7 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, { struct pipe_screen *pscreen; enum pipe_video_profile p; + int va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; @@ -90,12 +91,18 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + va_status = VA_STATUS_SUCCESS; + } + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED) && + p == PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncSlice; + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncPicture; + va_status = VA_STATUS_SUCCESS; + } - return VA_STATUS_SUCCESS; + return va_status; } VAStatus @@ -114,7 +121,7 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en value = VA_RT_FORMAT_YUV420; break; case VAConfigAttribRateControl: - value = VA_RC_NONE; + value = VA_RC_CQP | VA_RC_CBR; break; default: value = VA_ATTRIB_NOT_SUPPORTED; @@ -159,10 +166,15 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - if (entrypoint != VAEntrypointVLD) + if (entrypoint == VAEntrypointVLD) { + if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + else if (entrypoint == VAEntrypointEncSlice) { + if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED)) + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + else return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncPicture) -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 09/11] st/va: add functions for VAAPI encode
Add necessary functions/changes for VAAPI encoding to buffer and picture. These changes will allow driver to handle all Vaapi encode related operations. This patch doesn't change the Vaapi decode behaviour. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/buffer.c | 6 ++ src/gallium/state_trackers/va/picture.c| 162 - src/gallium/state_trackers/va/va_private.h | 3 + 3 files changed, 169 insertions(+), 2 deletions(-) diff --git a/src/gallium/state_trackers/va/buffer.c b/src/gallium/state_trackers/va/buffer.c index 7d3167b..dfcebbe 100644 --- a/src/gallium/state_trackers/va/buffer.c +++ b/src/gallium/state_trackers/va/buffer.c @@ -133,6 +133,12 @@ vlVaMapBuffer(VADriverContextP ctx, VABufferID buf_id, void **pbuff) if (!buf->derived_surface.transfer || !*pbuff) return VA_STATUS_ERROR_INVALID_BUFFER; + if (buf->type == VAEncCodedBufferType) { + ((VACodedBufferSegment*)buf->data)->buf = *pbuff; + ((VACodedBufferSegment*)buf->data)->size = buf->coded_size; + ((VACodedBufferSegment*)buf->data)->next = NULL; + *pbuff = buf->data; + } } else { pipe_mutex_unlock(drv->mutex); *pbuff = buf->data; diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 89ac024..c244619 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -78,7 +78,8 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende return VA_STATUS_SUCCESS; } - context->decoder->begin_frame(context->decoder, context->target, >desc.base); + if (context->decoder->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) + context->decoder->begin_frame(context->decoder, context->target, >desc.base); return VA_STATUS_SUCCESS; } @@ -278,6 +279,132 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) num_buffers, (const void * const*)buffers, sizes); } +static VAStatus +handleVAEncMiscParameterTypeRateControl(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAEncMiscParameterRateControl *rc = (VAEncMiscParameterRateControl *)misc->data; + if (context->desc.h264enc.rate_ctrl.rate_ctrl_method == + PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT) + context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second; + else + context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second * rc->target_percentage; + context->desc.h264enc.rate_ctrl.peak_bitrate = rc->bits_per_second; + if (context->desc.h264enc.rate_ctrl.target_bitrate < 200) + context->desc.h264enc.rate_ctrl.vbv_buffer_size = MIN2((context->desc.h264enc.rate_ctrl.target_bitrate * 2.75), 200); + else + context->desc.h264enc.rate_ctrl.vbv_buffer_size = context->desc.h264enc.rate_ctrl.target_bitrate; + + return VA_STATUS_SUCCESS; +} + +static VAStatus +handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + VAEncSequenceParameterBufferH264 *h264 = (VAEncSequenceParameterBufferH264 *)buf->data; + if (!context->decoder) { + context->templat.max_references = h264->max_num_ref_frames; + context->templat.level = h264->level_idc; + context->decoder = drv->pipe->create_video_codec(drv->pipe, >templat); + if (!context->decoder) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + context->desc.h264enc.gop_size = h264->intra_idr_period; + return VA_STATUS_SUCCESS; +} + +static VAStatus +handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) +{ + VAStatus vaStatus = VA_STATUS_SUCCESS; + VAEncMiscParameterBuffer *misc; + misc = buf->data; + + switch (misc->type) { + case VAEncMiscParameterTypeRateControl: + vaStatus = handleVAEncMiscParameterTypeRateControl(context, misc); + break; + + default: + break; + } + + return vaStatus; +} + +static VAStatus +handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + VAEncPictureParameterBufferH264 *h264; + vlVaBuffer *coded_buf; + + h264 = buf->data; + context->desc.h264enc.frame_num = h264->frame_num; + context->desc.h264enc.not_referenced = false; + context->desc.h264enc.is_idr = (h264->pic_fields.bits.idr_pic_flag == 1); + context->desc.h264enc.pic_order_cnt = h264->CurrPic.TopFieldOrderCnt / 2; + if (context->desc.h264enc.is_idr) + context->desc.h264enc.i_remain = 1; + else + context->desc.h264enc.i_remain = 0; + + context->desc.h264enc.p_remain = context->desc.h264enc.gop_size - context->desc.h264enc.gop_cnt - context->desc.h264enc.i_remain; +
[Mesa-dev] [PATCH 06/11] vl/util: add copy func for yv12image to nv12surface
Add function to copy from yv12 image to nv12 surface for VAAPI putimage call. We need this function in VaPutImage call where copying from yv12 image to nv12 surface for encoding. Existing function can't be used because it only work for copying from yv12 surface to nv12 image in Vaapi. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/auxiliary/util/u_video.h | 23 +++ 1 file changed, 23 insertions(+) diff --git a/src/gallium/auxiliary/util/u_video.h b/src/gallium/auxiliary/util/u_video.h index 9196afc..d147295 100644 --- a/src/gallium/auxiliary/util/u_video.h +++ b/src/gallium/auxiliary/util/u_video.h @@ -130,6 +130,29 @@ u_copy_yv12_to_nv12(void *const *destination_data, } static inline void +u_copy_yv12_img_to_nv12_surf(uint8_t *const *src, + uint8_t *dest, + int *offset, + int field) +{ + if (field == 0) { + for (int i = 0; i < offset[1] ; i++) + dest[i] = src[field][i]; + } else if (field == 1) { + bool odd = false; + for (int i = 0; i < (offset[1]/2) ; i++){ + if (odd == false) { +dest[i] = src[field][i/2]; +odd = true; + } else { +dest[i] = src[field+1][i/2]; +odd = false; + } + } + } +} + +static inline void u_copy_swap422_packed(void *const *destination_data, uint32_t const *destination_pitches, int src_plane, int src_field, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 05/11] st/va: add encode entrypoint
VAAPI passes PIPE_VIDEO_ENTRYPOINT_ENCODE as entry point for encoding case. We will save this encode entry point in config. config_id was used as profile previously. Now, config has both profile and entrypoint field, and config_id is used to get the config object. Later on, we pass this entrypoint to context->templat.entrypoint instead of always hardcoded to PIPE_VIDEO_ENTRYPOINT_BITSTREAM for decoding case previously. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 61 +++--- src/gallium/state_trackers/va/context.c| 57 src/gallium/state_trackers/va/surface.c| 12 -- src/gallium/state_trackers/va/va_private.h | 5 +++ 4 files changed, 103 insertions(+), 32 deletions(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 9ca0aa8..73704a1 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -34,6 +34,8 @@ #include "va_private.h" +#include "util/u_handle_table.h" + DEBUG_GET_ONCE_BOOL_OPTION(mpeg4, "VAAPI_MPEG4_ENABLED", false) VAStatus @@ -128,14 +130,27 @@ VAStatus vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id) { + vlVaDriver *drv; + vlVaConfig *config; struct pipe_screen *pscreen; enum pipe_video_profile p; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = CALLOC(1, sizeof(vlVaConfig)); + if (!config) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + if (profile == VAProfileNone && entrypoint == VAEntrypointVideoProc) { - *config_id = PIPE_VIDEO_PROFILE_UNKNOWN; + config->entrypoint = VAEntrypointVideoProc; + config->profile = PIPE_VIDEO_PROFILE_UNKNOWN; + *config_id = handle_table_add(drv->htab, config); return VA_STATUS_SUCCESS; } @@ -150,7 +165,14 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin if (entrypoint != VAEntrypointVLD) return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; - *config_id = p; + if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncPicture) + config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE; + else + config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM; + + config->profile = p; + + *config_id = handle_table_add(drv->htab, config); return VA_STATUS_SUCCESS; } @@ -158,9 +180,25 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin VAStatus vlVaDestroyConfig(VADriverContextP ctx, VAConfigID config_id) { + vlVaDriver *drv; + vlVaConfig *config; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = handle_table_get(drv->htab, config_id); + + if (!config) + return VA_STATUS_ERROR_INVALID_CONFIG; + + FREE(config); + handle_table_remove(drv->htab, config_id); + return VA_STATUS_SUCCESS; } @@ -168,18 +206,31 @@ VAStatus vlVaQueryConfigAttributes(VADriverContextP ctx, VAConfigID config_id, VAProfile *profile, VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list, int *num_attribs) { + vlVaDriver *drv; + vlVaConfig *config; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - *profile = PipeToProfile(config_id); + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = handle_table_get(drv->htab, config_id); + + if (!config) + return VA_STATUS_ERROR_INVALID_CONFIG; + + *profile = PipeToProfile(config->profile); - if (config_id == PIPE_VIDEO_PROFILE_UNKNOWN) { + if (config->profile == PIPE_VIDEO_PROFILE_UNKNOWN) { *entrypoint = VAEntrypointVideoProc; *num_attribs = 0; return VA_STATUS_SUCCESS; } - *entrypoint = VAEntrypointVLD; + *entrypoint = config->entrypoint; *num_attribs = 1; attrib_list[0].type = VAConfigAttribRTFormat; diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index 402fbb2..b4334f4 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -195,18 +195,21 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, { vlVaDriver *drv; vlVaContext *context; + vlVaConfig *config; int is_vpp; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - is_vpp = config_id == PIPE_VIDEO_PROFILE_UNKNOWN && !picture_width && + drv = VL_VA_DRIVER(ctx); + config = handle_table_get(drv->htab, config_id); + +
[Mesa-dev] [PATCH 07/11] st/va: add conversion for yv12 to nv12in putimage
For putimage call, if image format is yv12 (or IYUV with U V field swap) and surface format is nv12, then we need to convert yv12 to nv12 and then copy the converted data from image to surface. We can't use the existing logic where surface is destroyed and re-created with yv12 format. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/image.c | 33 ++--- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c index 1b956e3..47895ee 100644 --- a/src/gallium/state_trackers/va/image.c +++ b/src/gallium/state_trackers/va/image.c @@ -471,7 +471,9 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, return VA_STATUS_ERROR_OPERATION_FAILED; } - if (format != surf->buffer->buffer_format) { + if ((format != surf->buffer->buffer_format) && + ((format != PIPE_FORMAT_YV12) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12)) && + ((format != PIPE_FORMAT_IYUV) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12))) { struct pipe_video_buffer *tmp_buf; struct pipe_video_buffer templat = surf->templat; @@ -513,12 +515,29 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, unsigned width, height; if (!views[i]) continue; vlVaVideoSurfaceSize(surf, i, , ); - for (j = 0; j < views[i]->texture->array_size; ++j) { - struct pipe_box dst_box = {0, 0, j, width, height, 1}; - drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0, -PIPE_TRANSFER_WRITE, _box, -data[i] + pitches[i] * j, -pitches[i] * views[i]->texture->array_size, 0); + if ((format == PIPE_FORMAT_YV12) || (format == PIPE_FORMAT_IYUV) && +(surf->buffer->buffer_format == PIPE_FORMAT_NV12)) { + struct pipe_transfer *transfer = NULL; + uint8_t *map = NULL; + struct pipe_box dst_box_1 = {0, 0, 0, width, height, 1}; + map = drv->pipe->transfer_map(drv->pipe, + views[i]->texture, + 0, + PIPE_TRANSFER_DISCARD_RANGE, + _box_1, ); + if (map == NULL) +return VA_STATUS_ERROR_OPERATION_FAILED; + + u_copy_yv12_img_to_nv12_surf (data, map, vaimage->offsets, i); + pipe_transfer_unmap(drv->pipe, transfer); + } else { + for (j = 0; j < views[i]->texture->array_size; ++j) { +struct pipe_box dst_box = {0, 0, j, width, height, 1}; +drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0, + PIPE_TRANSFER_WRITE, _box, + data[i] + pitches[i] * j, + pitches[i] * views[i]->texture->array_size, 0); + } } } pipe_mutex_unlock(drv->mutex); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 02/11] vl: add entry point
Add entrypoint to distinguish H.264 decode and encode. For example, in patch 5/11 when is calling "VaCreateContext", "pps" and "sps" shouldn't be allocated for H.264 encoding. So we need to use the entry_point to determine this is H.264 decode or H.264 encode. We can use config to determine the entrypoint since config_id is passed to us for VaCreateContext call. However, for VaDestoyContext call, only context_id is passed to us. So we need to know the entrypoint in order to not free the pps/sps for encoding case. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/include/pipe/p_video_state.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 754d013..39b3905 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -131,6 +131,7 @@ enum pipe_h264_enc_rate_control_method struct pipe_picture_desc { enum pipe_video_profile profile; + enum pipe_video_entrypoint entry_point; }; struct pipe_quant_matrix -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 08/11] st/va: get rate control method from configattrib
Rate control method is passed from app to driver through config attrib list. That is why we need to store this rate control method to config. And later on, we will pass this value to context->desc.h264enc.rate_ctrl.rate_ctrl_method. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 11 +++ src/gallium/state_trackers/va/context.c| 3 ++- src/gallium/state_trackers/va/va_private.h | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 73704a1..ea838c0 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -172,6 +172,17 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin config->profile = p; + for (int i = 0; i rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT; + else if (attrib_list[i].value == VA_RC_VBR) +config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE; + else +config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE; + } + } + *config_id = handle_table_add(drv->htab, config); return VA_STATUS_SUCCESS; diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index b4334f4..c67ed1f 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -274,7 +274,8 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, context->desc.base.profile = config->profile; context->desc.base.entry_point = config->entrypoint; - + if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) + context->desc.h264enc.rate_ctrl.rate_ctrl_method = config->rc; pipe_mutex_lock(drv->mutex); *context_id = handle_table_add(drv->htab, context); pipe_mutex_unlock(drv->mutex); diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index 723983d..ad9010a 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -246,6 +246,7 @@ typedef struct { typedef struct { VAEntrypoint entrypoint; enum pipe_video_profile profile; + enum pipe_h264_enc_rate_control_method rc; } vlVaConfig; typedef struct { -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 10/11] st/va: add preset values for VAAPI encode
Add some hardcoded values hardware needs mainly for rate control purpose. With previously hardcoded values for OMX, the rate control result is not correct. This change fixed the rate control result by setting correct values for Vaapi. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/picture.c | 36 + 1 file changed, 36 insertions(+) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 12b3cd1..343afd7 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -95,6 +95,41 @@ vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id, *ref_frame = NULL; } +static void +getEncParamPreset(vlVaContext *context) +{ + //motion estimation preset + context->desc.h264enc.motion_est.motion_est_quarter_pixel = 0x0001; + context->desc.h264enc.motion_est.lsmvert = 0x0002; + context->desc.h264enc.motion_est.enc_disable_sub_mode = 0x0078; + context->desc.h264enc.motion_est.enc_en_ime_overw_dis_subm = 0x0001; + context->desc.h264enc.motion_est.enc_ime_overw_dis_subm_no = 0x0001; + context->desc.h264enc.motion_est.enc_ime2_search_range_x = 0x0004; + context->desc.h264enc.motion_est.enc_ime2_search_range_y = 0x0004; + + //pic control preset + context->desc.h264enc.pic_ctrl.enc_cabac_enable = 0x0001; + context->desc.h264enc.pic_ctrl.enc_constraint_set_flags = 0x0040; + + //rate control + context->desc.h264enc.rate_ctrl.vbv_buffer_size = 2000; + if (context->desc.h264enc.rate_ctrl.frame_rate_num == 0) { + context->desc.h264enc.rate_ctrl.frame_rate_num = 30; + context->desc.h264enc.rate_ctrl.frame_rate_den = 1; + } + context->desc.h264enc.rate_ctrl.vbv_buf_lv = 48; + context->desc.h264enc.rate_ctrl.fill_data_enable = 1; + context->desc.h264enc.rate_ctrl.enforce_hrd = 1; + context->desc.h264enc.enable_vui = false; + context->desc.h264enc.rate_ctrl.target_bits_picture = + context->desc.h264enc.rate_ctrl.target_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_integer = + context->desc.h264enc.rate_ctrl.peak_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_fraction = 0; + + context->desc.h264enc.ref_pic_mode = 0x0201; +} + static VAStatus handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) { @@ -513,6 +548,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { coded_buf = context->coded_buf; + getEncParamPreset(context); context->decoder->begin_frame(context->decoder, context->target, >desc.base); context->decoder->encode_bitstream(context->decoder, context->target, coded_buf->derived_surface.resource, ); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 06/11] vl/util: add copy func for yv12image to nv12surface
Add function to copy from yv12 image to nv12 surface for VAAPI putimage call. We need this function in VaPutImage call where copying from yv12 image to nv12 surface for encoding. Existing function can't be used because it only work for copying from yv12 surface to nv12 image in Vaapi. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/auxiliary/util/u_video.h | 23 +++ 1 file changed, 23 insertions(+) diff --git a/src/gallium/auxiliary/util/u_video.h b/src/gallium/auxiliary/util/u_video.h index 9196afc..d147295 100644 --- a/src/gallium/auxiliary/util/u_video.h +++ b/src/gallium/auxiliary/util/u_video.h @@ -130,6 +130,29 @@ u_copy_yv12_to_nv12(void *const *destination_data, } static inline void +u_copy_yv12_img_to_nv12_surf(uint8_t *const *src, + uint8_t *dest, + int *offset, + int field) +{ + if (field == 0) { + for (int i = 0; i < offset[1] ; i++) + dest[i] = src[field][i]; + } else if (field == 1) { + bool odd = false; + for (int i = 0; i < (offset[1]/2) ; i++){ + if (odd == false) { +dest[i] = src[field][i/2]; +odd = true; + } else { +dest[i] = src[field+1][i/2]; +odd = false; + } + } + } +} + +static inline void u_copy_swap422_packed(void *const *destination_data, uint32_t const *destination_pitches, int src_plane, int src_field, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 02/11] vl: add entry point
Add entrypoint to distinguish H.264 decode and encode. For example, in patch 5/11 when is calling "VaCreateContext", "pps" and "sps" shouldn't be allocated for H.264 encoding. So we need to use the entry_point to determine this is H.264 decode or H.264 encode. We can use config to determine the entrypoint since config_id is passed to us for VaCreateContext call. However, for VaDestoyContext call, only context_id is passed to us. So we need to know the entrypoint in order to not free the pps/sps for encoding case. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/include/pipe/p_video_state.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 754d013..39b3905 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -131,6 +131,7 @@ enum pipe_h264_enc_rate_control_method struct pipe_picture_desc { enum pipe_video_profile profile; + enum pipe_video_entrypoint entry_point; }; struct pipe_quant_matrix -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 11/11] st/va: enable h264 VAAPI encode
Enable H.264 VAAPI encoding through config. Currently only H.264 baseline is supported. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 32 ++-- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index ea838c0..04d214d 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -74,6 +74,7 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, { struct pipe_screen *pscreen; enum pipe_video_profile p; + int va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; @@ -90,12 +91,18 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + va_status = VA_STATUS_SUCCESS; + } + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED) && + p == PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncSlice; + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncPicture; + va_status = VA_STATUS_SUCCESS; + } - return VA_STATUS_SUCCESS; + return va_status; } VAStatus @@ -114,7 +121,7 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en value = VA_RT_FORMAT_YUV420; break; case VAConfigAttribRateControl: - value = VA_RC_NONE; + value = VA_RC_CQP | VA_RC_CBR; break; default: value = VA_ATTRIB_NOT_SUPPORTED; @@ -159,10 +166,15 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - if (entrypoint != VAEntrypointVLD) + if (entrypoint == VAEntrypointVLD) { + if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + else if (entrypoint == VAEntrypointEncSlice) { + if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED)) + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + else return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncPicture) -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 09/11] st/va: add functions for VAAPI encode
Add necessary functions/changes for VAAPI encoding to buffer and picture. These changes will allow driver to handle all Vaapi encode related operations. This patch doesn't change the Vaapi decode behaviour. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/buffer.c | 6 ++ src/gallium/state_trackers/va/picture.c| 161 - src/gallium/state_trackers/va/va_private.h | 3 + 3 files changed, 168 insertions(+), 2 deletions(-) diff --git a/src/gallium/state_trackers/va/buffer.c b/src/gallium/state_trackers/va/buffer.c index 7d3167b..dfcebbe 100644 --- a/src/gallium/state_trackers/va/buffer.c +++ b/src/gallium/state_trackers/va/buffer.c @@ -133,6 +133,12 @@ vlVaMapBuffer(VADriverContextP ctx, VABufferID buf_id, void **pbuff) if (!buf->derived_surface.transfer || !*pbuff) return VA_STATUS_ERROR_INVALID_BUFFER; + if (buf->type == VAEncCodedBufferType) { + ((VACodedBufferSegment*)buf->data)->buf = *pbuff; + ((VACodedBufferSegment*)buf->data)->size = buf->coded_size; + ((VACodedBufferSegment*)buf->data)->next = NULL; + *pbuff = buf->data; + } } else { pipe_mutex_unlock(drv->mutex); *pbuff = buf->data; diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 89ac024..12b3cd1 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -78,7 +78,8 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende return VA_STATUS_SUCCESS; } - context->decoder->begin_frame(context->decoder, context->target, >desc.base); + if (context->decoder->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) + context->decoder->begin_frame(context->decoder, context->target, >desc.base); return VA_STATUS_SUCCESS; } @@ -278,6 +279,131 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) num_buffers, (const void * const*)buffers, sizes); } +static VAStatus +handleVAEncMiscParameterTypeRateControl(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAEncMiscParameterRateControl *rc = (VAEncMiscParameterRateControl *)misc->data; + if (context->desc.h264enc.rate_ctrl.rate_ctrl_method == + PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT) + context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second; + else + context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second * rc->target_percentage; + context->desc.h264enc.rate_ctrl.peak_bitrate = rc->bits_per_second; + if (context->desc.h264enc.rate_ctrl.target_bitrate < 200) + context->desc.h264enc.rate_ctrl.vbv_buffer_size = MIN2((context->desc.h264enc.rate_ctrl.target_bitrate * 2.75), 200); + else + context->desc.h264enc.rate_ctrl.vbv_buffer_size = context->desc.h264enc.rate_ctrl.target_bitrate; + + return VA_STATUS_SUCCESS; +} + +static VAStatus +handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + VAEncSequenceParameterBufferH264 *h264 = (VAEncSequenceParameterBufferH264 *)buf->data; + if (!context->decoder) { + context->templat.max_references = h264->max_num_ref_frames; + context->templat.level = h264->level_idc; + context->decoder = drv->pipe->create_video_codec(drv->pipe, >templat); + if (!context->decoder) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + context->desc.h264enc.gop_size = h264->intra_idr_period; + return VA_STATUS_SUCCESS; +} + +static VAStatus +handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) +{ + VAStatus vaStatus = VA_STATUS_SUCCESS; + VAEncMiscParameterBuffer *misc; + misc = buf->data; + + switch (misc->type) { + case VAEncMiscParameterTypeRateControl: + vaStatus = handleVAEncMiscParameterTypeRateControl(context, misc); + break; + + default: + break; + } + + return vaStatus; +} + +static VAStatus +handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + VAEncPictureParameterBufferH264 *h264; + vlVaBuffer *coded_buf; + + h264 = buf->data; + context->desc.h264enc.frame_num = h264->frame_num; + context->desc.h264enc.not_referenced = false; + context->desc.h264enc.is_idr = (h264->pic_fields.bits.idr_pic_flag == 1); + context->desc.h264enc.pic_order_cnt = h264->CurrPic.TopFieldOrderCnt / 2; + if (context->desc.h264enc.is_idr) + context->desc.h264enc.i_remain = 1; + else + context->desc.h264enc.i_remain = 0; + + context->desc.h264enc.p_remain = context->desc.h264enc.gop_size - context->desc.h264enc.gop_cnt - context->desc.h264enc.i_remain; + + coded_buf = handle
[Mesa-dev] [PATCH 07/11] st/va: add conversion for yv12 to nv12in putimage
For putimage call, if image format is yv12 (or IYUV with U V field swap) and surface format is nv12, then we need to convert yv12 to nv12 and then copy the converted data from image to surface. We can't use the existing logic where surface is destroyed and re-created with yv12 format. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/image.c | 33 ++--- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c index 1b956e3..47895ee 100644 --- a/src/gallium/state_trackers/va/image.c +++ b/src/gallium/state_trackers/va/image.c @@ -471,7 +471,9 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, return VA_STATUS_ERROR_OPERATION_FAILED; } - if (format != surf->buffer->buffer_format) { + if ((format != surf->buffer->buffer_format) && + ((format != PIPE_FORMAT_YV12) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12)) && + ((format != PIPE_FORMAT_IYUV) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12))) { struct pipe_video_buffer *tmp_buf; struct pipe_video_buffer templat = surf->templat; @@ -513,12 +515,29 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, unsigned width, height; if (!views[i]) continue; vlVaVideoSurfaceSize(surf, i, , ); - for (j = 0; j < views[i]->texture->array_size; ++j) { - struct pipe_box dst_box = {0, 0, j, width, height, 1}; - drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0, -PIPE_TRANSFER_WRITE, _box, -data[i] + pitches[i] * j, -pitches[i] * views[i]->texture->array_size, 0); + if ((format == PIPE_FORMAT_YV12) || (format == PIPE_FORMAT_IYUV) && +(surf->buffer->buffer_format == PIPE_FORMAT_NV12)) { + struct pipe_transfer *transfer = NULL; + uint8_t *map = NULL; + struct pipe_box dst_box_1 = {0, 0, 0, width, height, 1}; + map = drv->pipe->transfer_map(drv->pipe, + views[i]->texture, + 0, + PIPE_TRANSFER_DISCARD_RANGE, + _box_1, ); + if (map == NULL) +return VA_STATUS_ERROR_OPERATION_FAILED; + + u_copy_yv12_img_to_nv12_surf (data, map, vaimage->offsets, i); + pipe_transfer_unmap(drv->pipe, transfer); + } else { + for (j = 0; j < views[i]->texture->array_size; ++j) { +struct pipe_box dst_box = {0, 0, j, width, height, 1}; +drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0, + PIPE_TRANSFER_WRITE, _box, + data[i] + pitches[i] * j, + pitches[i] * views[i]->texture->array_size, 0); + } } } pipe_mutex_unlock(drv->mutex); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 05/11] st/va: add encode entrypoint
VAAPI passes PIPE_VIDEO_ENTRYPOINT_ENCODE as entry point for encoding case. We will save this encode entry point in config. config_id was used as profile previously. Now, config has both profile and entrypoint field, and config_id is used to get the config object. Later on, we pass this entrypoint to context->templat.entrypoint instead of always hardcoded to PIPE_VIDEO_ENTRYPOINT_BITSTREAM for decoding case previously. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 61 +++--- src/gallium/state_trackers/va/context.c| 57 src/gallium/state_trackers/va/surface.c| 12 -- src/gallium/state_trackers/va/va_private.h | 5 +++ 4 files changed, 103 insertions(+), 32 deletions(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 9ca0aa8..73704a1 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -34,6 +34,8 @@ #include "va_private.h" +#include "util/u_handle_table.h" + DEBUG_GET_ONCE_BOOL_OPTION(mpeg4, "VAAPI_MPEG4_ENABLED", false) VAStatus @@ -128,14 +130,27 @@ VAStatus vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id) { + vlVaDriver *drv; + vlVaConfig *config; struct pipe_screen *pscreen; enum pipe_video_profile p; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = CALLOC(1, sizeof(vlVaConfig)); + if (!config) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + if (profile == VAProfileNone && entrypoint == VAEntrypointVideoProc) { - *config_id = PIPE_VIDEO_PROFILE_UNKNOWN; + config->entrypoint = VAEntrypointVideoProc; + config->profile = PIPE_VIDEO_PROFILE_UNKNOWN; + *config_id = handle_table_add(drv->htab, config); return VA_STATUS_SUCCESS; } @@ -150,7 +165,14 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin if (entrypoint != VAEntrypointVLD) return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; - *config_id = p; + if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncPicture) + config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE; + else + config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM; + + config->profile = p; + + *config_id = handle_table_add(drv->htab, config); return VA_STATUS_SUCCESS; } @@ -158,9 +180,25 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin VAStatus vlVaDestroyConfig(VADriverContextP ctx, VAConfigID config_id) { + vlVaDriver *drv; + vlVaConfig *config; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = handle_table_get(drv->htab, config_id); + + if (!config) + return VA_STATUS_ERROR_INVALID_CONFIG; + + FREE(config); + handle_table_remove(drv->htab, config_id); + return VA_STATUS_SUCCESS; } @@ -168,18 +206,31 @@ VAStatus vlVaQueryConfigAttributes(VADriverContextP ctx, VAConfigID config_id, VAProfile *profile, VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list, int *num_attribs) { + vlVaDriver *drv; + vlVaConfig *config; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - *profile = PipeToProfile(config_id); + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = handle_table_get(drv->htab, config_id); + + if (!config) + return VA_STATUS_ERROR_INVALID_CONFIG; + + *profile = PipeToProfile(config->profile); - if (config_id == PIPE_VIDEO_PROFILE_UNKNOWN) { + if (config->profile == PIPE_VIDEO_PROFILE_UNKNOWN) { *entrypoint = VAEntrypointVideoProc; *num_attribs = 0; return VA_STATUS_SUCCESS; } - *entrypoint = VAEntrypointVLD; + *entrypoint = config->entrypoint; *num_attribs = 1; attrib_list[0].type = VAConfigAttribRTFormat; diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index 402fbb2..b4334f4 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -195,18 +195,21 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, { vlVaDriver *drv; vlVaContext *context; + vlVaConfig *config; int is_vpp; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - is_vpp = config_id == PIPE_VIDEO_PROFILE_UNKNOWN && !picture_width && + drv = VL_VA_DRIVER(ctx); + config = handle_table_get(drv->htab, config_id); + +
[Mesa-dev] [PATCH 03/11] radeon/omx: assign previous values to new structure
Assign previously hardcoded values for OMX to newly defined structure. As a result, OMX behaviour will not change at all. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/omx/vid_enc.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/src/gallium/state_trackers/omx/vid_enc.c b/src/gallium/state_trackers/omx/vid_enc.c index d70439a..bbc7941 100644 --- a/src/gallium/state_trackers/omx/vid_enc.c +++ b/src/gallium/state_trackers/omx/vid_enc.c @@ -1006,6 +1006,14 @@ static void enc_ScaleInput(omx_base_PortType *port, struct pipe_video_buffer **v priv->current_scale_buffer %= OMX_VID_ENC_NUM_SCALING_BUFFERS; } +static void enc_GetPictureParamPreset(struct pipe_h264_enc_picture_desc *picture) +{ + picture->motion_est.enc_disable_sub_mode = 0x00fe; + picture->motion_est.enc_ime2_search_range_x = 0x0001; + picture->motion_est.enc_ime2_search_range_y = 0x0001; + picture->pic_ctrl.enc_constraint_set_flags = 0x0040; +} + static void enc_ControlPicture(omx_base_PortType *port, struct pipe_h264_enc_picture_desc *picture) { OMX_COMPONENTTYPE* comp = port->standCompContainer; @@ -1064,6 +1072,8 @@ static void enc_ControlPicture(omx_base_PortType *port, struct pipe_h264_enc_pic picture->frame_num = priv->frame_num; picture->ref_idx_l0 = priv->ref_idx_l0; picture->ref_idx_l1 = priv->ref_idx_l1; + picture->enable_vui = (picture->rate_ctrl.frame_rate_num != 0); + enc_GetPictureParamPreset(picture); } static void enc_HandleTask(omx_base_PortType *port, struct encode_task *task, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 07/11] st/va: add conversion for yv12 to nv12in putimage
For putimage call, if image format is yv12 (or IYUV with U V field swap) and surface format is nv12, then we need to convert yv12 to nv12 and then copy the converted data from image to surface. We can't use the existing logic where surface is destroyed and re-created with yv12 format. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/image.c | 33 ++--- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c index 1b956e3..47895ee 100644 --- a/src/gallium/state_trackers/va/image.c +++ b/src/gallium/state_trackers/va/image.c @@ -471,7 +471,9 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, return VA_STATUS_ERROR_OPERATION_FAILED; } - if (format != surf->buffer->buffer_format) { + if ((format != surf->buffer->buffer_format) && + ((format != PIPE_FORMAT_YV12) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12)) && + ((format != PIPE_FORMAT_IYUV) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12))) { struct pipe_video_buffer *tmp_buf; struct pipe_video_buffer templat = surf->templat; @@ -513,12 +515,29 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, unsigned width, height; if (!views[i]) continue; vlVaVideoSurfaceSize(surf, i, , ); - for (j = 0; j < views[i]->texture->array_size; ++j) { - struct pipe_box dst_box = {0, 0, j, width, height, 1}; - drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0, -PIPE_TRANSFER_WRITE, _box, -data[i] + pitches[i] * j, -pitches[i] * views[i]->texture->array_size, 0); + if ((format == PIPE_FORMAT_YV12) || (format == PIPE_FORMAT_IYUV) && +(surf->buffer->buffer_format == PIPE_FORMAT_NV12)) { + struct pipe_transfer *transfer = NULL; + uint8_t *map = NULL; + struct pipe_box dst_box_1 = {0, 0, 0, width, height, 1}; + map = drv->pipe->transfer_map(drv->pipe, + views[i]->texture, + 0, + PIPE_TRANSFER_DISCARD_RANGE, + _box_1, ); + if (map == NULL) +return VA_STATUS_ERROR_OPERATION_FAILED; + + u_copy_yv12_img_to_nv12_surf (data, map, vaimage->offsets, i); + pipe_transfer_unmap(drv->pipe, transfer); + } else { + for (j = 0; j < views[i]->texture->array_size; ++j) { +struct pipe_box dst_box = {0, 0, j, width, height, 1}; +drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0, + PIPE_TRANSFER_WRITE, _box, + data[i] + pitches[i] * j, + pitches[i] * views[i]->texture->array_size, 0); + } } } pipe_mutex_unlock(drv->mutex); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 02/11] vl: add entry point
Add entry point for encoding which previously hardcoded for decoding purpose only Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/include/pipe/p_video_state.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 754d013..39b3905 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -131,6 +131,7 @@ enum pipe_h264_enc_rate_control_method struct pipe_picture_desc { enum pipe_video_profile profile; + enum pipe_video_entrypoint entry_point; }; struct pipe_quant_matrix -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 04/11] radeon/vce: handle newly added parameters
Replace the previous hardcoded value with newly defined parameters Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/drivers/radeon/radeon_vce_52.c | 33 ++ 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vce_52.c b/src/gallium/drivers/radeon/radeon_vce_52.c index 7d33313..7986eb8 100644 --- a/src/gallium/drivers/radeon/radeon_vce_52.c +++ b/src/gallium/drivers/radeon/radeon_vce_52.c @@ -48,13 +48,14 @@ static void get_rate_control_param(struct rvce_encoder *enc, struct pipe_h264_en enc->enc_pic.rc.quant_i_frames = pic->quant_i_frames; enc->enc_pic.rc.quant_p_frames = pic->quant_p_frames; enc->enc_pic.rc.quant_b_frames = pic->quant_b_frames; + enc->enc_pic.rc.gop_size = pic->gop_size; enc->enc_pic.rc.frame_rate_num = pic->rate_ctrl.frame_rate_num; enc->enc_pic.rc.frame_rate_den = pic->rate_ctrl.frame_rate_den; enc->enc_pic.rc.max_qp = 51; enc->enc_pic.rc.vbv_buffer_size = pic->rate_ctrl.vbv_buffer_size; - enc->enc_pic.rc.vbv_buf_lv = 0; - enc->enc_pic.rc.fill_data_enable = 0; - enc->enc_pic.rc.enforce_hrd = 0; + enc->enc_pic.rc.vbv_buf_lv = pic->rate_ctrl.vbv_buf_lv; + enc->enc_pic.rc.fill_data_enable = pic->rate_ctrl.fill_data_enable; + enc->enc_pic.rc.enforce_hrd = pic->rate_ctrl.enforce_hrd; enc->enc_pic.rc.target_bits_picture = pic->rate_ctrl.target_bits_picture; enc->enc_pic.rc.peak_bits_picture_integer = pic->rate_ctrl.peak_bits_picture_integer; enc->enc_pic.rc.peak_bits_picture_fraction = pic->rate_ctrl.peak_bits_picture_fraction; @@ -62,13 +63,13 @@ static void get_rate_control_param(struct rvce_encoder *enc, struct pipe_h264_en static void get_motion_estimation_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) { - enc->enc_pic.me.motion_est_quarter_pixel = 0x; - enc->enc_pic.me.enc_disable_sub_mode = 0x00fe; - enc->enc_pic.me.lsmvert = 0x; - enc->enc_pic.me.enc_en_ime_overw_dis_subm = 0x; - enc->enc_pic.me.enc_ime_overw_dis_subm_no = 0x; - enc->enc_pic.me.enc_ime2_search_range_x = 0x0001; - enc->enc_pic.me.enc_ime2_search_range_y = 0x0001; + enc->enc_pic.me.motion_est_quarter_pixel = pic->motion_est.motion_est_quarter_pixel; + enc->enc_pic.me.enc_disable_sub_mode = pic->motion_est.enc_disable_sub_mode; + enc->enc_pic.me.lsmvert = pic->motion_est.lsmvert; + enc->enc_pic.me.enc_en_ime_overw_dis_subm = pic->motion_est.enc_en_ime_overw_dis_subm; + enc->enc_pic.me.enc_ime_overw_dis_subm_no = pic->motion_est.enc_ime_overw_dis_subm_no; + enc->enc_pic.me.enc_ime2_search_range_x = pic->motion_est.enc_ime2_search_range_x; + enc->enc_pic.me.enc_ime2_search_range_y = pic->motion_est.enc_ime2_search_range_y; enc->enc_pic.me.enc_ime_decimation_search = 0x0001; enc->enc_pic.me.motion_est_half_pixel = 0x0001; enc->enc_pic.me.enc_search_range_x = 0x0010; @@ -90,8 +91,8 @@ static void get_pic_control_param(struct rvce_encoder *enc, struct pipe_h264_enc enc->enc_pic.pc.enc_max_num_ref_frames = enc->base.max_references + 1; enc->enc_pic.pc.enc_num_default_active_ref_l0 = 0x0001; enc->enc_pic.pc.enc_num_default_active_ref_l1 = 0x0001; - enc->enc_pic.pc.enc_cabac_enable = 0x; - enc->enc_pic.pc.enc_constraint_set_flags = 0x0040; + enc->enc_pic.pc.enc_cabac_enable = pic->pic_ctrl.enc_cabac_enable; + enc->enc_pic.pc.enc_constraint_set_flags = pic->pic_ctrl.enc_constraint_set_flags; enc->enc_pic.pc.enc_num_default_active_ref_l0 = 0x0001; enc->enc_pic.pc.enc_num_default_active_ref_l1 = 0x0001; } @@ -113,7 +114,7 @@ static void get_config_ext_param(struct rvce_encoder *enc) static void get_vui_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) { - enc->enc_pic.enable_vui = (pic->rate_ctrl.frame_rate_num != 0); + enc->enc_pic.enable_vui = pic->enable_vui; enc->enc_pic.vui.video_format = 0x0005; enc->enc_pic.vui.color_prim = 0x0002; enc->enc_pic.vui.transfer_char = 0x0002; @@ -149,10 +150,16 @@ void radeon_vce_52_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_pict enc->enc_pic.picture_type = pic->picture_type; enc->enc_pic.frame_num = pic->frame_num; + enc->enc_pic.frame_num_cnt = pic->frame_num_cnt; + enc->enc_pic.p_remain = pic->p_remain; + enc->enc_pic.i_remain = pic->i_remain; + enc->enc_pic.gop_cnt = pic->gop_cnt; enc->en
[Mesa-dev] [PATCH 01/11] vl: add parameters for VAAPI encode
Allow to specify more parameters in the encoding interface which previously just hardcoded in the encoder Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/include/pipe/p_video_state.h | 33 1 file changed, 33 insertions(+) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index d353be6..754d013 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -352,9 +352,29 @@ struct pipe_h264_enc_rate_control unsigned frame_rate_num; unsigned frame_rate_den; unsigned vbv_buffer_size; + unsigned vbv_buf_lv; unsigned target_bits_picture; unsigned peak_bits_picture_integer; unsigned peak_bits_picture_fraction; + unsigned fill_data_enable; + unsigned enforce_hrd; +}; + +struct pipe_h264_enc_motion_estimation +{ + unsigned motion_est_quarter_pixel; + unsigned enc_disable_sub_mode; + unsigned lsmvert; + unsigned enc_en_ime_overw_dis_subm; + unsigned enc_ime_overw_dis_subm_no; + unsigned enc_ime2_search_range_x; + unsigned enc_ime2_search_range_y; +}; + +struct pipe_h264_enc_pic_control +{ + unsigned enc_cabac_enable; + unsigned enc_constraint_set_flags; }; struct pipe_h264_enc_picture_desc @@ -363,17 +383,30 @@ struct pipe_h264_enc_picture_desc struct pipe_h264_enc_rate_control rate_ctrl; + struct pipe_h264_enc_motion_estimation motion_est; + struct pipe_h264_enc_pic_control pic_ctrl; + unsigned quant_i_frames; unsigned quant_p_frames; unsigned quant_b_frames; enum pipe_h264_enc_picture_type picture_type; unsigned frame_num; + unsigned frame_num_cnt; + unsigned p_remain; + unsigned i_remain; + unsigned idr_pic_id; + unsigned gop_cnt; unsigned pic_order_cnt; unsigned ref_idx_l0; unsigned ref_idx_l1; + unsigned gop_size; + unsigned ref_pic_mode; bool not_referenced; + bool is_idr; + bool enable_vui; + unsigned int frame_idx[32]; }; struct pipe_h265_sps -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 06/11] st/va: add copy function for yv12 image to nv12 surface
Add function to copy from yv12 image to nv12 surface for VAAPI putimage call. Existing function only work for copying from yv12 surface to nv12 image. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/auxiliary/util/u_video.h | 22 ++ 1 file changed, 22 insertions(+) diff --git a/src/gallium/auxiliary/util/u_video.h b/src/gallium/auxiliary/util/u_video.h index 9196afc..6e835d8 100644 --- a/src/gallium/auxiliary/util/u_video.h +++ b/src/gallium/auxiliary/util/u_video.h @@ -130,6 +130,28 @@ u_copy_yv12_to_nv12(void *const *destination_data, } static inline void +u_copy_yv12_img_to_nv12_surf(uint8_t *const *src, uint8_t *dest, int *offset, int field) +{ + if (field == 0) { + for (int i = 0; i < offset[1] ; i++) + dest[i] = src[field][i]; + } + else if (field == 1) { + bool odd = false; + for (int k = 0; k < (offset[1]/2) ; k++){ + if (odd == false) { + dest[k] = src[field][k/2]; + odd = true; + } + else { + dest[k] = src[field+1][k/2]; + odd = false; + } + } + } +} + +static inline void u_copy_swap422_packed(void *const *destination_data, uint32_t const *destination_pitches, int src_plane, int src_field, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 05/11] st/va: add encode entrypoint
VAAPI passes PIPE_VIDEO_ENTRYPOINT_ENCODE as entry point for encoding case. We will save this encode entry point instead of always hardcoded to PIPE_VIDEO_ENTRYPOINT_BITSTREAM for decoding case previously. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 61 +++--- src/gallium/state_trackers/va/context.c| 57 src/gallium/state_trackers/va/surface.c| 12 -- src/gallium/state_trackers/va/va_private.h | 5 +++ 4 files changed, 103 insertions(+), 32 deletions(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 9ca0aa8..73704a1 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -34,6 +34,8 @@ #include "va_private.h" +#include "util/u_handle_table.h" + DEBUG_GET_ONCE_BOOL_OPTION(mpeg4, "VAAPI_MPEG4_ENABLED", false) VAStatus @@ -128,14 +130,27 @@ VAStatus vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id) { + vlVaDriver *drv; + vlVaConfig *config; struct pipe_screen *pscreen; enum pipe_video_profile p; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = CALLOC(1, sizeof(vlVaConfig)); + if (!config) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + if (profile == VAProfileNone && entrypoint == VAEntrypointVideoProc) { - *config_id = PIPE_VIDEO_PROFILE_UNKNOWN; + config->entrypoint = VAEntrypointVideoProc; + config->profile = PIPE_VIDEO_PROFILE_UNKNOWN; + *config_id = handle_table_add(drv->htab, config); return VA_STATUS_SUCCESS; } @@ -150,7 +165,14 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin if (entrypoint != VAEntrypointVLD) return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; - *config_id = p; + if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncPicture) + config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE; + else + config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM; + + config->profile = p; + + *config_id = handle_table_add(drv->htab, config); return VA_STATUS_SUCCESS; } @@ -158,9 +180,25 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin VAStatus vlVaDestroyConfig(VADriverContextP ctx, VAConfigID config_id) { + vlVaDriver *drv; + vlVaConfig *config; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = handle_table_get(drv->htab, config_id); + + if (!config) + return VA_STATUS_ERROR_INVALID_CONFIG; + + FREE(config); + handle_table_remove(drv->htab, config_id); + return VA_STATUS_SUCCESS; } @@ -168,18 +206,31 @@ VAStatus vlVaQueryConfigAttributes(VADriverContextP ctx, VAConfigID config_id, VAProfile *profile, VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list, int *num_attribs) { + vlVaDriver *drv; + vlVaConfig *config; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - *profile = PipeToProfile(config_id); + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = handle_table_get(drv->htab, config_id); + + if (!config) + return VA_STATUS_ERROR_INVALID_CONFIG; + + *profile = PipeToProfile(config->profile); - if (config_id == PIPE_VIDEO_PROFILE_UNKNOWN) { + if (config->profile == PIPE_VIDEO_PROFILE_UNKNOWN) { *entrypoint = VAEntrypointVideoProc; *num_attribs = 0; return VA_STATUS_SUCCESS; } - *entrypoint = VAEntrypointVLD; + *entrypoint = config->entrypoint; *num_attribs = 1; attrib_list[0].type = VAConfigAttribRTFormat; diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index 402fbb2..b4334f4 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -195,18 +195,21 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, { vlVaDriver *drv; vlVaContext *context; + vlVaConfig *config; int is_vpp; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - is_vpp = config_id == PIPE_VIDEO_PROFILE_UNKNOWN && !picture_width && + drv = VL_VA_DRIVER(ctx); + config = handle_table_get(drv->htab, config_id); + + is_vpp = config->profile == PIPE_VIDEO_PROFILE_UNKNOWN && !picture_width && !picture_height && !flag && !render_targets && !num_render_targets; if (!(picture_width
[Mesa-dev] [PATCH 10/11] st/va: add preset values for VAAPI encode
Add some hardcoded values hardware needs mainly for rate control purpose. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/picture.c | 36 + 1 file changed, 36 insertions(+) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 12b3cd1..343afd7 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -95,6 +95,41 @@ vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id, *ref_frame = NULL; } +static void +getEncParamPreset(vlVaContext *context) +{ + //motion estimation preset + context->desc.h264enc.motion_est.motion_est_quarter_pixel = 0x0001; + context->desc.h264enc.motion_est.lsmvert = 0x0002; + context->desc.h264enc.motion_est.enc_disable_sub_mode = 0x0078; + context->desc.h264enc.motion_est.enc_en_ime_overw_dis_subm = 0x0001; + context->desc.h264enc.motion_est.enc_ime_overw_dis_subm_no = 0x0001; + context->desc.h264enc.motion_est.enc_ime2_search_range_x = 0x0004; + context->desc.h264enc.motion_est.enc_ime2_search_range_y = 0x0004; + + //pic control preset + context->desc.h264enc.pic_ctrl.enc_cabac_enable = 0x0001; + context->desc.h264enc.pic_ctrl.enc_constraint_set_flags = 0x0040; + + //rate control + context->desc.h264enc.rate_ctrl.vbv_buffer_size = 2000; + if (context->desc.h264enc.rate_ctrl.frame_rate_num == 0) { + context->desc.h264enc.rate_ctrl.frame_rate_num = 30; + context->desc.h264enc.rate_ctrl.frame_rate_den = 1; + } + context->desc.h264enc.rate_ctrl.vbv_buf_lv = 48; + context->desc.h264enc.rate_ctrl.fill_data_enable = 1; + context->desc.h264enc.rate_ctrl.enforce_hrd = 1; + context->desc.h264enc.enable_vui = false; + context->desc.h264enc.rate_ctrl.target_bits_picture = + context->desc.h264enc.rate_ctrl.target_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_integer = + context->desc.h264enc.rate_ctrl.peak_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_fraction = 0; + + context->desc.h264enc.ref_pic_mode = 0x0201; +} + static VAStatus handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) { @@ -513,6 +548,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { coded_buf = context->coded_buf; + getEncParamPreset(context); context->decoder->begin_frame(context->decoder, context->target, >desc.base); context->decoder->encode_bitstream(context->decoder, context->target, coded_buf->derived_surface.resource, ); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 08/11] st/va: get rate control method from configattrib
Rate control method is passed from app to driver through config attrib list. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 11 +++ src/gallium/state_trackers/va/context.c| 3 ++- src/gallium/state_trackers/va/va_private.h | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 73704a1..ea838c0 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -172,6 +172,17 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin config->profile = p; + for (int i = 0; i rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT; + else if (attrib_list[i].value == VA_RC_VBR) +config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE; + else +config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE; + } + } + *config_id = handle_table_add(drv->htab, config); return VA_STATUS_SUCCESS; diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index b4334f4..c67ed1f 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -274,7 +274,8 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, context->desc.base.profile = config->profile; context->desc.base.entry_point = config->entrypoint; - + if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) + context->desc.h264enc.rate_ctrl.rate_ctrl_method = config->rc; pipe_mutex_lock(drv->mutex); *context_id = handle_table_add(drv->htab, context); pipe_mutex_unlock(drv->mutex); diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index 723983d..ad9010a 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -246,6 +246,7 @@ typedef struct { typedef struct { VAEntrypoint entrypoint; enum pipe_video_profile profile; + enum pipe_h264_enc_rate_control_method rc; } vlVaConfig; typedef struct { -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 11/11] st/va: enable h264 VAAPI encode
Enable H.264 VAAPI encoding through config. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 32 ++-- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index ea838c0..04d214d 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -74,6 +74,7 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, { struct pipe_screen *pscreen; enum pipe_video_profile p; + int va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; @@ -90,12 +91,18 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + va_status = VA_STATUS_SUCCESS; + } + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED) && + p == PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncSlice; + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncPicture; + va_status = VA_STATUS_SUCCESS; + } - return VA_STATUS_SUCCESS; + return va_status; } VAStatus @@ -114,7 +121,7 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en value = VA_RT_FORMAT_YUV420; break; case VAConfigAttribRateControl: - value = VA_RC_NONE; + value = VA_RC_CQP | VA_RC_CBR; break; default: value = VA_ATTRIB_NOT_SUPPORTED; @@ -159,10 +166,15 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - if (entrypoint != VAEntrypointVLD) + if (entrypoint == VAEntrypointVLD) { + if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + else if (entrypoint == VAEntrypointEncSlice) { + if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED)) + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + else return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncPicture) -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 09/11] st/va: add functions for VAAPI encode
Add necessary functions/changes for VAAPI encoding to buffer and picture, without affecting decode behaviour. Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/buffer.c | 6 ++ src/gallium/state_trackers/va/picture.c| 161 - src/gallium/state_trackers/va/va_private.h | 3 + 3 files changed, 168 insertions(+), 2 deletions(-) diff --git a/src/gallium/state_trackers/va/buffer.c b/src/gallium/state_trackers/va/buffer.c index 7d3167b..dfcebbe 100644 --- a/src/gallium/state_trackers/va/buffer.c +++ b/src/gallium/state_trackers/va/buffer.c @@ -133,6 +133,12 @@ vlVaMapBuffer(VADriverContextP ctx, VABufferID buf_id, void **pbuff) if (!buf->derived_surface.transfer || !*pbuff) return VA_STATUS_ERROR_INVALID_BUFFER; + if (buf->type == VAEncCodedBufferType) { + ((VACodedBufferSegment*)buf->data)->buf = *pbuff; + ((VACodedBufferSegment*)buf->data)->size = buf->coded_size; + ((VACodedBufferSegment*)buf->data)->next = NULL; + *pbuff = buf->data; + } } else { pipe_mutex_unlock(drv->mutex); *pbuff = buf->data; diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 89ac024..12b3cd1 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -78,7 +78,8 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende return VA_STATUS_SUCCESS; } - context->decoder->begin_frame(context->decoder, context->target, >desc.base); + if (context->decoder->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) + context->decoder->begin_frame(context->decoder, context->target, >desc.base); return VA_STATUS_SUCCESS; } @@ -278,6 +279,131 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) num_buffers, (const void * const*)buffers, sizes); } +static VAStatus +handleVAEncMiscParameterTypeRateControl(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAEncMiscParameterRateControl *rc = (VAEncMiscParameterRateControl *)misc->data; + if (context->desc.h264enc.rate_ctrl.rate_ctrl_method == + PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT) + context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second; + else + context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second * rc->target_percentage; + context->desc.h264enc.rate_ctrl.peak_bitrate = rc->bits_per_second; + if (context->desc.h264enc.rate_ctrl.target_bitrate < 200) + context->desc.h264enc.rate_ctrl.vbv_buffer_size = MIN2((context->desc.h264enc.rate_ctrl.target_bitrate * 2.75), 200); + else + context->desc.h264enc.rate_ctrl.vbv_buffer_size = context->desc.h264enc.rate_ctrl.target_bitrate; + + return VA_STATUS_SUCCESS; +} + +static VAStatus +handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + VAEncSequenceParameterBufferH264 *h264 = (VAEncSequenceParameterBufferH264 *)buf->data; + if (!context->decoder) { + context->templat.max_references = h264->max_num_ref_frames; + context->templat.level = h264->level_idc; + context->decoder = drv->pipe->create_video_codec(drv->pipe, >templat); + if (!context->decoder) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + context->desc.h264enc.gop_size = h264->intra_idr_period; + return VA_STATUS_SUCCESS; +} + +static VAStatus +handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) +{ + VAStatus vaStatus = VA_STATUS_SUCCESS; + VAEncMiscParameterBuffer *misc; + misc = buf->data; + + switch (misc->type) { + case VAEncMiscParameterTypeRateControl: + vaStatus = handleVAEncMiscParameterTypeRateControl(context, misc); + break; + + default: + break; + } + + return vaStatus; +} + +static VAStatus +handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + VAEncPictureParameterBufferH264 *h264; + vlVaBuffer *coded_buf; + + h264 = buf->data; + context->desc.h264enc.frame_num = h264->frame_num; + context->desc.h264enc.not_referenced = false; + context->desc.h264enc.is_idr = (h264->pic_fields.bits.idr_pic_flag == 1); + context->desc.h264enc.pic_order_cnt = h264->CurrPic.TopFieldOrderCnt / 2; + if (context->desc.h264enc.is_idr) + context->desc.h264enc.i_remain = 1; + else + context->desc.h264enc.i_remain = 0; + + context->desc.h264enc.p_remain = context->desc.h264enc.gop_size - context->desc.h264enc.gop_cnt - context->desc.h264enc.i_remain; + + coded_buf = handle_table_get(drv->htab, h264->coded_buf); + coded_buf->derived_surface.resourc
[Mesa-dev] [PATCH 03/12] st/va: add encode entrypoint
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 61 +++--- src/gallium/state_trackers/va/context.c| 57 src/gallium/state_trackers/va/surface.c| 12 -- src/gallium/state_trackers/va/va_private.h | 5 +++ 4 files changed, 103 insertions(+), 32 deletions(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 9ca0aa8..73704a1 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -34,6 +34,8 @@ #include "va_private.h" +#include "util/u_handle_table.h" + DEBUG_GET_ONCE_BOOL_OPTION(mpeg4, "VAAPI_MPEG4_ENABLED", false) VAStatus @@ -128,14 +130,27 @@ VAStatus vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id) { + vlVaDriver *drv; + vlVaConfig *config; struct pipe_screen *pscreen; enum pipe_video_profile p; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = CALLOC(1, sizeof(vlVaConfig)); + if (!config) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + if (profile == VAProfileNone && entrypoint == VAEntrypointVideoProc) { - *config_id = PIPE_VIDEO_PROFILE_UNKNOWN; + config->entrypoint = VAEntrypointVideoProc; + config->profile = PIPE_VIDEO_PROFILE_UNKNOWN; + *config_id = handle_table_add(drv->htab, config); return VA_STATUS_SUCCESS; } @@ -150,7 +165,14 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin if (entrypoint != VAEntrypointVLD) return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; - *config_id = p; + if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncPicture) + config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE; + else + config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM; + + config->profile = p; + + *config_id = handle_table_add(drv->htab, config); return VA_STATUS_SUCCESS; } @@ -158,9 +180,25 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin VAStatus vlVaDestroyConfig(VADriverContextP ctx, VAConfigID config_id) { + vlVaDriver *drv; + vlVaConfig *config; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = handle_table_get(drv->htab, config_id); + + if (!config) + return VA_STATUS_ERROR_INVALID_CONFIG; + + FREE(config); + handle_table_remove(drv->htab, config_id); + return VA_STATUS_SUCCESS; } @@ -168,18 +206,31 @@ VAStatus vlVaQueryConfigAttributes(VADriverContextP ctx, VAConfigID config_id, VAProfile *profile, VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list, int *num_attribs) { + vlVaDriver *drv; + vlVaConfig *config; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - *profile = PipeToProfile(config_id); + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = handle_table_get(drv->htab, config_id); + + if (!config) + return VA_STATUS_ERROR_INVALID_CONFIG; + + *profile = PipeToProfile(config->profile); - if (config_id == PIPE_VIDEO_PROFILE_UNKNOWN) { + if (config->profile == PIPE_VIDEO_PROFILE_UNKNOWN) { *entrypoint = VAEntrypointVideoProc; *num_attribs = 0; return VA_STATUS_SUCCESS; } - *entrypoint = VAEntrypointVLD; + *entrypoint = config->entrypoint; *num_attribs = 1; attrib_list[0].type = VAConfigAttribRTFormat; diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index 402fbb2..b4334f4 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -195,18 +195,21 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, { vlVaDriver *drv; vlVaContext *context; + vlVaConfig *config; int is_vpp; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - is_vpp = config_id == PIPE_VIDEO_PROFILE_UNKNOWN && !picture_width && + drv = VL_VA_DRIVER(ctx); + config = handle_table_get(drv->htab, config_id); + + is_vpp = config->profile == PIPE_VIDEO_PROFILE_UNKNOWN && !picture_width && !picture_height && !flag && !render_targets && !num_render_targets; if (!(picture_width && picture_height) && !is_vpp) return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT; - drv = VL_VA_DRIVER(ctx); context = CALLOC(1, sizeof(vlVaContext)); if (!context)
[Mesa-dev] [PATCH 07/12] st/va: get rate control method from configattrib
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 11 +++ src/gallium/state_trackers/va/context.c| 3 ++- src/gallium/state_trackers/va/va_private.h | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 73704a1..ea838c0 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -172,6 +172,17 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin config->profile = p; + for (int i = 0; i rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT; + else if (attrib_list[i].value == VA_RC_VBR) +config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE; + else +config->rc = PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE; + } + } + *config_id = handle_table_add(drv->htab, config); return VA_STATUS_SUCCESS; diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index b4334f4..c67ed1f 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -274,7 +274,8 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, context->desc.base.profile = config->profile; context->desc.base.entry_point = config->entrypoint; - + if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) + context->desc.h264enc.rate_ctrl.rate_ctrl_method = config->rc; pipe_mutex_lock(drv->mutex); *context_id = handle_table_add(drv->htab, context); pipe_mutex_unlock(drv->mutex); diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index 723983d..ad9010a 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -246,6 +246,7 @@ typedef struct { typedef struct { VAEntrypoint entrypoint; enum pipe_video_profile profile; + enum pipe_h264_enc_rate_control_method rc; } vlVaConfig; typedef struct { -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 10/12] radeon/omx: assign previous values to new structure
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/omx/vid_enc.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/src/gallium/state_trackers/omx/vid_enc.c b/src/gallium/state_trackers/omx/vid_enc.c index d70439a..bbc7941 100644 --- a/src/gallium/state_trackers/omx/vid_enc.c +++ b/src/gallium/state_trackers/omx/vid_enc.c @@ -1006,6 +1006,14 @@ static void enc_ScaleInput(omx_base_PortType *port, struct pipe_video_buffer **v priv->current_scale_buffer %= OMX_VID_ENC_NUM_SCALING_BUFFERS; } +static void enc_GetPictureParamPreset(struct pipe_h264_enc_picture_desc *picture) +{ + picture->motion_est.enc_disable_sub_mode = 0x00fe; + picture->motion_est.enc_ime2_search_range_x = 0x0001; + picture->motion_est.enc_ime2_search_range_y = 0x0001; + picture->pic_ctrl.enc_constraint_set_flags = 0x0040; +} + static void enc_ControlPicture(omx_base_PortType *port, struct pipe_h264_enc_picture_desc *picture) { OMX_COMPONENTTYPE* comp = port->standCompContainer; @@ -1064,6 +1072,8 @@ static void enc_ControlPicture(omx_base_PortType *port, struct pipe_h264_enc_pic picture->frame_num = priv->frame_num; picture->ref_idx_l0 = priv->ref_idx_l0; picture->ref_idx_l1 = priv->ref_idx_l1; + picture->enable_vui = (picture->rate_ctrl.frame_rate_num != 0); + enc_GetPictureParamPreset(picture); } static void enc_HandleTask(omx_base_PortType *port, struct encode_task *task, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 06/12] st/va: colorspace conversion when image is yv12 and surface is nv12
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/image.c | 48 +-- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c index 3c8cc9c..1f68169 100644 --- a/src/gallium/state_trackers/va/image.c +++ b/src/gallium/state_trackers/va/image.c @@ -499,7 +499,7 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, VAImage *vaimage; struct pipe_sampler_view **views; enum pipe_format format; - void *data[3]; + uint8_t *data[3]; unsigned pitches[3], i, j; if (!ctx) @@ -539,7 +539,9 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, return VA_STATUS_ERROR_OPERATION_FAILED; } - if (format != surf->buffer->buffer_format) { + if ((format != surf->buffer->buffer_format) && + ((format != PIPE_FORMAT_YV12) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12)) && + ((format != PIPE_FORMAT_IYUV) || (surf->buffer->buffer_format != PIPE_FORMAT_NV12))) { struct pipe_video_buffer *tmp_buf; struct pipe_video_buffer templat = surf->templat; @@ -581,12 +583,42 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, unsigned width, height; if (!views[i]) continue; vlVaVideoSurfaceSize(surf, i, , ); - for (j = 0; j < views[i]->texture->array_size; ++j) { - struct pipe_box dst_box = {0, 0, j, width, height, 1}; - drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0, -PIPE_TRANSFER_WRITE, _box, -data[i] + pitches[i] * j, -pitches[i] * views[i]->texture->array_size, 0); + if ((format == PIPE_FORMAT_YV12) || (format == PIPE_FORMAT_IYUV) && + (surf->buffer->buffer_format == PIPE_FORMAT_NV12) && (i == 1)) { + struct pipe_transfer *transfer = NULL; + uint8_t *map = NULL; + struct pipe_box dst_box_1 = {0, 0, 0, width, height, 1}; + map = drv->pipe->transfer_map(drv->pipe, + views[i]->texture, + 0, + PIPE_TRANSFER_DISCARD_RANGE, + _box_1, ); + if (map == NULL) +return VA_STATUS_ERROR_OPERATION_FAILED; + + bool odd = false; + for (unsigned int k = 0; k < ((vaimage->offsets[1])/2) ; k++){ +if (odd == false) { + map[k] = data[i][k/2]; + odd = true; +} +else { + map[k] = data[i+1][k/2]; + odd = false; +} + } + pipe_transfer_unmap(drv->pipe, transfer); + pipe_mutex_unlock(drv->mutex); + return VA_STATUS_SUCCESS; + } + else { + for (j = 0; j < views[i]->texture->array_size; ++j) { +struct pipe_box dst_box = {0, 0, j, width, height, 1}; +drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0, + PIPE_TRANSFER_WRITE, _box, + data[i] + pitches[i] * j, + pitches[i] * views[i]->texture->array_size, 0); + } } } pipe_mutex_unlock(drv->mutex); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 02/12] vl: add entry point
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/include/pipe/p_video_state.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 9cd489b..040d2f1 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -131,6 +131,7 @@ enum pipe_h264_enc_rate_control_method struct pipe_picture_desc { enum pipe_video_profile profile; + enum pipe_video_entrypoint entry_point; }; struct pipe_quant_matrix -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 04/12] st/va: use correct pitch value for deriveimage call
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/image.c | 55 --- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c index 1b956e3..c82b554 100644 --- a/src/gallium/state_trackers/va/image.c +++ b/src/gallium/state_trackers/va/image.c @@ -185,10 +185,12 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) vlVaSurface *surf; vlVaBuffer *img_buf; VAImage *img; + struct pipe_sampler_view **views; struct pipe_surface **surfaces; int w; int h; int i; + int pitch[3]; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; @@ -220,6 +222,51 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) w = align(surf->buffer->width, 2); h = align(surf->buffer->height, 2); + switch (img->format.fourcc) { + case VA_FOURCC('N','V','1','2'): + img->num_planes = 2; + break; + + case VA_FOURCC('I','4','2','0'): + case VA_FOURCC('Y','V','1','2'): + img->num_planes = 3; + break; + + case VA_FOURCC('U','Y','V','Y'): + case VA_FOURCC('Y','U','Y','V'): + case VA_FOURCC('B','G','R','A'): + case VA_FOURCC('R','G','B','A'): + case VA_FOURCC('B','G','R','X'): + case VA_FOURCC('R','G','B','X'): + img->num_planes = 1; + break; + + default: + /* VaDeriveImage is designed for contiguous planes. */ + FREE(img); + return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT; + } + + views = surf->buffer->get_sampler_view_planes(surf->buffer); + if (!views) + return VA_STATUS_ERROR_OPERATION_FAILED; + + for (i = 0; i < img->num_planes; i++) { + unsigned width, height; + if (!views[i]) continue; + vlVaVideoSurfaceSize(surf, i, , ); + struct pipe_box box = {0, 0, 0, width, height, 1}; + struct pipe_transfer *transfer; + uint8_t *map; + map = drv->pipe->transfer_map(drv->pipe, views[i]->texture, 0, +PIPE_TRANSFER_READ, , ); + if (!map) + return VA_STATUS_ERROR_OPERATION_FAILED; + + pitch[i] = transfer->stride; + pipe_transfer_unmap(drv->pipe, transfer); + } + for (i = 0; i < ARRAY_SIZE(formats); ++i) { if (img->format.fourcc == formats[i].fourcc) { img->format = formats[i]; @@ -231,9 +278,9 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) case VA_FOURCC('U','Y','V','Y'): case VA_FOURCC('Y','U','Y','V'): img->num_planes = 1; - img->pitches[0] = w * 2; + img->pitches[0] = pitch[0] * 2; img->offsets[0] = 0; - img->data_size = w * h * 2; + img->data_size = pitch[0] * h * 2; break; case VA_FOURCC('B','G','R','A'): @@ -241,9 +288,9 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) case VA_FOURCC('B','G','R','X'): case VA_FOURCC('R','G','B','X'): img->num_planes = 1; - img->pitches[0] = w * 4; + img->pitches[0] = pitch[0] * 4; img->offsets[0] = 0; - img->data_size = w * h * 4; + img->data_size = pitch[0] * h * 4; break; default: -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 11/12] radeon/vce: handle newly added parameters
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/drivers/radeon/radeon_vce_52.c | 33 ++ 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vce_52.c b/src/gallium/drivers/radeon/radeon_vce_52.c index 7d33313..7986eb8 100644 --- a/src/gallium/drivers/radeon/radeon_vce_52.c +++ b/src/gallium/drivers/radeon/radeon_vce_52.c @@ -48,13 +48,14 @@ static void get_rate_control_param(struct rvce_encoder *enc, struct pipe_h264_en enc->enc_pic.rc.quant_i_frames = pic->quant_i_frames; enc->enc_pic.rc.quant_p_frames = pic->quant_p_frames; enc->enc_pic.rc.quant_b_frames = pic->quant_b_frames; + enc->enc_pic.rc.gop_size = pic->gop_size; enc->enc_pic.rc.frame_rate_num = pic->rate_ctrl.frame_rate_num; enc->enc_pic.rc.frame_rate_den = pic->rate_ctrl.frame_rate_den; enc->enc_pic.rc.max_qp = 51; enc->enc_pic.rc.vbv_buffer_size = pic->rate_ctrl.vbv_buffer_size; - enc->enc_pic.rc.vbv_buf_lv = 0; - enc->enc_pic.rc.fill_data_enable = 0; - enc->enc_pic.rc.enforce_hrd = 0; + enc->enc_pic.rc.vbv_buf_lv = pic->rate_ctrl.vbv_buf_lv; + enc->enc_pic.rc.fill_data_enable = pic->rate_ctrl.fill_data_enable; + enc->enc_pic.rc.enforce_hrd = pic->rate_ctrl.enforce_hrd; enc->enc_pic.rc.target_bits_picture = pic->rate_ctrl.target_bits_picture; enc->enc_pic.rc.peak_bits_picture_integer = pic->rate_ctrl.peak_bits_picture_integer; enc->enc_pic.rc.peak_bits_picture_fraction = pic->rate_ctrl.peak_bits_picture_fraction; @@ -62,13 +63,13 @@ static void get_rate_control_param(struct rvce_encoder *enc, struct pipe_h264_en static void get_motion_estimation_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) { - enc->enc_pic.me.motion_est_quarter_pixel = 0x; - enc->enc_pic.me.enc_disable_sub_mode = 0x00fe; - enc->enc_pic.me.lsmvert = 0x; - enc->enc_pic.me.enc_en_ime_overw_dis_subm = 0x; - enc->enc_pic.me.enc_ime_overw_dis_subm_no = 0x; - enc->enc_pic.me.enc_ime2_search_range_x = 0x0001; - enc->enc_pic.me.enc_ime2_search_range_y = 0x0001; + enc->enc_pic.me.motion_est_quarter_pixel = pic->motion_est.motion_est_quarter_pixel; + enc->enc_pic.me.enc_disable_sub_mode = pic->motion_est.enc_disable_sub_mode; + enc->enc_pic.me.lsmvert = pic->motion_est.lsmvert; + enc->enc_pic.me.enc_en_ime_overw_dis_subm = pic->motion_est.enc_en_ime_overw_dis_subm; + enc->enc_pic.me.enc_ime_overw_dis_subm_no = pic->motion_est.enc_ime_overw_dis_subm_no; + enc->enc_pic.me.enc_ime2_search_range_x = pic->motion_est.enc_ime2_search_range_x; + enc->enc_pic.me.enc_ime2_search_range_y = pic->motion_est.enc_ime2_search_range_y; enc->enc_pic.me.enc_ime_decimation_search = 0x0001; enc->enc_pic.me.motion_est_half_pixel = 0x0001; enc->enc_pic.me.enc_search_range_x = 0x0010; @@ -90,8 +91,8 @@ static void get_pic_control_param(struct rvce_encoder *enc, struct pipe_h264_enc enc->enc_pic.pc.enc_max_num_ref_frames = enc->base.max_references + 1; enc->enc_pic.pc.enc_num_default_active_ref_l0 = 0x0001; enc->enc_pic.pc.enc_num_default_active_ref_l1 = 0x0001; - enc->enc_pic.pc.enc_cabac_enable = 0x; - enc->enc_pic.pc.enc_constraint_set_flags = 0x0040; + enc->enc_pic.pc.enc_cabac_enable = pic->pic_ctrl.enc_cabac_enable; + enc->enc_pic.pc.enc_constraint_set_flags = pic->pic_ctrl.enc_constraint_set_flags; enc->enc_pic.pc.enc_num_default_active_ref_l0 = 0x0001; enc->enc_pic.pc.enc_num_default_active_ref_l1 = 0x0001; } @@ -113,7 +114,7 @@ static void get_config_ext_param(struct rvce_encoder *enc) static void get_vui_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) { - enc->enc_pic.enable_vui = (pic->rate_ctrl.frame_rate_num != 0); + enc->enc_pic.enable_vui = pic->enable_vui; enc->enc_pic.vui.video_format = 0x0005; enc->enc_pic.vui.color_prim = 0x0002; enc->enc_pic.vui.transfer_char = 0x0002; @@ -149,10 +150,16 @@ void radeon_vce_52_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_pict enc->enc_pic.picture_type = pic->picture_type; enc->enc_pic.frame_num = pic->frame_num; + enc->enc_pic.frame_num_cnt = pic->frame_num_cnt; + enc->enc_pic.p_remain = pic->p_remain; + enc->enc_pic.i_remain = pic->i_remain; + enc->enc_pic.gop_cnt = pic->gop_cnt; enc->enc_pic.pic_order_cnt = pic->pic_order_cnt; enc->enc
[Mesa-dev] [PATCH 08/12] st/va: add functions for VAAPI encode
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/buffer.c | 6 + src/gallium/state_trackers/va/picture.c| 170 - src/gallium/state_trackers/va/va_private.h | 3 + 3 files changed, 177 insertions(+), 2 deletions(-) diff --git a/src/gallium/state_trackers/va/buffer.c b/src/gallium/state_trackers/va/buffer.c index 7d3167b..dfcebbe 100644 --- a/src/gallium/state_trackers/va/buffer.c +++ b/src/gallium/state_trackers/va/buffer.c @@ -133,6 +133,12 @@ vlVaMapBuffer(VADriverContextP ctx, VABufferID buf_id, void **pbuff) if (!buf->derived_surface.transfer || !*pbuff) return VA_STATUS_ERROR_INVALID_BUFFER; + if (buf->type == VAEncCodedBufferType) { + ((VACodedBufferSegment*)buf->data)->buf = *pbuff; + ((VACodedBufferSegment*)buf->data)->size = buf->coded_size; + ((VACodedBufferSegment*)buf->data)->next = NULL; + *pbuff = buf->data; + } } else { pipe_mutex_unlock(drv->mutex); *pbuff = buf->data; diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 89ac024..26205b1 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -78,7 +78,8 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende return VA_STATUS_SUCCESS; } - context->decoder->begin_frame(context->decoder, context->target, >desc.base); + if (context->decoder->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) + context->decoder->begin_frame(context->decoder, context->target, >desc.base); return VA_STATUS_SUCCESS; } @@ -278,6 +279,140 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) num_buffers, (const void * const*)buffers, sizes); } +static VAStatus +handleVAEncMiscParameterTypeRateControl(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAEncMiscParameterRateControl *rc = (VAEncMiscParameterRateControl *)misc->data; + if (context->desc.h264enc.rate_ctrl.rate_ctrl_method == + PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT) + context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second; + else + context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second * rc->target_percentage; + context->desc.h264enc.rate_ctrl.peak_bitrate = rc->bits_per_second; + if (context->desc.h264enc.rate_ctrl.target_bitrate < 200) + context->desc.h264enc.rate_ctrl.vbv_buffer_size = MIN2((context->desc.h264enc.rate_ctrl.target_bitrate * 2.75), 200); + else + context->desc.h264enc.rate_ctrl.vbv_buffer_size = context->desc.h264enc.rate_ctrl.target_bitrate; + + return VA_STATUS_SUCCESS; +} + +static VAStatus +handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + VAEncSequenceParameterBufferH264 *h264 = (VAEncSequenceParameterBufferH264 *)buf->data; + if (!context->decoder) { + context->templat.max_references = h264->max_num_ref_frames; + context->templat.level = h264->level_idc; + context->decoder = drv->pipe->create_video_codec(drv->pipe, >templat); + if (!context->decoder) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + context->desc.h264enc.gop_size = h264->intra_idr_period; + return VA_STATUS_SUCCESS; +} + +static VAStatus +handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) +{ + VAStatus vaStatus = VA_STATUS_SUCCESS; + VAEncMiscParameterBuffer *misc; + misc = buf->data; + + switch (misc->type) { + case VAEncMiscParameterTypeRateControl: + vaStatus = handleVAEncMiscParameterTypeRateControl(context, misc); + break; + + default: + break; + } + + return vaStatus; +} + +static VAStatus +handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + VAEncPictureParameterBufferH264 *h264; + vlVaBuffer *coded_buf; + + h264 = buf->data; + context->desc.h264enc.frame_num = h264->frame_num; + context->desc.h264enc.not_referenced = false; + context->desc.h264enc.is_idr = (h264->pic_fields.bits.idr_pic_flag == 1); + context->desc.h264enc.pic_order_cnt = h264->CurrPic.TopFieldOrderCnt / 2; + if (context->desc.h264enc.is_idr) + context->desc.h264enc.i_remain = 1; + else + context->desc.h264enc.i_remain = 0; + + context->desc.h264enc.p_remain = context->desc.h264enc.gop_size - context->desc.h264enc.gop_cnt - context->desc.h264enc.i_remain; + + coded_buf = handle_table_get(drv->htab, h264->coded_buf); + coded_buf->derived_surface.resource = pipe_buffer_create(drv->pipe->screen, PIPE_BIND_VERTEX_BUFFER, + PIPE
[Mesa-dev] [PATCH 09/12] st/va: add preset values for VAAPI encode
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/picture.c | 36 + 1 file changed, 36 insertions(+) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 26205b1..2d22e8b 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -95,6 +95,41 @@ vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id, *ref_frame = NULL; } +static void +getEncParamPreset(vlVaContext *context) +{ + //motion estimation preset + context->desc.h264enc.motion_est.motion_est_quarter_pixel = 0x0001; + context->desc.h264enc.motion_est.lsmvert = 0x0002; + context->desc.h264enc.motion_est.enc_disable_sub_mode = 0x0078; + context->desc.h264enc.motion_est.enc_en_ime_overw_dis_subm = 0x0001; + context->desc.h264enc.motion_est.enc_ime_overw_dis_subm_no = 0x0001; + context->desc.h264enc.motion_est.enc_ime2_search_range_x = 0x0004; + context->desc.h264enc.motion_est.enc_ime2_search_range_y = 0x0004; + + //pic control preset + context->desc.h264enc.pic_ctrl.enc_cabac_enable = 0x0001; + context->desc.h264enc.pic_ctrl.enc_constraint_set_flags = 0x0040; + + //rate control + context->desc.h264enc.rate_ctrl.vbv_buffer_size = 2000; + if (context->desc.h264enc.rate_ctrl.frame_rate_num == 0) { + context->desc.h264enc.rate_ctrl.frame_rate_num = 30; + context->desc.h264enc.rate_ctrl.frame_rate_den = 1; + } + context->desc.h264enc.rate_ctrl.vbv_buf_lv = 48; + context->desc.h264enc.rate_ctrl.fill_data_enable = 1; + context->desc.h264enc.rate_ctrl.enforce_hrd = 1; + context->desc.h264enc.enable_vui = false; + context->desc.h264enc.rate_ctrl.target_bits_picture = + context->desc.h264enc.rate_ctrl.target_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_integer = + context->desc.h264enc.rate_ctrl.peak_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num; + context->desc.h264enc.rate_ctrl.peak_bits_picture_fraction = 0; + + context->desc.h264enc.ref_pic_mode = 0x0201; +} + static VAStatus handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) { @@ -522,6 +557,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { coded_buf = context->coded_buf; + getEncParamPreset(context); context->decoder->begin_frame(context->decoder, context->target, >desc.base); context->decoder->encode_bitstream(context->decoder, context->target, coded_buf->derived_surface.resource, ); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 05/12] st/va: add nv12 i420 yv12 format to deriveimage call
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/image.c | 21 + 1 file changed, 21 insertions(+) diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c index c82b554..3c8cc9c 100644 --- a/src/gallium/state_trackers/va/image.c +++ b/src/gallium/state_trackers/va/image.c @@ -275,6 +275,27 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) } switch (img->format.fourcc) { + case VA_FOURCC('N','V','1','2'): + img->num_planes = 2; + img->pitches[0] = pitch[0]; + img->offsets[0] = 0; + img->pitches[1] = pitch[1]; + img->offsets[1] = pitch[0] * h; + img->data_size = pitch[0] * h + pitch[1] * h / 2; + break; + + case VA_FOURCC('I','4','2','0'): + case VA_FOURCC('Y','V','1','2'): + img->num_planes = 3; + img->pitches[0] = pitch[0]; + img->offsets[0] = 0; + img->pitches[1] = pitch[1]; + img->offsets[1] = pitch[0] * h; + img->pitches[2] = pitch[2]; + img->offsets[2] = pitch[0] * h + pitch[1] * h / 4; + img->data_size = pitch[0] * h + pitch[1] * h / 4 + pitch[2] * h / 4; + break; + case VA_FOURCC('U','Y','V','Y'): case VA_FOURCC('Y','U','Y','V'): img->num_planes = 1; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 12/12] st/va: enable h264 VAAPI encode
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/config.c | 32 ++-- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index ea838c0..04d214d 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -74,6 +74,7 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, { struct pipe_screen *pscreen; enum pipe_video_profile p; + int va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; @@ -90,12 +91,18 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + va_status = VA_STATUS_SUCCESS; + } + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED) && + p == PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncSlice; + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncPicture; + va_status = VA_STATUS_SUCCESS; + } - return VA_STATUS_SUCCESS; + return va_status; } VAStatus @@ -114,7 +121,7 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en value = VA_RT_FORMAT_YUV420; break; case VAConfigAttribRateControl: - value = VA_RC_NONE; + value = VA_RC_CQP | VA_RC_CBR; break; default: value = VA_ATTRIB_NOT_SUPPORTED; @@ -159,10 +166,15 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - if (entrypoint != VAEntrypointVLD) + if (entrypoint == VAEntrypointVLD) { + if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + else if (entrypoint == VAEntrypointEncSlice) { + if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED)) + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + else return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; if (entrypoint == VAEntrypointEncSlice || entrypoint == VAEntrypointEncPicture) -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 01/12] vl: add parameters for VAAPI encode
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/include/pipe/p_video_state.h | 36 1 file changed, 36 insertions(+) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index d353be6..9cd489b 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -352,9 +352,29 @@ struct pipe_h264_enc_rate_control unsigned frame_rate_num; unsigned frame_rate_den; unsigned vbv_buffer_size; + unsigned vbv_buf_lv; unsigned target_bits_picture; unsigned peak_bits_picture_integer; unsigned peak_bits_picture_fraction; + unsigned fill_data_enable; + unsigned enforce_hrd; +}; + +struct pipe_h264_enc_motion_estimation +{ + unsigned motion_est_quarter_pixel; + unsigned enc_disable_sub_mode; + unsigned lsmvert; + unsigned enc_en_ime_overw_dis_subm; + unsigned enc_ime_overw_dis_subm_no; + unsigned enc_ime2_search_range_x; + unsigned enc_ime2_search_range_y; +}; + +struct pipe_h264_enc_pic_control +{ + unsigned enc_cabac_enable; + unsigned enc_constraint_set_flags; }; struct pipe_h264_enc_picture_desc @@ -363,17 +383,33 @@ struct pipe_h264_enc_picture_desc struct pipe_h264_enc_rate_control rate_ctrl; + struct pipe_h264_enc_motion_estimation motion_est; + struct pipe_h264_enc_pic_control pic_ctrl; + unsigned quant_i_frames; unsigned quant_p_frames; unsigned quant_b_frames; enum pipe_h264_enc_picture_type picture_type; unsigned frame_num; + unsigned frame_num_cnt; + unsigned p_remain; + unsigned i_remain; + unsigned idr_pic_id; + unsigned gop_cnt; unsigned pic_order_cnt; unsigned ref_idx_l0; unsigned ref_idx_l1; + unsigned gop_size; + unsigned ref_pic_mode; bool not_referenced; + bool is_idr; + bool has_ref_pic_list; + bool enable_vui; + unsigned int ref_pic_list_0[32]; + unsigned int ref_pic_list_1[32]; + unsigned int frame_idx[32]; }; struct pipe_h265_sps -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 1/4] radeon/vce: add vce structures
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/drivers/radeon/radeon_vce.h | 297 1 file changed, 297 insertions(+) diff --git a/src/gallium/drivers/radeon/radeon_vce.h b/src/gallium/drivers/radeon/radeon_vce.h index e438148..da61285 100644 --- a/src/gallium/drivers/radeon/radeon_vce.h +++ b/src/gallium/drivers/radeon/radeon_vce.h @@ -65,6 +65,303 @@ struct rvce_cpb_slot { unsignedpic_order_cnt; }; +struct rvce_rate_control { + uint32_trc_method; + uint32_ttarget_bitrate; + uint32_tpeak_bitrate; + uint32_tframe_rate_num; + uint32_tgop_size; + uint32_tquant_i_frames; + uint32_tquant_p_frames; + uint32_tquant_b_frames; + uint32_tvbv_buffer_size; + uint32_tframe_rate_den; + uint32_tvbv_buf_lv; + uint32_tmax_au_size; + uint32_tqp_initial_mode; + uint32_ttarget_bits_picture; + uint32_tpeak_bits_picture_integer; + uint32_tpeak_bits_picture_fraction; + uint32_tmin_qp; + uint32_tmax_qp; + uint32_tskip_frame_enable; + uint32_tfill_data_enable; + uint32_tenforce_hrd; + uint32_tb_pics_delta_qp; + uint32_tref_b_pics_delta_qp; + uint32_trc_reinit_disable; + uint32_tenc_lcvbr_init_qp_flag; + uint32_tlcvbrsatd_based_nonlinear_bit_budget_flag; +}; + +struct rvce_motion_estimation { + uint32_tenc_ime_decimation_search; + uint32_tmotion_est_half_pixel; + uint32_tmotion_est_quarter_pixel; + uint32_tdisable_favor_pmv_point; + uint32_tforce_zero_point_center; + uint32_tlsmvert; + uint32_tenc_search_range_x; + uint32_tenc_search_range_y; + uint32_tenc_search1_range_x; + uint32_tenc_search1_range_y; + uint32_tdisable_16x16_frame1; + uint32_tdisable_satd; + uint32_tenable_amd; + uint32_tenc_disable_sub_mode; + uint32_tenc_ime_skip_x; + uint32_tenc_ime_skip_y; + uint32_tenc_en_ime_overw_dis_subm; + uint32_tenc_ime_overw_dis_subm_no; + uint32_tenc_ime2_search_range_x; + uint32_tenc_ime2_search_range_y; + uint32_tparallel_mode_speedup_enable; + uint32_tfme0_enc_disable_sub_mode; + uint32_tfme1_enc_disable_sub_mode; + uint32_time_sw_speedup_enable; +}; + +struct rvce_pic_control { + uint32_tenc_use_constrained_intra_pred; + uint32_tenc_cabac_enable; + uint32_tenc_cabac_idc; + uint32_tenc_loop_filter_disable; + int32_t enc_lf_beta_offset; + int32_t enc_lf_alpha_c0_offset; + uint32_tenc_crop_left_offset; + uint32_tenc_crop_right_offset; + uint32_tenc_crop_top_offset; + uint32_tenc_crop_bottom_offset; + uint32_tenc_num_mbs_per_slice; + uint32_tenc_intra_refresh_num_mbs_per_slot; + uint32_tenc_force_intra_refresh; + uint32_tenc_force_imb_period; + uint32_tenc_pic_order_cnt_type; + uint32_tlog2_max_pic_order_cnt_lsb_minus4; + uint32_tenc_sps_id; + uint32_tenc_pps_id; + uint32_tenc_constraint_set_flags; + uint32_tenc_b_pic_pattern; + uint32_tweight_pred_mode_b_picture; + uint32_tenc_number_of_reference_frames; + uint32_tenc_max_num_ref_frames; + uint32_tenc_num_default_active_ref_l0; + uint32_tenc_num_default_active_ref_l1; + uint32_tenc_slice_mode; + uint32_tenc_max_slice_size; +}; + +struct rvce_task_info { + uint32_toffset_of_next_task_info; + uint32_ttask_operation; + uint32_treference_picture_dependency; + uint32_tcollocate_flag_dependency; + uint32_tfeedback
[Mesa-dev] [PATCH 3/4] vl: add parameters for VAAPI encode
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/include/pipe/p_video_state.h | 12 1 file changed, 12 insertions(+) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index d353be6..2f2a4d9 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -369,11 +369,23 @@ struct pipe_h264_enc_picture_desc enum pipe_h264_enc_picture_type picture_type; unsigned frame_num; + unsigned frame_num_cnt; + unsigned p_remain; + unsigned i_remain; + unsigned idr_pic_id; + unsigned gop_cnt; unsigned pic_order_cnt; unsigned ref_idx_l0; unsigned ref_idx_l1; + unsigned gop_size; bool not_referenced; + bool is_idr; + bool has_ref_pic_list; + bool enable_low_level_control; + unsigned int ref_pic_list_0[32]; + unsigned int ref_pic_list_1[32]; + unsigned int frame_idx[32]; }; struct pipe_h265_sps -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 2/4] radeon/vce: use vce structure for vce 52 firmware
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/drivers/radeon/radeon_vce.c| 4 + src/gallium/drivers/radeon/radeon_vce.h| 17 + src/gallium/drivers/radeon/radeon_vce_40_2_2.c | 4 + src/gallium/drivers/radeon/radeon_vce_50.c | 4 + src/gallium/drivers/radeon/radeon_vce_52.c | 566 + 5 files changed, 509 insertions(+), 86 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vce.c b/src/gallium/drivers/radeon/radeon_vce.c index e16e0cf..e8aac8e 100644 --- a/src/gallium/drivers/radeon/radeon_vce.c +++ b/src/gallium/drivers/radeon/radeon_vce.c @@ -267,6 +267,7 @@ static void rvce_begin_frame(struct pipe_video_codec *encoder, enc->pic.quant_b_frames != pic->quant_b_frames; enc->pic = *pic; + get_pic_param(enc, pic); enc->get_buffer(vid_buf->resources[0], >handle, >luma); enc->get_buffer(vid_buf->resources[1], NULL, >chroma); @@ -474,6 +475,7 @@ struct pipe_video_codec *rvce_create_encoder(struct pipe_context *context, switch (rscreen->info.vce_fw_version) { case FW_40_2_2: radeon_vce_40_2_2_init(enc); + get_pic_param = radeon_vce_40_2_2_get_param; break; case FW_50_0_1: @@ -481,11 +483,13 @@ struct pipe_video_codec *rvce_create_encoder(struct pipe_context *context, case FW_50_10_2: case FW_50_17_3: radeon_vce_50_init(enc); + get_pic_param = radeon_vce_50_get_param; break; case FW_52_0_3: case FW_52_4_3: radeon_vce_52_init(enc); + get_pic_param = radeon_vce_52_get_param; break; default: diff --git a/src/gallium/drivers/radeon/radeon_vce.h b/src/gallium/drivers/radeon/radeon_vce.h index da61285..8c0b073 100644 --- a/src/gallium/drivers/radeon/radeon_vce.h +++ b/src/gallium/drivers/radeon/radeon_vce.h @@ -405,6 +405,7 @@ struct rvce_encoder { struct rvid_buffer *fb; struct rvid_buffer cpb; struct pipe_h264_enc_picture_desc pic; + struct rvce_h264_enc_picenc_pic; unsignedtask_info_idx; unsignedbs_idx; @@ -442,4 +443,20 @@ void radeon_vce_50_init(struct rvce_encoder *enc); /* init vce fw 52 specific callbacks */ void radeon_vce_52_init(struct rvce_encoder *enc); +/* version specific function for getting parameters */ +void (*get_pic_param)(struct rvce_encoder *enc, + struct pipe_h264_enc_picture_desc *pic); + +/* get parameters for vce 40.2.2 */ +void radeon_vce_40_2_2_get_param(struct rvce_encoder *enc, +struct pipe_h264_enc_picture_desc *pic); + +/* get parameters for vce 50 */ +void radeon_vce_50_get_param(struct rvce_encoder *enc, +struct pipe_h264_enc_picture_desc *pic); + +/* get parameters for vce 52 */ +void radeon_vce_52_get_param(struct rvce_encoder *enc, +struct pipe_h264_enc_picture_desc *pic); + #endif diff --git a/src/gallium/drivers/radeon/radeon_vce_40_2_2.c b/src/gallium/drivers/radeon/radeon_vce_40_2_2.c index 2906ad0..fe15ded 100644 --- a/src/gallium/drivers/radeon/radeon_vce_40_2_2.c +++ b/src/gallium/drivers/radeon/radeon_vce_40_2_2.c @@ -431,6 +431,10 @@ static void destroy(struct rvce_encoder *enc) RVCE_END(); } +void radeon_vce_40_2_2_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) +{ +} + void radeon_vce_40_2_2_init(struct rvce_encoder *enc) { enc->session = session; diff --git a/src/gallium/drivers/radeon/radeon_vce_50.c b/src/gallium/drivers/radeon/radeon_vce_50.c index 82e7ad2..262e13b 100644 --- a/src/gallium/drivers/radeon/radeon_vce_50.c +++ b/src/gallium/drivers/radeon/radeon_vce_50.c @@ -233,6 +233,10 @@ static void encode(struct rvce_encoder *enc) RVCE_END(); } +void radeon_vce_50_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) +{ +} + void radeon_vce_50_init(struct rvce_encoder *enc) { radeon_vce_40_2_2_init(enc); diff --git a/src/gallium/drivers/radeon/radeon_vce_52.c b/src/gallium/drivers/radeon/radeon_vce_52.c index 3894eea..56b6dd8 100644 --- a/src/gallium/drivers/radeon/radeon_vce_52.c +++ b/src/gallium/drivers/radeon/radeon_vce_52.c @@ -40,27 +40,146 @@ static const unsigned profiles[7] = { 66, 77, 88, 100, 110, 122, 244 }; +static void get_rate_control_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) +{ + enc->enc_pic.rc.rc_method = pic->rate_ctrl.rate_ctrl_method; + enc->enc_pic.rc.target_bitrate = pic->rate_ctrl.target_bitrate; + enc->enc_pic.rc.peak_bitrate = pic->rate_ctr
[Mesa-dev] [PATCH 4/4] radeon/vce: handle newly added parameters
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/drivers/radeon/radeon_vce_52.c | 107 + 1 file changed, 79 insertions(+), 28 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vce_52.c b/src/gallium/drivers/radeon/radeon_vce_52.c index 56b6dd8..ac577e3 100644 --- a/src/gallium/drivers/radeon/radeon_vce_52.c +++ b/src/gallium/drivers/radeon/radeon_vce_52.c @@ -48,36 +48,65 @@ static void get_rate_control_param(struct rvce_encoder *enc, struct pipe_h264_en enc->enc_pic.rc.quant_i_frames = pic->quant_i_frames; enc->enc_pic.rc.quant_p_frames = pic->quant_p_frames; enc->enc_pic.rc.quant_b_frames = pic->quant_b_frames; + enc->enc_pic.rc.gop_size = pic->gop_size; enc->enc_pic.rc.frame_rate_num = pic->rate_ctrl.frame_rate_num; enc->enc_pic.rc.frame_rate_den = pic->rate_ctrl.frame_rate_den; enc->enc_pic.rc.max_qp = 51; - enc->enc_pic.rc.vbv_buffer_size = pic->rate_ctrl.vbv_buffer_size; - enc->enc_pic.rc.vbv_buf_lv = 0; - enc->enc_pic.rc.fill_data_enable = 0; - enc->enc_pic.rc.enforce_hrd = 0; - enc->enc_pic.rc.target_bits_picture = pic->rate_ctrl.target_bits_picture; - enc->enc_pic.rc.peak_bits_picture_integer = pic->rate_ctrl.peak_bits_picture_integer; - enc->enc_pic.rc.peak_bits_picture_fraction = pic->rate_ctrl.peak_bits_picture_fraction; + if (pic->enable_low_level_control == true) { + enc->enc_pic.rc.vbv_buffer_size = 2000; + if (pic->rate_ctrl.frame_rate_num == 0) + enc->enc_pic.rc.frame_rate_num = 30; + if (pic->rate_ctrl.frame_rate_den == 0) + enc->enc_pic.rc.frame_rate_den = 1; + enc->enc_pic.rc.vbv_buf_lv = 48; + enc->enc_pic.rc.fill_data_enable = 1; + enc->enc_pic.rc.enforce_hrd = 1; + enc->enc_pic.rc.target_bits_picture = enc->enc_pic.rc.target_bitrate / enc->enc_pic.rc.frame_rate_num; + enc->enc_pic.rc.peak_bits_picture_integer = enc->enc_pic.rc.peak_bitrate / enc->enc_pic.rc.frame_rate_num; + enc->enc_pic.rc.peak_bits_picture_fraction = 0; + } else { + enc->enc_pic.rc.vbv_buffer_size = pic->rate_ctrl.vbv_buffer_size; + enc->enc_pic.rc.vbv_buf_lv = 0; + enc->enc_pic.rc.fill_data_enable = 0; + enc->enc_pic.rc.enforce_hrd = 0; + enc->enc_pic.rc.target_bits_picture = pic->rate_ctrl.target_bits_picture; + enc->enc_pic.rc.peak_bits_picture_integer = pic->rate_ctrl.peak_bits_picture_integer; + enc->enc_pic.rc.peak_bits_picture_fraction = pic->rate_ctrl.peak_bits_picture_fraction; + } } static void get_motion_estimation_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) { - - enc->enc_pic.me.motion_est_quarter_pixel = 0x; - enc->enc_pic.me.enc_disable_sub_mode = 0x00fe; - enc->enc_pic.me.lsmvert = 0x; - enc->enc_pic.me.enc_en_ime_overw_dis_subm = 0x; - enc->enc_pic.me.enc_ime_overw_dis_subm_no = 0x; - enc->enc_pic.me.enc_ime2_search_range_x = 0x0001; - enc->enc_pic.me.enc_ime2_search_range_y = 0x0001; - enc->enc_pic.me.enc_ime_decimation_search = 0x0001; - enc->enc_pic.me.motion_est_half_pixel = 0x0001; - enc->enc_pic.me.enc_search_range_x = 0x0010; - enc->enc_pic.me.enc_search_range_y = 0x0010; - enc->enc_pic.me.enc_search1_range_x = 0x0010; - enc->enc_pic.me.enc_search1_range_y = 0x0010; - + if (pic->enable_low_level_control == true) { + enc->enc_pic.me.motion_est_quarter_pixel = 0x0001; + enc->enc_pic.me.enc_disable_sub_mode = 0x0078; + enc->enc_pic.me.lsmvert = 0x0002; + enc->enc_pic.me.enc_en_ime_overw_dis_subm = 0x0001; + enc->enc_pic.me.enc_ime_overw_dis_subm_no = 0x0001; + enc->enc_pic.me.enc_ime2_search_range_x = 0x0004; + enc->enc_pic.me.enc_ime2_search_range_y = 0x0004; + enc->enc_pic.me.enc_ime_decimation_search = 0x0001; + enc->enc_pic.me.motion_est_half_pixel = 0x0001; + enc->enc_pic.me.enc_search_range_x = 0x0010; + enc->enc_pic.me.enc_search_range_y = 0x0010; + enc->enc_pic.me.enc_search1_range_x = 0x0010; + enc->enc_pic.me.enc_search1_range_y = 0x0010; + } else { + enc->enc_pic.me.motion_est_quarter_pixel = 0x; + enc->enc_pic.me.enc_di
[Mesa-dev] [PATCH 3/3] radeon/vce: use vce structures for vce_52 firmware
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/drivers/radeon/radeon_vce.c| 171 +++ src/gallium/drivers/radeon/radeon_vce.h| 1 + src/gallium/drivers/radeon/radeon_vce_52.c | 447 +++-- 3 files changed, 533 insertions(+), 86 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vce.c b/src/gallium/drivers/radeon/radeon_vce.c index e16e0cf..0d96085 100644 --- a/src/gallium/drivers/radeon/radeon_vce.c +++ b/src/gallium/drivers/radeon/radeon_vce.c @@ -139,6 +139,176 @@ static void sort_cpb(struct rvce_encoder *enc) } } +static void get_rate_control_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) +{ + enc->enc_pic.rc.rc_method = pic->rate_ctrl.rate_ctrl_method; + enc->enc_pic.rc.target_bitrate = pic->rate_ctrl.target_bitrate; + enc->enc_pic.rc.peak_bitrate = pic->rate_ctrl.peak_bitrate; + enc->enc_pic.rc.quant_i_frames = pic->quant_i_frames; + enc->enc_pic.rc.quant_p_frames = pic->quant_p_frames; + enc->enc_pic.rc.quant_b_frames = pic->quant_b_frames; + enc->enc_pic.rc.gop_size = pic->gop_size; + enc->enc_pic.rc.frame_rate_num = pic->rate_ctrl.frame_rate_num; + enc->enc_pic.rc.frame_rate_den = pic->rate_ctrl.frame_rate_den; + enc->enc_pic.rc.max_qp = 51; + + if (pic->enable_low_level_control == true) { + enc->enc_pic.rc.vbv_buffer_size = 2000; + if (pic->rate_ctrl.frame_rate_num == 0) + enc->enc_pic.rc.frame_rate_num = 30; + if (pic->rate_ctrl.frame_rate_den == 0) + enc->enc_pic.rc.frame_rate_den = 1; + enc->enc_pic.rc.vbv_buf_lv = 48; + enc->enc_pic.rc.fill_data_enable = 1; + enc->enc_pic.rc.enforce_hrd = 1; + enc->enc_pic.rc.target_bits_picture = enc->enc_pic.rc.target_bitrate / enc->enc_pic.rc.frame_rate_num; + enc->enc_pic.rc.peak_bits_picture_integer = enc->enc_pic.rc.peak_bitrate / enc->enc_pic.rc.frame_rate_num; + enc->enc_pic.rc.peak_bits_picture_fraction = 0; + } else { + enc->enc_pic.rc.vbv_buffer_size = pic->rate_ctrl.vbv_buffer_size; + enc->enc_pic.rc.vbv_buf_lv = 0; + enc->enc_pic.rc.fill_data_enable = 0; + enc->enc_pic.rc.enforce_hrd = 0; + enc->enc_pic.rc.target_bits_picture = pic->rate_ctrl.target_bits_picture; + enc->enc_pic.rc.peak_bits_picture_integer = pic->rate_ctrl.peak_bits_picture_integer; + enc->enc_pic.rc.peak_bits_picture_fraction = pic->rate_ctrl.peak_bits_picture_fraction; + } +} + +static void get_motion_estimation_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) +{ + if (pic->enable_low_level_control == true) { + enc->enc_pic.me.motion_est_quarter_pixel = 0x0001; + enc->enc_pic.me.enc_disable_sub_mode = 0x0078; + enc->enc_pic.me.lsmvert = 0x0002; + enc->enc_pic.me.enc_en_ime_overw_dis_subm = 0x0001; + enc->enc_pic.me.enc_ime_overw_dis_subm_no = 0x0001; + enc->enc_pic.me.enc_ime2_search_range_x = 0x0004; + enc->enc_pic.me.enc_ime2_search_range_y = 0x0004; + enc->enc_pic.me.enc_ime_decimation_search = 0x0001; + enc->enc_pic.me.motion_est_half_pixel = 0x0001; + enc->enc_pic.me.enc_search_range_x = 0x0010; + enc->enc_pic.me.enc_search_range_y = 0x0010; + enc->enc_pic.me.enc_search1_range_x = 0x0010; + enc->enc_pic.me.enc_search1_range_y = 0x0010; + } else { + enc->enc_pic.me.motion_est_quarter_pixel = 0x; + enc->enc_pic.me.enc_disable_sub_mode = 0x00fe; + enc->enc_pic.me.lsmvert = 0x; + enc->enc_pic.me.enc_en_ime_overw_dis_subm = 0x; + enc->enc_pic.me.enc_ime_overw_dis_subm_no = 0x; + enc->enc_pic.me.enc_ime2_search_range_x = 0x0001; + enc->enc_pic.me.enc_ime2_search_range_y = 0x0001; + enc->enc_pic.me.enc_ime_decimation_search = 0x0001; + enc->enc_pic.me.motion_est_half_pixel = 0x0001; + enc->enc_pic.me.enc_search_range_x = 0x0010; + enc->enc_pic.me.enc_search_range_y = 0x0010; + enc->enc_pic.me.enc_search1_range_x = 0x0010; + enc->enc_pic.me.enc_search1_range_y = 0x0010; + } +} + +static void get_pic_control_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) +{ +
[Mesa-dev] [PATCH 2/3] vl: add parameters for VAAPI encode
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/include/pipe/p_video_state.h | 13 + 1 file changed, 13 insertions(+) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index d353be6..d519d17 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -131,6 +131,7 @@ enum pipe_h264_enc_rate_control_method struct pipe_picture_desc { enum pipe_video_profile profile; + enum pipe_video_entrypoint entry_point; }; struct pipe_quant_matrix @@ -369,11 +370,23 @@ struct pipe_h264_enc_picture_desc enum pipe_h264_enc_picture_type picture_type; unsigned frame_num; + unsigned frame_num_cnt; + unsigned p_remain; + unsigned i_remain; + unsigned idr_pic_id; + unsigned gop_cnt; unsigned pic_order_cnt; unsigned ref_idx_l0; unsigned ref_idx_l1; + unsigned gop_size; bool not_referenced; + bool is_idr; + bool has_ref_pic_list; + bool enable_low_level_control; + unsigned int ref_pic_list_0[32]; + unsigned int ref_pic_list_1[32]; + unsigned int frame_idx[32]; }; struct pipe_h265_sps -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 1/3] radeon/vce: add vce structures
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/drivers/radeon/radeon_vce.h | 297 1 file changed, 297 insertions(+) diff --git a/src/gallium/drivers/radeon/radeon_vce.h b/src/gallium/drivers/radeon/radeon_vce.h index e438148..da61285 100644 --- a/src/gallium/drivers/radeon/radeon_vce.h +++ b/src/gallium/drivers/radeon/radeon_vce.h @@ -65,6 +65,303 @@ struct rvce_cpb_slot { unsignedpic_order_cnt; }; +struct rvce_rate_control { + uint32_trc_method; + uint32_ttarget_bitrate; + uint32_tpeak_bitrate; + uint32_tframe_rate_num; + uint32_tgop_size; + uint32_tquant_i_frames; + uint32_tquant_p_frames; + uint32_tquant_b_frames; + uint32_tvbv_buffer_size; + uint32_tframe_rate_den; + uint32_tvbv_buf_lv; + uint32_tmax_au_size; + uint32_tqp_initial_mode; + uint32_ttarget_bits_picture; + uint32_tpeak_bits_picture_integer; + uint32_tpeak_bits_picture_fraction; + uint32_tmin_qp; + uint32_tmax_qp; + uint32_tskip_frame_enable; + uint32_tfill_data_enable; + uint32_tenforce_hrd; + uint32_tb_pics_delta_qp; + uint32_tref_b_pics_delta_qp; + uint32_trc_reinit_disable; + uint32_tenc_lcvbr_init_qp_flag; + uint32_tlcvbrsatd_based_nonlinear_bit_budget_flag; +}; + +struct rvce_motion_estimation { + uint32_tenc_ime_decimation_search; + uint32_tmotion_est_half_pixel; + uint32_tmotion_est_quarter_pixel; + uint32_tdisable_favor_pmv_point; + uint32_tforce_zero_point_center; + uint32_tlsmvert; + uint32_tenc_search_range_x; + uint32_tenc_search_range_y; + uint32_tenc_search1_range_x; + uint32_tenc_search1_range_y; + uint32_tdisable_16x16_frame1; + uint32_tdisable_satd; + uint32_tenable_amd; + uint32_tenc_disable_sub_mode; + uint32_tenc_ime_skip_x; + uint32_tenc_ime_skip_y; + uint32_tenc_en_ime_overw_dis_subm; + uint32_tenc_ime_overw_dis_subm_no; + uint32_tenc_ime2_search_range_x; + uint32_tenc_ime2_search_range_y; + uint32_tparallel_mode_speedup_enable; + uint32_tfme0_enc_disable_sub_mode; + uint32_tfme1_enc_disable_sub_mode; + uint32_time_sw_speedup_enable; +}; + +struct rvce_pic_control { + uint32_tenc_use_constrained_intra_pred; + uint32_tenc_cabac_enable; + uint32_tenc_cabac_idc; + uint32_tenc_loop_filter_disable; + int32_t enc_lf_beta_offset; + int32_t enc_lf_alpha_c0_offset; + uint32_tenc_crop_left_offset; + uint32_tenc_crop_right_offset; + uint32_tenc_crop_top_offset; + uint32_tenc_crop_bottom_offset; + uint32_tenc_num_mbs_per_slice; + uint32_tenc_intra_refresh_num_mbs_per_slot; + uint32_tenc_force_intra_refresh; + uint32_tenc_force_imb_period; + uint32_tenc_pic_order_cnt_type; + uint32_tlog2_max_pic_order_cnt_lsb_minus4; + uint32_tenc_sps_id; + uint32_tenc_pps_id; + uint32_tenc_constraint_set_flags; + uint32_tenc_b_pic_pattern; + uint32_tweight_pred_mode_b_picture; + uint32_tenc_number_of_reference_frames; + uint32_tenc_max_num_ref_frames; + uint32_tenc_num_default_active_ref_l0; + uint32_tenc_num_default_active_ref_l1; + uint32_tenc_slice_mode; + uint32_tenc_max_slice_size; +}; + +struct rvce_task_info { + uint32_toffset_of_next_task_info; + uint32_ttask_operation; + uint32_treference_picture_dependency; + uint32_tcollocate_flag_dependency; + uint32_tfeedback
[Mesa-dev] [PATCH 4/5] radeon/vce: sort cpb by ref list for VAAPI encode
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/drivers/radeon/radeon_vce.c | 52 +++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vce.c b/src/gallium/drivers/radeon/radeon_vce.c index 549d999..0ff07eb 100644 --- a/src/gallium/drivers/radeon/radeon_vce.c +++ b/src/gallium/drivers/radeon/radeon_vce.c @@ -139,6 +139,48 @@ static void sort_cpb(struct rvce_encoder *enc) } } +/** + * sort l0 and l1 based on reference picture list + */ +static void sort_cpb_by_ref_list(struct rvce_encoder *enc) +{ + struct rvce_cpb_slot *i, *l0 = NULL, *l1 = NULL; + struct list_head *current = >cpb_slots; + + for (int j = 0 ; j < 32 ; j++) { + if ((enc->pic.ref_pic_list_0[j] == 0x) && + (enc->pic.ref_pic_list_1[j] == 0x)) + break; + LIST_FOR_EACH_ENTRY(i, >cpb_slots, list) { + if (i->frame_num == enc->pic.ref_pic_list_0[j]) + l0 = i; + + if (i->frame_num == enc->pic.ref_pic_list_1[j]) + l1 = i; + + if (enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P && + l0) + break; + + if (enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B && + l0 && l1) + break; + } + + if (l0) { + LIST_DEL(>list); + LIST_ADD(>list, current); + current = current->next; + } + + if (l1) { + LIST_DEL(>list); + LIST_ADD(>list, current); + current = current->next; + } + } +} + static void get_rate_control_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) { enc->pic.rc.rc_method = pic->rate_ctrl.rate_ctrl_method; @@ -444,9 +486,13 @@ static void rvce_begin_frame(struct pipe_video_codec *encoder, if (pic->picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR) reset_cpb(enc); else if (pic->picture_type == PIPE_H264_ENC_PICTURE_TYPE_P || -pic->picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) - sort_cpb(enc); - +pic->picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) { + if (pic->has_ref_pic_list) + sort_cpb_by_ref_list(enc); + else + sort_cpb(enc); + } + if (!enc->stream_handle) { struct rvid_buffer fb; enc->stream_handle = rvid_alloc_stream_handle(); -- 1.9.1 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 1/5] radeon/vce: add vce structures
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/drivers/radeon/radeon_vce.h | 297 1 file changed, 297 insertions(+) diff --git a/src/gallium/drivers/radeon/radeon_vce.h b/src/gallium/drivers/radeon/radeon_vce.h index e438148..da61285 100644 --- a/src/gallium/drivers/radeon/radeon_vce.h +++ b/src/gallium/drivers/radeon/radeon_vce.h @@ -65,6 +65,303 @@ struct rvce_cpb_slot { unsignedpic_order_cnt; }; +struct rvce_rate_control { + uint32_trc_method; + uint32_ttarget_bitrate; + uint32_tpeak_bitrate; + uint32_tframe_rate_num; + uint32_tgop_size; + uint32_tquant_i_frames; + uint32_tquant_p_frames; + uint32_tquant_b_frames; + uint32_tvbv_buffer_size; + uint32_tframe_rate_den; + uint32_tvbv_buf_lv; + uint32_tmax_au_size; + uint32_tqp_initial_mode; + uint32_ttarget_bits_picture; + uint32_tpeak_bits_picture_integer; + uint32_tpeak_bits_picture_fraction; + uint32_tmin_qp; + uint32_tmax_qp; + uint32_tskip_frame_enable; + uint32_tfill_data_enable; + uint32_tenforce_hrd; + uint32_tb_pics_delta_qp; + uint32_tref_b_pics_delta_qp; + uint32_trc_reinit_disable; + uint32_tenc_lcvbr_init_qp_flag; + uint32_tlcvbrsatd_based_nonlinear_bit_budget_flag; +}; + +struct rvce_motion_estimation { + uint32_tenc_ime_decimation_search; + uint32_tmotion_est_half_pixel; + uint32_tmotion_est_quarter_pixel; + uint32_tdisable_favor_pmv_point; + uint32_tforce_zero_point_center; + uint32_tlsmvert; + uint32_tenc_search_range_x; + uint32_tenc_search_range_y; + uint32_tenc_search1_range_x; + uint32_tenc_search1_range_y; + uint32_tdisable_16x16_frame1; + uint32_tdisable_satd; + uint32_tenable_amd; + uint32_tenc_disable_sub_mode; + uint32_tenc_ime_skip_x; + uint32_tenc_ime_skip_y; + uint32_tenc_en_ime_overw_dis_subm; + uint32_tenc_ime_overw_dis_subm_no; + uint32_tenc_ime2_search_range_x; + uint32_tenc_ime2_search_range_y; + uint32_tparallel_mode_speedup_enable; + uint32_tfme0_enc_disable_sub_mode; + uint32_tfme1_enc_disable_sub_mode; + uint32_time_sw_speedup_enable; +}; + +struct rvce_pic_control { + uint32_tenc_use_constrained_intra_pred; + uint32_tenc_cabac_enable; + uint32_tenc_cabac_idc; + uint32_tenc_loop_filter_disable; + int32_t enc_lf_beta_offset; + int32_t enc_lf_alpha_c0_offset; + uint32_tenc_crop_left_offset; + uint32_tenc_crop_right_offset; + uint32_tenc_crop_top_offset; + uint32_tenc_crop_bottom_offset; + uint32_tenc_num_mbs_per_slice; + uint32_tenc_intra_refresh_num_mbs_per_slot; + uint32_tenc_force_intra_refresh; + uint32_tenc_force_imb_period; + uint32_tenc_pic_order_cnt_type; + uint32_tlog2_max_pic_order_cnt_lsb_minus4; + uint32_tenc_sps_id; + uint32_tenc_pps_id; + uint32_tenc_constraint_set_flags; + uint32_tenc_b_pic_pattern; + uint32_tweight_pred_mode_b_picture; + uint32_tenc_number_of_reference_frames; + uint32_tenc_max_num_ref_frames; + uint32_tenc_num_default_active_ref_l0; + uint32_tenc_num_default_active_ref_l1; + uint32_tenc_slice_mode; + uint32_tenc_max_slice_size; +}; + +struct rvce_task_info { + uint32_toffset_of_next_task_info; + uint32_ttask_operation; + uint32_treference_picture_dependency; + uint32_tcollocate_flag_dependency; + uint32_tfeedback
[Mesa-dev] [PATCH 3/5] radeon/vce: use vce structures for encoding
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/drivers/radeon/radeon_vce.c| 180 ++- src/gallium/drivers/radeon/radeon_vce.h| 2 +- src/gallium/drivers/radeon/radeon_vce_40_2_2.c | 425 + src/gallium/drivers/radeon/radeon_vce_50.c | 183 ++- src/gallium/drivers/radeon/radeon_vce_52.c | 171 +- 5 files changed, 603 insertions(+), 358 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vce.c b/src/gallium/drivers/radeon/radeon_vce.c index e16e0cf..549d999 100644 --- a/src/gallium/drivers/radeon/radeon_vce.c +++ b/src/gallium/drivers/radeon/radeon_vce.c @@ -139,6 +139,176 @@ static void sort_cpb(struct rvce_encoder *enc) } } +static void get_rate_control_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) +{ + enc->pic.rc.rc_method = pic->rate_ctrl.rate_ctrl_method; + enc->pic.rc.target_bitrate = pic->rate_ctrl.target_bitrate; + enc->pic.rc.peak_bitrate = pic->rate_ctrl.peak_bitrate; + enc->pic.rc.quant_i_frames = pic->quant_i_frames; + enc->pic.rc.quant_p_frames = pic->quant_p_frames; + enc->pic.rc.quant_b_frames = pic->quant_b_frames; + enc->pic.rc.gop_size = pic->gop_size; + enc->pic.rc.frame_rate_num = pic->rate_ctrl.frame_rate_num; + enc->pic.rc.frame_rate_den = pic->rate_ctrl.frame_rate_den; + enc->pic.rc.max_qp = 51; + + if (pic->enable_low_level_control == true) { + enc->pic.rc.vbv_buffer_size = 2000; + if (pic->rate_ctrl.frame_rate_num == 0) + enc->pic.rc.frame_rate_num = 30; + if (pic->rate_ctrl.frame_rate_den == 0) + enc->pic.rc.frame_rate_den = 1; + enc->pic.rc.vbv_buf_lv = 48; + enc->pic.rc.fill_data_enable = 1; + enc->pic.rc.enforce_hrd = 1; + enc->pic.rc.target_bits_picture = enc->pic.rc.target_bitrate / enc->pic.rc.frame_rate_num; + enc->pic.rc.peak_bits_picture_integer = enc->pic.rc.peak_bitrate / enc->pic.rc.frame_rate_num; + enc->pic.rc.peak_bits_picture_fraction = 0; + } else { + enc->pic.rc.vbv_buffer_size = pic->rate_ctrl.vbv_buffer_size; + enc->pic.rc.vbv_buf_lv = 0; + enc->pic.rc.fill_data_enable = 0; + enc->pic.rc.enforce_hrd = 0; + enc->pic.rc.target_bits_picture = pic->rate_ctrl.target_bits_picture; + enc->pic.rc.peak_bits_picture_integer = pic->rate_ctrl.peak_bits_picture_integer; + enc->pic.rc.peak_bits_picture_fraction = pic->rate_ctrl.peak_bits_picture_fraction; + } +} + +static void get_motion_estimation_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) +{ + if (pic->enable_low_level_control == true) { + enc->pic.me.motion_est_quarter_pixel = 0x0001; + enc->pic.me.enc_disable_sub_mode = 0x0078; + enc->pic.me.lsmvert = 0x0002; + enc->pic.me.enc_en_ime_overw_dis_subm = 0x0001; + enc->pic.me.enc_ime_overw_dis_subm_no = 0x0001; + enc->pic.me.enc_ime2_search_range_x = 0x0004; + enc->pic.me.enc_ime2_search_range_y = 0x0004; + enc->pic.me.enc_ime_decimation_search = 0x0001; + enc->pic.me.motion_est_half_pixel = 0x0001; + enc->pic.me.enc_search_range_x = 0x0010; + enc->pic.me.enc_search_range_y = 0x0010; + enc->pic.me.enc_search1_range_x = 0x0010; + enc->pic.me.enc_search1_range_y = 0x0010; + } else { + enc->pic.me.motion_est_quarter_pixel = 0x; + enc->pic.me.enc_disable_sub_mode = 0x00fe; + enc->pic.me.lsmvert = 0x; + enc->pic.me.enc_en_ime_overw_dis_subm = 0x; + enc->pic.me.enc_ime_overw_dis_subm_no = 0x; + enc->pic.me.enc_ime2_search_range_x = 0x0001; + enc->pic.me.enc_ime2_search_range_y = 0x0001; + enc->pic.me.enc_ime_decimation_search = 0x0001; + enc->pic.me.motion_est_half_pixel = 0x0001; + enc->pic.me.enc_search_range_x = 0x0010; + enc->pic.me.enc_search_range_y = 0x0010; + enc->pic.me.enc_search1_range_x = 0x0010; + enc->pic.me.enc_search1_range_y = 0x0010; + } +} + +static void get_pic_control_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) +{ + unsigned encNumMBsPerSlice; + encNumMBsPerSlice = align(enc->base.width
[Mesa-dev] [PATCH 2/5] vl: add parameters for VAAPI encode
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/include/pipe/p_video_state.h | 13 + 1 file changed, 13 insertions(+) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index d353be6..d519d17 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -131,6 +131,7 @@ enum pipe_h264_enc_rate_control_method struct pipe_picture_desc { enum pipe_video_profile profile; + enum pipe_video_entrypoint entry_point; }; struct pipe_quant_matrix @@ -369,11 +370,23 @@ struct pipe_h264_enc_picture_desc enum pipe_h264_enc_picture_type picture_type; unsigned frame_num; + unsigned frame_num_cnt; + unsigned p_remain; + unsigned i_remain; + unsigned idr_pic_id; + unsigned gop_cnt; unsigned pic_order_cnt; unsigned ref_idx_l0; unsigned ref_idx_l1; + unsigned gop_size; bool not_referenced; + bool is_idr; + bool has_ref_pic_list; + bool enable_low_level_control; + unsigned int ref_pic_list_0[32]; + unsigned int ref_pic_list_1[32]; + unsigned int frame_idx[32]; }; struct pipe_h265_sps -- 1.9.1 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 5/5] st/va: enable h264 VAAPI encode
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> --- src/gallium/state_trackers/va/buffer.c | 6 ++ src/gallium/state_trackers/va/config.c | 104 +++--- src/gallium/state_trackers/va/context.c| 72 - src/gallium/state_trackers/va/image.c | 126 +++--- src/gallium/state_trackers/va/picture.c| 165 - src/gallium/state_trackers/va/surface.c| 16 ++- src/gallium/state_trackers/va/va_private.h | 9 ++ 7 files changed, 441 insertions(+), 57 deletions(-) diff --git a/src/gallium/state_trackers/va/buffer.c b/src/gallium/state_trackers/va/buffer.c index 7d3167b..dfcebbe 100644 --- a/src/gallium/state_trackers/va/buffer.c +++ b/src/gallium/state_trackers/va/buffer.c @@ -133,6 +133,12 @@ vlVaMapBuffer(VADriverContextP ctx, VABufferID buf_id, void **pbuff) if (!buf->derived_surface.transfer || !*pbuff) return VA_STATUS_ERROR_INVALID_BUFFER; + if (buf->type == VAEncCodedBufferType) { + ((VACodedBufferSegment*)buf->data)->buf = *pbuff; + ((VACodedBufferSegment*)buf->data)->size = buf->coded_size; + ((VACodedBufferSegment*)buf->data)->next = NULL; + *pbuff = buf->data; + } } else { pipe_mutex_unlock(drv->mutex); *pbuff = buf->data; diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 9ca0aa8..04d214d 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -34,6 +34,8 @@ #include "va_private.h" +#include "util/u_handle_table.h" + DEBUG_GET_ONCE_BOOL_OPTION(mpeg4, "VAAPI_MPEG4_ENABLED", false) VAStatus @@ -72,6 +74,7 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, { struct pipe_screen *pscreen; enum pipe_video_profile p; + int va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; @@ -88,12 +91,18 @@ vlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile, return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD; + va_status = VA_STATUS_SUCCESS; + } + if (pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_SUPPORTED) && + p == PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE) { + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncSlice; + entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncPicture; + va_status = VA_STATUS_SUCCESS; + } - return VA_STATUS_SUCCESS; + return va_status; } VAStatus @@ -112,7 +121,7 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en value = VA_RT_FORMAT_YUV420; break; case VAConfigAttribRateControl: - value = VA_RC_NONE; + value = VA_RC_CQP | VA_RC_CBR; break; default: value = VA_ATTRIB_NOT_SUPPORTED; @@ -128,14 +137,27 @@ VAStatus vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id) { + vlVaDriver *drv; + vlVaConfig *config; struct pipe_screen *pscreen; enum pipe_video_profile p; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + + if (!drv) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + config = CALLOC(1, sizeof(vlVaConfig)); + if (!config) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + if (profile == VAProfileNone && entrypoint == VAEntrypointVideoProc) { - *config_id = PIPE_VIDEO_PROFILE_UNKNOWN; + config->entrypoint = VAEntrypointVideoProc; + config->profile = PIPE_VIDEO_PROFILE_UNKNOWN; + *config_id = handle_table_add(drv->htab, config); return VA_STATUS_SUCCESS; } @@ -144,13 +166,36 @@ vlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoin return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; pscreen = VL_VA_PSCREEN(ctx); - if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) - return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; - - if (entrypoint != VAEntrypointVLD) + if (entrypoint == VAEntrypointVLD) { + if (!pscreen->get_video_param(pscreen, p, PIPE_VIDEO_ENTRYPOINT_BITSTREAM, PIPE_VIDEO_CAP_SUPPORTED)) + return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + } + else if (ent
[Mesa-dev] [PATCH] radeon/uvd: alignment fix for decode message buffer
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> Reviewed-by: Christian König <christian.koe...@amd.com> --- src/gallium/drivers/radeon/radeon_uvd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c index 233f460..098baf2 100644 --- a/src/gallium/drivers/radeon/radeon_uvd.c +++ b/src/gallium/drivers/radeon/radeon_uvd.c @@ -1003,7 +1003,7 @@ static void ruvd_end_frame(struct pipe_video_codec *decoder, dec->msg->body.decode.dpb_size = dec->dpb.res->buf->size; dec->msg->body.decode.bsd_size = bs_size; - dec->msg->body.decode.db_pitch = dec->base.width; + dec->msg->body.decode.db_pitch = align(dec->base.width, 16); dt = dec->set_dtb(dec->msg, (struct vl_video_buffer *)target); if (((struct r600_common_screen*)dec->screen)->family >= CHIP_STONEY) -- 1.9.1 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 1/3] radeon/uvd: handle HEVC main 10 decode
Signed-off-by: Boyuan Zhang <boyuan.zh...@amd.com> Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> --- src/gallium/drivers/radeon/radeon_uvd.c | 69 +++-- 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c index 6ea07be..164a2ae 100644 --- a/src/gallium/drivers/radeon/radeon_uvd.c +++ b/src/gallium/drivers/radeon/radeon_uvd.c @@ -207,7 +207,7 @@ static uint32_t profile2stream_type(struct ruvd_decoder *dec, unsigned family) } } -static unsigned calc_ctx_size(struct ruvd_decoder *dec) +static unsigned calc_ctx_size_h265_main(struct ruvd_decoder *dec) { unsigned width = align(dec->base.width, VL_MACROBLOCK_WIDTH); unsigned height = align(dec->base.height, VL_MACROBLOCK_HEIGHT); @@ -224,6 +224,39 @@ static unsigned calc_ctx_size(struct ruvd_decoder *dec) return ((width + 255) / 16) * ((height + 255) / 16) * 16 * max_references + 52 * 1024; } +static unsigned calc_ctx_size_h265_main10(struct ruvd_decoder *dec, struct pipe_h265_picture_desc *pic) +{ + unsigned block_size, log2_ctb_size, width_in_ctb, height_in_ctb, num_16x16_block_per_ctb; + unsigned context_buffer_size_per_ctb_row, cm_buffer_size, max_mb_address, db_left_tile_pxl_size; + unsigned db_left_tile_ctx_size = 4096 / 16 * (32 + 16 * 4); + + unsigned width = align(dec->base.width, VL_MACROBLOCK_WIDTH); + unsigned height = align(dec->base.height, VL_MACROBLOCK_HEIGHT); + unsigned coeff_10bit = (pic->pps->sps->bit_depth_luma_minus8 || pic->pps->sps->bit_depth_chroma_minus8) ? 2 : 1; + + unsigned max_references = dec->base.max_references + 1; + + if (dec->base.width * dec->base.height >= 4096*2000) + max_references = MAX2(max_references, 8); + else + max_references = MAX2(max_references, 17); + + block_size = (1 << (pic->pps->sps->log2_min_luma_coding_block_size_minus3 + 3)); + log2_ctb_size = block_size + pic->pps->sps->log2_diff_max_min_luma_coding_block_size; + + width_in_ctb = (width + ((1 << log2_ctb_size) - 1)) >> log2_ctb_size; + height_in_ctb = (height + ((1 << log2_ctb_size) - 1)) >> log2_ctb_size; + + num_16x16_block_per_ctb = ((1 << log2_ctb_size) >> 4) * ((1 << log2_ctb_size) >> 4); + context_buffer_size_per_ctb_row = align(width_in_ctb * num_16x16_block_per_ctb * 16, 256); + max_mb_address = (unsigned) ceil(height * 8 / 2048.0); + + cm_buffer_size = max_references * context_buffer_size_per_ctb_row * height_in_ctb; + db_left_tile_pxl_size = coeff_10bit * (max_mb_address * 2 * 2048 + 1024); + + return cm_buffer_size + db_left_tile_ctx_size + db_left_tile_pxl_size; +} + /* calculate size of reference picture buffer */ static unsigned calc_dpb_size(struct ruvd_decoder *dec) { @@ -305,7 +338,10 @@ static unsigned calc_dpb_size(struct ruvd_decoder *dec) width = align (width, 16); height = align (height, 16); - dpb_size = align((width * height * 3) / 2, 256) * max_references; + if (dec->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10) + dpb_size = align((width * height * 9) / 4, 256) * max_references; + else + dpb_size = align((width * height * 3) / 2, 256) * max_references; break; case PIPE_VIDEO_FORMAT_VC1: @@ -593,6 +629,15 @@ static struct ruvd_h265 get_h265_msg(struct ruvd_decoder *dec, struct pipe_video result.direct_reflist[i][j] = pic->RefPicList[i][j]; } + if ((pic->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10) && + (target->buffer_format == PIPE_FORMAT_NV12)) { + result.p010_mode = 0; + result.luma_10to8 = 5; + result.chroma_10to8 = 5; + result.sclr_luma10to8 = 4; + result.sclr_chroma10to8 = 4; + } + /* TODO result.highestTid; result.isNonRef; @@ -968,6 +1013,17 @@ static void ruvd_end_frame(struct pipe_video_codec *decoder, case PIPE_VIDEO_FORMAT_HEVC: dec->msg->body.decode.codec.h265 = get_h265_msg(dec, target, (struct pipe_h265_picture_desc*)picture); + if (dec->ctx.res == NULL) { + unsigned ctx_size; + if (dec->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10) + ctx_size = calc_ctx_size_h265_main10(dec, (struct pipe_h265_picture_desc*)picture); + else + ctx_size = calc_ctx_size_h265_main(dec); + if (!rvid_create_buffer(dec->screen, >ctx, ctx_size, PIPE_USAGE_DE