[Mesa-dev] [PATCH] st/va: enable vbr rate control for vaapi encode
From: Boyuan Zhang This patch enables variable bit-rate for vaapi encoding. According to va.h, target bit-rate equals to maximum bit-rate multiplies by target_percentage. Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/config.c | 2 +- src/gallium/state_trackers/va/picture.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gallium/state_trackers/va/config.c b/src/gallium/state_trackers/va/config.c index 84bf913..4052316 100644 --- a/src/gallium/state_trackers/va/config.c +++ b/src/gallium/state_trackers/va/config.c @@ -120,7 +120,7 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en value = VA_RT_FORMAT_YUV420; break; case VAConfigAttribRateControl: - value = VA_RC_CQP | VA_RC_CBR; + value = VA_RC_CQP | VA_RC_CBR | VA_RC_VBR; break; default: value = VA_ATTRIB_NOT_SUPPORTED; diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index a283e83..7f3d96d 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -322,7 +322,7 @@ handleVAEncMiscParameterTypeRateControl(vlVaContext *context, VAEncMiscParameter PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT) context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second; else - context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second * rc->target_percentage; + context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second * rc->target_percentage / 100; context->desc.h264enc.rate_ctrl.peak_bitrate = rc->bits_per_second; if (context->desc.h264enc.rate_ctrl.target_bitrate < 200) context->desc.h264enc.rate_ctrl.vbv_buffer_size = MIN2((context->desc.h264enc.rate_ctrl.target_bitrate * 2.75), 200); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] st/va: force to flush the last p frame in idr period
From: Boyuan Zhang During dual instance encoding submission, if the second encode task and first encode task have no reference dependency, e.g. p following with idr-frame, there is a chance the second task will use for its reconstructed picture buffer the same buffer used by first task for its reference/reconstructed picture. In this case, buffer corruption may occur depending on encoding speed. Fix is to force flush these two tasks separately to avoid race condition Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 7f3d96d..eae5dc4 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -578,6 +578,9 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) } context->decoder->end_frame(context->decoder, context->target, &context->desc.base); + if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && + context->desc.h264enc.p_remain == 1) + context->decoder->flush(context->decoder); pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] st/va: disable cabac for h264 baseline profile
From: Boyuan Zhang cabac is only supported in the h264 main and higher profiles Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index eae5dc4..db08a3c 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -110,7 +110,6 @@ getEncParamPreset(vlVaContext *context) context->desc.h264enc.motion_est.enc_ime2_search_range_y = 0x0004; //pic control preset - context->desc.h264enc.pic_ctrl.enc_cabac_enable = 0x0001; context->desc.h264enc.pic_ctrl.enc_constraint_set_flags = 0x0040; //rate control -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 2/2] st/va: fix gop size for rate control
From: Boyuan Zhang The gop_size in rate control is the budget window for internal rate control calculation, and shouldn't always equal to idr period. Define a coefficient to let budget window contains a number of idr period for proper rate control calculation. Adjust the number of i/p frame remaining accordingly. Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c| 14 -- src/gallium/state_trackers/va/va_private.h | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 8326b5b..dc1cef5 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -350,7 +350,7 @@ handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vl if (!context->decoder) return VA_STATUS_ERROR_ALLOCATION_FAILED; } - context->desc.h264enc.gop_size = h264->intra_idr_period; + context->desc.h264enc.gop_size = h264->intra_idr_period * VL_VA_ENC_GOP_COEFF; context->desc.h264enc.rate_ctrl.frame_rate_num = h264->time_scale / 2; context->desc.h264enc.rate_ctrl.frame_rate_den = 1; return VA_STATUS_SUCCESS; @@ -390,10 +390,10 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV context->desc.h264enc.not_referenced = false; context->desc.h264enc.is_idr = (h264->pic_fields.bits.idr_pic_flag == 1); context->desc.h264enc.pic_order_cnt = h264->CurrPic.TopFieldOrderCnt / 2; - if (context->desc.h264enc.is_idr) - context->desc.h264enc.i_remain = 1; - else - context->desc.h264enc.i_remain = 0; + if (context->desc.h264enc.gop_cnt == 0) + context->desc.h264enc.i_remain = VL_VA_ENC_GOP_COEFF; + else if (context->desc.h264enc.frame_num == 1) + context->desc.h264enc.i_remain--; context->desc.h264enc.p_remain = context->desc.h264enc.gop_size - context->desc.h264enc.gop_cnt - context->desc.h264enc.i_remain; @@ -578,9 +578,11 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) context->decoder->end_frame(context->decoder, context->target, &context->desc.base); if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + int idr_period = context->desc.h264enc.gop_size / VL_VA_ENC_GOP_COEFF; + int p_remain_in_idr = idr_period - context->desc.h264enc.frame_num; surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; surf->force_flushed = false; - if (context->first_single_submitted || (context->desc.h264enc.p_remain == 1)) { + if (context->first_single_submitted || (p_remain_in_idr == 1)) { context->decoder->flush(context->decoder); context->first_single_submitted = false; surf->force_flushed = true; diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index e7f6f2d..ccdcdb3 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -50,6 +50,7 @@ #define VL_VA_PSCREEN(ctx) (VL_VA_DRIVER(ctx)->vscreen->pscreen) #define VL_VA_MAX_IMAGE_FORMATS 9 +#define VL_VA_ENC_GOP_COEFF 16 static inline enum pipe_video_chroma_format ChromaToPipe(int format) -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 1/2] st/va: force to submit two consecutive single jobs
From: Boyuan Zhang When using dual instance and rate control, driver needs to submit jobs either in dual submissions or 2 consecutive single submissions to keep the pattern constant for rate control Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c| 16 +++- src/gallium/state_trackers/va/surface.c| 7 +-- src/gallium/state_trackers/va/va_private.h | 2 ++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index db08a3c..8326b5b 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -412,7 +412,6 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV context->desc.h264enc.quant_i_frames = h264->pic_init_qp; context->desc.h264enc.quant_b_frames = h264->pic_init_qp; context->desc.h264enc.quant_p_frames = h264->pic_init_qp; - context->desc.h264enc.frame_num_cnt++; context->desc.h264enc.gop_cnt++; if (context->desc.h264enc.gop_cnt == context->desc.h264enc.gop_size) context->desc.h264enc.gop_cnt = 0; @@ -568,18 +567,25 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { coded_buf = context->coded_buf; getEncParamPreset(context); + context->desc.h264enc.frame_num_cnt++; context->decoder->begin_frame(context->decoder, context->target, &context->desc.base); context->decoder->encode_bitstream(context->decoder, context->target, coded_buf->derived_surface.resource, &feedback); - surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; surf->feedback = feedback; surf->coded_buf = coded_buf; } context->decoder->end_frame(context->decoder, context->target, &context->desc.base); - if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && - context->desc.h264enc.p_remain == 1) - context->decoder->flush(context->decoder); + + if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; + surf->force_flushed = false; + if (context->first_single_submitted || (context->desc.h264enc.p_remain == 1)) { + context->decoder->flush(context->decoder); + context->first_single_submitted = false; + surf->force_flushed = true; + } + } pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c index 3ee1cdd..39b1960 100644 --- a/src/gallium/state_trackers/va/surface.c +++ b/src/gallium/state_trackers/va/surface.c @@ -119,12 +119,15 @@ vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { int frame_diff; - if (context->desc.h264enc.frame_num_cnt > surf->frame_num_cnt) + if (context->desc.h264enc.frame_num_cnt >= surf->frame_num_cnt) frame_diff = context->desc.h264enc.frame_num_cnt - surf->frame_num_cnt; else frame_diff = 0x - surf->frame_num_cnt + 1 + context->desc.h264enc.frame_num_cnt; - if (frame_diff < 2) + if (frame_diff == 0 && surf->force_flushed == false) { context->decoder->flush(context->decoder); + if (context->desc.h264enc.rate_ctrl.rate_ctrl_method == PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE) +context->first_single_submitted = true; + } context->decoder->get_feedback(context->decoder, surf->feedback, &(surf->coded_buf->coded_size)); } pipe_mutex_unlock(drv->mutex); diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index e9ccdbf..e7f6f2d 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -244,6 +244,7 @@ typedef struct { struct vl_deint_filter *deint; struct vlVaBuffer *coded_buf; int target_id; + bool first_single_submitted; } vlVaContext; typedef struct { @@ -273,6 +274,7 @@ typedef struct { vlVaBuffer *coded_buf; void *feedback; unsigned int frame_num_cnt; + bool force_flushed; } vlVaSurface; // Public functions: -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 1/2] st/va: force to submit two consecutive single jobs
From: Boyuan Zhang When using dual instance and rate control, driver needs to submit jobs either in dual submissions or 2 consecutive single submissions to keep the pattern constant for rate control Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=98005 Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c| 15 ++- src/gallium/state_trackers/va/surface.c| 8 ++-- src/gallium/state_trackers/va/va_private.h | 2 ++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index a8102a4..a49c790 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -413,7 +413,6 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV context->desc.h264enc.quant_i_frames = h264->pic_init_qp; context->desc.h264enc.quant_b_frames = h264->pic_init_qp; context->desc.h264enc.quant_p_frames = h264->pic_init_qp; - context->desc.h264enc.frame_num_cnt++; context->desc.h264enc.gop_cnt++; if (context->desc.h264enc.gop_cnt == context->desc.h264enc.gop_size) context->desc.h264enc.gop_cnt = 0; @@ -569,18 +568,24 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { coded_buf = context->coded_buf; getEncParamPreset(context); + context->desc.h264enc.frame_num_cnt++; context->decoder->begin_frame(context->decoder, context->target, &context->desc.base); context->decoder->encode_bitstream(context->decoder, context->target, coded_buf->derived_surface.resource, &feedback); - surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; surf->feedback = feedback; surf->coded_buf = coded_buf; } context->decoder->end_frame(context->decoder, context->target, &context->desc.base); - if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && - context->desc.h264enc.p_remain == 1) - context->decoder->flush(context->decoder); + if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; + surf->force_flushed = false; + if (context->first_single_submitted || (context->desc.h264enc.p_remain == 1)) { + context->decoder->flush(context->decoder); + context->first_single_submitted = false; + surf->force_flushed = true; + } + } pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c index f8513d9..78342a1 100644 --- a/src/gallium/state_trackers/va/surface.c +++ b/src/gallium/state_trackers/va/surface.c @@ -125,12 +125,16 @@ vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { int frame_diff; - if (context->desc.h264enc.frame_num_cnt > surf->frame_num_cnt) + if (context->desc.h264enc.frame_num_cnt >= surf->frame_num_cnt) frame_diff = context->desc.h264enc.frame_num_cnt - surf->frame_num_cnt; else frame_diff = 0x - surf->frame_num_cnt + 1 + context->desc.h264enc.frame_num_cnt; - if (frame_diff < 2) + if (frame_diff == 0 && surf->force_flushed == false) { context->decoder->flush(context->decoder); + if (context->desc.h264enc.rate_ctrl.rate_ctrl_method == +PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE) +context->first_single_submitted = true; + } context->decoder->get_feedback(context->decoder, surf->feedback, &(surf->coded_buf->coded_size)); surf->feedback = NULL; } diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index c9a6a41..9e3ba03 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -244,6 +244,7 @@ typedef struct { struct vl_deint_filter *deint; struct vlVaBuffer *coded_buf; int target_id; + bool first_single_submitted; } vlVaContext; typedef struct { @@ -274,6 +275,7 @@ typedef struct { vlVaBuffer *coded_buf; void *feedback; unsigned int frame_num_cnt; + bool force_flushed; } vlVaSurface; // Public functions: -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 2/2] st/va: fix gop size for rate control
From: Boyuan Zhang The gop_size in rate control is the budget window for internal rate control calculation, and shouldn't always equal to idr period. Define a coefficient to let budget window contains a number of idr period for proper rate control calculation. Adjust the number of i/p frame remaining accordingly. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=98005 Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c| 14 -- src/gallium/state_trackers/va/va_private.h | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index a49c790..14d6d06 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -351,7 +351,7 @@ handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vl if (!context->decoder) return VA_STATUS_ERROR_ALLOCATION_FAILED; } - context->desc.h264enc.gop_size = h264->intra_idr_period; + context->desc.h264enc.gop_size = h264->intra_idr_period * VL_VA_ENC_GOP_COEFF; context->desc.h264enc.rate_ctrl.frame_rate_num = h264->time_scale / 2; context->desc.h264enc.rate_ctrl.frame_rate_den = 1; return VA_STATUS_SUCCESS; @@ -391,10 +391,10 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV context->desc.h264enc.not_referenced = false; context->desc.h264enc.is_idr = (h264->pic_fields.bits.idr_pic_flag == 1); context->desc.h264enc.pic_order_cnt = h264->CurrPic.TopFieldOrderCnt; - if (context->desc.h264enc.is_idr) - context->desc.h264enc.i_remain = 1; - else - context->desc.h264enc.i_remain = 0; + if (context->desc.h264enc.gop_cnt == 0) + context->desc.h264enc.i_remain = VL_VA_ENC_GOP_COEFF; + else if (context->desc.h264enc.frame_num == 1) + context->desc.h264enc.i_remain--; context->desc.h264enc.p_remain = context->desc.h264enc.gop_size - context->desc.h264enc.gop_cnt - context->desc.h264enc.i_remain; @@ -578,9 +578,11 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) context->decoder->end_frame(context->decoder, context->target, &context->desc.base); if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + int idr_period = context->desc.h264enc.gop_size / VL_VA_ENC_GOP_COEFF; + int p_remain_in_idr = idr_period - context->desc.h264enc.frame_num; surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; surf->force_flushed = false; - if (context->first_single_submitted || (context->desc.h264enc.p_remain == 1)) { + if (context->first_single_submitted || (p_remain_in_idr == 1)) { context->decoder->flush(context->decoder); context->first_single_submitted = false; surf->force_flushed = true; diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index 9e3ba03..89c9532 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -50,6 +50,7 @@ #define VL_VA_PSCREEN(ctx) (VL_VA_DRIVER(ctx)->vscreen->pscreen) #define VL_VA_MAX_IMAGE_FORMATS 9 +#define VL_VA_ENC_GOP_COEFF 16 static inline enum pipe_video_chroma_format ChromaToPipe(int format) -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 2/2] st/va: fix gop size for rate control
From: Boyuan Zhang The gop_size in rate control is the budget window for internal rate control calculation, and shouldn't always equal to idr period. Define a coefficient to let budget window contains a number of idr period for proper rate control calculation. Adjust the number of i/p frame remaining accordingly. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=98005 Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c| 18 -- src/gallium/state_trackers/va/va_private.h | 2 ++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 592cdef..b5b9a83 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -351,7 +351,11 @@ handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vl if (!context->decoder) return VA_STATUS_ERROR_ALLOCATION_FAILED; } - context->desc.h264enc.gop_size = h264->intra_idr_period; + + context->gop_coeff = ((1024 + h264->intra_idr_period - 1) / h264->intra_idr_period + 1) / 2 * 2; + if (context->gop_coeff > VL_VA_ENC_GOP_COEFF) + context->gop_coeff = VL_VA_ENC_GOP_COEFF; + context->desc.h264enc.gop_size = h264->intra_idr_period * context->gop_coeff; context->desc.h264enc.rate_ctrl.frame_rate_num = h264->time_scale / 2; context->desc.h264enc.rate_ctrl.frame_rate_den = 1; return VA_STATUS_SUCCESS; @@ -391,10 +395,10 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV context->desc.h264enc.not_referenced = false; context->desc.h264enc.is_idr = (h264->pic_fields.bits.idr_pic_flag == 1); context->desc.h264enc.pic_order_cnt = h264->CurrPic.TopFieldOrderCnt; - if (context->desc.h264enc.is_idr) - context->desc.h264enc.i_remain = 1; - else - context->desc.h264enc.i_remain = 0; + if (context->desc.h264enc.gop_cnt == 0) + context->desc.h264enc.i_remain = context->gop_coeff; + else if (context->desc.h264enc.frame_num == 1) + context->desc.h264enc.i_remain--; context->desc.h264enc.p_remain = context->desc.h264enc.gop_size - context->desc.h264enc.gop_cnt - context->desc.h264enc.i_remain; @@ -578,6 +582,8 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) context->decoder->end_frame(context->decoder, context->target, &context->desc.base); if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + int idr_period = context->desc.h264enc.gop_size / context->gop_coeff; + int p_remain_in_idr = idr_period - context->desc.h264enc.frame_num; surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; surf->force_flushed = false; if (context->first_single_submitted) { @@ -585,7 +591,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) context->first_single_submitted = false; surf->force_flushed = true; } - if (context->desc.h264enc.p_remain == 1) { + if (p_remain_in_idr == 1) { if ((context->desc.h264enc.frame_num_cnt % 2) != 0) { context->decoder->flush(context->decoder); context->first_single_submitted = true; diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index 9e3ba03..900abbc 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -50,6 +50,7 @@ #define VL_VA_PSCREEN(ctx) (VL_VA_DRIVER(ctx)->vscreen->pscreen) #define VL_VA_MAX_IMAGE_FORMATS 9 +#define VL_VA_ENC_GOP_COEFF 16 static inline enum pipe_video_chroma_format ChromaToPipe(int format) @@ -245,6 +246,7 @@ typedef struct { struct vlVaBuffer *coded_buf; int target_id; bool first_single_submitted; + int gop_coeff; } vlVaContext; typedef struct { -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 1/2] st/va: force to submit two consecutive single jobs
From: Boyuan Zhang When using dual instance and rate control, driver needs to submit jobs either in dual submissions or 2 consecutive single submissions to keep the pattern constant for rate control Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=98005 Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c| 24 +++- src/gallium/state_trackers/va/surface.c| 8 ++-- src/gallium/state_trackers/va/va_private.h | 2 ++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index a8102a4..592cdef 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -413,7 +413,6 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV context->desc.h264enc.quant_i_frames = h264->pic_init_qp; context->desc.h264enc.quant_b_frames = h264->pic_init_qp; context->desc.h264enc.quant_p_frames = h264->pic_init_qp; - context->desc.h264enc.frame_num_cnt++; context->desc.h264enc.gop_cnt++; if (context->desc.h264enc.gop_cnt == context->desc.h264enc.gop_size) context->desc.h264enc.gop_cnt = 0; @@ -569,18 +568,33 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { coded_buf = context->coded_buf; getEncParamPreset(context); + context->desc.h264enc.frame_num_cnt++; context->decoder->begin_frame(context->decoder, context->target, &context->desc.base); context->decoder->encode_bitstream(context->decoder, context->target, coded_buf->derived_surface.resource, &feedback); - surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; surf->feedback = feedback; surf->coded_buf = coded_buf; } context->decoder->end_frame(context->decoder, context->target, &context->desc.base); - if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && - context->desc.h264enc.p_remain == 1) - context->decoder->flush(context->decoder); + if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; + surf->force_flushed = false; + if (context->first_single_submitted) { + context->decoder->flush(context->decoder); + context->first_single_submitted = false; + surf->force_flushed = true; + } + if (context->desc.h264enc.p_remain == 1) { + if ((context->desc.h264enc.frame_num_cnt % 2) != 0) { +context->decoder->flush(context->decoder); +context->first_single_submitted = true; + } + else +context->first_single_submitted = false; + surf->force_flushed = true; + } + } pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c index f8513d9..78342a1 100644 --- a/src/gallium/state_trackers/va/surface.c +++ b/src/gallium/state_trackers/va/surface.c @@ -125,12 +125,16 @@ vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { int frame_diff; - if (context->desc.h264enc.frame_num_cnt > surf->frame_num_cnt) + if (context->desc.h264enc.frame_num_cnt >= surf->frame_num_cnt) frame_diff = context->desc.h264enc.frame_num_cnt - surf->frame_num_cnt; else frame_diff = 0x - surf->frame_num_cnt + 1 + context->desc.h264enc.frame_num_cnt; - if (frame_diff < 2) + if (frame_diff == 0 && surf->force_flushed == false) { context->decoder->flush(context->decoder); + if (context->desc.h264enc.rate_ctrl.rate_ctrl_method == +PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE) +context->first_single_submitted = true; + } context->decoder->get_feedback(context->decoder, surf->feedback, &(surf->coded_buf->coded_size)); surf->feedback = NULL; } diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index c9a6a41..9e3ba03 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -244,6 +244,7 @@ typedef struct { struct vl_deint_filter *deint; struct vlVaBuffer *coded_buf; int target_id; + bool first_single_submitted; } vlVaContext; typedef struct { @@ -274,6 +275,7 @@ typedef struct { vlVaBuffer *coded_buf; void *feedback; unsigned int frame_num_cnt; + bool force_flushed; } vlVaSurface; // Public functions: -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 1/2] st/va: force to submit two consecutive single jobs
From: Boyuan Zhang The gop_size in rate control is the budget window for internal rate control calculation, and shouldn't always equal to idr period. Define a coefficient to let budget window contains a number of idr period for proper rate control calculation. Adjust the number of i/p frame remaining accordingly. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=98005 Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c| 24 +++- src/gallium/state_trackers/va/surface.c| 8 ++-- src/gallium/state_trackers/va/va_private.h | 2 ++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index a8102a4..592cdef 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -413,7 +413,6 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV context->desc.h264enc.quant_i_frames = h264->pic_init_qp; context->desc.h264enc.quant_b_frames = h264->pic_init_qp; context->desc.h264enc.quant_p_frames = h264->pic_init_qp; - context->desc.h264enc.frame_num_cnt++; context->desc.h264enc.gop_cnt++; if (context->desc.h264enc.gop_cnt == context->desc.h264enc.gop_size) context->desc.h264enc.gop_cnt = 0; @@ -569,18 +568,33 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { coded_buf = context->coded_buf; getEncParamPreset(context); + context->desc.h264enc.frame_num_cnt++; context->decoder->begin_frame(context->decoder, context->target, &context->desc.base); context->decoder->encode_bitstream(context->decoder, context->target, coded_buf->derived_surface.resource, &feedback); - surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; surf->feedback = feedback; surf->coded_buf = coded_buf; } context->decoder->end_frame(context->decoder, context->target, &context->desc.base); - if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && - context->desc.h264enc.p_remain == 1) - context->decoder->flush(context->decoder); + if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; + surf->force_flushed = false; + if (context->first_single_submitted) { + context->decoder->flush(context->decoder); + context->first_single_submitted = false; + surf->force_flushed = true; + } + if (context->desc.h264enc.p_remain == 1) { + if ((context->desc.h264enc.frame_num_cnt % 2) != 0) { +context->decoder->flush(context->decoder); +context->first_single_submitted = true; + } + else +context->first_single_submitted = false; + surf->force_flushed = true; + } + } pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c index f8513d9..85d2b9d 100644 --- a/src/gallium/state_trackers/va/surface.c +++ b/src/gallium/state_trackers/va/surface.c @@ -125,12 +125,16 @@ vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { int frame_diff; - if (context->desc.h264enc.frame_num_cnt > surf->frame_num_cnt) + if (context->desc.h264enc.frame_num_cnt >= surf->frame_num_cnt) frame_diff = context->desc.h264enc.frame_num_cnt - surf->frame_num_cnt; else frame_diff = 0x - surf->frame_num_cnt + 1 + context->desc.h264enc.frame_num_cnt; - if (frame_diff < 2) + if (frame_diff == 0 && surf->force_flushed == false) { context->decoder->flush(context->decoder); + if (context->desc.h264enc.rate_ctrl.rate_ctrl_method != +PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE) +context->first_single_submitted = true; + } context->decoder->get_feedback(context->decoder, surf->feedback, &(surf->coded_buf->coded_size)); surf->feedback = NULL; } diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index c9a6a41..9e3ba03 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -244,6 +244,7 @@ typedef struct { struct vl_deint_filter *deint; struct vlVaBuffer *coded_buf; int target_id; + bool first_single_submitted; } vlVaContext; typedef struct { @@ -274,6 +275,7 @@ typedef struct { vlVaBuffer *coded_buf; void *feedback; unsigned int frame_num_cnt; + bool force_flushed; } vlVaSurface; // Public functions: -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesk
[Mesa-dev] [PATCH 2/2] st/va: fix gop size for rate control
From: Boyuan Zhang The gop_size in rate control is the budget window for internal rate control calculation, and shouldn't always equal to idr period. Define a coefficient to let budget window contains a number of idr period for proper rate control calculation. Adjust the number of i/p frame remaining accordingly. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=98005 Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c| 18 -- src/gallium/state_trackers/va/va_private.h | 2 ++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 592cdef..b5b9a83 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -351,7 +351,11 @@ handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vl if (!context->decoder) return VA_STATUS_ERROR_ALLOCATION_FAILED; } - context->desc.h264enc.gop_size = h264->intra_idr_period; + + context->gop_coeff = ((1024 + h264->intra_idr_period - 1) / h264->intra_idr_period + 1) / 2 * 2; + if (context->gop_coeff > VL_VA_ENC_GOP_COEFF) + context->gop_coeff = VL_VA_ENC_GOP_COEFF; + context->desc.h264enc.gop_size = h264->intra_idr_period * context->gop_coeff; context->desc.h264enc.rate_ctrl.frame_rate_num = h264->time_scale / 2; context->desc.h264enc.rate_ctrl.frame_rate_den = 1; return VA_STATUS_SUCCESS; @@ -391,10 +395,10 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV context->desc.h264enc.not_referenced = false; context->desc.h264enc.is_idr = (h264->pic_fields.bits.idr_pic_flag == 1); context->desc.h264enc.pic_order_cnt = h264->CurrPic.TopFieldOrderCnt; - if (context->desc.h264enc.is_idr) - context->desc.h264enc.i_remain = 1; - else - context->desc.h264enc.i_remain = 0; + if (context->desc.h264enc.gop_cnt == 0) + context->desc.h264enc.i_remain = context->gop_coeff; + else if (context->desc.h264enc.frame_num == 1) + context->desc.h264enc.i_remain--; context->desc.h264enc.p_remain = context->desc.h264enc.gop_size - context->desc.h264enc.gop_cnt - context->desc.h264enc.i_remain; @@ -578,6 +582,8 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) context->decoder->end_frame(context->decoder, context->target, &context->desc.base); if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + int idr_period = context->desc.h264enc.gop_size / context->gop_coeff; + int p_remain_in_idr = idr_period - context->desc.h264enc.frame_num; surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; surf->force_flushed = false; if (context->first_single_submitted) { @@ -585,7 +591,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) context->first_single_submitted = false; surf->force_flushed = true; } - if (context->desc.h264enc.p_remain == 1) { + if (p_remain_in_idr == 1) { if ((context->desc.h264enc.frame_num_cnt % 2) != 0) { context->decoder->flush(context->decoder); context->first_single_submitted = true; diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index 9e3ba03..900abbc 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -50,6 +50,7 @@ #define VL_VA_PSCREEN(ctx) (VL_VA_DRIVER(ctx)->vscreen->pscreen) #define VL_VA_MAX_IMAGE_FORMATS 9 +#define VL_VA_ENC_GOP_COEFF 16 static inline enum pipe_video_chroma_format ChromaToPipe(int format) @@ -245,6 +246,7 @@ typedef struct { struct vlVaBuffer *coded_buf; int target_id; bool first_single_submitted; + int gop_coeff; } vlVaContext; typedef struct { -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 2/2] st/va: fix gop size for rate control
From: Boyuan Zhang The gop_size in rate control is the budget window for internal rate control calculation, and shouldn't always equal to idr period. Define a coefficient to let budget window contains a number of idr period for proper rate control calculation. Adjust the number of i/p frame remaining accordingly. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=98005 Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c| 18 -- src/gallium/state_trackers/va/va_private.h | 2 ++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 592cdef..b5b9a83 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -351,7 +351,11 @@ handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vl if (!context->decoder) return VA_STATUS_ERROR_ALLOCATION_FAILED; } - context->desc.h264enc.gop_size = h264->intra_idr_period; + + context->gop_coeff = ((1024 + h264->intra_idr_period - 1) / h264->intra_idr_period + 1) / 2 * 2; + if (context->gop_coeff > VL_VA_ENC_GOP_COEFF) + context->gop_coeff = VL_VA_ENC_GOP_COEFF; + context->desc.h264enc.gop_size = h264->intra_idr_period * context->gop_coeff; context->desc.h264enc.rate_ctrl.frame_rate_num = h264->time_scale / 2; context->desc.h264enc.rate_ctrl.frame_rate_den = 1; return VA_STATUS_SUCCESS; @@ -391,10 +395,10 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV context->desc.h264enc.not_referenced = false; context->desc.h264enc.is_idr = (h264->pic_fields.bits.idr_pic_flag == 1); context->desc.h264enc.pic_order_cnt = h264->CurrPic.TopFieldOrderCnt; - if (context->desc.h264enc.is_idr) - context->desc.h264enc.i_remain = 1; - else - context->desc.h264enc.i_remain = 0; + if (context->desc.h264enc.gop_cnt == 0) + context->desc.h264enc.i_remain = context->gop_coeff; + else if (context->desc.h264enc.frame_num == 1) + context->desc.h264enc.i_remain--; context->desc.h264enc.p_remain = context->desc.h264enc.gop_size - context->desc.h264enc.gop_cnt - context->desc.h264enc.i_remain; @@ -578,6 +582,8 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) context->decoder->end_frame(context->decoder, context->target, &context->desc.base); if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + int idr_period = context->desc.h264enc.gop_size / context->gop_coeff; + int p_remain_in_idr = idr_period - context->desc.h264enc.frame_num; surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; surf->force_flushed = false; if (context->first_single_submitted) { @@ -585,7 +591,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) context->first_single_submitted = false; surf->force_flushed = true; } - if (context->desc.h264enc.p_remain == 1) { + if (p_remain_in_idr == 1) { if ((context->desc.h264enc.frame_num_cnt % 2) != 0) { context->decoder->flush(context->decoder); context->first_single_submitted = true; diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index 9e3ba03..900abbc 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -50,6 +50,7 @@ #define VL_VA_PSCREEN(ctx) (VL_VA_DRIVER(ctx)->vscreen->pscreen) #define VL_VA_MAX_IMAGE_FORMATS 9 +#define VL_VA_ENC_GOP_COEFF 16 static inline enum pipe_video_chroma_format ChromaToPipe(int format) @@ -245,6 +246,7 @@ typedef struct { struct vlVaBuffer *coded_buf; int target_id; bool first_single_submitted; + int gop_coeff; } vlVaContext; typedef struct { -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 1/2] st/va: force to submit two consecutive single jobs
From: Boyuan Zhang The gop_size in rate control is the budget window for internal rate control calculation, and shouldn't always equal to idr period. Define a coefficient to let budget window contains a number of idr period for proper rate control calculation. Adjust the number of i/p frame remaining accordingly. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=98005 Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c| 24 +++- src/gallium/state_trackers/va/surface.c| 10 -- src/gallium/state_trackers/va/va_private.h | 2 ++ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index a8102a4..592cdef 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -413,7 +413,6 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV context->desc.h264enc.quant_i_frames = h264->pic_init_qp; context->desc.h264enc.quant_b_frames = h264->pic_init_qp; context->desc.h264enc.quant_p_frames = h264->pic_init_qp; - context->desc.h264enc.frame_num_cnt++; context->desc.h264enc.gop_cnt++; if (context->desc.h264enc.gop_cnt == context->desc.h264enc.gop_size) context->desc.h264enc.gop_cnt = 0; @@ -569,18 +568,33 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { coded_buf = context->coded_buf; getEncParamPreset(context); + context->desc.h264enc.frame_num_cnt++; context->decoder->begin_frame(context->decoder, context->target, &context->desc.base); context->decoder->encode_bitstream(context->decoder, context->target, coded_buf->derived_surface.resource, &feedback); - surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; surf->feedback = feedback; surf->coded_buf = coded_buf; } context->decoder->end_frame(context->decoder, context->target, &context->desc.base); - if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && - context->desc.h264enc.p_remain == 1) - context->decoder->flush(context->decoder); + if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; + surf->force_flushed = false; + if (context->first_single_submitted) { + context->decoder->flush(context->decoder); + context->first_single_submitted = false; + surf->force_flushed = true; + } + if (context->desc.h264enc.p_remain == 1) { + if ((context->desc.h264enc.frame_num_cnt % 2) != 0) { +context->decoder->flush(context->decoder); +context->first_single_submitted = true; + } + else +context->first_single_submitted = false; + surf->force_flushed = true; + } + } pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c index f8513d9..a7f3c35 100644 --- a/src/gallium/state_trackers/va/surface.c +++ b/src/gallium/state_trackers/va/surface.c @@ -125,12 +125,18 @@ vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { int frame_diff; - if (context->desc.h264enc.frame_num_cnt > surf->frame_num_cnt) + if (context->desc.h264enc.frame_num_cnt >= surf->frame_num_cnt) frame_diff = context->desc.h264enc.frame_num_cnt - surf->frame_num_cnt; else frame_diff = 0x - surf->frame_num_cnt + 1 + context->desc.h264enc.frame_num_cnt; - if (frame_diff < 2) + if ((frame_diff == 0) && + (surf->force_flushed == false) && + (context->desc.h264enc.frame_num_cnt % 2 != 0)) { context->decoder->flush(context->decoder); + if (context->desc.h264enc.rate_ctrl.rate_ctrl_method != +PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE) +context->first_single_submitted = true; + } context->decoder->get_feedback(context->decoder, surf->feedback, &(surf->coded_buf->coded_size)); surf->feedback = NULL; } diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index c9a6a41..9e3ba03 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -244,6 +244,7 @@ typedef struct { struct vl_deint_filter *deint; struct vlVaBuffer *coded_buf; int target_id; + bool first_single_submitted; } vlVaContext; typedef struct { @@ -274,6 +275,7 @@ typedef struct { vlVaBuffer *coded_buf; void *feedback; unsigned int frame_num_cnt; + bool force_flushed; } vlVaSurface; // Public functions: -- 2.7.4 ___
[Mesa-dev] [PATCH 2/2] st/va: fix gop size for rate control
From: Boyuan Zhang The gop_size in rate control is the budget window for internal rate control calculation, and shouldn't always equal to idr period. Define a coefficient to let budget window contains a number of idr period for proper rate control calculation. Adjust the number of i/p frame remaining accordingly. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=98005 Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c| 18 -- src/gallium/state_trackers/va/va_private.h | 2 ++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 592cdef..b5b9a83 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -351,7 +351,11 @@ handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vl if (!context->decoder) return VA_STATUS_ERROR_ALLOCATION_FAILED; } - context->desc.h264enc.gop_size = h264->intra_idr_period; + + context->gop_coeff = ((1024 + h264->intra_idr_period - 1) / h264->intra_idr_period + 1) / 2 * 2; + if (context->gop_coeff > VL_VA_ENC_GOP_COEFF) + context->gop_coeff = VL_VA_ENC_GOP_COEFF; + context->desc.h264enc.gop_size = h264->intra_idr_period * context->gop_coeff; context->desc.h264enc.rate_ctrl.frame_rate_num = h264->time_scale / 2; context->desc.h264enc.rate_ctrl.frame_rate_den = 1; return VA_STATUS_SUCCESS; @@ -391,10 +395,10 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV context->desc.h264enc.not_referenced = false; context->desc.h264enc.is_idr = (h264->pic_fields.bits.idr_pic_flag == 1); context->desc.h264enc.pic_order_cnt = h264->CurrPic.TopFieldOrderCnt; - if (context->desc.h264enc.is_idr) - context->desc.h264enc.i_remain = 1; - else - context->desc.h264enc.i_remain = 0; + if (context->desc.h264enc.gop_cnt == 0) + context->desc.h264enc.i_remain = context->gop_coeff; + else if (context->desc.h264enc.frame_num == 1) + context->desc.h264enc.i_remain--; context->desc.h264enc.p_remain = context->desc.h264enc.gop_size - context->desc.h264enc.gop_cnt - context->desc.h264enc.i_remain; @@ -578,6 +582,8 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) context->decoder->end_frame(context->decoder, context->target, &context->desc.base); if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + int idr_period = context->desc.h264enc.gop_size / context->gop_coeff; + int p_remain_in_idr = idr_period - context->desc.h264enc.frame_num; surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; surf->force_flushed = false; if (context->first_single_submitted) { @@ -585,7 +591,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) context->first_single_submitted = false; surf->force_flushed = true; } - if (context->desc.h264enc.p_remain == 1) { + if (p_remain_in_idr == 1) { if ((context->desc.h264enc.frame_num_cnt % 2) != 0) { context->decoder->flush(context->decoder); context->first_single_submitted = true; diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index 9e3ba03..900abbc 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -50,6 +50,7 @@ #define VL_VA_PSCREEN(ctx) (VL_VA_DRIVER(ctx)->vscreen->pscreen) #define VL_VA_MAX_IMAGE_FORMATS 9 +#define VL_VA_ENC_GOP_COEFF 16 static inline enum pipe_video_chroma_format ChromaToPipe(int format) @@ -245,6 +246,7 @@ typedef struct { struct vlVaBuffer *coded_buf; int target_id; bool first_single_submitted; + int gop_coeff; } vlVaContext; typedef struct { -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 1/2] st/va: force to submit two consecutive single jobs
From: Boyuan Zhang The gop_size in rate control is the budget window for internal rate control calculation, and shouldn't always equal to idr period. Define a coefficient to let budget window contains a number of idr period for proper rate control calculation. Adjust the number of i/p frame remaining accordingly. v2: fixed regression issues introduced by previous version Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=98005 Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c| 24 +++- src/gallium/state_trackers/va/surface.c| 8 ++-- src/gallium/state_trackers/va/va_private.h | 2 ++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index a8102a4..592cdef 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -413,7 +413,6 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV context->desc.h264enc.quant_i_frames = h264->pic_init_qp; context->desc.h264enc.quant_b_frames = h264->pic_init_qp; context->desc.h264enc.quant_p_frames = h264->pic_init_qp; - context->desc.h264enc.frame_num_cnt++; context->desc.h264enc.gop_cnt++; if (context->desc.h264enc.gop_cnt == context->desc.h264enc.gop_size) context->desc.h264enc.gop_cnt = 0; @@ -569,18 +568,33 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { coded_buf = context->coded_buf; getEncParamPreset(context); + context->desc.h264enc.frame_num_cnt++; context->decoder->begin_frame(context->decoder, context->target, &context->desc.base); context->decoder->encode_bitstream(context->decoder, context->target, coded_buf->derived_surface.resource, &feedback); - surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; surf->feedback = feedback; surf->coded_buf = coded_buf; } context->decoder->end_frame(context->decoder, context->target, &context->desc.base); - if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && - context->desc.h264enc.p_remain == 1) - context->decoder->flush(context->decoder); + if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { + surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt; + surf->force_flushed = false; + if (context->first_single_submitted) { + context->decoder->flush(context->decoder); + context->first_single_submitted = false; + surf->force_flushed = true; + } + if (context->desc.h264enc.p_remain == 1) { + if ((context->desc.h264enc.frame_num_cnt % 2) != 0) { +context->decoder->flush(context->decoder); +context->first_single_submitted = true; + } + else +context->first_single_submitted = false; + surf->force_flushed = true; + } + } pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c index f8513d9..38b3151 100644 --- a/src/gallium/state_trackers/va/surface.c +++ b/src/gallium/state_trackers/va/surface.c @@ -125,12 +125,16 @@ vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target) if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { int frame_diff; - if (context->desc.h264enc.frame_num_cnt > surf->frame_num_cnt) + if (context->desc.h264enc.frame_num_cnt >= surf->frame_num_cnt) frame_diff = context->desc.h264enc.frame_num_cnt - surf->frame_num_cnt; else frame_diff = 0x - surf->frame_num_cnt + 1 + context->desc.h264enc.frame_num_cnt; - if (frame_diff < 2) + if ((frame_diff == 0) && + (surf->force_flushed == false) && + (context->desc.h264enc.frame_num_cnt % 2 != 0)) { context->decoder->flush(context->decoder); + context->first_single_submitted = true; + } context->decoder->get_feedback(context->decoder, surf->feedback, &(surf->coded_buf->coded_size)); surf->feedback = NULL; } diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index c9a6a41..9e3ba03 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -244,6 +244,7 @@ typedef struct { struct vl_deint_filter *deint; struct vlVaBuffer *coded_buf; int target_id; + bool first_single_submitted; } vlVaContext; typedef struct { @@ -274,6 +275,7 @@ typedef struct { vlVaBuffer *coded_buf; void *feedback; unsigned int frame_num_cnt; + bool force_flushed; } vlVaSurface; // Public functions: -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lis
[Mesa-dev] [PATCH 4/4] st/va: add h264 constrained baseline profile
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/va_private.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index e9ccdbf..08e52fd 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -154,6 +154,7 @@ PipeToProfile(enum pipe_video_profile profile) case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10: case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH422: case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH444: + case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE: case PIPE_VIDEO_PROFILE_HEVC_MAIN_12: case PIPE_VIDEO_PROFILE_HEVC_MAIN_STILL: case PIPE_VIDEO_PROFILE_HEVC_MAIN_444: -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 2/4] radeon/uvd: add h264 constrained baseline support
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_uvd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c index d5d654a..228c20d 100644 --- a/src/gallium/drivers/radeon/radeon_uvd.c +++ b/src/gallium/drivers/radeon/radeon_uvd.c @@ -476,6 +476,7 @@ static struct ruvd_h264 get_h264_msg(struct ruvd_decoder *dec, struct pipe_h264_ memset(&result, 0, sizeof(result)); switch (pic->base.profile) { case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE: + case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE: result.profile = RUVD_H264_PROFILE_BASELINE; break; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 1/4] vl: add h264 constrained baseline profile
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/auxiliary/util/u_video.h | 1 + src/gallium/include/pipe/p_video_enums.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/gallium/auxiliary/util/u_video.h b/src/gallium/auxiliary/util/u_video.h index 7e743de..88af8f6 100644 --- a/src/gallium/auxiliary/util/u_video.h +++ b/src/gallium/auxiliary/util/u_video.h @@ -60,6 +60,7 @@ u_reduce_video_profile(enum pipe_video_profile profile) return PIPE_VIDEO_FORMAT_VC1; case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE: + case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE: case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN: case PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED: case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH: diff --git a/src/gallium/include/pipe/p_video_enums.h b/src/gallium/include/pipe/p_video_enums.h index aff7842..1e05075 100644 --- a/src/gallium/include/pipe/p_video_enums.h +++ b/src/gallium/include/pipe/p_video_enums.h @@ -54,6 +54,7 @@ enum pipe_video_profile PIPE_VIDEO_PROFILE_VC1_MAIN, PIPE_VIDEO_PROFILE_VC1_ADVANCED, PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE, + PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE, PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN, PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED, PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 3/4] st/vdpau: add h264 constrained baseline profile
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/vdpau/vdpau_private.h | 4 1 file changed, 4 insertions(+) diff --git a/src/gallium/state_trackers/vdpau/vdpau_private.h b/src/gallium/state_trackers/vdpau/vdpau_private.h index bcd4bb1..2780265 100644 --- a/src/gallium/state_trackers/vdpau/vdpau_private.h +++ b/src/gallium/state_trackers/vdpau/vdpau_private.h @@ -229,6 +229,8 @@ ProfileToPipe(VdpDecoderProfile vdpau_profile) return PIPE_VIDEO_PROFILE_MPEG2_MAIN; case VDP_DECODER_PROFILE_H264_BASELINE: return PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE; + case VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE: + return PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE; case VDP_DECODER_PROFILE_H264_MAIN: return PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN; case VDP_DECODER_PROFILE_H264_HIGH: @@ -270,6 +272,8 @@ PipeToProfile(enum pipe_video_profile p_profile) return VDP_DECODER_PROFILE_MPEG2_MAIN; case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE: return VDP_DECODER_PROFILE_H264_BASELINE; + case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE: + return VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE; case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN: return VDP_DECODER_PROFILE_H264_MAIN; case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH: -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 15/18] radeon/vcn: add encode get feedback
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index 0cb8e87..ab68039 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -200,7 +200,20 @@ static void radeon_enc_destroy(struct pipe_video_codec *encoder) static void radeon_enc_get_feedback(struct pipe_video_codec *encoder, void *feedback, unsigned *size) { - /* TODO*/ + struct radeon_encoder *enc = (struct radeon_encoder*)encoder; + struct rvid_buffer *fb = feedback; + + if (size) { + uint32_t *ptr = enc->ws->buffer_map(fb->res->buf, enc->cs, PIPE_TRANSFER_READ_WRITE); + if (ptr[1]) + *size = ptr[6]; + else + *size = 0; + enc->ws->buffer_unmap(fb->res->buf); + } + + si_vid_destroy_buffer(fb); + FREE(fb); } struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 04/18] winsys/amdgpu: add vcn enc cs support
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/winsys/amdgpu/drm/amdgpu_cs.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c index 0b47af9..75e1891 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c @@ -25,6 +25,10 @@ * next paragraph) shall be included in all copies or substantial portions * of the Software. */ +/* + * Authors: + * Marek Olšák + */ #include "amdgpu_cs.h" #include "os/os_time.h" @@ -326,7 +330,8 @@ static bool amdgpu_cs_has_user_fence(struct amdgpu_cs_context *cs) { return cs->ib[IB_MAIN].ip_type != AMDGPU_HW_IP_UVD && cs->ib[IB_MAIN].ip_type != AMDGPU_HW_IP_VCE && - cs->ib[IB_MAIN].ip_type != AMDGPU_HW_IP_VCN_DEC; + cs->ib[IB_MAIN].ip_type != AMDGPU_HW_IP_VCN_DEC && + cs->ib[IB_MAIN].ip_type != AMDGPU_HW_IP_VCN_ENC; } static bool amdgpu_cs_has_chaining(struct amdgpu_cs *cs) @@ -779,6 +784,10 @@ static bool amdgpu_init_cs_context(struct amdgpu_cs_context *cs, cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_VCN_DEC; break; + case RING_VCN_ENC: + cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_VCN_ENC; + break; + default: case RING_GFX: cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_GFX; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 12/18] radeon/vcn: add encode bitstream
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index 51cef7f..053cf0e 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -155,7 +155,19 @@ static void radeon_enc_encode_bitstream(struct pipe_video_codec *encoder, struct pipe_resource *destination, void **fb) { - /* TODO*/ + struct radeon_encoder *enc = (struct radeon_encoder*)encoder; + enc->get_buffer(destination, &enc->bs_handle, NULL); + enc->bs_size = destination->width0; + + *fb = enc->fb = CALLOC_STRUCT(rvid_buffer); + + if (!si_vid_create_buffer(enc->screen, enc->fb, 4096, PIPE_USAGE_STAGING)) { + RVID_ERR("Can't create feedback buffer.\n"); + return; + } + + enc->need_feedback = true; + enc->encode(enc); } static void radeon_enc_end_frame(struct pipe_video_codec *encoder, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 18/18] radeon/video: enable encode support for raven
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_video.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_video.c b/src/gallium/drivers/radeon/radeon_video.c index ea76ca1..4edd0a4 100644 --- a/src/gallium/drivers/radeon/radeon_video.c +++ b/src/gallium/drivers/radeon/radeon_video.c @@ -230,7 +230,8 @@ int si_vid_get_video_param(struct pipe_screen *screen, switch (param) { case PIPE_VIDEO_CAP_SUPPORTED: return codec == PIPE_VIDEO_FORMAT_MPEG4_AVC && - si_vce_is_fw_version_supported(rscreen); + (si_vce_is_fw_version_supported(rscreen) || + rscreen->family == CHIP_RAVEN); case PIPE_VIDEO_CAP_NPOT_TEXTURES: return 1; case PIPE_VIDEO_CAP_MAX_WIDTH: -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 13/18] radeon/vcn: add encode end frame
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index 053cf0e..a21deb1 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -174,7 +174,8 @@ static void radeon_enc_end_frame(struct pipe_video_codec *encoder, struct pipe_video_buffer *source, struct pipe_picture_desc *picture) { - /* TODO*/ + struct radeon_encoder *enc = (struct radeon_encoder*)encoder; + flush(enc); } static void radeon_enc_destroy(struct pipe_video_codec *encoder) -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 11/18] radeon/vcn: add encode begin frame
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 23 ++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index 437c2fc..51cef7f 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -126,7 +126,28 @@ static void radeon_enc_begin_frame(struct pipe_video_codec *encoder, struct pipe_video_buffer *source, struct pipe_picture_desc *picture) { - /* TODO*/ + struct radeon_encoder *enc = (struct radeon_encoder*)encoder; + struct vl_video_buffer *vid_buf = (struct vl_video_buffer *)source; + struct pipe_h264_enc_picture_desc *pic = (struct pipe_h264_enc_picture_desc *)picture; + + radeon_vcn_enc_get_param(enc, pic); + + enc->get_buffer(vid_buf->resources[0], &enc->handle, &enc->luma); + enc->get_buffer(vid_buf->resources[1], NULL, &enc->chroma); + + enc->need_feedback = false; + + if (!enc->stream_handle) { + struct rvid_buffer fb; + enc->stream_handle = si_vid_alloc_stream_handle(); + enc->si = CALLOC_STRUCT(rvid_buffer); + si_vid_create_buffer(enc->screen, enc->si, 128 * 1024, PIPE_USAGE_STAGING); + si_vid_create_buffer(enc->screen, &fb, 4096, PIPE_USAGE_STAGING); + enc->fb = &fb; + enc->begin(enc, pic); + flush(enc); + si_vid_destroy_buffer(&fb); + } } static void radeon_enc_encode_bitstream(struct pipe_video_codec *encoder, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 08/18] radeon/vcn: add ib implementations
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c | 292 ++-- 1 file changed, 268 insertions(+), 24 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c index ffd1155..f75f3d6 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c @@ -65,121 +65,365 @@ static void radeon_enc_add_buffer(struct radeon_encoder *enc, struct pb_buffer * static void radeon_enc_session_info(struct radeon_encoder *enc) { - /* TODO*/ + unsigned int interface_version = ((RENCODE_FW_INTERFACE_MAJOR_VERSION << RENCODE_IF_MAJOR_VERSION_SHIFT) | + (RENCODE_FW_INTERFACE_MINOR_VERSION << RENCODE_IF_MINOR_VERSION_SHIFT)); + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_SESSION_INFO); + RADEON_ENC_CS(interface_version); + RADEON_ENC_READWRITE(enc->si->res->buf, enc->si->res->domains, 0x0); + RADEON_ENC_END(); } static void radeon_enc_task_info(struct radeon_encoder *enc, bool need_feedback) { - /* TODO*/ + enc->enc_pic.task_info.task_id++; + + if (need_feedback) + enc->enc_pic.task_info.allowed_max_num_feedbacks = 1; + else + enc->enc_pic.task_info.allowed_max_num_feedbacks = 0; + + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_TASK_INFO); + enc->p_task_size = &enc->cs->current.buf[enc->cs->current.cdw++]; + RADEON_ENC_CS(enc->enc_pic.task_info.task_id); + RADEON_ENC_CS(enc->enc_pic.task_info.allowed_max_num_feedbacks); + RADEON_ENC_END(); } static void radeon_enc_session_init(struct radeon_encoder *enc) { - /* TODO*/ + enc->enc_pic.session_init.encode_standard = RENCODE_ENCODE_STANDARD_H264; + enc->enc_pic.session_init.aligned_picture_width = align(enc->base.width, 16); + enc->enc_pic.session_init.aligned_picture_height = align(enc->base.height, 16); + enc->enc_pic.session_init.padding_width = enc->enc_pic.session_init.aligned_picture_width - enc->base.width; + enc->enc_pic.session_init.padding_height = enc->enc_pic.session_init.aligned_picture_height - enc->base.height; + enc->enc_pic.session_init.pre_encode_mode = RENCODE_PREENCODE_MODE_NONE; + enc->enc_pic.session_init.pre_encode_chroma_enabled = false; + + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_SESSION_INIT); + RADEON_ENC_CS(enc->enc_pic.session_init.encode_standard); + RADEON_ENC_CS(enc->enc_pic.session_init.aligned_picture_width); + RADEON_ENC_CS(enc->enc_pic.session_init.aligned_picture_height); + RADEON_ENC_CS(enc->enc_pic.session_init.padding_width); + RADEON_ENC_CS(enc->enc_pic.session_init.padding_height); + RADEON_ENC_CS(enc->enc_pic.session_init.pre_encode_mode); + RADEON_ENC_CS(enc->enc_pic.session_init.pre_encode_chroma_enabled); + RADEON_ENC_END(); } static void radeon_enc_layer_control(struct radeon_encoder *enc) { - /* TODO*/ + enc->enc_pic.layer_ctrl.max_num_temporal_layers = 1; + enc->enc_pic.layer_ctrl.num_temporal_layers = 1; + + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_LAYER_CONTROL); + RADEON_ENC_CS(enc->enc_pic.layer_ctrl.max_num_temporal_layers); + RADEON_ENC_CS(enc->enc_pic.layer_ctrl.num_temporal_layers); + RADEON_ENC_END(); } static void radeon_enc_layer_select(struct radeon_encoder *enc) { - /* TODO*/ + enc->enc_pic.layer_sel.temporal_layer_index = 0; + + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_LAYER_SELECT); + RADEON_ENC_CS(enc->enc_pic.layer_sel.temporal_layer_index); + RADEON_ENC_END(); } static void radeon_enc_slice_control(struct radeon_encoder *enc) { - /* TODO*/ + enc->enc_pic.slice_ctrl.slice_control_mode = RENCODE_H264_SLICE_CONTROL_MODE_FIXED_MBS; + enc->enc_pic.slice_ctrl.num_mbs_per_slice = align(enc->base.width, 16) / 16 * align(enc->base.height, 16) / 16; + + RADEON_ENC_BEGIN(RENCODE_H264_IB_PARAM_SLICE_CONTROL); + RADEON_ENC_CS(enc->enc_pic.slice_ctrl.slice_control_mode); + RADEON_ENC_CS(enc->enc_pic.slice_ctrl.num_mbs_per_slice); + RADEON_ENC_END(); } static void radeon_enc_spec_misc(struct radeon_encoder *enc) { - /* TODO*/ + enc->enc_pic.spec_misc.constrained_intra_pred_flag = 0; + enc->enc_pic.spec_misc.cabac_enable = 0; + enc->enc_pic.spec_misc.cabac_init_idc = 0; + enc->enc_pic.spec_misc.half_pel_enabled = 1; + enc->enc_pic.spec_misc.quarter_pel_enabled = 1; + enc->enc_pic.spec_misc.profile_idc = profiles[enc->base.profile - PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE]; + enc->enc_pic.spec_misc.level_idc = enc->base.level; + + RADEON_ENC_BEGIN(RENCODE_H264_IB_PARAM_SPEC_MISC); + RADEON_ENC_CS(enc->enc_pic.spec_misc.constrained_intra_pred_flag); + RADEON_ENC_CS(enc->enc_pic.spe
[Mesa-dev] [PATCH 05/18] vl: add poc type
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/include/pipe/p_video_state.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index abd5d36..1d57165 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -400,6 +400,7 @@ struct pipe_h264_enc_picture_desc unsigned idr_pic_id; unsigned gop_cnt; unsigned pic_order_cnt; + unsigned pic_order_cnt_type; unsigned ref_idx_l0; unsigned ref_idx_l1; unsigned gop_size; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 06/18] st/va: implement poc type
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 7427b98..55ca16e 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -396,6 +396,7 @@ handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vl context->desc.h264enc.gop_size = h264->intra_idr_period * context->gop_coeff; context->desc.h264enc.rate_ctrl.frame_rate_num = h264->time_scale / 2; context->desc.h264enc.rate_ctrl.frame_rate_den = h264->num_units_in_tick; + context->desc.h264enc.pic_order_cnt_type = h264->seq_fields.bits.pic_order_cnt_type; return VA_STATUS_SUCCESS; } -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 17/18] radeonsi: enable vcn encode
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeonsi/si_uvd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeonsi/si_uvd.c b/src/gallium/drivers/radeonsi/si_uvd.c index 2fc5e30..09fdb23 100644 --- a/src/gallium/drivers/radeonsi/si_uvd.c +++ b/src/gallium/drivers/radeonsi/si_uvd.c @@ -30,6 +30,7 @@ #include "radeon/radeon_uvd.h" #include "radeon/radeon_vce.h" #include "radeon/radeon_vcn_dec.h" +#include "radeon/radeon_vcn_enc.h" /** * creates an video buffer with an UVD compatible memory layout @@ -146,7 +147,8 @@ struct pipe_video_codec *si_uvd_create_decoder(struct pipe_context *context, bool vcn = (ctx->b.family == CHIP_RAVEN) ? true : false; if (templ->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) - return si_vce_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); + return (vcn) ? radeon_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer) : + si_vce_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); return (vcn) ? radeon_create_decoder(context, templ) : si_common_uvd_create_decoder(context, templ, si_uvd_set_dtb); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 16/18] radeon/vcn: add create encoder
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 82 - 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index ab68039..0819b6f 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -221,7 +221,87 @@ struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context, struct radeon_winsys* ws, radeon_enc_get_buffer get_buffer) { - /* TODO*/ + struct r600_common_screen *rscreen = (struct r600_common_screen *)context->screen; + struct r600_common_context *rctx = (struct r600_common_context*)context; + struct radeon_encoder *enc; + struct pipe_video_buffer *tmp_buf, templat = {}; + struct radeon_surf *tmp_surf; + unsigned cpb_size; + + enc = CALLOC_STRUCT(radeon_encoder); + + if (!enc) + return NULL; + + enc->alignment = 256; + enc->base = *templ; + enc->base.context = context; + enc->base.destroy = radeon_enc_destroy; + enc->base.begin_frame = radeon_enc_begin_frame; + enc->base.encode_bitstream = radeon_enc_encode_bitstream; + enc->base.end_frame = radeon_enc_end_frame; + enc->base.flush = radeon_enc_flush; + enc->base.get_feedback = radeon_enc_get_feedback; + enc->get_buffer = get_buffer; + enc->bits_in_shifter = 0; + enc->screen = context->screen; + enc->ws = ws; + enc->cs = ws->cs_create(rctx->ctx, RING_VCN_ENC, radeon_enc_cs_flush, enc); + + if (!enc->cs) { + RVID_ERR("Can't get command submission context.\n"); + goto error; + } + + struct rvid_buffer si; + si_vid_create_buffer(enc->screen, &si, 128 * 1024, PIPE_USAGE_STAGING); + enc->si = &si; + + templat.buffer_format = PIPE_FORMAT_NV12; + templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420; + templat.width = enc->base.width; + templat.height = enc->base.height; + templat.interlaced = false; + + if (!(tmp_buf = context->create_video_buffer(context, &templat))) { + RVID_ERR("Can't create video buffer.\n"); + 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 = (rscreen->chip_class < GFX9) ? + align(tmp_surf->u.legacy.level[0].nblk_x * tmp_surf->bpe, 128) * + align(tmp_surf->u.legacy.level[0].nblk_y, 32) : + align(tmp_surf->u.gfx9.surf_pitch * tmp_surf->bpe, 256) * + align(tmp_surf->u.gfx9.surf_height, 32); + + cpb_size = cpb_size * 3 / 2; + cpb_size = cpb_size * enc->cpb_num; + tmp_buf->destroy(tmp_buf); + + if (!si_vid_create_buffer(enc->screen, &enc->cpb, cpb_size, PIPE_USAGE_DEFAULT)) { + RVID_ERR("Can't create CPB buffer.\n"); + goto error; + } + + radeon_enc_1_2_init(enc); + + return &enc->base; + +error: + if (enc->cs) + enc->ws->cs_destroy(enc->cs); + + si_vid_destroy_buffer(&enc->cpb); + + FREE(enc); + return NULL; } -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 09/18] radeon/vcn: add encode header algorithms
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.h | 6 ++ src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c | 121 2 files changed, 127 insertions(+) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.h b/src/gallium/drivers/radeon/radeon_vcn_enc.h index cbdf9c0..651502c 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.h +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.h @@ -396,9 +396,15 @@ struct radeon_encoder { struct radeon_enc_h264_enc_pic enc_pic; unsignedalignment; + unsignedshifter; + unsignedbits_in_shifter; + unsignednum_zeros; + unsignedbyte_index; + unsignedbits_output; uint32_ttotal_task_size; uint32_t* p_task_size; + boolemulation_prevention; boolneed_feedback; }; diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c index f75f3d6..5170c67 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c @@ -49,6 +49,7 @@ RADEON_ENC_CS(cmd) enc->total_task_size += *begin;} static const unsigned profiles[7] = { 66, 77, 88, 100, 110, 122, 244 }; +static const unsigned index_to_shifts[4] = {24, 16, 8, 0}; static void radeon_enc_add_buffer(struct radeon_encoder *enc, struct pb_buffer *buf, enum radeon_bo_usage usage, enum radeon_bo_domain domain, @@ -63,6 +64,126 @@ static void radeon_enc_add_buffer(struct radeon_encoder *enc, struct pb_buffer * RADEON_ENC_CS(addr); } +static void radeon_enc_set_emulation_prevention(struct radeon_encoder *enc, bool set) +{ + if (set != enc->emulation_prevention) { + enc->emulation_prevention = set; + enc->num_zeros = 0; + } +} + +static void radeon_enc_output_one_byte(struct radeon_encoder *enc, unsigned char byte) +{ + if (enc->byte_index == 0) + enc->cs->current.buf[enc->cs->current.cdw] = 0; + enc->cs->current.buf[enc->cs->current.cdw] |= ((unsigned int)(byte) << index_to_shifts[enc->byte_index]); + enc->byte_index++; + + if (enc->byte_index >= 4) { + enc->byte_index = 0; + enc->cs->current.cdw++; + } +} + +static void radeon_enc_emulation_prevention(struct radeon_encoder *enc, unsigned char byte) +{ + if(enc->emulation_prevention) { + if((enc->num_zeros >= 2) && ((byte == 0x00) || (byte == 0x01) || (byte == 0x03))) { +radeon_enc_output_one_byte(enc, 0x03); +enc->bits_output += 8; +enc->num_zeros = 0; +} +enc->num_zeros = (byte == 0 ? (enc->num_zeros + 1) : 0); +} +} + +static void radeon_enc_code_fixed_bits(struct radeon_encoder *enc, unsigned int value, unsigned int num_bits) +{ + unsigned int bits_to_pack = 0; + + while(num_bits > 0) { + unsigned int value_to_pack = value & (0x >> (32 - num_bits)); + bits_to_pack = num_bits > (32 - enc->bits_in_shifter) ? (32 - enc->bits_in_shifter) : num_bits; + + if (bits_to_pack < num_bits) + value_to_pack = value_to_pack >> (num_bits - bits_to_pack); + + enc->shifter |= value_to_pack << (32 - enc->bits_in_shifter - bits_to_pack); + num_bits -= bits_to_pack; + enc->bits_in_shifter += bits_to_pack; + + while(enc->bits_in_shifter >= 8) { + unsigned char output_byte = (unsigned char)(enc->shifter >> 24); + enc->shifter <<= 8; + radeon_enc_emulation_prevention(enc, output_byte); + radeon_enc_output_one_byte(enc, output_byte); + enc->bits_in_shifter -= 8; + enc->bits_output += 8; + } + } +} + +static void radeon_enc_reset(struct radeon_encoder *enc) +{ + enc->emulation_prevention = false; + enc->shifter = 0; + enc->bits_in_shifter = 0; + enc->bits_output = 0; + enc->num_zeros = 0; + enc->byte_index = 0; +} + +static void radeon_enc_byte_align(struct radeon_encoder *enc) +{ + unsigned int num_padding_zeros = (32 - enc->bits_in_shifter) % 8; + + if (num_padding_zeros > 0) + radeon_enc_code_fixed_bits(enc, 0, num_padding_zeros); +} + +static void radeon_enc_flush_headers(struct radeon_encoder *enc) +{ + if (enc->bits_in_shifter != 0) { + unsigned char output_byte = (unsigned char)(enc->shifter >> 24); + radeon_enc_emulation_prevention(enc, outp
[Mesa-dev] [PATCH 01/18] radeon/vcn: add vcn encode interface
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.h | 325 1 file changed, 325 insertions(+) create mode 100644 src/gallium/drivers/radeon/radeon_vcn_enc.h diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.h b/src/gallium/drivers/radeon/radeon_vcn_enc.h new file mode 100644 index 000..a58ff6b --- /dev/null +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.h @@ -0,0 +1,325 @@ +/** + * + * 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. + * + **/ + +#ifndef _RADEON_VCN_ENC_H +#define _RADEON_VCN_ENC_H + +#define RENCODE_FW_INTERFACE_MAJOR_VERSION 1 +#define RENCODE_FW_INTERFACE_MINOR_VERSION 2 + +#define RENCODE_IB_PARAM_SESSION_INFO 0x0001 +#define RENCODE_IB_PARAM_TASK_INFO 0x0002 +#define RENCODE_IB_PARAM_SESSION_INIT 0x0003 +#define RENCODE_IB_PARAM_LAYER_CONTROL 0x0004 +#define RENCODE_IB_PARAM_LAYER_SELECT 0x0005 +#define RENCODE_IB_PARAM_RATE_CONTROL_SESSION_INIT 0x0006 +#define RENCODE_IB_PARAM_RATE_CONTROL_LAYER_INIT 0x0007 +#define RENCODE_IB_PARAM_RATE_CONTROL_PER_PICTURE 0x0008 +#define RENCODE_IB_PARAM_QUALITY_PARAMS0x0009 +#define RENCODE_IB_PARAM_SLICE_HEADER 0x000a +#define RENCODE_IB_PARAM_ENCODE_PARAMS 0x000b +#define RENCODE_IB_PARAM_INTRA_REFRESH 0x000c +#define RENCODE_IB_PARAM_ENCODE_CONTEXT_BUFFER 0x000d +#define RENCODE_IB_PARAM_VIDEO_BITSTREAM_BUFFER0x000e +#define RENCODE_IB_PARAM_FEEDBACK_BUFFER 0x0010 +#define RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU0x0020 + +#define RENCODE_H264_IB_PARAM_SLICE_CONTROL0x0021 +#define RENCODE_H264_IB_PARAM_SPEC_MISC0x0022 +#define RENCODE_H264_IB_PARAM_ENCODE_PARAMS0x0023 +#define RENCODE_H264_IB_PARAM_DEBLOCKING_FILTER0x0024 + +#define RENCODE_IB_OP_INITIALIZE 0x0101 +#define RENCODE_IB_OP_CLOSE_SESSION0x0102 +#define RENCODE_IB_OP_ENCODE 0x0103 +#define RENCODE_IB_OP_INIT_RC 0x0104 +#define RENCODE_IB_OP_INIT_RC_VBV_BUFFER_LEVEL 0x0105 +#define RENCODE_IB_OP_SET_SPEED_ENCODING_MODE 0x0106 +#define RENCODE_IB_OP_SET_BALANCE_ENCODING_MODE0x0107 +#define RENCODE_IB_OP_SET_QUALITY_ENCODING_MODE0x0108 + +#define RENCODE_IF_MAJOR_VERSION_MASK 0x +#define RENCODE_IF_MAJOR_VERSION_SHIFT 16 +#define RENCODE_IF_MINOR_VERSION_MASK 0x +#define RENCODE_IF_MINOR_VERSION_SHIFT 0 + +#define RENCODE_ENCODE_STANDARD_H264 1 + +#define RENCODE_PREENCODE_MODE_NONE0x +#define RENCODE_PREENCODE_MODE_1X 0x0001 +#define RENCODE_PREENCODE_MODE_2X 0x0002 +#define RENCODE_PREENCODE_MODE_4X 0x0004 + +#define RENCODE_H264_SLICE_CONTROL_MODE_FIXED_MBS 0x +#define RENCODE_H264_SLICE_CONTROL_MODE_FIXED_BITS 0x0001 + +#define RENCODE_RATE_CONTROL_METHOD_NONE
[Mesa-dev] [PATCH 03/18] radeon/common: add vcn enc ip info query
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/amd/common/ac_gpu_info.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/amd/common/ac_gpu_info.c b/src/amd/common/ac_gpu_info.c index 2e56012..b0c0a08 100644 --- a/src/amd/common/ac_gpu_info.c +++ b/src/amd/common/ac_gpu_info.c @@ -98,7 +98,7 @@ bool ac_query_gpu_info(int fd, amdgpu_device_handle dev, { struct amdgpu_buffer_size_alignments alignment_info = {}; struct amdgpu_heap_info vram, vram_vis, gtt; - struct drm_amdgpu_info_hw_ip dma = {}, compute = {}, uvd = {}, vce = {}, vcn_dec = {}; + struct drm_amdgpu_info_hw_ip dma = {}, compute = {}, uvd = {}, vce = {}, vcn_dec = {}, vcn_enc = {}; uint32_t vce_version = 0, vce_feature = 0, uvd_version = 0, uvd_feature = 0; int r, i, j; drmDevicePtr devinfo; @@ -174,6 +174,14 @@ bool ac_query_gpu_info(int fd, amdgpu_device_handle dev, } } + if (info->drm_major == 3 && info->drm_minor >= 17) { + r = amdgpu_query_hw_ip_info(dev, AMDGPU_HW_IP_VCN_ENC, 0, &vcn_enc); + if (r) { + fprintf(stderr, "amdgpu: amdgpu_query_hw_ip_info(vcn_dec) failed.\n"); + return false; + } + } + r = amdgpu_query_firmware_version(dev, AMDGPU_INFO_FW_GFX_ME, 0, 0, &info->me_fw_version, &info->me_fw_feature); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 02/18] radeon/winsys: add vcn enc ring type
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_winsys.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h index 2d3f646..a14e6e3 100644 --- a/src/gallium/drivers/radeon/radeon_winsys.h +++ b/src/gallium/drivers/radeon/radeon_winsys.h @@ -78,6 +78,7 @@ enum ring_type { RING_VCE, RING_UVD_ENC, RING_VCN_DEC, +RING_VCN_ENC, RING_LAST, }; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 07/18] radeon/vcn: add common encode part
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- 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 000..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 + +#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; +
[Mesa-dev] [PATCH 14/18] radeon/vcn: add encode destroy
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 16 +++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index a21deb1..0cb8e87 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -180,7 +180,21 @@ static void radeon_enc_end_frame(struct pipe_video_codec *encoder, static void radeon_enc_destroy(struct pipe_video_codec *encoder) { - /* TODO*/ + struct radeon_encoder *enc = (struct radeon_encoder*)encoder; + + if (enc->stream_handle) { + struct rvid_buffer fb; + enc->need_feedback = false; + si_vid_create_buffer(enc->screen, &fb, 512, PIPE_USAGE_STAGING); + enc->fb = &fb; + enc->destroy(enc); + flush(enc); + si_vid_destroy_buffer(&fb); + } + + si_vid_destroy_buffer(&enc->cpb); + enc->ws->cs_destroy(enc->cs); + FREE(enc); } static void radeon_enc_get_feedback(struct pipe_video_codec *encoder, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 10/18] radeon/vcn: add encode header implementations
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c | 234 1 file changed, 234 insertions(+) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c index 5170c67..c6dc420 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c @@ -362,6 +362,233 @@ static void radeon_enc_quality_params(struct radeon_encoder *enc) RADEON_ENC_END(); } +static void radeon_enc_nalu_sps(struct radeon_encoder *enc) +{ + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU); + RADEON_ENC_CS(RENCODE_DIRECT_OUTPUT_NALU_TYPE_SPS); + uint32_t *size_in_bytes = &enc->cs->current.buf[enc->cs->current.cdw++]; + radeon_enc_reset(enc); + radeon_enc_set_emulation_prevention(enc, false); + radeon_enc_code_fixed_bits(enc, 0x0001, 32); + radeon_enc_code_fixed_bits(enc, 0x67, 8); + radeon_enc_byte_align(enc); + radeon_enc_set_emulation_prevention(enc, true); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.spec_misc.profile_idc, 8); + radeon_enc_code_fixed_bits(enc, 0x04, 8); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.spec_misc.level_idc, 8); + radeon_enc_code_ue(enc, 0x0); + + if(enc->enc_pic.spec_misc.profile_idc == 100 || enc->enc_pic.spec_misc.profile_idc == 110 || enc->enc_pic.spec_misc.profile_idc == 122 || + enc->enc_pic.spec_misc.profile_idc == 244 || enc->enc_pic.spec_misc.profile_idc == 44 || enc->enc_pic.spec_misc.profile_idc == 83 || + enc->enc_pic.spec_misc.profile_idc == 86 || enc->enc_pic.spec_misc.profile_idc == 118 || enc->enc_pic.spec_misc.profile_idc == 128 || + enc->enc_pic.spec_misc.profile_idc == 138) { + radeon_enc_code_ue(enc, 0x1); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_fixed_bits(enc, 0x0, 2); + } + + radeon_enc_code_ue(enc, 1); + radeon_enc_code_ue(enc, enc->enc_pic.pic_order_cnt_type); + + if (enc->enc_pic.pic_order_cnt_type == 0) + radeon_enc_code_ue(enc, 1); + + radeon_enc_code_ue(enc, (enc->base.max_references + 1)); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.layer_ctrl.max_num_temporal_layers > 1 ? 0x1 : 0x0, 1); + radeon_enc_code_ue(enc, (enc->enc_pic.session_init.aligned_picture_width / 16 - 1)); + radeon_enc_code_ue(enc, (enc->enc_pic.session_init.aligned_picture_height / 16 - 1)); + bool progressive_only = true; + radeon_enc_code_fixed_bits(enc, progressive_only ? 0x1 : 0x0, 1); + + if (!progressive_only) + radeon_enc_code_fixed_bits(enc, 0x0, 1); + + radeon_enc_code_fixed_bits(enc, 0x1, 1); + + if ((enc->enc_pic.crop_left != 0) || (enc->enc_pic.crop_right != 0) || + (enc->enc_pic.crop_top != 0) || (enc->enc_pic.crop_bottom != 0)) { + radeon_enc_code_fixed_bits(enc, 0x1, 1); + radeon_enc_code_ue(enc, enc->enc_pic.crop_left); + radeon_enc_code_ue(enc, enc->enc_pic.crop_right); + radeon_enc_code_ue(enc, enc->enc_pic.crop_top); + radeon_enc_code_ue(enc, enc->enc_pic.crop_bottom); + } else + radeon_enc_code_fixed_bits(enc, 0x0, 1); + + radeon_enc_code_fixed_bits(enc, 0x1, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x1, 1); + radeon_enc_code_fixed_bits(enc, 0x1, 1); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, 16); + radeon_enc_code_ue(enc, 16); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, (enc->base.max_references + 1)); + radeon_enc_code_fixed_bits(enc, 0x1, 1); + radeon_enc_byte_align(enc); + radeon_enc_flush_headers(enc); + *size_in_bytes = (enc->bits_output + 7) / 8; + RADEON_ENC_END(); +} + +static void radeon_enc_nalu_pps(struct radeon_encoder *enc) +{ + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU); + RADEON_ENC_CS(RENCODE_DIRECT_OUTPUT_NALU_TYPE_PPS); + uint32_t *size_in_bytes = &enc->cs->current.buf[enc->cs->current.cdw++]; + radeon_enc_reset(enc); + radeon_enc_set_emulation_prevention(enc, false); + radeon_enc_code_fixed_bits(enc, 0x0001, 32); + radeon_enc_code_fixed_bits(enc, 0x68, 8); + radeon_enc_byte_align(enc); + radeon_enc_set_emulatio
[Mesa-dev] [PATCH 03/18] radeon/common: add vcn enc ip info query
From: Boyuan Zhang New ip info query is needed for vcn encode Signed-off-by: Boyuan Zhang --- src/amd/common/ac_gpu_info.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/amd/common/ac_gpu_info.c b/src/amd/common/ac_gpu_info.c index 2e56012..1962c96 100644 --- a/src/amd/common/ac_gpu_info.c +++ b/src/amd/common/ac_gpu_info.c @@ -98,7 +98,7 @@ bool ac_query_gpu_info(int fd, amdgpu_device_handle dev, { struct amdgpu_buffer_size_alignments alignment_info = {}; struct amdgpu_heap_info vram, vram_vis, gtt; - struct drm_amdgpu_info_hw_ip dma = {}, compute = {}, uvd = {}, vce = {}, vcn_dec = {}; + struct drm_amdgpu_info_hw_ip dma = {}, compute = {}, uvd = {}, vce = {}, vcn_dec = {}, vcn_enc = {}; uint32_t vce_version = 0, vce_feature = 0, uvd_version = 0, uvd_feature = 0; int r, i, j; drmDevicePtr devinfo; @@ -174,6 +174,14 @@ bool ac_query_gpu_info(int fd, amdgpu_device_handle dev, } } + if (info->drm_major == 3 && info->drm_minor >= 17) { + r = amdgpu_query_hw_ip_info(dev, AMDGPU_HW_IP_VCN_ENC, 0, &vcn_enc); + if (r) { + fprintf(stderr, "amdgpu: amdgpu_query_hw_ip_info(vcn_enc) failed.\n"); + return false; + } + } + r = amdgpu_query_firmware_version(dev, AMDGPU_INFO_FW_GFX_ME, 0, 0, &info->me_fw_version, &info->me_fw_feature); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 02/18] radeon/winsys: add vcn enc ring type
From: Boyuan Zhang New ring type is needed for vcn encode Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_winsys.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h index 2d3f646..a14e6e3 100644 --- a/src/gallium/drivers/radeon/radeon_winsys.h +++ b/src/gallium/drivers/radeon/radeon_winsys.h @@ -78,6 +78,7 @@ enum ring_type { RING_VCE, RING_UVD_ENC, RING_VCN_DEC, +RING_VCN_ENC, RING_LAST, }; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 05/18] vl: add poc type
From: Boyuan Zhang Different from vce encoding, vcn encoding requires driver side to encode bitstream header, such as pps, sps and slice header. pic_order_cnt_type is a required variable when encoding both sps and slice header, therefore we need to add this new variable here, and hold the value passed from st, e.g. vaapi interface Signed-off-by: Boyuan Zhang --- src/gallium/include/pipe/p_video_state.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index abd5d36..1d57165 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -400,6 +400,7 @@ struct pipe_h264_enc_picture_desc unsigned idr_pic_id; unsigned gop_cnt; unsigned pic_order_cnt; + unsigned pic_order_cnt_type; unsigned ref_idx_l0; unsigned ref_idx_l1; unsigned gop_size; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 06/18] st/va: implement poc type
From: Boyuan Zhang pic_order_cnt_type is a required variable when encoding both sps and slice header, therefore we need to get this value from st, e.g. vaapi interface, and then pass it to radeon driver for encoding headers. Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 7427b98..55ca16e 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -396,6 +396,7 @@ handleVAEncSequenceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vl context->desc.h264enc.gop_size = h264->intra_idr_period * context->gop_coeff; context->desc.h264enc.rate_ctrl.frame_rate_num = h264->time_scale / 2; context->desc.h264enc.rate_ctrl.frame_rate_den = h264->num_units_in_tick; + context->desc.h264enc.pic_order_cnt_type = h264->seq_fields.bits.pic_order_cnt_type; return VA_STATUS_SUCCESS; } -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 04/18] winsys/amdgpu: add vcn enc cs support
From: Boyuan Zhang New cs support is needed for vcn encode Signed-off-by: Boyuan Zhang --- src/gallium/winsys/amdgpu/drm/amdgpu_cs.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c index 0b47af9..f82b4fb 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c @@ -326,7 +326,8 @@ static bool amdgpu_cs_has_user_fence(struct amdgpu_cs_context *cs) { return cs->ib[IB_MAIN].ip_type != AMDGPU_HW_IP_UVD && cs->ib[IB_MAIN].ip_type != AMDGPU_HW_IP_VCE && - cs->ib[IB_MAIN].ip_type != AMDGPU_HW_IP_VCN_DEC; + cs->ib[IB_MAIN].ip_type != AMDGPU_HW_IP_VCN_DEC && + cs->ib[IB_MAIN].ip_type != AMDGPU_HW_IP_VCN_ENC; } static bool amdgpu_cs_has_chaining(struct amdgpu_cs *cs) @@ -779,6 +780,10 @@ static bool amdgpu_init_cs_context(struct amdgpu_cs_context *cs, cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_VCN_DEC; break; + case RING_VCN_ENC: + cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_VCN_ENC; + break; + default: case RING_GFX: cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_GFX; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 01/18] radeon/vcn: add vcn encode interface
From: Boyuan Zhang Add a new header file for vcn encode interface Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.h | 325 1 file changed, 325 insertions(+) create mode 100644 src/gallium/drivers/radeon/radeon_vcn_enc.h diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.h b/src/gallium/drivers/radeon/radeon_vcn_enc.h new file mode 100644 index 000..f9fa168 --- /dev/null +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.h @@ -0,0 +1,325 @@ +/** + * + * 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. + * + **/ + +#ifndef _RADEON_VCN_ENC_H +#define _RADEON_VCN_ENC_H + +#define RENCODE_FW_INTERFACE_MAJOR_VERSION 1 +#define RENCODE_FW_INTERFACE_MINOR_VERSION 2 + +#define RENCODE_IB_PARAM_SESSION_INFO 0x0001 +#define RENCODE_IB_PARAM_TASK_INFO 0x0002 +#define RENCODE_IB_PARAM_SESSION_INIT 0x0003 +#define RENCODE_IB_PARAM_LAYER_CONTROL 0x0004 +#define RENCODE_IB_PARAM_LAYER_SELECT 0x0005 +#define RENCODE_IB_PARAM_RATE_CONTROL_SESSION_INIT 0x0006 +#define RENCODE_IB_PARAM_RATE_CONTROL_LAYER_INIT 0x0007 +#define RENCODE_IB_PARAM_RATE_CONTROL_PER_PICTURE 0x0008 +#define RENCODE_IB_PARAM_QUALITY_PARAMS0x0009 +#define RENCODE_IB_PARAM_SLICE_HEADER 0x000a +#define RENCODE_IB_PARAM_ENCODE_PARAMS 0x000b +#define RENCODE_IB_PARAM_INTRA_REFRESH 0x000c +#define RENCODE_IB_PARAM_ENCODE_CONTEXT_BUFFER 0x000d +#define RENCODE_IB_PARAM_VIDEO_BITSTREAM_BUFFER0x000e +#define RENCODE_IB_PARAM_FEEDBACK_BUFFER 0x0010 +#define RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU0x0020 + +#define RENCODE_H264_IB_PARAM_SLICE_CONTROL0x0021 +#define RENCODE_H264_IB_PARAM_SPEC_MISC0x0022 +#define RENCODE_H264_IB_PARAM_ENCODE_PARAMS0x0023 +#define RENCODE_H264_IB_PARAM_DEBLOCKING_FILTER0x0024 + +#define RENCODE_IB_OP_INITIALIZE 0x0101 +#define RENCODE_IB_OP_CLOSE_SESSION0x0102 +#define RENCODE_IB_OP_ENCODE 0x0103 +#define RENCODE_IB_OP_INIT_RC 0x0104 +#define RENCODE_IB_OP_INIT_RC_VBV_BUFFER_LEVEL 0x0105 +#define RENCODE_IB_OP_SET_SPEED_ENCODING_MODE 0x0106 +#define RENCODE_IB_OP_SET_BALANCE_ENCODING_MODE0x0107 +#define RENCODE_IB_OP_SET_QUALITY_ENCODING_MODE0x0108 + +#define RENCODE_IF_MAJOR_VERSION_MASK 0x +#define RENCODE_IF_MAJOR_VERSION_SHIFT 16 +#define RENCODE_IF_MINOR_VERSION_MASK 0x +#define RENCODE_IF_MINOR_VERSION_SHIFT 0 + +#define RENCODE_ENCODE_STANDARD_H264 1 + +#define RENCODE_PREENCODE_MODE_NONE0x +#define RENCODE_PREENCODE_MODE_1X 0x0001 +#define RENCODE_PREENCODE_MODE_2X 0x0002 +#define RENCODE_PREENCODE_MODE_4X 0x0004 + +#define RENCODE_H264_SLICE_CONTROL_MODE_FIXED_MBS 0x +#define RENCODE_H264_SLICE_CONTROL_MODE_FIXED_BITS 0x0001 + +#define RENCODE_RATE_CO
[Mesa-dev] [PATCH 07/18] radeon/vcn: add common encode part
From: Boyuan Zhang Add a skeleton pipe video interface and encode ib interface for video encode on vcn hardware. Add function defines and structures for vcn encode. Update Makefile.sources and meson.build with newly added files. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/Makefile.sources | 3 + src/gallium/drivers/radeon/meson.build | 3 + src/gallium/drivers/radeon/radeon_vcn_enc.c | 164 src/gallium/drivers/radeon/radeon_vcn_enc.h | 82 src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c | 237 5 files changed, 489 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..ebb194c 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_1_2.c \ + radeon_vcn_enc.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/meson.build b/src/gallium/drivers/radeon/meson.build index b4d2832..ed8a49a 100644 --- a/src/gallium/drivers/radeon/meson.build +++ b/src/gallium/drivers/radeon/meson.build @@ -31,6 +31,9 @@ files_libradeon = files( 'r600_texture.c', 'radeon_uvd.c', 'radeon_uvd.h', + 'radeon_vcn_enc_1_2.c', + 'radeon_vcn_enc.c', + 'radeon_vcn_enc.h', 'radeon_vcn_dec.c', 'radeon_vcn_dec.h', 'radeon_vce_40_2_2.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 000..48ff8db --- /dev/null +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -0,0 +1,164 @@ +/** + * + * 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 + +#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)
[Mesa-dev] [PATCH 09/18] radeon/vcn: add encode header algorithms
From: Boyuan Zhang Since bitstream headers, e.g. sps, pps, slice, are encoded in driver side, we need to add corresponding algorithms that required to generate those headers. According to h.264 specs, signed/unsigned interger Exp-Golomb-coded syntax element with left bit first (code_se and code_ue) and unsigned integer using n bits (code_fixed_bits) descriptors function are needed. Therefore, adding those algorithms and related variables and output algorithms here. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.h | 6 ++ src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c | 121 2 files changed, 127 insertions(+) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.h b/src/gallium/drivers/radeon/radeon_vcn_enc.h index fe61419..c04652b 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.h +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.h @@ -396,9 +396,15 @@ struct radeon_encoder { struct radeon_enc_h264_enc_pic enc_pic; unsignedalignment; + unsignedshifter; + unsignedbits_in_shifter; + unsignednum_zeros; + unsignedbyte_index; + unsignedbits_output; uint32_ttotal_task_size; uint32_t* p_task_size; + boolemulation_prevention; boolneed_feedback; }; diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c index f75f3d6..5170c67 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c @@ -49,6 +49,7 @@ RADEON_ENC_CS(cmd) enc->total_task_size += *begin;} static const unsigned profiles[7] = { 66, 77, 88, 100, 110, 122, 244 }; +static const unsigned index_to_shifts[4] = {24, 16, 8, 0}; static void radeon_enc_add_buffer(struct radeon_encoder *enc, struct pb_buffer *buf, enum radeon_bo_usage usage, enum radeon_bo_domain domain, @@ -63,6 +64,126 @@ static void radeon_enc_add_buffer(struct radeon_encoder *enc, struct pb_buffer * RADEON_ENC_CS(addr); } +static void radeon_enc_set_emulation_prevention(struct radeon_encoder *enc, bool set) +{ + if (set != enc->emulation_prevention) { + enc->emulation_prevention = set; + enc->num_zeros = 0; + } +} + +static void radeon_enc_output_one_byte(struct radeon_encoder *enc, unsigned char byte) +{ + if (enc->byte_index == 0) + enc->cs->current.buf[enc->cs->current.cdw] = 0; + enc->cs->current.buf[enc->cs->current.cdw] |= ((unsigned int)(byte) << index_to_shifts[enc->byte_index]); + enc->byte_index++; + + if (enc->byte_index >= 4) { + enc->byte_index = 0; + enc->cs->current.cdw++; + } +} + +static void radeon_enc_emulation_prevention(struct radeon_encoder *enc, unsigned char byte) +{ + if(enc->emulation_prevention) { + if((enc->num_zeros >= 2) && ((byte == 0x00) || (byte == 0x01) || (byte == 0x03))) { +radeon_enc_output_one_byte(enc, 0x03); +enc->bits_output += 8; +enc->num_zeros = 0; +} +enc->num_zeros = (byte == 0 ? (enc->num_zeros + 1) : 0); +} +} + +static void radeon_enc_code_fixed_bits(struct radeon_encoder *enc, unsigned int value, unsigned int num_bits) +{ + unsigned int bits_to_pack = 0; + + while(num_bits > 0) { + unsigned int value_to_pack = value & (0x >> (32 - num_bits)); + bits_to_pack = num_bits > (32 - enc->bits_in_shifter) ? (32 - enc->bits_in_shifter) : num_bits; + + if (bits_to_pack < num_bits) + value_to_pack = value_to_pack >> (num_bits - bits_to_pack); + + enc->shifter |= value_to_pack << (32 - enc->bits_in_shifter - bits_to_pack); + num_bits -= bits_to_pack; + enc->bits_in_shifter += bits_to_pack; + + while(enc->bits_in_shifter >= 8) { + unsigned char output_byte = (unsigned char)(enc->shifter >> 24); + enc->shifter <<= 8; + radeon_enc_emulation_prevention(enc, output_byte); + radeon_enc_output_one_byte(enc, output_byte); + enc->bits_in_shifter -= 8; + enc->bits_output += 8; + } + } +} + +static void radeon_enc_reset(struct radeon_encoder *enc) +{ + enc->emulation_prevention = false; + enc->shifter = 0; + enc->bits_in_shifter = 0; + enc->bits_output = 0; + enc->num_zeros = 0; + enc->byte_index = 0; +} + +static void radeon_enc_byte_align(struct radeon_
[Mesa-dev] [PATCH 13/18] radeon/vcn: add encode end frame
From: Boyuan Zhang Add implementation for end_frame interface for vcn encode. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index f78672a..05e7e83 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -174,7 +174,8 @@ static void radeon_enc_end_frame(struct pipe_video_codec *encoder, struct pipe_video_buffer *source, struct pipe_picture_desc *picture) { - /* TODO*/ + struct radeon_encoder *enc = (struct radeon_encoder*)encoder; + flush(enc); } static void radeon_enc_destroy(struct pipe_video_codec *encoder) -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 10/18] radeon/vcn: add encode header implementations
From: Boyuan Zhang Implement encoding of sps, pps, and silce headers using the newly added h.264 header coding descriptors functions based on h.264 specs. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c | 234 1 file changed, 234 insertions(+) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c index 5170c67..c6dc420 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c @@ -362,6 +362,233 @@ static void radeon_enc_quality_params(struct radeon_encoder *enc) RADEON_ENC_END(); } +static void radeon_enc_nalu_sps(struct radeon_encoder *enc) +{ + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU); + RADEON_ENC_CS(RENCODE_DIRECT_OUTPUT_NALU_TYPE_SPS); + uint32_t *size_in_bytes = &enc->cs->current.buf[enc->cs->current.cdw++]; + radeon_enc_reset(enc); + radeon_enc_set_emulation_prevention(enc, false); + radeon_enc_code_fixed_bits(enc, 0x0001, 32); + radeon_enc_code_fixed_bits(enc, 0x67, 8); + radeon_enc_byte_align(enc); + radeon_enc_set_emulation_prevention(enc, true); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.spec_misc.profile_idc, 8); + radeon_enc_code_fixed_bits(enc, 0x04, 8); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.spec_misc.level_idc, 8); + radeon_enc_code_ue(enc, 0x0); + + if(enc->enc_pic.spec_misc.profile_idc == 100 || enc->enc_pic.spec_misc.profile_idc == 110 || enc->enc_pic.spec_misc.profile_idc == 122 || + enc->enc_pic.spec_misc.profile_idc == 244 || enc->enc_pic.spec_misc.profile_idc == 44 || enc->enc_pic.spec_misc.profile_idc == 83 || + enc->enc_pic.spec_misc.profile_idc == 86 || enc->enc_pic.spec_misc.profile_idc == 118 || enc->enc_pic.spec_misc.profile_idc == 128 || + enc->enc_pic.spec_misc.profile_idc == 138) { + radeon_enc_code_ue(enc, 0x1); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_fixed_bits(enc, 0x0, 2); + } + + radeon_enc_code_ue(enc, 1); + radeon_enc_code_ue(enc, enc->enc_pic.pic_order_cnt_type); + + if (enc->enc_pic.pic_order_cnt_type == 0) + radeon_enc_code_ue(enc, 1); + + radeon_enc_code_ue(enc, (enc->base.max_references + 1)); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.layer_ctrl.max_num_temporal_layers > 1 ? 0x1 : 0x0, 1); + radeon_enc_code_ue(enc, (enc->enc_pic.session_init.aligned_picture_width / 16 - 1)); + radeon_enc_code_ue(enc, (enc->enc_pic.session_init.aligned_picture_height / 16 - 1)); + bool progressive_only = true; + radeon_enc_code_fixed_bits(enc, progressive_only ? 0x1 : 0x0, 1); + + if (!progressive_only) + radeon_enc_code_fixed_bits(enc, 0x0, 1); + + radeon_enc_code_fixed_bits(enc, 0x1, 1); + + if ((enc->enc_pic.crop_left != 0) || (enc->enc_pic.crop_right != 0) || + (enc->enc_pic.crop_top != 0) || (enc->enc_pic.crop_bottom != 0)) { + radeon_enc_code_fixed_bits(enc, 0x1, 1); + radeon_enc_code_ue(enc, enc->enc_pic.crop_left); + radeon_enc_code_ue(enc, enc->enc_pic.crop_right); + radeon_enc_code_ue(enc, enc->enc_pic.crop_top); + radeon_enc_code_ue(enc, enc->enc_pic.crop_bottom); + } else + radeon_enc_code_fixed_bits(enc, 0x0, 1); + + radeon_enc_code_fixed_bits(enc, 0x1, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, 0x1, 1); + radeon_enc_code_fixed_bits(enc, 0x1, 1); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, 16); + radeon_enc_code_ue(enc, 16); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, (enc->base.max_references + 1)); + radeon_enc_code_fixed_bits(enc, 0x1, 1); + radeon_enc_byte_align(enc); + radeon_enc_flush_headers(enc); + *size_in_bytes = (enc->bits_output + 7) / 8; + RADEON_ENC_END(); +} + +static void radeon_enc_nalu_pps(struct radeon_encoder *enc) +{ + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU); + RADEON_ENC_CS(RENCODE_DIRECT_OUTPUT_NALU_TYPE_PPS); + uint32_t *size_in_bytes = &enc->cs->current.buf[enc->cs->current.cdw++]; + radeon_enc_reset(enc); + radeon_enc_set_emulation_prevention(enc, false); + radeon_enc_code_fixed_bits(en
[Mesa-dev] [PATCH 14/18] radeon/vcn: add encode destroy
From: Boyuan Zhang Add implementation for destroy interface for vcn encode. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 16 +++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index 05e7e83..219f870 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -180,7 +180,21 @@ static void radeon_enc_end_frame(struct pipe_video_codec *encoder, static void radeon_enc_destroy(struct pipe_video_codec *encoder) { - /* TODO*/ + struct radeon_encoder *enc = (struct radeon_encoder*)encoder; + + if (enc->stream_handle) { + struct rvid_buffer fb; + enc->need_feedback = false; + si_vid_create_buffer(enc->screen, &fb, 512, PIPE_USAGE_STAGING); + enc->fb = &fb; + enc->destroy(enc); + flush(enc); + si_vid_destroy_buffer(&fb); + } + + si_vid_destroy_buffer(&enc->cpb); + enc->ws->cs_destroy(enc->cs); + FREE(enc); } static void radeon_enc_get_feedback(struct pipe_video_codec *encoder, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 12/18] radeon/vcn: add encode bitstream
From: Boyuan Zhang Add implementation for encode_bitstream interface for vcn encode. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index 0a2c5d8..f78672a 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -155,7 +155,19 @@ static void radeon_enc_encode_bitstream(struct pipe_video_codec *encoder, struct pipe_resource *destination, void **fb) { - /* TODO*/ + struct radeon_encoder *enc = (struct radeon_encoder*)encoder; + enc->get_buffer(destination, &enc->bs_handle, NULL); + enc->bs_size = destination->width0; + + *fb = enc->fb = CALLOC_STRUCT(rvid_buffer); + + if (!si_vid_create_buffer(enc->screen, enc->fb, 4096, PIPE_USAGE_STAGING)) { + RVID_ERR("Can't create feedback buffer.\n"); + return; + } + + enc->need_feedback = true; + enc->encode(enc); } static void radeon_enc_end_frame(struct pipe_video_codec *encoder, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 16/18] radeon/vcn: add create encoder
From: Boyuan Zhang Add implementation for create_encoder interface for vcn encode. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 82 - 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index de485cf..9806a69 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -221,5 +221,85 @@ struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context, struct radeon_winsys* ws, radeon_enc_get_buffer get_buffer) { - /* TODO*/ + struct r600_common_screen *rscreen = (struct r600_common_screen *)context->screen; + struct r600_common_context *rctx = (struct r600_common_context*)context; + struct radeon_encoder *enc; + struct pipe_video_buffer *tmp_buf, templat = {}; + struct radeon_surf *tmp_surf; + unsigned cpb_size; + + enc = CALLOC_STRUCT(radeon_encoder); + + if (!enc) + return NULL; + + enc->alignment = 256; + enc->base = *templ; + enc->base.context = context; + enc->base.destroy = radeon_enc_destroy; + enc->base.begin_frame = radeon_enc_begin_frame; + enc->base.encode_bitstream = radeon_enc_encode_bitstream; + enc->base.end_frame = radeon_enc_end_frame; + enc->base.flush = radeon_enc_flush; + enc->base.get_feedback = radeon_enc_get_feedback; + enc->get_buffer = get_buffer; + enc->bits_in_shifter = 0; + enc->screen = context->screen; + enc->ws = ws; + enc->cs = ws->cs_create(rctx->ctx, RING_VCN_ENC, radeon_enc_cs_flush, enc); + + if (!enc->cs) { + RVID_ERR("Can't get command submission context.\n"); + goto error; + } + + struct rvid_buffer si; + si_vid_create_buffer(enc->screen, &si, 128 * 1024, PIPE_USAGE_STAGING); + enc->si = &si; + + templat.buffer_format = PIPE_FORMAT_NV12; + templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420; + templat.width = enc->base.width; + templat.height = enc->base.height; + templat.interlaced = false; + + if (!(tmp_buf = context->create_video_buffer(context, &templat))) { + RVID_ERR("Can't create video buffer.\n"); + 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 = (rscreen->chip_class < GFX9) ? + align(tmp_surf->u.legacy.level[0].nblk_x * tmp_surf->bpe, 128) * + align(tmp_surf->u.legacy.level[0].nblk_y, 32) : + align(tmp_surf->u.gfx9.surf_pitch * tmp_surf->bpe, 256) * + align(tmp_surf->u.gfx9.surf_height, 32); + + cpb_size = cpb_size * 3 / 2; + cpb_size = cpb_size * enc->cpb_num; + tmp_buf->destroy(tmp_buf); + + if (!si_vid_create_buffer(enc->screen, &enc->cpb, cpb_size, PIPE_USAGE_DEFAULT)) { + RVID_ERR("Can't create CPB buffer.\n"); + goto error; + } + + radeon_enc_1_2_init(enc); + + return &enc->base; + +error: + if (enc->cs) + enc->ws->cs_destroy(enc->cs); + + si_vid_destroy_buffer(&enc->cpb); + + FREE(enc); + return NULL; } -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 17/18] radeonsi: enable vcn encode
From: Boyuan Zhang Enable vcn encode by creating radeon_encoder for vcn. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeonsi/si_uvd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeonsi/si_uvd.c b/src/gallium/drivers/radeonsi/si_uvd.c index 2fc5e30..09fdb23 100644 --- a/src/gallium/drivers/radeonsi/si_uvd.c +++ b/src/gallium/drivers/radeonsi/si_uvd.c @@ -30,6 +30,7 @@ #include "radeon/radeon_uvd.h" #include "radeon/radeon_vce.h" #include "radeon/radeon_vcn_dec.h" +#include "radeon/radeon_vcn_enc.h" /** * creates an video buffer with an UVD compatible memory layout @@ -146,7 +147,8 @@ struct pipe_video_codec *si_uvd_create_decoder(struct pipe_context *context, bool vcn = (ctx->b.family == CHIP_RAVEN) ? true : false; if (templ->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) - return si_vce_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); + return (vcn) ? radeon_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer) : + si_vce_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); return (vcn) ? radeon_create_decoder(context, templ) : si_common_uvd_create_decoder(context, templ, si_uvd_set_dtb); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 15/18] radeon/vcn: add encode get feedback
From: Boyuan Zhang Add implementation for get_feedback interface for vcn encode. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index 219f870..de485cf 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -200,7 +200,20 @@ static void radeon_enc_destroy(struct pipe_video_codec *encoder) static void radeon_enc_get_feedback(struct pipe_video_codec *encoder, void *feedback, unsigned *size) { - /* TODO*/ + struct radeon_encoder *enc = (struct radeon_encoder*)encoder; + struct rvid_buffer *fb = feedback; + + if (size) { + uint32_t *ptr = enc->ws->buffer_map(fb->res->buf, enc->cs, PIPE_TRANSFER_READ_WRITE); + if (ptr[1]) + *size = ptr[6]; + else + *size = 0; + enc->ws->buffer_unmap(fb->res->buf); + } + + si_vid_destroy_buffer(fb); + FREE(fb); } struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 11/18] radeon/vcn: add encode begin frame
From: Boyuan Zhang Add implementation for begin_frame interface for vcn encode. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 23 ++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index 48ff8db..0a2c5d8 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -126,7 +126,28 @@ static void radeon_enc_begin_frame(struct pipe_video_codec *encoder, struct pipe_video_buffer *source, struct pipe_picture_desc *picture) { - /* TODO*/ + struct radeon_encoder *enc = (struct radeon_encoder*)encoder; + struct vl_video_buffer *vid_buf = (struct vl_video_buffer *)source; + struct pipe_h264_enc_picture_desc *pic = (struct pipe_h264_enc_picture_desc *)picture; + + radeon_vcn_enc_get_param(enc, pic); + + enc->get_buffer(vid_buf->resources[0], &enc->handle, &enc->luma); + enc->get_buffer(vid_buf->resources[1], NULL, &enc->chroma); + + enc->need_feedback = false; + + if (!enc->stream_handle) { + struct rvid_buffer fb; + enc->stream_handle = si_vid_alloc_stream_handle(); + enc->si = CALLOC_STRUCT(rvid_buffer); + si_vid_create_buffer(enc->screen, enc->si, 128 * 1024, PIPE_USAGE_STAGING); + si_vid_create_buffer(enc->screen, &fb, 4096, PIPE_USAGE_STAGING); + enc->fb = &fb; + enc->begin(enc, pic); + flush(enc); + si_vid_destroy_buffer(&fb); + } } static void radeon_enc_encode_bitstream(struct pipe_video_codec *encoder, -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 18/18] radeon/video: enable encode support for raven
From: Boyuan Zhang Enable h.264 encode for vcn hardware (raven) Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_video.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_video.c b/src/gallium/drivers/radeon/radeon_video.c index ea76ca1..4edd0a4 100644 --- a/src/gallium/drivers/radeon/radeon_video.c +++ b/src/gallium/drivers/radeon/radeon_video.c @@ -230,7 +230,8 @@ int si_vid_get_video_param(struct pipe_screen *screen, switch (param) { case PIPE_VIDEO_CAP_SUPPORTED: return codec == PIPE_VIDEO_FORMAT_MPEG4_AVC && - si_vce_is_fw_version_supported(rscreen); + (si_vce_is_fw_version_supported(rscreen) || + rscreen->family == CHIP_RAVEN); case PIPE_VIDEO_CAP_NPOT_TEXTURES: return 1; case PIPE_VIDEO_CAP_MAX_WIDTH: -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 08/18] radeon/vcn: add ib implementations
From: Boyuan Zhang Implement required ibs and command buffer submission interfaces for vcn encode Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c | 292 ++-- 1 file changed, 268 insertions(+), 24 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c index ffd1155..f75f3d6 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c @@ -65,121 +65,365 @@ static void radeon_enc_add_buffer(struct radeon_encoder *enc, struct pb_buffer * static void radeon_enc_session_info(struct radeon_encoder *enc) { - /* TODO*/ + unsigned int interface_version = ((RENCODE_FW_INTERFACE_MAJOR_VERSION << RENCODE_IF_MAJOR_VERSION_SHIFT) | + (RENCODE_FW_INTERFACE_MINOR_VERSION << RENCODE_IF_MINOR_VERSION_SHIFT)); + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_SESSION_INFO); + RADEON_ENC_CS(interface_version); + RADEON_ENC_READWRITE(enc->si->res->buf, enc->si->res->domains, 0x0); + RADEON_ENC_END(); } static void radeon_enc_task_info(struct radeon_encoder *enc, bool need_feedback) { - /* TODO*/ + enc->enc_pic.task_info.task_id++; + + if (need_feedback) + enc->enc_pic.task_info.allowed_max_num_feedbacks = 1; + else + enc->enc_pic.task_info.allowed_max_num_feedbacks = 0; + + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_TASK_INFO); + enc->p_task_size = &enc->cs->current.buf[enc->cs->current.cdw++]; + RADEON_ENC_CS(enc->enc_pic.task_info.task_id); + RADEON_ENC_CS(enc->enc_pic.task_info.allowed_max_num_feedbacks); + RADEON_ENC_END(); } static void radeon_enc_session_init(struct radeon_encoder *enc) { - /* TODO*/ + enc->enc_pic.session_init.encode_standard = RENCODE_ENCODE_STANDARD_H264; + enc->enc_pic.session_init.aligned_picture_width = align(enc->base.width, 16); + enc->enc_pic.session_init.aligned_picture_height = align(enc->base.height, 16); + enc->enc_pic.session_init.padding_width = enc->enc_pic.session_init.aligned_picture_width - enc->base.width; + enc->enc_pic.session_init.padding_height = enc->enc_pic.session_init.aligned_picture_height - enc->base.height; + enc->enc_pic.session_init.pre_encode_mode = RENCODE_PREENCODE_MODE_NONE; + enc->enc_pic.session_init.pre_encode_chroma_enabled = false; + + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_SESSION_INIT); + RADEON_ENC_CS(enc->enc_pic.session_init.encode_standard); + RADEON_ENC_CS(enc->enc_pic.session_init.aligned_picture_width); + RADEON_ENC_CS(enc->enc_pic.session_init.aligned_picture_height); + RADEON_ENC_CS(enc->enc_pic.session_init.padding_width); + RADEON_ENC_CS(enc->enc_pic.session_init.padding_height); + RADEON_ENC_CS(enc->enc_pic.session_init.pre_encode_mode); + RADEON_ENC_CS(enc->enc_pic.session_init.pre_encode_chroma_enabled); + RADEON_ENC_END(); } static void radeon_enc_layer_control(struct radeon_encoder *enc) { - /* TODO*/ + enc->enc_pic.layer_ctrl.max_num_temporal_layers = 1; + enc->enc_pic.layer_ctrl.num_temporal_layers = 1; + + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_LAYER_CONTROL); + RADEON_ENC_CS(enc->enc_pic.layer_ctrl.max_num_temporal_layers); + RADEON_ENC_CS(enc->enc_pic.layer_ctrl.num_temporal_layers); + RADEON_ENC_END(); } static void radeon_enc_layer_select(struct radeon_encoder *enc) { - /* TODO*/ + enc->enc_pic.layer_sel.temporal_layer_index = 0; + + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_LAYER_SELECT); + RADEON_ENC_CS(enc->enc_pic.layer_sel.temporal_layer_index); + RADEON_ENC_END(); } static void radeon_enc_slice_control(struct radeon_encoder *enc) { - /* TODO*/ + enc->enc_pic.slice_ctrl.slice_control_mode = RENCODE_H264_SLICE_CONTROL_MODE_FIXED_MBS; + enc->enc_pic.slice_ctrl.num_mbs_per_slice = align(enc->base.width, 16) / 16 * align(enc->base.height, 16) / 16; + + RADEON_ENC_BEGIN(RENCODE_H264_IB_PARAM_SLICE_CONTROL); + RADEON_ENC_CS(enc->enc_pic.slice_ctrl.slice_control_mode); + RADEON_ENC_CS(enc->enc_pic.slice_ctrl.num_mbs_per_slice); + RADEON_ENC_END(); } static void radeon_enc_spec_misc(struct radeon_encoder *enc) { - /* TODO*/ + enc->enc_pic.spec_misc.constrained_intra_pred_flag = 0; + enc->enc_pic.spec_misc.cabac_enable = 0; + enc->enc_pic.spec_misc.cabac_init_idc = 0; + enc->enc_pic.spec_misc.half_pel_enabled = 1; + enc->enc_pic.spec_misc.quarter_pel_enabled = 1; + enc->enc_pic.spec_misc.profile_idc = profiles[enc->base.profile - PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE]; + enc->enc_pic.spec_misc.level_idc = enc->base.level; + + RADEON_ENC_BEGIN(RENCODE_H264_IB_PARAM_SPEC_MISC); + RADEON_ENC_CS(enc->enc_pi
[Mesa-dev] [PATCH] radeon/vce: support all firmwares with major ver 53
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vce.c | 25 + 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vce.c b/src/gallium/drivers/radeon/radeon_vce.c index 70c1e60..b97909f 100644 --- a/src/gallium/drivers/radeon/radeon_vce.c +++ b/src/gallium/drivers/radeon/radeon_vce.c @@ -52,7 +52,7 @@ #define FW_52_0_3 ((52 << 24) | (0 << 16) | (3 << 8)) #define FW_52_4_3 ((52 << 24) | (4 << 16) | (3 << 8)) #define FW_52_8_3 ((52 << 24) | (8 << 16) | (3 << 8)) -#define FW_53_19_4 ((53 << 24) | (19 << 16) | (4 << 8)) +#define FW_53 (53 << 24) /** * flush commands to the hardware @@ -510,13 +510,17 @@ struct pipe_video_codec *rvce_create_encoder(struct pipe_context *context, radeon_vce_52_init(enc); get_pic_param = radeon_vce_52_get_param; break; - case FW_53_19_4: - radeon_vce_52_init(enc); - get_pic_param = radeon_vce_52_get_param; - break; default: - goto error; + switch (rscreen->info.vce_fw_version & (0xff << 24)) { + case FW_53: + radeon_vce_52_init(enc); + get_pic_param = radeon_vce_52_get_param; + break; + + default: + goto error; + } } return &enc->base; @@ -546,10 +550,15 @@ bool rvce_is_fw_version_supported(struct r600_common_screen *rscreen) case FW_52_0_3: case FW_52_4_3: case FW_52_8_3: - case FW_53_19_4: return true; default: - return false; + switch (rscreen->info.vce_fw_version & (0xff << 24)) { + case FW_53: + return true; + + default: + return false; + } } } -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH libdrm] tests/amdgpu: add uvd encode unit tests
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- tests/amdgpu/Makefile.am | 1 + tests/amdgpu/amdgpu_test.c | 6 + tests/amdgpu/amdgpu_test.h | 15 ++ tests/amdgpu/frame.h | 2 +- tests/amdgpu/uvd_enc_tests.c | 500 tests/amdgpu/uve_ib.h| 527 +++ 6 files changed, 1050 insertions(+), 1 deletion(-) create mode 100644 tests/amdgpu/uvd_enc_tests.c create mode 100644 tests/amdgpu/uve_ib.h diff --git a/tests/amdgpu/Makefile.am b/tests/amdgpu/Makefile.am index 9e08578..13b3dc8 100644 --- a/tests/amdgpu/Makefile.am +++ b/tests/amdgpu/Makefile.am @@ -27,4 +27,5 @@ amdgpu_test_SOURCES = \ vce_tests.c \ vce_ib.h \ frame.h \ + uvd_enc_tests.c \ vcn_tests.c diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c index 1d44b09..cd6b826 100644 --- a/tests/amdgpu/amdgpu_test.c +++ b/tests/amdgpu/amdgpu_test.c @@ -91,6 +91,12 @@ static CU_SuiteInfo suites[] = { .pCleanupFunc = suite_vcn_tests_clean, .pTests = vcn_tests, }, + { + .pName = "UVD ENC Tests", + .pInitFunc = suite_uvd_enc_tests_init, + .pCleanupFunc = suite_uvd_enc_tests_clean, + .pTests = uvd_enc_tests, + }, CU_SUITE_INFO_NULL, }; diff --git a/tests/amdgpu/amdgpu_test.h b/tests/amdgpu/amdgpu_test.h index c75a07a..d0b61ba 100644 --- a/tests/amdgpu/amdgpu_test.h +++ b/tests/amdgpu/amdgpu_test.h @@ -120,6 +120,21 @@ int suite_vcn_tests_clean(); extern CU_TestInfo vcn_tests[]; /** + * Initialize uvd enc test suite + */ +int suite_uvd_enc_tests_init(); + +/** + * Deinitialize uvd enc test suite + */ +int suite_uvd_enc_tests_clean(); + +/** + * Tests in uvd enc test suite + */ +extern CU_TestInfo uvd_enc_tests[]; + +/** * Helper functions */ static inline amdgpu_bo_handle gpu_mem_alloc( diff --git a/tests/amdgpu/frame.h b/tests/amdgpu/frame.h index 4c946c2..335401c 100644 --- a/tests/amdgpu/frame.h +++ b/tests/amdgpu/frame.h @@ -24,7 +24,7 @@ #ifndef _frame_h_ #define _frame_h_ -const uint8_t frame[] = { +static const uint8_t frame[] = { 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xaa, 0xaa, 0xaa, diff --git a/tests/amdgpu/uvd_enc_tests.c b/tests/amdgpu/uvd_enc_tests.c new file mode 100644 index 000..6c19f7b --- /dev/null +++ b/tests/amdgpu/uvd_enc_tests.c @@ -0,0 +1,500 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. 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. + * +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "CUnit/Basic.h" + +#include "util_math.h" + +#include "amdgpu_test.h" +#include "amdgpu_drm.h" +#include "amdgpu_internal.h" +#include "frame.h" +#include "uve_ib.h" + +#define IB_SIZE4096 +#define MAX_RESOURCES 16 + +struct amdgpu_uvd_enc_bo { + amdgpu_bo_handle handle; + amdgpu_va_handle va_handle; + uint64_t addr; + uint64_t size; + uint8_t *ptr; +}; + +struct amdgpu_uvd_enc { + unsigned width; + unsigned height; + struct amdgpu_uvd_enc_bo session; + struct amdgpu_uvd_enc_bo vbuf; + struct amdgpu_uvd_enc_bo bs; + struct amdgpu_uvd_enc_bo fb; + struct amdgpu_uvd_enc_bo cpb; +}; + +static amdgpu_device_handle device_handle; +static uint32_t major_version; +static uint32_t minor_version; +static uint32_t family_id; + +static amdgpu_context_handle context_handle; +static amdgpu_bo_handle ib_handle; +static amdgpu_va_handle ib_va_handle; +static uint64_t ib_mc_address; +static uint32_t *ib_cpu; + +static struct amdgpu_uvd_enc enc; +stati
[Mesa-dev] [PATCH] radeon/vcn: determine idr by pic type
From: Boyuan Zhang Vaapi encode interface provides idr frame flags, where omx interface doesn't. Therefore, change to use picture type to determine idr frame, which will work for both interfaces. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index 9806a69..5fc9fc7 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -47,7 +47,7 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_h26 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.is_idr = (pic->picture_type == PIPE_H264_ENC_PICTURE_TYPE_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; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] radeon/vcn: determine idr by pic type
From: Boyuan Zhang Vaapi encode interface provides idr frame flags, where omx interface doesn't. Therefore, change to use picture type to determine idr frame, which will work for both interfaces. Signed-off-by: Boyuan Zhang Reviewed-by: Leo Liu Reviewed-by: Christian König --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index 9806a69..5fc9fc7 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -47,7 +47,7 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_h26 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.is_idr = (pic->picture_type == PIPE_H264_ENC_PICTURE_TYPE_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; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 2/3] st/va: directly use idr pic flag
From: Boyuan Zhang Remove is_idr flag, and use idr_pic_flag provided by vaapi directly Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 55ca16e..8951573 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -432,7 +432,6 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV h264 = buf->data; context->desc.h264enc.frame_num = h264->frame_num; context->desc.h264enc.not_referenced = false; - context->desc.h264enc.is_idr = (h264->pic_fields.bits.idr_pic_flag == 1); context->desc.h264enc.pic_order_cnt = h264->CurrPic.TopFieldOrderCnt; if (context->desc.h264enc.gop_cnt == 0) context->desc.h264enc.i_remain = context->gop_coeff; @@ -451,7 +450,7 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV UINT_TO_PTR(h264->CurrPic.picture_id), UINT_TO_PTR(h264->frame_num)); - if (context->desc.h264enc.is_idr) + if (h264->pic_fields.bits.idr_pic_flag == 1) context->desc.h264enc.picture_type = PIPE_H264_ENC_PICTURE_TYPE_IDR; else context->desc.h264enc.picture_type = PIPE_H264_ENC_PICTURE_TYPE_P; @@ -493,10 +492,9 @@ handleVAEncSliceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaB else if (h264->slice_type == 0) context->desc.h264enc.picture_type = PIPE_H264_ENC_PICTURE_TYPE_P; else if (h264->slice_type == 2) { - if (context->desc.h264enc.is_idr){ - context->desc.h264enc.picture_type = PIPE_H264_ENC_PICTURE_TYPE_IDR; + if (context->desc.h264enc.picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR) context->desc.h264enc.idr_pic_id++; - } else + else context->desc.h264enc.picture_type = PIPE_H264_ENC_PICTURE_TYPE_I; } else context->desc.h264enc.picture_type = PIPE_H264_ENC_PICTURE_TYPE_SKIP; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 3/3] vl: remove is idr flag
From: Boyuan Zhang Remove is_idr flag since not being used anymore. Signed-off-by: Boyuan Zhang --- src/gallium/include/pipe/p_video_state.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 1d57165..5a88e6c 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -407,7 +407,6 @@ struct pipe_h264_enc_picture_desc unsigned ref_pic_mode; bool not_referenced; - bool is_idr; bool enable_vui; struct util_hash_table *frame_idx; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 2/2] radeon/uvd: add and manage render picture list
From: Boyuan Zhang Create a list in decoder to store all render picture buffer pointers that currently being used in reference picture lists. During get message buffer call, check each pointer in render_pic_list[] within given pic->ref[] list, remove pointer that no longer being used by pic->ref[]. Then add current render surface pointer to the render_pic_list[] and assign the associated index to result.curr_idx. As a result, result.curr_idx will have the correct index to represent the current render picture, instead of the previous increamenting values. Signed-off-by: Boyuan Zhang Reviewed-by: Christian König --- src/gallium/drivers/radeon/radeon_uvd.c | 25 +++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c index bf7a2ae..a5392df 100644 --- a/src/gallium/drivers/radeon/radeon_uvd.c +++ b/src/gallium/drivers/radeon/radeon_uvd.c @@ -91,6 +91,8 @@ struct ruvd_decoder { unsignedcmd; unsignedcntl; } reg; + + void*render_pic_list[16]; }; /* flush IB to the hardware */ @@ -670,11 +672,28 @@ static struct ruvd_h265 get_h265_msg(struct ruvd_decoder *dec, struct pipe_video result.row_height_minus1[i] = pic->pps->row_height_minus1[i]; result.num_delta_pocs_ref_rps_idx = pic->NumDeltaPocsOfRefRpsIdx; - result.curr_idx = pic->CurrPicOrderCntVal; result.curr_poc = pic->CurrPicOrderCntVal; + for (i = 0 ; i < 15 ; i++) { + for (j = 0; (pic->ref[j] != NULL) && (j < 15) ; j++) { + if (dec->render_pic_list[i] == pic->ref[j]) + break; + if (j == 15) + dec->render_pic_list[i] = NULL; + else if (pic->ref[j+1] == NULL) + dec->render_pic_list[i] = NULL; + } + } + for (i = 0 ; i < 15 ; i++) { + if (dec->render_pic_list[i] == NULL) { + dec->render_pic_list[i] = target; + result.curr_idx = i; + break; + } + } + vl_video_buffer_set_associated_data(target, &dec->base, - (void *)(uintptr_t)pic->CurrPicOrderCntVal, + (void *)(uintptr_t)result.curr_idx, &ruvd_destroy_associated_data); for (i = 0; i < 16; ++i) { @@ -1401,6 +1420,8 @@ struct pipe_video_codec *si_common_uvd_create_decoder(struct pipe_context *conte goto error; } + for (i = 0; i < 15; i++) + dec->render_pic_list[i] = NULL; dec->fb_size = (info.family == CHIP_TONGA) ? FB_BUFFER_SIZE_TONGA : FB_BUFFER_SIZE; bs_buf_size = width * height * (512 / (16 * 16)); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 1/2] radeon/vcn: add and manage render picture list
From: Boyuan Zhang Create a list in decoder to store all render picture buffer pointers that currently being used in reference picture lists. During get message buffer call, check each pointer in render_pic_list[] within given pic->ref[] list, remove pointer that no longer being used by pic->ref[]. Then add current render surface pointer to the render_pic_list[] and assign the associated index to result.curr_idx. As a result, result.curr_idx will have the correct index to represent the current render picture, instead of the previous increamenting values. Signed-off-by: Boyuan Zhang Reviewed-by: Christian König --- src/gallium/drivers/radeon/radeon_vcn_dec.c | 26 +++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.c b/src/gallium/drivers/radeon/radeon_vcn_dec.c index 2ece4a3..f20f8ae 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeon/radeon_vcn_dec.c @@ -78,6 +78,7 @@ struct radeon_decoder { unsignedbs_size; unsignedcur_buffer; + void*render_pic_list[16]; }; static rvcn_dec_message_avc_t get_h264_msg(struct radeon_decoder *dec, @@ -186,7 +187,7 @@ static rvcn_dec_message_hevc_t get_h265_msg(struct radeon_decoder *dec, struct pipe_h265_picture_desc *pic) { rvcn_dec_message_hevc_t result; - unsigned i; + unsigned i, j; memset(&result, 0, sizeof(result)); result.sps_info_flags = 0; @@ -273,11 +274,28 @@ static rvcn_dec_message_hevc_t get_h265_msg(struct radeon_decoder *dec, result.row_height_minus1[i] = pic->pps->row_height_minus1[i]; result.num_delta_pocs_ref_rps_idx = pic->NumDeltaPocsOfRefRpsIdx; - result.curr_idx = pic->CurrPicOrderCntVal; result.curr_poc = pic->CurrPicOrderCntVal; + for (i = 0 ; i < 15 ; i++) { + for (j = 0; (pic->ref[j] != NULL) && (j < 15) ; j++) { + if (dec->render_pic_list[i] == pic->ref[j]) + break; + if (j == 15) + dec->render_pic_list[i] = NULL; + else if (pic->ref[j+1] == NULL) + dec->render_pic_list[i] = NULL; + } + } + for (i = 0 ; i < 15 ; i++) { + if (dec->render_pic_list[i] == NULL) { + dec->render_pic_list[i] = target; + result.curr_idx = i; + break; + } + } + vl_video_buffer_set_associated_data(target, &dec->base, - (void *)(uintptr_t)pic->CurrPicOrderCntVal, + (void *)(uintptr_t)result.curr_idx, &radeon_dec_destroy_associated_data); for (i = 0; i < 16; ++i) { @@ -1236,6 +1254,8 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, goto error; } + for (i = 0; i < 15; i++) + dec->render_pic_list[i] = NULL; bs_buf_size = width * height * (512 / (16 * 16)); for (i = 0; i < NUM_BUFFERS; ++i) { unsigned msg_fb_it_size = FB_BUFFER_OFFSET + FB_BUFFER_SIZE; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 1/4] radeon/vcn: determine idr by pic type
From: Boyuan Zhang Vaapi encode interface provides idr frame flags, where omx interface doesn't. Therefore, change to use picture type to determine idr frame, which will work for both interfaces. Signed-off-by: Boyuan Zhang Reviewed-by: Leo Liu Reviewed-by: Christian König --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index abc89a7..06579c8 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -47,7 +47,7 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_h26 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.is_idr = (pic->picture_type == PIPE_H264_ENC_PICTURE_TYPE_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; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 2/4] radeon/vce: determine idr by pic type
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vce_52.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vce_52.c b/src/gallium/drivers/radeon/radeon_vce_52.c index 10bf718..a941c47 100644 --- a/src/gallium/drivers/radeon/radeon_vce_52.c +++ b/src/gallium/drivers/radeon/radeon_vce_52.c @@ -162,7 +162,7 @@ void si_vce_52_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_ enc->enc_pic.addrmode_arraymode_disrdo_distwoinstants = 0x0201; else enc->enc_pic.addrmode_arraymode_disrdo_distwoinstants = 0x01000201; - enc->enc_pic.is_idr = pic->is_idr; + enc->enc_pic.is_idr = (pic->picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR); } static void create(struct rvce_encoder *enc) -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 4/4] vl: remove is idr flag
From: Boyuan Zhang Remove is_idr flag since not being used anymore. Signed-off-by: Boyuan Zhang Reviewed-by: Christian König --- src/gallium/include/pipe/p_video_state.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 1d57165..5a88e6c 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -407,7 +407,6 @@ struct pipe_h264_enc_picture_desc unsigned ref_pic_mode; bool not_referenced; - bool is_idr; bool enable_vui; struct util_hash_table *frame_idx; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 3/4] st/va: directly use idr pic flag
From: Boyuan Zhang Remove is_idr flag, and use idr_pic_flag provided by vaapi directly Signed-off-by: Boyuan Zhang Reviewed-by: Christian König --- src/gallium/state_trackers/va/picture.c | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index 55ca16e..8951573 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -432,7 +432,6 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV h264 = buf->data; context->desc.h264enc.frame_num = h264->frame_num; context->desc.h264enc.not_referenced = false; - context->desc.h264enc.is_idr = (h264->pic_fields.bits.idr_pic_flag == 1); context->desc.h264enc.pic_order_cnt = h264->CurrPic.TopFieldOrderCnt; if (context->desc.h264enc.gop_cnt == 0) context->desc.h264enc.i_remain = context->gop_coeff; @@ -451,7 +450,7 @@ handleVAEncPictureParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlV UINT_TO_PTR(h264->CurrPic.picture_id), UINT_TO_PTR(h264->frame_num)); - if (context->desc.h264enc.is_idr) + if (h264->pic_fields.bits.idr_pic_flag == 1) context->desc.h264enc.picture_type = PIPE_H264_ENC_PICTURE_TYPE_IDR; else context->desc.h264enc.picture_type = PIPE_H264_ENC_PICTURE_TYPE_P; @@ -493,10 +492,9 @@ handleVAEncSliceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaB else if (h264->slice_type == 0) context->desc.h264enc.picture_type = PIPE_H264_ENC_PICTURE_TYPE_P; else if (h264->slice_type == 2) { - if (context->desc.h264enc.is_idr){ - context->desc.h264enc.picture_type = PIPE_H264_ENC_PICTURE_TYPE_IDR; + if (context->desc.h264enc.picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR) context->desc.h264enc.idr_pic_id++; - } else + else context->desc.h264enc.picture_type = PIPE_H264_ENC_PICTURE_TYPE_I; } else context->desc.h264enc.picture_type = PIPE_H264_ENC_PICTURE_TYPE_SKIP; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] radeon/vce: add firmware support for version 53.14.3
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vce.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gallium/drivers/radeon/radeon_vce.c b/src/gallium/drivers/radeon/radeon_vce.c index dcd56ea..b7b309c 100644 --- a/src/gallium/drivers/radeon/radeon_vce.c +++ b/src/gallium/drivers/radeon/radeon_vce.c @@ -52,6 +52,7 @@ #define FW_52_0_3 ((52 << 24) | (0 << 16) | (3 << 8)) #define FW_52_4_3 ((52 << 24) | (4 << 16) | (3 << 8)) #define FW_52_8_3 ((52 << 24) | (8 << 16) | (3 << 8)) +#define FW_53_14_3 ((53 << 24) | (14 << 16) | (3 << 8)) /** * flush commands to the hardware @@ -492,6 +493,7 @@ struct pipe_video_codec *rvce_create_encoder(struct pipe_context *context, case FW_52_0_3: case FW_52_4_3: case FW_52_8_3: + case FW_53_14_3: radeon_vce_52_init(enc); get_pic_param = radeon_vce_52_get_param; break; @@ -527,6 +529,7 @@ bool rvce_is_fw_version_supported(struct r600_common_screen *rscreen) case FW_52_0_3: case FW_52_4_3: case FW_52_8_3: + case FW_53_14_3: return true; default: return false; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] radeon/video: only support h264 baseline encode
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_video.c b/src/gallium/drivers/radeon/radeon_video.c index 605a2c7..02e8dcf 100644 --- a/src/gallium/drivers/radeon/radeon_video.c +++ b/src/gallium/drivers/radeon/radeon_video.c @@ -221,7 +221,7 @@ int rvid_get_video_param(struct pipe_screen *screen, if (entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { switch (param) { case PIPE_VIDEO_CAP_SUPPORTED: - return codec == PIPE_VIDEO_FORMAT_MPEG4_AVC && + return profile == PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE && rvce_is_fw_version_supported(rscreen); case PIPE_VIDEO_CAP_NPOT_TEXTURES: return 1; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] radeon/vcn: fix mpeg4 msg buffer settings
From: Boyuan Zhang Previous bit-fields assignments are incorrect and will result certain mpeg4 decode failed due to wrong flag values. This patch fixes these assignments. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_dec.c | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.c b/src/gallium/drivers/radeon/radeon_vcn_dec.c index f83e9e5..4bc922d 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeon/radeon_vcn_dec.c @@ -554,15 +554,15 @@ static rvcn_dec_message_mpeg4_asp_vld_t get_mpeg4_msg(struct radeon_decoder *dec result.vop_time_increment_resolution = pic->vop_time_increment_resolution; - result.short_video_header |= pic->short_video_header << 0; - result.interlaced |= pic->interlaced << 2; -result.load_intra_quant_mat |= 1 << 3; - result.load_nonintra_quant_mat |= 1 << 4; - result.quarter_sample |= pic->quarter_sample << 5; - result.complexity_estimation_disable |= 1 << 6; - result.resync_marker_disable |= pic->resync_marker_disable << 7; - result.newpred_enable |= 0 << 10; // - result.reduced_resolution_vop_enable |= 0 << 11; + result.short_video_header = pic->short_video_header; + result.interlaced = pic->interlaced; + result.load_intra_quant_mat = 1; + result.load_nonintra_quant_mat = 1; + result.quarter_sample = pic->quarter_sample; + result.complexity_estimation_disable = 1; + result.resync_marker_disable = pic->resync_marker_disable; + result.newpred_enable = 0; + result.reduced_resolution_vop_enable = 0; result.quant_type = pic->quant_type; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] radeon/vcn: fix mpeg4 msg buffer settings
From: Boyuan Zhang Previous bit-fields assignments are incorrect and will result certain mpeg4 decode failed due to wrong flag values. This patch fixes these assignments. Signed-off-by: Boyuan Zhang Reviewed-by: Leo Liu --- src/gallium/drivers/radeon/radeon_vcn_dec.c | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.c b/src/gallium/drivers/radeon/radeon_vcn_dec.c index f83e9e5..4bc922d 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeon/radeon_vcn_dec.c @@ -554,15 +554,15 @@ static rvcn_dec_message_mpeg4_asp_vld_t get_mpeg4_msg(struct radeon_decoder *dec result.vop_time_increment_resolution = pic->vop_time_increment_resolution; - result.short_video_header |= pic->short_video_header << 0; - result.interlaced |= pic->interlaced << 2; -result.load_intra_quant_mat |= 1 << 3; - result.load_nonintra_quant_mat |= 1 << 4; - result.quarter_sample |= pic->quarter_sample << 5; - result.complexity_estimation_disable |= 1 << 6; - result.resync_marker_disable |= pic->resync_marker_disable << 7; - result.newpred_enable |= 0 << 10; // - result.reduced_resolution_vop_enable |= 0 << 11; + result.short_video_header = pic->short_video_header; + result.interlaced = pic->interlaced; + result.load_intra_quant_mat = 1; + result.load_nonintra_quant_mat = 1; + result.quarter_sample = pic->quarter_sample; + result.complexity_estimation_disable = 1; + result.resync_marker_disable = pic->resync_marker_disable; + result.newpred_enable = 0; + result.reduced_resolution_vop_enable = 0; result.quant_type = pic->quant_type; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] radeon/vcn: fix mpeg4 msg buffer settings
From: Boyuan Zhang Previous bit-fields assignments are incorrect and will result certain mpeg4 decode failed due to wrong flag values. This patch fixes these assignments. Cc: 18.0 18.1 Signed-off-by: Boyuan Zhang Reviewed-by: Leo Liu --- src/gallium/drivers/radeon/radeon_vcn_dec.c | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.c b/src/gallium/drivers/radeon/radeon_vcn_dec.c index f83e9e5..4bc922d 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeon/radeon_vcn_dec.c @@ -554,15 +554,15 @@ static rvcn_dec_message_mpeg4_asp_vld_t get_mpeg4_msg(struct radeon_decoder *dec result.vop_time_increment_resolution = pic->vop_time_increment_resolution; - result.short_video_header |= pic->short_video_header << 0; - result.interlaced |= pic->interlaced << 2; -result.load_intra_quant_mat |= 1 << 3; - result.load_nonintra_quant_mat |= 1 << 4; - result.quarter_sample |= pic->quarter_sample << 5; - result.complexity_estimation_disable |= 1 << 6; - result.resync_marker_disable |= pic->resync_marker_disable << 7; - result.newpred_enable |= 0 << 10; // - result.reduced_resolution_vop_enable |= 0 << 11; + result.short_video_header = pic->short_video_header; + result.interlaced = pic->interlaced; + result.load_intra_quant_mat = 1; + result.load_nonintra_quant_mat = 1; + result.quarter_sample = pic->quarter_sample; + result.complexity_estimation_disable = 1; + result.resync_marker_disable = pic->resync_marker_disable; + result.newpred_enable = 0; + result.reduced_resolution_vop_enable = 0; result.quant_type = pic->quant_type; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] radeon/vce: add firmware support for ver 53 and up
From: Boyuan Zhang All vce firmwares with major version greater than or equal to 53 are supported Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vce.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vce.c b/src/gallium/drivers/radeon/radeon_vce.c index 427bf01e..17a1125 100644 --- a/src/gallium/drivers/radeon/radeon_vce.c +++ b/src/gallium/drivers/radeon/radeon_vce.c @@ -506,7 +506,7 @@ struct pipe_video_codec *si_vce_create_encoder(struct pipe_context *context, break; default: - if ((sscreen->info.vce_fw_version & (0xff << 24)) == FW_53) { + if ((sscreen->info.vce_fw_version & (0xff << 24)) >= FW_53) { si_vce_52_init(enc); si_get_pic_param = si_vce_52_get_param; } else @@ -542,7 +542,7 @@ bool si_vce_is_fw_version_supported(struct si_screen *sscreen) case FW_52_8_3: return true; default: - if ((sscreen->info.vce_fw_version & (0xff << 24)) == FW_53) + if ((sscreen->info.vce_fw_version & (0xff << 24)) >= FW_53) return true; else return false; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 03/13] radeon/winsys: add vcn jpeg ring type
From: Boyuan Zhang Add a new ring type for vcn jpeg. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_winsys.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h index 0a56539..6290eef 100644 --- a/src/gallium/drivers/radeon/radeon_winsys.h +++ b/src/gallium/drivers/radeon/radeon_winsys.h @@ -78,6 +78,7 @@ enum ring_type { RING_UVD_ENC, RING_VCN_DEC, RING_VCN_ENC, +RING_VCN_JPEG, RING_LAST, }; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 01/13] radeon/vcn: move radeon decoder define to header file
From: Boyuan Zhang Move radeon_decoder definition from "radeon_vcn_dec.c" to "radeon_vcn_dec.h", so that it can be included by other files later. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_dec.c | 28 src/gallium/drivers/radeon/radeon_vcn_dec.h | 29 + 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.c b/src/gallium/drivers/radeon/radeon_vcn_dec.c index 4bc922d..8bea704 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeon/radeon_vcn_dec.c @@ -49,38 +49,10 @@ #define RDECODE_GPCOM_VCPU_DATA1 0x20714 #define RDECODE_ENGINE_CNTL0x20718 -#define NUM_BUFFERS4 #define NUM_MPEG2_REFS 6 #define NUM_H264_REFS 17 #define NUM_VC1_REFS 5 -struct radeon_decoder { - struct pipe_video_codec base; - - unsignedstream_handle; - unsignedstream_type; - unsignedframe_number; - - struct pipe_screen *screen; - struct radeon_winsys*ws; - struct radeon_winsys_cs *cs; - - void*msg; - uint32_t*fb; - uint8_t *it; - void*bs_ptr; - - struct rvid_buffer msg_fb_it_buffers[NUM_BUFFERS]; - struct rvid_buffer bs_buffers[NUM_BUFFERS]; - struct rvid_buffer dpb; - struct rvid_buffer ctx; - struct rvid_buffer sessionctx; - - unsignedbs_size; - unsignedcur_buffer; - void*render_pic_list[16]; -}; - static rvcn_dec_message_avc_t get_h264_msg(struct radeon_decoder *dec, struct pipe_h264_picture_desc *pic) { diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.h b/src/gallium/drivers/radeon/radeon_vcn_dec.h index accffef..4a90687 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec.h +++ b/src/gallium/drivers/radeon/radeon_vcn_dec.h @@ -105,6 +105,8 @@ #define RDECODE_SPS_INFO_H264_EXTENSION_SUPPORT_FLAG_SHIFT 7 +#define NUM_BUFFERS4 + typedef struct rvcn_dec_message_index_s { unsigned intmessage_id; unsigned intoffset; @@ -500,6 +502,33 @@ typedef struct rvcn_dec_feedback_profiling_s { unsigned intdmaHwCrc32Value2; } rvcn_dec_feedback_profiling_t; +struct radeon_decoder { + struct pipe_video_codec base; + + unsignedstream_handle; + unsignedstream_type; + unsignedframe_number; + + struct pipe_screen *screen; + struct radeon_winsys*ws; + struct radeon_winsys_cs *cs; + + void*msg; + uint32_t*fb; + uint8_t *it; + void*bs_ptr; + + struct rvid_buffer msg_fb_it_buffers[NUM_BUFFERS]; + struct rvid_buffer bs_buffers[NUM_BUFFERS]; + struct rvid_buffer dpb; + struct rvid_buffer ctx; + struct rvid_buffer sessionctx; + + unsignedbs_size; + unsignedcur_buffer; + void*render_pic_list[16]; +}; + struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, const struct pipe_video_codec *templat); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 02/13] radeon/vcn: add vcn jpeg decode interface
From: Boyuan Zhang Add VCN Jpeg decode interfaces and register defines. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_dec.h | 91 + 1 file changed, 91 insertions(+) diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.h b/src/gallium/drivers/radeon/radeon_vcn_dec.h index 4a90687..399d75c 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec.h +++ b/src/gallium/drivers/radeon/radeon_vcn_dec.h @@ -43,6 +43,15 @@ #define RDECODE_PKT2() (RDECODE_PKT_TYPE_S(2)) +#define RDECODE_PKT_REG_J(x) ((unsigned)(x) & 0x3) +#define RDECODE_PKT_RES_J(x) (((unsigned)(x) & 0x3F) << 18) +#define RDECODE_PKT_COND_J(x) (((unsigned)(x) & 0xF) << 24) +#define RDECODE_PKT_TYPE_J(x) (((unsigned)(x) & 0xF) << 28) +#define RDECODE_PKTJ(reg, cond, type) (RDECODE_PKT_REG_J(reg) | \ + RDECODE_PKT_RES_J(0) | \ + RDECODE_PKT_COND_J(cond) | \ + RDECODE_PKT_TYPE_J(type)) + #define RDECODE_CMD_MSG_BUFFER 0x #define RDECODE_CMD_DPB_BUFFER 0x0001 #define RDECODE_CMD_DECODING_TARGET_BUFFER 0x0002 @@ -61,6 +70,7 @@ #define RDECODE_CODEC_MPEG2_VLD0x0003 #define RDECODE_CODEC_MPEG40x0004 #define RDECODE_CODEC_H264_PERF0x0007 +#define RDECODE_CODEC_JPEG 0x0008 #define RDECODE_CODEC_H265 0x0010 #define RDECODE_ARRAY_MODE_LINEAR 0x @@ -107,6 +117,77 @@ #define NUM_BUFFERS4 +#define mmUVD_JPEG_CNTL0x0200 +#define mmUVD_JPEG_CNTL_BASE_IDX 1 +#define mmUVD_JPEG_RB_BASE 0x0201 +#define mmUVD_JPEG_RB_BASE_BASE_IDX1 +#define mmUVD_JPEG_RB_WPTR 0x0202 +#define mmUVD_JPEG_RB_WPTR_BASE_IDX1 +#define mmUVD_JPEG_RB_RPTR 0x0203 +#define mmUVD_JPEG_RB_RPTR_BASE_IDX1 +#define mmUVD_JPEG_RB_SIZE 0x0204 +#define mmUVD_JPEG_RB_SIZE_BASE_IDX1 +#define mmUVD_JPEG_TIER_CNTL2 0x021a +#define mmUVD_JPEG_TIER_CNTL2_BASE_IDX 1 +#define mmUVD_JPEG_UV_TILING_CTRL 0x021c +#define mmUVD_JPEG_UV_TILING_CTRL_BASE_IDX 1 +#define mmUVD_JPEG_TILING_CTRL 0x021e +#define mmUVD_JPEG_TILING_CTRL_BASE_IDX1 +#define mmUVD_JPEG_OUTBUF_RPTR 0x0220 +#define mmUVD_JPEG_OUTBUF_RPTR_BASE_IDX1 +#define mmUVD_JPEG_OUTBUF_WPTR 0x0221 +#define mmUVD_JPEG_OUTBUF_WPTR_BASE_IDX1 +#define mmUVD_JPEG_PITCH 0x0222 +#define mmUVD_JPEG_PITCH_BASE_IDX 1 +#define mmUVD_JPEG_INT_EN 0x0229 +#define mmUVD_JPEG_INT_EN_BASE_IDX 1 +#define mmUVD_JPEG_UV_PITCH0x022b +#define mmUVD_JPEG_UV_PITCH_BASE_IDX 1 +#define mmUVD_JPEG_INDEX 0x023e +#define mmUVD_JPEG_INDEX_BASE_IDX 1 +#define mmUVD_JPEG_DATA0x023f +#define mmUVD_JPEG_DATA_BASE_IDX 1 +#define mmUVD_LMI_JPEG_WRITE_64BIT_BAR_HIGH0x0438 +#define mmUVD_LMI_JPEG_WRITE_64BIT_BAR_HIGH_BASE_IDX 1 +#define mmUVD_LMI_JPEG_WRITE_64BIT_BAR_LOW 0x0439 +#define mmUVD_LMI_JPEG_WRITE_64BIT_BAR_LOW_BASE_IDX1 +#define mmUVD_LMI_JPEG_READ_64BIT_BAR_HIGH 0x045a +#define mmUVD_LMI_JPEG_READ_64BIT_BAR_HIGH_BASE_IDX1 +#define mmUVD_LMI_JPEG_READ_64BIT_BAR_LOW 0x045b +#define mmUVD_LMI_JPEG_READ_64BIT_BAR_LOW_BASE_IDX 1 +#define mmUVD_CTX_INDEX0x0528 +#define mmUVD_CTX_INDEX_BASE_IDX 1 +#define mmUVD_CTX_DATA 0x0529 +#define mmUVD_CTX_DATA_BASE_IDX1 +#define mmUVD_SOFT_RESET 0x05a0 +#define mmUVD_SOFT_RESET_BASE_IDX 1 + +#define UVD_BASE_INST0_SEG00x7800 +#define UVD_BASE_INST0_SEG10x7E00 +#define UVD_BASE_INST0_SEG20 +#define UVD_BASE_INST0_SEG30 +#define UVD_BASE_INST0_SEG40 + +#define SOC15_REG_ADDR(reg)(UVD_BASE_INST0_SEG1 + reg) + +#define COND0 0 +#define COND1 1 +#define COND2 2 +#define COND3 3 +#define COND4 4 +#de
[Mesa-dev] [PATCH 04/13] radeon/vcn: create cs based on ring type
From: Boyuan Zhang Add RING_VCN_JPEG for VCN Jpeg decode, and keep RING_VCN_DEC for other codecs. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_dec.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.c b/src/gallium/drivers/radeon/radeon_vcn_dec.c index 8bea704..e6c1b67 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeon/radeon_vcn_dec.c @@ -1173,7 +1173,7 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, struct radeon_winsys* ws = ((struct r600_common_context *)context)->ws; struct r600_common_context *rctx = (struct r600_common_context*)context; unsigned width = templ->width, height = templ->height; - unsigned dpb_size, bs_buf_size, stream_type = 0; + unsigned dpb_size, bs_buf_size, stream_type = 0, ring = RING_VCN_DEC; struct radeon_decoder *dec; int r, i; @@ -1199,6 +1199,10 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, case PIPE_VIDEO_FORMAT_HEVC: stream_type = RDECODE_CODEC_H265; break; + case PIPE_VIDEO_FORMAT_JPEG: + stream_type = RDECODE_CODEC_JPEG; + ring = RING_VCN_JPEG; + break; default: assert(0); break; @@ -1225,7 +1229,7 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, dec->stream_handle = si_vid_alloc_stream_handle(); dec->screen = context->screen; dec->ws = ws; - dec->cs = ws->cs_create(rctx->ctx, RING_VCN_DEC, NULL, NULL); + dec->cs = ws->cs_create(rctx->ctx, ring, NULL, NULL); if (!dec->cs) { RVID_ERR("Can't get command submission context.\n"); goto error; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 05/13] radeon/vcn: separate send cmd call from end frame
From: Boyuan Zhang Use function pointer for sending cmd in end_frame call. By doing this, we can assign different cmd sending logics for Jpeg decode later. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_dec.c | 30 - src/gallium/drivers/radeon/radeon_vcn_dec.h | 7 +++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.c b/src/gallium/drivers/radeon/radeon_vcn_dec.c index e6c1b67..30a8952 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeon/radeon_vcn_dec.c @@ -,24 +,17 @@ static void radeon_dec_decode_bitstream(struct pipe_video_codec *decoder, } /** - * end decoding of the current frame + * send cmd for vcn dec */ -static void radeon_dec_end_frame(struct pipe_video_codec *decoder, +void send_cmd_dec(struct radeon_decoder *dec, struct pipe_video_buffer *target, struct pipe_picture_desc *picture) { - struct radeon_decoder *dec = (struct radeon_decoder*)decoder; struct pb_buffer *dt; struct rvid_buffer *msg_fb_it_buf, *bs_buf; - assert(decoder); - - if (!dec->bs_ptr) - return; - msg_fb_it_buf = &dec->msg_fb_it_buffers[dec->cur_buffer]; bs_buf = &dec->bs_buffers[dec->cur_buffer]; - memset(dec->bs_ptr, 0, align(dec->bs_size, 128) - dec->bs_size); dec->ws->buffer_unmap(bs_buf->res->buf); @@ -1152,6 +1145,23 @@ static void radeon_dec_end_frame(struct pipe_video_codec *decoder, send_cmd(dec, RDECODE_CMD_IT_SCALING_TABLE_BUFFER, msg_fb_it_buf->res->buf, FB_BUFFER_OFFSET + FB_BUFFER_SIZE, RADEON_USAGE_READ, RADEON_DOMAIN_GTT); set_reg(dec, RDECODE_ENGINE_CNTL, 1); +} + +/** + * end decoding of the current frame + */ +static void radeon_dec_end_frame(struct pipe_video_codec *decoder, + struct pipe_video_buffer *target, + struct pipe_picture_desc *picture) +{ + struct radeon_decoder *dec = (struct radeon_decoder*)decoder; + + assert(decoder); + + if (!dec->bs_ptr) + return; + + dec->send_cmd(dec, target, picture); flush(dec, PIPE_FLUSH_ASYNC); next_buffer(dec); @@ -1294,6 +1304,8 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, next_buffer(dec); + dec->send_cmd = send_cmd_dec; + return &dec->base; error: diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.h b/src/gallium/drivers/radeon/radeon_vcn_dec.h index 399d75c..05e4847 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec.h +++ b/src/gallium/drivers/radeon/radeon_vcn_dec.h @@ -618,8 +618,15 @@ struct radeon_decoder { void*render_pic_list[16]; struct jpeg_params jpg; + void (*send_cmd)(struct radeon_decoder *dec, +struct pipe_video_buffer *target, +struct pipe_picture_desc *picture); }; +void send_cmd_dec(struct radeon_decoder *dec, + struct pipe_video_buffer *target, + struct pipe_picture_desc *picture); + struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, const struct pipe_video_codec *templat); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 11/13] amd/common: add vcn jpeg ip info query
From: Boyuan Zhang Signed-off-by: Boyuan Zhang --- src/amd/common/ac_gpu_info.c | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/amd/common/ac_gpu_info.c b/src/amd/common/ac_gpu_info.c index 73fc362..a1db3b9 100644 --- a/src/amd/common/ac_gpu_info.c +++ b/src/amd/common/ac_gpu_info.c @@ -99,7 +99,7 @@ bool ac_query_gpu_info(int fd, amdgpu_device_handle dev, struct amdgpu_buffer_size_alignments alignment_info = {}; struct amdgpu_heap_info vram, vram_vis, gtt; struct drm_amdgpu_info_hw_ip dma = {}, compute = {}, uvd = {}; - struct drm_amdgpu_info_hw_ip uvd_enc = {}, vce = {}, vcn_dec = {}; + struct drm_amdgpu_info_hw_ip uvd_enc = {}, vce = {}, vcn_dec = {}, vcn_jpeg = {}; struct drm_amdgpu_info_hw_ip vcn_enc = {}, gfx = {}; struct amdgpu_gds_resource_info gds = {}; uint32_t vce_version = 0, vce_feature = 0, uvd_version = 0, uvd_feature = 0; @@ -199,6 +199,14 @@ bool ac_query_gpu_info(int fd, amdgpu_device_handle dev, } } + if (info->drm_major == 3 && info->drm_minor >= 17) { + r = amdgpu_query_hw_ip_info(dev, AMDGPU_HW_IP_VCN_JPEG, 0, &vcn_jpeg); + if (r) { + fprintf(stderr, "amdgpu: amdgpu_query_hw_ip_info(vcn_jpeg) failed.\n"); + return false; + } + } + r = amdgpu_query_firmware_version(dev, AMDGPU_INFO_FW_GFX_ME, 0, 0, &info->me_fw_version, &info->me_fw_feature); @@ -301,7 +309,8 @@ bool ac_query_gpu_info(int fd, amdgpu_device_handle dev, info->max_se = amdinfo->num_shader_engines; info->max_sh_per_se = amdinfo->num_shader_arrays_per_engine; info->has_hw_decode = - (uvd.available_rings != 0) || (vcn_dec.available_rings != 0); + (uvd.available_rings != 0) || (vcn_dec.available_rings != 0) || + (vcn_jpeg.available_rings != 0); info->uvd_fw_version = uvd.available_rings ? uvd_version : 0; info->vce_fw_version = @@ -368,6 +377,7 @@ bool ac_query_gpu_info(int fd, amdgpu_device_handle dev, ib_align = MAX2(ib_align, vce.ib_start_alignment); ib_align = MAX2(ib_align, vcn_dec.ib_start_alignment); ib_align = MAX2(ib_align, vcn_enc.ib_start_alignment); + ib_align = MAX2(ib_align, vcn_jpeg.ib_start_alignment); assert(ib_align); info->ib_start_alignment = ib_align; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 07/13] st/va: get mjpeg slice header
From: Boyuan Zhang Move the previous get_mjpeg_slice_header function from radeon/vcn to st/va. Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c | 3 + src/gallium/state_trackers/va/picture_mjpeg.c | 132 ++ src/gallium/state_trackers/va/va_private.h| 3 + 3 files changed, 138 insertions(+) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index f2e9ba8..d326ed4 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -293,6 +293,9 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) sizes[num_buffers++] = context->mpeg4.start_code_size; break; case PIPE_VIDEO_FORMAT_JPEG: + vlVaGetJpegSliceHeader(context); + buffers[num_buffers] = (void *)context->mjpeg.slice_header; + sizes[num_buffers++] = context->mjpeg.slice_header_size; break; default: break; diff --git a/src/gallium/state_trackers/va/picture_mjpeg.c b/src/gallium/state_trackers/va/picture_mjpeg.c index 396b743..f1292ea 100644 --- a/src/gallium/state_trackers/va/picture_mjpeg.c +++ b/src/gallium/state_trackers/va/picture_mjpeg.c @@ -114,3 +114,135 @@ void vlVaHandleSliceParameterBufferMJPEG(vlVaContext *context, vlVaBuffer *buf) context->desc.mjpeg.slice_parameter.restart_interval = mjpeg->restart_interval; context->desc.mjpeg.slice_parameter.num_mcus = mjpeg->num_mcus; } + +void vlVaGetJpegSliceHeader(vlVaContext *context) +{ + int size = 0, saved_size, len_pos, i; + uint16_t *bs; + uint8_t *p = context->mjpeg.slice_header; + + /* SOI */ + p[size++] = 0xff; + p[size++] = 0xd8; + + /* DQT */ + p[size++] = 0xff; + p[size++] = 0xdb; + + len_pos = size++; + size++; + + for (i = 0; i < 4; ++i) { + if (context->desc.mjpeg.quantization_table.load_quantiser_table[i] == 0) + continue; + + p[size++] = i; + memcpy((p + size), &context->desc.mjpeg.quantization_table.quantiser_table[i], 64); + size += 64; + } + + bs = (uint16_t*)&p[len_pos]; + *bs = util_bswap16(size - 4); + + saved_size = size; + + /* DHT */ + p[size++] = 0xff; + p[size++] = 0xc4; + + len_pos = size++; + size++; + + for (i = 0; i < 2; ++i) { + if (context->desc.mjpeg.huffman_table.load_huffman_table[i] == 0) + continue; + + p[size++] = 0x00 | i; + memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].num_dc_codes, 16); + size += 16; + memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].dc_values, 12); + size += 12; + } + + for (i = 0; i < 2; ++i) { + if (context->desc.mjpeg.huffman_table.load_huffman_table[i] == 0) + continue; + + p[size++] = 0x10 | i; + memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].num_ac_codes, 16); + size += 16; + memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].ac_values, 162); + size += 162; + } + + bs = (uint16_t*)&p[len_pos]; + *bs = util_bswap16(size - saved_size - 2); + + saved_size = size; + + /* DRI */ + if (context->desc.mjpeg.slice_parameter.restart_interval) { + p[size++] = 0xff; + p[size++] = 0xdd; + p[size++] = 0x00; + p[size++] = 0x04; + bs = (uint16_t*)&p[size++]; + *bs = util_bswap16(context->desc.mjpeg.slice_parameter.restart_interval); + saved_size = ++size; + } + + /* SOF */ + p[size++] = 0xff; + p[size++] = 0xc0; + + len_pos = size++; + size++; + + p[size++] = 0x08; + + bs = (uint16_t*)&p[size++]; + *bs = util_bswap16(context->desc.mjpeg.picture_parameter.picture_height); + size++; + + bs = (uint16_t*)&p[size++]; + *bs = util_bswap16(context->desc.mjpeg.picture_parameter.picture_width); + size++; + + p[size++] = context->desc.mjpeg.picture_parameter.num_components; + + for (i = 0; i < context->desc.mjpeg.picture_parameter.num_components; ++i) { + p[size++] = context->desc.mjpeg.picture_parameter.components[i].component_id; + p[size++] = context->desc.mjpeg.picture_parameter.components[i].h_sampling_factor << 4 | + context->desc.mjpeg.picture_parameter.components[i].v_sampling_factor; + p[size++] = context->desc.mjpeg.picture_parameter.components[i].quantiser_table_selector; + } + + bs = (uint16_t*)&p[len_pos]; + *bs = util_bswap16(size - saved_size - 2); + + saved_size = size; + + /* SOS */ + p[size++] = 0xff; + p[size++] = 0xda; + + len_pos = size++; + size++; + + p[size++] = context->desc.mjpeg.slice_parameter.num_components; + + for (i = 0; i < context->desc.mjpeg.slice_parameter.num_components; ++i) { + p[size++] = context->desc.mjpeg.slice_parameter.components[i].component_selector; + p[size++] = context->desc.mjpeg.slice_parameter.components[i].dc_table_selector << 4 | + context->desc.mjpeg.slice_parameter.components[i].ac_table_selector; + } + + p
[Mesa-dev] [PATCH 12/13] winsys/amdgpu: add vcn jpeg cs support
From: Boyuan Zhang Add vcn jpeg cs support, align cs by no-op. Signed-off-by: Boyuan Zhang --- src/gallium/winsys/amdgpu/drm/amdgpu_cs.c | 12 1 file changed, 12 insertions(+) diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c index a3feeb9..5092f49 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c @@ -840,6 +840,10 @@ static bool amdgpu_init_cs_context(struct amdgpu_cs_context *cs, cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_VCN_ENC; break; + case RING_VCN_JPEG: + cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_VCN_JPEG; + break; + default: case RING_GFX: cs->ib[IB_MAIN].ip_type = AMDGPU_HW_IP_GFX; @@ -1545,6 +1549,14 @@ static int amdgpu_cs_flush(struct radeon_winsys_cs *rcs, while (rcs->current.cdw & 15) radeon_emit(rcs, 0x8000); /* type2 nop packet */ break; + case RING_VCN_JPEG: + if (rcs->current.cdw % 2) + assert(0); + while (rcs->current.cdw & 15) { + radeon_emit(rcs, 0x6000); /* nop packet */ + radeon_emit(rcs, 0x); + } + break; case RING_VCN_DEC: while (rcs->current.cdw & 15) radeon_emit(rcs, 0x81ff); /* nop packet */ -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 13/13] radeonsi: enable vcn jpeg decode for raven
From: Boyuan Zhang Enable vcn jpeg decode for raven. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeonsi/si_get.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gallium/drivers/radeonsi/si_get.c b/src/gallium/drivers/radeonsi/si_get.c index fc2be33..de587bb 100644 --- a/src/gallium/drivers/radeonsi/si_get.c +++ b/src/gallium/drivers/radeonsi/si_get.c @@ -640,6 +640,8 @@ static int si_get_video_param(struct pipe_screen *screen, return profile == PIPE_VIDEO_PROFILE_HEVC_MAIN; return false; case PIPE_VIDEO_FORMAT_JPEG: + if (sscreen->info.family == CHIP_RAVEN) + return true; if (sscreen->info.family < CHIP_CARRIZO || sscreen->info.family >= CHIP_VEGA10) return false; if (!(sscreen->info.drm_major == 3 && sscreen->info.drm_minor >= 19)) { -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 10/13] radeon/vcn: implement jpeg target buffer cmd
From: Boyuan Zhang Implement jpeg target buffer cmd by programming registers directly, since there is no firmware for VCN Jpeg decode. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c | 73 +++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c b/src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c index d46581c..7ab4e67 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c +++ b/src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c @@ -116,7 +116,78 @@ static void send_cmd_target(struct radeon_decoder *dec, struct pb_buffer* buf, uint32_t off, enum radeon_bo_usage usage, enum radeon_bo_domain domain) { - /* TODO */ + uint64_t addr; + + set_reg_jpeg(dec, mmUVD_JPEG_PITCH, COND0, TYPE0, (dec->jpg.dt_pitch >> 4)); + set_reg_jpeg(dec, mmUVD_JPEG_UV_PITCH, COND0, TYPE0, ((dec->jpg.dt_uv_pitch * 2) >> 4)); + + set_reg_jpeg(dec, mmUVD_JPEG_TILING_CTRL, COND0, TYPE0, 0); + set_reg_jpeg(dec, mmUVD_JPEG_UV_TILING_CTRL, COND0, TYPE0, 0); + + dec->ws->cs_add_buffer(dec->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED, + domain, RADEON_PRIO_UVD); + addr = dec->ws->buffer_get_virtual_address(buf); + addr = addr + off; + + // set UVD_LMI_JPEG_WRITE_64BIT_BAR_LOW/HIGH based on target buffer address + set_reg_jpeg(dec, mmUVD_LMI_JPEG_WRITE_64BIT_BAR_HIGH, COND0, TYPE0, (addr >> 32)); + set_reg_jpeg(dec, mmUVD_LMI_JPEG_WRITE_64BIT_BAR_LOW, COND0, TYPE0, addr); + + // set output buffer data address + set_reg_jpeg(dec, mmUVD_JPEG_INDEX, COND0, TYPE0, 0); + set_reg_jpeg(dec, mmUVD_JPEG_DATA, COND0, TYPE0, dec->jpg.dt_luma_top_offset); + set_reg_jpeg(dec, mmUVD_JPEG_INDEX, COND0, TYPE0, 1); + set_reg_jpeg(dec, mmUVD_JPEG_DATA, COND0, TYPE0, dec->jpg.dt_chroma_top_offset); + set_reg_jpeg(dec, mmUVD_JPEG_TIER_CNTL2, COND0, TYPE3, 0); + + // set output buffer read pointer + set_reg_jpeg(dec, mmUVD_JPEG_OUTBUF_RPTR, COND0, TYPE0, 0); + + // enable error interrupts + set_reg_jpeg(dec, mmUVD_JPEG_INT_EN, COND0, TYPE0, 0xFFFE); + + // start engine command + set_reg_jpeg(dec, mmUVD_JPEG_CNTL, COND0, TYPE0, 0x6); + + // wait for job completion, wait for job JBSI fetch done + set_reg_jpeg(dec, mmUVD_CTX_INDEX, COND0, TYPE0, 0x01C3); + set_reg_jpeg(dec, mmUVD_CTX_DATA, COND0, TYPE0, (dec->jpg.bsd_size >> 2)); + set_reg_jpeg(dec, mmUVD_CTX_INDEX, COND0, TYPE0, 0x01C2); + set_reg_jpeg(dec, mmUVD_CTX_DATA, COND0, TYPE0, 0x01400200); + set_reg_jpeg(dec, mmUVD_JPEG_RB_RPTR, COND0, TYPE3, 0x); + + // wait for job jpeg outbuf idle + set_reg_jpeg(dec, mmUVD_CTX_INDEX, COND0, TYPE0, 0x01C3); + set_reg_jpeg(dec, mmUVD_CTX_DATA, COND0, TYPE0, 0x); + set_reg_jpeg(dec, mmUVD_JPEG_OUTBUF_WPTR, COND0, TYPE3, 0x0001); + + // stop engine + set_reg_jpeg(dec, mmUVD_JPEG_CNTL, COND0, TYPE0, 0x4); + + // asserting jpeg lmi drop + set_reg_jpeg(dec, mmUVD_CTX_INDEX, COND0, TYPE0, 0x0005); + set_reg_jpeg(dec, mmUVD_CTX_DATA, COND0, TYPE0, (1 << 23 | 1 << 0)); + set_reg_jpeg(dec, mmUVD_CTX_DATA, COND0, TYPE1, 0); + + // asserting jpeg reset + set_reg_jpeg(dec, mmUVD_JPEG_CNTL, COND0, TYPE0, 1); + + // ensure reset is asserted in sclk domain + set_reg_jpeg(dec, mmUVD_CTX_INDEX, COND0, TYPE0, 0x01C3); + set_reg_jpeg(dec, mmUVD_CTX_DATA, COND0, TYPE0, (1 << 9)); + set_reg_jpeg(dec, mmUVD_SOFT_RESET, COND0, TYPE3, (1 << 9)); + + // de-assert jpeg reset + set_reg_jpeg(dec, mmUVD_JPEG_CNTL, COND0, TYPE0, 0); + + // ensure reset is de-asserted in sclk domain + set_reg_jpeg(dec, mmUVD_CTX_INDEX, COND0, TYPE0, 0x01C3); + set_reg_jpeg(dec, mmUVD_CTX_DATA, COND0, TYPE0, (0 << 9)); + set_reg_jpeg(dec, mmUVD_SOFT_RESET, COND0, TYPE3, (1 << 9)); + + // de-asserting jpeg lmi drop + set_reg_jpeg(dec, mmUVD_CTX_INDEX, COND0, TYPE0, 0x0005); + set_reg_jpeg(dec, mmUVD_CTX_DATA, COND0, TYPE0, 0); } /** -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 09/13] radeon/vcn: implement jpeg bitstream buffer cmd
From: Boyuan Zhang Implement jpeg bitstream buffer cmd by programming registers directly, since there is no firmware for VCN Jpeg decode. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c | 46 +++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c b/src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c index c52ed36..d46581c 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c +++ b/src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c @@ -59,12 +59,56 @@ static struct pb_buffer *radeon_jpeg_get_decode_param(struct radeon_decoder *dec return luma->resource.buf; } +/* add a new set register command to the IB */ +static void set_reg_jpeg(struct radeon_decoder *dec, unsigned reg, +unsigned cond, unsigned type, uint32_t val) +{ + radeon_emit(dec->cs, RDECODE_PKTJ(SOC15_REG_ADDR(reg), cond, type)); + radeon_emit(dec->cs, val); +} + /* send a bitstream buffer command */ static void send_cmd_bitstream(struct radeon_decoder *dec, struct pb_buffer* buf, uint32_t off, enum radeon_bo_usage usage, enum radeon_bo_domain domain) { - /* TODO */ + uint64_t addr; + + // jpeg soft reset + set_reg_jpeg(dec, mmUVD_JPEG_CNTL, COND0, TYPE0, 1); + + // ensuring the Reset is asserted in SCLK domain + set_reg_jpeg(dec, mmUVD_CTX_INDEX, COND0, TYPE0, 0x01C2); + set_reg_jpeg(dec, mmUVD_CTX_DATA, COND0, TYPE0, 0x01400200); + set_reg_jpeg(dec, mmUVD_CTX_INDEX, COND0, TYPE0, 0x01C3); + set_reg_jpeg(dec, mmUVD_CTX_DATA, COND0, TYPE0, (1 << 9)); + set_reg_jpeg(dec, mmUVD_SOFT_RESET, COND0, TYPE3, (1 << 9)); + + // wait mem + set_reg_jpeg(dec, mmUVD_JPEG_CNTL, COND0, TYPE0, 0); + + // ensuring the Reset is de-asserted in SCLK domain + set_reg_jpeg(dec, mmUVD_CTX_INDEX, COND0, TYPE0, 0x01C3); + set_reg_jpeg(dec, mmUVD_CTX_DATA, COND0, TYPE0, (0 << 9)); + set_reg_jpeg(dec, mmUVD_SOFT_RESET, COND0, TYPE3, (1 << 9)); + + dec->ws->cs_add_buffer(dec->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED, + domain, RADEON_PRIO_UVD); + addr = dec->ws->buffer_get_virtual_address(buf); + addr = addr + off; + + // set UVD_LMI_JPEG_READ_64BIT_BAR_LOW/HIGH based on bitstream buffer address + set_reg_jpeg(dec, mmUVD_LMI_JPEG_READ_64BIT_BAR_HIGH, COND0, TYPE0, (addr >> 32)); + set_reg_jpeg(dec, mmUVD_LMI_JPEG_READ_64BIT_BAR_LOW, COND0, TYPE0, addr); + + // set jpeg_rb_base + set_reg_jpeg(dec, mmUVD_JPEG_RB_BASE, COND0, TYPE0, 0); + + // set jpeg_rb_base + set_reg_jpeg(dec, mmUVD_JPEG_RB_SIZE, COND0, TYPE0, 0xFFF0); + + // set jpeg_rb_wptr + set_reg_jpeg(dec, mmUVD_JPEG_RB_WPTR, COND0, TYPE0, (dec->jpg.bsd_size >> 2)); } /* send a target buffer command */ -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 08/13] radeon/uvd: remove get mjpeg slice header
From: Boyuan Zhang Move the previous get_mjpeg_slice_header function from radeon/vcn to st/va. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_uvd.c | 136 1 file changed, 136 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c index 78ced17..78575e7 100644 --- a/src/gallium/drivers/radeon/radeon_uvd.c +++ b/src/gallium/drivers/radeon/radeon_uvd.c @@ -965,139 +965,6 @@ static struct ruvd_mpeg4 get_mpeg4_msg(struct ruvd_decoder *dec, return result; } -static void get_mjpeg_slice_header(struct ruvd_decoder *dec, struct pipe_mjpeg_picture_desc *pic) -{ - int size = 0, saved_size, len_pos, i; - uint16_t *bs; - uint8_t *buf = dec->bs_ptr; - - /* SOI */ - buf[size++] = 0xff; - buf[size++] = 0xd8; - - /* DQT */ - buf[size++] = 0xff; - buf[size++] = 0xdb; - - len_pos = size++; - size++; - - for (i = 0; i < 4; ++i) { - if (pic->quantization_table.load_quantiser_table[i] == 0) - continue; - - buf[size++] = i; - memcpy((buf + size), &pic->quantization_table.quantiser_table[i], 64); - size += 64; - } - - bs = (uint16_t*)&buf[len_pos]; - *bs = util_bswap16(size - 4); - - saved_size = size; - - /* DHT */ - buf[size++] = 0xff; - buf[size++] = 0xc4; - - len_pos = size++; - size++; - - for (i = 0; i < 2; ++i) { - if (pic->huffman_table.load_huffman_table[i] == 0) - continue; - - buf[size++] = 0x00 | i; - memcpy((buf + size), &pic->huffman_table.table[i].num_dc_codes, 16); - size += 16; - memcpy((buf + size), &pic->huffman_table.table[i].dc_values, 12); - size += 12; - } - - for (i = 0; i < 2; ++i) { - if (pic->huffman_table.load_huffman_table[i] == 0) - continue; - - buf[size++] = 0x10 | i; - memcpy((buf + size), &pic->huffman_table.table[i].num_ac_codes, 16); - size += 16; - memcpy((buf + size), &pic->huffman_table.table[i].ac_values, 162); - size += 162; - } - - bs = (uint16_t*)&buf[len_pos]; - *bs = util_bswap16(size - saved_size - 2); - - saved_size = size; - - /* DRI */ - if (pic->slice_parameter.restart_interval) { - buf[size++] = 0xff; - buf[size++] = 0xdd; - buf[size++] = 0x00; - buf[size++] = 0x04; - bs = (uint16_t*)&buf[size++]; - *bs = util_bswap16(pic->slice_parameter.restart_interval); - saved_size = ++size; - } - - /* SOF */ - buf[size++] = 0xff; - buf[size++] = 0xc0; - - len_pos = size++; - size++; - - buf[size++] = 0x08; - - bs = (uint16_t*)&buf[size++]; - *bs = util_bswap16(pic->picture_parameter.picture_height); - size++; - - bs = (uint16_t*)&buf[size++]; - *bs = util_bswap16(pic->picture_parameter.picture_width); - size++; - - buf[size++] = pic->picture_parameter.num_components; - - for (i = 0; i < pic->picture_parameter.num_components; ++i) { - buf[size++] = pic->picture_parameter.components[i].component_id; - buf[size++] = pic->picture_parameter.components[i].h_sampling_factor << 4 | - pic->picture_parameter.components[i].v_sampling_factor; - buf[size++] = pic->picture_parameter.components[i].quantiser_table_selector; - } - - bs = (uint16_t*)&buf[len_pos]; - *bs = util_bswap16(size - saved_size - 2); - - saved_size = size; - - /* SOS */ - buf[size++] = 0xff; - buf[size++] = 0xda; - - len_pos = size++; - size++; - - buf[size++] = pic->slice_parameter.num_components; - - for (i = 0; i < pic->slice_parameter.num_components; ++i) { - buf[size++] = pic->slice_parameter.components[i].component_selector; - buf[size++] = pic->slice_parameter.components[i].dc_table_selector << 4 | - pic->slice_parameter.components[i].ac_table_selector; - } - - buf[size++] = 0x00; - buf[size++] = 0x3f; - buf[size++] = 0x00; - - bs = (uint16_t*)&buf[len_pos]; - *bs = util_bswap16(size - saved_size - 2); - - dec->bs_ptr += size; - dec->bs_size += size; -} - /** * destroy this video decoder */ @@ -1184,9 +1051,6 @@ static void ruvd_decode_bitstream(struct pipe_video_codec *decoder, if (!dec->bs_ptr) return; - if (format == PIPE_VIDEO_FORMAT_JPEG) - get_mjpeg_slice_header(dec, (struct pipe_mjpeg_picture_desc*)picture); - for (i = 0; i < num_buffers; ++i) {
[Mesa-dev] [PATCH 06/13] radeon/vcn: add jpeg decode implementation
From: Boyuan Zhang Add a new file to handle VCN Jpeg decode specific functions. Use Jpeg specific cmd sending function in end_frame call. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/Makefile.sources | 1 + src/gallium/drivers/radeon/meson.build | 1 + src/gallium/drivers/radeon/radeon_vcn_dec.c | 32 ++-- src/gallium/drivers/radeon/radeon_vcn_dec.h | 4 + src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c | 99 5 files changed, 130 insertions(+), 7 deletions(-) create mode 100644 src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c diff --git a/src/gallium/drivers/radeon/Makefile.sources b/src/gallium/drivers/radeon/Makefile.sources index f8ee860..e3ee82c 100644 --- a/src/gallium/drivers/radeon/Makefile.sources +++ b/src/gallium/drivers/radeon/Makefile.sources @@ -10,6 +10,7 @@ C_SOURCES := \ r600_texture.c \ radeon_uvd.c \ radeon_uvd.h \ + radeon_vcn_dec_jpeg.c \ radeon_vcn_dec.c \ radeon_vcn_dec.h \ radeon_vcn_enc_1_2.c \ diff --git a/src/gallium/drivers/radeon/meson.build b/src/gallium/drivers/radeon/meson.build index 582a5ff..c984a75 100644 --- a/src/gallium/drivers/radeon/meson.build +++ b/src/gallium/drivers/radeon/meson.build @@ -33,6 +33,7 @@ files_libradeon = files( 'radeon_vcn_enc_1_2.c', 'radeon_vcn_enc.c', 'radeon_vcn_enc.h', + 'radeon_vcn_dec_jpeg.c', 'radeon_vcn_dec.c', 'radeon_vcn_dec.h', 'radeon_uvd_enc_1_1.c', diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.c b/src/gallium/drivers/radeon/radeon_vcn_dec.c index 30a8952..861a40e 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeon/radeon_vcn_dec.c @@ -991,6 +991,10 @@ static unsigned calc_dpb_size(struct radeon_decoder *dec) dpb_size = MAX2(dpb_size, 30 * 1024 * 1024); break; + case PIPE_VIDEO_FORMAT_JPEG: + dpb_size = 0; + break; + default: // something is missing here assert(0); @@ -1078,6 +1082,7 @@ static void radeon_dec_decode_bitstream(struct pipe_video_codec *decoder, const unsigned *sizes) { struct radeon_decoder *dec = (struct radeon_decoder*)decoder; + enum pipe_video_format format = u_reduce_video_profile(picture->profile); unsigned i; assert(decoder); @@ -1089,6 +1094,9 @@ static void radeon_dec_decode_bitstream(struct pipe_video_codec *decoder, struct rvid_buffer *buf = &dec->bs_buffers[dec->cur_buffer]; unsigned new_size = dec->bs_size + sizes[i]; + if (format == PIPE_VIDEO_FORMAT_JPEG) + new_size += 2; /* save for EOI */ + if (new_size > buf->res->buf->size) { dec->ws->buffer_unmap(buf->res->buf); if (!si_vid_resize_buffer(dec->screen, dec->cs, buf, new_size)) { @@ -1108,6 +1116,13 @@ static void radeon_dec_decode_bitstream(struct pipe_video_codec *decoder, dec->bs_size += sizes[i]; dec->bs_ptr += sizes[i]; } + + if (format == PIPE_VIDEO_FORMAT_JPEG) { + ((uint8_t *)dec->bs_ptr)[0] = 0xff; /* EOI */ + ((uint8_t *)dec->bs_ptr)[1] = 0xd9; + dec->bs_size += 2; + dec->bs_ptr += 2; + } } /** @@ -1270,14 +1285,14 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, } dpb_size = calc_dpb_size(dec); - - if (!si_vid_create_buffer(dec->screen, &dec->dpb, dpb_size, PIPE_USAGE_DEFAULT)) { - RVID_ERR("Can't allocated dpb.\n"); - goto error; + if (dpb_size) { + if (!si_vid_create_buffer(dec->screen, &dec->dpb, dpb_size, PIPE_USAGE_DEFAULT)) { + RVID_ERR("Can't allocated dpb.\n"); + goto error; + } + si_vid_clear_buffer(context, &dec->dpb); } - si_vid_clear_buffer(context, &dec->dpb); - if (dec->stream_type == RDECODE_CODEC_H264_PERF) { unsigned ctx_size = calc_ctx_size_h264_perf(dec); if (!si_vid_create_buffer(dec->screen, &dec->ctx, ctx_size, PIPE_USAGE_DEFAULT)) { @@ -1304,7 +1319,10 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, next_buffer(dec); - dec->send_cmd = send_cmd_dec; + if (stream_type == RDECODE_CODEC_JPEG) + dec->send_cmd = send_cmd_jpeg; + else + dec->send_cmd = send_cmd_dec; return &dec->base; diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.h b/src/gallium/drivers/radeon/radeon_vcn_dec.h index 05e4847..782eb65 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec.h +++ b/src/gallium/drivers/radeon/radeon_vcn_dec.h @@ -627,6 +627,10 @@ void send_cmd_dec(struct radeon_decoder *
[Mesa-dev] [PATCH 07/13] st/va: get mjpeg slice header
From: Boyuan Zhang Move the previous get_mjpeg_slice_heaeder function and eoi from "radeon/vcn" to "st/va". Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/picture.c | 13 ++- src/gallium/state_trackers/va/picture_mjpeg.c | 132 ++ src/gallium/state_trackers/va/va_private.h| 11 +++ 3 files changed, 154 insertions(+), 2 deletions(-) diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index f2e9ba8..af136fb 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -251,11 +251,12 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) { enum pipe_video_format format; unsigned num_buffers = 0; - void * const *buffers[2]; - unsigned sizes[2]; + void * const *buffers[3]; + unsigned sizes[3]; static const uint8_t start_code_h264[] = { 0x00, 0x00, 0x01 }; static const uint8_t start_code_h265[] = { 0x00, 0x00, 0x01 }; static const uint8_t start_code_vc1[] = { 0x00, 0x00, 0x01, 0x0d }; + static const uint8_t eoi_jpeg[] = { 0xff, 0xd9 }; format = u_reduce_video_profile(context->templat.profile); switch (format) { @@ -293,6 +294,9 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) sizes[num_buffers++] = context->mpeg4.start_code_size; break; case PIPE_VIDEO_FORMAT_JPEG: + vlVaGetJpegSliceHeader(context); + buffers[num_buffers] = (void *)context->mjpeg.slice_header; + sizes[num_buffers++] = context->mjpeg.slice_header_size; break; default: break; @@ -302,6 +306,11 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) sizes[num_buffers] = buf->size; ++num_buffers; + if (format == PIPE_VIDEO_FORMAT_JPEG) { + buffers[num_buffers] = (void *const)&eoi_jpeg; + sizes[num_buffers++] = sizeof(eoi_jpeg); + } + if (context->needs_begin_frame) { context->decoder->begin_frame(context->decoder, context->target, &context->desc.base); diff --git a/src/gallium/state_trackers/va/picture_mjpeg.c b/src/gallium/state_trackers/va/picture_mjpeg.c index 396b743..f1292ea 100644 --- a/src/gallium/state_trackers/va/picture_mjpeg.c +++ b/src/gallium/state_trackers/va/picture_mjpeg.c @@ -114,3 +114,135 @@ void vlVaHandleSliceParameterBufferMJPEG(vlVaContext *context, vlVaBuffer *buf) context->desc.mjpeg.slice_parameter.restart_interval = mjpeg->restart_interval; context->desc.mjpeg.slice_parameter.num_mcus = mjpeg->num_mcus; } + +void vlVaGetJpegSliceHeader(vlVaContext *context) +{ + int size = 0, saved_size, len_pos, i; + uint16_t *bs; + uint8_t *p = context->mjpeg.slice_header; + + /* SOI */ + p[size++] = 0xff; + p[size++] = 0xd8; + + /* DQT */ + p[size++] = 0xff; + p[size++] = 0xdb; + + len_pos = size++; + size++; + + for (i = 0; i < 4; ++i) { + if (context->desc.mjpeg.quantization_table.load_quantiser_table[i] == 0) + continue; + + p[size++] = i; + memcpy((p + size), &context->desc.mjpeg.quantization_table.quantiser_table[i], 64); + size += 64; + } + + bs = (uint16_t*)&p[len_pos]; + *bs = util_bswap16(size - 4); + + saved_size = size; + + /* DHT */ + p[size++] = 0xff; + p[size++] = 0xc4; + + len_pos = size++; + size++; + + for (i = 0; i < 2; ++i) { + if (context->desc.mjpeg.huffman_table.load_huffman_table[i] == 0) + continue; + + p[size++] = 0x00 | i; + memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].num_dc_codes, 16); + size += 16; + memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].dc_values, 12); + size += 12; + } + + for (i = 0; i < 2; ++i) { + if (context->desc.mjpeg.huffman_table.load_huffman_table[i] == 0) + continue; + + p[size++] = 0x10 | i; + memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].num_ac_codes, 16); + size += 16; + memcpy((p + size), &context->desc.mjpeg.huffman_table.table[i].ac_values, 162); + size += 162; + } + + bs = (uint16_t*)&p[len_pos]; + *bs = util_bswap16(size - saved_size - 2); + + saved_size = size; + + /* DRI */ + if (context->desc.mjpeg.slice_parameter.restart_interval) { + p[size++] = 0xff; + p[size++] = 0xdd; + p[size++] = 0x00; + p[size++] = 0x04; + bs = (uint16_t*)&p[size++]; + *bs = util_bswap16(context->desc.mjpeg.slice_parameter.restart_interval); + saved_size = ++size; + } + + /* SOF */ + p[size++] = 0xff; + p[size++] = 0xc0; + + len_pos = size++; + size++; + + p[size++] = 0x08; + + bs = (uint16_t*)&p[size++]; + *bs = util_bswap16(context->desc.mjpeg.picture_parameter.picture_height); + size++; + + bs = (uint16_t*)&p[size++]; + *bs = util_bswap16(context->desc.mjpeg.picture_parameter.picture_width); + size++; + + p[size++] = context->desc.mjpeg.picture_parameter.num_components; + + for (i =
[Mesa-dev] [PATCH 06/13] radeon/vcn: add jpeg decode implementation
From: Boyuan Zhang Add a new file to handle VCN Jpeg decode specific functions. Use Jpeg specific cmd sending function in end_frame call. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/Makefile.sources | 1 + src/gallium/drivers/radeon/meson.build | 1 + src/gallium/drivers/radeon/radeon_vcn_dec.c | 21 +++-- src/gallium/drivers/radeon/radeon_vcn_dec.h | 4 + src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c | 99 5 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c diff --git a/src/gallium/drivers/radeon/Makefile.sources b/src/gallium/drivers/radeon/Makefile.sources index f8ee860..e3ee82c 100644 --- a/src/gallium/drivers/radeon/Makefile.sources +++ b/src/gallium/drivers/radeon/Makefile.sources @@ -10,6 +10,7 @@ C_SOURCES := \ r600_texture.c \ radeon_uvd.c \ radeon_uvd.h \ + radeon_vcn_dec_jpeg.c \ radeon_vcn_dec.c \ radeon_vcn_dec.h \ radeon_vcn_enc_1_2.c \ diff --git a/src/gallium/drivers/radeon/meson.build b/src/gallium/drivers/radeon/meson.build index 582a5ff..c984a75 100644 --- a/src/gallium/drivers/radeon/meson.build +++ b/src/gallium/drivers/radeon/meson.build @@ -33,6 +33,7 @@ files_libradeon = files( 'radeon_vcn_enc_1_2.c', 'radeon_vcn_enc.c', 'radeon_vcn_enc.h', + 'radeon_vcn_dec_jpeg.c', 'radeon_vcn_dec.c', 'radeon_vcn_dec.h', 'radeon_uvd_enc_1_1.c', diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.c b/src/gallium/drivers/radeon/radeon_vcn_dec.c index 30a8952..264abea 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeon/radeon_vcn_dec.c @@ -991,6 +991,10 @@ static unsigned calc_dpb_size(struct radeon_decoder *dec) dpb_size = MAX2(dpb_size, 30 * 1024 * 1024); break; + case PIPE_VIDEO_FORMAT_JPEG: + dpb_size = 0; + break; + default: // something is missing here assert(0); @@ -1270,14 +1274,14 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, } dpb_size = calc_dpb_size(dec); - - if (!si_vid_create_buffer(dec->screen, &dec->dpb, dpb_size, PIPE_USAGE_DEFAULT)) { - RVID_ERR("Can't allocated dpb.\n"); - goto error; + if (dpb_size) { + if (!si_vid_create_buffer(dec->screen, &dec->dpb, dpb_size, PIPE_USAGE_DEFAULT)) { + RVID_ERR("Can't allocated dpb.\n"); + goto error; + } + si_vid_clear_buffer(context, &dec->dpb); } - si_vid_clear_buffer(context, &dec->dpb); - if (dec->stream_type == RDECODE_CODEC_H264_PERF) { unsigned ctx_size = calc_ctx_size_h264_perf(dec); if (!si_vid_create_buffer(dec->screen, &dec->ctx, ctx_size, PIPE_USAGE_DEFAULT)) { @@ -1304,7 +1308,10 @@ struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, next_buffer(dec); - dec->send_cmd = send_cmd_dec; + if (stream_type == RDECODE_CODEC_JPEG) + dec->send_cmd = send_cmd_jpeg; + else + dec->send_cmd = send_cmd_dec; return &dec->base; diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.h b/src/gallium/drivers/radeon/radeon_vcn_dec.h index 05e4847..782eb65 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_dec.h +++ b/src/gallium/drivers/radeon/radeon_vcn_dec.h @@ -627,6 +627,10 @@ void send_cmd_dec(struct radeon_decoder *dec, struct pipe_video_buffer *target, struct pipe_picture_desc *picture); +void send_cmd_jpeg(struct radeon_decoder *dec, + struct pipe_video_buffer *target, + struct pipe_picture_desc *picture); + struct pipe_video_codec *radeon_create_decoder(struct pipe_context *context, const struct pipe_video_codec *templat); diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c b/src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c new file mode 100644 index 000..c52ed36 --- /dev/null +++ b/src/gallium/drivers/radeon/radeon_vcn_dec_jpeg.c @@ -0,0 +1,99 @@ +/** + * + * Copyright 2018 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)
[Mesa-dev] [PATCH 08/13] radeon/uvd: remove get mjpeg slice header
From: Boyuan Zhang Move the previous get_mjpeg_slice_heaeder function and eoi from "radeon/vcn" to "st/va". Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_uvd.c | 147 1 file changed, 147 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c index 78ced17..bff48ad 100644 --- a/src/gallium/drivers/radeon/radeon_uvd.c +++ b/src/gallium/drivers/radeon/radeon_uvd.c @@ -965,139 +965,6 @@ static struct ruvd_mpeg4 get_mpeg4_msg(struct ruvd_decoder *dec, return result; } -static void get_mjpeg_slice_header(struct ruvd_decoder *dec, struct pipe_mjpeg_picture_desc *pic) -{ - int size = 0, saved_size, len_pos, i; - uint16_t *bs; - uint8_t *buf = dec->bs_ptr; - - /* SOI */ - buf[size++] = 0xff; - buf[size++] = 0xd8; - - /* DQT */ - buf[size++] = 0xff; - buf[size++] = 0xdb; - - len_pos = size++; - size++; - - for (i = 0; i < 4; ++i) { - if (pic->quantization_table.load_quantiser_table[i] == 0) - continue; - - buf[size++] = i; - memcpy((buf + size), &pic->quantization_table.quantiser_table[i], 64); - size += 64; - } - - bs = (uint16_t*)&buf[len_pos]; - *bs = util_bswap16(size - 4); - - saved_size = size; - - /* DHT */ - buf[size++] = 0xff; - buf[size++] = 0xc4; - - len_pos = size++; - size++; - - for (i = 0; i < 2; ++i) { - if (pic->huffman_table.load_huffman_table[i] == 0) - continue; - - buf[size++] = 0x00 | i; - memcpy((buf + size), &pic->huffman_table.table[i].num_dc_codes, 16); - size += 16; - memcpy((buf + size), &pic->huffman_table.table[i].dc_values, 12); - size += 12; - } - - for (i = 0; i < 2; ++i) { - if (pic->huffman_table.load_huffman_table[i] == 0) - continue; - - buf[size++] = 0x10 | i; - memcpy((buf + size), &pic->huffman_table.table[i].num_ac_codes, 16); - size += 16; - memcpy((buf + size), &pic->huffman_table.table[i].ac_values, 162); - size += 162; - } - - bs = (uint16_t*)&buf[len_pos]; - *bs = util_bswap16(size - saved_size - 2); - - saved_size = size; - - /* DRI */ - if (pic->slice_parameter.restart_interval) { - buf[size++] = 0xff; - buf[size++] = 0xdd; - buf[size++] = 0x00; - buf[size++] = 0x04; - bs = (uint16_t*)&buf[size++]; - *bs = util_bswap16(pic->slice_parameter.restart_interval); - saved_size = ++size; - } - - /* SOF */ - buf[size++] = 0xff; - buf[size++] = 0xc0; - - len_pos = size++; - size++; - - buf[size++] = 0x08; - - bs = (uint16_t*)&buf[size++]; - *bs = util_bswap16(pic->picture_parameter.picture_height); - size++; - - bs = (uint16_t*)&buf[size++]; - *bs = util_bswap16(pic->picture_parameter.picture_width); - size++; - - buf[size++] = pic->picture_parameter.num_components; - - for (i = 0; i < pic->picture_parameter.num_components; ++i) { - buf[size++] = pic->picture_parameter.components[i].component_id; - buf[size++] = pic->picture_parameter.components[i].h_sampling_factor << 4 | - pic->picture_parameter.components[i].v_sampling_factor; - buf[size++] = pic->picture_parameter.components[i].quantiser_table_selector; - } - - bs = (uint16_t*)&buf[len_pos]; - *bs = util_bswap16(size - saved_size - 2); - - saved_size = size; - - /* SOS */ - buf[size++] = 0xff; - buf[size++] = 0xda; - - len_pos = size++; - size++; - - buf[size++] = pic->slice_parameter.num_components; - - for (i = 0; i < pic->slice_parameter.num_components; ++i) { - buf[size++] = pic->slice_parameter.components[i].component_selector; - buf[size++] = pic->slice_parameter.components[i].dc_table_selector << 4 | - pic->slice_parameter.components[i].ac_table_selector; - } - - buf[size++] = 0x00; - buf[size++] = 0x3f; - buf[size++] = 0x00; - - bs = (uint16_t*)&buf[len_pos]; - *bs = util_bswap16(size - saved_size - 2); - - dec->bs_ptr += size; - dec->bs_size += size; -} - /** * destroy this video decoder */ @@ -1176,7 +1043,6 @@ static void ruvd_decode_bitstream(struct pipe_video_codec *decoder, const unsigned *sizes) { struct ruvd_decoder *dec = (struct ruvd_decoder*)decoder; - enum pipe_video_format format = u_reduce_video_profile(picture->profile); unsigned i;
[Mesa-dev] [PATCH] vl: reorder H264 profiles
From: Boyuan Zhang Fix the wrong h264 profiles order. Previously, the constrained baseline was added in between baseline and main profiles, which breaked the logic in radeon/vce when converting from pipe_video_profile to profile_idc Signed-off-by: Boyuan Zhang --- src/gallium/include/pipe/p_video_enums.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/include/pipe/p_video_enums.h b/src/gallium/include/pipe/p_video_enums.h index b5b8b06228..260f47ea8a 100644 --- a/src/gallium/include/pipe/p_video_enums.h +++ b/src/gallium/include/pipe/p_video_enums.h @@ -55,8 +55,8 @@ enum pipe_video_profile PIPE_VIDEO_PROFILE_VC1_SIMPLE, PIPE_VIDEO_PROFILE_VC1_MAIN, PIPE_VIDEO_PROFILE_VC1_ADVANCED, - PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE, PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE, + PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE, PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN, PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED, PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH, -- 2.17.1 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] radeon/vce: use switch to convert profile idc
From: Boyuan Zhang The previous array logic for converting pipe video profile to profile idc relies on the order of pipe_video_profile enum defines. Adding new profile to enum defines may break the logic. Therefore, it's better to use switch helper function to acheive the same goal. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vce.c | 24 +++ src/gallium/drivers/radeon/radeon_vce.h | 3 +++ .../drivers/radeon/radeon_vce_40_2_2.c| 5 +--- src/gallium/drivers/radeon/radeon_vce_52.c| 5 +--- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vce.c b/src/gallium/drivers/radeon/radeon_vce.c index 8972253c7c..6b9f2ab37b 100644 --- a/src/gallium/drivers/radeon/radeon_vce.c +++ b/src/gallium/drivers/radeon/radeon_vce.c @@ -572,3 +572,27 @@ void si_vce_add_buffer(struct rvce_encoder *enc, struct pb_buffer *buf, RVCE_CS(offset); } } + +unsigned si_vce_get_profile_idc(enum pipe_video_profile profile) +{ + switch (profile) { + case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE: + case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE: + return 66; + case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN: + return 77; + case PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED: + return 88; + case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH: + return 100; + case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10: + return 110; + case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH422: + return 122; + case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH444: + return 244; + default: + RVID_ERR("Unsupported profile! Use baseline profile instead.\n"); + return 66; + } +} diff --git a/src/gallium/drivers/radeon/radeon_vce.h b/src/gallium/drivers/radeon/radeon_vce.h index cf625e6fed..255a3bf200 100644 --- a/src/gallium/drivers/radeon/radeon_vce.h +++ b/src/gallium/drivers/radeon/radeon_vce.h @@ -453,4 +453,7 @@ void si_vce_50_get_param(struct rvce_encoder *enc, void si_vce_52_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic); +/* convert pipe video profile to profile idc */ +unsigned si_vce_get_profile_idc(enum pipe_video_profile profile); + #endif diff --git a/src/gallium/drivers/radeon/radeon_vce_40_2_2.c b/src/gallium/drivers/radeon/radeon_vce_40_2_2.c index 66b54dab25..925480e4af 100644 --- a/src/gallium/drivers/radeon/radeon_vce_40_2_2.c +++ b/src/gallium/drivers/radeon/radeon_vce_40_2_2.c @@ -38,8 +38,6 @@ #include "radeon_video.h" #include "radeon_vce.h" -static const unsigned profiles[7] = { 66, 77, 88, 100, 110, 122, 244 }; - static void session(struct rvce_encoder *enc) { RVCE_BEGIN(0x0001); // session cmd @@ -82,8 +80,7 @@ static void create(struct rvce_encoder *enc) RVCE_BEGIN(0x0101); // create cmd RVCE_CS(0x); // encUseCircularBuffer - RVCE_CS(profiles[enc->base.profile - - PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE]); // encProfile + RVCE_CS(si_vce_get_profile_idc(enc->base.profile)); // encProfile RVCE_CS(enc->base.level); // encLevel RVCE_CS(0x); // encPicStructRestriction RVCE_CS(enc->base.width); // encImageWidth diff --git a/src/gallium/drivers/radeon/radeon_vce_52.c b/src/gallium/drivers/radeon/radeon_vce_52.c index 421539c4bd..bf7c5d6ff2 100644 --- a/src/gallium/drivers/radeon/radeon_vce_52.c +++ b/src/gallium/drivers/radeon/radeon_vce_52.c @@ -38,8 +38,6 @@ #include "radeon_video.h" #include "radeon_vce.h" -static const unsigned profiles[7] = { 66, 77, 88, 100, 110, 122, 244 }; - static void get_rate_control_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) { enc->enc_pic.rc.rc_method = pic->rate_ctrl.rate_ctrl_method; @@ -172,8 +170,7 @@ static void create(struct rvce_encoder *enc) RVCE_BEGIN(0x0101); // create cmd RVCE_CS(enc->enc_pic.ec.enc_use_circular_buffer); - RVCE_CS(profiles[enc->base.profile - - PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE]); // encProfile + RVCE_CS(si_vce_get_profile_idc(enc->base.profile)); // encProfile RVCE_CS(enc->base.level); // encLevel RVCE_CS(enc->enc_pic.ec.enc_pic_struct_restriction); RVCE_CS(enc->base.width); // encImageWidth -- 2.17.1 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] radeonsi: fix radeon create encoder return
From: Boyuan Zhang Previous patch missed a "return" when trying to modify the create encoder function, which made the whole logic fail. Therefore, add the return back. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeonsi/si_uvd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeonsi/si_uvd.c b/src/gallium/drivers/radeonsi/si_uvd.c index 3906bbd..b6cb4cb 100644 --- a/src/gallium/drivers/radeonsi/si_uvd.c +++ b/src/gallium/drivers/radeonsi/si_uvd.c @@ -150,7 +150,7 @@ struct pipe_video_codec *si_uvd_create_decoder(struct pipe_context *context, if (templ->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { if (vcn) { - radeon_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); + return radeon_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); } else { if (u_reduce_video_profile(templ->profile) == PIPE_VIDEO_FORMAT_HEVC) return radeon_uvd_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] radeon/vcn: use enc profile instead of pic profile
From: Boyuan Zhang Picture profile might not be set in some cases. Therefore, better to use the profile stored in encoder base. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc.c | 4 ++-- src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c | 16 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c index 388a333..dcc25f2 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -40,7 +40,7 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_picture_desc *picture) { - if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { + if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { struct pipe_h264_enc_picture_desc *pic = (struct pipe_h264_enc_picture_desc *)picture; enc->enc_pic.picture_type = pic->picture_type; enc->enc_pic.frame_num = pic->frame_num; @@ -54,7 +54,7 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_pic 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; - } else if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_HEVC) { + } else if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) { struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture; enc->enc_pic.picture_type = pic->picture_type; enc->enc_pic.frame_num = pic->frame_num; diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c index 07493d8..9adf40f 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c @@ -341,7 +341,7 @@ static void radeon_enc_spec_misc_hevc(struct radeon_encoder *enc, struct pipe_pi static void radeon_enc_rc_session_init(struct radeon_encoder *enc, struct pipe_picture_desc *picture) { - if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { + if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { struct pipe_h264_enc_picture_desc *pic = (struct pipe_h264_enc_picture_desc *)picture; enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rate_ctrl.vbv_buf_lv; switch(pic->rate_ctrl.rate_ctrl_method) { @@ -359,7 +359,7 @@ static void radeon_enc_rc_session_init(struct radeon_encoder *enc, struct pipe_p default: enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE; } - } else if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_HEVC) { + } else if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) { struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture; enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rc.vbv_buf_lv; switch(pic->rc.rate_ctrl_method) { @@ -387,7 +387,7 @@ static void radeon_enc_rc_session_init(struct radeon_encoder *enc, struct pipe_p static void radeon_enc_rc_layer_init(struct radeon_encoder *enc, struct pipe_picture_desc *picture) { - if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { + if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { struct pipe_h264_enc_picture_desc *pic = (struct pipe_h264_enc_picture_desc *)picture; enc->enc_pic.rc_layer_init.target_bit_rate = pic->rate_ctrl.target_bitrate; enc->enc_pic.rc_layer_init.peak_bit_rate = pic->rate_ctrl.peak_bitrate; @@ -397,7 +397,7 @@ static void radeon_enc_rc_layer_init(struct radeon_encoder *enc, struct pipe_pic enc->enc_pic.rc_layer_init.avg_target_bits_per_picture = pic->rate_ctrl.target_bits_picture; enc->enc_pic.rc_layer_init.peak_bits_per_picture_integer = pic->rate_ctrl.peak_bits_picture_integer; enc->enc_pic.rc_layer_init.peak_bits_per_picture_fractional = pic->rate_ctrl.peak_bits_picture_fraction; - } else if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_HEVC) { + } else if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) { struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture; enc->enc_pic.rc_layer_init.target_bit_rate = pic->rc.target_bitrate; enc->enc_pic.rc_layer_init.peak_bit_rate = pic->rc.peak_bitrate; @@ -1113,7 +1113,7 @@ static void radeon_enc_intra_refresh(struct radeon_encoder *enc)
[Mesa-dev] [PATCH] st/omx_bellagio: add picture profile and entry point
From: Boyuan Zhang Profile and entry point were missing in the picture structure. Therefore, add them back. Signed-off-by: Boyuan Zhang Reviewed-by: Leo Liu --- src/gallium/state_trackers/omx_bellagio/vid_enc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gallium/state_trackers/omx_bellagio/vid_enc.c b/src/gallium/state_trackers/omx_bellagio/vid_enc.c index 1a4fb62..162ec1f 100644 --- a/src/gallium/state_trackers/omx_bellagio/vid_enc.c +++ b/src/gallium/state_trackers/omx_bellagio/vid_enc.c @@ -1098,6 +1098,8 @@ static void enc_HandleTask(omx_base_PortType *port, struct encode_task *task, picture.picture_type = picture_type; picture.pic_order_cnt = task->pic_order_cnt; + picture.base.profile = enc_TranslateOMXProfileToPipe(priv->profile_level.eProfile); + picture.base.entry_point = PIPE_VIDEO_ENTRYPOINT_ENCODE; if (priv->restricted_b_frames && picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) picture.not_referenced = true; enc_ControlPicture(port, &picture); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] radeonsi: fix radeon create encoder return
From: Boyuan Zhang Previous patch missed a "return" when trying to modify the create encoder function, which made the whole logic fail. Therefore, add the return back. Fixes: b38b208ff8886e799d6a2 "radeonsi:create uvd hevc enc entry" Signed-off-by: Boyuan Zhang Reviewed-by: Alex Deucher Reviewed-by: Eric Engestrom --- src/gallium/drivers/radeonsi/si_uvd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeonsi/si_uvd.c b/src/gallium/drivers/radeonsi/si_uvd.c index 3906bbd..b6cb4cb 100644 --- a/src/gallium/drivers/radeonsi/si_uvd.c +++ b/src/gallium/drivers/radeonsi/si_uvd.c @@ -150,7 +150,7 @@ struct pipe_video_codec *si_uvd_create_decoder(struct pipe_context *context, if (templ->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { if (vcn) { - radeon_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); + return radeon_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); } else { if (u_reduce_video_profile(templ->profile) == PIPE_VIDEO_FORMAT_HEVC) return radeon_uvd_create_encoder(context, templ, ctx->b.ws, si_vce_get_buffer); -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 08/12] st/va: add entrypoint check for HEVC
From: Boyuan Zhang Add entrypoint check for HEVC to differentiate decode and encode jobs. Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/context.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index f03b326..f567f54 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -263,16 +263,18 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, case PIPE_VIDEO_FORMAT_HEVC: context->templat.max_references = num_render_targets; - context->desc.h265.pps = CALLOC_STRUCT(pipe_h265_pps); - if (!context->desc.h265.pps) { -FREE(context); -return VA_STATUS_ERROR_ALLOCATION_FAILED; - } - context->desc.h265.pps->sps = CALLOC_STRUCT(pipe_h265_sps); - if (!context->desc.h265.pps->sps) { -FREE(context->desc.h265.pps); -FREE(context); -return VA_STATUS_ERROR_ALLOCATION_FAILED; + if (config->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) { +context->desc.h265.pps = CALLOC_STRUCT(pipe_h265_pps); +if (!context->desc.h265.pps) { + FREE(context); + return VA_STATUS_ERROR_ALLOCATION_FAILED; +} +context->desc.h265.pps->sps = CALLOC_STRUCT(pipe_h265_sps); +if (!context->desc.h265.pps->sps) { + FREE(context->desc.h265.pps); + FREE(context); + return VA_STATUS_ERROR_ALLOCATION_FAILED; +} } break; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 04/12] radeon/vcn: add ib implementations for HEVC
From: Boyuan Zhang Implement required ibs for vcn HEVC encode. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c | 267 1 file changed, 222 insertions(+), 45 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c index 06b8092..a651f7e 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c @@ -231,6 +231,27 @@ static void radeon_enc_session_init(struct radeon_encoder *enc) RADEON_ENC_END(); } +static void radeon_enc_session_init_hevc(struct radeon_encoder *enc) +{ + enc->enc_pic.session_init.encode_standard = RENCODE_ENCODE_STANDARD_HEVC; + enc->enc_pic.session_init.aligned_picture_width = align(enc->base.width, 64); + enc->enc_pic.session_init.aligned_picture_height = align(enc->base.height, 16); + enc->enc_pic.session_init.padding_width = enc->enc_pic.session_init.aligned_picture_width - enc->base.width; + enc->enc_pic.session_init.padding_height = enc->enc_pic.session_init.aligned_picture_height - enc->base.height; + enc->enc_pic.session_init.pre_encode_mode = RENCODE_PREENCODE_MODE_NONE; + enc->enc_pic.session_init.pre_encode_chroma_enabled = false; + + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_SESSION_INIT); + RADEON_ENC_CS(enc->enc_pic.session_init.encode_standard); + RADEON_ENC_CS(enc->enc_pic.session_init.aligned_picture_width); + RADEON_ENC_CS(enc->enc_pic.session_init.aligned_picture_height); + RADEON_ENC_CS(enc->enc_pic.session_init.padding_width); + RADEON_ENC_CS(enc->enc_pic.session_init.padding_height); + RADEON_ENC_CS(enc->enc_pic.session_init.pre_encode_mode); + RADEON_ENC_CS(enc->enc_pic.session_init.pre_encode_chroma_enabled); + RADEON_ENC_END(); +} + static void radeon_enc_layer_control(struct radeon_encoder *enc) { enc->enc_pic.layer_ctrl.max_num_temporal_layers = 1; @@ -262,6 +283,19 @@ static void radeon_enc_slice_control(struct radeon_encoder *enc) RADEON_ENC_END(); } +static void radeon_enc_slice_control_hevc(struct radeon_encoder *enc) +{ + enc->enc_pic.hevc_slice_ctrl.slice_control_mode = RENCODE_HEVC_SLICE_CONTROL_MODE_FIXED_CTBS; + enc->enc_pic.hevc_slice_ctrl.fixed_ctbs_per_slice.num_ctbs_per_slice = align(enc->base.width, 64) / 64 * align(enc->base.height, 64) / 64; + enc->enc_pic.hevc_slice_ctrl.fixed_ctbs_per_slice.num_ctbs_per_slice_segment = enc->enc_pic.hevc_slice_ctrl.fixed_ctbs_per_slice.num_ctbs_per_slice; + + RADEON_ENC_BEGIN(RENCODE_HEVC_IB_PARAM_SLICE_CONTROL); + RADEON_ENC_CS(enc->enc_pic.hevc_slice_ctrl.slice_control_mode); + RADEON_ENC_CS(enc->enc_pic.hevc_slice_ctrl.fixed_ctbs_per_slice.num_ctbs_per_slice); + RADEON_ENC_CS(enc->enc_pic.hevc_slice_ctrl.fixed_ctbs_per_slice.num_ctbs_per_slice_segment); + RADEON_ENC_END(); +} + static void radeon_enc_spec_misc(struct radeon_encoder *enc) { enc->enc_pic.spec_misc.constrained_intra_pred_flag = 0; @@ -283,27 +317,68 @@ static void radeon_enc_spec_misc(struct radeon_encoder *enc) RADEON_ENC_END(); } +static void radeon_enc_spec_misc_hevc(struct radeon_encoder *enc, struct pipe_picture_desc *picture) +{ + struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture; + enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3 = pic->seq.log2_min_luma_coding_block_size_minus3; + enc->enc_pic.hevc_spec_misc.amp_disabled = !pic->seq.amp_enabled_flag; + enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled = pic->seq.strong_intra_smoothing_enabled_flag; + enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag = pic->pic.constrained_intra_pred_flag; + enc->enc_pic.hevc_spec_misc.cabac_init_flag = pic->slice.cabac_init_flag; + enc->enc_pic.hevc_spec_misc.half_pel_enabled = 1; + enc->enc_pic.hevc_spec_misc.quarter_pel_enabled = 1; + + RADEON_ENC_BEGIN(RENCODE_HEVC_IB_PARAM_SPEC_MISC); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.amp_disabled); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.cabac_init_flag); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.half_pel_enabled); + RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.quarter_pel_enabled); + RADEON_ENC_END(); +} + static void radeon_enc_rc_session_init(struct radeon_encoder *enc, struct pipe_picture_desc *picture) { - struct pipe_h264_enc_picture_desc *pic = (struct pipe_h264_enc_picture_desc *)picture; - switch(pic->rate_ctrl.rate_ctrl_method) { - case PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABL
[Mesa-dev] [PATCH 01/12] vl: add parameters for HEVC encode
From: Boyuan Zhang Add HEVC encode interface Signed-off-by: Boyuan Zhang --- src/gallium/include/pipe/p_video_state.h | 100 +++ 1 file changed, 100 insertions(+) diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 5a88e6c..26e0acf 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -120,6 +120,15 @@ enum pipe_h264_enc_picture_type PIPE_H264_ENC_PICTURE_TYPE_SKIP = 0x04 }; +enum pipe_h265_enc_picture_type +{ + PIPE_H265_ENC_PICTURE_TYPE_P = 0x00, + PIPE_H265_ENC_PICTURE_TYPE_B = 0x01, + PIPE_H265_ENC_PICTURE_TYPE_I = 0x02, + PIPE_H265_ENC_PICTURE_TYPE_IDR = 0x03, + PIPE_H265_ENC_PICTURE_TYPE_SKIP = 0x04 +}; + enum pipe_h264_enc_rate_control_method { PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE = 0x00, @@ -129,6 +138,15 @@ enum pipe_h264_enc_rate_control_method PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE = 0x04 }; +enum pipe_h265_enc_rate_control_method +{ + PIPE_H265_ENC_RATE_CONTROL_METHOD_DISABLE = 0x00, + PIPE_H265_ENC_RATE_CONTROL_METHOD_CONSTANT_SKIP = 0x01, + PIPE_H265_ENC_RATE_CONTROL_METHOD_VARIABLE_SKIP = 0x02, + PIPE_H265_ENC_RATE_CONTROL_METHOD_CONSTANT = 0x03, + PIPE_H265_ENC_RATE_CONTROL_METHOD_VARIABLE = 0x04 +}; + struct pipe_picture_desc { enum pipe_video_profile profile; @@ -412,6 +430,88 @@ struct pipe_h264_enc_picture_desc }; +struct pipe_h265_enc_seq_param +{ + uint8_t general_profile_idc; + uint8_t general_level_idc; + uint8_t general_tier_flag; + uint32_t intra_period; + uint16_t pic_width_in_luma_samples; + uint16_t pic_height_in_luma_samples; + uint32_t chroma_format_idc; + uint32_t bit_depth_luma_minus8; + uint32_t bit_depth_chroma_minus8; + bool strong_intra_smoothing_enabled_flag; + bool amp_enabled_flag; + bool sample_adaptive_offset_enabled_flag; + bool pcm_enabled_flag; + bool sps_temporal_mvp_enabled_flag; + uint8_t log2_min_luma_coding_block_size_minus3; + uint8_t log2_diff_max_min_luma_coding_block_size; + uint8_t log2_min_transform_block_size_minus2; + uint8_t log2_diff_max_min_transform_block_size; + uint8_t max_transform_hierarchy_depth_inter; + uint8_t max_transform_hierarchy_depth_intra; +}; + +struct pipe_h265_enc_pic_param +{ + uint8_t log2_parallel_merge_level_minus2; + uint8_t nal_unit_type; + bool constrained_intra_pred_flag; + bool loop_filter_across_tiles_enabled_flag; +}; + +struct pipe_h265_enc_slice_param +{ + uint8_t max_num_merge_cand; + int8_t slice_cb_qp_offset; + int8_t slice_cr_qp_offset; + int8_t slice_beta_offset_div2; + int8_t slice_tc_offset_div2; + bool cabac_init_flag; + uint32_t slice_deblocking_filter_disabled_flag; + bool slice_loop_filter_across_slices_enabled_flag; +}; + +struct pipe_h265_enc_rate_control +{ + enum pipe_h265_enc_rate_control_method rate_ctrl_method; + unsigned target_bitrate; + unsigned peak_bitrate; + unsigned frame_rate_num; + unsigned frame_rate_den; + unsigned quant_i_frames; + unsigned vbv_buffer_size; + unsigned vbv_buf_lv; + unsigned target_bits_picture; + unsigned peak_bits_picture_integer; + unsigned peak_bits_picture_fraction; + unsigned fill_data_enable; + unsigned enforce_hrd; +}; + +struct pipe_h265_enc_picture_desc +{ + struct pipe_picture_desc base; + + struct pipe_h265_enc_seq_param seq; + struct pipe_h265_enc_pic_param pic; + struct pipe_h265_enc_slice_param slice; + struct pipe_h265_enc_rate_control rc; + + enum pipe_h265_enc_picture_type picture_type; + unsigned decoded_curr_pic; + unsigned reference_frames[16]; + unsigned frame_num; + unsigned pic_order_cnt; + unsigned pic_order_cnt_type; + unsigned ref_idx_l0; + unsigned ref_idx_l1; + bool not_referenced; + struct util_hash_table *frame_idx; +}; + struct pipe_h265_sps { uint8_t chroma_format_idc; -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 07/12] st/va: add HEVC picture desc
From: Boyuan Zhang Add HEVC picture desc, and add codec check when creating and destroying context. Signed-off-by: Boyuan Zhang --- src/gallium/state_trackers/va/context.c| 26 ++ src/gallium/state_trackers/va/va_private.h | 1 + 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index 78e1f19..f03b326 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -284,8 +284,18 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, context->desc.base.profile = config->profile; context->desc.base.entry_point = config->entrypoint; if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { - context->desc.h264enc.rate_ctrl.rate_ctrl_method = config->rc; - context->desc.h264enc.frame_idx = util_hash_table_create(handle_hash, handle_compare); + switch (u_reduce_video_profile(context->templat.profile)) { + case PIPE_VIDEO_FORMAT_MPEG4_AVC: + context->desc.h264enc.rate_ctrl.rate_ctrl_method = config->rc; + context->desc.h264enc.frame_idx = util_hash_table_create(handle_hash, handle_compare); + break; + case PIPE_VIDEO_FORMAT_HEVC: + context->desc.h265enc.rc.rate_ctrl_method = config->rc; + context->desc.h265enc.frame_idx = util_hash_table_create(handle_hash, handle_compare); + break; + default: + break; + } } mtx_lock(&drv->mutex); @@ -314,8 +324,16 @@ vlVaDestroyContext(VADriverContextP ctx, VAContextID context_id) if (context->decoder) { if (context->desc.base.entry_point == PIPE_VIDEO_ENTRYPOINT_ENCODE) { - if (context->desc.h264enc.frame_idx) -util_hash_table_destroy (context->desc.h264enc.frame_idx); + if (u_reduce_video_profile(context->decoder->profile) == + PIPE_VIDEO_FORMAT_MPEG4_AVC) { +if (context->desc.h264enc.frame_idx) + util_hash_table_destroy (context->desc.h264enc.frame_idx); + } + if (u_reduce_video_profile(context->decoder->profile) == + PIPE_VIDEO_FORMAT_HEVC) { +if (context->desc.h265enc.frame_idx) + util_hash_table_destroy (context->desc.h265enc.frame_idx); + } } else { if (u_reduce_video_profile(context->decoder->profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index 520f970..c022feb 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -270,6 +270,7 @@ typedef struct { struct pipe_h265_picture_desc h265; struct pipe_mjpeg_picture_desc mjpeg; struct pipe_h264_enc_picture_desc h264enc; + struct pipe_h265_enc_picture_desc h265enc; } desc; struct { -- 2.7.4 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 05/12] radeon/vcn: add header implementations for HEVC
From: Boyuan Zhang Implement encoding of sps, pps, vps, aud, and slice headers for HEVC based on HEVC specs. Signed-off-by: Boyuan Zhang --- src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c | 348 +++- 1 file changed, 347 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c index a651f7e..74c4a08 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c +++ b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c @@ -551,6 +551,86 @@ static void radeon_enc_nalu_sps(struct radeon_encoder *enc) RADEON_ENC_END(); } +static void radeon_enc_nalu_sps_hevc(struct radeon_encoder *enc) +{ + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU); + RADEON_ENC_CS(RENCODE_DIRECT_OUTPUT_NALU_TYPE_SPS); + uint32_t *size_in_bytes = &enc->cs->current.buf[enc->cs->current.cdw++]; + int i; + + radeon_enc_reset(enc); + radeon_enc_set_emulation_prevention(enc, false); + radeon_enc_code_fixed_bits(enc, 0x0001, 32); + radeon_enc_code_fixed_bits(enc, 0x4201, 16); + radeon_enc_byte_align(enc); + radeon_enc_set_emulation_prevention(enc, true); + radeon_enc_code_fixed_bits(enc, 0x0, 4); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1, 3); + radeon_enc_code_fixed_bits(enc, 0x1, 1); + radeon_enc_code_fixed_bits(enc, 0x0, 2); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.general_tier_flag, 1); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.general_profile_idc, 5); + radeon_enc_code_fixed_bits(enc, 0x6000, 32); + radeon_enc_code_fixed_bits(enc, 0xb000, 32); + radeon_enc_code_fixed_bits(enc, 0x0, 16); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.general_level_idc, 8); + + for (i = 0; i < (enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1) ; i++) + radeon_enc_code_fixed_bits(enc, 0x0, 2); + + if ((enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1) > 0) { + for (i = (enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1); i < 8; i++) + radeon_enc_code_fixed_bits(enc, 0x0, 2); + } + + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, enc->enc_pic.chroma_format_idc); + radeon_enc_code_ue(enc, enc->enc_pic.pic_width_in_luma_samples); + radeon_enc_code_ue(enc, enc->enc_pic.pic_height_in_luma_samples); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_ue(enc, enc->enc_pic.bit_depth_luma_minus8); + radeon_enc_code_ue(enc, enc->enc_pic.bit_depth_chroma_minus8); + radeon_enc_code_ue(enc, enc->enc_pic.log2_max_poc - 4); + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_ue(enc, 1); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, 0x0); + radeon_enc_code_ue(enc, enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3); + //Only support CTBSize 64 + radeon_enc_code_ue(enc, 6 - (enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3 + 3)); + radeon_enc_code_ue(enc, enc->enc_pic.log2_min_transform_block_size_minus2); + radeon_enc_code_ue(enc, enc->enc_pic.log2_diff_max_min_transform_block_size); + radeon_enc_code_ue(enc, enc->enc_pic.max_transform_hierarchy_depth_inter); + radeon_enc_code_ue(enc, enc->enc_pic.max_transform_hierarchy_depth_intra); + + radeon_enc_code_fixed_bits(enc, 0x0, 1); + radeon_enc_code_fixed_bits(enc, !enc->enc_pic.hevc_spec_misc.amp_disabled, 1); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.sample_adaptive_offset_enabled_flag, 1); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.pcm_enabled_flag, 1); + + radeon_enc_code_ue(enc, 1); + radeon_enc_code_ue(enc, 1); + radeon_enc_code_ue(enc, 0); + radeon_enc_code_ue(enc, 0); + radeon_enc_code_fixed_bits(enc, 0x1, 1); + + radeon_enc_code_fixed_bits(enc, 0x0, 1); + + radeon_enc_code_fixed_bits(enc, 0, 1); + radeon_enc_code_fixed_bits(enc, enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled, 1); + + radeon_enc_code_fixed_bits(enc, 0x0, 1); + + radeon_enc_code_fixed_bits(enc, 0x0, 1); + + radeon_enc_code_fixed_bits(enc, 0x1, 1); + + radeon_enc_byte_align(enc); + radeon_enc_flush_headers(enc); + *size_in_bytes = (enc->bits_output + 7) / 8; + RADEON_ENC_END(); +} + static void radeon_enc_nalu_pps(struct radeon_encoder *enc) { RADEON_ENC_BEGIN(RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU); @@ -586,6 +666,150 @@ static void radeon_enc_nalu_pps(struct radeon_encoder *enc) RADEON_ENC_END(); } +static void radeon_enc_nalu_pps_hevc(struct radeon_encoder *enc) +{ + RADEON_ENC_BEGIN(RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU); + RADEON_ENC_CS(RENCODE_DIRECT_OUTPUT_NALU_TYPE_PPS); + uint32_t *size_in_bytes = &enc->cs->