summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2014-11-21 15:32:21 +0800
committerXiang, Haihao <haihao.xiang@intel.com>2014-11-26 13:38:43 +0800
commitc095cc6cf08523cd0dffcfe5ac4bce9122527f22 (patch)
treee71ea25f9e3229584022cd8b78db679f55b73113
parentfd83a7d44f790d40626eaa90fda18fb5c42b2c45 (diff)
downloadlibva-c095cc6cf08523cd0dffcfe5ac4bce9122527f22.tar.gz
Encoding/avcenc: Optimize the allocated VA surfaces to reduce the memory pressure
When it needs to encode one new frame, it will try to reuse the previously used surface for the reconstructed frame. In such case it is helpfl to reduce the memory pressure under multi-channel 4K encoding. Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
-rw-r--r--test/encode/avcenc.c45
1 files changed, 43 insertions, 2 deletions
diff --git a/test/encode/avcenc.c b/test/encode/avcenc.c
index 6097e35..d41fb1b 100644
--- a/test/encode/avcenc.c
+++ b/test/encode/avcenc.c
@@ -254,6 +254,7 @@ static void destory_encode_pipe()
static VASurfaceID surface_ids[SID_NUMBER];
static VASurfaceID ref_surface[SURFACE_NUM];
+static int use_slot[SURFACE_NUM];
static unsigned long long current_frame_display = 0;
static unsigned long long current_IDR_display = 0;
@@ -272,6 +273,23 @@ static unsigned int num_ref_frames = 2;
static unsigned int numShortTerm = 0;
/***************************************************/
+static int get_free_slot()
+{
+ int i, index = -1;
+
+ for (i = 0; i < SURFACE_NUM; i++) {
+ if (use_slot[i] == 0) {
+ index = i;
+ break;
+ }
+ }
+ if (index < 0) {
+ printf("WARNING: No free slot to store the reconstructed frame \n");
+ index = SURFACE_NUM - 1;
+ }
+ return index;
+}
+
static void *
upload_thread_function(void *data)
{
@@ -488,11 +506,13 @@ static void avcenc_update_picture_parameter(int slice_type, int is_idr)
{
VAEncPictureParameterBufferH264 *pic_param;
VAStatus va_status;
+ int recon_index;
+ recon_index = get_free_slot();
// Picture level
pic_param = &avcenc_context.pic_param;
- pic_param->CurrPic.picture_id = ref_surface[current_slot];
+ pic_param->CurrPic.picture_id = ref_surface[recon_index];
pic_param->CurrPic.frame_idx = current_frame_num;
pic_param->CurrPic.flags = 0;
@@ -674,7 +694,6 @@ static void avcenc_update_slice_parameter(int slice_type)
static int update_ReferenceFrames(void)
{
int i;
-
/* B-frame is not used for reference */
if (current_frame_type == SLICE_TYPE_B)
return 0;
@@ -692,6 +711,26 @@ static int update_ReferenceFrames(void)
if (current_frame_num > MaxFrameNum)
current_frame_num = 0;
+ /* Update the use_slot. Only when the surface is used in reference
+ * frame list, the use_slot[index] is set
+ */
+ for (i = 0; i < SURFACE_NUM; i++) {
+ int j;
+ bool found;
+
+ found = false;
+ for (j = 0; j < numShortTerm; j++) {
+ if (ref_surface[i] == ReferenceFrames[j].picture_id) {
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ use_slot[i] = 1;
+ else
+ use_slot[i] = 0;
+ }
+
return 0;
}
@@ -1790,6 +1829,7 @@ static void avcenc_context_init(int width, int height)
memset(&avcenc_context, 0, sizeof(avcenc_context));
avcenc_context.profile = VAProfileH264Main;
+ memset(&use_slot, 0, sizeof(use_slot));
switch (avcenc_context.profile) {
case VAProfileH264Baseline:
avcenc_context.constraint_set_flag |= (1 << 0); /* Annex A.2.1 */
@@ -1945,6 +1985,7 @@ int main(int argc, char *argv[])
if (current_frame_type == FRAME_IDR) {
numShortTerm = 0;
current_frame_num = 0;
+ memset(&use_slot, 0, sizeof(use_slot));
current_IDR_display = current_frame_display;
if (avcenc_context.rate_control_method == VA_RC_CBR) {
unsigned long long frame_interval;