[Libva] [Libva PATCH] Encoding/avcenc: Optimize the allocated VA surfaces to reduce the memory pressure

Xiang, Haihao haihao.xiang at intel.com
Tue Nov 25 21:39:30 PST 2014


Applied.

Thanks
Haihao

> 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 at intel.com>
> ---
>  test/encode/avcenc.c |   45 +++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 43 insertions(+), 2 deletions(-)
> 
> diff --git a/test/encode/avcenc.c b/test/encode/avcenc.c
> index d28c7ef..ce40d0e 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;
>  }
>  
> @@ -1788,6 +1827,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 */
> @@ -1943,6 +1983,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;




More information about the Libva mailing list