[FFmpeg-cvslog] vaapi_encode_h265: Query encoding block sizes and features

2022-04-10 Thread Mark Thompson
ffmpeg | branch: master | Mark Thompson  | Thu Mar 17 14:41:52 
2022 +0800| [9f02e033875185409c861846f209b04a3be339d2] | committer: Haihao Xiang

vaapi_encode_h265: Query encoding block sizes and features

Signed-off-by: Fei Wang 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9f02e033875185409c861846f209b04a3be339d2
---

 libavcodec/vaapi_encode_h265.c | 114 ++---
 1 file changed, 108 insertions(+), 6 deletions(-)

diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
index 5b19381c5a..456307d570 100644
--- a/libavcodec/vaapi_encode_h265.c
+++ b/libavcodec/vaapi_encode_h265.c
@@ -56,6 +56,9 @@ typedef struct VAAPIEncodeH265Context {
 VAAPIEncodeContext common;
 
 // Encoder features.
+uint32_t va_features;
+// Block size info.
+uint32_t va_bs;
 uint32_t ctu_size;
 uint32_t min_cb_size;
 
@@ -427,9 +430,9 @@ static int 
vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
 vps->vps_max_latency_increase_plus1[i];
 }
 
-// These have to come from the capabilities of the encoder.  We have no
-// way to query them, so just hardcode parameters which work on the Intel
-// driver.
+// These values come from the capabilities of the first encoder
+// implementation in the i965 driver on Intel Skylake.  They may
+// fail badly with other platforms or drivers.
 // CTB size from 8x8 to 32x32.
 sps->log2_min_luma_coding_block_size_minus3   = 0;
 sps->log2_diff_max_min_luma_coding_block_size = 2;
@@ -447,6 +450,42 @@ static int 
vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
 
 sps->pcm_enabled_flag = 0;
 
+// update sps setting according to queried result
+#if VA_CHECK_VERSION(1, 13, 0)
+if (priv->va_features) {
+VAConfigAttribValEncHEVCFeatures features = { .value = 
priv->va_features };
+
+// Enable feature if get queried result is VA_FEATURE_SUPPORTED | 
VA_FEATURE_REQUIRED
+sps->amp_enabled_flag =
+!!features.bits.amp;
+sps->sample_adaptive_offset_enabled_flag =
+!!features.bits.sao;
+sps->sps_temporal_mvp_enabled_flag =
+!!features.bits.temporal_mvp;
+sps->pcm_enabled_flag =
+!!features.bits.pcm;
+}
+
+if (priv->va_bs) {
+VAConfigAttribValEncHEVCBlockSizes bs = { .value = priv->va_bs };
+sps->log2_min_luma_coding_block_size_minus3 =
+ff_ctz(priv->min_cb_size) - 3;
+sps->log2_diff_max_min_luma_coding_block_size =
+ff_ctz(priv->ctu_size) - ff_ctz(priv->min_cb_size);
+
+sps->log2_min_luma_transform_block_size_minus2 =
+bs.bits.log2_min_luma_transform_block_size_minus2;
+sps->log2_diff_max_min_luma_transform_block_size =
+bs.bits.log2_max_luma_transform_block_size_minus2 -
+bs.bits.log2_min_luma_transform_block_size_minus2;
+
+sps->max_transform_hierarchy_depth_inter =
+bs.bits.max_max_transform_hierarchy_depth_inter;
+sps->max_transform_hierarchy_depth_intra =
+bs.bits.max_max_transform_hierarchy_depth_intra;
+}
+#endif
+
 // STRPSs should ideally be here rather than defined individually in
 // each slice, but the structure isn't completely fixed so for now
 // don't bother.
@@ -539,6 +578,23 @@ static int 
vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
 pps->cu_qp_delta_enabled_flag = (ctx->va_rc_mode != VA_RC_CQP);
 pps->diff_cu_qp_delta_depth   = 0;
 
+// update pps setting according to queried result
+#if VA_CHECK_VERSION(1, 13, 0)
+if (priv->va_features) {
+VAConfigAttribValEncHEVCFeatures features = { .value = 
priv->va_features };
+if (ctx->va_rc_mode != VA_RC_CQP)
+pps->cu_qp_delta_enabled_flag =
+!!features.bits.cu_qp_delta;
+
+pps->transform_skip_enabled_flag =
+!!features.bits.transform_skip;
+// set diff_cu_qp_delta_depth as its max value if cu_qp_delta enabled. 
Otherwise
+// 0 will make cu_qp_delta invalid.
+if (pps->cu_qp_delta_enabled_flag)
+pps->diff_cu_qp_delta_depth = 
sps->log2_diff_max_min_luma_coding_block_size;
+}
+#endif
+
 if (ctx->tile_rows && ctx->tile_cols) {
 int uniform_spacing;
 
@@ -640,8 +696,8 @@ static int 
vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
 
 .coded_buf = VA_INVALID_ID,
 
-.collocated_ref_pic_index = 0xff,
-
+.collocated_ref_pic_index = sps->sps_temporal_mvp_enabled_flag ?
+0 : 0xff,
 .last_picture = 0,
 
 .pic_init_qp= pps->init_qp_minus26 + 26,
@@ -674,6 +730,8 @@ static int 
vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
 .entropy_coding_sync_enabled_flag = 
pps->entropy_coding_sync_enabled_flag,
 .loop_filter_across_tiles_enabled_flag =

[FFmpeg-cvslog] vaapi_encode: Move block size calculation after entrypoint selection

2022-04-10 Thread Mark Thompson
ffmpeg | branch: master | Mark Thompson  | Thu Mar 17 14:41:50 
2022 +0800| [99b333e5ff5a91de2a5d740bbc9fa344154511c1] | committer: Haihao Xiang

vaapi_encode: Move block size calculation after entrypoint selection

The block size can be dependent on the profile and entrypoint selected.
It defaults to 16x16, with codecs able to override this choice with their
own function.

Signed-off-by: Fei Wang 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=99b333e5ff5a91de2a5d740bbc9fa344154511c1
---

 libavcodec/vaapi_encode.c   | 16 
 libavcodec/vaapi_encode.h   |  7 +++
 libavcodec/vaapi_encode_h265.c  | 32 ++--
 libavcodec/vaapi_encode_mjpeg.c | 18 +++---
 libavcodec/vaapi_encode_mpeg2.c |  3 ---
 libavcodec/vaapi_encode_vp8.c   |  3 ---
 libavcodec/vaapi_encode_vp9.c   | 16 
 7 files changed, 76 insertions(+), 19 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 21a0ed0827..0e2f5ed447 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -2117,6 +2117,8 @@ static av_cold int 
vaapi_encode_init_slice_structure(AVCodecContext *avctx)
 return 0;
 }
 
+av_assert0(ctx->slice_block_height > 0 && ctx->slice_block_width > 0);
+
 ctx->slice_block_rows = (avctx->height + ctx->slice_block_height - 1) /
  ctx->slice_block_height;
 ctx->slice_block_cols = (avctx->width  + ctx->slice_block_width  - 1) /
@@ -2506,6 +2508,20 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
 if (err < 0)
 goto fail;
 
+if (ctx->codec->get_encoder_caps) {
+err = ctx->codec->get_encoder_caps(avctx);
+if (err < 0)
+goto fail;
+} else {
+// Assume 16x16 blocks.
+ctx->surface_width  = FFALIGN(avctx->width,  16);
+ctx->surface_height = FFALIGN(avctx->height, 16);
+if (ctx->codec->flags & FLAG_SLICE_CONTROL) {
+ctx->slice_block_width  = 16;
+ctx->slice_block_height = 16;
+}
+}
+
 err = vaapi_encode_init_rate_control(avctx);
 if (err < 0)
 goto fail;
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index 4596e49ba9..af0588c30b 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -386,6 +386,13 @@ typedef struct VAAPIEncodeType {
 // factor depending on RC mode.
 int default_quality;
 
+// Determine encode parameters like block sizes for surface alignment
+// and slices. This may need to query the profile and entrypoint,
+// which will be available when this function is called. If not set,
+// assume that all blocks are 16x16 and that surfaces should be
+// aligned to match this.
+int (*get_encoder_caps)(AVCodecContext *avctx);
+
 // Perform any extra codec-specific configuration after the
 // codec context is initialised (set up the private data and
 // add any necessary global parameters).
diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
index 76d67237d2..3fa1336bb0 100644
--- a/libavcodec/vaapi_encode_h265.c
+++ b/libavcodec/vaapi_encode_h265.c
@@ -55,6 +55,10 @@ typedef struct VAAPIEncodeH265Picture {
 typedef struct VAAPIEncodeH265Context {
 VAAPIEncodeContext common;
 
+// Encoder features.
+uint32_t ctu_size;
+uint32_t min_cb_size;
+
 // User options.
 int qp;
 int aud;
@@ -1091,6 +1095,27 @@ static int 
vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
 return 0;
 }
 
+static av_cold int vaapi_encode_h265_get_encoder_caps(AVCodecContext *avctx)
+{
+VAAPIEncodeContext  *ctx = avctx->priv_data;
+VAAPIEncodeH265Context *priv = avctx->priv_data;
+
+if (!priv->ctu_size) {
+priv->ctu_size = 32;
+priv->min_cb_size  = 16;
+}
+av_log(avctx, AV_LOG_VERBOSE, "Using CTU size %dx%d, "
+   "min CB size %dx%d.\n", priv->ctu_size, priv->ctu_size,
+   priv->min_cb_size, priv->min_cb_size);
+
+ctx->surface_width  = FFALIGN(avctx->width,  priv->min_cb_size);
+ctx->surface_height = FFALIGN(avctx->height, priv->min_cb_size);
+
+ctx->slice_block_width = ctx->slice_block_height = priv->ctu_size;
+
+return 0;
+}
+
 static av_cold int vaapi_encode_h265_configure(AVCodecContext *avctx)
 {
 VAAPIEncodeContext  *ctx = avctx->priv_data;
@@ -1160,6 +1185,7 @@ static const VAAPIEncodeType vaapi_encode_type_h265 = {
 
 .default_quality   = 25,
 
+.get_encoder_caps  = _encode_h265_get_encoder_caps,
 .configure = _encode_h265_configure,
 
 .picture_priv_data_size = sizeof(VAAPIEncodeH265Picture),
@@ -1205,12 +1231,6 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext 
*avctx)
 VA_ENC_PACKED_HEADER_SLICE| // Slice headers.
 VA_ENC_PACKED_HEADER_MISC;  // SEI
 
-ctx->surface_width  = FFALIGN(avctx->width,  16);
-ctx->surface_height = 

[FFmpeg-cvslog] vaapi_encode_h265: Explicitly set and correct some flags

2022-04-10 Thread Mark Thompson
ffmpeg | branch: master | Mark Thompson  | Thu Mar 17 14:41:51 
2022 +0800| [77fd2f9c7c5c82e5991225a005f4f724ea5a207b] | committer: Haihao Xiang

vaapi_encode_h265: Explicitly set and correct some flags

max_14bit_constraint_flag should be set if the bit depth is not greater than
14 (currently always true).

one_picture_only_flag should not be set because we don't support the still
picture profiles.

general_profile_compatibility_flag should be set according to 
general_profile_idc
instead of bit depth.

Signed-off-by: Fei Wang 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=77fd2f9c7c5c82e5991225a005f4f724ea5a207b
---

 libavcodec/vaapi_encode_h265.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
index 3fa1336bb0..5b19381c5a 100644
--- a/libavcodec/vaapi_encode_h265.c
+++ b/libavcodec/vaapi_encode_h265.c
@@ -303,17 +303,21 @@ static int 
vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
 ptl->general_profile_idc   = avctx->profile;
 ptl->general_tier_flag = priv->tier;
 
-if (chroma_format == 1) {
-ptl->general_profile_compatibility_flag[1] = bit_depth ==  8;
-ptl->general_profile_compatibility_flag[2] = bit_depth <= 10;
+ptl->general_profile_compatibility_flag[ptl->general_profile_idc] = 1;
+
+if (ptl->general_profile_compatibility_flag[1])
+ptl->general_profile_compatibility_flag[2] = 1;
+if (ptl->general_profile_compatibility_flag[3]) {
+ptl->general_profile_compatibility_flag[1] = 1;
+ptl->general_profile_compatibility_flag[2] = 1;
 }
-ptl->general_profile_compatibility_flag[4] = 1;
 
 ptl->general_progressive_source_flag= 1;
 ptl->general_interlaced_source_flag = 0;
 ptl->general_non_packed_constraint_flag = 1;
 ptl->general_frame_only_constraint_flag = 1;
 
+ptl->general_max_14bit_constraint_flag = bit_depth <= 14;
 ptl->general_max_12bit_constraint_flag = bit_depth <= 12;
 ptl->general_max_10bit_constraint_flag = bit_depth <= 10;
 ptl->general_max_8bit_constraint_flag  = bit_depth ==  8;
@@ -323,6 +327,7 @@ static int 
vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
 ptl->general_max_monochrome_constraint_flag = chroma_format == 0;
 
 ptl->general_intra_constraint_flag = ctx->gop_size == 1;
+ptl->general_one_picture_only_constraint_flag = 0;
 
 ptl->general_lower_bit_rate_constraint_flag = 1;
 

___
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".


[FFmpeg-cvslog] lavc/vaapi_encode_h265: Add GPB frame support for hevc_vaapi

2022-04-10 Thread Linjie Fu
ffmpeg | branch: master | Linjie Fu  | Thu Mar 17 14:41:49 
2022 +0800| [a285968a0b122484635846babd9a1e8183e70fb0] | committer: Haihao Xiang

lavc/vaapi_encode_h265: Add GPB frame support for hevc_vaapi

Use GPB frames to replace regular P/B frames if backend driver does not
support it.

- GPB:
Generalized P and B picture. Regular P/B frames replaced by B
frames with previous-predict only, L0 == L1. Normal B frames
still have 2 different ref_lists and allow bi-prediction

Signed-off-by: Linjie Fu 
Signed-off-by: Fei Wang 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a285968a0b122484635846babd9a1e8183e70fb0
---

 libavcodec/vaapi_encode.c  | 67 ++
 libavcodec/vaapi_encode.h  |  1 +
 libavcodec/vaapi_encode_h265.c | 15 ++
 3 files changed, 78 insertions(+), 5 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index ffd6cb1c25..21a0ed0827 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -1875,6 +1875,7 @@ static av_cold int 
vaapi_encode_init_gop_structure(AVCodecContext *avctx)
 VAStatus vas;
 VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
 uint32_t ref_l0, ref_l1;
+int prediction_pre_only;
 
 vas = vaGetConfigAttributes(ctx->hwctx->display,
 ctx->va_profile,
@@ -1893,6 +1894,51 @@ static av_cold int 
vaapi_encode_init_gop_structure(AVCodecContext *avctx)
 ref_l1 = attr.value >> 16 & 0x;
 }
 
+ctx->p_to_gpb = 0;
+prediction_pre_only = 0;
+
+#if VA_CHECK_VERSION(1, 9, 0)
+if (!(ctx->codec->flags & FLAG_INTRA_ONLY ||
+avctx->gop_size <= 1)) {
+attr = (VAConfigAttrib) { VAConfigAttribPredictionDirection };
+vas = vaGetConfigAttributes(ctx->hwctx->display,
+ctx->va_profile,
+ctx->va_entrypoint,
+, 1);
+if (vas != VA_STATUS_SUCCESS) {
+av_log(avctx, AV_LOG_WARNING, "Failed to query prediction 
direction "
+   "attribute: %d (%s).\n", vas, vaErrorStr(vas));
+return AVERROR_EXTERNAL;
+} else if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
+av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any 
additional "
+   "prediction constraints.\n");
+} else {
+if (((ref_l0 > 0 || ref_l1 > 0) && !(attr.value & 
VA_PREDICTION_DIRECTION_PREVIOUS)) ||
+((ref_l1 == 0) && (attr.value & 
(VA_PREDICTION_DIRECTION_FUTURE | VA_PREDICTION_DIRECTION_BI_NOT_EMPTY {
+av_log(avctx, AV_LOG_ERROR, "Driver report incorrect 
prediction "
+   "direction attribute.\n");
+return AVERROR_EXTERNAL;
+}
+
+if (!(attr.value & VA_PREDICTION_DIRECTION_FUTURE)) {
+if (ref_l0 > 0 && ref_l1 > 0) {
+prediction_pre_only = 1;
+av_log(avctx, AV_LOG_VERBOSE, "Driver only support same 
reference "
+   "lists for B-frames.\n");
+}
+}
+
+if (attr.value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) {
+if (ref_l0 > 0 && ref_l1 > 0) {
+ctx->p_to_gpb = 1;
+av_log(avctx, AV_LOG_VERBOSE, "Driver does not support 
P-frames, "
+   "replacing them with B-frames.\n");
+}
+}
+}
+}
+#endif
+
 if (ctx->codec->flags & FLAG_INTRA_ONLY ||
 avctx->gop_size <= 1) {
 av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
@@ -1902,15 +1948,26 @@ static av_cold int 
vaapi_encode_init_gop_structure(AVCodecContext *avctx)
"reference frames.\n");
 return AVERROR(EINVAL);
 } else if (!(ctx->codec->flags & FLAG_B_PICTURES) ||
-   ref_l1 < 1 || avctx->max_b_frames < 1) {
-av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
-   "(supported references: %d / %d).\n", ref_l0, ref_l1);
+   ref_l1 < 1 || avctx->max_b_frames < 1 ||
+   prediction_pre_only) {
+if (ctx->p_to_gpb)
+   av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
+  "(supported references: %d / %d).\n",
+  ref_l0, ref_l1);
+else
+av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
+   "(supported references: %d / %d).\n", ref_l0, ref_l1);
 ctx->gop_size = avctx->gop_size;
 ctx->p_per_i  = INT_MAX;
 ctx->b_per_p  = 0;
 } else {
-av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
-   "(supported references: %d / %d).\n", ref_l0, ref_l1);
+   if (ctx->p_to_gpb)
+   av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
+  "(supported references: %d / 

[FFmpeg-cvslog] avfilter: let single output frame A->V filters set reasonable frame rate

2022-04-10 Thread Paul B Mahol
ffmpeg | branch: master | Paul B Mahol  | Sun Apr 10 22:39:12 
2022 +0200| [6e45acd23b6b5062f548c2551b1a64cc268eb787] | committer: Paul B Mahol

avfilter: let single output frame A->V filters set reasonable frame rate

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=6e45acd23b6b5062f548c2551b1a64cc268eb787
---

 libavfilter/avf_showspectrum.c | 2 ++
 libavfilter/avf_showwaves.c| 7 +--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c
index 6b99fc9a8b..c99dabad87 100644
--- a/libavfilter/avf_showspectrum.c
+++ b/libavfilter/avf_showspectrum.c
@@ -1241,6 +1241,8 @@ static int config_output(AVFilterLink *outlink)
 int ret = av_parse_video_rate(>frame_rate, s->rate_str);
 if (ret < 0)
 return ret;
+} else if (s->single_pic) {
+s->frame_rate = av_make_q(1, 1);
 } else {
 s->frame_rate = s->auto_frame_rate;
 }
diff --git a/libavfilter/avf_showwaves.c b/libavfilter/avf_showwaves.c
index f491277ce1..76399ab13d 100644
--- a/libavfilter/avf_showwaves.c
+++ b/libavfilter/avf_showwaves.c
@@ -437,8 +437,11 @@ static int config_output(AVFilterLink *outlink)
 outlink->h = showwaves->h;
 outlink->sample_aspect_ratio = (AVRational){1,1};
 
-outlink->frame_rate = 
av_div_q((AVRational){inlink->sample_rate,showwaves->n},
-   (AVRational){showwaves->w,1});
+if (showwaves->single_pic)
+outlink->frame_rate = av_make_q(1, 1);
+else
+outlink->frame_rate = 
av_div_q((AVRational){inlink->sample_rate,showwaves->n},
+   (AVRational){showwaves->w,1});
 
 av_log(ctx, AV_LOG_VERBOSE, "s:%dx%d r:%f n:%d\n",
showwaves->w, showwaves->h, av_q2d(outlink->frame_rate), 
showwaves->n);

___
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".


[FFmpeg-cvslog] fate: add fate tests for VBN encoder and decoder

2022-04-10 Thread Marton Balint
ffmpeg | branch: master | Marton Balint  | Wed Mar 23 23:55:21 
2022 +0100| [7ac559b819070b1d0ae7b80e35b9f1fb4cf3] | committer: Marton 
Balint

fate: add fate tests for VBN encoder and decoder

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7ac559b819070b1d0ae7b80e35b9f1fb4cf3
---

 tests/Makefile   |  1 +
 tests/fate-run.sh| 11 +++
 tests/fate/vbn.mak   | 36 
 tests/ref/fate/vbn-dxt1  | 11 +++
 tests/ref/fate/vbn-dxt5  | 11 +++
 tests/ref/fate/vbn-raw-rgb24 |  9 +
 tests/ref/fate/vbn-raw-rgba  | 11 +++
 7 files changed, 90 insertions(+)

diff --git a/tests/Makefile b/tests/Makefile
index 9f33394856..e3b41a4f7b 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -191,6 +191,7 @@ include $(SRC_PATH)/tests/fate/speedhq.mak
 include $(SRC_PATH)/tests/fate/subtitles.mak
 include $(SRC_PATH)/tests/fate/truehd.mak
 include $(SRC_PATH)/tests/fate/utvideo.mak
+include $(SRC_PATH)/tests/fate/vbn.mak
 include $(SRC_PATH)/tests/fate/video.mak
 include $(SRC_PATH)/tests/fate/voice.mak
 include $(SRC_PATH)/tests/fate/vorbis.mak
diff --git a/tests/fate-run.sh b/tests/fate-run.sh
index a5730c1f62..8c27210ac0 100755
--- a/tests/fate-run.sh
+++ b/tests/fate-run.sh
@@ -391,6 +391,17 @@ cmp_metadata(){
 -f null /dev/null | awk -v ref=${ref} -v fuzz=${fuzz} -f 
${base}/refcmp-metadata.awk -
 }
 
+refcmp_metadata_files(){
+refcmp=$1
+pixfmt=$2
+file1=$3
+file2=$4
+fuzz=${5:-0.001}
+ffmpeg -auto_conversion_filters $FLAGS -i $file1 $FLAGS -i $file2 
$ENC_OPTS \
+-lavfi 
"[0:v]format=${pixfmt}[v0];[1:v]format=${pixfmt}[v1];[v0][v1]${refcmp},metadata=print:file=-"
 \
+-f null /dev/null | awk -v ref=${ref} -v fuzz=${fuzz} -f 
${base}/refcmp-metadata.awk -
+}
+
 pixfmt_conversion(){
 conversion="${test#pixfmt-}"
 outdir="tests/data/pixfmt"
diff --git a/tests/fate/vbn.mak b/tests/fate/vbn.mak
new file mode 100644
index 00..044b110ac1
--- /dev/null
+++ b/tests/fate/vbn.mak
@@ -0,0 +1,36 @@
+fate-vbn-%: VBN_FILE = tests/data/$(subst fate-vbn-,,$(@)).vbn
+fate-vbn-%: PIX_FMT = rgba
+fate-vbn-raw-rgb24: PIX_FMT = rgb24
+fate-vbn-%: SRC = $(TARGET_SAMPLES)/png1/lena-$(PIX_FMT).png
+fate-vbn-%: CMD = refcmp_metadata_files psnr $(PIX_FMT) $(VBN_FILE) $(SRC)
+
+fate-vbn-dxt1: tests/data/dxt1.vbn
+fate-vbn-dxt5: tests/data/dxt5.vbn
+fate-vbn-raw-rgba: tests/data/raw-rgba.vbn
+fate-vbn-raw-rgb24: tests/data/raw-rgb24.vbn
+
+FATE_VBN += fate-vbn-dxt1
+FATE_VBN += fate-vbn-dxt5
+FATE_VBN += fate-vbn-raw-rgba
+FATE_VBN += fate-vbn-raw-rgb24
+
+tests/data/dxt1.vbn: TAG = GEN
+tests/data/dxt1.vbn: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data
+   $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< -nostdin -i 
$(TARGET_SAMPLES)/png1/lena-rgba.png -nostdin -c:v vbn -format dxt1 
$(TARGET_PATH)/$@ -y 2>/dev/null
+
+tests/data/dxt5.vbn: TAG = GEN
+tests/data/dxt5.vbn: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data
+   $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< -nostdin -i 
$(TARGET_SAMPLES)/png1/lena-rgba.png -nostdin -c:v vbn -format dxt5 
$(TARGET_PATH)/$@ -y 2>/dev/null
+
+tests/data/raw-rgba.vbn: TAG = GEN
+tests/data/raw-rgba.vbn: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data
+   $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< -nostdin -i 
$(TARGET_SAMPLES)/png1/lena-rgba.png -nostdin -c:v vbn -format raw 
$(TARGET_PATH)/$@ -y 2>/dev/null
+
+tests/data/raw-rgb24.vbn: TAG = GEN
+tests/data/raw-rgb24.vbn: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data
+   $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< -nostdin -i 
$(TARGET_SAMPLES)/png1/lena-rgb24.png -nostdin -c:v vbn -format raw 
$(TARGET_PATH)/$@ -y 2>/dev/null
+
+VBN_REFCMP_DEPS = PSNR_FILTER METADATA_FILTER VBN_ENCODER VBN_DECODER 
IMAGE2_MUXER IMAGE2_DEMUXER PNG_DECODER
+
+FATE_SAMPLES_FFMPEG-$(call ALLYES, $(VBN_REFCMP_DEPS)) += $(FATE_VBN)
+fate-vbn: $(FATE_VBN)
diff --git a/tests/ref/fate/vbn-dxt1 b/tests/ref/fate/vbn-dxt1
new file mode 100644
index 00..0afd94
--- /dev/null
+++ b/tests/ref/fate/vbn-dxt1
@@ -0,0 +1,11 @@
+frame:0pts:0   pts_time:0
+lavfi.psnr.mse.r=36.794250
+lavfi.psnr.psnr.r=32.473003
+lavfi.psnr.mse.g=33.350525
+lavfi.psnr.psnr.g=32.899776
+lavfi.psnr.mse.b=28.317383
+lavfi.psnr.psnr.b=33.610271
+lavfi.psnr.mse.a=21186.988281
+lavfi.psnr.psnr.a=4.870111
+lavfi.psnr.mse_avg=5321.362793
+lavfi.psnr.psnr_avg=10.870575
diff --git a/tests/ref/fate/vbn-dxt5 b/tests/ref/fate/vbn-dxt5
new file mode 100644
index 00..dbec0bd13d
--- /dev/null
+++ b/tests/ref/fate/vbn-dxt5
@@ -0,0 +1,11 @@
+frame:0pts:0   pts_time:0
+lavfi.psnr.mse.r=36.794250
+lavfi.psnr.psnr.r=32.473003
+lavfi.psnr.mse.g=33.350525
+lavfi.psnr.psnr.g=32.899776
+lavfi.psnr.mse.b=28.317383
+lavfi.psnr.psnr.b=33.610271
+lavfi.psnr.mse.a=0.000183
+lavfi.psnr.psnr.a=85.503792
+lavfi.psnr.mse_avg=24.615585
+lavfi.psnr.psnr_avg=34.218700
diff --git a/tests/ref/fate/vbn-raw-rgb24 b/tests/ref/fate/vbn-raw-rgb24

[FFmpeg-cvslog] avcodec/vbnenc: add VBN encoder

2022-04-10 Thread Marton Balint
ffmpeg | branch: master | Marton Balint  | Tue Mar 22 02:29:29 
2022 +0100| [ee50cc18b3943405aa476e31c8553aa098350b1e] | committer: Marton 
Balint

avcodec/vbnenc: add VBN encoder

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ee50cc18b3943405aa476e31c8553aa098350b1e
---

 Changelog |   2 +-
 configure |   1 +
 doc/encoders.texi |  16 +
 doc/general_contents.texi |   2 +
 libavcodec/Makefile   |   1 +
 libavcodec/allcodecs.c|   1 +
 libavcodec/vbnenc.c   | 173 ++
 libavcodec/version.h  |   4 +-
 libavformat/img2enc.c |   2 +-
 libavformat/version.h |   4 +-
 10 files changed, 200 insertions(+), 6 deletions(-)

diff --git a/Changelog b/Changelog
index 55512c8e03..29754be4c9 100644
--- a/Changelog
+++ b/Changelog
@@ -7,7 +7,7 @@ version 5.1:
 - pcm-bluray encoder
 - DFPWM audio encoder/decoder and raw muxer/demuxer
 - SITI filter
-- Vizrt Binary Image decoder
+- Vizrt Binary Image encoder/decoder
 
 
 version 5.0:
diff --git a/configure b/configure
index 90c99ff85e..9c8965852b 100755
--- a/configure
+++ b/configure
@@ -2960,6 +2960,7 @@ utvideo_decoder_select="bswapdsp llviddsp"
 utvideo_encoder_select="bswapdsp huffman llvidencdsp"
 vble_decoder_select="llviddsp"
 vbn_decoder_select="texturedsp"
+vbn_encoder_select="texturedspenc"
 vc1_decoder_select="blockdsp h263_decoder h264qpel intrax8 mpegvideodec vc1dsp"
 vc1image_decoder_select="vc1_decoder"
 vorbis_decoder_select="mdct"
diff --git a/doc/encoders.texi b/doc/encoders.texi
index 806cc430d4..aac9f25e55 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3773,6 +3773,22 @@ required to produce a stream usable with all decoders.
 
 @end table
 
+@section vbn
+
+Vizrt Binary Image encoder.
+
+This format is used by the broadcast vendor Vizrt for quick texture streaming.
+Advanced features of the format such as LZW compression of texture data or
+generation of mipmaps are not supported.
+
+@subsection Options
+
+@table @option
+@item format @var{string}
+Sets the texture compression used by the VBN file. Can be @var{dxt1},
+@var{dxt5} or @var{raw}. Default is @var{dxt5}.
+@end table
+
 @section vc2
 
 SMPTE VC-2 (previously BBC Dirac Pro). This codec was primarily aimed at
diff --git a/doc/general_contents.texi b/doc/general_contents.texi
index fcd9da1b34..238568f2bb 100644
--- a/doc/general_contents.texi
+++ b/doc/general_contents.texi
@@ -786,6 +786,8 @@ following image formats are supported:
 @tab YUV, JPEG and some extension is not supported yet.
 @item Truevision Targa  @tab X @tab X
 @tab Targa (.TGA) image format
+@item VBN  @tab X @tab X
+@tab Vizrt Binary Image format
 @item WebP @tab E @tab X
 @tab WebP image format, encoding supported through external library libwebp
 @item XBM  @tab X @tab X
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 90700085b8..90f46035d9 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -709,6 +709,7 @@ OBJS-$(CONFIG_V410_DECODER)+= v410dec.o
 OBJS-$(CONFIG_V410_ENCODER)+= v410enc.o
 OBJS-$(CONFIG_VB_DECODER)  += vb.o
 OBJS-$(CONFIG_VBN_DECODER) += vbndec.o
+OBJS-$(CONFIG_VBN_ENCODER) += vbnenc.o
 OBJS-$(CONFIG_VBLE_DECODER)+= vble.o
 OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1_block.o 
vc1_loopfilter.o \
   vc1_mc.o vc1_pred.o vc1.o vc1data.o \
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index f0a7ea7fd4..585918da93 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -347,6 +347,7 @@ extern const FFCodec ff_v408_decoder;
 extern const FFCodec ff_v410_encoder;
 extern const FFCodec ff_v410_decoder;
 extern const FFCodec ff_vb_decoder;
+extern const FFCodec ff_vbn_encoder;
 extern const FFCodec ff_vbn_decoder;
 extern const FFCodec ff_vble_decoder;
 extern const FFCodec ff_vc1_decoder;
diff --git a/libavcodec/vbnenc.c b/libavcodec/vbnenc.c
new file mode 100644
index 00..5c855bcd73
--- /dev/null
+++ b/libavcodec/vbnenc.c
@@ -0,0 +1,173 @@
+/*
+ * Vizrt Binary Image encoder
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file

[FFmpeg-cvslog] avcodec/hapenc: use the common texturedsp encode function

2022-04-10 Thread Marton Balint
ffmpeg | branch: master | Marton Balint  | Wed Mar 23 01:19:58 
2022 +0100| [a4570d7a66da772d2f530980a60ef5057750f8e6] | committer: Marton 
Balint

avcodec/hapenc: use the common texturedsp encode function

And add slice thread capabilities.

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a4570d7a66da772d2f530980a60ef5057750f8e6
---

 libavcodec/hap.h|  4 +---
 libavcodec/hapenc.c | 34 --
 2 files changed, 17 insertions(+), 21 deletions(-)

diff --git a/libavcodec/hap.h b/libavcodec/hap.h
index 7e065e4838..fb5a4c4123 100644
--- a/libavcodec/hap.h
+++ b/libavcodec/hap.h
@@ -80,9 +80,7 @@ typedef struct HapContext {
 int texture_count;  /* 2 for HAQA, 1 for other version */
 int texture_section_size; /* size of the part of the texture section (for 
HAPQA) */
 
-/* Pointer to the selected compress function (encoder only) */
-int (*tex_fun)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block);
-
+TextureDSPThreadContext enc;
 TextureDSPThreadContext dec[2];
 } HapContext;
 
diff --git a/libavcodec/hapenc.c b/libavcodec/hapenc.c
index f3964896d5..6a9d4e06cb 100644
--- a/libavcodec/hapenc.c
+++ b/libavcodec/hapenc.c
@@ -56,18 +56,14 @@ enum HapHeaderLength {
 static int compress_texture(AVCodecContext *avctx, uint8_t *out, int 
out_length, const AVFrame *f)
 {
 HapContext *ctx = avctx->priv_data;
-int i, j;
 
 if (ctx->tex_size > out_length)
 return AVERROR_BUFFER_TOO_SMALL;
 
-for (j = 0; j < avctx->height; j += 4) {
-for (i = 0; i < avctx->width; i += 4) {
-uint8_t *p = f->data[0] + i * 4 + j * f->linesize[0];
-const int step = ctx->tex_fun(out, f->linesize[0], p);
-out += step;
-}
-}
+ctx->enc.tex_data.out = out;
+ctx->enc.frame_data.in = f->data[0];
+ctx->enc.stride = f->linesize[0];
+avctx->execute2(avctx, ff_texturedsp_compress_thread, >enc, NULL, 
ctx->enc.slice_count);
 
 return 0;
 }
@@ -236,7 +232,6 @@ static int hap_encode(AVCodecContext *avctx, AVPacket *pkt,
 static av_cold int hap_init(AVCodecContext *avctx)
 {
 HapContext *ctx = avctx->priv_data;
-int ratio;
 int corrected_chunk_count;
 int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
 
@@ -256,32 +251,34 @@ static av_cold int hap_init(AVCodecContext *avctx)
 
 switch (ctx->opt_tex_fmt) {
 case HAP_FMT_RGBDXT1:
-ratio = 8;
+ctx->enc.tex_ratio = 8;
 avctx->codec_tag = MKTAG('H', 'a', 'p', '1');
 avctx->bits_per_coded_sample = 24;
-ctx->tex_fun = ctx->dxtc.dxt1_block;
+ctx->enc.tex_funct = ctx->dxtc.dxt1_block;
 break;
 case HAP_FMT_RGBADXT5:
-ratio = 4;
+ctx->enc.tex_ratio = 16;
 avctx->codec_tag = MKTAG('H', 'a', 'p', '5');
 avctx->bits_per_coded_sample = 32;
-ctx->tex_fun = ctx->dxtc.dxt5_block;
+ctx->enc.tex_funct = ctx->dxtc.dxt5_block;
 break;
 case HAP_FMT_YCOCGDXT5:
-ratio = 4;
+ctx->enc.tex_ratio = 16;
 avctx->codec_tag = MKTAG('H', 'a', 'p', 'Y');
 avctx->bits_per_coded_sample = 24;
-ctx->tex_fun = ctx->dxtc.dxt5ys_block;
+ctx->enc.tex_funct = ctx->dxtc.dxt5ys_block;
 break;
 default:
 av_log(avctx, AV_LOG_ERROR, "Invalid format %02X\n", ctx->opt_tex_fmt);
 return AVERROR_INVALIDDATA;
 }
+ctx->enc.raw_ratio = 16;
+ctx->enc.slice_count = av_clip(avctx->thread_count, 1, avctx->height / 
TEXTURE_BLOCK_H);
 
 /* Texture compression ratio is constant, so can we computer
  * beforehand the final size of the uncompressed buffer. */
-ctx->tex_size   = FFALIGN(avctx->width,  TEXTURE_BLOCK_W) *
-  FFALIGN(avctx->height, TEXTURE_BLOCK_H) * 4 / ratio;
+ctx->tex_size   = avctx->width  / TEXTURE_BLOCK_W *
+  avctx->height / TEXTURE_BLOCK_H * ctx->enc.tex_ratio;
 
 switch (ctx->opt_compressor) {
 case HAP_COMP_NONE:
@@ -294,7 +291,7 @@ static av_cold int hap_init(AVCodecContext *avctx)
 case HAP_COMP_SNAPPY:
 /* Round the chunk count to divide evenly on DXT block edges */
 corrected_chunk_count = av_clip(ctx->opt_chunk_count, 1, 
HAP_MAX_CHUNKS);
-while ((ctx->tex_size / (64 / ratio)) % corrected_chunk_count != 0) {
+while ((ctx->tex_size / ctx->enc.tex_ratio) % corrected_chunk_count != 
0) {
 corrected_chunk_count--;
 }
 
@@ -356,6 +353,7 @@ const FFCodec ff_hap_encoder = {
 .p.id   = AV_CODEC_ID_HAP,
 .priv_data_size = sizeof(HapContext),
 .p.priv_class   = _class,
+.p.capabilities = AV_CODEC_CAP_SLICE_THREADS,
 .init   = hap_init,
 FF_CODEC_ENCODE_CB(hap_encode),
 .close  = hap_close,

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org

[FFmpeg-cvslog] avcodec/vbndec: add VBN decoder

2022-04-10 Thread Marton Balint
ffmpeg | branch: master | Marton Balint  | Sat Mar 19 01:22:23 
2022 +0100| [013d774e225c685cf2a9674f4c5dc9bb13941cb4] | committer: Marton 
Balint

avcodec/vbndec: add VBN decoder

Add support for decoding Vizrt Binary Image (VBN) files.

LZW-compressed data is not supported yet.

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=013d774e225c685cf2a9674f4c5dc9bb13941cb4
---

 Changelog|   1 +
 configure|   1 +
 libavcodec/Makefile  |   1 +
 libavcodec/allcodecs.c   |   1 +
 libavcodec/codec_desc.c  |   7 ++
 libavcodec/codec_id.h|   1 +
 libavcodec/vbn.h |  50 
 libavcodec/vbndec.c  | 195 +++
 libavformat/allformats.c |   1 +
 libavformat/img2.c   |   1 +
 libavformat/img2dec.c|  12 +++
 11 files changed, 271 insertions(+)

diff --git a/Changelog b/Changelog
index e173d43229..55512c8e03 100644
--- a/Changelog
+++ b/Changelog
@@ -7,6 +7,7 @@ version 5.1:
 - pcm-bluray encoder
 - DFPWM audio encoder/decoder and raw muxer/demuxer
 - SITI filter
+- Vizrt Binary Image decoder
 
 
 version 5.0:
diff --git a/configure b/configure
index e4d36aa639..90c99ff85e 100755
--- a/configure
+++ b/configure
@@ -2959,6 +2959,7 @@ txd_decoder_select="texturedsp"
 utvideo_decoder_select="bswapdsp llviddsp"
 utvideo_encoder_select="bswapdsp huffman llvidencdsp"
 vble_decoder_select="llviddsp"
+vbn_decoder_select="texturedsp"
 vc1_decoder_select="blockdsp h263_decoder h264qpel intrax8 mpegvideodec vc1dsp"
 vc1image_decoder_select="vc1_decoder"
 vorbis_decoder_select="mdct"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index fb8b0e824b..90700085b8 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -708,6 +708,7 @@ OBJS-$(CONFIG_V408_ENCODER)+= v408enc.o
 OBJS-$(CONFIG_V410_DECODER)+= v410dec.o
 OBJS-$(CONFIG_V410_ENCODER)+= v410enc.o
 OBJS-$(CONFIG_VB_DECODER)  += vb.o
+OBJS-$(CONFIG_VBN_DECODER) += vbndec.o
 OBJS-$(CONFIG_VBLE_DECODER)+= vble.o
 OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1_block.o 
vc1_loopfilter.o \
   vc1_mc.o vc1_pred.o vc1.o vc1data.o \
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 22d56760ec..f0a7ea7fd4 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -347,6 +347,7 @@ extern const FFCodec ff_v408_decoder;
 extern const FFCodec ff_v410_encoder;
 extern const FFCodec ff_v410_decoder;
 extern const FFCodec ff_vb_decoder;
+extern const FFCodec ff_vbn_decoder;
 extern const FFCodec ff_vble_decoder;
 extern const FFCodec ff_vc1_decoder;
 extern const FFCodec ff_vc1_crystalhd_decoder;
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 81f3b3c640..c08854cc93 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -1863,6 +1863,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
 .long_name = NULL_IF_CONFIG_SMALL("GEM Raster image"),
 .props = AV_CODEC_PROP_LOSSY,
 },
+{
+.id= AV_CODEC_ID_VBN,
+.type  = AVMEDIA_TYPE_VIDEO,
+.name  = "vbn",
+.long_name = NULL_IF_CONFIG_SMALL("Vizrt Binary Image"),
+.props = AV_CODEC_PROP_LOSSY,
+},
 
 /* various PCM "codecs" */
 {
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index 3ffb9bd22e..43c72ce8e4 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -308,6 +308,7 @@ enum AVCodecID {
 AV_CODEC_ID_SIMBIOSIS_IMX,
 AV_CODEC_ID_SGA_VIDEO,
 AV_CODEC_ID_GEM,
+AV_CODEC_ID_VBN,
 
 /* various PCM "codecs" */
 AV_CODEC_ID_FIRST_AUDIO = 0x1, ///< A dummy id pointing at the 
start of audio codecs
diff --git a/libavcodec/vbn.h b/libavcodec/vbn.h
new file mode 100644
index 00..8660786de8
--- /dev/null
+++ b/libavcodec/vbn.h
@@ -0,0 +1,50 @@
+/*
+ * VBN format definitions
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * VBN format definitions.
+ */
+
+#ifndef AVCODEC_VBN_H
+#define AVCODEC_VBN_H
+
+#define VBN_MAGIC  0x900df11e
+#define VBN_MAJOR   3
+#define VBN_MINOR   4
+

[FFmpeg-cvslog] avcodec/hapdec: use the common texturedsp decode function

2022-04-10 Thread Marton Balint
ffmpeg | branch: master | Marton Balint  | Sat Mar 19 21:01:41 
2022 +0100| [b3074ac9f4987bd730d6e8e7d50c107ec65d79a3] | committer: Marton 
Balint

avcodec/hapdec: use the common texturedsp decode function

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b3074ac9f4987bd730d6e8e7d50c107ec65d79a3
---

 libavcodec/hap.h|  11 ++
 libavcodec/hapdec.c | 110 
 2 files changed, 28 insertions(+), 93 deletions(-)

diff --git a/libavcodec/hap.h b/libavcodec/hap.h
index 00c3dbb32d..7e065e4838 100644
--- a/libavcodec/hap.h
+++ b/libavcodec/hap.h
@@ -72,23 +72,18 @@ typedef struct HapContext {
 HapChunk *chunks;
 int *chunk_results;  /* Results from threaded operations */
 
-int tex_rat; /* Compression ratio */
-int tex_rat2; /* Compression ratio of the second texture */
-const uint8_t *tex_data; /* Compressed texture */
 uint8_t *tex_buf;/* Buffer for compressed texture */
 size_t tex_size; /* Size of the compressed texture */
 
 size_t max_snappy;   /* Maximum compressed size for snappy buffer */
 
-int slice_count; /* Number of slices for threaded operations */
-
 int texture_count;  /* 2 for HAQA, 1 for other version */
 int texture_section_size; /* size of the part of the texture section (for 
HAPQA) */
-int uncompress_pix_size; /* nb of byte / pixel for the target picture */
 
-/* Pointer to the selected compress or decompress function */
+/* Pointer to the selected compress function (encoder only) */
 int (*tex_fun)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block);
-int (*tex_fun2)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block);
+
+TextureDSPThreadContext dec[2];
 } HapContext;
 
 /*
diff --git a/libavcodec/hapdec.c b/libavcodec/hapdec.c
index 7db3f5fd76..0aab1ab87b 100644
--- a/libavcodec/hapdec.c
+++ b/libavcodec/hapdec.c
@@ -247,60 +247,6 @@ static int decompress_chunks_thread(AVCodecContext *avctx, 
void *arg,
 return 0;
 }
 
-static int decompress_texture_thread_internal(AVCodecContext *avctx, void *arg,
-  int slice, int thread_nb, int 
texture_num)
-{
-HapContext *ctx = avctx->priv_data;
-AVFrame *frame = arg;
-const uint8_t *d = ctx->tex_data;
-int w_block = avctx->coded_width / TEXTURE_BLOCK_W;
-int h_block = avctx->coded_height / TEXTURE_BLOCK_H;
-int x, y;
-int start_slice, end_slice;
-int base_blocks_per_slice = h_block / ctx->slice_count;
-int remainder_blocks = h_block % ctx->slice_count;
-
-/* When the frame height (in blocks) doesn't divide evenly between the
- * number of slices, spread the remaining blocks evenly between the first
- * operations */
-start_slice = slice * base_blocks_per_slice;
-/* Add any extra blocks (one per slice) that have been added before this 
slice */
-start_slice += FFMIN(slice, remainder_blocks);
-
-end_slice = start_slice + base_blocks_per_slice;
-/* Add an extra block if there are still remainder blocks to be accounted 
for */
-if (slice < remainder_blocks)
-end_slice++;
-
-for (y = start_slice; y < end_slice; y++) {
-uint8_t *p = frame->data[0] + y * frame->linesize[0] * TEXTURE_BLOCK_H;
-int off  = y * w_block;
-for (x = 0; x < w_block; x++) {
-if (texture_num == 0) {
-ctx->tex_fun(p + x * 4 * ctx->uncompress_pix_size, 
frame->linesize[0],
- d + (off + x) * ctx->tex_rat);
-} else {
-ctx->tex_fun2(p + x * 4 * ctx->uncompress_pix_size, 
frame->linesize[0],
-  d + (off + x) * ctx->tex_rat2);
-}
-}
-}
-
-return 0;
-}
-
-static int decompress_texture_thread(AVCodecContext *avctx, void *arg,
- int slice, int thread_nb)
-{
-return decompress_texture_thread_internal(avctx, arg, slice, thread_nb, 0);
-}
-
-static int decompress_texture2_thread(AVCodecContext *avctx, void *arg,
-  int slice, int thread_nb)
-{
-return decompress_texture_thread_internal(avctx, arg, slice, thread_nb, 1);
-}
-
 static int hap_decode(AVCodecContext *avctx, AVFrame *frame,
   int *got_frame, AVPacket *avpkt)
 {
@@ -309,12 +255,9 @@ static int hap_decode(AVCodecContext *avctx, AVFrame 
*frame,
 int section_size;
 enum HapSectionType section_type;
 int start_texture_section = 0;
-int tex_rat[2] = {0, 0};
 
 bytestream2_init(>gbc, avpkt->data, avpkt->size);
 
-tex_rat[0] = ctx->tex_rat;
-
 /* check for multi texture header */
 if (ctx->texture_count == 2) {
 ret = ff_hap_parse_section_header(>gbc, _size, 
_type);
@@ -325,7 +268,6 @@ static int hap_decode(AVCodecContext *avctx, AVFrame *frame,
 return AVERROR_INVALIDDATA;
 

[FFmpeg-cvslog] avcodec/dds: use the common texture dsp decode function

2022-04-10 Thread Marton Balint
ffmpeg | branch: master | Marton Balint  | Sat Mar 19 20:53:17 
2022 +0100| [30fdcd2e12532c23e4662abf8523292c3f32e5e4] | committer: Marton 
Balint

avcodec/dds: use the common texture dsp decode function

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=30fdcd2e12532c23e4662abf8523292c3f32e5e4
---

 libavcodec/dds.c | 135 ---
 1 file changed, 48 insertions(+), 87 deletions(-)

diff --git a/libavcodec/dds.c b/libavcodec/dds.c
index d4f6800ec9..30788f1777 100644
--- a/libavcodec/dds.c
+++ b/libavcodec/dds.c
@@ -106,12 +106,7 @@ typedef struct DDSContext {
 int bpp;
 enum DDSPostProc postproc;
 
-const uint8_t *tex_data; // Compressed texture
-int tex_ratio;   // Compression ratio
-int slice_count; // Number of slices for threaded operations
-
-/* Pointer to the selected compress or decompress function. */
-int (*tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block);
+TextureDSPThreadContext dec;
 } DDSContext;
 
 static int parse_pixel_format(AVCodecContext *avctx)
@@ -170,35 +165,36 @@ static int parse_pixel_format(AVCodecContext *avctx)
 avctx->pix_fmt = AV_PIX_FMT_RGBA;
 
 if (ctx->compressed) {
+ctx->dec.raw_ratio = 16;
 switch (fourcc) {
 case MKTAG('D', 'X', 'T', '1'):
-ctx->tex_ratio = 8;
-ctx->tex_funct = ctx->texdsp.dxt1a_block;
+ctx->dec.tex_ratio = 8;
+ctx->dec.tex_funct = ctx->texdsp.dxt1a_block;
 break;
 case MKTAG('D', 'X', 'T', '2'):
-ctx->tex_ratio = 16;
-ctx->tex_funct = ctx->texdsp.dxt2_block;
+ctx->dec.tex_ratio = 16;
+ctx->dec.tex_funct = ctx->texdsp.dxt2_block;
 break;
 case MKTAG('D', 'X', 'T', '3'):
-ctx->tex_ratio = 16;
-ctx->tex_funct = ctx->texdsp.dxt3_block;
+ctx->dec.tex_ratio = 16;
+ctx->dec.tex_funct = ctx->texdsp.dxt3_block;
 break;
 case MKTAG('D', 'X', 'T', '4'):
-ctx->tex_ratio = 16;
-ctx->tex_funct = ctx->texdsp.dxt4_block;
+ctx->dec.tex_ratio = 16;
+ctx->dec.tex_funct = ctx->texdsp.dxt4_block;
 break;
 case MKTAG('D', 'X', 'T', '5'):
-ctx->tex_ratio = 16;
+ctx->dec.tex_ratio = 16;
 if (ycocg_scaled)
-ctx->tex_funct = ctx->texdsp.dxt5ys_block;
+ctx->dec.tex_funct = ctx->texdsp.dxt5ys_block;
 else if (ycocg_classic)
-ctx->tex_funct = ctx->texdsp.dxt5y_block;
+ctx->dec.tex_funct = ctx->texdsp.dxt5y_block;
 else
-ctx->tex_funct = ctx->texdsp.dxt5_block;
+ctx->dec.tex_funct = ctx->texdsp.dxt5_block;
 break;
 case MKTAG('R', 'X', 'G', 'B'):
-ctx->tex_ratio = 16;
-ctx->tex_funct = ctx->texdsp.dxt5_block;
+ctx->dec.tex_ratio = 16;
+ctx->dec.tex_funct = ctx->texdsp.dxt5_block;
 /* This format may be considered as a normal map,
  * but it is handled differently in a separate postproc. */
 ctx->postproc = DDS_SWIZZLE_RXGB;
@@ -206,25 +202,25 @@ static int parse_pixel_format(AVCodecContext *avctx)
 break;
 case MKTAG('A', 'T', 'I', '1'):
 case MKTAG('B', 'C', '4', 'U'):
-ctx->tex_ratio = 8;
-ctx->tex_funct = ctx->texdsp.rgtc1u_block;
+ctx->dec.tex_ratio = 8;
+ctx->dec.tex_funct = ctx->texdsp.rgtc1u_block;
 break;
 case MKTAG('B', 'C', '4', 'S'):
-ctx->tex_ratio = 8;
-ctx->tex_funct = ctx->texdsp.rgtc1s_block;
+ctx->dec.tex_ratio = 8;
+ctx->dec.tex_funct = ctx->texdsp.rgtc1s_block;
 break;
 case MKTAG('A', 'T', 'I', '2'):
 /* RGT2 variant with swapped R and G (3Dc)*/
-ctx->tex_ratio = 16;
-ctx->tex_funct = ctx->texdsp.dxn3dc_block;
+ctx->dec.tex_ratio = 16;
+ctx->dec.tex_funct = ctx->texdsp.dxn3dc_block;
 break;
 case MKTAG('B', 'C', '5', 'U'):
-ctx->tex_ratio = 16;
-ctx->tex_funct = ctx->texdsp.rgtc2u_block;
+ctx->dec.tex_ratio = 16;
+ctx->dec.tex_funct = ctx->texdsp.rgtc2u_block;
 break;
 case MKTAG('B', 'C', '5', 'S'):
-ctx->tex_ratio = 16;
-ctx->tex_funct = ctx->texdsp.rgtc2s_block;
+ctx->dec.tex_ratio = 16;
+ctx->dec.tex_funct = ctx->texdsp.rgtc2s_block;
 break;
 case MKTAG('U', 'Y', 'V', 'Y'):
 ctx->compressed = 0;
@@ -299,40 +295,40 @@ static int parse_pixel_format(AVCodecContext *avctx)
 avctx->colorspace = AVCOL_SPC_RGB;
 case DXGI_FORMAT_BC1_TYPELESS:
 

[FFmpeg-cvslog] fate/filter-refcmp-*: make refcmp_metadata fail on empty or truncated input

2022-04-10 Thread Marton Balint
ffmpeg | branch: master | Marton Balint  | Wed Mar 30 00:55:14 
2022 +0200| [80e997b0818a36b1b28e39d745c466d01038aa1f] | committer: Marton 
Balint

fate/filter-refcmp-*: make refcmp_metadata fail on empty or truncated input

On empty input the awk script was always successful which caused the
filter-refcmp tests to always succeed.

Also fix the command lines for refcmp_metadata compare function because it
needs auto conversion filters, and update reference of test
filter-refcmp-psnr-rgb because it was missed in
a7fc78c1a638a32c3695c06f727774c740d675c2 but was never noticed due to the
original issue...

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=80e997b0818a36b1b28e39d745c466d01038aa1f
---

 tests/fate-run.sh |  2 +-
 tests/ref/fate/filter-refcmp-psnr-rgb | 80 +--
 tests/refcmp-metadata.awk |  5 ++-
 3 files changed, 45 insertions(+), 42 deletions(-)

diff --git a/tests/fate-run.sh b/tests/fate-run.sh
index a3be44d0eb..a5730c1f62 100755
--- a/tests/fate-run.sh
+++ b/tests/fate-run.sh
@@ -377,7 +377,7 @@ refcmp_metadata(){
 refcmp=$1
 pixfmt=$2
 fuzz=${3:-0.001}
-ffmpeg $FLAGS $ENC_OPTS \
+ffmpeg -auto_conversion_filters $FLAGS $ENC_OPTS \
 -lavfi 
"testsrc2=size=300x200:rate=1:duration=5,format=${pixfmt},split[ref][tmp];[tmp]avgblur=4[enc];[enc][ref]${refcmp},metadata=print:file=-"
 \
 -f null /dev/null | awk -v ref=${ref} -v fuzz=${fuzz} -f 
${base}/refcmp-metadata.awk -
 }
diff --git a/tests/ref/fate/filter-refcmp-psnr-rgb 
b/tests/ref/fate/filter-refcmp-psnr-rgb
index f06db575ac..20abd3dc5a 100644
--- a/tests/ref/fate/filter-refcmp-psnr-rgb
+++ b/tests/ref/fate/filter-refcmp-psnr-rgb
@@ -1,45 +1,45 @@
 frame:0pts:0   pts_time:0
-lavfi.psnr.mse.r=1381.80
-lavfi.psnr.psnr.r=16.73
-lavfi.psnr.mse.g=896.00
-lavfi.psnr.psnr.g=18.61
-lavfi.psnr.mse.b=277.38
-lavfi.psnr.psnr.b=23.70
-lavfi.psnr.mse_avg=851.73
-lavfi.psnr.psnr_avg=18.83
+lavfi.psnr.mse.r=1367.642090
+lavfi.psnr.psnr.r=16.771078
+lavfi.psnr.mse.g=885.804382
+lavfi.psnr.psnr.g=18.657425
+lavfi.psnr.mse.b=274.825073
+lavfi.psnr.psnr.b=23.740240
+lavfi.psnr.mse_avg=842.757202
+lavfi.psnr.psnr_avg=18.873779
 frame:1pts:1   pts_time:1
-lavfi.psnr.mse.r=1380.37
-lavfi.psnr.psnr.r=16.73
-lavfi.psnr.mse.g=975.91
-lavfi.psnr.psnr.g=18.24
-lavfi.psnr.mse.b=435.72
-lavfi.psnr.psnr.b=21.74
-lavfi.psnr.mse_avg=930.67
-lavfi.psnr.psnr_avg=18.44
+lavfi.psnr.mse.r=1356.681152
+lavfi.psnr.psnr.r=16.806026
+lavfi.psnr.mse.g=958.161560
+lavfi.psnr.psnr.g=18.316416
+lavfi.psnr.mse.b=428.238312
+lavfi.psnr.psnr.b=21.813948
+lavfi.psnr.mse_avg=914.360352
+lavfi.psnr.psnr_avg=18.519630
 frame:2pts:2   pts_time:2
-lavfi.psnr.mse.r=1403.20
-lavfi.psnr.psnr.r=16.66
-lavfi.psnr.mse.g=954.05
-lavfi.psnr.psnr.g=18.34
-lavfi.psnr.mse.b=494.22
-lavfi.psnr.psnr.b=21.19
-lavfi.psnr.mse_avg=950.49
-lavfi.psnr.psnr_avg=18.35
+lavfi.psnr.mse.r=1387.254883
+lavfi.psnr.psnr.r=16.709242
+lavfi.psnr.mse.g=939.230957
+lavfi.psnr.psnr.g=18.403080
+lavfi.psnr.mse.b=493.913757
+lavfi.psnr.psnr.b=21.194292
+lavfi.psnr.mse_avg=940.133179
+lavfi.psnr.psnr_avg=18.398911
 frame:3pts:3   pts_time:3
-lavfi.psnr.mse.r=1452.80
-lavfi.psnr.psnr.r=16.51
-lavfi.psnr.mse.g=1001.02
-lavfi.psnr.psnr.g=18.13
-lavfi.psnr.mse.b=557.39
-lavfi.psnr.psnr.b=20.67
-lavfi.psnr.mse_avg=1003.74
-lavfi.psnr.psnr_avg=18.11
+lavfi.psnr.mse.r=1433.291260
+lavfi.psnr.psnr.r=16.567459
+lavfi.psnr.mse.g=990.005859
+lavfi.psnr.psnr.g=18.174425
+lavfi.psnr.mse.b=550.512329
+lavfi.psnr.psnr.b=20.723133
+lavfi.psnr.mse_avg=991.269836
+lavfi.psnr.psnr_avg=18.168884
 frame:4pts:4   pts_time:4
-lavfi.psnr.mse.r=1401.25
-lavfi.psnr.psnr.r=16.67
-lavfi.psnr.mse.g=1009.80
-lavfi.psnr.psnr.g=18.09
-lavfi.psnr.mse.b=602.42
-lavfi.psnr.psnr.b=20.33
-lavfi.psnr.mse_avg=1004.49
-lavfi.psnr.psnr_avg=18.11
+lavfi.psnr.mse.r=1385.949341
+lavfi.psnr.psnr.r=16.713329
+lavfi.psnr.mse.g=997.065796
+lavfi.psnr.psnr.g=18.143566
+lavfi.psnr.mse.b=601.962952
+lavfi.psnr.psnr.b=20.335106
+lavfi.psnr.mse_avg=994.992676
+lavfi.psnr.psnr_avg=18.152605
diff --git a/tests/refcmp-metadata.awk b/tests/refcmp-metadata.awk
index fa21aad0e0..850aaac5a3 100644
--- a/tests/refcmp-metadata.awk
+++ b/tests/refcmp-metadata.awk
@@ -50,13 +50,16 @@ BEGIN {
 }
 
 END {
+result = result && (NR == ref_nr);
 if (result) {
 for (i = 1; i <= ref_nr; i++)
 print ref_lines[i];
 } else {
 for (i = 1; i <= NR; i++)
 print cmp_lines[i];
-if (NR != ref_nr)
+if (NR == 0)
+print "[refcmp] no input" > "/dev/stderr";
+else if (NR != ref_nr)
 print "[refcmp] lines: " NR " != " ref_nr > "/dev/stderr";
 if (delta_max >= fuzz)
 print "[refcmp] delta_max: " delta_max " >= " fuzz > "/dev/stderr";

___
ffmpeg-cvslog mailing list

[FFmpeg-cvslog] avcodec/texturedsp: add TextureDSPThreadContext for common decode/encode function

2022-04-10 Thread Marton Balint
ffmpeg | branch: master | Marton Balint  | Sat Mar 19 20:51:24 
2022 +0100| [541d3755e92da34b69df8c3c08d0d66cc4b05afd] | committer: Marton 
Balint

avcodec/texturedsp: add TextureDSPThreadContext for common decode/encode 
function

This will allow using a common threaded decode or encode function from most
codecs using texture DSP functions.

Signed-off-by: Marton Balint 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=541d3755e92da34b69df8c3c08d0d66cc4b05afd
---

 libavcodec/texturedsp.c  |  4 +++
 libavcodec/texturedsp.h  | 23 
 libavcodec/texturedsp_template.c | 57 
 libavcodec/texturedspenc.c   |  4 +++
 4 files changed, 88 insertions(+)

diff --git a/libavcodec/texturedsp.c b/libavcodec/texturedsp.c
index b7dd8baa12..b8938213ef 100644
--- a/libavcodec/texturedsp.c
+++ b/libavcodec/texturedsp.c
@@ -652,3 +652,7 @@ av_cold void ff_texturedsp_init(TextureDSPContext *c)
 c->rgtc2u_block   = rgtc2u_block;
 c->dxn3dc_block   = dxn3dc_block;
 }
+
+#define TEXTUREDSP_FUNC_NAME ff_texturedsp_decompress_thread
+#define TEXTUREDSP_TEX_FUNC(a, b, c) tex_funct(a, b, c)
+#include "texturedsp_template.c"
diff --git a/libavcodec/texturedsp.h b/libavcodec/texturedsp.h
index 90ceb2b6aa..e15d3c2b02 100644
--- a/libavcodec/texturedsp.h
+++ b/libavcodec/texturedsp.h
@@ -39,6 +39,8 @@
 #include 
 #include 
 
+#include "avcodec.h"
+
 #define TEXTURE_BLOCK_W 4
 #define TEXTURE_BLOCK_H 4
 
@@ -60,7 +62,28 @@ typedef struct TextureDSPContext {
 int (*dxn3dc_block)  (uint8_t *dst, ptrdiff_t stride, const uint8_t 
*block);
 } TextureDSPContext;
 
+typedef struct TextureDSPThreadContext {
+union {
+const uint8_t *in;   // Input frame data
+uint8_t *out;// Output frame data
+} frame_data;
+ptrdiff_t stride;// Frame linesize
+union {
+const uint8_t *in;   // Compressed texture for decompression
+uint8_t *out;// Compressed texture of compression
+} tex_data;
+int tex_ratio;   // Number of compressed bytes in a texture 
block
+int raw_ratio;   // Number bytes in a line of a raw block
+int slice_count; // Number of slices for threaded operations
+
+/* Pointer to the selected compress or decompress function. */
+int (*tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block);
+} TextureDSPThreadContext;
+
 void ff_texturedsp_init(TextureDSPContext *c);
 void ff_texturedspenc_init(TextureDSPContext *c);
 
+int ff_texturedsp_decompress_thread(AVCodecContext *avctx, void *arg, int 
slice, int thread_nb);
+int ff_texturedsp_compress_thread(AVCodecContext *avctx, void *arg, int slice, 
int thread_nb);
+
 #endif /* AVCODEC_TEXTUREDSP_H */
diff --git a/libavcodec/texturedsp_template.c b/libavcodec/texturedsp_template.c
new file mode 100644
index 00..bd193aa97c
--- /dev/null
+++ b/libavcodec/texturedsp_template.c
@@ -0,0 +1,57 @@
+/*
+ * Texture block compression and decompression
+ * Copyright (C) 2015 Vittorio Giovara 
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+int TEXTUREDSP_FUNC_NAME(AVCodecContext *avctx, void *arg,
+ int slice, int thread_nb)
+{
+TextureDSPThreadContext *ctx = arg;
+uint8_t *d = ctx->tex_data.out;
+int w_block = avctx->coded_width / TEXTURE_BLOCK_W;
+int h_block = avctx->coded_height / TEXTURE_BLOCK_H;
+int x, y;
+int start_slice, end_slice;
+int base_blocks_per_slice = h_block / ctx->slice_count;
+int remainder_blocks = h_block % ctx->slice_count;
+
+/* When the frame height (in blocks) doesn't divide evenly between the
+ * number of slices, spread the remaining blocks evenly between the first
+ * operations */
+start_slice = slice * base_blocks_per_slice;
+/* Add any extra blocks (one per slice) that have been added before this 
slice */
+start_slice += FFMIN(slice, remainder_blocks);
+
+end_slice = start_slice + base_blocks_per_slice;
+/* Add an extra block if there are still remainder blocks to be accounted 
for */
+if (slice < remainder_blocks)
+end_slice++;
+
+for (y = start_slice; y < end_slice; y++) {
+