mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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 <michael@niedermayer.cc>
This commit is contained in:
parent
d147b3d7ec
commit
2c71366d3b
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user