avcodec/h264_slice: compute and export film grain seed
From SMPTE RDD 5-2006, the grain seed is to be computed from the following definition of `pic_offset`: > When decoding H.264 | MPEG-4 AVC bitstreams, pic_offset is defined as > follows: > - pic_offset = PicOrderCnt(CurrPic) + (PicOrderCnt_offset << 5) > where: > - PicOrderCnt(CurrPic) is the picture order count of the current frame, > which shall be derived from [the video stream]. > > - PicOrderCnt_offset is set to idr_pic_id on IDR frames. idr_pic_id > shall be read from the slice header of [the video stream]. On non-IDR I > frames, PicOrderCnt_offset is set to 0. A frame shall be classified as I > frame when all its slices are I slices, which may be optionally > designated by setting primary_pic_type to 0 in the access delimiter NAL > unit. Otherwise, PicOrderCnt_offset it not changed. PicOrderCnt_offset is > updated in decoding order. Co-authored-by: James Almer <jamrial@gmail.com> Signed-off-by: Niklas Haas <git@haasn.dev> Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
parent
61b38f7aef
commit
cf37c3fb6c
@ -406,6 +406,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
|
|||||||
|
|
||||||
h->next_output_pic = h1->next_output_pic;
|
h->next_output_pic = h1->next_output_pic;
|
||||||
h->next_outputed_poc = h1->next_outputed_poc;
|
h->next_outputed_poc = h1->next_outputed_poc;
|
||||||
|
h->poc_offset = h1->poc_offset;
|
||||||
|
|
||||||
memcpy(h->mmco, h1->mmco, sizeof(h->mmco));
|
memcpy(h->mmco, h1->mmco, sizeof(h->mmco));
|
||||||
h->nb_mmco = h1->nb_mmco;
|
h->nb_mmco = h1->nb_mmco;
|
||||||
@ -1335,6 +1336,7 @@ static int h264_export_frame_props(H264Context *h)
|
|||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
fgp->type = AV_FILM_GRAIN_PARAMS_H274;
|
fgp->type = AV_FILM_GRAIN_PARAMS_H274;
|
||||||
|
fgp->seed = cur->poc + (h->poc_offset << 5);
|
||||||
|
|
||||||
fgp->codec.h274.model_id = fgc->model_id;
|
fgp->codec.h274.model_id = fgc->model_id;
|
||||||
if (fgc->separate_colour_description_present_flag) {
|
if (fgc->separate_colour_description_present_flag) {
|
||||||
@ -1543,6 +1545,11 @@ static int h264_field_start(H264Context *h, const H264SliceContext *sl,
|
|||||||
h->poc.delta_poc[0] = sl->delta_poc[0];
|
h->poc.delta_poc[0] = sl->delta_poc[0];
|
||||||
h->poc.delta_poc[1] = sl->delta_poc[1];
|
h->poc.delta_poc[1] = sl->delta_poc[1];
|
||||||
|
|
||||||
|
if (nal->type == H264_NAL_IDR_SLICE)
|
||||||
|
h->poc_offset = sl->idr_pic_id;
|
||||||
|
else if (h->picture_intra_only)
|
||||||
|
h->poc_offset = 0;
|
||||||
|
|
||||||
/* Shorten frame num gaps so we don't have to allocate reference
|
/* Shorten frame num gaps so we don't have to allocate reference
|
||||||
* frames just to throw them away */
|
* frames just to throw them away */
|
||||||
if (h->poc.frame_num != h->poc.prev_frame_num) {
|
if (h->poc.frame_num != h->poc.prev_frame_num) {
|
||||||
@ -1891,7 +1898,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nal->type == H264_NAL_IDR_SLICE)
|
if (nal->type == H264_NAL_IDR_SLICE)
|
||||||
get_ue_golomb_long(&sl->gb); /* idr_pic_id */
|
sl->idr_pic_id = get_ue_golomb_long(&sl->gb);
|
||||||
|
|
||||||
sl->poc_lsb = 0;
|
sl->poc_lsb = 0;
|
||||||
sl->delta_poc_bottom = 0;
|
sl->delta_poc_bottom = 0;
|
||||||
|
@ -485,6 +485,8 @@ static void h264_decode_flush(AVCodecContext *avctx)
|
|||||||
static int get_last_needed_nal(H264Context *h)
|
static int get_last_needed_nal(H264Context *h)
|
||||||
{
|
{
|
||||||
int nals_needed = 0;
|
int nals_needed = 0;
|
||||||
|
int slice_type = 0;
|
||||||
|
int picture_intra_only = 1;
|
||||||
int first_slice = 0;
|
int first_slice = 0;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
@ -516,11 +518,23 @@ static int get_last_needed_nal(H264Context *h)
|
|||||||
!first_slice ||
|
!first_slice ||
|
||||||
first_slice != nal->type)
|
first_slice != nal->type)
|
||||||
nals_needed = i;
|
nals_needed = i;
|
||||||
|
slice_type = get_ue_golomb_31(&gb);
|
||||||
|
if (slice_type > 9) {
|
||||||
|
if (h->avctx->err_recognition & AV_EF_EXPLODE)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
if (slice_type > 4)
|
||||||
|
slice_type -= 5;
|
||||||
|
|
||||||
|
slice_type = ff_h264_golomb_to_pict_type[slice_type];
|
||||||
|
picture_intra_only &= (slice_type & 3) == AV_PICTURE_TYPE_I;
|
||||||
if (!first_slice)
|
if (!first_slice)
|
||||||
first_slice = nal->type;
|
first_slice = nal->type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h->picture_intra_only = picture_intra_only;
|
||||||
|
|
||||||
return nals_needed;
|
return nals_needed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,6 +331,7 @@ typedef struct H264SliceContext {
|
|||||||
int explicit_ref_marking;
|
int explicit_ref_marking;
|
||||||
|
|
||||||
int frame_num;
|
int frame_num;
|
||||||
|
int idr_pic_id;
|
||||||
int poc_lsb;
|
int poc_lsb;
|
||||||
int delta_poc_bottom;
|
int delta_poc_bottom;
|
||||||
int delta_poc[2];
|
int delta_poc[2];
|
||||||
@ -384,6 +385,11 @@ typedef struct H264Context {
|
|||||||
*/
|
*/
|
||||||
int picture_idr;
|
int picture_idr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set to 1 when the current picture contains only I slices, 0 otherwise.
|
||||||
|
*/
|
||||||
|
int picture_intra_only;
|
||||||
|
|
||||||
int crop_left;
|
int crop_left;
|
||||||
int crop_right;
|
int crop_right;
|
||||||
int crop_top;
|
int crop_top;
|
||||||
@ -473,6 +479,7 @@ typedef struct H264Context {
|
|||||||
int last_pocs[MAX_DELAYED_PIC_COUNT];
|
int last_pocs[MAX_DELAYED_PIC_COUNT];
|
||||||
H264Picture *next_output_pic;
|
H264Picture *next_output_pic;
|
||||||
int next_outputed_poc;
|
int next_outputed_poc;
|
||||||
|
int poc_offset; ///< PicOrderCnt_offset from SMPTE RDD-2006
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* memory management control operations buffer.
|
* memory management control operations buffer.
|
||||||
|
@ -221,6 +221,9 @@ typedef struct AVFilmGrainParams {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Seed to use for the synthesis process, if the codec allows for it.
|
* Seed to use for the synthesis process, if the codec allows for it.
|
||||||
|
*
|
||||||
|
* @note For H.264, this refers to `pic_offset` as defined in
|
||||||
|
* SMPTE RDD 5-2006.
|
||||||
*/
|
*/
|
||||||
uint64_t seed;
|
uint64_t seed;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user