1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * This file is part of FFmpeg.
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
5cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
6cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
7cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
8cabdff1aSopenharmony_ci *
9cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
10cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
11cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12cabdff1aSopenharmony_ci * Lesser General Public License for more details.
13cabdff1aSopenharmony_ci *
14cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
15cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
16cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17cabdff1aSopenharmony_ci */
18cabdff1aSopenharmony_ci
19cabdff1aSopenharmony_ci#include "bytestream.h"
20cabdff1aSopenharmony_ci#include "get_bits.h"
21cabdff1aSopenharmony_ci#include "golomb.h"
22cabdff1aSopenharmony_ci#include "h264.h"
23cabdff1aSopenharmony_ci#include "h264pred.h"
24cabdff1aSopenharmony_ci#include "h264_parse.h"
25cabdff1aSopenharmony_ci#include "h264_ps.h"
26cabdff1aSopenharmony_ci#include "h2645_parse.h"
27cabdff1aSopenharmony_ci#include "mpegutils.h"
28cabdff1aSopenharmony_ci
29cabdff1aSopenharmony_ciint ff_h264_pred_weight_table(GetBitContext *gb, const SPS *sps,
30cabdff1aSopenharmony_ci                              const int *ref_count, int slice_type_nos,
31cabdff1aSopenharmony_ci                              H264PredWeightTable *pwt,
32cabdff1aSopenharmony_ci                              int picture_structure, void *logctx)
33cabdff1aSopenharmony_ci{
34cabdff1aSopenharmony_ci    int list, i, j;
35cabdff1aSopenharmony_ci    int luma_def, chroma_def;
36cabdff1aSopenharmony_ci
37cabdff1aSopenharmony_ci    pwt->use_weight             = 0;
38cabdff1aSopenharmony_ci    pwt->use_weight_chroma      = 0;
39cabdff1aSopenharmony_ci
40cabdff1aSopenharmony_ci    pwt->luma_log2_weight_denom = get_ue_golomb_31(gb);
41cabdff1aSopenharmony_ci    if (pwt->luma_log2_weight_denom > 7U) {
42cabdff1aSopenharmony_ci        av_log(logctx, AV_LOG_ERROR, "luma_log2_weight_denom %d is out of range\n", pwt->luma_log2_weight_denom);
43cabdff1aSopenharmony_ci        pwt->luma_log2_weight_denom = 0;
44cabdff1aSopenharmony_ci    }
45cabdff1aSopenharmony_ci    luma_def = 1 << pwt->luma_log2_weight_denom;
46cabdff1aSopenharmony_ci
47cabdff1aSopenharmony_ci    if (sps->chroma_format_idc) {
48cabdff1aSopenharmony_ci        pwt->chroma_log2_weight_denom = get_ue_golomb_31(gb);
49cabdff1aSopenharmony_ci        if (pwt->chroma_log2_weight_denom > 7U) {
50cabdff1aSopenharmony_ci            av_log(logctx, AV_LOG_ERROR, "chroma_log2_weight_denom %d is out of range\n", pwt->chroma_log2_weight_denom);
51cabdff1aSopenharmony_ci            pwt->chroma_log2_weight_denom = 0;
52cabdff1aSopenharmony_ci        }
53cabdff1aSopenharmony_ci        chroma_def = 1 << pwt->chroma_log2_weight_denom;
54cabdff1aSopenharmony_ci    }
55cabdff1aSopenharmony_ci
56cabdff1aSopenharmony_ci    for (list = 0; list < 2; list++) {
57cabdff1aSopenharmony_ci        pwt->luma_weight_flag[list]   = 0;
58cabdff1aSopenharmony_ci        pwt->chroma_weight_flag[list] = 0;
59cabdff1aSopenharmony_ci        for (i = 0; i < ref_count[list]; i++) {
60cabdff1aSopenharmony_ci            int luma_weight_flag, chroma_weight_flag;
61cabdff1aSopenharmony_ci
62cabdff1aSopenharmony_ci            luma_weight_flag = get_bits1(gb);
63cabdff1aSopenharmony_ci            if (luma_weight_flag) {
64cabdff1aSopenharmony_ci                pwt->luma_weight[i][list][0] = get_se_golomb(gb);
65cabdff1aSopenharmony_ci                pwt->luma_weight[i][list][1] = get_se_golomb(gb);
66cabdff1aSopenharmony_ci                if ((int8_t)pwt->luma_weight[i][list][0] != pwt->luma_weight[i][list][0] ||
67cabdff1aSopenharmony_ci                    (int8_t)pwt->luma_weight[i][list][1] != pwt->luma_weight[i][list][1])
68cabdff1aSopenharmony_ci                    goto out_range_weight;
69cabdff1aSopenharmony_ci                if (pwt->luma_weight[i][list][0] != luma_def ||
70cabdff1aSopenharmony_ci                    pwt->luma_weight[i][list][1] != 0) {
71cabdff1aSopenharmony_ci                    pwt->use_weight             = 1;
72cabdff1aSopenharmony_ci                    pwt->luma_weight_flag[list] = 1;
73cabdff1aSopenharmony_ci                }
74cabdff1aSopenharmony_ci            } else {
75cabdff1aSopenharmony_ci                pwt->luma_weight[i][list][0] = luma_def;
76cabdff1aSopenharmony_ci                pwt->luma_weight[i][list][1] = 0;
77cabdff1aSopenharmony_ci            }
78cabdff1aSopenharmony_ci
79cabdff1aSopenharmony_ci            if (sps->chroma_format_idc) {
80cabdff1aSopenharmony_ci                chroma_weight_flag = get_bits1(gb);
81cabdff1aSopenharmony_ci                if (chroma_weight_flag) {
82cabdff1aSopenharmony_ci                    int j;
83cabdff1aSopenharmony_ci                    for (j = 0; j < 2; j++) {
84cabdff1aSopenharmony_ci                        pwt->chroma_weight[i][list][j][0] = get_se_golomb(gb);
85cabdff1aSopenharmony_ci                        pwt->chroma_weight[i][list][j][1] = get_se_golomb(gb);
86cabdff1aSopenharmony_ci                        if ((int8_t)pwt->chroma_weight[i][list][j][0] != pwt->chroma_weight[i][list][j][0] ||
87cabdff1aSopenharmony_ci                            (int8_t)pwt->chroma_weight[i][list][j][1] != pwt->chroma_weight[i][list][j][1]) {
88cabdff1aSopenharmony_ci                            pwt->chroma_weight[i][list][j][0] = chroma_def;
89cabdff1aSopenharmony_ci                            pwt->chroma_weight[i][list][j][1] = 0;
90cabdff1aSopenharmony_ci                            goto out_range_weight;
91cabdff1aSopenharmony_ci                        }
92cabdff1aSopenharmony_ci                        if (pwt->chroma_weight[i][list][j][0] != chroma_def ||
93cabdff1aSopenharmony_ci                            pwt->chroma_weight[i][list][j][1] != 0) {
94cabdff1aSopenharmony_ci                            pwt->use_weight_chroma        = 1;
95cabdff1aSopenharmony_ci                            pwt->chroma_weight_flag[list] = 1;
96cabdff1aSopenharmony_ci                        }
97cabdff1aSopenharmony_ci                    }
98cabdff1aSopenharmony_ci                } else {
99cabdff1aSopenharmony_ci                    int j;
100cabdff1aSopenharmony_ci                    for (j = 0; j < 2; j++) {
101cabdff1aSopenharmony_ci                        pwt->chroma_weight[i][list][j][0] = chroma_def;
102cabdff1aSopenharmony_ci                        pwt->chroma_weight[i][list][j][1] = 0;
103cabdff1aSopenharmony_ci                    }
104cabdff1aSopenharmony_ci                }
105cabdff1aSopenharmony_ci            }
106cabdff1aSopenharmony_ci
107cabdff1aSopenharmony_ci            // for MBAFF
108cabdff1aSopenharmony_ci            if (picture_structure == PICT_FRAME) {
109cabdff1aSopenharmony_ci                pwt->luma_weight[16 + 2 * i][list][0] = pwt->luma_weight[16 + 2 * i + 1][list][0] = pwt->luma_weight[i][list][0];
110cabdff1aSopenharmony_ci                pwt->luma_weight[16 + 2 * i][list][1] = pwt->luma_weight[16 + 2 * i + 1][list][1] = pwt->luma_weight[i][list][1];
111cabdff1aSopenharmony_ci                if (sps->chroma_format_idc) {
112cabdff1aSopenharmony_ci                    for (j = 0; j < 2; j++) {
113cabdff1aSopenharmony_ci                        pwt->chroma_weight[16 + 2 * i][list][j][0] = pwt->chroma_weight[16 + 2 * i + 1][list][j][0] = pwt->chroma_weight[i][list][j][0];
114cabdff1aSopenharmony_ci                        pwt->chroma_weight[16 + 2 * i][list][j][1] = pwt->chroma_weight[16 + 2 * i + 1][list][j][1] = pwt->chroma_weight[i][list][j][1];
115cabdff1aSopenharmony_ci                    }
116cabdff1aSopenharmony_ci                }
117cabdff1aSopenharmony_ci            }
118cabdff1aSopenharmony_ci        }
119cabdff1aSopenharmony_ci        if (slice_type_nos != AV_PICTURE_TYPE_B)
120cabdff1aSopenharmony_ci            break;
121cabdff1aSopenharmony_ci    }
122cabdff1aSopenharmony_ci    pwt->use_weight = pwt->use_weight || pwt->use_weight_chroma;
123cabdff1aSopenharmony_ci    return 0;
124cabdff1aSopenharmony_ciout_range_weight:
125cabdff1aSopenharmony_ci    avpriv_request_sample(logctx, "Out of range weight");
126cabdff1aSopenharmony_ci    return AVERROR_INVALIDDATA;
127cabdff1aSopenharmony_ci}
128cabdff1aSopenharmony_ci
129cabdff1aSopenharmony_ci/**
130cabdff1aSopenharmony_ci * Check if the top & left blocks are available if needed and
131cabdff1aSopenharmony_ci * change the dc mode so it only uses the available blocks.
132cabdff1aSopenharmony_ci */
133cabdff1aSopenharmony_ciint ff_h264_check_intra4x4_pred_mode(int8_t *pred_mode_cache, void *logctx,
134cabdff1aSopenharmony_ci                                     int top_samples_available, int left_samples_available)
135cabdff1aSopenharmony_ci{
136cabdff1aSopenharmony_ci    static const int8_t top[12] = {
137cabdff1aSopenharmony_ci        -1, 0, LEFT_DC_PRED, -1, -1, -1, -1, -1, 0
138cabdff1aSopenharmony_ci    };
139cabdff1aSopenharmony_ci    static const int8_t left[12] = {
140cabdff1aSopenharmony_ci        0, -1, TOP_DC_PRED, 0, -1, -1, -1, 0, -1, DC_128_PRED
141cabdff1aSopenharmony_ci    };
142cabdff1aSopenharmony_ci    int i;
143cabdff1aSopenharmony_ci
144cabdff1aSopenharmony_ci    if (!(top_samples_available & 0x8000)) {
145cabdff1aSopenharmony_ci        for (i = 0; i < 4; i++) {
146cabdff1aSopenharmony_ci            int status = top[pred_mode_cache[scan8[0] + i]];
147cabdff1aSopenharmony_ci            if (status < 0) {
148cabdff1aSopenharmony_ci                av_log(logctx, AV_LOG_ERROR,
149cabdff1aSopenharmony_ci                       "top block unavailable for requested intra mode %d\n",
150cabdff1aSopenharmony_ci                       status);
151cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
152cabdff1aSopenharmony_ci            } else if (status) {
153cabdff1aSopenharmony_ci                pred_mode_cache[scan8[0] + i] = status;
154cabdff1aSopenharmony_ci            }
155cabdff1aSopenharmony_ci        }
156cabdff1aSopenharmony_ci    }
157cabdff1aSopenharmony_ci
158cabdff1aSopenharmony_ci    if ((left_samples_available & 0x8888) != 0x8888) {
159cabdff1aSopenharmony_ci        static const int mask[4] = { 0x8000, 0x2000, 0x80, 0x20 };
160cabdff1aSopenharmony_ci        for (i = 0; i < 4; i++)
161cabdff1aSopenharmony_ci            if (!(left_samples_available & mask[i])) {
162cabdff1aSopenharmony_ci                int status = left[pred_mode_cache[scan8[0] + 8 * i]];
163cabdff1aSopenharmony_ci                if (status < 0) {
164cabdff1aSopenharmony_ci                    av_log(logctx, AV_LOG_ERROR,
165cabdff1aSopenharmony_ci                           "left block unavailable for requested intra4x4 mode %d\n",
166cabdff1aSopenharmony_ci                           status);
167cabdff1aSopenharmony_ci                    return AVERROR_INVALIDDATA;
168cabdff1aSopenharmony_ci                } else if (status) {
169cabdff1aSopenharmony_ci                    pred_mode_cache[scan8[0] + 8 * i] = status;
170cabdff1aSopenharmony_ci                }
171cabdff1aSopenharmony_ci            }
172cabdff1aSopenharmony_ci    }
173cabdff1aSopenharmony_ci
174cabdff1aSopenharmony_ci    return 0;
175cabdff1aSopenharmony_ci}
176cabdff1aSopenharmony_ci
177cabdff1aSopenharmony_ci/**
178cabdff1aSopenharmony_ci * Check if the top & left blocks are available if needed and
179cabdff1aSopenharmony_ci * change the dc mode so it only uses the available blocks.
180cabdff1aSopenharmony_ci */
181cabdff1aSopenharmony_ciint ff_h264_check_intra_pred_mode(void *logctx, int top_samples_available,
182cabdff1aSopenharmony_ci                                  int left_samples_available,
183cabdff1aSopenharmony_ci                                  int mode, int is_chroma)
184cabdff1aSopenharmony_ci{
185cabdff1aSopenharmony_ci    static const int8_t top[4]  = { LEFT_DC_PRED8x8, 1, -1, -1 };
186cabdff1aSopenharmony_ci    static const int8_t left[5] = { TOP_DC_PRED8x8, -1,  2, -1, DC_128_PRED8x8 };
187cabdff1aSopenharmony_ci
188cabdff1aSopenharmony_ci    if (mode > 3U) {
189cabdff1aSopenharmony_ci        av_log(logctx, AV_LOG_ERROR,
190cabdff1aSopenharmony_ci               "out of range intra chroma pred mode\n");
191cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
192cabdff1aSopenharmony_ci    }
193cabdff1aSopenharmony_ci
194cabdff1aSopenharmony_ci    if (!(top_samples_available & 0x8000)) {
195cabdff1aSopenharmony_ci        mode = top[mode];
196cabdff1aSopenharmony_ci        if (mode < 0) {
197cabdff1aSopenharmony_ci            av_log(logctx, AV_LOG_ERROR,
198cabdff1aSopenharmony_ci                   "top block unavailable for requested intra mode\n");
199cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
200cabdff1aSopenharmony_ci        }
201cabdff1aSopenharmony_ci    }
202cabdff1aSopenharmony_ci
203cabdff1aSopenharmony_ci    if ((left_samples_available & 0x8080) != 0x8080) {
204cabdff1aSopenharmony_ci        mode = left[mode];
205cabdff1aSopenharmony_ci        if (mode < 0) {
206cabdff1aSopenharmony_ci            av_log(logctx, AV_LOG_ERROR,
207cabdff1aSopenharmony_ci                   "left block unavailable for requested intra mode\n");
208cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
209cabdff1aSopenharmony_ci        }
210cabdff1aSopenharmony_ci        if (is_chroma && (left_samples_available & 0x8080)) {
211cabdff1aSopenharmony_ci            // mad cow disease mode, aka MBAFF + constrained_intra_pred
212cabdff1aSopenharmony_ci            mode = ALZHEIMER_DC_L0T_PRED8x8 +
213cabdff1aSopenharmony_ci                   (!(left_samples_available & 0x8000)) +
214cabdff1aSopenharmony_ci                   2 * (mode == DC_128_PRED8x8);
215cabdff1aSopenharmony_ci        }
216cabdff1aSopenharmony_ci    }
217cabdff1aSopenharmony_ci
218cabdff1aSopenharmony_ci    return mode;
219cabdff1aSopenharmony_ci}
220cabdff1aSopenharmony_ci
221cabdff1aSopenharmony_ciint ff_h264_parse_ref_count(int *plist_count, int ref_count[2],
222cabdff1aSopenharmony_ci                            GetBitContext *gb, const PPS *pps,
223cabdff1aSopenharmony_ci                            int slice_type_nos, int picture_structure, void *logctx)
224cabdff1aSopenharmony_ci{
225cabdff1aSopenharmony_ci    int list_count;
226cabdff1aSopenharmony_ci    int num_ref_idx_active_override_flag;
227cabdff1aSopenharmony_ci
228cabdff1aSopenharmony_ci    // set defaults, might be overridden a few lines later
229cabdff1aSopenharmony_ci    ref_count[0] = pps->ref_count[0];
230cabdff1aSopenharmony_ci    ref_count[1] = pps->ref_count[1];
231cabdff1aSopenharmony_ci
232cabdff1aSopenharmony_ci    if (slice_type_nos != AV_PICTURE_TYPE_I) {
233cabdff1aSopenharmony_ci        unsigned max[2];
234cabdff1aSopenharmony_ci        max[0] = max[1] = picture_structure == PICT_FRAME ? 15 : 31;
235cabdff1aSopenharmony_ci
236cabdff1aSopenharmony_ci        num_ref_idx_active_override_flag = get_bits1(gb);
237cabdff1aSopenharmony_ci
238cabdff1aSopenharmony_ci        if (num_ref_idx_active_override_flag) {
239cabdff1aSopenharmony_ci            ref_count[0] = get_ue_golomb(gb) + 1;
240cabdff1aSopenharmony_ci            if (slice_type_nos == AV_PICTURE_TYPE_B) {
241cabdff1aSopenharmony_ci                ref_count[1] = get_ue_golomb(gb) + 1;
242cabdff1aSopenharmony_ci            } else
243cabdff1aSopenharmony_ci                // full range is spec-ok in this case, even for frames
244cabdff1aSopenharmony_ci                ref_count[1] = 1;
245cabdff1aSopenharmony_ci        }
246cabdff1aSopenharmony_ci
247cabdff1aSopenharmony_ci        if (slice_type_nos == AV_PICTURE_TYPE_B)
248cabdff1aSopenharmony_ci            list_count = 2;
249cabdff1aSopenharmony_ci        else
250cabdff1aSopenharmony_ci            list_count = 1;
251cabdff1aSopenharmony_ci
252cabdff1aSopenharmony_ci        if (ref_count[0] - 1 > max[0] || (list_count == 2 && (ref_count[1] - 1 > max[1]))) {
253cabdff1aSopenharmony_ci            av_log(logctx, AV_LOG_ERROR, "reference overflow %u > %u or %u > %u\n",
254cabdff1aSopenharmony_ci                   ref_count[0] - 1, max[0], ref_count[1] - 1, max[1]);
255cabdff1aSopenharmony_ci            ref_count[0] = ref_count[1] = 0;
256cabdff1aSopenharmony_ci            *plist_count = 0;
257cabdff1aSopenharmony_ci            goto fail;
258cabdff1aSopenharmony_ci        } else if (ref_count[1] - 1 > max[1]) {
259cabdff1aSopenharmony_ci            av_log(logctx, AV_LOG_DEBUG, "reference overflow %u > %u \n",
260cabdff1aSopenharmony_ci                   ref_count[1] - 1, max[1]);
261cabdff1aSopenharmony_ci            ref_count[1] = 0;
262cabdff1aSopenharmony_ci        }
263cabdff1aSopenharmony_ci
264cabdff1aSopenharmony_ci    } else {
265cabdff1aSopenharmony_ci        list_count   = 0;
266cabdff1aSopenharmony_ci        ref_count[0] = ref_count[1] = 0;
267cabdff1aSopenharmony_ci    }
268cabdff1aSopenharmony_ci
269cabdff1aSopenharmony_ci    *plist_count = list_count;
270cabdff1aSopenharmony_ci
271cabdff1aSopenharmony_ci    return 0;
272cabdff1aSopenharmony_cifail:
273cabdff1aSopenharmony_ci    *plist_count = 0;
274cabdff1aSopenharmony_ci    ref_count[0] = 0;
275cabdff1aSopenharmony_ci    ref_count[1] = 0;
276cabdff1aSopenharmony_ci    return AVERROR_INVALIDDATA;
277cabdff1aSopenharmony_ci}
278cabdff1aSopenharmony_ci
279cabdff1aSopenharmony_ciint ff_h264_init_poc(int pic_field_poc[2], int *pic_poc,
280cabdff1aSopenharmony_ci                     const SPS *sps, H264POCContext *pc,
281cabdff1aSopenharmony_ci                     int picture_structure, int nal_ref_idc)
282cabdff1aSopenharmony_ci{
283cabdff1aSopenharmony_ci    const int max_frame_num = 1 << sps->log2_max_frame_num;
284cabdff1aSopenharmony_ci    int64_t field_poc[2];
285cabdff1aSopenharmony_ci
286cabdff1aSopenharmony_ci    pc->frame_num_offset = pc->prev_frame_num_offset;
287cabdff1aSopenharmony_ci    if (pc->frame_num < pc->prev_frame_num)
288cabdff1aSopenharmony_ci        pc->frame_num_offset += max_frame_num;
289cabdff1aSopenharmony_ci
290cabdff1aSopenharmony_ci    if (sps->poc_type == 0) {
291cabdff1aSopenharmony_ci        const int max_poc_lsb = 1 << sps->log2_max_poc_lsb;
292cabdff1aSopenharmony_ci        if (pc->prev_poc_lsb < 0)
293cabdff1aSopenharmony_ci            pc->prev_poc_lsb =  pc->poc_lsb;
294cabdff1aSopenharmony_ci
295cabdff1aSopenharmony_ci        if (pc->poc_lsb < pc->prev_poc_lsb &&
296cabdff1aSopenharmony_ci            pc->prev_poc_lsb - pc->poc_lsb >= max_poc_lsb / 2)
297cabdff1aSopenharmony_ci            pc->poc_msb = pc->prev_poc_msb + max_poc_lsb;
298cabdff1aSopenharmony_ci        else if (pc->poc_lsb > pc->prev_poc_lsb &&
299cabdff1aSopenharmony_ci                 pc->prev_poc_lsb - pc->poc_lsb < -max_poc_lsb / 2)
300cabdff1aSopenharmony_ci            pc->poc_msb = pc->prev_poc_msb - max_poc_lsb;
301cabdff1aSopenharmony_ci        else
302cabdff1aSopenharmony_ci            pc->poc_msb = pc->prev_poc_msb;
303cabdff1aSopenharmony_ci        field_poc[0] =
304cabdff1aSopenharmony_ci        field_poc[1] = pc->poc_msb + pc->poc_lsb;
305cabdff1aSopenharmony_ci        if (picture_structure == PICT_FRAME)
306cabdff1aSopenharmony_ci            field_poc[1] += pc->delta_poc_bottom;
307cabdff1aSopenharmony_ci    } else if (sps->poc_type == 1) {
308cabdff1aSopenharmony_ci        int abs_frame_num;
309cabdff1aSopenharmony_ci        int64_t expected_delta_per_poc_cycle, expectedpoc;
310cabdff1aSopenharmony_ci        int i;
311cabdff1aSopenharmony_ci
312cabdff1aSopenharmony_ci        if (sps->poc_cycle_length != 0)
313cabdff1aSopenharmony_ci            abs_frame_num = pc->frame_num_offset + pc->frame_num;
314cabdff1aSopenharmony_ci        else
315cabdff1aSopenharmony_ci            abs_frame_num = 0;
316cabdff1aSopenharmony_ci
317cabdff1aSopenharmony_ci        if (nal_ref_idc == 0 && abs_frame_num > 0)
318cabdff1aSopenharmony_ci            abs_frame_num--;
319cabdff1aSopenharmony_ci
320cabdff1aSopenharmony_ci        expected_delta_per_poc_cycle = 0;
321cabdff1aSopenharmony_ci        for (i = 0; i < sps->poc_cycle_length; i++)
322cabdff1aSopenharmony_ci            // FIXME integrate during sps parse
323cabdff1aSopenharmony_ci            expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i];
324cabdff1aSopenharmony_ci
325cabdff1aSopenharmony_ci        if (abs_frame_num > 0) {
326cabdff1aSopenharmony_ci            int poc_cycle_cnt          = (abs_frame_num - 1) / sps->poc_cycle_length;
327cabdff1aSopenharmony_ci            int frame_num_in_poc_cycle = (abs_frame_num - 1) % sps->poc_cycle_length;
328cabdff1aSopenharmony_ci
329cabdff1aSopenharmony_ci            expectedpoc = poc_cycle_cnt * expected_delta_per_poc_cycle;
330cabdff1aSopenharmony_ci            for (i = 0; i <= frame_num_in_poc_cycle; i++)
331cabdff1aSopenharmony_ci                expectedpoc = expectedpoc + sps->offset_for_ref_frame[i];
332cabdff1aSopenharmony_ci        } else
333cabdff1aSopenharmony_ci            expectedpoc = 0;
334cabdff1aSopenharmony_ci
335cabdff1aSopenharmony_ci        if (nal_ref_idc == 0)
336cabdff1aSopenharmony_ci            expectedpoc = expectedpoc + sps->offset_for_non_ref_pic;
337cabdff1aSopenharmony_ci
338cabdff1aSopenharmony_ci        field_poc[0] = expectedpoc + pc->delta_poc[0];
339cabdff1aSopenharmony_ci        field_poc[1] = field_poc[0] + sps->offset_for_top_to_bottom_field;
340cabdff1aSopenharmony_ci
341cabdff1aSopenharmony_ci        if (picture_structure == PICT_FRAME)
342cabdff1aSopenharmony_ci            field_poc[1] += pc->delta_poc[1];
343cabdff1aSopenharmony_ci    } else {
344cabdff1aSopenharmony_ci        int poc = 2 * (pc->frame_num_offset + pc->frame_num);
345cabdff1aSopenharmony_ci
346cabdff1aSopenharmony_ci        if (!nal_ref_idc)
347cabdff1aSopenharmony_ci            poc--;
348cabdff1aSopenharmony_ci
349cabdff1aSopenharmony_ci        field_poc[0] = poc;
350cabdff1aSopenharmony_ci        field_poc[1] = poc;
351cabdff1aSopenharmony_ci    }
352cabdff1aSopenharmony_ci
353cabdff1aSopenharmony_ci    if (   field_poc[0] != (int)field_poc[0]
354cabdff1aSopenharmony_ci        || field_poc[1] != (int)field_poc[1])
355cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
356cabdff1aSopenharmony_ci
357cabdff1aSopenharmony_ci    if (picture_structure != PICT_BOTTOM_FIELD)
358cabdff1aSopenharmony_ci        pic_field_poc[0] = field_poc[0];
359cabdff1aSopenharmony_ci    if (picture_structure != PICT_TOP_FIELD)
360cabdff1aSopenharmony_ci        pic_field_poc[1] = field_poc[1];
361cabdff1aSopenharmony_ci    *pic_poc = FFMIN(pic_field_poc[0], pic_field_poc[1]);
362cabdff1aSopenharmony_ci
363cabdff1aSopenharmony_ci    return 0;
364cabdff1aSopenharmony_ci}
365cabdff1aSopenharmony_ci
366cabdff1aSopenharmony_cistatic int decode_extradata_ps(const uint8_t *data, int size, H264ParamSets *ps,
367cabdff1aSopenharmony_ci                               int is_avc, void *logctx)
368cabdff1aSopenharmony_ci{
369cabdff1aSopenharmony_ci    H2645Packet pkt = { 0 };
370cabdff1aSopenharmony_ci    int i, ret = 0;
371cabdff1aSopenharmony_ci
372cabdff1aSopenharmony_ci    ret = ff_h2645_packet_split(&pkt, data, size, logctx, is_avc, 2, AV_CODEC_ID_H264, 1, 0);
373cabdff1aSopenharmony_ci    if (ret < 0) {
374cabdff1aSopenharmony_ci        ret = 0;
375cabdff1aSopenharmony_ci        goto fail;
376cabdff1aSopenharmony_ci    }
377cabdff1aSopenharmony_ci
378cabdff1aSopenharmony_ci    for (i = 0; i < pkt.nb_nals; i++) {
379cabdff1aSopenharmony_ci        H2645NAL *nal = &pkt.nals[i];
380cabdff1aSopenharmony_ci        switch (nal->type) {
381cabdff1aSopenharmony_ci        case H264_NAL_SPS: {
382cabdff1aSopenharmony_ci            GetBitContext tmp_gb = nal->gb;
383cabdff1aSopenharmony_ci            ret = ff_h264_decode_seq_parameter_set(&tmp_gb, logctx, ps, 0);
384cabdff1aSopenharmony_ci            if (ret >= 0)
385cabdff1aSopenharmony_ci                break;
386cabdff1aSopenharmony_ci            av_log(logctx, AV_LOG_DEBUG,
387cabdff1aSopenharmony_ci                   "SPS decoding failure, trying again with the complete NAL\n");
388cabdff1aSopenharmony_ci            init_get_bits8(&tmp_gb, nal->raw_data + 1, nal->raw_size - 1);
389cabdff1aSopenharmony_ci            ret = ff_h264_decode_seq_parameter_set(&tmp_gb, logctx, ps, 0);
390cabdff1aSopenharmony_ci            if (ret >= 0)
391cabdff1aSopenharmony_ci                break;
392cabdff1aSopenharmony_ci            ret = ff_h264_decode_seq_parameter_set(&nal->gb, logctx, ps, 1);
393cabdff1aSopenharmony_ci            if (ret < 0)
394cabdff1aSopenharmony_ci                goto fail;
395cabdff1aSopenharmony_ci            break;
396cabdff1aSopenharmony_ci        }
397cabdff1aSopenharmony_ci        case H264_NAL_PPS:
398cabdff1aSopenharmony_ci            ret = ff_h264_decode_picture_parameter_set(&nal->gb, logctx, ps,
399cabdff1aSopenharmony_ci                                                       nal->size_bits);
400cabdff1aSopenharmony_ci            if (ret < 0)
401cabdff1aSopenharmony_ci                goto fail;
402cabdff1aSopenharmony_ci            break;
403cabdff1aSopenharmony_ci        default:
404cabdff1aSopenharmony_ci            av_log(logctx, AV_LOG_VERBOSE, "Ignoring NAL type %d in extradata\n",
405cabdff1aSopenharmony_ci                   nal->type);
406cabdff1aSopenharmony_ci            break;
407cabdff1aSopenharmony_ci        }
408cabdff1aSopenharmony_ci    }
409cabdff1aSopenharmony_ci
410cabdff1aSopenharmony_cifail:
411cabdff1aSopenharmony_ci    ff_h2645_packet_uninit(&pkt);
412cabdff1aSopenharmony_ci    return ret;
413cabdff1aSopenharmony_ci}
414cabdff1aSopenharmony_ci
415cabdff1aSopenharmony_ci/* There are (invalid) samples in the wild with mp4-style extradata, where the
416cabdff1aSopenharmony_ci * parameter sets are stored unescaped (i.e. as RBSP).
417cabdff1aSopenharmony_ci * This function catches the parameter set decoding failure and tries again
418cabdff1aSopenharmony_ci * after escaping it */
419cabdff1aSopenharmony_cistatic int decode_extradata_ps_mp4(const uint8_t *buf, int buf_size, H264ParamSets *ps,
420cabdff1aSopenharmony_ci                                   int err_recognition, void *logctx)
421cabdff1aSopenharmony_ci{
422cabdff1aSopenharmony_ci    int ret;
423cabdff1aSopenharmony_ci
424cabdff1aSopenharmony_ci    ret = decode_extradata_ps(buf, buf_size, ps, 1, logctx);
425cabdff1aSopenharmony_ci    if (ret < 0 && !(err_recognition & AV_EF_EXPLODE)) {
426cabdff1aSopenharmony_ci        GetByteContext gbc;
427cabdff1aSopenharmony_ci        PutByteContext pbc;
428cabdff1aSopenharmony_ci        uint8_t *escaped_buf;
429cabdff1aSopenharmony_ci        int escaped_buf_size;
430cabdff1aSopenharmony_ci
431cabdff1aSopenharmony_ci        av_log(logctx, AV_LOG_WARNING,
432cabdff1aSopenharmony_ci               "SPS decoding failure, trying again after escaping the NAL\n");
433cabdff1aSopenharmony_ci
434cabdff1aSopenharmony_ci        if (buf_size / 2 >= (INT16_MAX - AV_INPUT_BUFFER_PADDING_SIZE) / 3)
435cabdff1aSopenharmony_ci            return AVERROR(ERANGE);
436cabdff1aSopenharmony_ci        escaped_buf_size = buf_size * 3 / 2 + AV_INPUT_BUFFER_PADDING_SIZE;
437cabdff1aSopenharmony_ci        escaped_buf = av_mallocz(escaped_buf_size);
438cabdff1aSopenharmony_ci        if (!escaped_buf)
439cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
440cabdff1aSopenharmony_ci
441cabdff1aSopenharmony_ci        bytestream2_init(&gbc, buf, buf_size);
442cabdff1aSopenharmony_ci        bytestream2_init_writer(&pbc, escaped_buf, escaped_buf_size);
443cabdff1aSopenharmony_ci
444cabdff1aSopenharmony_ci        while (bytestream2_get_bytes_left(&gbc)) {
445cabdff1aSopenharmony_ci            if (bytestream2_get_bytes_left(&gbc) >= 3 &&
446cabdff1aSopenharmony_ci                bytestream2_peek_be24(&gbc) <= 3) {
447cabdff1aSopenharmony_ci                bytestream2_put_be24(&pbc, 3);
448cabdff1aSopenharmony_ci                bytestream2_skip(&gbc, 2);
449cabdff1aSopenharmony_ci            } else
450cabdff1aSopenharmony_ci                bytestream2_put_byte(&pbc, bytestream2_get_byte(&gbc));
451cabdff1aSopenharmony_ci        }
452cabdff1aSopenharmony_ci
453cabdff1aSopenharmony_ci        escaped_buf_size = bytestream2_tell_p(&pbc);
454cabdff1aSopenharmony_ci        AV_WB16(escaped_buf, escaped_buf_size - 2);
455cabdff1aSopenharmony_ci
456cabdff1aSopenharmony_ci        (void)decode_extradata_ps(escaped_buf, escaped_buf_size, ps, 1, logctx);
457cabdff1aSopenharmony_ci        // lorex.mp4 decodes ok even with extradata decoding failing
458cabdff1aSopenharmony_ci        av_freep(&escaped_buf);
459cabdff1aSopenharmony_ci    }
460cabdff1aSopenharmony_ci
461cabdff1aSopenharmony_ci    return 0;
462cabdff1aSopenharmony_ci}
463cabdff1aSopenharmony_ci
464cabdff1aSopenharmony_ciint ff_h264_decode_extradata(const uint8_t *data, int size, H264ParamSets *ps,
465cabdff1aSopenharmony_ci                             int *is_avc, int *nal_length_size,
466cabdff1aSopenharmony_ci                             int err_recognition, void *logctx)
467cabdff1aSopenharmony_ci{
468cabdff1aSopenharmony_ci    int ret;
469cabdff1aSopenharmony_ci
470cabdff1aSopenharmony_ci    if (!data || size <= 0)
471cabdff1aSopenharmony_ci        return -1;
472cabdff1aSopenharmony_ci
473cabdff1aSopenharmony_ci    if (data[0] == 1) {
474cabdff1aSopenharmony_ci        int i, cnt, nalsize;
475cabdff1aSopenharmony_ci        const uint8_t *p = data;
476cabdff1aSopenharmony_ci
477cabdff1aSopenharmony_ci        *is_avc = 1;
478cabdff1aSopenharmony_ci
479cabdff1aSopenharmony_ci        if (size < 7) {
480cabdff1aSopenharmony_ci            av_log(logctx, AV_LOG_ERROR, "avcC %d too short\n", size);
481cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
482cabdff1aSopenharmony_ci        }
483cabdff1aSopenharmony_ci
484cabdff1aSopenharmony_ci        // Decode sps from avcC
485cabdff1aSopenharmony_ci        cnt = *(p + 5) & 0x1f; // Number of sps
486cabdff1aSopenharmony_ci        p  += 6;
487cabdff1aSopenharmony_ci        for (i = 0; i < cnt; i++) {
488cabdff1aSopenharmony_ci            nalsize = AV_RB16(p) + 2;
489cabdff1aSopenharmony_ci            if (nalsize > size - (p - data))
490cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
491cabdff1aSopenharmony_ci            ret = decode_extradata_ps_mp4(p, nalsize, ps, err_recognition, logctx);
492cabdff1aSopenharmony_ci            if (ret < 0) {
493cabdff1aSopenharmony_ci                av_log(logctx, AV_LOG_ERROR,
494cabdff1aSopenharmony_ci                       "Decoding sps %d from avcC failed\n", i);
495cabdff1aSopenharmony_ci                return ret;
496cabdff1aSopenharmony_ci            }
497cabdff1aSopenharmony_ci            p += nalsize;
498cabdff1aSopenharmony_ci        }
499cabdff1aSopenharmony_ci        // Decode pps from avcC
500cabdff1aSopenharmony_ci        cnt = *(p++); // Number of pps
501cabdff1aSopenharmony_ci        for (i = 0; i < cnt; i++) {
502cabdff1aSopenharmony_ci            nalsize = AV_RB16(p) + 2;
503cabdff1aSopenharmony_ci            if (nalsize > size - (p - data))
504cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
505cabdff1aSopenharmony_ci            ret = decode_extradata_ps_mp4(p, nalsize, ps, err_recognition, logctx);
506cabdff1aSopenharmony_ci            if (ret < 0) {
507cabdff1aSopenharmony_ci                av_log(logctx, AV_LOG_ERROR,
508cabdff1aSopenharmony_ci                       "Decoding pps %d from avcC failed\n", i);
509cabdff1aSopenharmony_ci                return ret;
510cabdff1aSopenharmony_ci            }
511cabdff1aSopenharmony_ci            p += nalsize;
512cabdff1aSopenharmony_ci        }
513cabdff1aSopenharmony_ci        // Store right nal length size that will be used to parse all other nals
514cabdff1aSopenharmony_ci        *nal_length_size = (data[4] & 0x03) + 1;
515cabdff1aSopenharmony_ci    } else {
516cabdff1aSopenharmony_ci        *is_avc = 0;
517cabdff1aSopenharmony_ci        ret = decode_extradata_ps(data, size, ps, 0, logctx);
518cabdff1aSopenharmony_ci        if (ret < 0)
519cabdff1aSopenharmony_ci            return ret;
520cabdff1aSopenharmony_ci    }
521cabdff1aSopenharmony_ci    return size;
522cabdff1aSopenharmony_ci}
523cabdff1aSopenharmony_ci
524cabdff1aSopenharmony_ci/**
525cabdff1aSopenharmony_ci * Compute profile from profile_idc and constraint_set?_flags.
526cabdff1aSopenharmony_ci *
527cabdff1aSopenharmony_ci * @param sps SPS
528cabdff1aSopenharmony_ci *
529cabdff1aSopenharmony_ci * @return profile as defined by FF_PROFILE_H264_*
530cabdff1aSopenharmony_ci */
531cabdff1aSopenharmony_ciint ff_h264_get_profile(const SPS *sps)
532cabdff1aSopenharmony_ci{
533cabdff1aSopenharmony_ci    int profile = sps->profile_idc;
534cabdff1aSopenharmony_ci
535cabdff1aSopenharmony_ci    switch (sps->profile_idc) {
536cabdff1aSopenharmony_ci    case FF_PROFILE_H264_BASELINE:
537cabdff1aSopenharmony_ci        // constraint_set1_flag set to 1
538cabdff1aSopenharmony_ci        profile |= (sps->constraint_set_flags & 1 << 1) ? FF_PROFILE_H264_CONSTRAINED : 0;
539cabdff1aSopenharmony_ci        break;
540cabdff1aSopenharmony_ci    case FF_PROFILE_H264_HIGH_10:
541cabdff1aSopenharmony_ci    case FF_PROFILE_H264_HIGH_422:
542cabdff1aSopenharmony_ci    case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
543cabdff1aSopenharmony_ci        // constraint_set3_flag set to 1
544cabdff1aSopenharmony_ci        profile |= (sps->constraint_set_flags & 1 << 3) ? FF_PROFILE_H264_INTRA : 0;
545cabdff1aSopenharmony_ci        break;
546cabdff1aSopenharmony_ci    }
547cabdff1aSopenharmony_ci
548cabdff1aSopenharmony_ci    return profile;
549cabdff1aSopenharmony_ci}
550