aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michael@niedermayer.cc>2024-10-01 22:06:40 +0200
committerMichael Niedermayer <michael@niedermayer.cc>2024-10-10 19:34:09 +0200
commitb7ff66a35804275b25c1176cad560540785e8750 (patch)
tree96d80afcee7f23a6b704aad73dc7a63532232ea5
parent0f5592cfc73773b895e81ae1ab8404b0ff2dc6b1 (diff)
downloadffmpeg-b7ff66a35804275b25c1176cad560540785e8750.tar.gz
avcodec/ffv1enc: Prevent generation of files with broken slices
Fixes: Ticket5548 Sponsored-by: Sovereign Tech Fund Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r--libavcodec/ffv1.c7
-rw-r--r--libavcodec/ffv1.h1
-rw-r--r--libavcodec/ffv1enc.c4
3 files changed, 12 insertions, 0 deletions
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index 56a36e479f..2b8564c2f5 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -119,6 +119,13 @@ av_cold int ff_ffv1_init_slices_state(FFV1Context *f)
return 0;
}
+int ff_need_new_slices(int width, int num_h_slices, int chroma_shift) {
+ int mpw = 1<<chroma_shift;
+ int i = width * (int64_t)(num_h_slices - 1) / num_h_slices;
+
+ return width % mpw && (width - i) % mpw == 0;
+}
+
av_cold int ff_ffv1_init_slice_contexts(FFV1Context *f)
{
int max_slice_count = f->num_h_slices * f->num_v_slices;
diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h
index a35197964e..e19c0df014 100644
--- a/libavcodec/ffv1.h
+++ b/libavcodec/ffv1.h
@@ -171,6 +171,7 @@ PlaneContext *ff_ffv1_planes_alloc(void);
int ff_ffv1_allocate_initial_states(FFV1Context *f);
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);
static av_always_inline int fold(int diff, int bits)
{
diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
index 94d9830e07..56af7dc427 100644
--- a/libavcodec/ffv1enc.c
+++ b/libavcodec/ffv1enc.c
@@ -865,6 +865,10 @@ static av_cold int encode_init(AVCodecContext *avctx)
continue;
if (maxw * maxh * (int64_t)(s->bits_per_raw_sample+1) * plane_count > 8<<24)
continue;
+ if (s->version < 4)
+ if ( ff_need_new_slices(avctx->width , s->num_h_slices, s->chroma_h_shift)
+ ||ff_need_new_slices(avctx->height, s->num_v_slices, s->chroma_v_shift))
+ continue;
if (avctx->slices == s->num_h_slices * s->num_v_slices && avctx->slices <= MAX_SLICES || !avctx->slices)
goto slices_ok;
}