gallium: Parse packed HEVC SPS encode header for crop parameters
The crop / conformance window parameters are set by ffmpeg but they only seem to be made available in packed headers. This commit copies the H265 header parsing code from st/omx (planning in the future to move this code to a common place to be shared by the different state trackers) in order to grab the crop parameters Signed-off-by: Thong Thai <thong.thai@amd.com> Reviewed-by: Leo Liu <leo.liu@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4184>
This commit is contained in:
parent
0a3f92bcc6
commit
245f619411
|
@ -157,7 +157,9 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en
|
|||
value = VA_RC_CQP | VA_RC_CBR | VA_RC_VBR;
|
||||
break;
|
||||
case VAConfigAttribEncPackedHeaders:
|
||||
value = 0;
|
||||
value = VA_ENC_PACKED_HEADER_NONE;
|
||||
if (u_reduce_video_profile(ProfileToPipe(profile)) == PIPE_VIDEO_FORMAT_HEVC)
|
||||
value |= VA_ENC_PACKED_HEADER_SEQUENCE;
|
||||
break;
|
||||
case VAConfigAttribEncMaxRefFrames:
|
||||
value = 1;
|
||||
|
|
|
@ -466,6 +466,48 @@ handleVAEncSliceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaB
|
|||
return status;
|
||||
}
|
||||
|
||||
static VAStatus
|
||||
handleVAEncPackedHeaderParameterBufferType(vlVaContext *context, vlVaBuffer *buf)
|
||||
{
|
||||
VAStatus status = VA_STATUS_SUCCESS;
|
||||
|
||||
switch (u_reduce_video_profile(context->templat.profile)) {
|
||||
case PIPE_VIDEO_FORMAT_HEVC:
|
||||
break;
|
||||
|
||||
default:
|
||||
return VA_STATUS_ERROR_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)buf->data;
|
||||
if (param->type == VAEncPackedHeaderSequence)
|
||||
context->packed_header_type = param->type;
|
||||
else
|
||||
status = VA_STATUS_ERROR_UNIMPLEMENTED;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static VAStatus
|
||||
handleVAEncPackedHeaderDataBufferType(vlVaContext *context, vlVaBuffer *buf)
|
||||
{
|
||||
VAStatus status = VA_STATUS_SUCCESS;
|
||||
|
||||
if (context->packed_header_type != VAEncPackedHeaderSequence)
|
||||
return VA_STATUS_ERROR_UNIMPLEMENTED;
|
||||
|
||||
switch (u_reduce_video_profile(context->templat.profile)) {
|
||||
case PIPE_VIDEO_FORMAT_HEVC:
|
||||
status = vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(context, buf);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
VAStatus
|
||||
vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buffers, int num_buffers)
|
||||
{
|
||||
|
@ -536,6 +578,13 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff
|
|||
vlVaHandleHuffmanTableBufferType(context, buf);
|
||||
break;
|
||||
|
||||
case VAEncPackedHeaderParameterBufferType:
|
||||
handleVAEncPackedHeaderParameterBufferType(context, buf);
|
||||
break;
|
||||
case VAEncPackedHeaderDataBufferType:
|
||||
handleVAEncPackedHeaderDataBufferType(context, buf);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,15 @@
|
|||
#include "util/u_video.h"
|
||||
#include "va_private.h"
|
||||
|
||||
#include "vl/vl_vlc.h"
|
||||
#include "vl/vl_rbsp.h"
|
||||
|
||||
enum HEVCNALUnitType {
|
||||
HEVC_NAL_VPS = 32,
|
||||
HEVC_NAL_SPS = 33,
|
||||
HEVC_NAL_PPS = 34,
|
||||
};
|
||||
|
||||
VAStatus
|
||||
vlVaHandleVAEncPictureParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
|
||||
{
|
||||
|
@ -188,6 +197,128 @@ vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(vlVaContext *context, VAEncMiscPar
|
|||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void profile_tier(struct vl_rbsp *rbsp)
|
||||
{
|
||||
vl_rbsp_u(rbsp, 2); /* general_profile_space */
|
||||
vl_rbsp_u(rbsp, 1); /* general_tier_flag */
|
||||
vl_rbsp_u(rbsp, 5); /* general_profile_idc */
|
||||
|
||||
/* general_profile_compatibility_flag */
|
||||
for(int i = 0; i < 32; ++i)
|
||||
vl_rbsp_u(rbsp, 1);
|
||||
|
||||
vl_rbsp_u(rbsp, 1); /* general_progressive_source_flag */
|
||||
vl_rbsp_u(rbsp, 1); /* general_interlaced_source_flag */
|
||||
vl_rbsp_u(rbsp, 1); /* general_non_packed_constraint_flag */
|
||||
vl_rbsp_u(rbsp, 1); /* general_frame_only_constraint_flag */
|
||||
|
||||
/* general_reserved_zero_44bits */
|
||||
vl_rbsp_u(rbsp, 16);
|
||||
vl_rbsp_u(rbsp, 16);
|
||||
vl_rbsp_u(rbsp, 12);
|
||||
}
|
||||
|
||||
static unsigned profile_tier_level(struct vl_rbsp *rbsp,
|
||||
int max_sublayers_minus1)
|
||||
{
|
||||
bool sub_layer_profile_present_flag[6];
|
||||
bool sub_layer_level_present_flag[6];
|
||||
unsigned level_idc;
|
||||
int i;
|
||||
|
||||
profile_tier(rbsp);
|
||||
level_idc = vl_rbsp_u(rbsp, 8); /* general_level_idc */
|
||||
|
||||
for (i = 0; i < max_sublayers_minus1; ++i) {
|
||||
sub_layer_profile_present_flag[i] = vl_rbsp_u(rbsp, 1);
|
||||
sub_layer_level_present_flag[i] = vl_rbsp_u(rbsp, 1);
|
||||
}
|
||||
|
||||
if (max_sublayers_minus1 > 0)
|
||||
for (i = max_sublayers_minus1; i < 8; ++i)
|
||||
vl_rbsp_u(rbsp, 2); /* reserved_zero_2bits */
|
||||
|
||||
for (i = 0; i < max_sublayers_minus1; ++i) {
|
||||
if (sub_layer_profile_present_flag[i])
|
||||
profile_tier(rbsp);
|
||||
|
||||
if (sub_layer_level_present_flag[i])
|
||||
vl_rbsp_u(rbsp, 8); /* sub_layer_level_idc */
|
||||
}
|
||||
|
||||
return level_idc;
|
||||
}
|
||||
|
||||
static void parseEncSpsParamsH265(vlVaContext *context, struct vl_rbsp *rbsp)
|
||||
{
|
||||
int sps_max_sub_layers_minus1;
|
||||
|
||||
vl_rbsp_u(rbsp, 4); /* sps_video_parameter_set_id */
|
||||
sps_max_sub_layers_minus1 = vl_rbsp_u(rbsp, 3);
|
||||
vl_rbsp_u(rbsp, 1); /* sps_temporal_id_nesting_flag */
|
||||
|
||||
/* level_idc */
|
||||
profile_tier_level(rbsp, sps_max_sub_layers_minus1);
|
||||
|
||||
vl_rbsp_ue(rbsp); /* id */
|
||||
context->desc.h265enc.seq.chroma_format_idc = vl_rbsp_ue(rbsp);
|
||||
if (context->desc.h265enc.seq.chroma_format_idc == 3)
|
||||
vl_rbsp_u(rbsp, 1); /* separate_colour_plane_flag */
|
||||
|
||||
context->desc.h265enc.seq.pic_width_in_luma_samples = vl_rbsp_ue(rbsp);
|
||||
context->desc.h265enc.seq.pic_height_in_luma_samples = vl_rbsp_ue(rbsp);
|
||||
|
||||
/* conformance_window_flag - used for cropping */
|
||||
context->desc.h265enc.seq.conformance_window_flag = vl_rbsp_u(rbsp, 1);
|
||||
if (context->desc.h265enc.seq.conformance_window_flag) {
|
||||
context->desc.h265enc.seq.conf_win_left_offset = vl_rbsp_ue(rbsp);
|
||||
context->desc.h265enc.seq.conf_win_right_offset = vl_rbsp_ue(rbsp);
|
||||
context->desc.h265enc.seq.conf_win_top_offset = vl_rbsp_ue(rbsp);
|
||||
context->desc.h265enc.seq.conf_win_bottom_offset = vl_rbsp_ue(rbsp);
|
||||
}
|
||||
}
|
||||
|
||||
VAStatus
|
||||
vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(vlVaContext *context, vlVaBuffer *buf)
|
||||
{
|
||||
struct vl_vlc vlc = {0};
|
||||
vl_vlc_init(&vlc, 1, (const void * const*)&buf->data, &buf->size);
|
||||
|
||||
while (vl_vlc_bits_left(&vlc) > 0) {
|
||||
/* search the first 64 bytes for a startcode */
|
||||
for (int i = 0; i < 64 && vl_vlc_bits_left(&vlc) >= 24; ++i) {
|
||||
if (vl_vlc_peekbits(&vlc, 24) == 0x000001)
|
||||
break;
|
||||
vl_vlc_eatbits(&vlc, 8);
|
||||
vl_vlc_fillbits(&vlc);
|
||||
}
|
||||
vl_vlc_eatbits(&vlc, 24); /* eat the startcode */
|
||||
|
||||
if (vl_vlc_valid_bits(&vlc) < 15)
|
||||
vl_vlc_fillbits(&vlc);
|
||||
|
||||
vl_vlc_eatbits(&vlc, 1);
|
||||
unsigned nal_unit_type = vl_vlc_get_uimsbf(&vlc, 6);
|
||||
vl_vlc_eatbits(&vlc, 6);
|
||||
vl_vlc_eatbits(&vlc, 3);
|
||||
|
||||
struct vl_rbsp rbsp;
|
||||
vl_rbsp_init(&rbsp, &vlc, ~0);
|
||||
|
||||
switch(nal_unit_type) {
|
||||
case HEVC_NAL_SPS:
|
||||
parseEncSpsParamsH265(context, &rbsp);
|
||||
break;
|
||||
case HEVC_NAL_VPS:
|
||||
case HEVC_NAL_PPS:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void getEncParamPresetH265(vlVaContext *context)
|
||||
{
|
||||
//rate control
|
||||
|
|
|
@ -308,6 +308,7 @@ typedef struct {
|
|||
int gop_coeff;
|
||||
bool needs_begin_frame;
|
||||
void *blit_cs;
|
||||
int packed_header_type;
|
||||
} vlVaContext;
|
||||
|
||||
typedef struct {
|
||||
|
@ -459,5 +460,5 @@ VAStatus vlVaHandleVAEncSliceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContex
|
|||
VAStatus vlVaHandleVAEncSequenceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);
|
||||
VAStatus vlVaHandleVAEncMiscParameterTypeRateControlHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf);
|
||||
VAStatus vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf);
|
||||
|
||||
VAStatus vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(vlVaContext *context, vlVaBuffer *buf);
|
||||
#endif //VA_PRIVATE_H
|
||||
|
|
|
@ -457,6 +457,11 @@ struct pipe_h265_enc_seq_param
|
|||
uint8_t log2_diff_max_min_transform_block_size;
|
||||
uint8_t max_transform_hierarchy_depth_inter;
|
||||
uint8_t max_transform_hierarchy_depth_intra;
|
||||
uint8_t conformance_window_flag;
|
||||
uint16_t conf_win_left_offset;
|
||||
uint16_t conf_win_right_offset;
|
||||
uint16_t conf_win_top_offset;
|
||||
uint16_t conf_win_bottom_offset;
|
||||
};
|
||||
|
||||
struct pipe_h265_enc_pic_param
|
||||
|
|
Loading…
Reference in New Issue