Thank you, Frank, Applied with some minor changes. On Sat, Jan 11, 2025 at 5:31 AM Frank Plowman <p...@frankplowman.com> wrote:
> The criteria for slice structure validity is similar to that of > subpicture structure validity that we saw not too long ago [1]. > The relationship between tiles and slices must satisfy the following > properties: > > * Exhaustivity. All tiles in a picture must belong to a slice. The > tiles cover the picture, so this implies the slices must cover the > picture. > * Mutual exclusivity. No tile may belong to more than one slice, i.e. > slices may not overlap. > > In most cases these properties are guaranteed by the syntax. There is > one noticable exception however: when pps_tile_idx_delta_present_flag is > equal to one, each slice is associated with a syntax element > pps_tile_idx_delta_val[i] which "specifies the difference between the > tile index of the tile containing the first CTU in the ( i + 1 )-th > rectangular slice and the tile index of the tile containing the first > CTU in the i-th rectangular slice" [2]. When these syntax elements are > present, the i-th slice can begin anywhere and the usual guarantees > provided by the syntax are lost. > > The patch detects slice structures which violate either of the two > properties above, and are therefore invalid, while building the > slice map. Should the slice map be determined to be invalid, an > AVERROR_INVALIDDATA is returned. This prevents issues including > segmentation faults when trying to decode, invalid bitstreams. > > [1]: https://ffmpeg.org//pipermail/ffmpeg-devel/2024-October/334470.html > [2]: H.266 (V3) Section 7.4.3.5, Picture parameter set RBSP semantics > > Signed-off-by: Frank Plowman <p...@frankplowman.com> > --- > libavcodec/vvc/ps.c | 39 ++++++++++++++++++++++++++++++++------- > 1 file changed, 32 insertions(+), 7 deletions(-) > > diff --git a/libavcodec/vvc/ps.c b/libavcodec/vvc/ps.c > index a5cf1d74bd..13f1cf02dd 100644 > --- a/libavcodec/vvc/ps.c > +++ b/libavcodec/vvc/ps.c > @@ -460,7 +460,7 @@ static int pps_one_tile_slices(VVCPPS *pps, const int > tile_idx, int i, int *off) > return i; > } > > -static void pps_multi_tiles_slice(VVCPPS *pps, const int tile_idx, const > int i, int *off) > +static int pps_multi_tiles_slice(VVCPPS *pps, int tile_idx, const int i, > int *off, int *tile_in_slice) > { > const H266RawPPS *r = pps->r; > int rx, ry, tile_x, tile_y; > @@ -470,32 +470,53 @@ static void pps_multi_tiles_slice(VVCPPS *pps, const > int tile_idx, const int i, > pps->num_ctus_in_slice[i] = 0; > for (int ty = tile_y; ty <= tile_y + > r->pps_slice_height_in_tiles_minus1[i]; ty++) { > for (int tx = tile_x; tx <= tile_x + > r->pps_slice_width_in_tiles_minus1[i]; tx++) { > + tile_idx = ty * r->num_tile_columns + tx; > + if (tile_in_slice[tile_idx]) > + return AVERROR_INVALIDDATA; > + tile_in_slice[tile_idx] = 1; > ctu_xy(&rx, &ry, tx, ty, pps); > pps->num_ctus_in_slice[i] += pps_add_ctus(pps, off, rx, ry, > r->col_width_val[tx], r->row_height_val[ty]); > } > } > + > + return 0; > } > > -static void pps_rect_slice(VVCPPS *pps, const VVCSPS *sps) > +static int pps_rect_slice(VVCPPS *pps, const VVCSPS *sps) > { > const H266RawPPS *r = pps->r; > + int tile_in_slice[VVC_MAX_TILES_PER_AU] = {0}; > int tile_idx = 0, off = 0; > + int ret; > > if (r->pps_single_slice_per_subpic_flag) { > pps_single_slice_per_subpic(pps, sps, &off); > - return; > + return 0; > } > > for (int i = 0; i < r->pps_num_slices_in_pic_minus1 + 1; i++) { > if (!r->pps_slice_width_in_tiles_minus1[i] && > !r->pps_slice_height_in_tiles_minus1[i]) { > + if (tile_in_slice[tile_idx]) { > + return AVERROR_INVALIDDATA; > + } > i = pps_one_tile_slices(pps, tile_idx, i, &off); > + tile_in_slice[tile_idx] = 1; > } else { > - pps_multi_tiles_slice(pps, tile_idx, i, &off); > + ret = pps_multi_tiles_slice(pps, tile_idx, i, &off, > tile_in_slice); > + if (ret < 0) > + return ret; > } > tile_idx = next_tile_idx(tile_idx, i, r); > } > + > + for (int i = 0; i < r->num_tiles_in_pic; i++) { > + if (!tile_in_slice[i]) > + return AVERROR_INVALIDDATA; > + } > + > + return 0; > } > > static void pps_no_rect_slice(VVCPPS* pps) > @@ -513,13 +534,17 @@ static void pps_no_rect_slice(VVCPPS* pps) > > static int pps_slice_map(VVCPPS *pps, const VVCSPS *sps) > { > + int ret; > + > pps->ctb_addr_in_slice = av_calloc(pps->ctb_count, > sizeof(*pps->ctb_addr_in_slice)); > if (!pps->ctb_addr_in_slice) > return AVERROR(ENOMEM); > > - if (pps->r->pps_rect_slice_flag) > - pps_rect_slice(pps, sps); > - else > + if (pps->r->pps_rect_slice_flag) { > + ret = pps_rect_slice(pps, sps); > + if (ret < 0) > + return AVERROR_INVALIDDATA; > + } else > pps_no_rect_slice(pps); > > return 0; > -- > 2.47.0 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".