From 700100d94bcd46b6088c27cc77e12f86f9fda122 Mon Sep 17 00:00:00 2001 From: Leo Liu Date: Thu, 12 Jun 2014 12:48:05 -0400 Subject: radeon/vce: set number of cpbs based on level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v2: add error check for cpb size 0 Signed-off-by: Leo Liu Reviewed-by: Christian König --- src/gallium/drivers/radeon/radeon_vce.c | 63 +++++++++++++++++++++++++++++++-- src/gallium/drivers/radeon/radeon_vce.h | 3 +- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vce.c b/src/gallium/drivers/radeon/radeon_vce.c index 81e62d365d3..f5395b3fb39 100644 --- a/src/gallium/drivers/radeon/radeon_vce.c +++ b/src/gallium/drivers/radeon/radeon_vce.c @@ -87,7 +87,7 @@ static void reset_cpb(struct rvce_encoder *enc) unsigned i; LIST_INITHEAD(&enc->cpb_slots); - for (i = 0; i < RVCE_NUM_CPB_FRAMES; ++i) { + for (i = 0; i < enc->cpb_num; ++i) { struct rvce_cpb_slot *slot = &enc->cpb_array[i]; slot->index = i; slot->picture_type = PIPE_H264_ENC_PICTURE_TYPE_SKIP; @@ -130,6 +130,59 @@ static void sort_cpb(struct rvce_encoder *enc) } } +/** + * get number of cpbs based on dpb + */ +static unsigned get_cpb_num(struct rvce_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; + default: + case 42: + dpb = 34816; + break; + case 50: + dpb = 110400; + break; + case 51: + dpb = 184320; + break; + } + + return MIN2(dpb / (w * h), 16); +} + /** * destroy this video encoder */ @@ -327,18 +380,22 @@ struct pipe_video_codec *rvce_create_encoder(struct pipe_context *context, goto error; } + enc->cpb_num = get_cpb_num(enc); + if (!enc->cpb_num) + goto error; + get_buffer(((struct vl_video_buffer *)tmp_buf)->resources[0], NULL, &tmp_surf); cpb_size = align(tmp_surf->level[0].pitch_bytes, 128); cpb_size = cpb_size * align(tmp_surf->npix_y, 16); cpb_size = cpb_size * 3 / 2; - cpb_size = cpb_size * RVCE_NUM_CPB_FRAMES; + cpb_size = cpb_size * enc->cpb_num; tmp_buf->destroy(tmp_buf); if (!rvid_create_buffer(enc->ws, &enc->cpb, cpb_size, RADEON_DOMAIN_VRAM)) { RVID_ERR("Can't create CPB buffer.\n"); goto error; } - enc->cpb_array = CALLOC(RVCE_NUM_CPB_FRAMES, sizeof(struct rvce_cpb_slot)); + enc->cpb_array = CALLOC(enc->cpb_num, sizeof(struct rvce_cpb_slot)); if (!enc->cpb_array) goto error; diff --git a/src/gallium/drivers/radeon/radeon_vce.h b/src/gallium/drivers/radeon/radeon_vce.h index 7cc87be37f3..f1dea8ae904 100644 --- a/src/gallium/drivers/radeon/radeon_vce.h +++ b/src/gallium/drivers/radeon/radeon_vce.h @@ -45,8 +45,6 @@ #define RVCE_READWRITE(buf, domain) RVCE_CS(RVCE_RELOC(buf, RADEON_USAGE_READWRITE, domain) * 4) #define RVCE_END() *begin = (&enc->cs->buf[enc->cs->cdw] - begin) * 4; } -#define RVCE_NUM_CPB_FRAMES 3 - struct r600_common_screen; /* driver dependent callback */ @@ -96,6 +94,7 @@ struct rvce_encoder { struct rvce_cpb_slot *cpb_array; struct list_head cpb_slots; + unsigned cpb_num; struct rvid_buffer *fb; struct rvid_buffer cpb; -- cgit v1.2.3