@@ -245,7 +245,6 @@ struct rpivid_dec_state {
245
245
246
246
// Slice vars
247
247
unsigned int slice_idx ;
248
- bool frame_end ;
249
248
bool slice_temporal_mvp ; /* Slice flag but constant for frame */
250
249
251
250
// Temp vars per run - don't actually need to persist
@@ -740,7 +739,8 @@ static void new_slice_segment(struct rpivid_dec_env *const de,
740
739
V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED ))
741
740
<< 24 ));
742
741
743
- if ((sps -> flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED ) != 0 )
742
+ if (!s -> start_ts &&
743
+ (sps -> flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED ) != 0 )
744
744
write_scaling_factors (de );
745
745
746
746
if (!s -> dependent_slice_segment_flag ) {
@@ -1111,7 +1111,8 @@ static int wpp_end_previous_slice(struct rpivid_dec_env *const de,
1111
1111
* next chunk code simpler
1112
1112
*/
1113
1113
static int wpp_decode_slice (struct rpivid_dec_env * const de ,
1114
- const struct rpivid_dec_state * const s )
1114
+ const struct rpivid_dec_state * const s ,
1115
+ bool last_slice )
1115
1116
{
1116
1117
bool reset_qp_y = true;
1117
1118
const bool indep = !s -> dependent_slice_segment_flag ;
@@ -1150,7 +1151,7 @@ static int wpp_decode_slice(struct rpivid_dec_env *const de,
1150
1151
0 , 0 , s -> start_ctb_x , s -> start_ctb_y ,
1151
1152
s -> slice_qp , slice_reg_const (s ));
1152
1153
1153
- if (s -> frame_end ) {
1154
+ if (last_slice ) {
1154
1155
rv = wpp_entry_fill (de , s , s -> ctb_height - 1 );
1155
1156
if (rv )
1156
1157
return rv ;
@@ -1229,7 +1230,8 @@ static int end_previous_slice(struct rpivid_dec_env *const de,
1229
1230
}
1230
1231
1231
1232
static int decode_slice (struct rpivid_dec_env * const de ,
1232
- const struct rpivid_dec_state * const s )
1233
+ const struct rpivid_dec_state * const s ,
1234
+ bool last_slice )
1233
1235
{
1234
1236
bool reset_qp_y ;
1235
1237
unsigned int tile_x = ctb_to_tile_x (s , s -> start_ctb_x );
@@ -1275,7 +1277,7 @@ static int decode_slice(struct rpivid_dec_env *const de,
1275
1277
* now, otherwise this will be done at the start of the next slice
1276
1278
* when it will be known where this slice finishes
1277
1279
*/
1278
- if (s -> frame_end ) {
1280
+ if (last_slice ) {
1279
1281
rv = tile_entry_fill (de , s ,
1280
1282
s -> tile_width - 1 ,
1281
1283
s -> tile_height - 1 );
@@ -1670,11 +1672,13 @@ static u32 mk_config2(const struct rpivid_dec_state *const s)
1670
1672
static void rpivid_h265_setup (struct rpivid_ctx * ctx , struct rpivid_run * run )
1671
1673
{
1672
1674
struct rpivid_dev * const dev = ctx -> dev ;
1673
- const struct v4l2_ctrl_hevc_slice_params * const sh =
1674
- run -> h265 .slice_params ;
1675
1675
const struct v4l2_ctrl_hevc_decode_params * const dec =
1676
1676
run -> h265 .dec ;
1677
- // const struct v4l2_hevc_pred_weight_table *pred_weight_table;
1677
+ /* sh0 used where slice header contents should be constant over all
1678
+ * slices, or first slice of frame
1679
+ */
1680
+ const struct v4l2_ctrl_hevc_slice_params * const sh0 =
1681
+ run -> h265 .slice_params ;
1678
1682
struct rpivid_q_aux * dpb_q_aux [V4L2_HEVC_DPB_ENTRIES_NUM_MAX ];
1679
1683
struct rpivid_dec_state * const s = ctx -> state ;
1680
1684
struct vb2_queue * vq ;
@@ -1684,20 +1688,18 @@ static void rpivid_h265_setup(struct rpivid_ctx *ctx, struct rpivid_run *run)
1684
1688
int use_aux ;
1685
1689
int rv ;
1686
1690
bool slice_temporal_mvp ;
1691
+ bool frame_end ;
1687
1692
1688
1693
xtrace_in (dev , de );
1694
+ s -> sh = NULL ; // Avoid use until in the slice loop
1689
1695
1690
- // pred_weight_table = &sh->pred_weight_table;
1691
-
1692
- s -> frame_end =
1696
+ frame_end =
1693
1697
((run -> src -> flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF ) == 0 );
1694
1698
1695
- slice_temporal_mvp = (sh -> flags &
1699
+ slice_temporal_mvp = (sh0 -> flags &
1696
1700
V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED );
1697
1701
1698
1702
if (de && de -> state != RPIVID_DECODE_END ) {
1699
- ++ s -> slice_idx ;
1700
-
1701
1703
switch (de -> state ) {
1702
1704
case RPIVID_DECODE_SLICE_CONTINUE :
1703
1705
// Expected state
@@ -1830,7 +1832,7 @@ static void rpivid_h265_setup(struct rpivid_ctx *ctx, struct rpivid_run *run)
1830
1832
de -> rpi_config2 = mk_config2 (s );
1831
1833
de -> rpi_framesize = (s -> sps .pic_height_in_luma_samples << 16 ) |
1832
1834
s -> sps .pic_width_in_luma_samples ;
1833
- de -> rpi_currpoc = sh -> slice_pic_order_cnt ;
1835
+ de -> rpi_currpoc = sh0 -> slice_pic_order_cnt ;
1834
1836
1835
1837
if (s -> sps .flags &
1836
1838
V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED ) {
@@ -1839,17 +1841,17 @@ static void rpivid_h265_setup(struct rpivid_ctx *ctx, struct rpivid_run *run)
1839
1841
1840
1842
s -> slice_idx = 0 ;
1841
1843
1842
- if (sh -> slice_segment_addr != 0 ) {
1844
+ if (sh0 -> slice_segment_addr != 0 ) {
1843
1845
v4l2_warn (& dev -> v4l2_dev ,
1844
1846
"New frame but segment_addr=%d\n" ,
1845
- sh -> slice_segment_addr );
1847
+ sh0 -> slice_segment_addr );
1846
1848
goto fail ;
1847
1849
}
1848
1850
1849
1851
/* Allocate a bitbuf if we need one - don't need one if single
1850
1852
* slice as we can use the src buf directly
1851
1853
*/
1852
- if (!s -> frame_end && !de -> bit_copy_gptr -> ptr ) {
1854
+ if (!frame_end && !de -> bit_copy_gptr -> ptr ) {
1853
1855
size_t bits_alloc ;
1854
1856
bits_alloc = rpivid_bit_buf_size (s -> sps .pic_width_in_luma_samples ,
1855
1857
s -> sps .pic_height_in_luma_samples ,
@@ -1873,21 +1875,7 @@ static void rpivid_h265_setup(struct rpivid_ctx *ctx, struct rpivid_run *run)
1873
1875
s -> src_addr = 0 ;
1874
1876
s -> src_buf = NULL ;
1875
1877
1876
- if (run -> src -> planes [0 ].bytesused < (sh -> bit_size + 7 ) / 8 ) {
1877
- v4l2_warn (& dev -> v4l2_dev ,
1878
- "Bit size %d > bytesused %d\n" ,
1879
- sh -> bit_size , run -> src -> planes [0 ].bytesused );
1880
- goto fail ;
1881
- }
1882
- if (sh -> data_bit_offset >= sh -> bit_size ||
1883
- sh -> bit_size - sh -> data_bit_offset < 8 ) {
1884
- v4l2_warn (& dev -> v4l2_dev ,
1885
- "Bit size %d < Bit offset %d + 8\n" ,
1886
- sh -> bit_size , sh -> data_bit_offset );
1887
- goto fail ;
1888
- }
1889
-
1890
- if (s -> frame_end )
1878
+ if (frame_end )
1891
1879
s -> src_addr = vb2_dma_contig_plane_dma_addr (& run -> src -> vb2_buf ,
1892
1880
0 );
1893
1881
if (!s -> src_addr )
@@ -1898,44 +1886,65 @@ static void rpivid_h265_setup(struct rpivid_ctx *ctx, struct rpivid_run *run)
1898
1886
}
1899
1887
1900
1888
// Pre calc a few things
1901
- s -> sh = sh ;
1902
1889
s -> dec = dec ;
1903
- s -> slice_qp = 26 + s -> pps .init_qp_minus26 + s -> sh -> slice_qp_delta ;
1904
- s -> max_num_merge_cand = sh -> slice_type == HEVC_SLICE_I ?
1890
+ for (i = 0 ; i != run -> h265 .slice_ents ; ++ i ) {
1891
+ const struct v4l2_ctrl_hevc_slice_params * const sh = sh0 + i ;
1892
+ const bool last_slice = frame_end && i + 1 == run -> h265 .slice_ents ;
1893
+
1894
+ s -> sh = sh ;
1895
+
1896
+ if (run -> src -> planes [0 ].bytesused < (sh -> bit_size + 7 ) / 8 ) {
1897
+ v4l2_warn (& dev -> v4l2_dev ,
1898
+ "Bit size %d > bytesused %d\n" ,
1899
+ sh -> bit_size , run -> src -> planes [0 ].bytesused );
1900
+ goto fail ;
1901
+ }
1902
+ if (sh -> data_bit_offset >= sh -> bit_size ||
1903
+ sh -> bit_size - sh -> data_bit_offset < 8 ) {
1904
+ v4l2_warn (& dev -> v4l2_dev ,
1905
+ "Bit size %d < Bit offset %d + 8\n" ,
1906
+ sh -> bit_size , sh -> data_bit_offset );
1907
+ goto fail ;
1908
+ }
1909
+
1910
+ s -> slice_qp = 26 + s -> pps .init_qp_minus26 + sh -> slice_qp_delta ;
1911
+ s -> max_num_merge_cand = sh -> slice_type == HEVC_SLICE_I ?
1912
+ 0 :
1913
+ (5 - sh -> five_minus_max_num_merge_cand );
1914
+ s -> dependent_slice_segment_flag =
1915
+ ((sh -> flags &
1916
+ V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT ) != 0 );
1917
+
1918
+ s -> nb_refs [0 ] = (sh -> slice_type == HEVC_SLICE_I ) ?
1905
1919
0 :
1906
- (5 - sh -> five_minus_max_num_merge_cand );
1907
- // * SH DSS flag invented by me - but clearly needed
1908
- s -> dependent_slice_segment_flag =
1909
- ((sh -> flags &
1910
- V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT ) != 0 );
1911
-
1912
- s -> nb_refs [0 ] = (sh -> slice_type == HEVC_SLICE_I ) ?
1913
- 0 :
1914
- sh -> num_ref_idx_l0_active_minus1 + 1 ;
1915
- s -> nb_refs [1 ] = (sh -> slice_type != HEVC_SLICE_B ) ?
1916
- 0 :
1917
- sh -> num_ref_idx_l1_active_minus1 + 1 ;
1918
-
1919
- if (s -> sps .flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED )
1920
- populate_scaling_factors (run , de , s );
1921
-
1922
- // Calc all the random coord info to avoid repeated conversion in/out
1923
- s -> start_ts = s -> ctb_addr_rs_to_ts [sh -> slice_segment_addr ];
1924
- s -> start_ctb_x = sh -> slice_segment_addr % de -> pic_width_in_ctbs_y ;
1925
- s -> start_ctb_y = sh -> slice_segment_addr / de -> pic_width_in_ctbs_y ;
1926
- // Last CTB of previous slice
1927
- prev_rs = !s -> start_ts ? 0 : s -> ctb_addr_ts_to_rs [s -> start_ts - 1 ];
1928
- s -> prev_ctb_x = prev_rs % de -> pic_width_in_ctbs_y ;
1929
- s -> prev_ctb_y = prev_rs / de -> pic_width_in_ctbs_y ;
1930
-
1931
- if ((s -> pps .flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED ))
1932
- rv = wpp_decode_slice (de , s );
1933
- else
1934
- rv = decode_slice (de , s );
1935
- if (rv )
1936
- goto fail ;
1920
+ sh -> num_ref_idx_l0_active_minus1 + 1 ;
1921
+ s -> nb_refs [1 ] = (sh -> slice_type != HEVC_SLICE_B ) ?
1922
+ 0 :
1923
+ sh -> num_ref_idx_l1_active_minus1 + 1 ;
1924
+
1925
+ if (s -> sps .flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED )
1926
+ populate_scaling_factors (run , de , s );
1927
+
1928
+ /* Calc all the random coord info to avoid repeated conversion in/out */
1929
+ s -> start_ts = s -> ctb_addr_rs_to_ts [sh -> slice_segment_addr ];
1930
+ s -> start_ctb_x = sh -> slice_segment_addr % de -> pic_width_in_ctbs_y ;
1931
+ s -> start_ctb_y = sh -> slice_segment_addr / de -> pic_width_in_ctbs_y ;
1932
+ /* Last CTB of previous slice */
1933
+ prev_rs = !s -> start_ts ? 0 : s -> ctb_addr_ts_to_rs [s -> start_ts - 1 ];
1934
+ s -> prev_ctb_x = prev_rs % de -> pic_width_in_ctbs_y ;
1935
+ s -> prev_ctb_y = prev_rs / de -> pic_width_in_ctbs_y ;
1936
+
1937
+ if ((s -> pps .flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED ))
1938
+ rv = wpp_decode_slice (de , s , last_slice );
1939
+ else
1940
+ rv = decode_slice (de , s , last_slice );
1941
+ if (rv )
1942
+ goto fail ;
1943
+
1944
+ ++ s -> slice_idx ;
1945
+ }
1937
1946
1938
- if (!s -> frame_end ) {
1947
+ if (!frame_end ) {
1939
1948
xtrace_ok (dev , de );
1940
1949
return ;
1941
1950
}
@@ -2054,8 +2063,8 @@ static void rpivid_h265_setup(struct rpivid_ctx *ctx, struct rpivid_run *run)
2054
2063
fail :
2055
2064
if (de )
2056
2065
// Actual error reporting happens in Trigger
2057
- de -> state = s -> frame_end ? RPIVID_DECODE_ERROR_DONE :
2058
- RPIVID_DECODE_ERROR_CONTINUE ;
2066
+ de -> state = frame_end ? RPIVID_DECODE_ERROR_DONE :
2067
+ RPIVID_DECODE_ERROR_CONTINUE ;
2059
2068
xtrace_fail (dev , de );
2060
2069
}
2061
2070
0 commit comments