blob: dee48e947bdb1045a5d7ffc1e83e376a2e031ac9 [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"
20#include "parser.h"
21#include "evc.h"
22#include "evc_parse.h"
23
Dawid Kozinski34e4f182023-06-15 11:46:4324// nuh_temporal_id specifies a temporal identifier for the NAL unit
25int ff_evc_get_temporal_id(const uint8_t *bits, int bits_size, void *logctx)
26{
27 int temporal_id = 0;
28 uint16_t t = 0;
29
30 if (bits_size < EVC_NALU_HEADER_SIZE) {
31 av_log(logctx, AV_LOG_ERROR, "Can't read NAL unit header\n");
32 return 0;
33 }
34
35 // forbidden_zero_bit
36 if ((bits[0] & 0x80) != 0)
37 return -1;
38
39 t = AV_RB16(bits);
40
41 temporal_id = (t >> 6) & 0x0007;
42
43 return temporal_id;
44}
45
Dawid Kozinski34e4f182023-06-15 11:46:4346// @see ISO_IEC_23094-1 (7.3.2.6 Slice layer RBSP syntax)
James Almere5da2ec2023-06-20 14:05:3847int ff_evc_parse_slice_header(GetBitContext *gb, EVCParserSliceHeader *sh,
48 const EVCParamSets *ps, enum EVCNALUnitType nalu_type)
Dawid Kozinski34e4f182023-06-15 11:46:4349{
James Almera5663f22023-06-17 21:02:2650 const EVCParserPPS *pps;
51 const EVCParserSPS *sps;
Dawid Kozinski34e4f182023-06-15 11:46:4352 int num_tiles_in_slice = 0;
53 int slice_pic_parameter_set_id;
54
James Almere5da2ec2023-06-20 14:05:3855 slice_pic_parameter_set_id = get_ue_golomb(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4356
57 if (slice_pic_parameter_set_id < 0 || slice_pic_parameter_set_id >= EVC_MAX_PPS_COUNT)
James Almer44f26312023-06-15 14:03:5158 return AVERROR_INVALIDDATA;
Dawid Kozinski34e4f182023-06-15 11:46:4359
James Almera5663f22023-06-17 21:02:2660 pps = ps->pps[slice_pic_parameter_set_id];
Dawid Kozinski34e4f182023-06-15 11:46:4361 if(!pps)
James Almer44f26312023-06-15 14:03:5162 return AVERROR_INVALIDDATA;
Dawid Kozinski34e4f182023-06-15 11:46:4363
James Almera5663f22023-06-17 21:02:2664 sps = ps->sps[pps->pps_seq_parameter_set_id];
Dawid Kozinski34e4f182023-06-15 11:46:4365 if(!sps)
James Almer44f26312023-06-15 14:03:5166 return AVERROR_INVALIDDATA;
Dawid Kozinski34e4f182023-06-15 11:46:4367
James Almer44f26312023-06-15 14:03:5168 memset(sh, 0, sizeof(*sh));
Dawid Kozinski34e4f182023-06-15 11:46:4369 sh->slice_pic_parameter_set_id = slice_pic_parameter_set_id;
70
71 if (!pps->single_tile_in_pic_flag) {
James Almere5da2ec2023-06-20 14:05:3872 sh->single_tile_in_slice_flag = get_bits1(gb);
73 sh->first_tile_id = get_bits(gb, pps->tile_id_len_minus1 + 1);
Dawid Kozinski34e4f182023-06-15 11:46:4374 } else
75 sh->single_tile_in_slice_flag = 1;
76
77 if (!sh->single_tile_in_slice_flag) {
78 if (pps->arbitrary_slice_present_flag)
James Almere5da2ec2023-06-20 14:05:3879 sh->arbitrary_slice_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4380
81 if (!sh->arbitrary_slice_flag)
James Almere5da2ec2023-06-20 14:05:3882 sh->last_tile_id = get_bits(gb, pps->tile_id_len_minus1 + 1);
Dawid Kozinski34e4f182023-06-15 11:46:4383 else {
James Almere5da2ec2023-06-20 14:05:3884 sh->num_remaining_tiles_in_slice_minus1 = get_ue_golomb(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4385 num_tiles_in_slice = sh->num_remaining_tiles_in_slice_minus1 + 2;
86 for (int i = 0; i < num_tiles_in_slice - 1; ++i)
James Almere5da2ec2023-06-20 14:05:3887 sh->delta_tile_id_minus1[i] = get_ue_golomb(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4388 }
89 }
90
James Almere5da2ec2023-06-20 14:05:3891 sh->slice_type = get_ue_golomb(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4392
James Almera5663f22023-06-17 21:02:2693 if (nalu_type == EVC_IDR_NUT)
James Almere5da2ec2023-06-20 14:05:3894 sh->no_output_of_prior_pics_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4395
96 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:3897 sh->mmvd_group_enable_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4398 else
99 sh->mmvd_group_enable_flag = 0;
100
101 if (sps->sps_alf_flag) {
102 int ChromaArrayType = sps->chroma_format_idc;
103
James Almere5da2ec2023-06-20 14:05:38104 sh->slice_alf_enabled_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:43105
106 if (sh->slice_alf_enabled_flag) {
James Almere5da2ec2023-06-20 14:05:38107 sh->slice_alf_luma_aps_id = get_bits(gb, 5);
108 sh->slice_alf_map_flag = get_bits1(gb);
109 sh->slice_alf_chroma_idc = get_bits(gb, 2);
Dawid Kozinski34e4f182023-06-15 11:46:43110
111 if ((ChromaArrayType == 1 || ChromaArrayType == 2) && sh->slice_alf_chroma_idc > 0)
James Almere5da2ec2023-06-20 14:05:38112 sh->slice_alf_chroma_aps_id = get_bits(gb, 5);
Dawid Kozinski34e4f182023-06-15 11:46:43113 }
114 if (ChromaArrayType == 3) {
115 int sliceChromaAlfEnabledFlag = 0;
116 int sliceChroma2AlfEnabledFlag = 0;
117
118 if (sh->slice_alf_chroma_idc == 1) { // @see ISO_IEC_23094-1 (7.4.5)
119 sliceChromaAlfEnabledFlag = 1;
120 sliceChroma2AlfEnabledFlag = 0;
121 } else if (sh->slice_alf_chroma_idc == 2) {
122 sliceChromaAlfEnabledFlag = 0;
123 sliceChroma2AlfEnabledFlag = 1;
124 } else if (sh->slice_alf_chroma_idc == 3) {
125 sliceChromaAlfEnabledFlag = 1;
126 sliceChroma2AlfEnabledFlag = 1;
127 } else {
128 sliceChromaAlfEnabledFlag = 0;
129 sliceChroma2AlfEnabledFlag = 0;
130 }
131
132 if (!sh->slice_alf_enabled_flag)
James Almere5da2ec2023-06-20 14:05:38133 sh->slice_alf_chroma_idc = get_bits(gb, 2);
Dawid Kozinski34e4f182023-06-15 11:46:43134
135 if (sliceChromaAlfEnabledFlag) {
James Almere5da2ec2023-06-20 14:05:38136 sh->slice_alf_chroma_aps_id = get_bits(gb, 5);
137 sh->slice_alf_chroma_map_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:43138 }
139
140 if (sliceChroma2AlfEnabledFlag) {
James Almere5da2ec2023-06-20 14:05:38141 sh->slice_alf_chroma2_aps_id = get_bits(gb, 5);
142 sh->slice_alf_chroma2_map_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:43143 }
144 }
145 }
146
James Almera5663f22023-06-17 21:02:26147 if (nalu_type != EVC_IDR_NUT) {
Dawid Kozinski34e4f182023-06-15 11:46:43148 if (sps->sps_pocs_flag)
James Almere5da2ec2023-06-20 14:05:38149 sh->slice_pic_order_cnt_lsb = get_bits(gb, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
Dawid Kozinski34e4f182023-06-15 11:46:43150 }
151
152 // @note
153 // If necessary, add the missing fields to the EVCParserSliceHeader structure
154 // and then extend parser implementation
155
James Almer44f26312023-06-15 14:03:51156 return 0;
Dawid Kozinski34e4f182023-06-15 11:46:43157}
158
James Almerff7a4cd2023-06-17 20:18:04159int ff_evc_derive_poc(const EVCParamSets *ps, const EVCParserSliceHeader *sh,
160 EVCParserPoc *poc, enum EVCNALUnitType nalu_type, int tid)
161{
162 const EVCParserPPS *pps = ps->pps[sh->slice_pic_parameter_set_id];
163 const EVCParserSPS *sps;
164
165 if (!pps)
166 return AVERROR_INVALIDDATA;
167
168 sps = ps->sps[pps->pps_seq_parameter_set_id];
169 if (!sps)
170 return AVERROR_INVALIDDATA;
171
172 if (sps->sps_pocs_flag) {
173 int PicOrderCntMsb = 0;
174 poc->prevPicOrderCntVal = poc->PicOrderCntVal;
175
176 if (nalu_type == EVC_IDR_NUT)
177 PicOrderCntMsb = 0;
178 else {
179 int MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
180 int prevPicOrderCntLsb = poc->PicOrderCntVal & (MaxPicOrderCntLsb - 1);
181 int prevPicOrderCntMsb = poc->PicOrderCntVal - prevPicOrderCntLsb;
182
183 if ((sh->slice_pic_order_cnt_lsb < prevPicOrderCntLsb) &&
184 ((prevPicOrderCntLsb - sh->slice_pic_order_cnt_lsb) >= (MaxPicOrderCntLsb / 2)))
185 PicOrderCntMsb = prevPicOrderCntMsb + MaxPicOrderCntLsb;
186 else if ((sh->slice_pic_order_cnt_lsb > prevPicOrderCntLsb) &&
187 ((sh->slice_pic_order_cnt_lsb - prevPicOrderCntLsb) > (MaxPicOrderCntLsb / 2)))
188 PicOrderCntMsb = prevPicOrderCntMsb - MaxPicOrderCntLsb;
189 else
190 PicOrderCntMsb = prevPicOrderCntMsb;
191 }
192 poc->PicOrderCntVal = PicOrderCntMsb + sh->slice_pic_order_cnt_lsb;
193 } else {
194 if (nalu_type == EVC_IDR_NUT) {
195 poc->PicOrderCntVal = 0;
196 poc->DocOffset = -1;
197 } else {
198 int SubGopLength = (int)pow(2.0, sps->log2_sub_gop_length);
199 if (tid == 0) {
200 poc->PicOrderCntVal = poc->prevPicOrderCntVal + SubGopLength;
201 poc->DocOffset = 0;
202 poc->prevPicOrderCntVal = poc->PicOrderCntVal;
203 } else {
204 int ExpectedTemporalId;
205 int PocOffset;
206 int prevDocOffset = poc->DocOffset;
207
208 poc->DocOffset = (prevDocOffset + 1) % SubGopLength;
209 if (poc->DocOffset == 0) {
210 poc->prevPicOrderCntVal += SubGopLength;
211 ExpectedTemporalId = 0;
212 } else
213 ExpectedTemporalId = 1 + (int)log2(poc->DocOffset);
214 while (tid != ExpectedTemporalId) {
215 poc->DocOffset = (poc->DocOffset + 1) % SubGopLength;
216 if (poc->DocOffset == 0)
217 ExpectedTemporalId = 0;
218 else
219 ExpectedTemporalId = 1 + (int)log2(poc->DocOffset);
220 }
221 PocOffset = (int)(SubGopLength * ((2.0 * poc->DocOffset + 1) / (int)pow(2.0, tid) - 2));
222 poc->PicOrderCntVal = poc->prevPicOrderCntVal + PocOffset;
223 }
224 }
225 }
226
227 return 0;
228}