[Mesa-dev] [PATCH 07/18] radeon/vcn: add common encode part

boyuan.zhang at amd.com boyuan.zhang at amd.com
Tue Nov 7 21:59:02 UTC 2017


From: Boyuan Zhang <boyuan.zhang at amd.com>

Signed-off-by: Boyuan Zhang <boyuan.zhang at amd.com>
---
 src/gallium/drivers/radeon/Makefile.sources     |   3 +
 src/gallium/drivers/radeon/radeon_vcn_enc.c     | 166 +++++++++++++++++
 src/gallium/drivers/radeon/radeon_vcn_enc.h     |  82 ++++++++
 src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c | 237 ++++++++++++++++++++++++
 4 files changed, 488 insertions(+)
 create mode 100644 src/gallium/drivers/radeon/radeon_vcn_enc.c
 create mode 100644 src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c

diff --git a/src/gallium/drivers/radeon/Makefile.sources b/src/gallium/drivers/radeon/Makefile.sources
index 22de129..0871666 100644
--- a/src/gallium/drivers/radeon/Makefile.sources
+++ b/src/gallium/drivers/radeon/Makefile.sources
@@ -13,6 +13,9 @@ C_SOURCES := \
 	radeon_uvd.h \
 	radeon_vcn_dec.c \
 	radeon_vcn_dec.h \
+	radeon_vcn_enc.c \
+	radeon_vcn_enc_1_2.c \
+	radeon_vcn_enc.h \
 	radeon_vce_40_2_2.c \
 	radeon_vce_50.c \
 	radeon_vce_52.c \
diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c
new file mode 100644
index 0000000..437c2fc
--- /dev/null
+++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c
@@ -0,0 +1,166 @@
+/**************************************************************************
+ *
+ * Copyright 2017 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 <stdio.h>
+
+#include "pipe/p_video_codec.h"
+
+#include "util/u_video.h"
+#include "util/u_memory.h"
+
+#include "vl/vl_video_buffer.h"
+
+#include "r600_pipe_common.h"
+#include "radeon_video.h"
+#include "radeon_vcn_enc.h"
+
+static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_h264_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->is_idr;
+	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;
+}
+
+static void flush(struct radeon_encoder *enc)
+{
+	enc->ws->cs_flush(enc->cs, RADEON_FLUSH_ASYNC, NULL);
+}
+
+static void radeon_enc_flush(struct pipe_video_codec *encoder)
+{
+	struct radeon_encoder *enc = (struct radeon_encoder*)encoder;
+	flush(enc);
+}
+
+static void radeon_enc_cs_flush(void *ctx, unsigned flags,
+								struct pipe_fence_handle **fence)
+{
+	// just ignored
+}
+
+static unsigned get_cpb_num(struct radeon_encoder *enc)
+{
+	unsigned w = align(enc->base.width, 16) / 16;
+	unsigned h = align(enc->base.height, 16) / 16;
+	unsigned dpb;
+
+	switch (enc->base.level) {
+	case 10:
+		dpb = 396;
+		break;
+	case 11:
+		dpb = 900;
+		break;
+	case 12:
+	case 13:
+	case 20:
+		dpb = 2376;
+		break;
+	case 21:
+		dpb = 4752;
+		break;
+	case 22:
+	case 30:
+		dpb = 8100;
+		break;
+	case 31:
+		dpb = 18000;
+		break;
+	case 32:
+		dpb = 20480;
+		break;
+	case 40:
+	case 41:
+		dpb = 32768;
+		break;
+	case 42:
+		dpb = 34816;
+		break;
+	case 50:
+		dpb = 110400;
+		break;
+	default:
+	case 51:
+	case 52:
+		dpb = 184320;
+		break;
+	}
+
+	return MIN2(dpb / (w * h), 16);
+}
+
+static void radeon_enc_begin_frame(struct pipe_video_codec *encoder,
+							 struct pipe_video_buffer *source,
+							 struct pipe_picture_desc *picture)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_encode_bitstream(struct pipe_video_codec *encoder,
+								  struct pipe_video_buffer *source,
+								  struct pipe_resource *destination,
+								  void **fb)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_end_frame(struct pipe_video_codec *encoder,
+						   struct pipe_video_buffer *source,
+						   struct pipe_picture_desc *picture)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_destroy(struct pipe_video_codec *encoder)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_get_feedback(struct pipe_video_codec *encoder,
+							  void *feedback, unsigned *size)
+{
+	/* TODO*/
+}
+
+struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context,
+		const struct pipe_video_codec *templ,
+		struct radeon_winsys* ws,
+		radeon_enc_get_buffer get_buffer)
+{
+	/* TODO*/
+}
+
+
diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.h b/src/gallium/drivers/radeon/radeon_vcn_enc.h
index a58ff6b..cbdf9c0 100644
--- a/src/gallium/drivers/radeon/radeon_vcn_enc.h
+++ b/src/gallium/drivers/radeon/radeon_vcn_enc.h
@@ -322,4 +322,86 @@ typedef struct rvcn_enc_feedback_buffer_s
     unsigned int	feedback_data_size;
 } rvcn_enc_feedback_buffer_t;
 
+typedef void (*radeon_enc_get_buffer)(struct pipe_resource *resource,
+		struct pb_buffer **handle,
+		struct radeon_surf **surface);
+
+struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context,
+		const struct pipe_video_codec *templat,
+		struct radeon_winsys* ws,
+		radeon_enc_get_buffer get_buffer);
+
+struct radeon_enc_h264_enc_pic {
+	enum	pipe_h264_enc_picture_type picture_type;
+
+	unsigned	frame_num;
+	unsigned	pic_order_cnt;
+	unsigned	pic_order_cnt_type;
+	unsigned	ref_idx_l0;
+	unsigned	ref_idx_l1;
+	unsigned	crop_left;
+	unsigned	crop_right;
+	unsigned	crop_top;
+	unsigned	crop_bottom;
+
+	bool	not_referenced;
+	bool	is_idr;
+
+	rvcn_enc_task_info_t	task_info;
+	rvcn_enc_session_init_t	session_init;
+	rvcn_enc_layer_control_t	layer_ctrl;
+	rvcn_enc_layer_select_t	layer_sel;
+	rvcn_enc_h264_slice_control_t	slice_ctrl;
+	rvcn_enc_h264_spec_misc_t	spec_misc;
+	rvcn_enc_rate_ctl_session_init_t	rc_session_init;
+	rvcn_enc_rate_ctl_layer_init_t	rc_layer_init;
+	rvcn_enc_h264_encode_params_t	h264_enc_params;
+	rvcn_enc_h264_deblocking_filter_t	h264_deblock;
+	rvcn_enc_rate_ctl_per_picture_t	rc_per_pic;
+	rvcn_enc_quality_params_t	quality_params;
+	rvcn_enc_encode_context_buffer_t	ctx_buf;
+	rvcn_enc_video_bitstream_buffer_t	bit_buf;
+	rvcn_enc_feedback_buffer_t	fb_buf;
+	rvcn_enc_intra_refresh_t	intra_ref;
+	rvcn_enc_encode_params_t	enc_params;
+};
+
+struct radeon_encoder {
+	struct pipe_video_codec		base;
+
+	void (*begin)(struct radeon_encoder *enc, struct pipe_h264_enc_picture_desc *pic);
+	void (*encode)(struct radeon_encoder *enc);
+	void (*destroy)(struct radeon_encoder *enc);
+
+	unsigned			stream_handle;
+
+	struct pipe_screen		*screen;
+	struct radeon_winsys*		ws;
+	struct radeon_winsys_cs*	cs;
+
+	radeon_enc_get_buffer			get_buffer;
+
+	struct pb_buffer*	handle;
+	struct radeon_surf*		luma;
+	struct radeon_surf*		chroma;
+
+	struct pb_buffer*	bs_handle;
+	unsigned			bs_size;
+
+	unsigned			cpb_num;
+
+	struct rvid_buffer		*si;
+	struct rvid_buffer		*fb;
+	struct rvid_buffer		cpb;
+	struct radeon_enc_h264_enc_pic	enc_pic;
+
+	unsigned			alignment;
+	uint32_t			total_task_size;
+	uint32_t*			p_task_size;
+
+	bool				need_feedback;
+};
+
+void radeon_enc_1_2_init(struct radeon_encoder *enc);
+
 #endif  // _RADEON_VCN_ENC_H
diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c
new file mode 100644
index 0000000..ffd1155
--- /dev/null
+++ b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c
@@ -0,0 +1,237 @@
+/**************************************************************************
+ *
+ * Copyright 2017 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 <stdio.h>
+
+#include "pipe/p_video_codec.h"
+
+#include "util/u_video.h"
+#include "util/u_memory.h"
+
+#include "vl/vl_video_buffer.h"
+
+#include "r600_pipe_common.h"
+#include "radeon_video.h"
+#include "radeon_vcn_enc.h"
+
+#define RADEON_ENC_CS(value) (enc->cs->current.buf[enc->cs->current.cdw++] = (value))
+#define RADEON_ENC_BEGIN(cmd) { \
+	uint32_t *begin = &enc->cs->current.buf[enc->cs->current.cdw++]; \
+RADEON_ENC_CS(cmd)
+#define RADEON_ENC_READ(buf, domain, off) radeon_enc_add_buffer(enc, (buf), RADEON_USAGE_READ, (domain), (off))
+#define RADEON_ENC_WRITE(buf, domain, off) radeon_enc_add_buffer(enc, (buf), RADEON_USAGE_WRITE, (domain), (off))
+#define RADEON_ENC_READWRITE(buf, domain, off) radeon_enc_add_buffer(enc, (buf), RADEON_USAGE_READWRITE, (domain), (off))
+#define RADEON_ENC_END() *begin = (&enc->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 void radeon_enc_add_buffer(struct radeon_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_enc_session_info(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_task_info(struct radeon_encoder *enc, bool need_feedback)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_session_init(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_layer_control(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_layer_select(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_slice_control(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_spec_misc(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_rc_session_init(struct radeon_encoder *enc, struct pipe_h264_enc_picture_desc *pic)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_rc_layer_init(struct radeon_encoder *enc, struct pipe_h264_enc_picture_desc *pic)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_deblocking_filter_h264(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_quality_params(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_ctx(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_bitstream(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_feedback(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_intra_refresh(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_rc_per_pic(struct radeon_encoder *enc, struct pipe_h264_enc_picture_desc *pic)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_encode_params(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+static void radeon_enc_encode_params_h264(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_op_init(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_op_close(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_op_enc(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_op_init_rc(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_op_init_rc_vbv(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void radeon_enc_op_speed(struct radeon_encoder *enc)
+{
+	/* TODO*/
+}
+
+static void begin(struct radeon_encoder *enc, struct pipe_h264_enc_picture_desc *pic)
+{
+	radeon_enc_session_info(enc);
+	enc->total_task_size = 0;
+	radeon_enc_task_info(enc, enc->need_feedback);
+	radeon_enc_op_init(enc);
+	radeon_enc_session_init(enc);
+	radeon_enc_layer_control(enc);
+	radeon_enc_slice_control(enc);
+	radeon_enc_spec_misc(enc);
+	radeon_enc_rc_session_init(enc, pic);
+	radeon_enc_deblocking_filter_h264(enc);
+	radeon_enc_quality_params(enc);
+	radeon_enc_layer_select(enc);
+	radeon_enc_rc_layer_init(enc, pic);
+	radeon_enc_layer_select(enc);
+	radeon_enc_rc_per_pic(enc, pic);
+	radeon_enc_op_init_rc(enc);
+	radeon_enc_op_init_rc_vbv(enc);
+	*enc->p_task_size = (enc->total_task_size);
+}
+
+static void encode(struct radeon_encoder *enc)
+{
+	radeon_enc_session_info(enc);
+	enc->total_task_size = 0;
+	radeon_enc_task_info(enc, enc->need_feedback);
+	radeon_enc_ctx(enc);
+	radeon_enc_bitstream(enc);
+	radeon_enc_feedback(enc);
+	radeon_enc_intra_refresh(enc);
+	radeon_enc_encode_params(enc);
+	radeon_enc_encode_params_h264(enc);
+	radeon_enc_op_speed(enc);
+	radeon_enc_op_enc(enc);
+	*enc->p_task_size = (enc->total_task_size);
+}
+
+static void destroy(struct radeon_encoder *enc)
+{
+	radeon_enc_session_info(enc);
+	enc->total_task_size = 0;
+	radeon_enc_task_info(enc, enc->need_feedback);
+	radeon_enc_op_close(enc);
+	*enc->p_task_size = (enc->total_task_size);
+}
+
+void radeon_enc_1_2_init(struct radeon_encoder *enc)
+{
+	enc->begin = begin;
+	enc->encode = encode;
+	enc->destroy = destroy;
+}
-- 
2.7.4



More information about the mesa-dev mailing list