summaryrefslogtreecommitdiff
path: root/libavcodec/h264_slice.c
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.dev>2021-08-17 21:25:31 +0200
committerJames Almer <jamrial@gmail.com>2021-08-24 09:58:52 -0300
commitcf37c3fb6c84d8eb61079520b4c57e3c969bc25d (patch)
treed449ba2158a00e4f606f1ce9faea50811ee32086 /libavcodec/h264_slice.c
parent61b38f7aef8d2f34135eb6a1e1e637d4fef667d2 (diff)
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>
Diffstat (limited to 'libavcodec/h264_slice.c')
-rw-r--r--libavcodec/h264_slice.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index 0d7107d455..9244d2d5dd 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -406,6 +406,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
h->next_output_pic = h1->next_output_pic;
h->next_outputed_poc = h1->next_outputed_poc;
+ h->poc_offset = h1->poc_offset;
memcpy(h->mmco, h1->mmco, sizeof(h->mmco));
h->nb_mmco = h1->nb_mmco;
@@ -1335,6 +1336,7 @@ static int h264_export_frame_props(H264Context *h)
return AVERROR(ENOMEM);
fgp->type = AV_FILM_GRAIN_PARAMS_H274;
+ fgp->seed = cur->poc + (h->poc_offset << 5);
fgp->codec.h274.model_id = fgc->model_id;
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[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
* frames just to throw them away */
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)
- get_ue_golomb_long(&sl->gb); /* idr_pic_id */
+ sl->idr_pic_id = get_ue_golomb_long(&sl->gb);
sl->poc_lsb = 0;
sl->delta_poc_bottom = 0;