blob: 43b8dabf8bee8b3e98d4ecaec6af060f3a9e5e15 [file] [log] [blame]
Dawid Kozinski34e4f182023-06-15 11:46:431/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include "golomb.h"
Dawid Kozinski34e4f182023-06-15 11:46:4320#include "evc.h"
21#include "evc_parse.h"
22
Dawid Kozinski34e4f182023-06-15 11:46:4323// @see ISO_IEC_23094-1 (7.3.2.6 Slice layer RBSP syntax)
James Almere5da2ec2023-06-20 14:05:3824int ff_evc_parse_slice_header(GetBitContext *gb, EVCParserSliceHeader *sh,
25 const EVCParamSets *ps, enum EVCNALUnitType nalu_type)
Dawid Kozinski34e4f182023-06-15 11:46:4326{
James Almera5663f22023-06-17 21:02:2627 const EVCParserPPS *pps;
28 const EVCParserSPS *sps;
Dawid Kozinski34e4f182023-06-15 11:46:4329 int num_tiles_in_slice = 0;
James Almer5b966be2023-06-22 22:46:2230 unsigned slice_pic_parameter_set_id;
Dawid Kozinski34e4f182023-06-15 11:46:4331
James Almer5b966be2023-06-22 22:46:2232 slice_pic_parameter_set_id = get_ue_golomb_31(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4333
James Almer5b966be2023-06-22 22:46:2234 if (slice_pic_parameter_set_id >= EVC_MAX_PPS_COUNT)
James Almer44f26312023-06-15 14:03:5135 return AVERROR_INVALIDDATA;
Dawid Kozinski34e4f182023-06-15 11:46:4336
James Almera5663f22023-06-17 21:02:2637 pps = ps->pps[slice_pic_parameter_set_id];
Dawid Kozinski34e4f182023-06-15 11:46:4338 if(!pps)
James Almer44f26312023-06-15 14:03:5139 return AVERROR_INVALIDDATA;
Dawid Kozinski34e4f182023-06-15 11:46:4340
James Almera5663f22023-06-17 21:02:2641 sps = ps->sps[pps->pps_seq_parameter_set_id];
Dawid Kozinski34e4f182023-06-15 11:46:4342 if(!sps)
James Almer44f26312023-06-15 14:03:5143 return AVERROR_INVALIDDATA;
Dawid Kozinski34e4f182023-06-15 11:46:4344
James Almer44f26312023-06-15 14:03:5145 memset(sh, 0, sizeof(*sh));
Dawid Kozinski34e4f182023-06-15 11:46:4346 sh->slice_pic_parameter_set_id = slice_pic_parameter_set_id;
47
48 if (!pps->single_tile_in_pic_flag) {
James Almere5da2ec2023-06-20 14:05:3849 sh->single_tile_in_slice_flag = get_bits1(gb);
50 sh->first_tile_id = get_bits(gb, pps->tile_id_len_minus1 + 1);
Dawid Kozinski34e4f182023-06-15 11:46:4351 } else
52 sh->single_tile_in_slice_flag = 1;
53
54 if (!sh->single_tile_in_slice_flag) {
55 if (pps->arbitrary_slice_present_flag)
James Almere5da2ec2023-06-20 14:05:3856 sh->arbitrary_slice_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4357
58 if (!sh->arbitrary_slice_flag)
James Almere5da2ec2023-06-20 14:05:3859 sh->last_tile_id = get_bits(gb, pps->tile_id_len_minus1 + 1);
Dawid Kozinski34e4f182023-06-15 11:46:4360 else {
James Almer5b966be2023-06-22 22:46:2261 sh->num_remaining_tiles_in_slice_minus1 = get_ue_golomb_long(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4362 num_tiles_in_slice = sh->num_remaining_tiles_in_slice_minus1 + 2;
63 for (int i = 0; i < num_tiles_in_slice - 1; ++i)
James Almer5b966be2023-06-22 22:46:2264 sh->delta_tile_id_minus1[i] = get_ue_golomb_long(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4365 }
66 }
67
James Almer5b966be2023-06-22 22:46:2268 sh->slice_type = get_ue_golomb_31(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4369
James Almera5663f22023-06-17 21:02:2670 if (nalu_type == EVC_IDR_NUT)
James Almere5da2ec2023-06-20 14:05:3871 sh->no_output_of_prior_pics_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4372
73 if (sps->sps_mmvd_flag && ((sh->slice_type == EVC_SLICE_TYPE_B) || (sh->slice_type == EVC_SLICE_TYPE_P)))
James Almere5da2ec2023-06-20 14:05:3874 sh->mmvd_group_enable_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4375 else
76 sh->mmvd_group_enable_flag = 0;
77
78 if (sps->sps_alf_flag) {
79 int ChromaArrayType = sps->chroma_format_idc;
80
James Almere5da2ec2023-06-20 14:05:3881 sh->slice_alf_enabled_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4382
83 if (sh->slice_alf_enabled_flag) {
James Almere5da2ec2023-06-20 14:05:3884 sh->slice_alf_luma_aps_id = get_bits(gb, 5);
85 sh->slice_alf_map_flag = get_bits1(gb);
86 sh->slice_alf_chroma_idc = get_bits(gb, 2);
Dawid Kozinski34e4f182023-06-15 11:46:4387
88 if ((ChromaArrayType == 1 || ChromaArrayType == 2) && sh->slice_alf_chroma_idc > 0)
James Almere5da2ec2023-06-20 14:05:3889 sh->slice_alf_chroma_aps_id = get_bits(gb, 5);
Dawid Kozinski34e4f182023-06-15 11:46:4390 }
91 if (ChromaArrayType == 3) {
92 int sliceChromaAlfEnabledFlag = 0;
93 int sliceChroma2AlfEnabledFlag = 0;
94
95 if (sh->slice_alf_chroma_idc == 1) { // @see ISO_IEC_23094-1 (7.4.5)
96 sliceChromaAlfEnabledFlag = 1;
97 sliceChroma2AlfEnabledFlag = 0;
98 } else if (sh->slice_alf_chroma_idc == 2) {
99 sliceChromaAlfEnabledFlag = 0;
100 sliceChroma2AlfEnabledFlag = 1;
101 } else if (sh->slice_alf_chroma_idc == 3) {
102 sliceChromaAlfEnabledFlag = 1;
103 sliceChroma2AlfEnabledFlag = 1;
104 } else {
105 sliceChromaAlfEnabledFlag = 0;
106 sliceChroma2AlfEnabledFlag = 0;
107 }
108
109 if (!sh->slice_alf_enabled_flag)
James Almere5da2ec2023-06-20 14:05:38110 sh->slice_alf_chroma_idc = get_bits(gb, 2);
Dawid Kozinski34e4f182023-06-15 11:46:43111
112 if (sliceChromaAlfEnabledFlag) {
James Almere5da2ec2023-06-20 14:05:38113 sh->slice_alf_chroma_aps_id = get_bits(gb, 5);
114 sh->slice_alf_chroma_map_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:43115 }
116
117 if (sliceChroma2AlfEnabledFlag) {
James Almere5da2ec2023-06-20 14:05:38118 sh->slice_alf_chroma2_aps_id = get_bits(gb, 5);
119 sh->slice_alf_chroma2_map_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:43120 }
121 }
122 }
123
James Almera5663f22023-06-17 21:02:26124 if (nalu_type != EVC_IDR_NUT) {
Dawid Kozinski34e4f182023-06-15 11:46:43125 if (sps->sps_pocs_flag)
James Almere5da2ec2023-06-20 14:05:38126 sh->slice_pic_order_cnt_lsb = get_bits(gb, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
Dawid Kozinski34e4f182023-06-15 11:46:43127 }
128
129 // @note
130 // If necessary, add the missing fields to the EVCParserSliceHeader structure
131 // and then extend parser implementation
132
James Almer44f26312023-06-15 14:03:51133 return 0;
Dawid Kozinski34e4f182023-06-15 11:46:43134}
135
James Almerff7a4cd2023-06-17 20:18:04136int ff_evc_derive_poc(const EVCParamSets *ps, const EVCParserSliceHeader *sh,
137 EVCParserPoc *poc, enum EVCNALUnitType nalu_type, int tid)
138{
139 const EVCParserPPS *pps = ps->pps[sh->slice_pic_parameter_set_id];
140 const EVCParserSPS *sps;
141
142 if (!pps)
143 return AVERROR_INVALIDDATA;
144
145 sps = ps->sps[pps->pps_seq_parameter_set_id];
146 if (!sps)
147 return AVERROR_INVALIDDATA;
148
149 if (sps->sps_pocs_flag) {
150 int PicOrderCntMsb = 0;
151 poc->prevPicOrderCntVal = poc->PicOrderCntVal;
152
153 if (nalu_type == EVC_IDR_NUT)
154 PicOrderCntMsb = 0;
155 else {
156 int MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
157 int prevPicOrderCntLsb = poc->PicOrderCntVal & (MaxPicOrderCntLsb - 1);
158 int prevPicOrderCntMsb = poc->PicOrderCntVal - prevPicOrderCntLsb;
159
160 if ((sh->slice_pic_order_cnt_lsb < prevPicOrderCntLsb) &&
161 ((prevPicOrderCntLsb - sh->slice_pic_order_cnt_lsb) >= (MaxPicOrderCntLsb / 2)))
162 PicOrderCntMsb = prevPicOrderCntMsb + MaxPicOrderCntLsb;
163 else if ((sh->slice_pic_order_cnt_lsb > prevPicOrderCntLsb) &&
164 ((sh->slice_pic_order_cnt_lsb - prevPicOrderCntLsb) > (MaxPicOrderCntLsb / 2)))
165 PicOrderCntMsb = prevPicOrderCntMsb - MaxPicOrderCntLsb;
166 else
167 PicOrderCntMsb = prevPicOrderCntMsb;
168 }
169 poc->PicOrderCntVal = PicOrderCntMsb + sh->slice_pic_order_cnt_lsb;
170 } else {
171 if (nalu_type == EVC_IDR_NUT) {
172 poc->PicOrderCntVal = 0;
173 poc->DocOffset = -1;
174 } else {
Michael Niedermayerd35eecd2023-10-04 22:10:18175 int SubGopLength = 1 << sps->log2_sub_gop_length;
176
Michael Niedermayer68cc1742023-10-04 22:19:53177 if (tid > (SubGopLength > 1 ? 1 + av_log2(SubGopLength - 1) : 0))
178 return AVERROR_INVALIDDATA;
179
James Almerff7a4cd2023-06-17 20:18:04180 if (tid == 0) {
181 poc->PicOrderCntVal = poc->prevPicOrderCntVal + SubGopLength;
182 poc->DocOffset = 0;
183 poc->prevPicOrderCntVal = poc->PicOrderCntVal;
184 } else {
185 int ExpectedTemporalId;
186 int PocOffset;
187 int prevDocOffset = poc->DocOffset;
188
189 poc->DocOffset = (prevDocOffset + 1) % SubGopLength;
190 if (poc->DocOffset == 0) {
191 poc->prevPicOrderCntVal += SubGopLength;
192 ExpectedTemporalId = 0;
193 } else
Michael Niedermayerd35eecd2023-10-04 22:10:18194 ExpectedTemporalId = 1 + av_log2(poc->DocOffset);
195
James Almerff7a4cd2023-06-17 20:18:04196 while (tid != ExpectedTemporalId) {
197 poc->DocOffset = (poc->DocOffset + 1) % SubGopLength;
198 if (poc->DocOffset == 0)
199 ExpectedTemporalId = 0;
200 else
Michael Niedermayerd35eecd2023-10-04 22:10:18201 ExpectedTemporalId = 1 + av_log2(poc->DocOffset);
James Almerff7a4cd2023-06-17 20:18:04202 }
Michael Niedermayerd35eecd2023-10-04 22:10:18203 PocOffset = (int)(SubGopLength * ((2.0 * poc->DocOffset + 1) / (1 << tid) - 2));
James Almerff7a4cd2023-06-17 20:18:04204 poc->PicOrderCntVal = poc->prevPicOrderCntVal + PocOffset;
205 }
206 }
207 }
208
209 return 0;
210}