On Fri, Oct 25, 2024 at 04:24:04AM +0200, Lynne via ffmpeg-devel wrote: > On 25/10/2024 03:57, Michael Niedermayer wrote: > > Sponsored-by: Sovereign Tech Fund > > Signed-off-by: Michael Niedermayer <mich...@niedermayer.cc> > > --- > > libavcodec/ffv1dec.c | 20 ++++++++++---------- > > libavcodec/ffv1dec_template.c | 3 +++ > > libavcodec/ffv1enc.c | 23 ++++++++++++----------- > > 3 files changed, 25 insertions(+), 21 deletions(-) > > > > diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c > > index ac8cc8a31dc..de5abfe9b41 100644 > > --- a/libavcodec/ffv1dec.c > > +++ b/libavcodec/ffv1dec.c > > @@ -120,9 +120,8 @@ static int is_input_end(RangeCoder *c, GetBitContext > > *gb, int ac) > > static int decode_plane(FFV1Context *f, FFV1SliceContext *sc, > > GetBitContext *gb, > > uint8_t *src, int w, int h, int stride, int > > plane_index, > > - int pixel_stride) > > + int pixel_stride, int ac) > > { > > - const int ac = f->ac; > > int x, y; > > int16_t *sample[2]; > > sample[0] = sc->sample_buffer + 3; > > @@ -273,6 +272,7 @@ static int decode_slice(AVCodecContext *c, void *arg) > > AVFrame * const p = f->picture.f; > > const int si = sc - f->slices; > > GetBitContext gb; > > + int ac = f->ac || sc->slice_coding_mode == 1; > > if (!(p->flags & AV_FRAME_FLAG_KEY) && f->last_picture.f) > > ff_progress_frame_await(&f->last_picture, si); > > @@ -305,7 +305,7 @@ static int decode_slice(AVCodecContext *c, void *arg) > > x = sc->slice_x; > > y = sc->slice_y; > > - if (f->ac == AC_GOLOMB_RICE) { > > + if (ac == AC_GOLOMB_RICE) { > > if (f->version == 3 && f->micro_version > 1 || f->version > 3) > > get_rac(&sc->c, (uint8_t[]) { 129 }); > > sc->ac_byte_count = f->version > 2 || (!x && !y) ? > > sc->c.bytestream - sc->c.bytestream_start - 1 : 0; > > @@ -320,17 +320,17 @@ static int decode_slice(AVCodecContext *c, void *arg) > > const int chroma_height = AV_CEIL_RSHIFT(height, > > f->chroma_v_shift); > > const int cx = x >> f->chroma_h_shift; > > const int cy = y >> f->chroma_v_shift; > > - decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0], > > width, height, p->linesize[0], 0, 1); > > + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0], > > width, height, p->linesize[0], 0, 1, ac); > > if (f->chroma_planes) { > > - decode_plane(f, sc, &gb, p->data[1] + ps*cx+cy*p->linesize[1], > > chroma_width, chroma_height, p->linesize[1], 1, 1); > > - decode_plane(f, sc, &gb, p->data[2] + ps*cx+cy*p->linesize[2], > > chroma_width, chroma_height, p->linesize[2], 1, 1); > > + decode_plane(f, sc, &gb, p->data[1] + ps*cx+cy*p->linesize[1], > > chroma_width, chroma_height, p->linesize[1], 1, 1, ac); > > + decode_plane(f, sc, &gb, p->data[2] + ps*cx+cy*p->linesize[2], > > chroma_width, chroma_height, p->linesize[2], 1, 1, ac); > > } > > if (f->transparency) > > - decode_plane(f, sc, &gb, p->data[3] + ps*x + y*p->linesize[3], > > width, height, p->linesize[3], (f->version >= 4 && !f->chroma_planes) ? 1 : > > 2, 1); > > + decode_plane(f, sc, &gb, p->data[3] + ps*x + y*p->linesize[3], > > width, height, p->linesize[3], (f->version >= 4 && !f->chroma_planes) ? 1 : > > 2, 1, ac); > > } else if (f->colorspace == 0) { > > - decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] > > , width, height, p->linesize[0], 0, 2); > > - decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] + > > 1, width, height, p->linesize[0], 1, 2); > > + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] > > , width, height, p->linesize[0], 0, 2, ac); > > + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] + > > 1, width, height, p->linesize[0], 1, 2, ac); > > } else if (f->use32bit) { > > uint8_t *planes[4] = { p->data[0] + ps * x + y * p->linesize[0], > > p->data[1] + ps * x + y * p->linesize[1], > > @@ -344,7 +344,7 @@ static int decode_slice(AVCodecContext *c, void *arg) > > p->data[3] + ps * x + y * p->linesize[3] }; > > decode_rgb_frame(f, sc, &gb, planes, width, height, p->linesize); > > } > > - if (f->ac != AC_GOLOMB_RICE && f->version > 2) { > > + if (ac != AC_GOLOMB_RICE && f->version > 2) { > > int v; > > get_rac(&sc->c, (uint8_t[]) { 129 }); > > v = sc->c.bytestream_end - sc->c.bytestream - 2 - 5*!!f->ec; > > diff --git a/libavcodec/ffv1dec_template.c b/libavcodec/ffv1dec_template.c > > index 2da6bd935dc..e983d1ba648 100644 > > --- a/libavcodec/ffv1dec_template.c > > +++ b/libavcodec/ffv1dec_template.c > > @@ -143,6 +143,9 @@ static int RENAME(decode_rgb_frame)(FFV1Context *f, > > FFV1SliceContext *sc, > > int transparency = f->transparency; > > int ac = f->ac; > > + if (sc->slice_coding_mode == 1) > > + ac = 1; > > + > > for (x = 0; x < 4; x++) { > > sample[x][0] = RENAME(sc->sample_buffer) + x * 2 * (w + 6) > > + 3; > > sample[x][1] = RENAME(sc->sample_buffer) + (x * 2 + 1) * (w + 6) > > + 3; > > diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c > > index a32059886c0..547fb598d6d 100644 > > --- a/libavcodec/ffv1enc.c > > +++ b/libavcodec/ffv1enc.c > > @@ -271,10 +271,9 @@ static inline void put_vlc_symbol(PutBitContext *pb, > > VlcState *const state, > > static int encode_plane(FFV1Context *f, FFV1SliceContext *sc, > > const uint8_t *src, int w, int h, > > - int stride, int plane_index, int pixel_stride) > > + int stride, int plane_index, int pixel_stride, > > int ac) > > { > > int x, y, i, ret; > > - const int ac = f->ac; > > const int pass1 = !!(f->avctx->flags & AV_CODEC_FLAG_PASS1); > > const int ring_size = f->context_model ? 3 : 2; > > int16_t *sample[3]; > > @@ -1068,6 +1067,7 @@ static int encode_slice(AVCodecContext *c, void *arg) > > p->data[1] ? p->data[1] + ps*x + > > y*p->linesize[1] : NULL, > > p->data[2] ? p->data[2] + ps*x + > > y*p->linesize[2] : NULL, > > p->data[3] ? p->data[3] + ps*x + > > y*p->linesize[3] : NULL}; > > + int ac = f->ac; > > sc->slice_coding_mode = 0; > > if (f->version > 3 && f->colorspace == 1) { > > @@ -1083,7 +1083,7 @@ retry: > > if (f->version > 2) { > > encode_slice_header(f, sc); > > } > > - if (f->ac == AC_GOLOMB_RICE) { > > + if (ac == AC_GOLOMB_RICE) { > > sc->ac_byte_count = f->version > 2 || (!x && !y) ? > > ff_rac_terminate(&sc->c, f->version > 2) : 0; > > init_put_bits(&sc->pb, > > sc->c.bytestream_start + sc->ac_byte_count, > > @@ -1096,24 +1096,24 @@ retry: > > const int cx = x >> f->chroma_h_shift; > > const int cy = y >> f->chroma_v_shift; > > - ret = encode_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], > > width, height, p->linesize[0], 0, 1); > > + ret = encode_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], > > width, height, p->linesize[0], 0, 1, ac); > > if (f->chroma_planes) { > > - ret |= encode_plane(f, sc, p->data[1] + > > ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1, 1); > > - ret |= encode_plane(f, sc, p->data[2] + > > ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1, 1); > > + ret |= encode_plane(f, sc, p->data[1] + > > ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1, 1, > > ac); > > + ret |= encode_plane(f, sc, p->data[2] + > > ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1, 1, > > ac); > > } > > if (f->transparency) > > - ret |= encode_plane(f, sc, p->data[3] + ps*x + > > y*p->linesize[3], width, height, p->linesize[3], 2, 1); > > + ret |= encode_plane(f, sc, p->data[3] + ps*x + > > y*p->linesize[3], width, height, p->linesize[3], 2, 1, ac); > > } else if (c->pix_fmt == AV_PIX_FMT_YA8) { > > - ret = encode_plane(f, sc, p->data[0] + ps*x + > > y*p->linesize[0], width, height, p->linesize[0], 0, 2); > > - ret |= encode_plane(f, sc, p->data[0] + 1 + ps*x + > > y*p->linesize[0], width, height, p->linesize[0], 1, 2); > > + ret = encode_plane(f, sc, p->data[0] + ps*x + > > y*p->linesize[0], width, height, p->linesize[0], 0, 2, ac); > > + ret |= encode_plane(f, sc, p->data[0] + 1 + ps*x + > > y*p->linesize[0], width, height, p->linesize[0], 1, 2, ac); > > } else if (f->use32bit) { > > ret = encode_rgb_frame32(f, sc, planes, width, height, > > p->linesize); > > } else { > > ret = encode_rgb_frame(f, sc, planes, width, height, p->linesize); > > } > > - if (f->ac != AC_GOLOMB_RICE) { > > + if (ac != AC_GOLOMB_RICE) { > > sc->ac_byte_count = ff_rac_terminate(&sc->c, 1); > > } else { > > flush_put_bits(&sc->pb); // FIXME: nicer padding > > @@ -1122,11 +1122,12 @@ retry: > > if (ret < 0) { > > av_assert0(sc->slice_coding_mode == 0); > > - if (f->version < 4 || !f->ac) { > > + if (f->version < 4) { > > av_log(c, AV_LOG_ERROR, "Buffer too small\n"); > > return ret; > > } > > av_log(c, AV_LOG_DEBUG, "Coding slice as PCM\n"); > > + ac = 1; > > sc->slice_coding_mode = 1; > > sc->c = c_bak; > > goto retry; > > Is there a reason to support this with Golomb? Being a fallback-only mode > for range coding, I don't think there's much point in supporting Golomb > coding for it.
The reason behind slice_coding_mode is to ensure that the maximum size of the bitstream can be bound in a reasonable way. This will allows decoders and encoders to use a known and limited amount of memory. This is of course not a problem with normal videos but one could craft a video that pushes each context state to one side and then follows that up with crafted data where each is opposit thus generating the worst case. Its a bigger issue for the range coder than golomb, yes thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Those who are too smart to engage in politics are punished by being governed by those who are dumber. -- Plato
signature.asc
Description: PGP signature
_______________________________________________ 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".