Expose deblocking filter offset parameters.
Whitespace fixes.

diff --git a/doc/params.txt b/doc/params.txt
index 45bdc1d..869e500 100644
--- a/doc/params.txt
+++ b/doc/params.txt
@@ -126,6 +126,12 @@ Enable wavefront parallel processing to allow multi-threaded decoding.
 Enable the deblocking filter.
 
 
+* deblock-off=X,Y. Default to 0,0.
+
+Set the deblocking filter Beta and tC offsets respectively. The valid range of
+each offset is [-6, 6] (raw value specified in the PPS).
+
+
 * sao=X. Default to 0.
 
 Enable the sample adaptive offset filter.
diff --git a/f265/bdi.c b/f265/bdi.c
index fc9ca0a..e20cc09 100644
--- a/f265/bdi.c
+++ b/f265/bdi.c
@@ -249,7 +249,11 @@ void f265_normalize_params(f265_enc_params *p)
     CL(p->nb_b_frames, 0, 16);
     CL(p->nb_b_refs, 0, F265_MAX(F265_MIN(p->nb_refs, p->nb_b_frames) - 2, 0));
     CL(p->chroma_qp_idx_off, -12, 12);
-    for (int i = 0; i < 2; i++) CL(p->deblock_off[i], -6, 6);
+    for (int i = 0; i < 2; i++)
+    {
+        p->deblock_off[i] &= ~1;
+        CL(p->deblock_off[i], -12, 12);
+    }
     CL(p->merge_cand, 1, 5);
     CL(p->parallel_merge_level, 2, 6);
     for (int i = 0; i < 4; i++) CL(p->me_algo[i], 0, 3);
diff --git a/f265/bdi.h b/f265/bdi.h
index c8fab2c..9c170ac 100644
--- a/f265/bdi.h
+++ b/f265/bdi.h
@@ -431,20 +431,20 @@ do\
 #define F265_PART_V3                    7
 
 // Stash control flags (YUV components, transform nodes, cabac contexts).
-#define F265_STASH_Y			(1<<0)
-#define F265_STASH_U            	(1<<1)
-#define F265_STASH_V            	(1<<2)
-#define F265_STASH_TN           	(1<<3)
-#define F265_STASH_CABAC        	(1<<4)
-#define F265_STASH_YUV			(F265_STASH_Y|F265_STASH_U|F265_STASH_V)
-#define F265_STASH_ALL			(F265_STASH_CABAC|F265_STASH_TN|F265_STASH_YUV)
+#define F265_STASH_Y                    (1<<0)
+#define F265_STASH_U                    (1<<1)
+#define F265_STASH_V                    (1<<2)
+#define F265_STASH_TN                   (1<<3)
+#define F265_STASH_CABAC                (1<<4)
+#define F265_STASH_YUV                  (F265_STASH_Y|F265_STASH_U|F265_STASH_V)
+#define F265_STASH_ALL                  (F265_STASH_CABAC|F265_STASH_TN|F265_STASH_YUV)
 
 // Index of the coding block that represents an unavailable out-of-CTB
 // neighbour.
 #define F265_UNAVAIL_CB_IDX             103
 
 // Number of CB modes.
-#define F265_NB_CB_MODES		(1+3+8+5)
+#define F265_NB_CB_MODES                (1+3+8+5)
 
 // Hadamard matrix dimension.
 #define F265_H_DIM                      8
diff --git a/f265/bs.c b/f265/bs.c
index 57c47af..17da79b 100644
--- a/f265/bs.c
+++ b/f265/bs.c
@@ -266,6 +266,7 @@ void fenc_write_pps(f265_vlc_bs *vbs, f265_enc *enc)
 {
     f265_gen_data *gd = &enc->gd;
     int deblock_flag = F265_GET_FLAG(gd->eflags, F265_PF_DEBLOCK);
+    int deblocking_filter_control_present_flag = !deblock_flag || gd->deblock_off[0] || gd->deblock_off[1];
     int tiles_enabled = F265_GET_FLAG(gd->eflags, F265_PF_TILES);
 
     FENC_ANNOUNCE_VLC("PPS");
@@ -306,11 +307,16 @@ void fenc_write_pps(f265_vlc_bs *vbs, f265_enc *enc)
     }
     FENC_PUT_FLAG(vbs, 1, "loop_filter_across_slices_enabled_flag");
 
-    FENC_PUT_FLAG(vbs, !deblock_flag, "deblocking_filter_control_present_flag");
-    if (!deblock_flag)
+    FENC_PUT_FLAG(vbs, deblocking_filter_control_present_flag, "deblocking_filter_control_present_flag");
+    if (deblocking_filter_control_present_flag)
     {
         FENC_PUT_FLAG(vbs, 0, "deblocking_filter_override_enabled_flag");
-        FENC_PUT_FLAG(vbs, 1, "pps_disable_deblocking_filter_flag");
+        FENC_PUT_FLAG(vbs, !deblock_flag, "pps_disable_deblocking_filter_flag");
+        if (deblock_flag)
+        {
+            FENC_PUT_SE_V(vbs, gd->deblock_off[0]>>1, "pps_beta_offset_div2");
+            FENC_PUT_SE_V(vbs, gd->deblock_off[1]>>1, "pps_tc_offset_div2");
+        }
     }
 
     FENC_PUT_FLAG(vbs, 0, "pps_scaling_list_data_present_flag");
diff --git a/f265/enc.h b/f265/enc.h
index 8a9875a..9ea5c07 100644
--- a/f265/enc.h
+++ b/f265/enc.h
@@ -690,7 +690,7 @@ typedef struct f265_intra_block
 
     // Unfiltered/filtered neighbours of the current partition.
     // Layout:
-    // - [0-63]    : Bottom left and left neighbours, packed near index 63 
+    // - [0-63]    : Bottom left and left neighbours, packed near index 63
     //               (index 63 is always the topmost left neighbour).
     // - [64-127]  : Top and top left neighbours, packed near index 64.
     //               (index 64 is always the leftmost top neighbour).
@@ -2160,7 +2160,7 @@ typedef struct f265_gen_data
     // Chroma QP index offset.
     int8_t chroma_qp_idx_off;
 
-    // Deblocking filter Beta/tC offsets.
+    // Deblocking filter Beta/tC effective offsets. Range [-12, 12].
     int8_t deblock_off[2];
 
     // Number of merge candidates.
diff --git a/f265/f265.h b/f265/f265.h
index 18bfc05..476be04 100644
--- a/f265/f265.h
+++ b/f265/f265.h
@@ -148,7 +148,7 @@ typedef struct f265_enc_params
     // Chroma QP index offset.
     int8_t chroma_qp_idx_off;
 
-    // Deblocking filter alpha/beta offsets.
+    // Deblocking filter Beta/tC effective offsets. Range [-12, 12].
     int8_t deblock_off[2];
 
     // Number of merge candidates.
diff --git a/f265/parse.c b/f265/parse.c
index 1e4c368..3ddbac1 100644
--- a/f265/parse.c
+++ b/f265/parse.c
@@ -186,6 +186,12 @@ static void handle_param_deblock(f265_parse_ctx *ctx, f265_enc_params *p, f265_p
     p->deblock_flag = a->i;
 }
 
+static void handle_param_deblock_off(f265_parse_ctx *ctx, f265_enc_params *p, f265_parse_arg *a, int32_t nb_args)
+{
+    p->deblock_off[0] = a[0].i<<1;
+    p->deblock_off[1] = a[1].i<<1;
+}
+
 static void handle_param_sao(f265_parse_ctx *ctx, f265_enc_params *p, f265_parse_arg *a, int32_t nb_args)
 {
     p->sao_flag = a->i;
@@ -528,6 +534,7 @@ static const f265_parse_entry f265_enc_params_table[] =
     { "bref", handle_param_bref, 1, 0 },
     { "wpp", handle_param_wpp, 1, 0 },
     { "deblock", handle_param_deblock, 1, 0 },
+    { "deblock-off", handle_param_deblock_off, 2, 0 },
     { "sao", handle_param_sao, 1, 0 },
     { "scaling", handle_param_scaling, 1, 0 },
     { "transquant-bypass", handle_param_transquant_bypass, 1, 0 },

Reply via email to