ffmpeg | branch: master | Michael Niedermayer <mich...@niedermayer.cc> | Tue Oct 1 22:08:08 2024 +0200| [2c71366d3b09ad25e7d93839344d731a87646b42] | committer: Michael Niedermayer
avcodec/ffv1: Implement new slice tiling This fixes corner cases (requires version 4 or a spec update) Fixes: Ticket5548 Sponsored-by: Sovereign Tech Fund Signed-off-by: Michael Niedermayer <mich...@niedermayer.cc> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2c71366d3b09ad25e7d93839344d731a87646b42 --- libavcodec/ffv1.c | 21 +++++++++++++++++---- libavcodec/ffv1.h | 5 +++++ libavcodec/ffv1dec.c | 8 ++++---- libavcodec/ffv1enc.c | 2 +- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index 2b8564c2f5..6c953e860f 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -126,6 +126,19 @@ int ff_need_new_slices(int width, int num_h_slices, int chroma_shift) { return width % mpw && (width - i) % mpw == 0; } +int ff_slice_coord(const FFV1Context *f, int width, int sx, int num_h_slices, int chroma_shift) { + int mpw = 1<<chroma_shift; + int awidth = FFALIGN(width, mpw); + + if (f->version < 4 || f->version == 4 && f->micro_version < 3) + return width * sx / num_h_slices; + + sx = (2LL * awidth * sx + num_h_slices * mpw) / (2 * num_h_slices * mpw) * mpw; + if (sx == awidth) + sx = width; + return sx; +} + av_cold int ff_ffv1_init_slice_contexts(FFV1Context *f) { int max_slice_count = f->num_h_slices * f->num_v_slices; @@ -142,10 +155,10 @@ av_cold int ff_ffv1_init_slice_contexts(FFV1Context *f) FFV1SliceContext *sc = &f->slices[i]; int sx = i % f->num_h_slices; int sy = i / f->num_h_slices; - int sxs = f->avctx->width * sx / f->num_h_slices; - int sxe = f->avctx->width * (sx + 1) / f->num_h_slices; - int sys = f->avctx->height * sy / f->num_v_slices; - int sye = f->avctx->height * (sy + 1) / f->num_v_slices; + int sxs = ff_slice_coord(f, f->avctx->width , sx , f->num_h_slices, f->chroma_h_shift); + int sxe = ff_slice_coord(f, f->avctx->width , sx + 1, f->num_h_slices, f->chroma_h_shift); + int sys = ff_slice_coord(f, f->avctx->height, sy , f->num_v_slices, f->chroma_v_shift); + int sye = ff_slice_coord(f, f->avctx->height, sy + 1, f->num_v_slices, f->chroma_v_shift); sc->slice_width = sxe - sxs; sc->slice_height = sye - sys; diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h index 4f5a8ab2be..2af457be27 100644 --- a/libavcodec/ffv1.h +++ b/libavcodec/ffv1.h @@ -177,6 +177,11 @@ void ff_ffv1_clear_slice_state(const FFV1Context *f, FFV1SliceContext *sc); int ff_ffv1_close(AVCodecContext *avctx); int ff_need_new_slices(int width, int num_h_slices, int chroma_shift); +/** + * This is intended for both width and height + */ +int ff_slice_coord(const FFV1Context *f, int width, int sx, int num_h_slices, int chroma_shift); + static av_always_inline int fold(int diff, int bits) { if (bits == 8) diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index 5c099e49ad..ac8cc8a31d 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -187,10 +187,10 @@ static int decode_slice_header(const FFV1Context *f, if (sx > f->num_h_slices - sw || sy > f->num_v_slices - sh) return AVERROR_INVALIDDATA; - sc->slice_x = sx * (int64_t)f->width / f->num_h_slices; - sc->slice_y = sy * (int64_t)f->height / f->num_v_slices; - sc->slice_width = (sx + sw) * (int64_t)f->width / f->num_h_slices - sc->slice_x; - sc->slice_height = (sy + sh) * (int64_t)f->height / f->num_v_slices - sc->slice_y; + sc->slice_x = ff_slice_coord(f, f->width , sx , f->num_h_slices, f->chroma_h_shift); + sc->slice_y = ff_slice_coord(f, f->height, sy , f->num_v_slices, f->chroma_v_shift); + sc->slice_width = ff_slice_coord(f, f->width , sx + sw, f->num_h_slices, f->chroma_h_shift) - sc->slice_x; + sc->slice_height = ff_slice_coord(f, f->height, sy + sh, f->num_v_slices, f->chroma_v_shift) - sc->slice_y; av_assert0((unsigned)sc->slice_width <= f->width && (unsigned)sc->slice_height <= f->height); diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 0dbfebc1a1..a32059886c 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -416,7 +416,7 @@ static int write_extradata(FFV1Context *f) if (f->version == 3) { f->micro_version = 4; } else if (f->version == 4) - f->micro_version = 2; + f->micro_version = 3; put_symbol(&c, state, f->micro_version, 0); } _______________________________________________ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".