Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • dwlsalmeida/for-upstream
  • benjamin.gaignard/for-upstream
  • linux/for-upstream
3 results
Show changes
Commits on Source (33)
Showing
with 1377 additions and 926 deletions
......@@ -2048,3 +2048,900 @@ This structure contains all loop filter related parameters. See sections
- 0x2
- When set, the bitstream contains additional syntax elements that
specify which mode and reference frame deltas are to be updated.
.. _v4l2-codec-stateless-hevc:
``V4L2_CID_STATELESS_HEVC_SPS (struct)``
Specifies the Sequence Parameter Set fields (as extracted from the
bitstream) for the associated HEVC slice data.
These bitstream parameters are defined according to :ref:`hevc`.
They are described in section 7.4.3.2 "Sequence parameter set RBSP
semantics" of the specification.
.. c:type:: v4l2_ctrl_hevc_sps
.. raw:: latex
\small
.. tabularcolumns:: |p{1.2cm}|p{9.2cm}|p{6.9cm}|
.. cssclass:: longtable
.. flat-table:: struct v4l2_ctrl_hevc_sps
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2
* - __u8
- ``video_parameter_set_id``
- Specifies the value of the vps_video_parameter_set_id of the active VPS
as descibed in section "7.4.3.2.1 General sequence parameter set RBSP semantics"
of H.265 specifications.
* - __u8
- ``seq_parameter_set_id``
- Provides an identifier for the SPS for reference by other syntax elements
as descibed in section "7.4.3.2.1 General sequence parameter set RBSP semantics"
of H.265 specifications.
* - __u16
- ``pic_width_in_luma_samples``
- Specifies the width of each decoded picture in units of luma samples.
* - __u16
- ``pic_height_in_luma_samples``
- Specifies the height of each decoded picture in units of luma samples.
* - __u8
- ``bit_depth_luma_minus8``
- Specifies the bit depth of the samples of the luma array.
* - __u8
- ``bit_depth_chroma_minus8``
- Specifies the bit depth of the samples of the chroma arrays.
* - __u8
- ``log2_max_pic_order_cnt_lsb_minus4``
- Specifies the value of the variable MaxPicOrderCntLsb.
* - __u8
- ``sps_max_dec_pic_buffering_minus1``
- Plus 1 specifies the maximum required size of the decoded picture buffer for
the CVS
* - __u8
- ``sps_max_num_reorder_pics``
- Indicates the maximum allowed number of pictures.
* - __u8
- ``sps_max_latency_increase_plus1``
- Used to signal MaxLatencyPictures, which indicates the maximum number of
pictures that can precede any picture in output order and follow that
picture in decoding order.
* - __u8
- ``log2_min_luma_coding_block_size_minus3``
- Plus 3 specifies the minimum luma coding block size.
* - __u8
- ``log2_diff_max_min_luma_coding_block_size``
- Specifies the difference between the maximum and minimum luma coding block size.
* - __u8
- ``log2_min_luma_transform_block_size_minus2``
- Plus 2 specifies the minimum luma transform block size.
* - __u8
- ``log2_diff_max_min_luma_transform_block_size``
- Specifies the difference between the maximum and minimum luma transform block size.
* - __u8
- ``max_transform_hierarchy_depth_inter``
- Specifies the maximum hierarchy depth for transform units of coding units coded
in inter prediction mode.
* - __u8
- ``max_transform_hierarchy_depth_intra``
- Specifies the maximum hierarchy depth for transform units of coding units coded in
intra prediction mode.
* - __u8
- ``pcm_sample_bit_depth_luma_minus1``
- Specifies the number of bits used to represent each of PCM sample values of the
luma component.
* - __u8
- ``pcm_sample_bit_depth_chroma_minus1``
- Specifies the number of bits used to represent each of PCM sample values of
the chroma components.
* - __u8
- ``log2_min_pcm_luma_coding_block_size_minus3``
- Plus 3 specifies the minimum size of coding blocks.
* - __u8
- ``log2_diff_max_min_pcm_luma_coding_block_size``
- Specifies the difference between the maximum and minimum size of coding blocks.
* - __u8
- ``num_short_term_ref_pic_sets``
- Specifies the number of st_ref_pic_set() syntax structures included in the SPS.
* - __u8
- ``num_long_term_ref_pics_sps``
- Specifies the number of candidate long-term reference pictures that are
specified in the SPS.
* - __u8
- ``chroma_format_idc``
- Specifies the chroma sampling.
* - __u8
- ``sps_max_sub_layers_minus1``
- plus 1 specifies the maximum number of temporal sub-layers.
* - __u64
- ``flags``
- See :ref:`Sequence Parameter Set Flags <hevc_sps_flags>`
.. raw:: latex
\normalsize
.. _hevc_sps_flags:
``Sequence Parameter Set Flags``
.. raw:: latex
\small
.. cssclass:: longtable
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2
* - ``V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE``
- 0x00000001
-
* - ``V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED``
- 0x00000002
-
* - ``V4L2_HEVC_SPS_FLAG_AMP_ENABLED``
- 0x00000004
-
* - ``V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET``
- 0x00000008
-
* - ``V4L2_HEVC_SPS_FLAG_PCM_ENABLED``
- 0x00000010
-
* - ``V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED``
- 0x00000020
-
* - ``V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT``
- 0x00000040
-
* - ``V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED``
- 0x00000080
-
* - ``V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED``
- 0x00000100
-
.. raw:: latex
\normalsize
``V4L2_CID_STATELESS_HEVC_PPS (struct)``
Specifies the Picture Parameter Set fields (as extracted from the
bitstream) for the associated HEVC slice data.
These bitstream parameters are defined according to :ref:`hevc`.
They are described in section 7.4.3.3 "Picture parameter set RBSP
semantics" of the specification.
.. c:type:: v4l2_ctrl_hevc_pps
.. tabularcolumns:: |p{1.2cm}|p{8.6cm}|p{7.5cm}|
.. cssclass:: longtable
.. flat-table:: struct v4l2_ctrl_hevc_pps
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2
* - __u8
- ``pic_parameter_set_id``
- Identifies the PPS for reference by other syntax elements.
* - __u8
- ``num_extra_slice_header_bits``
- Specifies the number of extra slice header bits that are present
in the slice header RBSP for coded pictures referring to the PPS.
* - __u8
- ``num_ref_idx_l0_default_active_minus1``
- Specifies the inferred value of num_ref_idx_l0_active_minus1
* - __u8
- ``num_ref_idx_l1_default_active_minus1``
- Specifies the inferred value of num_ref_idx_l1_active_minus1
* - __s8
- ``init_qp_minus26``
- Plus 26 specifies the initial value of SliceQp Y for each slice
referring to the PPS.
* - __u8
- ``diff_cu_qp_delta_depth``
- Specifies the difference between the luma coding tree block size
and the minimum luma coding block size of coding units that
convey cu_qp_delta_abs and cu_qp_delta_sign_flag.
* - __s8
- ``pps_cb_qp_offset``
- Specify the offsets to the luma quantization parameter Cb.
* - __s8
- ``pps_cr_qp_offset``
- Specify the offsets to the luma quantization parameter Cr.
* - __u8
- ``num_tile_columns_minus1``
- Plus 1 specifies the number of tile columns partitioning the picture.
* - __u8
- ``num_tile_rows_minus1``
- Plus 1 specifies the number of tile rows partitioning the picture.
* - __u8
- ``column_width_minus1[20]``
- Plus 1 specifies the width of the i-th tile column in units of
coding tree blocks.
* - __u8
- ``row_height_minus1[22]``
- Plus 1 specifies the height of the i-th tile row in units of coding
tree blocks.
* - __s8
- ``pps_beta_offset_div2``
- Specify the default deblocking parameter offsets for beta divided by 2.
* - __s8
- ``pps_tc_offset_div2``
- Specify the default deblocking parameter offsets for tC divided by 2.
* - __u8
- ``log2_parallel_merge_level_minus2``
- Plus 2 specifies the value of the variable Log2ParMrgLevel.
* - __u8
- ``padding[4]``
- Applications and drivers must set this to zero.
* - __u64
- ``flags``
- See :ref:`Picture Parameter Set Flags <hevc_pps_flags>`
.. _hevc_pps_flags:
``Picture Parameter Set Flags``
.. raw:: latex
\small
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2
* - ``V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED``
- 0x00000001
-
* - ``V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT``
- 0x00000002
-
* - ``V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED``
- 0x00000004
-
* - ``V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT``
- 0x00000008
-
* - ``V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED``
- 0x00000010
-
* - ``V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED``
- 0x00000020
-
* - ``V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED``
- 0x00000040
-
* - ``V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT``
- 0x00000080
-
* - ``V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED``
- 0x00000100
-
* - ``V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED``
- 0x00000200
-
* - ``V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED``
- 0x00000400
-
* - ``V4L2_HEVC_PPS_FLAG_TILES_ENABLED``
- 0x00000800
-
* - ``V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED``
- 0x00001000
-
* - ``V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED``
- 0x00002000
-
* - ``V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED``
- 0x00004000
-
* - ``V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED``
- 0x00008000
-
* - ``V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER``
- 0x00010000
-
* - ``V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT``
- 0x00020000
-
* - ``V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT``
- 0x00040000
-
* - ``V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT``
- 0x00080000
- Specifies the presence of deblocking filter control syntax elements in
the PPS
* - ``V4L2_HEVC_PPS_FLAG_UNIFORM_SPACING``
- 0x00100000
- Specifies that tile column boundaries and likewise tile row boundaries
are distributed uniformly across the picture
.. raw:: latex
\normalsize
``V4L2_CID_STATELESS_HEVC_SLICE_PARAMS (struct)``
Specifies various slice-specific parameters, especially from the NAL unit
header, general slice segment header and weighted prediction parameter
parts of the bitstream.
These bitstream parameters are defined according to :ref:`hevc`.
They are described in section 7.4.7 "General slice segment header
semantics" of the specification.
This control is a dynamically sized 1-dimensional array,
V4L2_CTRL_FLAG_DYNAMIC_ARRAY flag must be set when using it.
.. c:type:: v4l2_ctrl_hevc_slice_params
.. raw:: latex
\scriptsize
.. tabularcolumns:: |p{5.4cm}|p{6.8cm}|p{5.1cm}|
.. cssclass:: longtable
.. flat-table:: struct v4l2_ctrl_hevc_slice_params
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2
* - __u32
- ``bit_size``
- Size (in bits) of the current slice data.
* - __u32
- ``data_byte_offset``
- Offset (in byte) to the video data in the current slice data.
* - __u32
- ``num_entry_point_offsets``
- Specifies the number of entry point offset syntax elements in the slice header.
* - __u8
- ``nal_unit_type``
- Specifies the coding type of the slice (B, P or I).
* - __u8
- ``nuh_temporal_id_plus1``
- Minus 1 specifies a temporal identifier for the NAL unit.
* - __u8
- ``slice_type``
-
(V4L2_HEVC_SLICE_TYPE_I, V4L2_HEVC_SLICE_TYPE_P or
V4L2_HEVC_SLICE_TYPE_B).
* - __u8
- ``colour_plane_id``
- Specifies the colour plane associated with the current slice.
* - __s32
- ``slice_pic_order_cnt``
- Specifies the picture order count.
* - __u8
- ``num_ref_idx_l0_active_minus1``
- Specifies the maximum reference index for reference picture list 0
that may be used to decode the slice.
* - __u8
- ``num_ref_idx_l1_active_minus1``
- Specifies the maximum reference index for reference picture list 1
that may be used to decode the slice.
* - __u8
- ``collocated_ref_idx``
- Specifies the reference index of the collocated picture used for
temporal motion vector prediction.
* - __u8
- ``five_minus_max_num_merge_cand``
- Specifies the maximum number of merging motion vector prediction
candidates supported in the slice subtracted from 5.
* - __s8
- ``slice_qp_delta``
- Specifies the initial value of QpY to be used for the coding blocks in the slice.
* - __s8
- ``slice_cb_qp_offset``
- Specifies a difference to be added to the value of pps_cb_qp_offset.
* - __s8
- ``slice_cr_qp_offset``
- Specifies a difference to be added to the value of pps_cr_qp_offset.
* - __s8
- ``slice_act_y_qp_offset``
- Specifies the offset to the luma of quantization parameter qP derived in section 8.6.2
* - __s8
- ``slice_act_cb_qp_offset``
- Specifies the offset to the cb of quantization parameter qP derived in section 8.6.2
* - __s8
- ``slice_act_cr_qp_offset``
- Specifies the offset to the cr of quantization parameter qP derived in section 8.6.2
* - __s8
- ``slice_beta_offset_div2``
- Specify the deblocking parameter offsets for beta divided by 2.
* - __s8
- ``slice_tc_offset_div2``
- Specify the deblocking parameter offsets for tC divided by 2.
* - __u8
- ``pic_struct``
- Indicates whether a picture should be displayed as a frame or as one or more fields.
* - __u32
- ``slice_segment_addr``
- Specifies the address of the first coding tree block in the slice segment.
* - __u8
- ``ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
- The list of L0 reference elements as indices in the DPB.
* - __u8
- ``ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
- The list of L1 reference elements as indices in the DPB.
* - __u16
- ``short_term_ref_pic_set_size``
- Specifies the size, in bits, of the short-term reference picture set, described as st_ref_pic_set()
in the specification, included in the slice header or SPS (section 7.3.6.1).
* - __u16
- ``long_term_ref_pic_set_size``
- Specifies the size, in bits, of the long-term reference picture set include in the slice header
or SPS. It is the number of bits in the conditional block if(long_term_ref_pics_present_flag)
in section 7.3.6.1 of the specification.
* - __u8
- ``padding``
- Applications and drivers must set this to zero.
* - struct :c:type:`v4l2_hevc_pred_weight_table`
- ``pred_weight_table``
- The prediction weight coefficients for inter-picture prediction.
* - __u64
- ``flags``
- See :ref:`Slice Parameters Flags <hevc_slice_params_flags>`
.. raw:: latex
\normalsize
.. _hevc_slice_params_flags:
``Slice Parameters Flags``
.. raw:: latex
\scriptsize
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2
* - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA``
- 0x00000001
-
* - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA``
- 0x00000002
-
* - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED``
- 0x00000004
-
* - ``V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO``
- 0x00000008
-
* - ``V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT``
- 0x00000010
-
* - ``V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0``
- 0x00000020
-
* - ``V4L2_HEVC_SLICE_PARAMS_FLAG_USE_INTEGER_MV``
- 0x00000040
-
* - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED``
- 0x00000080
-
* - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED``
- 0x00000100
-
* - ``V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT``
- 0x00000200
-
.. raw:: latex
\normalsize
``V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS (integer)``
Specifies entry point offsets in bytes.
This control is a dynamically sized array. The number of entry point
offsets is reported by the ``elems`` field.
This bitstream parameter is defined according to :ref:`hevc`.
They are described in section 7.4.7.1 "General slice segment header
semantics" of the specification.
``V4L2_CID_STATELESS_HEVC_SCALING_MATRIX (struct)``
Specifies the HEVC scaling matrix parameters used for the scaling process
for transform coefficients.
These matrix and parameters are defined according to :ref:`hevc`.
They are described in section 7.4.5 "Scaling list data semantics" of
the specification.
.. c:type:: v4l2_ctrl_hevc_scaling_matrix
.. raw:: latex
\scriptsize
.. tabularcolumns:: |p{5.4cm}|p{6.8cm}|p{5.1cm}|
.. cssclass:: longtable
.. flat-table:: struct v4l2_ctrl_hevc_scaling_matrix
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2
* - __u8
- ``scaling_list_4x4[6][16]``
- Scaling list is used for the scaling process for transform
coefficients. The values on each scaling list are expected
in raster scan order.
* - __u8
- ``scaling_list_8x8[6][64]``
- Scaling list is used for the scaling process for transform
coefficients. The values on each scaling list are expected
in raster scan order.
* - __u8
- ``scaling_list_16x16[6][64]``
- Scaling list is used for the scaling process for transform
coefficients. The values on each scaling list are expected
in raster scan order.
* - __u8
- ``scaling_list_32x32[2][64]``
- Scaling list is used for the scaling process for transform
coefficients. The values on each scaling list are expected
in raster scan order.
* - __u8
- ``scaling_list_dc_coef_16x16[6]``
- Scaling list is used for the scaling process for transform
coefficients. The values on each scaling list are expected
in raster scan order.
* - __u8
- ``scaling_list_dc_coef_32x32[2]``
- Scaling list is used for the scaling process for transform
coefficients. The values on each scaling list are expected
in raster scan order.
.. raw:: latex
\normalsize
.. c:type:: v4l2_hevc_dpb_entry
.. raw:: latex
\small
.. tabularcolumns:: |p{1.0cm}|p{4.2cm}|p{12.1cm}|
.. flat-table:: struct v4l2_hevc_dpb_entry
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2
* - __u64
- ``timestamp``
- Timestamp of the V4L2 capture buffer to use as reference, used
with B-coded and P-coded frames. The timestamp refers to the
``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
:c:func:`v4l2_timeval_to_ns()` function to convert the struct
:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
* - __u8
- ``flags``
- Long term flag for the reference frame
(V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE). The flag is set as
described in the ITU HEVC specification chapter "8.3.2 Decoding
process for reference picture set".
* - __u8
- ``field_pic``
- Whether the reference is a field picture or a frame.
See :ref:`HEVC dpb field pic Flags <hevc_dpb_field_pic_flags>`
* - __s32
- ``pic_order_cnt_val``
- The picture order count of the current picture.
* - __u8
- ``padding[2]``
- Applications and drivers must set this to zero.
.. raw:: latex
\normalsize
.. _hevc_dpb_field_pic_flags:
``HEVC dpb field pic Flags``
.. raw:: latex
\scriptsize
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2
* - ``V4L2_HEVC_SEI_PIC_STRUCT_FRAME``
- 0
- (progressive) Frame
* - ``V4L2_HEVC_SEI_PIC_STRUCT_TOP_FIELD``
- 1
- Top field
* - ``V4L2_HEVC_SEI_PIC_STRUCT_BOTTOM_FIELD``
- 2
- Bottom field
* - ``V4L2_HEVC_SEI_PIC_STRUCT_TOP_BOTTOM``
- 3
- Top field, bottom field, in that order
* - ``V4L2_HEVC_SEI_PIC_STRUCT_BOTTOM_TOP``
- 4
- Bottom field, top field, in that order
* - ``V4L2_HEVC_SEI_PIC_STRUCT_TOP_BOTTOM_TOP``
- 5
- Top field, bottom field, top field repeated, in that order
* - ``V4L2_HEVC_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM``
- 6
- Bottom field, top field, bottom field repeated, in that order
* - ``V4L2_HEVC_SEI_PIC_STRUCT_FRAME_DOUBLING``
- 7
- Frame doubling
* - ``V4L2_HEVC_SEI_PIC_STRUCT_FRAME_TRIPLING``
- 8
- Frame tripling
* - ``V4L2_HEVC_SEI_PIC_STRUCT_TOP_PAIRED_PREVIOUS_BOTTOM``
- 9
- Top field paired with previous bottom field in output order
* - ``V4L2_HEVC_SEI_PIC_STRUCT_BOTTOM_PAIRED_PREVIOUS_TOP``
- 10
- Bottom field paired with previous top field in output order
* - ``V4L2_HEVC_SEI_PIC_STRUCT_TOP_PAIRED_NEXT_BOTTOM``
- 11
- Top field paired with next bottom field in output order
* - ``V4L2_HEVC_SEI_PIC_STRUCT_BOTTOM_PAIRED_NEXT_TOP``
- 12
- Bottom field paired with next top field in output order
.. c:type:: v4l2_hevc_pred_weight_table
.. raw:: latex
\footnotesize
.. tabularcolumns:: |p{0.8cm}|p{10.6cm}|p{5.9cm}|
.. flat-table:: struct v4l2_hevc_pred_weight_table
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2
* - __s8
- ``delta_luma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
- The difference of the weighting factor applied to the luma
prediction value for list 0.
* - __s8
- ``luma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
- The additive offset applied to the luma prediction value for list 0.
* - __s8
- ``delta_chroma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
- The difference of the weighting factor applied to the chroma
prediction value for list 0.
* - __s8
- ``chroma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
- The difference of the additive offset applied to the chroma
prediction values for list 0.
* - __s8
- ``delta_luma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
- The difference of the weighting factor applied to the luma
prediction value for list 1.
* - __s8
- ``luma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
- The additive offset applied to the luma prediction value for list 1.
* - __s8
- ``delta_chroma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
- The difference of the weighting factor applied to the chroma
prediction value for list 1.
* - __s8
- ``chroma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
- The difference of the additive offset applied to the chroma
prediction values for list 1.
* - __u8
- ``luma_log2_weight_denom``
- The base 2 logarithm of the denominator for all luma weighting
factors.
* - __s8
- ``delta_chroma_log2_weight_denom``
- The difference of the base 2 logarithm of the denominator for
all chroma weighting factors.
* - __u8
- ``padding[6]``
- Applications and drivers must set this to zero.
.. raw:: latex
\normalsize
``V4L2_CID_STATELESS_HEVC_DECODE_MODE (enum)``
Specifies the decoding mode to use. Currently exposes slice-based and
frame-based decoding but new modes might be added later on.
This control is used as a modifier for V4L2_PIX_FMT_HEVC_SLICE
pixel format. Applications that support V4L2_PIX_FMT_HEVC_SLICE
are required to set this control in order to specify the decoding mode
that is expected for the buffer.
Drivers may expose a single or multiple decoding modes, depending
on what they can support.
.. c:type:: v4l2_stateless_hevc_decode_mode
.. raw:: latex
\small
.. tabularcolumns:: |p{9.4cm}|p{0.6cm}|p{7.3cm}|
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2
* - ``V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED``
- 0
- Decoding is done at the slice granularity.
The OUTPUT buffer must contain a single slice.
* - ``V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED``
- 1
- Decoding is done at the frame granularity.
The OUTPUT buffer must contain all slices needed to decode the
frame.
.. raw:: latex
\normalsize
``V4L2_CID_STATELESS_HEVC_START_CODE (enum)``
Specifies the HEVC slice start code expected for each slice.
This control is used as a modifier for V4L2_PIX_FMT_HEVC_SLICE
pixel format. Applications that support V4L2_PIX_FMT_HEVC_SLICE
are required to set this control in order to specify the start code
that is expected for the buffer.
Drivers may expose a single or multiple start codes, depending
on what they can support.
.. c:type:: v4l2_stateless_hevc_start_code
.. tabularcolumns:: |p{9.2cm}|p{0.6cm}|p{7.5cm}|
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2
* - ``V4L2_STATELESS_HEVC_START_CODE_NONE``
- 0
- Selecting this value specifies that HEVC slices are passed
to the driver without any start code. The bitstream data should be
according to :ref:`hevc` 7.3.1.1 General NAL unit syntax, hence
contains emulation prevention bytes when required.
* - ``V4L2_STATELESS_HEVC_START_CODE_ANNEX_B``
- 1
- Selecting this value specifies that HEVC slices are expected
to be prefixed by Annex B start codes. According to :ref:`hevc`
valid start codes can be 3-bytes 0x000001 or 4-bytes 0x00000001.
.. raw:: latex
\normalsize
``V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID (integer)``
Specifies a priority identifier for the NAL unit, which will be applied to
the base layer. By default this value is set to 0 for the base layer,
and the next layer will have the priority ID assigned as 1, 2, 3 and so on.
The video encoder can't decide the priority id to be applied to a layer,
so this has to come from client.
This is applicable to H264 and valid Range is from 0 to 63.
Source Rec. ITU-T H.264 (06/2019); G.7.4.1.1, G.8.8.1.
``V4L2_CID_MPEG_VIDEO_LTR_COUNT (integer)``
Specifies the maximum number of Long Term Reference (LTR) frames at any
given time that the encoder can keep.
This is applicable to the H264 and HEVC encoders.
``V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX (integer)``
After setting this control the frame that will be queued next
will be marked as a Long Term Reference (LTR) frame
and given this LTR index which ranges from 0 to LTR_COUNT-1.
This is applicable to the H264 and HEVC encoders.
Source Rec. ITU-T H.264 (06/2019); Table 7.9
``V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES (bitmask)``
Specifies the Long Term Reference (LTR) frame(s) to be used for
encoding the next frame queued after setting this control.
This provides a bitmask which consists of bits [0, LTR_COUNT-1].
This is applicable to the H264 and HEVC encoders.
``V4L2_CID_STATELESS_HEVC_DECODE_PARAMS (struct)``
Specifies various decode parameters, especially the references picture order
count (POC) for all the lists (short, long, before, current, after) and the
number of entries for each of them.
These parameters are defined according to :ref:`hevc`.
They are described in section 8.3 "Slice decoding process" of the
specification.
.. c:type:: v4l2_ctrl_hevc_decode_params
.. cssclass:: longtable
.. flat-table:: struct v4l2_ctrl_hevc_decode_params
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2
* - __s32
- ``pic_order_cnt_val``
- PicOrderCntVal as described in section 8.3.1 "Decoding process
for picture order count" of the specification.
* - __u16
- ``short_term_ref_pic_set_size``
- Specifies the size, in bits, of the short-term reference picture set, of the first slice
described as st_ref_pic_set() in the specification, included in the slice header
or SPS (section 7.3.6.1).
* - __u16
- ``long_term_ref_pic_set_size``
- Specifies the size, in bits, of the long-term reference picture set, of the first slice
included in the slice header or SPS. It is the number of bits in the conditional block
if(long_term_ref_pics_present_flag) in section 7.3.6.1 of the specification.
* - __u8
- ``num_active_dpb_entries``
- The number of entries in ``dpb``.
* - __u8
- ``num_poc_st_curr_before``
- The number of reference pictures in the short-term set that come before
the current frame.
* - __u8
- ``num_poc_st_curr_after``
- The number of reference pictures in the short-term set that come after
the current frame.
* - __u8
- ``num_poc_lt_curr``
- The number of reference pictures in the long-term set.
* - __u8
- ``poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
- PocStCurrBefore as described in section 8.3.2 "Decoding process for reference
picture set": provides the index of the short term before references in DPB array.
* - __u8
- ``poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
- PocStCurrAfter as described in section 8.3.2 "Decoding process for reference
picture set": provides the index of the short term after references in DPB array.
* - __u8
- ``poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
- PocLtCurr as described in section 8.3.2 "Decoding process for reference
picture set": provides the index of the long term references in DPB array.
* - struct :c:type:`v4l2_hevc_dpb_entry`
- ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
- The decoded picture buffer, for meta-data about reference frames.
* - __u64
- ``flags``
- See :ref:`Decode Parameters Flags <hevc_decode_params_flags>`
.. _hevc_decode_params_flags:
``Decode Parameters Flags``
.. cssclass:: longtable
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 1 2
* - ``V4L2_HEVC_DECODE_PARAM_FLAG_IRAP_PIC``
- 0x00000001
-
* - ``V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC``
- 0x00000002
-
* - ``V4L2_HEVC_DECODE_PARAM_FLAG_NO_OUTPUT_OF_PRIOR``
- 0x00000004
-
......@@ -212,14 +212,9 @@ Compressed Formats
``V4L2_CID_MPEG_VIDEO_HEVC_SPS``,
``V4L2_CID_MPEG_VIDEO_HEVC_PPS``, and
``V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS``.
See the :ref:`associated Codec Control IDs <v4l2-mpeg-hevc>`.
See the :ref:`associated Codec Control IDs <v4l2-codec-stateless-hevc>`.
Buffers associated with this pixel format must contain the appropriate
number of macroblocks to decode a full corresponding frame.
.. note::
This format is not yet part of the public kernel API and it
is expected to change.
* .. _V4L2-PIX-FMT-FWHT:
- ``V4L2_PIX_FMT_FWHT``
......
......@@ -109,6 +109,13 @@ All components are stored with the same number of bits per component.
- Cb, Cr
- No
- 16x16 tiles
* - V4L2_PIX_FMT_P010
- 'P010'
- 10
- 4:2:0
- Cb, Cr
- Yes
- Linear
* - V4L2_PIX_FMT_NV16
- 'NV16'
- 8
......@@ -171,6 +178,7 @@ horizontally.
.. _V4L2-PIX-FMT-NV21:
.. _V4L2-PIX-FMT-NV12M:
.. _V4L2-PIX-FMT-NV21M:
.. _V4L2-PIX-FMT-P010:
NV12, NV21, NV12M and NV21M
---------------------------
......@@ -519,6 +527,52 @@ number of lines as the luma plane.
- Cb\ :sub:`33`
- Cr\ :sub:`33`
.. _V4L2_PIX_FMT_P010:
P010
----
Like NV12 with 10 bits per component, expanded to 16 bits.
Data in the 10 high bits, zeros in the 6 low bits, arranged in little endian order.
.. flat-table:: Sample 4x4 P010 Image
:header-rows: 0
:stub-columns: 0
* - start + 0:
- Y'\ :sub:`00`
- Y'\ :sub:`01`
- Y'\ :sub:`02`
- Y'\ :sub:`03`
* - start + 8:
- Y'\ :sub:`10`
- Y'\ :sub:`11`
- Y'\ :sub:`12`
- Y'\ :sub:`13`
* - start + 16:
- Y'\ :sub:`20`
- Y'\ :sub:`21`
- Y'\ :sub:`22`
- Y'\ :sub:`23`
* - start + 24:
- Y'\ :sub:`30`
- Y'\ :sub:`31`
- Y'\ :sub:`32`
- Y'\ :sub:`33`
* - start + 32:
- Cb\ :sub:`00`
- Cr\ :sub:`00`
- Cb\ :sub:`01`
- Cr\ :sub:`01`
* - start + 40:
- Cb\ :sub:`10`
- Cr\ :sub:`10`
- Cb\ :sub:`11`
- Cr\ :sub:`11`
.. raw:: latex
\endgroup
Fully Planar YUV Formats
========================
......
......@@ -249,6 +249,26 @@ still cause this situation.
- ``p_hdr10_mastering``
- A pointer to a struct :c:type:`v4l2_ctrl_hdr10_mastering_display`. Valid if this control is
of type ``V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY``.
* - struct :c:type:`v4l2_ctrl_hevc_sps` *
- ``p_hevc_sps``
- A pointer to a struct :c:type:`v4l2_ctrl_hevc_sps`. Valid if this
control is of type ``V4L2_CTRL_TYPE_HEVC_SPS``.
* - struct :c:type:`v4l2_ctrl_hevc_pps` *
- ``p_hevc_pps``
- A pointer to a struct :c:type:`v4l2_ctrl_hevc_pps`. Valid if this
control is of type ``V4L2_CTRL_TYPE_HEVC_PPS``.
* - struct :c:type:`v4l2_ctrl_hevc_slice_params` *
- ``p_hevc_slice_params``
- A pointer to a struct :c:type:`v4l2_ctrl_hevc_slice_params`. Valid if this
control is of type ``V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS``.
* - struct :c:type:`v4l2_ctrl_hevc_scaling_matrix` *
- ``p_hevc_scaling_matrix``
- A pointer to a struct :c:type:`v4l2_ctrl_hevc_scaling_matrix`. Valid if this
control is of type ``V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX``.
* - struct :c:type:`v4l2_ctrl_hevc_decode_params` *
- ``p_hevc_decode_params``
- A pointer to a struct :c:type:`v4l2_ctrl_hevc_decode_params`. Valid if this
control is of type ``V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS``.
* - void *
- ``ptr``
- A pointer to a compound type which can be an N-dimensional array
......
......@@ -625,6 +625,14 @@ See also the examples in :ref:`control`.
``V4L2_CTRL_FLAG_GRABBED`` flag when buffers are allocated or
streaming is in progress since most drivers do not support changing
the format in that case.
* - ``V4L2_CTRL_FLAG_DYNAMIC_ARRAY``
- 0x0800
- This control is a dynamically sized 1-dimensional array. It
behaves the same as a regular array, except that the number
of elements as reported by the ``elems`` field is between 1 and
``dims[0]``. So setting the control with a differently sized
array will change the ``elems`` field when the control is
queried afterwards.
Return Value
============
......
......@@ -153,6 +153,11 @@ replace symbol V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR :c:type:`v4l2_ctrl_type`
replace symbol V4L2_CTRL_TYPE_VP9_FRAME :c:type:`v4l2_ctrl_type`
replace symbol V4L2_CTRL_TYPE_HDR10_CLL_INFO :c:type:`v4l2_ctrl_type`
replace symbol V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY :c:type:`v4l2_ctrl_type`
replace symbol V4L2_CTRL_TYPE_HEVC_SPS :c:type:`v4l2_ctrl_type`
replace symbol V4L2_CTRL_TYPE_HEVC_PPS :c:type:`v4l2_ctrl_type`
replace symbol V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
replace symbol V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX :c:type:`v4l2_ctrl_type`
replace symbol V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS :c:type:`v4l2_ctrl_type`
# V4L2 capability defines
replace define V4L2_CAP_VIDEO_CAPTURE device-capabilities
......
......@@ -749,7 +749,7 @@ pgc_vpu: power-domain@6 {
<&clk IMX8MQ_SYS1_PLL_800M>,
<&clk IMX8MQ_VPU_PLL>;
assigned-clock-rates = <600000000>,
<600000000>,
<300000000>,
<800000000>,
<0>;
};
......
......@@ -34,6 +34,7 @@
#define VIVID_CID_U8_4D_ARRAY (VIVID_CID_CUSTOM_BASE + 10)
#define VIVID_CID_AREA (VIVID_CID_CUSTOM_BASE + 11)
#define VIVID_CID_RO_INTEGER (VIVID_CID_CUSTOM_BASE + 12)
#define VIVID_CID_U32_DYN_ARRAY (VIVID_CID_CUSTOM_BASE + 13)
#define VIVID_CID_VIVID_BASE (0x00f00000 | 0xf000)
#define VIVID_CID_VIVID_CLASS (0x00f00000 | 1)
......@@ -189,6 +190,19 @@ static const struct v4l2_ctrl_config vivid_ctrl_u32_array = {
.dims = { 1 },
};
static const struct v4l2_ctrl_config vivid_ctrl_u32_dyn_array = {
.ops = &vivid_user_gen_ctrl_ops,
.id = VIVID_CID_U32_DYN_ARRAY,
.name = "U32 Dynamic Array",
.type = V4L2_CTRL_TYPE_U32,
.flags = V4L2_CTRL_FLAG_DYNAMIC_ARRAY,
.def = 50,
.min = 10,
.max = 90,
.step = 1,
.dims = { 100 },
};
static const struct v4l2_ctrl_config vivid_ctrl_u16_matrix = {
.ops = &vivid_user_gen_ctrl_ops,
.id = VIVID_CID_U16_MATRIX,
......@@ -1612,6 +1626,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
dev->ro_int32 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_ro_int32, NULL);
v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_area, NULL);
v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_array, NULL);
v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_dyn_array, NULL);
v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u16_matrix, NULL);
v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_4d_array, NULL);
......
......@@ -266,6 +266,7 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
{ .format = V4L2_PIX_FMT_NV61, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
{ .format = V4L2_PIX_FMT_NV24, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
{ .format = V4L2_PIX_FMT_NV42, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
{ .format = V4L2_PIX_FMT_P010, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
{ .format = V4L2_PIX_FMT_YUV410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
{ .format = V4L2_PIX_FMT_YVU410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
......@@ -277,6 +278,7 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
/* Tiled YUV formats */
{ .format = V4L2_PIX_FMT_NV12_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
{ .format = V4L2_PIX_FMT_P010_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .hdiv = 2, .vdiv = 2 },
/* YUV planar formats, non contiguous variant */
{ .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
......
......@@ -97,29 +97,47 @@ static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
return ptr_to_user(c, ctrl, ctrl->p_new);
}
/* Helper function: copy the caller-provider value to the given control value */
static int user_to_ptr(struct v4l2_ext_control *c,
struct v4l2_ctrl *ctrl,
union v4l2_ctrl_ptr ptr)
/* Helper function: copy the caller-provider value as the new control value */
static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
{
int ret;
u32 size;
ctrl->is_new = 1;
ctrl->is_new = 0;
if (ctrl->is_dyn_array &&
c->size > ctrl->p_dyn_alloc_elems * ctrl->elem_size) {
void *old = ctrl->p_dyn;
void *tmp = kvzalloc(2 * c->size, GFP_KERNEL);
if (!tmp)
return -ENOMEM;
memcpy(tmp, ctrl->p_new.p, ctrl->elems * ctrl->elem_size);
memcpy(tmp + c->size, ctrl->p_cur.p, ctrl->elems * ctrl->elem_size);
ctrl->p_new.p = tmp;
ctrl->p_cur.p = tmp + c->size;
ctrl->p_dyn = tmp;
ctrl->p_dyn_alloc_elems = c->size / ctrl->elem_size;
kvfree(old);
}
if (ctrl->is_ptr && !ctrl->is_string) {
unsigned int elems = c->size / ctrl->elem_size;
unsigned int idx;
ret = copy_from_user(ptr.p, c->ptr, c->size) ? -EFAULT : 0;
if (ret || !ctrl->is_array)
return ret;
for (idx = c->size / ctrl->elem_size; idx < ctrl->elems; idx++)
ctrl->type_ops->init(ctrl, idx, ptr);
if (copy_from_user(ctrl->p_new.p, c->ptr, c->size))
return -EFAULT;
ctrl->is_new = 1;
if (ctrl->is_dyn_array)
ctrl->new_elems = elems;
else if (ctrl->is_array)
for (idx = elems; idx < ctrl->elems; idx++)
ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
return 0;
}
switch (ctrl->type) {
case V4L2_CTRL_TYPE_INTEGER64:
*ptr.p_s64 = c->value64;
*ctrl->p_new.p_s64 = c->value64;
break;
case V4L2_CTRL_TYPE_STRING:
size = c->size;
......@@ -127,32 +145,27 @@ static int user_to_ptr(struct v4l2_ext_control *c,
return -ERANGE;
if (size > ctrl->maximum + 1)
size = ctrl->maximum + 1;
ret = copy_from_user(ptr.p_char, c->string, size) ? -EFAULT : 0;
ret = copy_from_user(ctrl->p_new.p_char, c->string, size) ? -EFAULT : 0;
if (!ret) {
char last = ptr.p_char[size - 1];
char last = ctrl->p_new.p_char[size - 1];
ptr.p_char[size - 1] = 0;
ctrl->p_new.p_char[size - 1] = 0;
/*
* If the string was longer than ctrl->maximum,
* then return an error.
*/
if (strlen(ptr.p_char) == ctrl->maximum && last)
if (strlen(ctrl->p_new.p_char) == ctrl->maximum && last)
return -ERANGE;
}
return ret;
default:
*ptr.p_s32 = c->value;
*ctrl->p_new.p_s32 = c->value;
break;
}
ctrl->is_new = 1;
return 0;
}
/* Helper function: copy the caller-provider value as the new control value */
static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
{
return user_to_ptr(c, ctrl, ctrl->p_new);
}
/*
* VIDIOC_G/TRY/S_EXT_CTRLS implementation
*/
......@@ -254,7 +267,31 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
have_clusters = true;
if (ctrl->cluster[0] != ctrl)
ref = find_ref_lock(hdl, ctrl->cluster[0]->id);
if (ctrl->is_ptr && !ctrl->is_string) {
if (ctrl->is_dyn_array) {
unsigned int max_size = ctrl->dims[0] * ctrl->elem_size;
unsigned int tot_size = ctrl->elem_size;
if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL)
tot_size *= ref->p_req_elems;
else
tot_size *= ctrl->elems;
c->size = ctrl->elem_size * (c->size / ctrl->elem_size);
if (get) {
if (c->size < tot_size) {
c->size = tot_size;
return -ENOSPC;
}
c->size = tot_size;
} else {
if (c->size > max_size) {
c->size = max_size;
return -ENOSPC;
}
if (!c->size)
return -EFAULT;
}
} else if (ctrl->is_ptr && !ctrl->is_string) {
unsigned int tot_size = ctrl->elems * ctrl->elem_size;
if (c->size < tot_size) {
......@@ -346,7 +383,7 @@ static int class_check(struct v4l2_ctrl_handler *hdl, u32 which)
*
* Note that v4l2_g_ext_ctrls_common() with 'which' set to
* V4L2_CTRL_WHICH_REQUEST_VAL is only called if the request was
* completed, and in that case valid_p_req is true for all controls.
* completed, and in that case p_req_valid is true for all controls.
*/
int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl,
struct v4l2_ext_controls *cs,
......@@ -430,7 +467,9 @@ int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl,
if (is_default)
ret = def_to_user(cs->controls + idx, ref->ctrl);
else if (is_request && ref->valid_p_req)
else if (is_request && ref->p_req_dyn_enomem)
ret = -ENOMEM;
else if (is_request && ref->p_req_valid)
ret = req_to_user(cs->controls + idx, ref);
else if (is_volatile)
ret = new_to_user(cs->controls + idx, ref->ctrl);
......@@ -457,6 +496,17 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct video_device *vdev,
}
EXPORT_SYMBOL(v4l2_g_ext_ctrls);
/* Validate a new control */
static int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new)
{
unsigned int idx;
int err = 0;
for (idx = 0; !err && idx < ctrl->new_elems; idx++)
err = ctrl->type_ops->validate(ctrl, idx, p_new);
return err;
}
/* Validate controls. */
static int validate_ctrls(struct v4l2_ext_controls *cs,
struct v4l2_ctrl_helper *helpers,
......@@ -872,6 +922,9 @@ int __v4l2_ctrl_s_ctrl_compound(struct v4l2_ctrl *ctrl,
/* It's a driver bug if this happens. */
if (WARN_ON(ctrl->type != type))
return -EINVAL;
/* Setting dynamic arrays is not (yet?) supported. */
if (WARN_ON(ctrl->is_dyn_array))
return -EINVAL;
memcpy(ctrl->p_new.p, p, ctrl->elems * ctrl->elem_size);
return set_ctrl(NULL, ctrl, 0);
}
......
......@@ -307,6 +307,21 @@ static void std_log(const struct v4l2_ctrl *ctrl)
case V4L2_CTRL_TYPE_VP9_FRAME:
pr_cont("VP9_FRAME");
break;
case V4L2_CTRL_TYPE_HEVC_SPS:
pr_cont("HEVC_SPS");
break;
case V4L2_CTRL_TYPE_HEVC_PPS:
pr_cont("HEVC_PPS");
break;
case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
pr_cont("HEVC_SLICE_PARAMS");
break;
case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX:
pr_cont("HEVC_SCALING_MATRIX");
break;
case V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS:
pr_cont("HEVC_DECODE_PARAMS");
break;
default:
pr_cont("unknown type %d", ctrl->type);
break;
......@@ -809,20 +824,11 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
if (p_hevc_decode_params->num_active_dpb_entries >
V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
return -EINVAL;
for (i = 0; i < p_hevc_decode_params->num_active_dpb_entries;
i++) {
struct v4l2_hevc_dpb_entry *dpb_entry =
&p_hevc_decode_params->dpb[i];
zero_padding(*dpb_entry);
}
break;
case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
p_hevc_slice_params = p;
zero_padding(p_hevc_slice_params->pred_weight_table);
zero_padding(*p_hevc_slice_params);
break;
......@@ -991,11 +997,12 @@ EXPORT_SYMBOL(v4l2_ctrl_notify);
/* Copy the one value to another. */
static void ptr_to_ptr(struct v4l2_ctrl *ctrl,
union v4l2_ctrl_ptr from, union v4l2_ctrl_ptr to)
union v4l2_ctrl_ptr from, union v4l2_ctrl_ptr to,
unsigned int elems)
{
if (ctrl == NULL)
return;
memcpy(to.p, from.p_const, ctrl->elems * ctrl->elem_size);
memcpy(to.p, from.p_const, elems * ctrl->elem_size);
}
/* Copy the new value to the current value. */
......@@ -1008,8 +1015,11 @@ void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags)
/* has_changed is set by cluster_changed */
changed = ctrl->has_changed;
if (changed)
ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur);
if (changed) {
if (ctrl->is_dyn_array)
ctrl->elems = ctrl->new_elems;
ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur, ctrl->elems);
}
if (ch_flags & V4L2_EVENT_CTRL_CH_FLAGS) {
/* Note: CH_FLAGS is only set for auto clusters. */
......@@ -1039,36 +1049,122 @@ void cur_to_new(struct v4l2_ctrl *ctrl)
{
if (ctrl == NULL)
return;
ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new);
if (ctrl->is_dyn_array)
ctrl->new_elems = ctrl->elems;
ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new, ctrl->new_elems);
}
static bool req_alloc_dyn_array(struct v4l2_ctrl_ref *ref, u32 elems)
{
void *tmp;
if (elems < ref->p_req_dyn_alloc_elems)
return true;
tmp = kvmalloc(elems * ref->ctrl->elem_size, GFP_KERNEL);
if (!tmp) {
ref->p_req_dyn_enomem = true;
return false;
}
ref->p_req_dyn_enomem = false;
kvfree(ref->p_req.p);
ref->p_req.p = tmp;
ref->p_req_dyn_alloc_elems = elems;
return true;
}
/* Copy the new value to the request value */
void new_to_req(struct v4l2_ctrl_ref *ref)
{
struct v4l2_ctrl *ctrl;
if (!ref)
return;
ptr_to_ptr(ref->ctrl, ref->ctrl->p_new, ref->p_req);
ref->valid_p_req = true;
ctrl = ref->ctrl;
if (ctrl->is_dyn_array && !req_alloc_dyn_array(ref, ctrl->new_elems))
return;
ref->p_req_elems = ctrl->new_elems;
ptr_to_ptr(ctrl, ctrl->p_new, ref->p_req, ref->p_req_elems);
ref->p_req_valid = true;
}
/* Copy the current value to the request value */
void cur_to_req(struct v4l2_ctrl_ref *ref)
{
struct v4l2_ctrl *ctrl;
if (!ref)
return;
ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->p_req);
ref->valid_p_req = true;
ctrl = ref->ctrl;
if (ctrl->is_dyn_array && !req_alloc_dyn_array(ref, ctrl->elems))
return;
ref->p_req_elems = ctrl->elems;
ptr_to_ptr(ctrl, ctrl->p_cur, ref->p_req, ctrl->elems);
ref->p_req_valid = true;
}
/* Copy the request value to the new value */
void req_to_new(struct v4l2_ctrl_ref *ref)
int req_to_new(struct v4l2_ctrl_ref *ref)
{
struct v4l2_ctrl *ctrl;
if (!ref)
return;
if (ref->valid_p_req)
ptr_to_ptr(ref->ctrl, ref->p_req, ref->ctrl->p_new);
else
ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->ctrl->p_new);
return 0;
ctrl = ref->ctrl;
/*
* This control was never set in the request, so just use the current
* value.
*/
if (!ref->p_req_valid) {
if (ctrl->is_dyn_array)
ctrl->new_elems = ctrl->elems;
ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new, ctrl->new_elems);
return 0;
}
/* Not a dynamic array, so just copy the request value */
if (!ctrl->is_dyn_array) {
ptr_to_ptr(ctrl, ref->p_req, ctrl->p_new, ctrl->new_elems);
return 0;
}
/* Sanity check, should never happen */
if (WARN_ON(!ref->p_req_dyn_alloc_elems))
return -ENOMEM;
/*
* Check if the number of elements in the request is more than the
* elements in ctrl->p_dyn. If so, attempt to realloc ctrl->p_dyn.
* Note that p_dyn is allocated with twice the number of elements
* in the dynamic array since it has to store both the current and
* new value of such a control.
*/
if (ref->p_req_elems > ctrl->p_dyn_alloc_elems) {
unsigned int sz = ref->p_req_elems * ctrl->elem_size;
void *old = ctrl->p_dyn;
void *tmp = kvzalloc(2 * sz, GFP_KERNEL);
if (!tmp)
return -ENOMEM;
memcpy(tmp, ctrl->p_new.p, ctrl->elems * ctrl->elem_size);
memcpy(tmp + sz, ctrl->p_cur.p, ctrl->elems * ctrl->elem_size);
ctrl->p_new.p = tmp;
ctrl->p_cur.p = tmp + sz;
ctrl->p_dyn = tmp;
ctrl->p_dyn_alloc_elems = ref->p_req_elems;
kvfree(old);
}
ctrl->new_elems = ref->p_req_elems;
ptr_to_ptr(ctrl, ref->p_req, ctrl->p_new, ctrl->new_elems);
return 0;
}
/* Control range checking */
......@@ -1110,17 +1206,6 @@ int check_range(enum v4l2_ctrl_type type,
}
}
/* Validate a new control */
int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new)
{
unsigned idx;
int err = 0;
for (idx = 0; !err && idx < ctrl->elems; idx++)
err = ctrl->type_ops->validate(ctrl, idx, p_new);
return err;
}
/* Set the handler's error code if it wasn't set earlier already */
static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err)
{
......@@ -1164,6 +1249,8 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
/* Free all nodes */
list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) {
list_del(&ref->node);
if (ref->p_req_dyn_alloc_elems)
kvfree(ref->p_req.p);
kfree(ref);
}
/* Free all controls owned by the handler */
......@@ -1171,6 +1258,7 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
list_del(&ctrl->node);
list_for_each_entry_safe(sev, next_sev, &ctrl->ev_subs, node)
list_del(&sev->node);
kvfree(ctrl->p_dyn);
kvfree(ctrl);
}
kvfree(hdl->buckets);
......@@ -1286,7 +1374,7 @@ int handler_new_ref(struct v4l2_ctrl_handler *hdl,
if (hdl->error)
return hdl->error;
if (allocate_req)
if (allocate_req && !ctrl->is_dyn_array)
size_extra_req = ctrl->elems * ctrl->elem_size;
new_ref = kzalloc(sizeof(*new_ref) + size_extra_req, GFP_KERNEL);
if (!new_ref)
......@@ -1460,7 +1548,6 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
elem_size = sizeof(s32);
break;
}
tot_ctrl_size = elem_size * elems;
/* Sanity checks */
if (id == 0 || name == NULL || !elem_size ||
......@@ -1481,17 +1568,33 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
handler_set_err(hdl, -EINVAL);
return NULL;
}
if (flags & V4L2_CTRL_FLAG_DYNAMIC_ARRAY) {
/*
* For now only support this for one-dimensional arrays only.
*
* This can be relaxed in the future, but this will
* require more effort.
*/
if (nr_of_dims != 1) {
handler_set_err(hdl, -EINVAL);
return NULL;
}
/* Start with just 1 element */
elems = 1;
}
tot_ctrl_size = elem_size * elems;
sz_extra = 0;
if (type == V4L2_CTRL_TYPE_BUTTON)
flags |= V4L2_CTRL_FLAG_WRITE_ONLY |
V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
else if (type == V4L2_CTRL_TYPE_CTRL_CLASS)
flags |= V4L2_CTRL_FLAG_READ_ONLY;
else if (type == V4L2_CTRL_TYPE_INTEGER64 ||
type == V4L2_CTRL_TYPE_STRING ||
type >= V4L2_CTRL_COMPOUND_TYPES ||
is_array)
else if (!(flags & V4L2_CTRL_FLAG_DYNAMIC_ARRAY) &&
(type == V4L2_CTRL_TYPE_INTEGER64 ||
type == V4L2_CTRL_TYPE_STRING ||
type >= V4L2_CTRL_COMPOUND_TYPES ||
is_array))
sz_extra += 2 * tot_ctrl_size;
if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const)
......@@ -1520,7 +1623,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
ctrl->is_ptr = is_array || type >= V4L2_CTRL_COMPOUND_TYPES || ctrl->is_string;
ctrl->is_int = !ctrl->is_ptr && type != V4L2_CTRL_TYPE_INTEGER64;
ctrl->is_array = is_array;
ctrl->is_dyn_array = !!(flags & V4L2_CTRL_FLAG_DYNAMIC_ARRAY);
ctrl->elems = elems;
ctrl->new_elems = elems;
ctrl->nr_of_dims = nr_of_dims;
if (nr_of_dims)
memcpy(ctrl->dims, dims, nr_of_dims * sizeof(dims[0]));
......@@ -1533,6 +1638,16 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
ctrl->cur.val = ctrl->val = def;
data = &ctrl[1];
if (ctrl->is_dyn_array) {
ctrl->p_dyn_alloc_elems = elems;
ctrl->p_dyn = kvzalloc(2 * elems * elem_size, GFP_KERNEL);
if (!ctrl->p_dyn) {
kvfree(ctrl);
return NULL;
}
data = ctrl->p_dyn;
}
if (!ctrl->is_int) {
ctrl->p_new.p = data;
ctrl->p_cur.p = data + tot_ctrl_size;
......@@ -1542,7 +1657,10 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
}
if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const) {
ctrl->p_def.p = ctrl->p_cur.p + tot_ctrl_size;
if (ctrl->is_dyn_array)
ctrl->p_def.p = &ctrl[1];
else
ctrl->p_def.p = ctrl->p_cur.p + tot_ctrl_size;
memcpy(ctrl->p_def.p, p_def.p_const, elem_size);
}
......@@ -1552,6 +1670,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
}
if (handler_new_ref(hdl, ctrl, NULL, false, false)) {
kvfree(ctrl->p_dyn);
kvfree(ctrl);
return NULL;
}
......@@ -1889,6 +2008,9 @@ static int cluster_changed(struct v4l2_ctrl *master)
continue;
}
if (ctrl->elems != ctrl->new_elems)
ctrl_changed = true;
for (idx = 0; !ctrl_changed && idx < ctrl->elems; idx++)
ctrl_changed = !ctrl->type_ops->equal(ctrl, idx,
ctrl->p_cur, ctrl->p_new);
......
......@@ -704,9 +704,9 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
return hevc_tier;
case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE:
return hevc_loop_filter_mode;
case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE:
case V4L2_CID_STATELESS_HEVC_DECODE_MODE:
return hevc_decode_mode;
case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE:
case V4L2_CID_STATELESS_HEVC_START_CODE:
return hevc_start_code;
case V4L2_CID_CAMERA_ORIENTATION:
return camera_orientation;
......@@ -1003,13 +1003,6 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: return "HEVC Size of Length Field";
case V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES: return "Reference Frames for a P-Frame";
case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR: return "Prepend SPS and PPS to IDR";
case V4L2_CID_MPEG_VIDEO_HEVC_SPS: return "HEVC Sequence Parameter Set";
case V4L2_CID_MPEG_VIDEO_HEVC_PPS: return "HEVC Picture Parameter Set";
case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: return "HEVC Slice Parameters";
case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX: return "HEVC Scaling Matrix";
case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS: return "HEVC Decode Parameters";
case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: return "HEVC Decode Mode";
case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: return "HEVC Start Code";
/* CAMERA controls */
/* Keep the order of the 'case's the same as in v4l2-controls.h! */
......@@ -1188,6 +1181,14 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_STATELESS_MPEG2_QUANTISATION: return "MPEG-2 Quantisation Matrices";
case V4L2_CID_STATELESS_VP9_COMPRESSED_HDR: return "VP9 Probabilities Updates";
case V4L2_CID_STATELESS_VP9_FRAME: return "VP9 Frame Decode Parameters";
case V4L2_CID_STATELESS_HEVC_SPS: return "HEVC Sequence Parameter Set";
case V4L2_CID_STATELESS_HEVC_PPS: return "HEVC Picture Parameter Set";
case V4L2_CID_STATELESS_HEVC_SLICE_PARAMS: return "HEVC Slice Parameters";
case V4L2_CID_STATELESS_HEVC_SCALING_MATRIX: return "HEVC Scaling Matrix";
case V4L2_CID_STATELESS_HEVC_DECODE_PARAMS: return "HEVC Decode Parameters";
case V4L2_CID_STATELESS_HEVC_DECODE_MODE: return "HEVC Decode Mode";
case V4L2_CID_STATELESS_HEVC_START_CODE: return "HEVC Start Code";
case V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS: return "HEVC Entry Point Offsets";
/* Colorimetry controls */
/* Keep the order of the 'case's the same as in v4l2-controls.h! */
......@@ -1363,8 +1364,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD:
case V4L2_CID_MPEG_VIDEO_HEVC_TIER:
case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE:
case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE:
case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE:
case V4L2_CID_STATELESS_HEVC_DECODE_MODE:
case V4L2_CID_STATELESS_HEVC_START_CODE:
case V4L2_CID_STATELESS_H264_DECODE_MODE:
case V4L2_CID_STATELESS_H264_START_CODE:
case V4L2_CID_CAMERA_ORIENTATION:
......@@ -1502,21 +1503,26 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_STATELESS_VP8_FRAME:
*type = V4L2_CTRL_TYPE_VP8_FRAME;
break;
case V4L2_CID_MPEG_VIDEO_HEVC_SPS:
case V4L2_CID_STATELESS_HEVC_SPS:
*type = V4L2_CTRL_TYPE_HEVC_SPS;
break;
case V4L2_CID_MPEG_VIDEO_HEVC_PPS:
case V4L2_CID_STATELESS_HEVC_PPS:
*type = V4L2_CTRL_TYPE_HEVC_PPS;
break;
case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS:
case V4L2_CID_STATELESS_HEVC_SLICE_PARAMS:
*type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS;
*flags |= V4L2_CTRL_FLAG_DYNAMIC_ARRAY;
break;
case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX:
case V4L2_CID_STATELESS_HEVC_SCALING_MATRIX:
*type = V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX;
break;
case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS:
case V4L2_CID_STATELESS_HEVC_DECODE_PARAMS:
*type = V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS;
break;
case V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS:
*type = V4L2_CTRL_TYPE_U32;
*flags |= V4L2_CTRL_FLAG_DYNAMIC_ARRAY;
break;
case V4L2_CID_STATELESS_VP9_COMPRESSED_HDR:
*type = V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR;
break;
......
......@@ -57,10 +57,9 @@ void cur_to_new(struct v4l2_ctrl *ctrl);
void cur_to_req(struct v4l2_ctrl_ref *ref);
void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags);
void new_to_req(struct v4l2_ctrl_ref *ref);
void req_to_new(struct v4l2_ctrl_ref *ref);
int req_to_new(struct v4l2_ctrl_ref *ref);
void send_initial_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl);
void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes);
int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new);
int handler_new_ref(struct v4l2_ctrl_handler *hdl,
struct v4l2_ctrl *ctrl,
struct v4l2_ctrl_ref **ctrl_ref,
......
......@@ -143,7 +143,7 @@ v4l2_ctrl_request_hdl_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id)
{
struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id);
return (ref && ref->valid_p_req) ? ref->ctrl : NULL;
return (ref && ref->p_req_valid) ? ref->ctrl : NULL;
}
EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_ctrl_find);
......@@ -373,7 +373,7 @@ void v4l2_ctrl_request_complete(struct media_request *req,
v4l2_ctrl_unlock(master);
continue;
}
if (ref->valid_p_req)
if (ref->p_req_valid)
continue;
/* Copy the current control value into the request */
......@@ -442,7 +442,7 @@ int v4l2_ctrl_request_setup(struct media_request *req,
struct v4l2_ctrl_ref *r =
find_ref(hdl, master->cluster[i]->id);
if (r->valid_p_req) {
if (r->p_req_valid) {
have_new_data = true;
break;
}
......@@ -458,7 +458,11 @@ int v4l2_ctrl_request_setup(struct media_request *req,
struct v4l2_ctrl_ref *r =
find_ref(hdl, master->cluster[i]->id);
req_to_new(r);
ret = req_to_new(r);
if (ret) {
v4l2_ctrl_unlock(master);
goto error;
}
master->cluster[i]->is_new = 1;
r->req_done = true;
}
......@@ -490,6 +494,7 @@ int v4l2_ctrl_request_setup(struct media_request *req,
break;
}
error:
media_request_object_put(obj);
return ret;
}
......
......@@ -1306,9 +1306,11 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_PIX_FMT_NV61: descr = "Y/CrCb 4:2:2"; break;
case V4L2_PIX_FMT_NV24: descr = "Y/CbCr 4:4:4"; break;
case V4L2_PIX_FMT_NV42: descr = "Y/CrCb 4:4:4"; break;
case V4L2_PIX_FMT_P010: descr = "10-bit Y/CrCb 4:2:0"; break;
case V4L2_PIX_FMT_NV12_4L4: descr = "Y/CbCr 4:2:0 (4x4 Linear)"; break;
case V4L2_PIX_FMT_NV12_16L16: descr = "Y/CbCr 4:2:0 (16x16 Linear)"; break;
case V4L2_PIX_FMT_NV12_32L32: descr = "Y/CbCr 4:2:0 (32x32 Linear)"; break;
case V4L2_PIX_FMT_P010_4L4: descr = "P010 tiled"; break;
case V4L2_PIX_FMT_NV12M: descr = "Y/CbCr 4:2:0 (N-C)"; break;
case V4L2_PIX_FMT_NV21M: descr = "Y/CrCb 4:2:0 (N-C)"; break;
case V4L2_PIX_FMT_NV16M: descr = "Y/CbCr 4:2:2 (N-C)"; break;
......
......@@ -227,6 +227,7 @@ struct hantro_dev {
*
* @ctrl_handler: Control handler used to register controls.
* @jpeg_quality: User-specified JPEG compression quality.
* @bit_depth: Bit depth of current frame
*
* @codec_ops: Set of operations related to codec mode.
* @postproc: Post-processing context.
......@@ -252,6 +253,7 @@ struct hantro_ctx {
struct v4l2_ctrl_handler ctrl_handler;
int jpeg_quality;
int bit_depth;
const struct hantro_codec_ops *codec_ops;
struct hantro_postproc_ctx postproc;
......@@ -277,6 +279,7 @@ struct hantro_ctx {
* @enc_fmt: Format identifier for encoder registers.
* @frmsize: Supported range of frame sizes (only for bitstream formats).
* @postprocessed: Indicates if this format needs the post-processor.
* @match_depth: Indicates if format bit depth must match video bit depth
*/
struct hantro_fmt {
char *name;
......@@ -287,6 +290,7 @@ struct hantro_fmt {
enum hantro_enc_fmt enc_fmt;
struct v4l2_frmsize_stepwise frmsize;
bool postprocessed;
bool match_depth;
};
struct hantro_reg {
......
......@@ -253,6 +253,11 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
{
struct hantro_ctx *ctx;
ctx = container_of(ctrl->handler,
struct hantro_ctx, ctrl_handler);
if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) {
const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;
......@@ -265,15 +270,10 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
if (sps->bit_depth_luma_minus8 != 0)
/* Only 8-bit is supported */
return -EINVAL;
} else if (ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_SPS) {
} else if (ctrl->id == V4L2_CID_STATELESS_HEVC_SPS) {
const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps;
if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8)
/* Luma and chroma bit depth mismatch */
return -EINVAL;
if (sps->bit_depth_luma_minus8 != 0)
/* Only 8-bit is supported */
return -EINVAL;
return hantro_hevc_validate_sps(ctx, sps);
} else if (ctrl->id == V4L2_CID_STATELESS_VP9_FRAME) {
const struct v4l2_ctrl_vp9_frame *dec_params = ctrl->p_new.p_vp9_frame;
......@@ -304,18 +304,16 @@ static int hantro_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
return 0;
}
static int hantro_hevc_s_ctrl(struct v4l2_ctrl *ctrl)
static int hantro_vp9_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct hantro_ctx *ctx;
ctx = container_of(ctrl->handler,
struct hantro_ctx, ctrl_handler);
vpu_debug(1, "s_ctrl: id = %d, val = %d\n", ctrl->id, ctrl->val);
switch (ctrl->id) {
case V4L2_CID_HANTRO_HEVC_SLICE_HEADER_SKIP:
ctx->hevc_dec.ctrls.hevc_hdr_skip_length = ctrl->val;
case V4L2_CID_STATELESS_VP9_FRAME:
ctx->bit_depth = ctrl->p_new.p_vp9_frame->bit_depth;
break;
default:
return -EINVAL;
......@@ -332,15 +330,15 @@ static const struct v4l2_ctrl_ops hantro_jpeg_ctrl_ops = {
.s_ctrl = hantro_jpeg_s_ctrl,
};
static const struct v4l2_ctrl_ops hantro_hevc_ctrl_ops = {
.s_ctrl = hantro_hevc_s_ctrl,
};
#define HANTRO_JPEG_ACTIVE_MARKERS (V4L2_JPEG_ACTIVE_MARKER_APP0 | \
V4L2_JPEG_ACTIVE_MARKER_COM | \
V4L2_JPEG_ACTIVE_MARKER_DQT | \
V4L2_JPEG_ACTIVE_MARKER_DHT)
static const struct v4l2_ctrl_ops hantro_vp9_ctrl_ops = {
.s_ctrl = hantro_vp9_s_ctrl,
};
static const struct hantro_ctrl controls[] = {
{
.codec = HANTRO_JPEG_ENCODER,
......@@ -438,18 +436,18 @@ static const struct hantro_ctrl controls[] = {
}, {
.codec = HANTRO_HEVC_DECODER,
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE,
.min = V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED,
.max = V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED,
.def = V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED,
.id = V4L2_CID_STATELESS_HEVC_DECODE_MODE,
.min = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED,
.max = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED,
.def = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED,
},
}, {
.codec = HANTRO_HEVC_DECODER,
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_HEVC_START_CODE,
.min = V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B,
.max = V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B,
.def = V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B,
.id = V4L2_CID_STATELESS_HEVC_START_CODE,
.min = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B,
.max = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B,
.def = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B,
},
}, {
.codec = HANTRO_HEVC_DECODER,
......@@ -469,40 +467,29 @@ static const struct hantro_ctrl controls[] = {
}, {
.codec = HANTRO_HEVC_DECODER,
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_HEVC_SPS,
.id = V4L2_CID_STATELESS_HEVC_SPS,
.ops = &hantro_ctrl_ops,
},
}, {
.codec = HANTRO_HEVC_DECODER,
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_HEVC_PPS,
.id = V4L2_CID_STATELESS_HEVC_PPS,
},
}, {
.codec = HANTRO_HEVC_DECODER,
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS,
.id = V4L2_CID_STATELESS_HEVC_DECODE_PARAMS,
},
}, {
.codec = HANTRO_HEVC_DECODER,
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX,
},
}, {
.codec = HANTRO_HEVC_DECODER,
.cfg = {
.id = V4L2_CID_HANTRO_HEVC_SLICE_HEADER_SKIP,
.name = "Hantro HEVC slice header skip bytes",
.type = V4L2_CTRL_TYPE_INTEGER,
.min = 0,
.def = 0,
.max = 0x100,
.step = 1,
.ops = &hantro_hevc_ctrl_ops,
.id = V4L2_CID_STATELESS_HEVC_SCALING_MATRIX,
},
}, {
.codec = HANTRO_VP9_DECODER,
.cfg = {
.id = V4L2_CID_STATELESS_VP9_FRAME,
.ops = &hantro_vp9_ctrl_ops,
},
}, {
.codec = HANTRO_VP9_DECODER,
......
......@@ -12,7 +12,7 @@
static size_t hantro_hevc_chroma_offset(struct hantro_ctx *ctx)
{
return ctx->dst_fmt.width * ctx->dst_fmt.height;
return ctx->dst_fmt.width * ctx->dst_fmt.height * ctx->bit_depth / 8;
}
static size_t hantro_hevc_motion_vectors_offset(struct hantro_ctx *ctx)
......@@ -117,6 +117,66 @@ static void prepare_tile_info_buffer(struct hantro_ctx *ctx)
vpu_debug(1, "%s: no chroma!\n", __func__);
}
static unsigned int ceil_log2(unsigned int v)
{
/* Compute Ceil(Log2(v))
* Derived from branchless code for integer log2(v) from:
* <http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog>
*/
unsigned int r, shift;
v--;
r = (v > 0xFFFF) << 4;
v >>= r;
shift = (v > 0xFF) << 3;
v >>= shift;
r |= shift;
shift = (v > 0xF) << 2;
v >>= shift;
r |= shift;
shift = (v > 0x3) << 1;
v >>= shift;
r |= shift;
r |= (v >> 1);
return r + 1;
}
static int compute_header_skip_lenght(struct hantro_ctx *ctx)
{
const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params;
const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps;
const struct v4l2_ctrl_hevc_pps *pps = ctrls->pps;
int skip = 0;
if (pps->flags & V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT)
/* size of pic_output_flag */
skip++;
if (sps->flags & V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE)
/* size of pic_order_cnt_lsb */
skip += 2;
if (!(decode_params->flags & V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC)) {
/* size of pic_order_cnt_lsb */
skip += sps->log2_max_pic_order_cnt_lsb_minus4 + 4;
/* size of short_term_ref_pic_set_sps_flag */
skip++;
if (decode_params->short_term_ref_pic_set_size)
/* size of st_ref_pic_set( num_short_term_ref_pic_sets ) */
skip += decode_params->short_term_ref_pic_set_size;
else if (sps->num_short_term_ref_pic_sets > 1)
skip += ceil_log2(sps->num_short_term_ref_pic_sets);
skip += decode_params->long_term_ref_pic_set_size;
}
return skip;
}
static void set_params(struct hantro_ctx *ctx)
{
const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
......@@ -132,9 +192,7 @@ static void set_params(struct hantro_ctx *ctx)
hantro_reg_write(vpu, &g2_bit_depth_y_minus8, sps->bit_depth_luma_minus8);
hantro_reg_write(vpu, &g2_bit_depth_c_minus8, sps->bit_depth_chroma_minus8);
hantro_reg_write(vpu, &g2_output_8_bits, 0);
hantro_reg_write(vpu, &g2_hdr_skip_length, ctrls->hevc_hdr_skip_length);
hantro_reg_write(vpu, &g2_hdr_skip_length, compute_header_skip_lenght(ctx));
min_log2_cb_size = sps->log2_min_luma_coding_block_size_minus3 + 3;
max_log2_ctb_size = min_log2_cb_size + sps->log2_diff_max_min_luma_coding_block_size;
......@@ -390,11 +448,10 @@ static int set_ref(struct hantro_ctx *ctx)
!!(pps->flags & V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED));
/*
* Write POC count diff from current pic. For frame decoding only compute
* pic_order_cnt[0] and ignore pic_order_cnt[1] used in field-coding.
* Write POC count diff from current pic.
*/
for (i = 0; i < decode_params->num_active_dpb_entries && i < ARRAY_SIZE(cur_poc); i++) {
char poc_diff = decode_params->pic_order_cnt_val - dpb[i].pic_order_cnt[0];
char poc_diff = decode_params->pic_order_cnt_val - dpb[i].pic_order_cnt_val;
hantro_reg_write(vpu, &cur_poc[i], poc_diff);
}
......@@ -414,14 +471,14 @@ static int set_ref(struct hantro_ctx *ctx)
set_ref_pic_list(ctx);
/* We will only keep the reference pictures that are still used */
/* We will only keep the references pictures that are still used */
hantro_hevc_ref_init(ctx);
/* Set up addresses of DPB buffers */
dpb_longterm_e = 0;
for (i = 0; i < decode_params->num_active_dpb_entries &&
i < (V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1); i++) {
luma_addr = hantro_hevc_get_ref_buf(ctx, dpb[i].pic_order_cnt[0]);
luma_addr = hantro_hevc_get_ref_buf(ctx, dpb[i].pic_order_cnt_val);
if (!luma_addr)
return -ENOMEM;
......
......@@ -107,7 +107,7 @@
#define g2_start_code_e G2_DEC_REG(10, 31, 0x1)
#define g2_init_qp_old G2_DEC_REG(10, 25, 0x3f)
#define g2_init_qp G2_DEC_REG(10, 24, 0x3f)
#define g2_init_qp G2_DEC_REG(10, 24, 0x7f)
#define g2_num_tile_cols_old G2_DEC_REG(10, 20, 0x1f)
#define g2_num_tile_cols G2_DEC_REG(10, 19, 0x1f)
#define g2_num_tile_rows_old G2_DEC_REG(10, 15, 0x1f)
......