radeon/vce: set number of cpbs based on level
authorLeo Liu <leo.liu@amd.com>
Thu, 12 Jun 2014 16:48:05 +0000 (12:48 -0400)
committerChristian König <christian.koenig@amd.com>
Wed, 18 Jun 2014 11:53:27 +0000 (13:53 +0200)
v2: add error check for cpb size 0

Signed-off-by: Leo Liu <leo.liu@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
src/gallium/drivers/radeon/radeon_vce.c
src/gallium/drivers/radeon/radeon_vce.h

index 81e62d365d3ef92c45de23a550058106f6b355c0..f5395b3fb39314512ca2550eef12146c949c992a 100644 (file)
@@ -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;
 
index 7cc87be37f33bcba0cac1e5db38e93e1e0da7fb1..f1dea8ae904034132546ffe5a875a48d86af0cc6 100644 (file)
@@ -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;