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;
|
value = VA_RC_CQP | VA_RC_CBR | VA_RC_VBR;
|
||||||
break;
|
break;
|
||||||
case VAConfigAttribEncPackedHeaders:
|
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;
|
break;
|
||||||
case VAConfigAttribEncMaxRefFrames:
|
case VAConfigAttribEncMaxRefFrames:
|
||||||
value = 1;
|
value = 1;
|
||||||
|
|
|
@ -466,6 +466,48 @@ handleVAEncSliceParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaB
|
||||||
return status;
|
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
|
VAStatus
|
||||||
vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buffers, int num_buffers)
|
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);
|
vlVaHandleHuffmanTableBufferType(context, buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VAEncPackedHeaderParameterBufferType:
|
||||||
|
handleVAEncPackedHeaderParameterBufferType(context, buf);
|
||||||
|
break;
|
||||||
|
case VAEncPackedHeaderDataBufferType:
|
||||||
|
handleVAEncPackedHeaderDataBufferType(context, buf);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,15 @@
|
||||||
#include "util/u_video.h"
|
#include "util/u_video.h"
|
||||||
#include "va_private.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
|
VAStatus
|
||||||
vlVaHandleVAEncPictureParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
|
vlVaHandleVAEncPictureParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
|
||||||
{
|
{
|
||||||
|
@ -188,6 +197,128 @@ vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(vlVaContext *context, VAEncMiscPar
|
||||||
return VA_STATUS_SUCCESS;
|
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)
|
void getEncParamPresetH265(vlVaContext *context)
|
||||||
{
|
{
|
||||||
//rate control
|
//rate control
|
||||||
|
|
|
@ -308,6 +308,7 @@ typedef struct {
|
||||||
int gop_coeff;
|
int gop_coeff;
|
||||||
bool needs_begin_frame;
|
bool needs_begin_frame;
|
||||||
void *blit_cs;
|
void *blit_cs;
|
||||||
|
int packed_header_type;
|
||||||
} vlVaContext;
|
} vlVaContext;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -459,5 +460,5 @@ VAStatus vlVaHandleVAEncSliceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContex
|
||||||
VAStatus vlVaHandleVAEncSequenceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);
|
VAStatus vlVaHandleVAEncSequenceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);
|
||||||
VAStatus vlVaHandleVAEncMiscParameterTypeRateControlHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf);
|
VAStatus vlVaHandleVAEncMiscParameterTypeRateControlHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf);
|
||||||
VAStatus vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf);
|
VAStatus vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf);
|
||||||
|
VAStatus vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(vlVaContext *context, vlVaBuffer *buf);
|
||||||
#endif //VA_PRIVATE_H
|
#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 log2_diff_max_min_transform_block_size;
|
||||||
uint8_t max_transform_hierarchy_depth_inter;
|
uint8_t max_transform_hierarchy_depth_inter;
|
||||||
uint8_t max_transform_hierarchy_depth_intra;
|
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
|
struct pipe_h265_enc_pic_param
|
||||||
|
|
Loading…
Reference in New Issue