You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
avcodec/cbs_h2645: fix parsing and storing Picture Header references in the context
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
@@ -525,12 +525,6 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx,
|
|||||||
if (frag->data_size == 0)
|
if (frag->data_size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (codec_id == AV_CODEC_ID_VVC) {
|
|
||||||
//we deactive picture header here to avoid reuse previous au's ph.
|
|
||||||
CodedBitstreamH266Context *h266 = ctx->priv_data;
|
|
||||||
h266->priv.ph = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (header && frag->data[0] && codec_id == AV_CODEC_ID_H264) {
|
if (header && frag->data[0] && codec_id == AV_CODEC_ID_H264) {
|
||||||
// AVCC header.
|
// AVCC header.
|
||||||
size_t size, start, end;
|
size_t size, start, end;
|
||||||
@@ -793,19 +787,20 @@ cbs_h266_replace_ps(6, SPS, sps, sps_seq_parameter_set_id)
|
|||||||
cbs_h266_replace_ps(6, PPS, pps, pps_pic_parameter_set_id)
|
cbs_h266_replace_ps(6, PPS, pps, pps_pic_parameter_set_id)
|
||||||
|
|
||||||
static int cbs_h266_replace_ph(CodedBitstreamContext *ctx,
|
static int cbs_h266_replace_ph(CodedBitstreamContext *ctx,
|
||||||
CodedBitstreamUnit *unit)
|
CodedBitstreamUnit *unit,
|
||||||
|
H266RawPictureHeader *ph)
|
||||||
{
|
{
|
||||||
CodedBitstreamH266Context *h266 = ctx->priv_data;
|
CodedBitstreamH266Context *h266 = ctx->priv_data;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
h266->priv.ph = NULL;
|
|
||||||
err = ff_cbs_make_unit_refcounted(ctx, unit);
|
err = ff_cbs_make_unit_refcounted(ctx, unit);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
err = av_buffer_replace(&h266->priv.ph_ref, unit->content_ref);
|
av_assert0(unit->content_ref);
|
||||||
|
err = av_buffer_replace(&h266->ph_ref, unit->content_ref);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
h266->priv.ph = (H266RawPH*)h266->priv.ph_ref->data;
|
h266->ph = ph;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1111,7 +1106,7 @@ static int cbs_h266_read_nal_unit(CodedBitstreamContext *ctx,
|
|||||||
err = cbs_h266_read_ph(ctx, &gbc, ph);
|
err = cbs_h266_read_ph(ctx, &gbc, ph);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
err = cbs_h266_replace_ph(ctx, unit);
|
err = cbs_h266_replace_ph(ctx, unit, &ph->ph_picture_header);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -1139,6 +1134,12 @@ static int cbs_h266_read_nal_unit(CodedBitstreamContext *ctx,
|
|||||||
pos = get_bits_count(&gbc);
|
pos = get_bits_count(&gbc);
|
||||||
len = unit->data_size;
|
len = unit->data_size;
|
||||||
|
|
||||||
|
if (slice->header.sh_picture_header_in_slice_header_flag) {
|
||||||
|
err = cbs_h266_replace_ph(ctx, unit, &slice->header.sh_picture_header);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
slice->data_size = len - pos / 8;
|
slice->data_size = len - pos / 8;
|
||||||
slice->data_ref = av_buffer_ref(unit->data_ref);
|
slice->data_ref = av_buffer_ref(unit->data_ref);
|
||||||
if (!slice->data_ref)
|
if (!slice->data_ref)
|
||||||
@@ -1640,7 +1641,7 @@ static int cbs_h266_write_nal_unit(CodedBitstreamContext *ctx,
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = cbs_h266_replace_ph(ctx, unit);
|
err = cbs_h266_replace_ph(ctx, unit, &ph->ph_picture_header);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -1661,6 +1662,12 @@ static int cbs_h266_write_nal_unit(CodedBitstreamContext *ctx,
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
if (slice->header.sh_picture_header_in_slice_header_flag) {
|
||||||
|
err = cbs_h266_replace_ph(ctx, unit, &slice->header.sh_picture_header);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (slice->data) {
|
if (slice->data) {
|
||||||
err = cbs_h2645_write_slice_data(ctx, pbc, slice->data,
|
err = cbs_h2645_write_slice_data(ctx, pbc, slice->data,
|
||||||
slice->data_size,
|
slice->data_size,
|
||||||
@@ -1884,8 +1891,8 @@ static void cbs_h266_flush(CodedBitstreamContext *ctx)
|
|||||||
av_buffer_unref(&h266->pps_ref[i]);
|
av_buffer_unref(&h266->pps_ref[i]);
|
||||||
h266->pps[i] = NULL;
|
h266->pps[i] = NULL;
|
||||||
}
|
}
|
||||||
av_buffer_unref(&h266->priv.ph_ref);
|
av_buffer_unref(&h266->ph_ref);
|
||||||
h266->priv.ph = NULL;
|
h266->ph = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cbs_h266_close(CodedBitstreamContext *ctx)
|
static void cbs_h266_close(CodedBitstreamContext *ctx)
|
||||||
|
@@ -581,8 +581,7 @@ typedef struct H266RawPredWeightTable {
|
|||||||
int16_t delta_chroma_offset_l1[15][2];
|
int16_t delta_chroma_offset_l1[15][2];
|
||||||
} H266RawPredWeightTable;
|
} H266RawPredWeightTable;
|
||||||
|
|
||||||
typedef struct H266RawPH {
|
typedef struct H266RawPictureHeader {
|
||||||
H266RawNALUnitHeader nal_unit_header;
|
|
||||||
uint8_t ph_gdr_or_irap_pic_flag;
|
uint8_t ph_gdr_or_irap_pic_flag;
|
||||||
uint8_t ph_non_ref_pic_flag;
|
uint8_t ph_non_ref_pic_flag;
|
||||||
uint8_t ph_gdr_pic_flag;
|
uint8_t ph_gdr_pic_flag;
|
||||||
@@ -670,12 +669,17 @@ typedef struct H266RawPH {
|
|||||||
|
|
||||||
uint8_t ph_extension_length;
|
uint8_t ph_extension_length;
|
||||||
uint8_t ph_extension_data_byte[256];
|
uint8_t ph_extension_data_byte[256];
|
||||||
|
} H266RawPictureHeader;
|
||||||
|
|
||||||
|
typedef struct H266RawPH {
|
||||||
|
H266RawNALUnitHeader nal_unit_header;
|
||||||
|
H266RawPictureHeader ph_picture_header;
|
||||||
} H266RawPH;
|
} H266RawPH;
|
||||||
|
|
||||||
typedef struct H266RawSliceHeader {
|
typedef struct H266RawSliceHeader {
|
||||||
H266RawNALUnitHeader nal_unit_header;
|
H266RawNALUnitHeader nal_unit_header;
|
||||||
uint8_t sh_picture_header_in_slice_header_flag;
|
uint8_t sh_picture_header_in_slice_header_flag;
|
||||||
H266RawPH sh_picture_header;
|
H266RawPictureHeader sh_picture_header;
|
||||||
|
|
||||||
uint16_t sh_subpic_id;
|
uint16_t sh_subpic_id;
|
||||||
uint16_t sh_slice_address;
|
uint16_t sh_slice_address;
|
||||||
@@ -770,14 +774,11 @@ typedef struct CodedBitstreamH266Context {
|
|||||||
AVBufferRef *vps_ref[VVC_MAX_VPS_COUNT];
|
AVBufferRef *vps_ref[VVC_MAX_VPS_COUNT];
|
||||||
AVBufferRef *sps_ref[VVC_MAX_SPS_COUNT];
|
AVBufferRef *sps_ref[VVC_MAX_SPS_COUNT];
|
||||||
AVBufferRef *pps_ref[VVC_MAX_PPS_COUNT];
|
AVBufferRef *pps_ref[VVC_MAX_PPS_COUNT];
|
||||||
|
AVBufferRef *ph_ref;
|
||||||
H266RawVPS *vps[VVC_MAX_SPS_COUNT];
|
H266RawVPS *vps[VVC_MAX_SPS_COUNT];
|
||||||
H266RawSPS *sps[VVC_MAX_SPS_COUNT];
|
H266RawSPS *sps[VVC_MAX_SPS_COUNT];
|
||||||
H266RawPPS *pps[VVC_MAX_PPS_COUNT];
|
H266RawPPS *pps[VVC_MAX_PPS_COUNT];
|
||||||
|
H266RawPictureHeader *ph;
|
||||||
struct {
|
|
||||||
AVBufferRef *ph_ref;
|
|
||||||
H266RawPH *ph;
|
|
||||||
} priv;
|
|
||||||
} CodedBitstreamH266Context;
|
} CodedBitstreamH266Context;
|
||||||
|
|
||||||
#endif /* AVCODEC_CBS_H266_H */
|
#endif /* AVCODEC_CBS_H266_H */
|
||||||
|
@@ -2232,7 +2232,7 @@ static int FUNC(pred_weight_table) (CodedBitstreamContext *ctx, RWContext *rw,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int FUNC(picture_header) (CodedBitstreamContext *ctx, RWContext *rw,
|
static int FUNC(picture_header) (CodedBitstreamContext *ctx, RWContext *rw,
|
||||||
H266RawPH *current){
|
H266RawPictureHeader *current) {
|
||||||
CodedBitstreamH266Context *h266 = ctx->priv_data;
|
CodedBitstreamH266Context *h266 = ctx->priv_data;
|
||||||
const H266RawVPS *vps;
|
const H266RawVPS *vps;
|
||||||
const H266RawSPS *sps;
|
const H266RawSPS *sps;
|
||||||
@@ -2651,7 +2651,7 @@ static int FUNC(ph) (CodedBitstreamContext *ctx, RWContext *rw,
|
|||||||
HEADER("Picture Header");
|
HEADER("Picture Header");
|
||||||
|
|
||||||
CHECK(FUNC(nal_unit_header) (ctx, rw, ¤t->nal_unit_header, VVC_PH_NUT));
|
CHECK(FUNC(nal_unit_header) (ctx, rw, ¤t->nal_unit_header, VVC_PH_NUT));
|
||||||
CHECK(FUNC(picture_header) (ctx, rw, current));
|
CHECK(FUNC(picture_header) (ctx, rw, ¤t->ph_picture_header));
|
||||||
CHECK(FUNC(rbsp_trailing_bits) (ctx, rw));
|
CHECK(FUNC(rbsp_trailing_bits) (ctx, rw));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2662,7 +2662,7 @@ static int FUNC(slice_header) (CodedBitstreamContext *ctx, RWContext *rw,
|
|||||||
CodedBitstreamH266Context *h266 = ctx->priv_data;
|
CodedBitstreamH266Context *h266 = ctx->priv_data;
|
||||||
const H266RawSPS *sps;
|
const H266RawSPS *sps;
|
||||||
const H266RawPPS *pps;
|
const H266RawPPS *pps;
|
||||||
const H266RawPH *ph;
|
const H266RawPictureHeader *ph;
|
||||||
const H266RefPicLists *ref_pic_lists;
|
const H266RefPicLists *ref_pic_lists;
|
||||||
int err, i;
|
int err, i;
|
||||||
uint8_t nal_unit_type, qp_bd_offset;
|
uint8_t nal_unit_type, qp_bd_offset;
|
||||||
@@ -2675,12 +2675,11 @@ static int FUNC(slice_header) (CodedBitstreamContext *ctx, RWContext *rw,
|
|||||||
|
|
||||||
flag(sh_picture_header_in_slice_header_flag);
|
flag(sh_picture_header_in_slice_header_flag);
|
||||||
if (current->sh_picture_header_in_slice_header_flag) {
|
if (current->sh_picture_header_in_slice_header_flag) {
|
||||||
|
// 7.4.8 if sh_picture_header_in_slice_header_flag is true, we do not have a PH NAL unit
|
||||||
CHECK(FUNC(picture_header) (ctx, rw, ¤t->sh_picture_header));
|
CHECK(FUNC(picture_header) (ctx, rw, ¤t->sh_picture_header));
|
||||||
ph = ¤t->sh_picture_header;
|
ph = ¤t->sh_picture_header;
|
||||||
//7.4.8 if sh_picture_header_in_slice_header_flag is true, we do not have PH NAL unit
|
|
||||||
h266->priv.ph = NULL;
|
|
||||||
} else {
|
} else {
|
||||||
ph = h266->priv.ph;
|
ph = h266->ph;
|
||||||
if (!ph) {
|
if (!ph) {
|
||||||
av_log(ctx->log_ctx, AV_LOG_ERROR,
|
av_log(ctx->log_ctx, AV_LOG_ERROR,
|
||||||
"Picture header not available.\n");
|
"Picture header not available.\n");
|
||||||
@@ -2822,7 +2821,7 @@ static int FUNC(slice_header) (CodedBitstreamContext *ctx, RWContext *rw,
|
|||||||
(ctx, rw, sps, pps, ¤t->sh_ref_pic_lists));
|
(ctx, rw, sps, pps, ¤t->sh_ref_pic_lists));
|
||||||
ref_pic_lists = ¤t->sh_ref_pic_lists;
|
ref_pic_lists = ¤t->sh_ref_pic_lists;
|
||||||
} else {
|
} else {
|
||||||
ref_pic_lists = &h266->priv.ph->ph_ref_pic_lists;
|
ref_pic_lists = &ph->ph_ref_pic_lists;
|
||||||
}
|
}
|
||||||
if ((current->sh_slice_type != VVC_SLICE_TYPE_I &&
|
if ((current->sh_slice_type != VVC_SLICE_TYPE_I &&
|
||||||
ref_pic_lists->rpl_ref_list[0].num_ref_entries > 1) ||
|
ref_pic_lists->rpl_ref_list[0].num_ref_entries > 1) ||
|
||||||
|
@@ -48,7 +48,7 @@ static int h266_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt,
|
|||||||
ff_cbs_delete_unit(pu, 0);
|
ff_cbs_delete_unit(pu, 0);
|
||||||
} else if ( pkt && ctx->aud == BSF_ELEMENT_INSERT) {
|
} else if ( pkt && ctx->aud == BSF_ELEMENT_INSERT) {
|
||||||
const H266RawSlice *first_slice = NULL;
|
const H266RawSlice *first_slice = NULL;
|
||||||
const H266RawPH *ph = NULL;
|
const H266RawPictureHeader *ph = NULL;
|
||||||
H266RawAUD *aud = &ctx->aud_nal;
|
H266RawAUD *aud = &ctx->aud_nal;
|
||||||
int pic_type = 0, temporal_id = 8, layer_id = 0;
|
int pic_type = 0, temporal_id = 8, layer_id = 0;
|
||||||
for (i = 0; i < pu->nb_units; i++) {
|
for (i = 0; i < pu->nb_units; i++) {
|
||||||
@@ -58,7 +58,8 @@ static int h266_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt,
|
|||||||
if (nal->nuh_temporal_id_plus1 < temporal_id + 1)
|
if (nal->nuh_temporal_id_plus1 < temporal_id + 1)
|
||||||
temporal_id = nal->nuh_temporal_id_plus1 - 1;
|
temporal_id = nal->nuh_temporal_id_plus1 - 1;
|
||||||
if ( nal->nal_unit_type == VVC_PH_NUT ) {
|
if ( nal->nal_unit_type == VVC_PH_NUT ) {
|
||||||
ph = pu->units[i].content;
|
const H266RawPH *header = pu->units[i].content;
|
||||||
|
ph = &header->ph_picture_header;
|
||||||
} else if (IS_H266_SLICE(nal->nal_unit_type)) {
|
} else if (IS_H266_SLICE(nal->nal_unit_type)) {
|
||||||
const H266RawSlice *slice = pu->units[i].content;
|
const H266RawSlice *slice = pu->units[i].content;
|
||||||
layer_id = nal->nuh_layer_id;
|
layer_id = nal->nuh_layer_id;
|
||||||
|
@@ -31,7 +31,7 @@
|
|||||||
typedef struct PuInfo {
|
typedef struct PuInfo {
|
||||||
const H266RawPPS *pps;
|
const H266RawPPS *pps;
|
||||||
const H266RawSPS *sps;
|
const H266RawSPS *sps;
|
||||||
const H266RawPH *ph;
|
const H266RawPictureHeader *ph;
|
||||||
const H266RawSlice *slice;
|
const H266RawSlice *slice;
|
||||||
int pic_type;
|
int pic_type;
|
||||||
} PuInfo;
|
} PuInfo;
|
||||||
@@ -155,7 +155,6 @@ static void set_parser_ctx(AVCodecParserContext *s, AVCodecContext *avctx,
|
|||||||
};
|
};
|
||||||
const H266RawSPS *sps = pu->sps;
|
const H266RawSPS *sps = pu->sps;
|
||||||
const H266RawPPS *pps = pu->pps;
|
const H266RawPPS *pps = pu->pps;
|
||||||
//const H266RawPH *ph = pu->ph;
|
|
||||||
const H266RawNALUnitHeader *nal = &pu->slice->header.nal_unit_header;
|
const H266RawNALUnitHeader *nal = &pu->slice->header.nal_unit_header;
|
||||||
|
|
||||||
s->pict_type = pu->pic_type;
|
s->pict_type = pu->pic_type;
|
||||||
@@ -205,7 +204,7 @@ static void set_parser_ctx(AVCodecParserContext *s, AVCodecContext *avctx,
|
|||||||
//We follow the VTM.
|
//We follow the VTM.
|
||||||
static void get_slice_poc(VVCParserContext *s, int *poc,
|
static void get_slice_poc(VVCParserContext *s, int *poc,
|
||||||
const H266RawSPS *sps,
|
const H266RawSPS *sps,
|
||||||
const H266RawPH *ph,
|
const H266RawPictureHeader *ph,
|
||||||
const H266RawSliceHeader *slice, void *log_ctx)
|
const H266RawSliceHeader *slice, void *log_ctx)
|
||||||
{
|
{
|
||||||
int poc_msb, max_poc_lsb, poc_lsb;
|
int poc_msb, max_poc_lsb, poc_lsb;
|
||||||
@@ -251,7 +250,7 @@ static int is_au_start(VVCParserContext *s, const PuInfo *pu, void *log_ctx)
|
|||||||
AuDetector *d = &s->au_detector;
|
AuDetector *d = &s->au_detector;
|
||||||
const H266RawSPS *sps = pu->sps;
|
const H266RawSPS *sps = pu->sps;
|
||||||
const H266RawNALUnitHeader *nal = &pu->slice->header.nal_unit_header;
|
const H266RawNALUnitHeader *nal = &pu->slice->header.nal_unit_header;
|
||||||
const H266RawPH *ph = pu->ph;
|
const H266RawPictureHeader *ph = pu->ph;
|
||||||
const H266RawSlice *slice = pu->slice;
|
const H266RawSlice *slice = pu->slice;
|
||||||
int ret, poc, nut;
|
int ret, poc, nut;
|
||||||
|
|
||||||
@@ -282,7 +281,8 @@ static int get_pu_info(PuInfo *info, const CodedBitstreamH266Context *h266,
|
|||||||
if (!nal)
|
if (!nal)
|
||||||
continue;
|
continue;
|
||||||
if ( nal->nal_unit_type == VVC_PH_NUT ) {
|
if ( nal->nal_unit_type == VVC_PH_NUT ) {
|
||||||
info->ph = pu->units[i].content;
|
const H266RawPH *ph = pu->units[i].content;
|
||||||
|
info->ph = &ph->ph_picture_header;
|
||||||
} else if (IS_H266_SLICE(nal->nal_unit_type)) {
|
} else if (IS_H266_SLICE(nal->nal_unit_type)) {
|
||||||
info->slice = pu->units[i].content;
|
info->slice = pu->units[i].content;
|
||||||
if (info->slice->header.sh_picture_header_in_slice_header_flag)
|
if (info->slice->header.sh_picture_header_in_slice_header_flag)
|
||||||
|
Reference in New Issue
Block a user