* [FFmpeg-devel] [PATCH] ffv1: implement remap for encode/decode_plane()
@ 2025-03-10 0:45 Michael Niedermayer
2025-03-10 17:48 ` Lynne
0 siblings, 1 reply; 6+ messages in thread
From: Michael Niedermayer @ 2025-03-10 0:45 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Sponsored-by: Sovereign Tech Fund
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavcodec/ffv1dec.c | 20 ++++++++-----
libavcodec/ffv1enc.c | 67 ++++++++++++++++++++++++++++++++++++++------
2 files changed, 71 insertions(+), 16 deletions(-)
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index 9738e4e9c9f..72c93fcf0cd 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -92,7 +92,7 @@ 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 ac)
+ int remap_index, int pixel_stride, int ac)
{
int x, y;
int16_t *sample[2];
@@ -116,12 +116,18 @@ static int decode_plane(FFV1Context *f, FFV1SliceContext *sc,
int ret = decode_line(f, sc, gb, w, sample, plane_index, 8, ac);
if (ret < 0)
return ret;
+ if (sc->remap)
+ for (x = 0; x < w; x++)
+ sample[1][x] = sc->fltmap[remap_index][sample[1][x]];
for (x = 0; x < w; x++)
src[x*pixel_stride + stride * y] = sample[1][x];
} else {
int ret = decode_line(f, sc, gb, w, sample, plane_index, f->avctx->bits_per_raw_sample, ac);
if (ret < 0)
return ret;
+ if (sc->remap)
+ for (x = 0; x < w; x++)
+ sample[1][x] = sc->fltmap[remap_index][sample[1][x]];
if (f->packed_at_lsb) {
for (x = 0; x < w; x++) {
((uint16_t*)(src + stride*y))[x*pixel_stride] = sample[1][x];
@@ -347,17 +353,17 @@ static int decode_slice(AVCodecContext *c, void *arg)
if (f->colorspace == 0 && (f->chroma_planes || !f->transparency)) {
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, ac);
+ decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 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, 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);
+ decode_plane(f, sc, &gb, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 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, 2, 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, ac);
+ 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, 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, ac);
- decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] + 1, width, height, p->linesize[0], 1, 2, ac);
+ decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] , width, height, p->linesize[0], 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, 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],
diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
index f3041219b71..4c55c01263b 100644
--- a/libavcodec/ffv1enc.c
+++ b/libavcodec/ffv1enc.c
@@ -272,7 +272,7 @@ 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 ac)
+ int stride, int plane_index, int remap_index, int pixel_stride, int ac)
{
int x, y, i, ret;
const int pass1 = !!(f->avctx->flags & AV_CODEC_FLAG_PASS1);
@@ -288,9 +288,14 @@ static int encode_plane(FFV1Context *f, FFV1SliceContext *sc,
sample[0][-1]= sample[1][0 ];
sample[1][ w]= sample[1][w-1];
+
if (f->bits_per_raw_sample <= 8) {
for (x = 0; x < w; x++)
sample[0][x] = src[x * pixel_stride + stride * y];
+ if (sc->remap)
+ for (x = 0; x < w; x++)
+ sample[0][x] = sc->fltmap[remap_index][ sample[0][x] ];
+
if((ret = encode_line(f, sc, f->avctx, w, sample, plane_index, 8, ac, pass1)) < 0)
return ret;
} else {
@@ -303,6 +308,10 @@ static int encode_plane(FFV1Context *f, FFV1SliceContext *sc,
sample[0][x] = ((uint16_t*)(src + stride*y))[x] >> (16 - f->bits_per_raw_sample);
}
}
+ if (sc->remap)
+ for (x = 0; x < w; x++)
+ sample[0][x] = sc->fltmap[remap_index][ sample[0][x] ];
+
if((ret = encode_line(f, sc, f->avctx, w, sample, plane_index, f->bits_per_raw_sample, ac, pass1)) < 0)
return ret;
}
@@ -310,6 +319,30 @@ static int encode_plane(FFV1Context *f, FFV1SliceContext *sc,
return 0;
}
+static void load_plane(FFV1Context *f, FFV1SliceContext *sc,
+ const uint8_t *src, int w, int h,
+ int stride, int remap_index, int pixel_stride)
+{
+ int x, y;
+
+ memset(sc->fltmap[remap_index], 0, sizeof(sc->fltmap[remap_index]));
+
+ for (y = 0; y < h; y++) {
+ if (f->bits_per_raw_sample <= 8) {
+ for (x = 0; x < w; x++)
+ sc->fltmap[remap_index][ src[x * pixel_stride + stride * y] ] = 1;
+ } else {
+ if (f->packed_at_lsb) {
+ for (x = 0; x < w; x++)
+ sc->fltmap[remap_index][ ((uint16_t*)(src + stride*y))[x] ] = 1;
+ } else {
+ for (x = 0; x < w; x++)
+ sc->fltmap[remap_index][ ((uint16_t*)(src + stride*y))[x] >> (16 - f->bits_per_raw_sample) ] = 1;
+ }
+ }
+ }
+}
+
static void write_quant_table(RangeCoder *c, int16_t *quant_table)
{
int last = 0;
@@ -1178,8 +1211,24 @@ retry:
}
if (sc->remap) {
- if (f->colorspace == 0) {
- av_assert0(0);
+ if (f->colorspace == 0 && c->pix_fmt != AV_PIX_FMT_YA8) {
+ const int cx = x >> f->chroma_h_shift;
+ const int cy = y >> f->chroma_v_shift;
+
+ //TODO decide on the order for the encoded remaps and loads. with golomb rice it
+ // easier to have all range coded ones together, otherwise it may be nicer to handle each plane as a whole?
+
+ load_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 1);
+
+ if (f->chroma_planes) {
+ load_plane(f, sc, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1, 1);
+ load_plane(f, sc, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 2, 1);
+ }
+ if (f->transparency)
+ load_plane(f, sc, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 3, 1);
+ } else if (c->pix_fmt == AV_PIX_FMT_YA8) {
+ load_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 2);
+ load_plane(f, sc, p->data[0] + 1 + ps*x + y*p->linesize[0], width, height, p->linesize[0], 1, 2);
} else if (f->use32bit) {
load_rgb_frame32(f, sc, planes, width, height, p->linesize);
} else
@@ -1206,17 +1255,17 @@ 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, ac);
+ ret = encode_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 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, 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);
+ ret |= encode_plane(f, sc, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 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, 2, 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, ac);
+ ret |= encode_plane(f, sc, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 2, 3, 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, ac);
- ret |= encode_plane(f, sc, p->data[0] + 1 + ps*x + y*p->linesize[0], width, height, p->linesize[0], 1, 2, ac);
+ ret = encode_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 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, 1, 2, ac);
} else if (f->use32bit) {
ret = encode_rgb_frame32(f, sc, planes, width, height, p->linesize, ac);
} else {
--
2.48.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [FFmpeg-devel] [PATCH] ffv1: implement remap for encode/decode_plane()
2025-03-10 0:45 [FFmpeg-devel] [PATCH] ffv1: implement remap for encode/decode_plane() Michael Niedermayer
@ 2025-03-10 17:48 ` Lynne
2025-03-11 0:59 ` Michael Niedermayer
0 siblings, 1 reply; 6+ messages in thread
From: Lynne @ 2025-03-10 17:48 UTC (permalink / raw)
To: ffmpeg-devel
On 10/03/2025 01:45, Michael Niedermayer wrote:
> Sponsored-by: Sovereign Tech Fund
> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> ---
> libavcodec/ffv1dec.c | 20 ++++++++-----
> libavcodec/ffv1enc.c | 67 ++++++++++++++++++++++++++++++++++++++------
> 2 files changed, 71 insertions(+), 16 deletions(-)
>
> diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
> index 9738e4e9c9f..72c93fcf0cd 100644
> --- a/libavcodec/ffv1dec.c
> +++ b/libavcodec/ffv1dec.c
> @@ -92,7 +92,7 @@ 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 ac)
> + int remap_index, int pixel_stride, int ac)
> {
> int x, y;
> int16_t *sample[2];
> @@ -116,12 +116,18 @@ static int decode_plane(FFV1Context *f, FFV1SliceContext *sc,
> int ret = decode_line(f, sc, gb, w, sample, plane_index, 8, ac);
> if (ret < 0)
> return ret;
> + if (sc->remap)
> + for (x = 0; x < w; x++)
> + sample[1][x] = sc->fltmap[remap_index][sample[1][x]];
> for (x = 0; x < w; x++)
> src[x*pixel_stride + stride * y] = sample[1][x];
> } else {
> int ret = decode_line(f, sc, gb, w, sample, plane_index, f->avctx->bits_per_raw_sample, ac);
> if (ret < 0)
> return ret;
> + if (sc->remap)
> + for (x = 0; x < w; x++)
> + sample[1][x] = sc->fltmap[remap_index][sample[1][x]];
> if (f->packed_at_lsb) {
> for (x = 0; x < w; x++) {
> ((uint16_t*)(src + stride*y))[x*pixel_stride] = sample[1][x];
> @@ -347,17 +353,17 @@ static int decode_slice(AVCodecContext *c, void *arg)
> if (f->colorspace == 0 && (f->chroma_planes || !f->transparency)) {
> 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, ac);
> + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 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, 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);
> + decode_plane(f, sc, &gb, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 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, 2, 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, ac);
> + 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, 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, ac);
> - decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] + 1, width, height, p->linesize[0], 1, 2, ac);
> + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] , width, height, p->linesize[0], 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, 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],
> diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
> index f3041219b71..4c55c01263b 100644
> --- a/libavcodec/ffv1enc.c
> +++ b/libavcodec/ffv1enc.c
> @@ -272,7 +272,7 @@ 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 ac)
> + int stride, int plane_index, int remap_index, int pixel_stride, int ac)
> {
> int x, y, i, ret;
> const int pass1 = !!(f->avctx->flags & AV_CODEC_FLAG_PASS1);
> @@ -288,9 +288,14 @@ static int encode_plane(FFV1Context *f, FFV1SliceContext *sc,
>
> sample[0][-1]= sample[1][0 ];
> sample[1][ w]= sample[1][w-1];
> +
> if (f->bits_per_raw_sample <= 8) {
> for (x = 0; x < w; x++)
> sample[0][x] = src[x * pixel_stride + stride * y];
> + if (sc->remap)
> + for (x = 0; x < w; x++)
> + sample[0][x] = sc->fltmap[remap_index][ sample[0][x] ];
> +
> if((ret = encode_line(f, sc, f->avctx, w, sample, plane_index, 8, ac, pass1)) < 0)
> return ret;
> } else {
> @@ -303,6 +308,10 @@ static int encode_plane(FFV1Context *f, FFV1SliceContext *sc,
> sample[0][x] = ((uint16_t*)(src + stride*y))[x] >> (16 - f->bits_per_raw_sample);
> }
> }
> + if (sc->remap)
> + for (x = 0; x < w; x++)
> + sample[0][x] = sc->fltmap[remap_index][ sample[0][x] ];
> +
> if((ret = encode_line(f, sc, f->avctx, w, sample, plane_index, f->bits_per_raw_sample, ac, pass1)) < 0)
> return ret;
> }
> @@ -310,6 +319,30 @@ static int encode_plane(FFV1Context *f, FFV1SliceContext *sc,
> return 0;
> }
>
> +static void load_plane(FFV1Context *f, FFV1SliceContext *sc,
> + const uint8_t *src, int w, int h,
> + int stride, int remap_index, int pixel_stride)
> +{
> + int x, y;
> +
> + memset(sc->fltmap[remap_index], 0, sizeof(sc->fltmap[remap_index]));
> +
> + for (y = 0; y < h; y++) {
> + if (f->bits_per_raw_sample <= 8) {
> + for (x = 0; x < w; x++)
> + sc->fltmap[remap_index][ src[x * pixel_stride + stride * y] ] = 1;
> + } else {
> + if (f->packed_at_lsb) {
> + for (x = 0; x < w; x++)
> + sc->fltmap[remap_index][ ((uint16_t*)(src + stride*y))[x] ] = 1;
> + } else {
> + for (x = 0; x < w; x++)
> + sc->fltmap[remap_index][ ((uint16_t*)(src + stride*y))[x] >> (16 - f->bits_per_raw_sample) ] = 1;
> + }
> + }
> + }
> +}
> +
> static void write_quant_table(RangeCoder *c, int16_t *quant_table)
> {
> int last = 0;
> @@ -1178,8 +1211,24 @@ retry:
> }
>
> if (sc->remap) {
> - if (f->colorspace == 0) {
> - av_assert0(0);
> + if (f->colorspace == 0 && c->pix_fmt != AV_PIX_FMT_YA8) {
> + const int cx = x >> f->chroma_h_shift;
> + const int cy = y >> f->chroma_v_shift;
> +
> + //TODO decide on the order for the encoded remaps and loads. with golomb rice it
> + // easier to have all range coded ones together, otherwise it may be nicer to handle each plane as a whole?
> +
> + load_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 1);
> +
> + if (f->chroma_planes) {
> + load_plane(f, sc, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1, 1);
> + load_plane(f, sc, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 2, 1);
> + }
> + if (f->transparency)
> + load_plane(f, sc, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 3, 1);
> + } else if (c->pix_fmt == AV_PIX_FMT_YA8) {
> + load_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 2);
> + load_plane(f, sc, p->data[0] + 1 + ps*x + y*p->linesize[0], width, height, p->linesize[0], 1, 2);
> } else if (f->use32bit) {
> load_rgb_frame32(f, sc, planes, width, height, p->linesize);
> } else
> @@ -1206,17 +1255,17 @@ 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, ac);
> + ret = encode_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 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, 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);
> + ret |= encode_plane(f, sc, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 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, 2, 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, ac);
> + ret |= encode_plane(f, sc, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 2, 3, 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, ac);
> - ret |= encode_plane(f, sc, p->data[0] + 1 + ps*x + y*p->linesize[0], width, height, p->linesize[0], 1, 2, ac);
> + ret = encode_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 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, 1, 2, ac);
> } else if (f->use32bit) {
> ret = encode_rgb_frame32(f, sc, planes, width, height, p->linesize, ac);
> } else {
Doesn't apply properly.
What does it even do? Does the current git master not already do this?
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [FFmpeg-devel] [PATCH] ffv1: implement remap for encode/decode_plane()
2025-03-10 17:48 ` Lynne
@ 2025-03-11 0:59 ` Michael Niedermayer
2025-03-11 14:13 ` James Almer
0 siblings, 1 reply; 6+ messages in thread
From: Michael Niedermayer @ 2025-03-11 0:59 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1.1: Type: text/plain, Size: 11676 bytes --]
On Mon, Mar 10, 2025 at 06:48:29PM +0100, Lynne wrote:
> On 10/03/2025 01:45, Michael Niedermayer wrote:
> > Sponsored-by: Sovereign Tech Fund
> > Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> > ---
> > libavcodec/ffv1dec.c | 20 ++++++++-----
> > libavcodec/ffv1enc.c | 67 ++++++++++++++++++++++++++++++++++++++------
> > 2 files changed, 71 insertions(+), 16 deletions(-)
> >
> > diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
> > index 9738e4e9c9f..72c93fcf0cd 100644
> > --- a/libavcodec/ffv1dec.c
> > +++ b/libavcodec/ffv1dec.c
> > @@ -92,7 +92,7 @@ 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 ac)
> > + int remap_index, int pixel_stride, int ac)
> > {
> > int x, y;
> > int16_t *sample[2];
> > @@ -116,12 +116,18 @@ static int decode_plane(FFV1Context *f, FFV1SliceContext *sc,
> > int ret = decode_line(f, sc, gb, w, sample, plane_index, 8, ac);
> > if (ret < 0)
> > return ret;
> > + if (sc->remap)
> > + for (x = 0; x < w; x++)
> > + sample[1][x] = sc->fltmap[remap_index][sample[1][x]];
> > for (x = 0; x < w; x++)
> > src[x*pixel_stride + stride * y] = sample[1][x];
> > } else {
> > int ret = decode_line(f, sc, gb, w, sample, plane_index, f->avctx->bits_per_raw_sample, ac);
> > if (ret < 0)
> > return ret;
> > + if (sc->remap)
> > + for (x = 0; x < w; x++)
> > + sample[1][x] = sc->fltmap[remap_index][sample[1][x]];
> > if (f->packed_at_lsb) {
> > for (x = 0; x < w; x++) {
> > ((uint16_t*)(src + stride*y))[x*pixel_stride] = sample[1][x];
> > @@ -347,17 +353,17 @@ static int decode_slice(AVCodecContext *c, void *arg)
> > if (f->colorspace == 0 && (f->chroma_planes || !f->transparency)) {
> > 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, ac);
> > + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 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, 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);
> > + decode_plane(f, sc, &gb, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 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, 2, 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, ac);
> > + 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, 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, ac);
> > - decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] + 1, width, height, p->linesize[0], 1, 2, ac);
> > + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] , width, height, p->linesize[0], 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, 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],
> > diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
> > index f3041219b71..4c55c01263b 100644
> > --- a/libavcodec/ffv1enc.c
> > +++ b/libavcodec/ffv1enc.c
> > @@ -272,7 +272,7 @@ 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 ac)
> > + int stride, int plane_index, int remap_index, int pixel_stride, int ac)
> > {
> > int x, y, i, ret;
> > const int pass1 = !!(f->avctx->flags & AV_CODEC_FLAG_PASS1);
> > @@ -288,9 +288,14 @@ static int encode_plane(FFV1Context *f, FFV1SliceContext *sc,
> > sample[0][-1]= sample[1][0 ];
> > sample[1][ w]= sample[1][w-1];
> > +
> > if (f->bits_per_raw_sample <= 8) {
> > for (x = 0; x < w; x++)
> > sample[0][x] = src[x * pixel_stride + stride * y];
> > + if (sc->remap)
> > + for (x = 0; x < w; x++)
> > + sample[0][x] = sc->fltmap[remap_index][ sample[0][x] ];
> > +
> > if((ret = encode_line(f, sc, f->avctx, w, sample, plane_index, 8, ac, pass1)) < 0)
> > return ret;
> > } else {
> > @@ -303,6 +308,10 @@ static int encode_plane(FFV1Context *f, FFV1SliceContext *sc,
> > sample[0][x] = ((uint16_t*)(src + stride*y))[x] >> (16 - f->bits_per_raw_sample);
> > }
> > }
> > + if (sc->remap)
> > + for (x = 0; x < w; x++)
> > + sample[0][x] = sc->fltmap[remap_index][ sample[0][x] ];
> > +
> > if((ret = encode_line(f, sc, f->avctx, w, sample, plane_index, f->bits_per_raw_sample, ac, pass1)) < 0)
> > return ret;
> > }
> > @@ -310,6 +319,30 @@ static int encode_plane(FFV1Context *f, FFV1SliceContext *sc,
> > return 0;
> > }
> > +static void load_plane(FFV1Context *f, FFV1SliceContext *sc,
> > + const uint8_t *src, int w, int h,
> > + int stride, int remap_index, int pixel_stride)
> > +{
> > + int x, y;
> > +
> > + memset(sc->fltmap[remap_index], 0, sizeof(sc->fltmap[remap_index]));
> > +
> > + for (y = 0; y < h; y++) {
> > + if (f->bits_per_raw_sample <= 8) {
> > + for (x = 0; x < w; x++)
> > + sc->fltmap[remap_index][ src[x * pixel_stride + stride * y] ] = 1;
> > + } else {
> > + if (f->packed_at_lsb) {
> > + for (x = 0; x < w; x++)
> > + sc->fltmap[remap_index][ ((uint16_t*)(src + stride*y))[x] ] = 1;
> > + } else {
> > + for (x = 0; x < w; x++)
> > + sc->fltmap[remap_index][ ((uint16_t*)(src + stride*y))[x] >> (16 - f->bits_per_raw_sample) ] = 1;
> > + }
> > + }
> > + }
> > +}
> > +
> > static void write_quant_table(RangeCoder *c, int16_t *quant_table)
> > {
> > int last = 0;
> > @@ -1178,8 +1211,24 @@ retry:
> > }
> > if (sc->remap) {
> > - if (f->colorspace == 0) {
> > - av_assert0(0);
> > + if (f->colorspace == 0 && c->pix_fmt != AV_PIX_FMT_YA8) {
> > + const int cx = x >> f->chroma_h_shift;
> > + const int cy = y >> f->chroma_v_shift;
> > +
> > + //TODO decide on the order for the encoded remaps and loads. with golomb rice it
> > + // easier to have all range coded ones together, otherwise it may be nicer to handle each plane as a whole?
> > +
> > + load_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 1);
> > +
> > + if (f->chroma_planes) {
> > + load_plane(f, sc, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1, 1);
> > + load_plane(f, sc, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 2, 1);
> > + }
> > + if (f->transparency)
> > + load_plane(f, sc, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 3, 1);
> > + } else if (c->pix_fmt == AV_PIX_FMT_YA8) {
> > + load_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 2);
> > + load_plane(f, sc, p->data[0] + 1 + ps*x + y*p->linesize[0], width, height, p->linesize[0], 1, 2);
> > } else if (f->use32bit) {
> > load_rgb_frame32(f, sc, planes, width, height, p->linesize);
> > } else
> > @@ -1206,17 +1255,17 @@ 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, ac);
> > + ret = encode_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 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, 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);
> > + ret |= encode_plane(f, sc, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 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, 2, 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, ac);
> > + ret |= encode_plane(f, sc, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 2, 3, 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, ac);
> > - ret |= encode_plane(f, sc, p->data[0] + 1 + ps*x + y*p->linesize[0], width, height, p->linesize[0], 1, 2, ac);
> > + ret = encode_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 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, 1, 2, ac);
> > } else if (f->use32bit) {
> > ret = encode_rgb_frame32(f, sc, planes, width, height, p->linesize, ac);
> > } else {
>
> Doesn't apply properly.
> What does it even do? Does the current git master not already do this?
master implements remap for encode_rgb_frame*
This implements it for the other cases.
Most of this is untested though, i have no YUV planar float16 material
thx
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
In a rich man's house there is no place to spit but his face.
-- Diogenes of Sinope
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [FFmpeg-devel] [PATCH] ffv1: implement remap for encode/decode_plane()
2025-03-11 0:59 ` Michael Niedermayer
@ 2025-03-11 14:13 ` James Almer
2025-03-11 19:06 ` James Almer
0 siblings, 1 reply; 6+ messages in thread
From: James Almer @ 2025-03-11 14:13 UTC (permalink / raw)
To: ffmpeg-devel
[-- Attachment #1.1.1: Type: text/plain, Size: 11814 bytes --]
On 3/10/2025 9:59 PM, Michael Niedermayer wrote:
> On Mon, Mar 10, 2025 at 06:48:29PM +0100, Lynne wrote:
>> On 10/03/2025 01:45, Michael Niedermayer wrote:
>>> Sponsored-by: Sovereign Tech Fund
>>> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
>>> ---
>>> libavcodec/ffv1dec.c | 20 ++++++++-----
>>> libavcodec/ffv1enc.c | 67 ++++++++++++++++++++++++++++++++++++++------
>>> 2 files changed, 71 insertions(+), 16 deletions(-)
>>>
>>> diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
>>> index 9738e4e9c9f..72c93fcf0cd 100644
>>> --- a/libavcodec/ffv1dec.c
>>> +++ b/libavcodec/ffv1dec.c
>>> @@ -92,7 +92,7 @@ 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 ac)
>>> + int remap_index, int pixel_stride, int ac)
>>> {
>>> int x, y;
>>> int16_t *sample[2];
>>> @@ -116,12 +116,18 @@ static int decode_plane(FFV1Context *f, FFV1SliceContext *sc,
>>> int ret = decode_line(f, sc, gb, w, sample, plane_index, 8, ac);
>>> if (ret < 0)
>>> return ret;
>>> + if (sc->remap)
>>> + for (x = 0; x < w; x++)
>>> + sample[1][x] = sc->fltmap[remap_index][sample[1][x]];
>>> for (x = 0; x < w; x++)
>>> src[x*pixel_stride + stride * y] = sample[1][x];
>>> } else {
>>> int ret = decode_line(f, sc, gb, w, sample, plane_index, f->avctx->bits_per_raw_sample, ac);
>>> if (ret < 0)
>>> return ret;
>>> + if (sc->remap)
>>> + for (x = 0; x < w; x++)
>>> + sample[1][x] = sc->fltmap[remap_index][sample[1][x]];
>>> if (f->packed_at_lsb) {
>>> for (x = 0; x < w; x++) {
>>> ((uint16_t*)(src + stride*y))[x*pixel_stride] = sample[1][x];
>>> @@ -347,17 +353,17 @@ static int decode_slice(AVCodecContext *c, void *arg)
>>> if (f->colorspace == 0 && (f->chroma_planes || !f->transparency)) {
>>> 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, ac);
>>> + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 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, 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);
>>> + decode_plane(f, sc, &gb, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 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, 2, 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, ac);
>>> + 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, 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, ac);
>>> - decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] + 1, width, height, p->linesize[0], 1, 2, ac);
>>> + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] , width, height, p->linesize[0], 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, 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],
>>> diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
>>> index f3041219b71..4c55c01263b 100644
>>> --- a/libavcodec/ffv1enc.c
>>> +++ b/libavcodec/ffv1enc.c
>>> @@ -272,7 +272,7 @@ 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 ac)
>>> + int stride, int plane_index, int remap_index, int pixel_stride, int ac)
>>> {
>>> int x, y, i, ret;
>>> const int pass1 = !!(f->avctx->flags & AV_CODEC_FLAG_PASS1);
>>> @@ -288,9 +288,14 @@ static int encode_plane(FFV1Context *f, FFV1SliceContext *sc,
>>> sample[0][-1]= sample[1][0 ];
>>> sample[1][ w]= sample[1][w-1];
>>> +
>>> if (f->bits_per_raw_sample <= 8) {
>>> for (x = 0; x < w; x++)
>>> sample[0][x] = src[x * pixel_stride + stride * y];
>>> + if (sc->remap)
>>> + for (x = 0; x < w; x++)
>>> + sample[0][x] = sc->fltmap[remap_index][ sample[0][x] ];
>>> +
>>> if((ret = encode_line(f, sc, f->avctx, w, sample, plane_index, 8, ac, pass1)) < 0)
>>> return ret;
>>> } else {
>>> @@ -303,6 +308,10 @@ static int encode_plane(FFV1Context *f, FFV1SliceContext *sc,
>>> sample[0][x] = ((uint16_t*)(src + stride*y))[x] >> (16 - f->bits_per_raw_sample);
>>> }
>>> }
>>> + if (sc->remap)
>>> + for (x = 0; x < w; x++)
>>> + sample[0][x] = sc->fltmap[remap_index][ sample[0][x] ];
>>> +
>>> if((ret = encode_line(f, sc, f->avctx, w, sample, plane_index, f->bits_per_raw_sample, ac, pass1)) < 0)
>>> return ret;
>>> }
>>> @@ -310,6 +319,30 @@ static int encode_plane(FFV1Context *f, FFV1SliceContext *sc,
>>> return 0;
>>> }
>>> +static void load_plane(FFV1Context *f, FFV1SliceContext *sc,
>>> + const uint8_t *src, int w, int h,
>>> + int stride, int remap_index, int pixel_stride)
>>> +{
>>> + int x, y;
>>> +
>>> + memset(sc->fltmap[remap_index], 0, sizeof(sc->fltmap[remap_index]));
>>> +
>>> + for (y = 0; y < h; y++) {
>>> + if (f->bits_per_raw_sample <= 8) {
>>> + for (x = 0; x < w; x++)
>>> + sc->fltmap[remap_index][ src[x * pixel_stride + stride * y] ] = 1;
>>> + } else {
>>> + if (f->packed_at_lsb) {
>>> + for (x = 0; x < w; x++)
>>> + sc->fltmap[remap_index][ ((uint16_t*)(src + stride*y))[x] ] = 1;
>>> + } else {
>>> + for (x = 0; x < w; x++)
>>> + sc->fltmap[remap_index][ ((uint16_t*)(src + stride*y))[x] >> (16 - f->bits_per_raw_sample) ] = 1;
>>> + }
>>> + }
>>> + }
>>> +}
>>> +
>>> static void write_quant_table(RangeCoder *c, int16_t *quant_table)
>>> {
>>> int last = 0;
>>> @@ -1178,8 +1211,24 @@ retry:
>>> }
>>> if (sc->remap) {
>>> - if (f->colorspace == 0) {
>>> - av_assert0(0);
>>> + if (f->colorspace == 0 && c->pix_fmt != AV_PIX_FMT_YA8) {
>>> + const int cx = x >> f->chroma_h_shift;
>>> + const int cy = y >> f->chroma_v_shift;
>>> +
>>> + //TODO decide on the order for the encoded remaps and loads. with golomb rice it
>>> + // easier to have all range coded ones together, otherwise it may be nicer to handle each plane as a whole?
>>> +
>>> + load_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 1);
>>> +
>>> + if (f->chroma_planes) {
>>> + load_plane(f, sc, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1, 1);
>>> + load_plane(f, sc, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 2, 1);
>>> + }
>>> + if (f->transparency)
>>> + load_plane(f, sc, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 3, 1);
>>> + } else if (c->pix_fmt == AV_PIX_FMT_YA8) {
>>> + load_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 2);
>>> + load_plane(f, sc, p->data[0] + 1 + ps*x + y*p->linesize[0], width, height, p->linesize[0], 1, 2);
>>> } else if (f->use32bit) {
>>> load_rgb_frame32(f, sc, planes, width, height, p->linesize);
>>> } else
>>> @@ -1206,17 +1255,17 @@ 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, ac);
>>> + ret = encode_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 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, 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);
>>> + ret |= encode_plane(f, sc, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 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, 2, 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, ac);
>>> + ret |= encode_plane(f, sc, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 2, 3, 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, ac);
>>> - ret |= encode_plane(f, sc, p->data[0] + 1 + ps*x + y*p->linesize[0], width, height, p->linesize[0], 1, 2, ac);
>>> + ret = encode_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 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, 1, 2, ac);
>>> } else if (f->use32bit) {
>>> ret = encode_rgb_frame32(f, sc, planes, width, height, p->linesize, ac);
>>> } else {
>>
>> Doesn't apply properly.
>> What does it even do? Does the current git master not already do this?
>
> master implements remap for encode_rgb_frame*
> This implements it for the other cases.
> Most of this is untested though, i have no YUV planar float16 material
There is one very tiny exr sample that's YA float16, the one from
fate-exr-ya-scanline-zip-half-12x8. Not sure how useful can it be
considering it's so small and has no chroma planes.
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [FFmpeg-devel] [PATCH] ffv1: implement remap for encode/decode_plane()
2025-03-11 14:13 ` James Almer
@ 2025-03-11 19:06 ` James Almer
2025-03-15 0:34 ` Michael Niedermayer
0 siblings, 1 reply; 6+ messages in thread
From: James Almer @ 2025-03-11 19:06 UTC (permalink / raw)
To: ffmpeg-devel
[-- Attachment #1.1.1: Type: text/plain, Size: 14445 bytes --]
On 3/11/2025 11:13 AM, James Almer wrote:
> On 3/10/2025 9:59 PM, Michael Niedermayer wrote:
>> On Mon, Mar 10, 2025 at 06:48:29PM +0100, Lynne wrote:
>>> On 10/03/2025 01:45, Michael Niedermayer wrote:
>>>> Sponsored-by: Sovereign Tech Fund
>>>> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
>>>> ---
>>>> libavcodec/ffv1dec.c | 20 ++++++++-----
>>>> libavcodec/ffv1enc.c | 67 +++++++++++++++++++++++++++++++++++++
>>>> +------
>>>> 2 files changed, 71 insertions(+), 16 deletions(-)
>>>>
>>>> diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
>>>> index 9738e4e9c9f..72c93fcf0cd 100644
>>>> --- a/libavcodec/ffv1dec.c
>>>> +++ b/libavcodec/ffv1dec.c
>>>> @@ -92,7 +92,7 @@ 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 ac)
>>>> + int remap_index, int pixel_stride, int ac)
>>>> {
>>>> int x, y;
>>>> int16_t *sample[2];
>>>> @@ -116,12 +116,18 @@ static int decode_plane(FFV1Context *f,
>>>> FFV1SliceContext *sc,
>>>> int ret = decode_line(f, sc, gb, w, sample,
>>>> plane_index, 8, ac);
>>>> if (ret < 0)
>>>> return ret;
>>>> + if (sc->remap)
>>>> + for (x = 0; x < w; x++)
>>>> + sample[1][x] = sc->fltmap[remap_index]
>>>> [sample[1][x]];
>>>> for (x = 0; x < w; x++)
>>>> src[x*pixel_stride + stride * y] = sample[1][x];
>>>> } else {
>>>> int ret = decode_line(f, sc, gb, w, sample,
>>>> plane_index, f->avctx->bits_per_raw_sample, ac);
>>>> if (ret < 0)
>>>> return ret;
>>>> + if (sc->remap)
>>>> + for (x = 0; x < w; x++)
>>>> + sample[1][x] = sc->fltmap[remap_index]
>>>> [sample[1][x]];
>>>> if (f->packed_at_lsb) {
>>>> for (x = 0; x < w; x++) {
>>>> ((uint16_t*)(src + stride*y))[x*pixel_stride]
>>>> = sample[1][x];
>>>> @@ -347,17 +353,17 @@ static int decode_slice(AVCodecContext *c,
>>>> void *arg)
>>>> if (f->colorspace == 0 && (f->chroma_planes || !f-
>>>> >transparency)) {
>>>> 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, ac);
>>>> + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p-
>>>> >linesize[0], width, height, p->linesize[0], 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, 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);
>>>> + decode_plane(f, sc, &gb, p->data[1] + ps*cx+cy*p-
>>>> >linesize[1], chroma_width, chroma_height, p->linesize[1], 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, 2, 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, ac);
>>>> + 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, 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, ac);
>>>> - decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p-
>>>> >linesize[0] + 1, width, height, p->linesize[0], 1, 2, ac);
>>>> + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p-
>>>> >linesize[0] , width, height, p->linesize[0], 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, 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],
>>>> diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
>>>> index f3041219b71..4c55c01263b 100644
>>>> --- a/libavcodec/ffv1enc.c
>>>> +++ b/libavcodec/ffv1enc.c
>>>> @@ -272,7 +272,7 @@ 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 ac)
>>>> + int stride, int plane_index, int
>>>> remap_index, int pixel_stride, int ac)
>>>> {
>>>> int x, y, i, ret;
>>>> const int pass1 = !!(f->avctx->flags & AV_CODEC_FLAG_PASS1);
>>>> @@ -288,9 +288,14 @@ static int encode_plane(FFV1Context *f,
>>>> FFV1SliceContext *sc,
>>>> sample[0][-1]= sample[1][0 ];
>>>> sample[1][ w]= sample[1][w-1];
>>>> +
>>>> if (f->bits_per_raw_sample <= 8) {
>>>> for (x = 0; x < w; x++)
>>>> sample[0][x] = src[x * pixel_stride + stride * y];
>>>> + if (sc->remap)
>>>> + for (x = 0; x < w; x++)
>>>> + sample[0][x] = sc->fltmap[remap_index]
>>>> [ sample[0][x] ];
>>>> +
>>>> if((ret = encode_line(f, sc, f->avctx, w, sample,
>>>> plane_index, 8, ac, pass1)) < 0)
>>>> return ret;
>>>> } else {
>>>> @@ -303,6 +308,10 @@ static int encode_plane(FFV1Context *f,
>>>> FFV1SliceContext *sc,
>>>> sample[0][x] = ((uint16_t*)(src + stride*y))
>>>> [x] >> (16 - f->bits_per_raw_sample);
>>>> }
>>>> }
>>>> + if (sc->remap)
>>>> + for (x = 0; x < w; x++)
>>>> + sample[0][x] = sc->fltmap[remap_index]
>>>> [ sample[0][x] ];
>>>> +
>>>> if((ret = encode_line(f, sc, f->avctx, w, sample,
>>>> plane_index, f->bits_per_raw_sample, ac, pass1)) < 0)
>>>> return ret;
>>>> }
>>>> @@ -310,6 +319,30 @@ static int encode_plane(FFV1Context *f,
>>>> FFV1SliceContext *sc,
>>>> return 0;
>>>> }
>>>> +static void load_plane(FFV1Context *f, FFV1SliceContext *sc,
>>>> + const uint8_t *src, int w, int h,
>>>> + int stride, int remap_index, int pixel_stride)
>>>> +{
>>>> + int x, y;
>>>> +
>>>> + memset(sc->fltmap[remap_index], 0, sizeof(sc-
>>>> >fltmap[remap_index]));
>>>> +
>>>> + for (y = 0; y < h; y++) {
>>>> + if (f->bits_per_raw_sample <= 8) {
>>>> + for (x = 0; x < w; x++)
>>>> + sc->fltmap[remap_index][ src[x * pixel_stride +
>>>> stride * y] ] = 1;
>>>> + } else {
>>>> + if (f->packed_at_lsb) {
>>>> + for (x = 0; x < w; x++)
>>>> + sc->fltmap[remap_index][ ((uint16_t*)(src +
>>>> stride*y))[x] ] = 1;
>>>> + } else {
>>>> + for (x = 0; x < w; x++)
>>>> + sc->fltmap[remap_index][ ((uint16_t*)(src +
>>>> stride*y))[x] >> (16 - f->bits_per_raw_sample) ] = 1;
>>>> + }
>>>> + }
>>>> + }
>>>> +}
>>>> +
>>>> static void write_quant_table(RangeCoder *c, int16_t *quant_table)
>>>> {
>>>> int last = 0;
>>>> @@ -1178,8 +1211,24 @@ retry:
>>>> }
>>>> if (sc->remap) {
>>>> - if (f->colorspace == 0) {
>>>> - av_assert0(0);
>>>> + if (f->colorspace == 0 && c->pix_fmt != AV_PIX_FMT_YA8) {
>>>> + const int cx = x >> f->chroma_h_shift;
>>>> + const int cy = y >> f->chroma_v_shift;
>>>> +
>>>> + //TODO decide on the order for the encoded remaps and
>>>> loads. with golomb rice it
>>>> + // easier to have all range coded ones together,
>>>> otherwise it may be nicer to handle each plane as a whole?
>>>> +
>>>> + load_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0],
>>>> width, height, p->linesize[0], 0, 1);
>>>> +
>>>> + if (f->chroma_planes) {
>>>> + load_plane(f, sc, p->data[1] + ps*cx+cy*p-
>>>> >linesize[1], chroma_width, chroma_height, p->linesize[1], 1, 1);
>>>> + load_plane(f, sc, p->data[2] + ps*cx+cy*p-
>>>> >linesize[2], chroma_width, chroma_height, p->linesize[2], 2, 1);
>>>> + }
>>>> + if (f->transparency)
>>>> + load_plane(f, sc, p->data[3] + ps*x + y*p-
>>>> >linesize[3], width, height, p->linesize[3], 3, 1);
>>>> + } else if (c->pix_fmt == AV_PIX_FMT_YA8) {
>>>> + load_plane(f, sc, p->data[0] + ps*x + y*p-
>>>> >linesize[0], width, height, p->linesize[0], 0, 2);
>>>> + load_plane(f, sc, p->data[0] + 1 + ps*x + y*p-
>>>> >linesize[0], width, height, p->linesize[0], 1, 2);
>>>> } else if (f->use32bit) {
>>>> load_rgb_frame32(f, sc, planes, width, height, p-
>>>> >linesize);
>>>> } else
>>>> @@ -1206,17 +1255,17 @@ 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, ac);
>>>> + ret = encode_plane(f, sc, p->data[0] + ps*x + y*p-
>>>> >linesize[0], width, height, p->linesize[0], 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, 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);
>>>> + ret |= encode_plane(f, sc, p->data[1] + ps*cx+cy*p-
>>>> >linesize[1], chroma_width, chroma_height, p->linesize[1], 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, 2, 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, ac);
>>>> + ret |= encode_plane(f, sc, p->data[3] + ps*x + y*p-
>>>> >linesize[3], width, height, p->linesize[3], 2, 3, 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, ac);
>>>> - ret |= encode_plane(f, sc, p->data[0] + 1 + ps*x + y*p-
>>>> >linesize[0], width, height, p->linesize[0], 1, 2, ac);
>>>> + ret = encode_plane(f, sc, p->data[0] + ps*x + y*p-
>>>> >linesize[0], width, height, p->linesize[0], 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, 1, 2, ac);
>>>> } else if (f->use32bit) {
>>>> ret = encode_rgb_frame32(f, sc, planes, width, height, p-
>>>> >linesize, ac);
>>>> } else {
>>>
>>> Doesn't apply properly.
>>> What does it even do? Does the current git master not already do this?
>>
>> master implements remap for encode_rgb_frame*
>> This implements it for the other cases.
>> Most of this is untested though, i have no YUV planar float16 material
> There is one very tiny exr sample that's YA float16, the one from fate-
> exr-ya-scanline-zip-half-12x8. Not sure how useful can it be considering
> it's so small and has no chroma planes.
There's also
https://raw.githubusercontent.com/AcademySoftwareFoundation/openexr-images/main/LuminanceChroma/Garden.exr
which is grayf16.
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [FFmpeg-devel] [PATCH] ffv1: implement remap for encode/decode_plane()
2025-03-11 19:06 ` James Almer
@ 2025-03-15 0:34 ` Michael Niedermayer
0 siblings, 0 replies; 6+ messages in thread
From: Michael Niedermayer @ 2025-03-15 0:34 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1.1: Type: text/plain, Size: 14635 bytes --]
On Tue, Mar 11, 2025 at 04:06:58PM -0300, James Almer wrote:
>
>
> On 3/11/2025 11:13 AM, James Almer wrote:
> > On 3/10/2025 9:59 PM, Michael Niedermayer wrote:
> > > On Mon, Mar 10, 2025 at 06:48:29PM +0100, Lynne wrote:
> > > > On 10/03/2025 01:45, Michael Niedermayer wrote:
> > > > > Sponsored-by: Sovereign Tech Fund
> > > > > Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> > > > > ---
> > > > > libavcodec/ffv1dec.c | 20 ++++++++-----
> > > > > libavcodec/ffv1enc.c | 67
> > > > > +++++++++++++++++++++++++++++++++++++ +------
> > > > > 2 files changed, 71 insertions(+), 16 deletions(-)
> > > > >
> > > > > diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
> > > > > index 9738e4e9c9f..72c93fcf0cd 100644
> > > > > --- a/libavcodec/ffv1dec.c
> > > > > +++ b/libavcodec/ffv1dec.c
> > > > > @@ -92,7 +92,7 @@ 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 ac)
> > > > > + int remap_index, int pixel_stride, int ac)
> > > > > {
> > > > > int x, y;
> > > > > int16_t *sample[2];
> > > > > @@ -116,12 +116,18 @@ static int decode_plane(FFV1Context
> > > > > *f, FFV1SliceContext *sc,
> > > > > int ret = decode_line(f, sc, gb, w, sample,
> > > > > plane_index, 8, ac);
> > > > > if (ret < 0)
> > > > > return ret;
> > > > > + if (sc->remap)
> > > > > + for (x = 0; x < w; x++)
> > > > > + sample[1][x] = sc->fltmap[remap_index]
> > > > > [sample[1][x]];
> > > > > for (x = 0; x < w; x++)
> > > > > src[x*pixel_stride + stride * y] = sample[1][x];
> > > > > } else {
> > > > > int ret = decode_line(f, sc, gb, w, sample,
> > > > > plane_index, f->avctx->bits_per_raw_sample, ac);
> > > > > if (ret < 0)
> > > > > return ret;
> > > > > + if (sc->remap)
> > > > > + for (x = 0; x < w; x++)
> > > > > + sample[1][x] = sc->fltmap[remap_index]
> > > > > [sample[1][x]];
> > > > > if (f->packed_at_lsb) {
> > > > > for (x = 0; x < w; x++) {
> > > > > ((uint16_t*)(src +
> > > > > stride*y))[x*pixel_stride] = sample[1][x];
> > > > > @@ -347,17 +353,17 @@ static int decode_slice(AVCodecContext
> > > > > *c, void *arg)
> > > > > if (f->colorspace == 0 && (f->chroma_planes || !f-
> > > > > >transparency)) {
> > > > > 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, ac);
> > > > > + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p-
> > > > > >linesize[0], width, height, p->linesize[0], 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, 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);
> > > > > + decode_plane(f, sc, &gb, p->data[1] +
> > > > > ps*cx+cy*p- >linesize[1], chroma_width, chroma_height,
> > > > > p->linesize[1], 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, 2, 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, ac);
> > > > > + 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, 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, ac);
> > > > > - decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p-
> > > > > >linesize[0] + 1, width, height, p->linesize[0], 1, 2, ac);
> > > > > + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p-
> > > > > >linesize[0] , width, height, p->linesize[0], 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, 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],
> > > > > diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
> > > > > index f3041219b71..4c55c01263b 100644
> > > > > --- a/libavcodec/ffv1enc.c
> > > > > +++ b/libavcodec/ffv1enc.c
> > > > > @@ -272,7 +272,7 @@ 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 ac)
> > > > > + int stride, int plane_index, int
> > > > > remap_index, int pixel_stride, int ac)
> > > > > {
> > > > > int x, y, i, ret;
> > > > > const int pass1 = !!(f->avctx->flags & AV_CODEC_FLAG_PASS1);
> > > > > @@ -288,9 +288,14 @@ static int encode_plane(FFV1Context *f,
> > > > > FFV1SliceContext *sc,
> > > > > sample[0][-1]= sample[1][0 ];
> > > > > sample[1][ w]= sample[1][w-1];
> > > > > +
> > > > > if (f->bits_per_raw_sample <= 8) {
> > > > > for (x = 0; x < w; x++)
> > > > > sample[0][x] = src[x * pixel_stride + stride * y];
> > > > > + if (sc->remap)
> > > > > + for (x = 0; x < w; x++)
> > > > > + sample[0][x] = sc->fltmap[remap_index]
> > > > > [ sample[0][x] ];
> > > > > +
> > > > > if((ret = encode_line(f, sc, f->avctx, w,
> > > > > sample, plane_index, 8, ac, pass1)) < 0)
> > > > > return ret;
> > > > > } else {
> > > > > @@ -303,6 +308,10 @@ static int encode_plane(FFV1Context *f,
> > > > > FFV1SliceContext *sc,
> > > > > sample[0][x] = ((uint16_t*)(src +
> > > > > stride*y)) [x] >> (16 - f->bits_per_raw_sample);
> > > > > }
> > > > > }
> > > > > + if (sc->remap)
> > > > > + for (x = 0; x < w; x++)
> > > > > + sample[0][x] = sc->fltmap[remap_index]
> > > > > [ sample[0][x] ];
> > > > > +
> > > > > if((ret = encode_line(f, sc, f->avctx, w,
> > > > > sample, plane_index, f->bits_per_raw_sample, ac, pass1)) <
> > > > > 0)
> > > > > return ret;
> > > > > }
> > > > > @@ -310,6 +319,30 @@ static int encode_plane(FFV1Context *f,
> > > > > FFV1SliceContext *sc,
> > > > > return 0;
> > > > > }
> > > > > +static void load_plane(FFV1Context *f, FFV1SliceContext *sc,
> > > > > + const uint8_t *src, int w, int h,
> > > > > + int stride, int remap_index, int pixel_stride)
> > > > > +{
> > > > > + int x, y;
> > > > > +
> > > > > + memset(sc->fltmap[remap_index], 0, sizeof(sc-
> > > > > >fltmap[remap_index]));
> > > > > +
> > > > > + for (y = 0; y < h; y++) {
> > > > > + if (f->bits_per_raw_sample <= 8) {
> > > > > + for (x = 0; x < w; x++)
> > > > > + sc->fltmap[remap_index][ src[x *
> > > > > pixel_stride + stride * y] ] = 1;
> > > > > + } else {
> > > > > + if (f->packed_at_lsb) {
> > > > > + for (x = 0; x < w; x++)
> > > > > + sc->fltmap[remap_index][
> > > > > ((uint16_t*)(src + stride*y))[x] ] = 1;
> > > > > + } else {
> > > > > + for (x = 0; x < w; x++)
> > > > > + sc->fltmap[remap_index][
> > > > > ((uint16_t*)(src + stride*y))[x] >> (16 -
> > > > > f->bits_per_raw_sample) ] = 1;
> > > > > + }
> > > > > + }
> > > > > + }
> > > > > +}
> > > > > +
> > > > > static void write_quant_table(RangeCoder *c, int16_t *quant_table)
> > > > > {
> > > > > int last = 0;
> > > > > @@ -1178,8 +1211,24 @@ retry:
> > > > > }
> > > > > if (sc->remap) {
> > > > > - if (f->colorspace == 0) {
> > > > > - av_assert0(0);
> > > > > + if (f->colorspace == 0 && c->pix_fmt != AV_PIX_FMT_YA8) {
> > > > > + const int cx = x >> f->chroma_h_shift;
> > > > > + const int cy = y >> f->chroma_v_shift;
> > > > > +
> > > > > + //TODO decide on the order for the encoded
> > > > > remaps and loads. with golomb rice it
> > > > > + // easier to have all range coded ones
> > > > > together, otherwise it may be nicer to handle each plane as
> > > > > a whole?
> > > > > +
> > > > > + load_plane(f, sc, p->data[0] + ps*x +
> > > > > y*p->linesize[0], width, height, p->linesize[0], 0, 1);
> > > > > +
> > > > > + if (f->chroma_planes) {
> > > > > + load_plane(f, sc, p->data[1] + ps*cx+cy*p-
> > > > > >linesize[1], chroma_width, chroma_height, p->linesize[1],
> > > > > 1, 1);
> > > > > + load_plane(f, sc, p->data[2] + ps*cx+cy*p-
> > > > > >linesize[2], chroma_width, chroma_height, p->linesize[2],
> > > > > 2, 1);
> > > > > + }
> > > > > + if (f->transparency)
> > > > > + load_plane(f, sc, p->data[3] + ps*x + y*p-
> > > > > >linesize[3], width, height, p->linesize[3], 3, 1);
> > > > > + } else if (c->pix_fmt == AV_PIX_FMT_YA8) {
> > > > > + load_plane(f, sc, p->data[0] + ps*x + y*p-
> > > > > >linesize[0], width, height, p->linesize[0], 0, 2);
> > > > > + load_plane(f, sc, p->data[0] + 1 + ps*x + y*p-
> > > > > >linesize[0], width, height, p->linesize[0], 1, 2);
> > > > > } else if (f->use32bit) {
> > > > > load_rgb_frame32(f, sc, planes, width,
> > > > > height, p- >linesize);
> > > > > } else
> > > > > @@ -1206,17 +1255,17 @@ 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, ac);
> > > > > + ret = encode_plane(f, sc, p->data[0] + ps*x + y*p-
> > > > > >linesize[0], width, height, p->linesize[0], 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, 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);
> > > > > + ret |= encode_plane(f, sc, p->data[1] +
> > > > > ps*cx+cy*p- >linesize[1], chroma_width, chroma_height,
> > > > > p->linesize[1], 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, 2, 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, ac);
> > > > > + ret |= encode_plane(f, sc, p->data[3] + ps*x +
> > > > > y*p- >linesize[3], width, height, p->linesize[3], 2, 3, 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, ac);
> > > > > - ret |= encode_plane(f, sc, p->data[0] + 1 + ps*x +
> > > > > y*p- >linesize[0], width, height, p->linesize[0], 1, 2, ac);
> > > > > + ret = encode_plane(f, sc, p->data[0] + ps*x +
> > > > > y*p- >linesize[0], width, height, p->linesize[0], 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, 1, 2,
> > > > > ac);
> > > > > } else if (f->use32bit) {
> > > > > ret = encode_rgb_frame32(f, sc, planes, width,
> > > > > height, p- >linesize, ac);
> > > > > } else {
> > > >
> > > > Doesn't apply properly.
> > > > What does it even do? Does the current git master not already do this?
> > >
> > > master implements remap for encode_rgb_frame*
> > > This implements it for the other cases.
> > > Most of this is untested though, i have no YUV planar float16 material
> > There is one very tiny exr sample that's YA float16, the one from fate-
> > exr-ya-scanline-zip-half-12x8. Not sure how useful can it be considering
> > it's so small and has no chroma planes.
>
> There's also https://raw.githubusercontent.com/AcademySoftwareFoundation/openexr-images/main/LuminanceChroma/Garden.exr
> which is grayf16.
patches sent to support these
thx
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Modern terrorism, a quick summary: Need oil, start war with country that
has oil, kill hundread thousand in war. Let country fall into chaos,
be surprised about raise of fundamantalists. Drop more bombs, kill more
people, be surprised about them taking revenge and drop even more bombs
and strip your own citizens of their rights and freedoms. to be continued
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-03-15 0:34 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-10 0:45 [FFmpeg-devel] [PATCH] ffv1: implement remap for encode/decode_plane() Michael Niedermayer
2025-03-10 17:48 ` Lynne
2025-03-11 0:59 ` Michael Niedermayer
2025-03-11 14:13 ` James Almer
2025-03-11 19:06 ` James Almer
2025-03-15 0:34 ` Michael Niedermayer
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git