blob: 447f6195c236537abe1a4723aade23319a5c8026 [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// @see ISO_IEC_23094-1 (7.3.2.6 Slice layer RBSP syntax)
James Almere5da2ec2023-06-20 14:05:3825int ff_evc_parse_slice_header(GetBitContext *gb, EVCParserSliceHeader *sh,
26 const EVCParamSets *ps, enum EVCNALUnitType nalu_type)
Dawid Kozinski34e4f182023-06-15 11:46:4327{
James Almera5663f22023-06-17 21:02:2628 const EVCParserPPS *pps;
29 const EVCParserSPS *sps;
Dawid Kozinski34e4f182023-06-15 11:46:4330 int num_tiles_in_slice = 0;
James Almer5b966be2023-06-22 22:46:2231 unsigned slice_pic_parameter_set_id;
Dawid Kozinski34e4f182023-06-15 11:46:4332
James Almer5b966be2023-06-22 22:46:2233 slice_pic_parameter_set_id = get_ue_golomb_31(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4334
James Almer5b966be2023-06-22 22:46:2235 if (slice_pic_parameter_set_id >= EVC_MAX_PPS_COUNT)
James Almer44f26312023-06-15 14:03:5136 return AVERROR_INVALIDDATA;
Dawid Kozinski34e4f182023-06-15 11:46:4337
James Almera5663f22023-06-17 21:02:2638 pps = ps->pps[slice_pic_parameter_set_id];
Dawid Kozinski34e4f182023-06-15 11:46:4339 if(!pps)
James Almer44f26312023-06-15 14:03:5140 return AVERROR_INVALIDDATA;
Dawid Kozinski34e4f182023-06-15 11:46:4341
James Almera5663f22023-06-17 21:02:2642 sps = ps->sps[pps->pps_seq_parameter_set_id];
Dawid Kozinski34e4f182023-06-15 11:46:4343 if(!sps)
James Almer44f26312023-06-15 14:03:5144 return AVERROR_INVALIDDATA;
Dawid Kozinski34e4f182023-06-15 11:46:4345
James Almer44f26312023-06-15 14:03:5146 memset(sh, 0, sizeof(*sh));
Dawid Kozinski34e4f182023-06-15 11:46:4347 sh->slice_pic_parameter_set_id = slice_pic_parameter_set_id;
48
49 if (!pps->single_tile_in_pic_flag) {
James Almere5da2ec2023-06-20 14:05:3850 sh->single_tile_in_slice_flag = get_bits1(gb);
51 sh->first_tile_id = get_bits(gb, pps->tile_id_len_minus1 + 1);
Dawid Kozinski34e4f182023-06-15 11:46:4352 } else
53 sh->single_tile_in_slice_flag = 1;
54
55 if (!sh->single_tile_in_slice_flag) {
56 if (pps->arbitrary_slice_present_flag)
James Almere5da2ec2023-06-20 14:05:3857 sh->arbitrary_slice_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4358
59 if (!sh->arbitrary_slice_flag)
James Almere5da2ec2023-06-20 14:05:3860 sh->last_tile_id = get_bits(gb, pps->tile_id_len_minus1 + 1);
Dawid Kozinski34e4f182023-06-15 11:46:4361 else {
James Almer5b966be2023-06-22 22:46:2262 sh->num_remaining_tiles_in_slice_minus1 = get_ue_golomb_long(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4363 num_tiles_in_slice = sh->num_remaining_tiles_in_slice_minus1 + 2;
64 for (int i = 0; i < num_tiles_in_slice - 1; ++i)
James Almer5b966be2023-06-22 22:46:2265 sh->delta_tile_id_minus1[i] = get_ue_golomb_long(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4366 }
67 }
68
James Almer5b966be2023-06-22 22:46:2269 sh->slice_type = get_ue_golomb_31(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4370
James Almera5663f22023-06-17 21:02:2671 if (nalu_type == EVC_IDR_NUT)
James Almere5da2ec2023-06-20 14:05:3872 sh->no_output_of_prior_pics_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4373
74 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:3875 sh->mmvd_group_enable_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4376 else
77 sh->mmvd_group_enable_flag = 0;
78
79 if (sps->sps_alf_flag) {
80 int ChromaArrayType = sps->chroma_format_idc;
81
James Almere5da2ec2023-06-20 14:05:3882 sh->slice_alf_enabled_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:4383
84 if (sh->slice_alf_enabled_flag) {
James Almere5da2ec2023-06-20 14:05:3885 sh->slice_alf_luma_aps_id = get_bits(gb, 5);
86 sh->slice_alf_map_flag = get_bits1(gb);
87 sh->slice_alf_chroma_idc = get_bits(gb, 2);
Dawid Kozinski34e4f182023-06-15 11:46:4388
89 if ((ChromaArrayType == 1 || ChromaArrayType == 2) && sh->slice_alf_chroma_idc > 0)
James Almere5da2ec2023-06-20 14:05:3890 sh->slice_alf_chroma_aps_id = get_bits(gb, 5);
Dawid Kozinski34e4f182023-06-15 11:46:4391 }
92 if (ChromaArrayType == 3) {
93 int sliceChromaAlfEnabledFlag = 0;
94 int sliceChroma2AlfEnabledFlag = 0;
95
96 if (sh->slice_alf_chroma_idc == 1) { // @see ISO_IEC_23094-1 (7.4.5)
97 sliceChromaAlfEnabledFlag = 1;
98 sliceChroma2AlfEnabledFlag = 0;
99 } else if (sh->slice_alf_chroma_idc == 2) {
100 sliceChromaAlfEnabledFlag = 0;
101 sliceChroma2AlfEnabledFlag = 1;
102 } else if (sh->slice_alf_chroma_idc == 3) {
103 sliceChromaAlfEnabledFlag = 1;
104 sliceChroma2AlfEnabledFlag = 1;
105 } else {
106 sliceChromaAlfEnabledFlag = 0;
107 sliceChroma2AlfEnabledFlag = 0;
108 }
109
110 if (!sh->slice_alf_enabled_flag)
James Almere5da2ec2023-06-20 14:05:38111 sh->slice_alf_chroma_idc = get_bits(gb, 2);
Dawid Kozinski34e4f182023-06-15 11:46:43112
113 if (sliceChromaAlfEnabledFlag) {
James Almere5da2ec2023-06-20 14:05:38114 sh->slice_alf_chroma_aps_id = get_bits(gb, 5);
115 sh->slice_alf_chroma_map_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:43116 }
117
118 if (sliceChroma2AlfEnabledFlag) {
James Almere5da2ec2023-06-20 14:05:38119 sh->slice_alf_chroma2_aps_id = get_bits(gb, 5);
120 sh->slice_alf_chroma2_map_flag = get_bits1(gb);
Dawid Kozinski34e4f182023-06-15 11:46:43121 }
122 }
123 }
124
James Almera5663f22023-06-17 21:02:26125 if (nalu_type != EVC_IDR_NUT) {
Dawid Kozinski34e4f182023-06-15 11:46:43126 if (sps->sps_pocs_flag)
James Almere5da2ec2023-06-20 14:05:38127 sh->slice_pic_order_cnt_lsb = get_bits(gb, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
Dawid Kozinski34e4f182023-06-15 11:46:43128 }
129
130 // @note
131 // If necessary, add the missing fields to the EVCParserSliceHeader structure
132 // and then extend parser implementation
133
James Almer44f26312023-06-15 14:03:51134 return 0;
Dawid Kozinski34e4f182023-06-15 11:46:43135}
136
James Almerff7a4cd2023-06-17 20:18:04137int ff_evc_derive_poc(const EVCParamSets *ps, const EVCParserSliceHeader *sh,
138 EVCParserPoc *poc, enum EVCNALUnitType nalu_type, int tid)
139{
140 const EVCParserPPS *pps = ps->pps[sh->slice_pic_parameter_set_id];
141 const EVCParserSPS *sps;
142
143 if (!pps)
144 return AVERROR_INVALIDDATA;
145
146 sps = ps->sps[pps->pps_seq_parameter_set_id];
147 if (!sps)
148 return AVERROR_INVALIDDATA;
149
150 if (sps->sps_pocs_flag) {
151 int PicOrderCntMsb = 0;
152 poc->prevPicOrderCntVal = poc->PicOrderCntVal;
153
154 if (nalu_type == EVC_IDR_NUT)
155 PicOrderCntMsb = 0;
156 else {
157 int MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
158 int prevPicOrderCntLsb = poc->PicOrderCntVal & (MaxPicOrderCntLsb - 1);
159 int prevPicOrderCntMsb = poc->PicOrderCntVal - prevPicOrderCntLsb;
160
161 if ((sh->slice_pic_order_cnt_lsb < prevPicOrderCntLsb) &&
162 ((prevPicOrderCntLsb - sh->slice_pic_order_cnt_lsb) >= (MaxPicOrderCntLsb / 2)))
163 PicOrderCntMsb = prevPicOrderCntMsb + MaxPicOrderCntLsb;
164 else if ((sh->slice_pic_order_cnt_lsb > prevPicOrderCntLsb) &&
165 ((sh->slice_pic_order_cnt_lsb - prevPicOrderCntLsb) > (MaxPicOrderCntLsb / 2)))
166 PicOrderCntMsb = prevPicOrderCntMsb - MaxPicOrderCntLsb;
167 else
168 PicOrderCntMsb = prevPicOrderCntMsb;
169 }
170 poc->PicOrderCntVal = PicOrderCntMsb + sh->slice_pic_order_cnt_lsb;
171 } else {
172 if (nalu_type == EVC_IDR_NUT) {
173 poc->PicOrderCntVal = 0;
174 poc->DocOffset = -1;
175 } else {
176 int SubGopLength = (int)pow(2.0, sps->log2_sub_gop_length);
177 if (tid == 0) {
178 poc->PicOrderCntVal = poc->prevPicOrderCntVal + SubGopLength;
179 poc->DocOffset = 0;
180 poc->prevPicOrderCntVal = poc->PicOrderCntVal;
181 } else {
182 int ExpectedTemporalId;
183 int PocOffset;
184 int prevDocOffset = poc->DocOffset;
185
186 poc->DocOffset = (prevDocOffset + 1) % SubGopLength;
187 if (poc->DocOffset == 0) {
188 poc->prevPicOrderCntVal += SubGopLength;
189 ExpectedTemporalId = 0;
190 } else
191 ExpectedTemporalId = 1 + (int)log2(poc->DocOffset);
192 while (tid != ExpectedTemporalId) {
193 poc->DocOffset = (poc->DocOffset + 1) % SubGopLength;
194 if (poc->DocOffset == 0)
195 ExpectedTemporalId = 0;
196 else
197 ExpectedTemporalId = 1 + (int)log2(poc->DocOffset);
198 }
199 PocOffset = (int)(SubGopLength * ((2.0 * poc->DocOffset + 1) / (int)pow(2.0, tid) - 2));
200 poc->PicOrderCntVal = poc->prevPicOrderCntVal + PocOffset;
201 }
202 }
203 }
204
205 return 0;
206}