1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) STMicroelectronics SA 2015
4*4882a593Smuzhiyun * Authors: Yannick Fertre <yannick.fertre@st.com>
5*4882a593Smuzhiyun * Hugues Fruchet <hugues.fruchet@st.com>
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include "hva.h"
9*4882a593Smuzhiyun #include "hva-hw.h"
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #define MAX_SPS_PPS_SIZE 128
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #define BITSTREAM_OFFSET_MASK 0x7F
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun /* video max size*/
16*4882a593Smuzhiyun #define H264_MAX_SIZE_W 1920
17*4882a593Smuzhiyun #define H264_MAX_SIZE_H 1920
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun /* macroBlocs number (width & height) */
20*4882a593Smuzhiyun #define MB_W(w) ((w + 0xF) / 0x10)
21*4882a593Smuzhiyun #define MB_H(h) ((h + 0xF) / 0x10)
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun /* formula to get temporal or spatial data size */
24*4882a593Smuzhiyun #define DATA_SIZE(w, h) (MB_W(w) * MB_H(h) * 16)
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #define SEARCH_WINDOW_BUFFER_MAX_SIZE(w) ((4 * MB_W(w) + 42) * 256 * 3 / 2)
27*4882a593Smuzhiyun #define CABAC_CONTEXT_BUFFER_MAX_SIZE(w) (MB_W(w) * 16)
28*4882a593Smuzhiyun #define CTX_MB_BUFFER_MAX_SIZE(w) (MB_W(w) * 16 * 8)
29*4882a593Smuzhiyun #define SLICE_HEADER_SIZE (4 * 16)
30*4882a593Smuzhiyun #define BRC_DATA_SIZE (5 * 16)
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun /* source buffer copy in YUV 420 MB-tiled format with size=16*256*3/2 */
33*4882a593Smuzhiyun #define CURRENT_WINDOW_BUFFER_MAX_SIZE (16 * 256 * 3 / 2)
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun /*
36*4882a593Smuzhiyun * 4 lines of pixels (in Luma, Chroma blue and Chroma red) of top MB
37*4882a593Smuzhiyun * for deblocking with size=4*16*MBx*2
38*4882a593Smuzhiyun */
39*4882a593Smuzhiyun #define LOCAL_RECONSTRUCTED_BUFFER_MAX_SIZE(w) (4 * 16 * MB_W(w) * 2)
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun /* factor for bitrate and cpb buffer size max values if profile >= high */
42*4882a593Smuzhiyun #define H264_FACTOR_HIGH 1200
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /* factor for bitrate and cpb buffer size max values if profile < high */
45*4882a593Smuzhiyun #define H264_FACTOR_BASELINE 1000
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun /* number of bytes for NALU_TYPE_FILLER_DATA header and footer */
48*4882a593Smuzhiyun #define H264_FILLER_DATA_SIZE 6
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun struct h264_profile {
51*4882a593Smuzhiyun enum v4l2_mpeg_video_h264_level level;
52*4882a593Smuzhiyun u32 max_mb_per_seconds;
53*4882a593Smuzhiyun u32 max_frame_size;
54*4882a593Smuzhiyun u32 max_bitrate;
55*4882a593Smuzhiyun u32 max_cpb_size;
56*4882a593Smuzhiyun u32 min_comp_ratio;
57*4882a593Smuzhiyun };
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun static const struct h264_profile h264_infos_list[] = {
60*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_1_0, 1485, 99, 64, 175, 2},
61*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_1B, 1485, 99, 128, 350, 2},
62*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_1_1, 3000, 396, 192, 500, 2},
63*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_1_2, 6000, 396, 384, 1000, 2},
64*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_1_3, 11880, 396, 768, 2000, 2},
65*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_2_0, 11880, 396, 2000, 2000, 2},
66*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_2_1, 19800, 792, 4000, 4000, 2},
67*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_2_2, 20250, 1620, 4000, 4000, 2},
68*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_3_0, 40500, 1620, 10000, 10000, 2},
69*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_3_1, 108000, 3600, 14000, 14000, 4},
70*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_3_2, 216000, 5120, 20000, 20000, 4},
71*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_4_0, 245760, 8192, 20000, 25000, 4},
72*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_4_1, 245760, 8192, 50000, 62500, 2},
73*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_4_2, 522240, 8704, 50000, 62500, 2},
74*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 589824, 22080, 135000, 135000, 2},
75*4882a593Smuzhiyun {V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 983040, 36864, 240000, 240000, 2}
76*4882a593Smuzhiyun };
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun enum hva_brc_type {
79*4882a593Smuzhiyun BRC_TYPE_NONE = 0,
80*4882a593Smuzhiyun BRC_TYPE_CBR = 1,
81*4882a593Smuzhiyun BRC_TYPE_VBR = 2,
82*4882a593Smuzhiyun BRC_TYPE_VBR_LOW_DELAY = 3
83*4882a593Smuzhiyun };
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun enum hva_entropy_coding_mode {
86*4882a593Smuzhiyun CAVLC = 0,
87*4882a593Smuzhiyun CABAC = 1
88*4882a593Smuzhiyun };
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun enum hva_picture_coding_type {
91*4882a593Smuzhiyun PICTURE_CODING_TYPE_I = 0,
92*4882a593Smuzhiyun PICTURE_CODING_TYPE_P = 1,
93*4882a593Smuzhiyun PICTURE_CODING_TYPE_B = 2
94*4882a593Smuzhiyun };
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun enum hva_h264_sampling_mode {
97*4882a593Smuzhiyun SAMPLING_MODE_NV12 = 0,
98*4882a593Smuzhiyun SAMPLING_MODE_UYVY = 1,
99*4882a593Smuzhiyun SAMPLING_MODE_RGB3 = 3,
100*4882a593Smuzhiyun SAMPLING_MODE_XRGB4 = 4,
101*4882a593Smuzhiyun SAMPLING_MODE_NV21 = 8,
102*4882a593Smuzhiyun SAMPLING_MODE_VYUY = 9,
103*4882a593Smuzhiyun SAMPLING_MODE_BGR3 = 11,
104*4882a593Smuzhiyun SAMPLING_MODE_XBGR4 = 12,
105*4882a593Smuzhiyun SAMPLING_MODE_RGBX4 = 20,
106*4882a593Smuzhiyun SAMPLING_MODE_BGRX4 = 28
107*4882a593Smuzhiyun };
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun enum hva_h264_nalu_type {
110*4882a593Smuzhiyun NALU_TYPE_UNKNOWN = 0,
111*4882a593Smuzhiyun NALU_TYPE_SLICE = 1,
112*4882a593Smuzhiyun NALU_TYPE_SLICE_DPA = 2,
113*4882a593Smuzhiyun NALU_TYPE_SLICE_DPB = 3,
114*4882a593Smuzhiyun NALU_TYPE_SLICE_DPC = 4,
115*4882a593Smuzhiyun NALU_TYPE_SLICE_IDR = 5,
116*4882a593Smuzhiyun NALU_TYPE_SEI = 6,
117*4882a593Smuzhiyun NALU_TYPE_SPS = 7,
118*4882a593Smuzhiyun NALU_TYPE_PPS = 8,
119*4882a593Smuzhiyun NALU_TYPE_AU_DELIMITER = 9,
120*4882a593Smuzhiyun NALU_TYPE_SEQ_END = 10,
121*4882a593Smuzhiyun NALU_TYPE_STREAM_END = 11,
122*4882a593Smuzhiyun NALU_TYPE_FILLER_DATA = 12,
123*4882a593Smuzhiyun NALU_TYPE_SPS_EXT = 13,
124*4882a593Smuzhiyun NALU_TYPE_PREFIX_UNIT = 14,
125*4882a593Smuzhiyun NALU_TYPE_SUBSET_SPS = 15,
126*4882a593Smuzhiyun NALU_TYPE_SLICE_AUX = 19,
127*4882a593Smuzhiyun NALU_TYPE_SLICE_EXT = 20
128*4882a593Smuzhiyun };
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun enum hva_h264_sei_payload_type {
131*4882a593Smuzhiyun SEI_BUFFERING_PERIOD = 0,
132*4882a593Smuzhiyun SEI_PICTURE_TIMING = 1,
133*4882a593Smuzhiyun SEI_STEREO_VIDEO_INFO = 21,
134*4882a593Smuzhiyun SEI_FRAME_PACKING_ARRANGEMENT = 45
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun /*
138*4882a593Smuzhiyun * stereo Video Info struct
139*4882a593Smuzhiyun */
140*4882a593Smuzhiyun struct hva_h264_stereo_video_sei {
141*4882a593Smuzhiyun u8 field_views_flag;
142*4882a593Smuzhiyun u8 top_field_is_left_view_flag;
143*4882a593Smuzhiyun u8 current_frame_is_left_view_flag;
144*4882a593Smuzhiyun u8 next_frame_is_second_view_flag;
145*4882a593Smuzhiyun u8 left_view_self_contained_flag;
146*4882a593Smuzhiyun u8 right_view_self_contained_flag;
147*4882a593Smuzhiyun };
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun /*
150*4882a593Smuzhiyun * struct hva_h264_td
151*4882a593Smuzhiyun *
152*4882a593Smuzhiyun * @frame_width: width in pixels of the buffer containing the input frame
153*4882a593Smuzhiyun * @frame_height: height in pixels of the buffer containing the input frame
154*4882a593Smuzhiyun * @frame_num: the parameter to be written in the slice header
155*4882a593Smuzhiyun * @picture_coding_type: type I, P or B
156*4882a593Smuzhiyun * @pic_order_cnt_type: POC mode, as defined in H264 std : can be 0,1,2
157*4882a593Smuzhiyun * @first_picture_in_sequence: flag telling to encoder that this is the
158*4882a593Smuzhiyun * first picture in a video sequence.
159*4882a593Smuzhiyun * Used for VBR
160*4882a593Smuzhiyun * @slice_size_type: 0 = no constraint to close the slice
161*4882a593Smuzhiyun * 1= a slice is closed as soon as the slice_mb_size limit
162*4882a593Smuzhiyun * is reached
163*4882a593Smuzhiyun * 2= a slice is closed as soon as the slice_byte_size limit
164*4882a593Smuzhiyun * is reached
165*4882a593Smuzhiyun * 3= a slice is closed as soon as either the slice_byte_size
166*4882a593Smuzhiyun * limit or the slice_mb_size limit is reached
167*4882a593Smuzhiyun * @slice_mb_size: defines the slice size in number of macroblocks
168*4882a593Smuzhiyun * (used when slice_size_type=1 or slice_size_type=3)
169*4882a593Smuzhiyun * @ir_param_option: defines the number of macroblocks per frame to be
170*4882a593Smuzhiyun * refreshed by AIR algorithm OR the refresh period
171*4882a593Smuzhiyun * by CIR algorithm
172*4882a593Smuzhiyun * @intra_refresh_type: enables the adaptive intra refresh algorithm.
173*4882a593Smuzhiyun * Disable=0 / Adaptative=1 and Cycle=2 as intra refresh
174*4882a593Smuzhiyun * @use_constrained_intra_flag: constrained_intra_pred_flag from PPS
175*4882a593Smuzhiyun * @transform_mode: controls the use of 4x4/8x8 transform mode
176*4882a593Smuzhiyun * @disable_deblocking_filter_idc:
177*4882a593Smuzhiyun * 0: specifies that all luma and chroma block edges of
178*4882a593Smuzhiyun * the slice are filtered.
179*4882a593Smuzhiyun * 1: specifies that deblocking is disabled for all block
180*4882a593Smuzhiyun * edges of the slice.
181*4882a593Smuzhiyun * 2: specifies that all luma and chroma block edges of
182*4882a593Smuzhiyun * the slice are filtered with exception of the block edges
183*4882a593Smuzhiyun * that coincide with slice boundaries
184*4882a593Smuzhiyun * @slice_alpha_c0_offset_div2: to be written in slice header,
185*4882a593Smuzhiyun * controls deblocking
186*4882a593Smuzhiyun * @slice_beta_offset_div2: to be written in slice header,
187*4882a593Smuzhiyun * controls deblocking
188*4882a593Smuzhiyun * @encoder_complexity: encoder complexity control (IME).
189*4882a593Smuzhiyun * 0 = I_16x16, P_16x16, Full ME Complexity
190*4882a593Smuzhiyun * 1 = I_16x16, I_NxN, P_16x16, Full ME Complexity
191*4882a593Smuzhiyun * 2 = I_16x16, I_NXN, P_16x16, P_WxH, Full ME Complexity
192*4882a593Smuzhiyun * 4 = I_16x16, P_16x16, Reduced ME Complexity
193*4882a593Smuzhiyun * 5 = I_16x16, I_NxN, P_16x16, Reduced ME Complexity
194*4882a593Smuzhiyun * 6 = I_16x16, I_NXN, P_16x16, P_WxH, Reduced ME Complexity
195*4882a593Smuzhiyun * @chroma_qp_index_offset: coming from picture parameter set
196*4882a593Smuzhiyun * (PPS see [H.264 STD] 7.4.2.2)
197*4882a593Smuzhiyun * @entropy_coding_mode: entropy coding mode.
198*4882a593Smuzhiyun * 0 = CAVLC
199*4882a593Smuzhiyun * 1 = CABAC
200*4882a593Smuzhiyun * @brc_type: selects the bit-rate control algorithm
201*4882a593Smuzhiyun * 0 = constant Qp, (no BRC)
202*4882a593Smuzhiyun * 1 = CBR
203*4882a593Smuzhiyun * 2 = VBR
204*4882a593Smuzhiyun * @quant: Quantization param used in case of fix QP encoding (no BRC)
205*4882a593Smuzhiyun * @non_VCL_NALU_Size: size of non-VCL NALUs (SPS, PPS, filler),
206*4882a593Smuzhiyun * used by BRC
207*4882a593Smuzhiyun * @cpb_buffer_size: size of Coded Picture Buffer, used by BRC
208*4882a593Smuzhiyun * @bit_rate: target bitrate, for BRC
209*4882a593Smuzhiyun * @qp_min: min QP threshold
210*4882a593Smuzhiyun * @qp_max: max QP threshold
211*4882a593Smuzhiyun * @framerate_num: target framerate numerator , used by BRC
212*4882a593Smuzhiyun * @framerate_den: target framerate denomurator , used by BRC
213*4882a593Smuzhiyun * @delay: End-to-End Initial Delay
214*4882a593Smuzhiyun * @strict_HRD_compliancy: flag for HDR compliancy (1)
215*4882a593Smuzhiyun * May impact quality encoding
216*4882a593Smuzhiyun * @addr_source_buffer: address of input frame buffer for current frame
217*4882a593Smuzhiyun * @addr_fwd_Ref_Buffer: address of reference frame buffer
218*4882a593Smuzhiyun * @addr_rec_buffer: address of reconstructed frame buffer
219*4882a593Smuzhiyun * @addr_output_bitstream_start: output bitstream start address
220*4882a593Smuzhiyun * @addr_output_bitstream_end: output bitstream end address
221*4882a593Smuzhiyun * @addr_external_sw : address of external search window
222*4882a593Smuzhiyun * @addr_lctx : address of context picture buffer
223*4882a593Smuzhiyun * @addr_local_rec_buffer: address of local reconstructed buffer
224*4882a593Smuzhiyun * @addr_spatial_context: address of spatial context buffer
225*4882a593Smuzhiyun * @bitstream_offset: offset in bits between aligned bitstream start
226*4882a593Smuzhiyun * address and first bit to be written by HVA.
227*4882a593Smuzhiyun * Range value is [0..63]
228*4882a593Smuzhiyun * @sampling_mode: Input picture format .
229*4882a593Smuzhiyun * 0: YUV420 semi_planar Interleaved
230*4882a593Smuzhiyun * 1: YUV422 raster Interleaved
231*4882a593Smuzhiyun * @addr_param_out: address of output parameters structure
232*4882a593Smuzhiyun * @addr_scaling_matrix: address to the coefficient of
233*4882a593Smuzhiyun * the inverse scaling matrix
234*4882a593Smuzhiyun * @addr_scaling_matrix_dir: address to the coefficient of
235*4882a593Smuzhiyun * the direct scaling matrix
236*4882a593Smuzhiyun * @addr_cabac_context_buffer: address of cabac context buffer
237*4882a593Smuzhiyun * @GmvX: Input information about the horizontal global displacement of
238*4882a593Smuzhiyun * the encoded frame versus the previous one
239*4882a593Smuzhiyun * @GmvY: Input information about the vertical global displacement of
240*4882a593Smuzhiyun * the encoded frame versus the previous one
241*4882a593Smuzhiyun * @window_width: width in pixels of the window to be encoded inside
242*4882a593Smuzhiyun * the input frame
243*4882a593Smuzhiyun * @window_height: width in pixels of the window to be encoded inside
244*4882a593Smuzhiyun * the input frame
245*4882a593Smuzhiyun * @window_horizontal_offset: horizontal offset in pels for input window
246*4882a593Smuzhiyun * within input frame
247*4882a593Smuzhiyun * @window_vertical_offset: vertical offset in pels for input window
248*4882a593Smuzhiyun * within input frame
249*4882a593Smuzhiyun * @addr_roi: Map of QP offset for the Region of Interest algorithm and
250*4882a593Smuzhiyun * also used for Error map.
251*4882a593Smuzhiyun * Bit 0-6 used for qp offset (value -64 to 63).
252*4882a593Smuzhiyun * Bit 7 used to force intra
253*4882a593Smuzhiyun * @addr_slice_header: address to slice header
254*4882a593Smuzhiyun * @slice_header_size_in_bits: size in bits of the Slice header
255*4882a593Smuzhiyun * @slice_header_offset0: Slice header offset where to insert
256*4882a593Smuzhiyun * first_Mb_in_slice
257*4882a593Smuzhiyun * @slice_header_offset1: Slice header offset where to insert
258*4882a593Smuzhiyun * slice_qp_delta
259*4882a593Smuzhiyun * @slice_header_offset2: Slice header offset where to insert
260*4882a593Smuzhiyun * num_MBs_in_slice
261*4882a593Smuzhiyun * @slice_synchro_enable: enable "slice ready" interrupt after each slice
262*4882a593Smuzhiyun * @max_slice_number: Maximum number of slice in a frame
263*4882a593Smuzhiyun * (0 is strictly forbidden)
264*4882a593Smuzhiyun * @rgb2_yuv_y_coeff: Four coefficients (C0C1C2C3) to convert from RGB to
265*4882a593Smuzhiyun * YUV for the Y component.
266*4882a593Smuzhiyun * Y = C0*R + C1*G + C2*B + C3 (C0 is on byte 0)
267*4882a593Smuzhiyun * @rgb2_yuv_u_coeff: four coefficients (C0C1C2C3) to convert from RGB to
268*4882a593Smuzhiyun * YUV for the Y component.
269*4882a593Smuzhiyun * Y = C0*R + C1*G + C2*B + C3 (C0 is on byte 0)
270*4882a593Smuzhiyun * @rgb2_yuv_v_coeff: Four coefficients (C0C1C2C3) to convert from RGB to
271*4882a593Smuzhiyun * YUV for the U (Cb) component.
272*4882a593Smuzhiyun * U = C0*R + C1*G + C2*B + C3 (C0 is on byte 0)
273*4882a593Smuzhiyun * @slice_byte_size: maximum slice size in bytes
274*4882a593Smuzhiyun * (used when slice_size_type=2 or slice_size_type=3)
275*4882a593Smuzhiyun * @max_air_intra_mb_nb: Maximum number of intra macroblock in a frame
276*4882a593Smuzhiyun * for the AIR algorithm
277*4882a593Smuzhiyun * @brc_no_skip: Disable skipping in the Bitrate Controller
278*4882a593Smuzhiyun * @addr_brc_in_out_parameter: address of static buffer for BRC parameters
279*4882a593Smuzhiyun */
280*4882a593Smuzhiyun struct hva_h264_td {
281*4882a593Smuzhiyun u16 frame_width;
282*4882a593Smuzhiyun u16 frame_height;
283*4882a593Smuzhiyun u32 frame_num;
284*4882a593Smuzhiyun u16 picture_coding_type;
285*4882a593Smuzhiyun u16 reserved1;
286*4882a593Smuzhiyun u16 pic_order_cnt_type;
287*4882a593Smuzhiyun u16 first_picture_in_sequence;
288*4882a593Smuzhiyun u16 slice_size_type;
289*4882a593Smuzhiyun u16 reserved2;
290*4882a593Smuzhiyun u32 slice_mb_size;
291*4882a593Smuzhiyun u16 ir_param_option;
292*4882a593Smuzhiyun u16 intra_refresh_type;
293*4882a593Smuzhiyun u16 use_constrained_intra_flag;
294*4882a593Smuzhiyun u16 transform_mode;
295*4882a593Smuzhiyun u16 disable_deblocking_filter_idc;
296*4882a593Smuzhiyun s16 slice_alpha_c0_offset_div2;
297*4882a593Smuzhiyun s16 slice_beta_offset_div2;
298*4882a593Smuzhiyun u16 encoder_complexity;
299*4882a593Smuzhiyun s16 chroma_qp_index_offset;
300*4882a593Smuzhiyun u16 entropy_coding_mode;
301*4882a593Smuzhiyun u16 brc_type;
302*4882a593Smuzhiyun u16 quant;
303*4882a593Smuzhiyun u32 non_vcl_nalu_size;
304*4882a593Smuzhiyun u32 cpb_buffer_size;
305*4882a593Smuzhiyun u32 bit_rate;
306*4882a593Smuzhiyun u16 qp_min;
307*4882a593Smuzhiyun u16 qp_max;
308*4882a593Smuzhiyun u16 framerate_num;
309*4882a593Smuzhiyun u16 framerate_den;
310*4882a593Smuzhiyun u16 delay;
311*4882a593Smuzhiyun u16 strict_hrd_compliancy;
312*4882a593Smuzhiyun u32 addr_source_buffer;
313*4882a593Smuzhiyun u32 addr_fwd_ref_buffer;
314*4882a593Smuzhiyun u32 addr_rec_buffer;
315*4882a593Smuzhiyun u32 addr_output_bitstream_start;
316*4882a593Smuzhiyun u32 addr_output_bitstream_end;
317*4882a593Smuzhiyun u32 addr_external_sw;
318*4882a593Smuzhiyun u32 addr_lctx;
319*4882a593Smuzhiyun u32 addr_local_rec_buffer;
320*4882a593Smuzhiyun u32 addr_spatial_context;
321*4882a593Smuzhiyun u16 bitstream_offset;
322*4882a593Smuzhiyun u16 sampling_mode;
323*4882a593Smuzhiyun u32 addr_param_out;
324*4882a593Smuzhiyun u32 addr_scaling_matrix;
325*4882a593Smuzhiyun u32 addr_scaling_matrix_dir;
326*4882a593Smuzhiyun u32 addr_cabac_context_buffer;
327*4882a593Smuzhiyun u32 reserved3;
328*4882a593Smuzhiyun u32 reserved4;
329*4882a593Smuzhiyun s16 gmv_x;
330*4882a593Smuzhiyun s16 gmv_y;
331*4882a593Smuzhiyun u16 window_width;
332*4882a593Smuzhiyun u16 window_height;
333*4882a593Smuzhiyun u16 window_horizontal_offset;
334*4882a593Smuzhiyun u16 window_vertical_offset;
335*4882a593Smuzhiyun u32 addr_roi;
336*4882a593Smuzhiyun u32 addr_slice_header;
337*4882a593Smuzhiyun u16 slice_header_size_in_bits;
338*4882a593Smuzhiyun u16 slice_header_offset0;
339*4882a593Smuzhiyun u16 slice_header_offset1;
340*4882a593Smuzhiyun u16 slice_header_offset2;
341*4882a593Smuzhiyun u32 reserved5;
342*4882a593Smuzhiyun u32 reserved6;
343*4882a593Smuzhiyun u16 reserved7;
344*4882a593Smuzhiyun u16 reserved8;
345*4882a593Smuzhiyun u16 slice_synchro_enable;
346*4882a593Smuzhiyun u16 max_slice_number;
347*4882a593Smuzhiyun u32 rgb2_yuv_y_coeff;
348*4882a593Smuzhiyun u32 rgb2_yuv_u_coeff;
349*4882a593Smuzhiyun u32 rgb2_yuv_v_coeff;
350*4882a593Smuzhiyun u32 slice_byte_size;
351*4882a593Smuzhiyun u16 max_air_intra_mb_nb;
352*4882a593Smuzhiyun u16 brc_no_skip;
353*4882a593Smuzhiyun u32 addr_temporal_context;
354*4882a593Smuzhiyun u32 addr_brc_in_out_parameter;
355*4882a593Smuzhiyun };
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun /*
358*4882a593Smuzhiyun * struct hva_h264_slice_po
359*4882a593Smuzhiyun *
360*4882a593Smuzhiyun * @ slice_size: slice size
361*4882a593Smuzhiyun * @ slice_start_time: start time
362*4882a593Smuzhiyun * @ slice_stop_time: stop time
363*4882a593Smuzhiyun * @ slice_num: slice number
364*4882a593Smuzhiyun */
365*4882a593Smuzhiyun struct hva_h264_slice_po {
366*4882a593Smuzhiyun u32 slice_size;
367*4882a593Smuzhiyun u32 slice_start_time;
368*4882a593Smuzhiyun u32 slice_end_time;
369*4882a593Smuzhiyun u32 slice_num;
370*4882a593Smuzhiyun };
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun /*
373*4882a593Smuzhiyun * struct hva_h264_po
374*4882a593Smuzhiyun *
375*4882a593Smuzhiyun * @ bitstream_size: bitstream size
376*4882a593Smuzhiyun * @ dct_bitstream_size: dtc bitstream size
377*4882a593Smuzhiyun * @ stuffing_bits: number of stuffing bits inserted by the encoder
378*4882a593Smuzhiyun * @ removal_time: removal time of current frame (nb of ticks 1/framerate)
379*4882a593Smuzhiyun * @ hvc_start_time: hvc start time
380*4882a593Smuzhiyun * @ hvc_stop_time: hvc stop time
381*4882a593Smuzhiyun * @ slice_count: slice count
382*4882a593Smuzhiyun */
383*4882a593Smuzhiyun struct hva_h264_po {
384*4882a593Smuzhiyun u32 bitstream_size;
385*4882a593Smuzhiyun u32 dct_bitstream_size;
386*4882a593Smuzhiyun u32 stuffing_bits;
387*4882a593Smuzhiyun u32 removal_time;
388*4882a593Smuzhiyun u32 hvc_start_time;
389*4882a593Smuzhiyun u32 hvc_stop_time;
390*4882a593Smuzhiyun u32 slice_count;
391*4882a593Smuzhiyun u32 reserved0;
392*4882a593Smuzhiyun struct hva_h264_slice_po slice_params[16];
393*4882a593Smuzhiyun };
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun struct hva_h264_task {
396*4882a593Smuzhiyun struct hva_h264_td td;
397*4882a593Smuzhiyun struct hva_h264_po po;
398*4882a593Smuzhiyun };
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun /*
401*4882a593Smuzhiyun * struct hva_h264_ctx
402*4882a593Smuzhiyun *
403*4882a593Smuzhiyun * @seq_info: sequence information buffer
404*4882a593Smuzhiyun * @ref_frame: reference frame buffer
405*4882a593Smuzhiyun * @rec_frame: reconstructed frame buffer
406*4882a593Smuzhiyun * @task: task descriptor
407*4882a593Smuzhiyun */
408*4882a593Smuzhiyun struct hva_h264_ctx {
409*4882a593Smuzhiyun struct hva_buffer *seq_info;
410*4882a593Smuzhiyun struct hva_buffer *ref_frame;
411*4882a593Smuzhiyun struct hva_buffer *rec_frame;
412*4882a593Smuzhiyun struct hva_buffer *task;
413*4882a593Smuzhiyun };
414*4882a593Smuzhiyun
hva_h264_fill_slice_header(struct hva_ctx * pctx,u8 * slice_header_addr,struct hva_controls * ctrls,int frame_num,u16 * header_size,u16 * header_offset0,u16 * header_offset1,u16 * header_offset2)415*4882a593Smuzhiyun static int hva_h264_fill_slice_header(struct hva_ctx *pctx,
416*4882a593Smuzhiyun u8 *slice_header_addr,
417*4882a593Smuzhiyun struct hva_controls *ctrls,
418*4882a593Smuzhiyun int frame_num,
419*4882a593Smuzhiyun u16 *header_size,
420*4882a593Smuzhiyun u16 *header_offset0,
421*4882a593Smuzhiyun u16 *header_offset1,
422*4882a593Smuzhiyun u16 *header_offset2)
423*4882a593Smuzhiyun {
424*4882a593Smuzhiyun /*
425*4882a593Smuzhiyun * with this HVA hardware version, part of the slice header is computed
426*4882a593Smuzhiyun * on host and part by hardware.
427*4882a593Smuzhiyun * The part of host is precomputed and available through this array.
428*4882a593Smuzhiyun */
429*4882a593Smuzhiyun struct device *dev = ctx_to_dev(pctx);
430*4882a593Smuzhiyun int cabac = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
431*4882a593Smuzhiyun const unsigned char slice_header[] = { 0x00, 0x00, 0x00, 0x01,
432*4882a593Smuzhiyun 0x41, 0x34, 0x07, 0x00};
433*4882a593Smuzhiyun int idr_pic_id = frame_num % 2;
434*4882a593Smuzhiyun enum hva_picture_coding_type type;
435*4882a593Smuzhiyun u32 frame_order = frame_num % ctrls->gop_size;
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun if (!(frame_num % ctrls->gop_size))
438*4882a593Smuzhiyun type = PICTURE_CODING_TYPE_I;
439*4882a593Smuzhiyun else
440*4882a593Smuzhiyun type = PICTURE_CODING_TYPE_P;
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun memcpy(slice_header_addr, slice_header, sizeof(slice_header));
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun *header_size = 56;
445*4882a593Smuzhiyun *header_offset0 = 40;
446*4882a593Smuzhiyun *header_offset1 = 13;
447*4882a593Smuzhiyun *header_offset2 = 0;
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun if (type == PICTURE_CODING_TYPE_I) {
450*4882a593Smuzhiyun slice_header_addr[4] = 0x65;
451*4882a593Smuzhiyun slice_header_addr[5] = 0x11;
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun /* toggle the I frame */
454*4882a593Smuzhiyun if ((frame_num / ctrls->gop_size) % 2) {
455*4882a593Smuzhiyun *header_size += 4;
456*4882a593Smuzhiyun *header_offset1 += 4;
457*4882a593Smuzhiyun slice_header_addr[6] = 0x04;
458*4882a593Smuzhiyun slice_header_addr[7] = 0x70;
459*4882a593Smuzhiyun
460*4882a593Smuzhiyun } else {
461*4882a593Smuzhiyun *header_size += 2;
462*4882a593Smuzhiyun *header_offset1 += 2;
463*4882a593Smuzhiyun slice_header_addr[6] = 0x09;
464*4882a593Smuzhiyun slice_header_addr[7] = 0xC0;
465*4882a593Smuzhiyun }
466*4882a593Smuzhiyun } else {
467*4882a593Smuzhiyun if (ctrls->entropy_mode == cabac) {
468*4882a593Smuzhiyun *header_size += 1;
469*4882a593Smuzhiyun *header_offset1 += 1;
470*4882a593Smuzhiyun slice_header_addr[7] = 0x80;
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun /*
473*4882a593Smuzhiyun * update slice header with P frame order
474*4882a593Smuzhiyun * frame order is limited to 16 (coded on 4bits only)
475*4882a593Smuzhiyun */
476*4882a593Smuzhiyun slice_header_addr[5] += ((frame_order & 0x0C) >> 2);
477*4882a593Smuzhiyun slice_header_addr[6] += ((frame_order & 0x03) << 6);
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun dev_dbg(dev,
481*4882a593Smuzhiyun "%s %s slice header order %d idrPicId %d header size %d\n",
482*4882a593Smuzhiyun pctx->name, __func__, frame_order, idr_pic_id, *header_size);
483*4882a593Smuzhiyun return 0;
484*4882a593Smuzhiyun }
485*4882a593Smuzhiyun
hva_h264_fill_data_nal(struct hva_ctx * pctx,unsigned int stuffing_bytes,u8 * addr,unsigned int stream_size,unsigned int * size)486*4882a593Smuzhiyun static int hva_h264_fill_data_nal(struct hva_ctx *pctx,
487*4882a593Smuzhiyun unsigned int stuffing_bytes, u8 *addr,
488*4882a593Smuzhiyun unsigned int stream_size, unsigned int *size)
489*4882a593Smuzhiyun {
490*4882a593Smuzhiyun struct device *dev = ctx_to_dev(pctx);
491*4882a593Smuzhiyun const u8 start[] = { 0x00, 0x00, 0x00, 0x01 };
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun dev_dbg(dev, "%s %s stuffing bytes %d\n", pctx->name, __func__,
494*4882a593Smuzhiyun stuffing_bytes);
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun if ((*size + stuffing_bytes + H264_FILLER_DATA_SIZE) > stream_size) {
497*4882a593Smuzhiyun dev_dbg(dev, "%s %s too many stuffing bytes %d\n",
498*4882a593Smuzhiyun pctx->name, __func__, stuffing_bytes);
499*4882a593Smuzhiyun return 0;
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun /* start code */
503*4882a593Smuzhiyun memcpy(addr + *size, start, sizeof(start));
504*4882a593Smuzhiyun *size += sizeof(start);
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun /* nal_unit_type */
507*4882a593Smuzhiyun addr[*size] = NALU_TYPE_FILLER_DATA;
508*4882a593Smuzhiyun *size += 1;
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun memset(addr + *size, 0xff, stuffing_bytes);
511*4882a593Smuzhiyun *size += stuffing_bytes;
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun addr[*size] = 0x80;
514*4882a593Smuzhiyun *size += 1;
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun return 0;
517*4882a593Smuzhiyun }
518*4882a593Smuzhiyun
hva_h264_fill_sei_nal(struct hva_ctx * pctx,enum hva_h264_sei_payload_type type,u8 * addr,u32 * size)519*4882a593Smuzhiyun static int hva_h264_fill_sei_nal(struct hva_ctx *pctx,
520*4882a593Smuzhiyun enum hva_h264_sei_payload_type type,
521*4882a593Smuzhiyun u8 *addr, u32 *size)
522*4882a593Smuzhiyun {
523*4882a593Smuzhiyun struct device *dev = ctx_to_dev(pctx);
524*4882a593Smuzhiyun const u8 start[] = { 0x00, 0x00, 0x00, 0x01 };
525*4882a593Smuzhiyun struct hva_h264_stereo_video_sei info;
526*4882a593Smuzhiyun u8 offset = 7;
527*4882a593Smuzhiyun u8 msg = 0;
528*4882a593Smuzhiyun
529*4882a593Smuzhiyun /* start code */
530*4882a593Smuzhiyun memcpy(addr + *size, start, sizeof(start));
531*4882a593Smuzhiyun *size += sizeof(start);
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun /* nal_unit_type */
534*4882a593Smuzhiyun addr[*size] = NALU_TYPE_SEI;
535*4882a593Smuzhiyun *size += 1;
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun /* payload type */
538*4882a593Smuzhiyun addr[*size] = type;
539*4882a593Smuzhiyun *size += 1;
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun switch (type) {
542*4882a593Smuzhiyun case SEI_STEREO_VIDEO_INFO:
543*4882a593Smuzhiyun memset(&info, 0, sizeof(info));
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun /* set to top/bottom frame packing arrangement */
546*4882a593Smuzhiyun info.field_views_flag = 1;
547*4882a593Smuzhiyun info.top_field_is_left_view_flag = 1;
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun /* payload size */
550*4882a593Smuzhiyun addr[*size] = 1;
551*4882a593Smuzhiyun *size += 1;
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun /* payload */
554*4882a593Smuzhiyun msg = info.field_views_flag << offset--;
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun if (info.field_views_flag) {
557*4882a593Smuzhiyun msg |= info.top_field_is_left_view_flag <<
558*4882a593Smuzhiyun offset--;
559*4882a593Smuzhiyun } else {
560*4882a593Smuzhiyun msg |= info.current_frame_is_left_view_flag <<
561*4882a593Smuzhiyun offset--;
562*4882a593Smuzhiyun msg |= info.next_frame_is_second_view_flag <<
563*4882a593Smuzhiyun offset--;
564*4882a593Smuzhiyun }
565*4882a593Smuzhiyun msg |= info.left_view_self_contained_flag << offset--;
566*4882a593Smuzhiyun msg |= info.right_view_self_contained_flag << offset--;
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun addr[*size] = msg;
569*4882a593Smuzhiyun *size += 1;
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun addr[*size] = 0x80;
572*4882a593Smuzhiyun *size += 1;
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun return 0;
575*4882a593Smuzhiyun case SEI_BUFFERING_PERIOD:
576*4882a593Smuzhiyun case SEI_PICTURE_TIMING:
577*4882a593Smuzhiyun case SEI_FRAME_PACKING_ARRANGEMENT:
578*4882a593Smuzhiyun default:
579*4882a593Smuzhiyun dev_err(dev, "%s sei nal type not supported %d\n",
580*4882a593Smuzhiyun pctx->name, type);
581*4882a593Smuzhiyun return -EINVAL;
582*4882a593Smuzhiyun }
583*4882a593Smuzhiyun }
584*4882a593Smuzhiyun
hva_h264_prepare_task(struct hva_ctx * pctx,struct hva_h264_task * task,struct hva_frame * frame,struct hva_stream * stream)585*4882a593Smuzhiyun static int hva_h264_prepare_task(struct hva_ctx *pctx,
586*4882a593Smuzhiyun struct hva_h264_task *task,
587*4882a593Smuzhiyun struct hva_frame *frame,
588*4882a593Smuzhiyun struct hva_stream *stream)
589*4882a593Smuzhiyun {
590*4882a593Smuzhiyun struct hva_dev *hva = ctx_to_hdev(pctx);
591*4882a593Smuzhiyun struct device *dev = ctx_to_dev(pctx);
592*4882a593Smuzhiyun struct hva_h264_ctx *ctx = (struct hva_h264_ctx *)pctx->priv;
593*4882a593Smuzhiyun struct hva_buffer *seq_info = ctx->seq_info;
594*4882a593Smuzhiyun struct hva_buffer *fwd_ref_frame = ctx->ref_frame;
595*4882a593Smuzhiyun struct hva_buffer *loc_rec_frame = ctx->rec_frame;
596*4882a593Smuzhiyun struct hva_h264_td *td = &task->td;
597*4882a593Smuzhiyun struct hva_controls *ctrls = &pctx->ctrls;
598*4882a593Smuzhiyun struct v4l2_fract *time_per_frame = &pctx->ctrls.time_per_frame;
599*4882a593Smuzhiyun int cavlc = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
600*4882a593Smuzhiyun u32 frame_num = pctx->stream_num;
601*4882a593Smuzhiyun u32 addr_esram = hva->esram_addr;
602*4882a593Smuzhiyun enum v4l2_mpeg_video_h264_level level;
603*4882a593Smuzhiyun dma_addr_t paddr = 0;
604*4882a593Smuzhiyun u8 *slice_header_vaddr;
605*4882a593Smuzhiyun u32 frame_width = frame->info.aligned_width;
606*4882a593Smuzhiyun u32 frame_height = frame->info.aligned_height;
607*4882a593Smuzhiyun u32 max_cpb_buffer_size;
608*4882a593Smuzhiyun unsigned int payload = stream->bytesused;
609*4882a593Smuzhiyun u32 max_bitrate;
610*4882a593Smuzhiyun
611*4882a593Smuzhiyun /* check width and height parameters */
612*4882a593Smuzhiyun if ((frame_width > max(H264_MAX_SIZE_W, H264_MAX_SIZE_H)) ||
613*4882a593Smuzhiyun (frame_height > max(H264_MAX_SIZE_W, H264_MAX_SIZE_H))) {
614*4882a593Smuzhiyun dev_err(dev,
615*4882a593Smuzhiyun "%s width(%d) or height(%d) exceeds limits (%dx%d)\n",
616*4882a593Smuzhiyun pctx->name, frame_width, frame_height,
617*4882a593Smuzhiyun H264_MAX_SIZE_W, H264_MAX_SIZE_H);
618*4882a593Smuzhiyun pctx->frame_errors++;
619*4882a593Smuzhiyun return -EINVAL;
620*4882a593Smuzhiyun }
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun level = ctrls->level;
623*4882a593Smuzhiyun
624*4882a593Smuzhiyun memset(td, 0, sizeof(struct hva_h264_td));
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun td->frame_width = frame_width;
627*4882a593Smuzhiyun td->frame_height = frame_height;
628*4882a593Smuzhiyun
629*4882a593Smuzhiyun /* set frame alignment */
630*4882a593Smuzhiyun td->window_width = frame_width;
631*4882a593Smuzhiyun td->window_height = frame_height;
632*4882a593Smuzhiyun td->window_horizontal_offset = 0;
633*4882a593Smuzhiyun td->window_vertical_offset = 0;
634*4882a593Smuzhiyun
635*4882a593Smuzhiyun td->first_picture_in_sequence = (!frame_num) ? 1 : 0;
636*4882a593Smuzhiyun
637*4882a593Smuzhiyun /* pic_order_cnt_type hard coded to '2' as only I & P frames */
638*4882a593Smuzhiyun td->pic_order_cnt_type = 2;
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun /* useConstrainedIntraFlag set to false for better coding efficiency */
641*4882a593Smuzhiyun td->use_constrained_intra_flag = false;
642*4882a593Smuzhiyun td->brc_type = (ctrls->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
643*4882a593Smuzhiyun ? BRC_TYPE_CBR : BRC_TYPE_VBR;
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun td->entropy_coding_mode = (ctrls->entropy_mode == cavlc) ? CAVLC :
646*4882a593Smuzhiyun CABAC;
647*4882a593Smuzhiyun
648*4882a593Smuzhiyun td->bit_rate = ctrls->bitrate;
649*4882a593Smuzhiyun
650*4882a593Smuzhiyun /* set framerate, framerate = 1 n/ time per frame */
651*4882a593Smuzhiyun if (time_per_frame->numerator >= 536) {
652*4882a593Smuzhiyun /*
653*4882a593Smuzhiyun * due to a hardware bug, framerate denominator can't exceed
654*4882a593Smuzhiyun * 536 (BRC overflow). Compute nearest framerate
655*4882a593Smuzhiyun */
656*4882a593Smuzhiyun td->framerate_den = 1;
657*4882a593Smuzhiyun td->framerate_num = (time_per_frame->denominator +
658*4882a593Smuzhiyun (time_per_frame->numerator >> 1) - 1) /
659*4882a593Smuzhiyun time_per_frame->numerator;
660*4882a593Smuzhiyun
661*4882a593Smuzhiyun /*
662*4882a593Smuzhiyun * update bitrate to introduce a correction due to
663*4882a593Smuzhiyun * the new framerate
664*4882a593Smuzhiyun * new bitrate = (old bitrate * new framerate) / old framerate
665*4882a593Smuzhiyun */
666*4882a593Smuzhiyun td->bit_rate /= time_per_frame->numerator;
667*4882a593Smuzhiyun td->bit_rate *= time_per_frame->denominator;
668*4882a593Smuzhiyun td->bit_rate /= td->framerate_num;
669*4882a593Smuzhiyun } else {
670*4882a593Smuzhiyun td->framerate_den = time_per_frame->numerator;
671*4882a593Smuzhiyun td->framerate_num = time_per_frame->denominator;
672*4882a593Smuzhiyun }
673*4882a593Smuzhiyun
674*4882a593Smuzhiyun /* compute maximum bitrate depending on profile */
675*4882a593Smuzhiyun if (ctrls->profile >= V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)
676*4882a593Smuzhiyun max_bitrate = h264_infos_list[level].max_bitrate *
677*4882a593Smuzhiyun H264_FACTOR_HIGH;
678*4882a593Smuzhiyun else
679*4882a593Smuzhiyun max_bitrate = h264_infos_list[level].max_bitrate *
680*4882a593Smuzhiyun H264_FACTOR_BASELINE;
681*4882a593Smuzhiyun
682*4882a593Smuzhiyun /* check if bitrate doesn't exceed max size */
683*4882a593Smuzhiyun if (td->bit_rate > max_bitrate) {
684*4882a593Smuzhiyun dev_dbg(dev,
685*4882a593Smuzhiyun "%s bitrate (%d) larger than level and profile allow, clip to %d\n",
686*4882a593Smuzhiyun pctx->name, td->bit_rate, max_bitrate);
687*4882a593Smuzhiyun td->bit_rate = max_bitrate;
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun /* convert cpb_buffer_size in bits */
691*4882a593Smuzhiyun td->cpb_buffer_size = ctrls->cpb_size * 8000;
692*4882a593Smuzhiyun
693*4882a593Smuzhiyun /* compute maximum cpb buffer size depending on profile */
694*4882a593Smuzhiyun if (ctrls->profile >= V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)
695*4882a593Smuzhiyun max_cpb_buffer_size =
696*4882a593Smuzhiyun h264_infos_list[level].max_cpb_size * H264_FACTOR_HIGH;
697*4882a593Smuzhiyun else
698*4882a593Smuzhiyun max_cpb_buffer_size =
699*4882a593Smuzhiyun h264_infos_list[level].max_cpb_size * H264_FACTOR_BASELINE;
700*4882a593Smuzhiyun
701*4882a593Smuzhiyun /* check if cpb buffer size doesn't exceed max size */
702*4882a593Smuzhiyun if (td->cpb_buffer_size > max_cpb_buffer_size) {
703*4882a593Smuzhiyun dev_dbg(dev,
704*4882a593Smuzhiyun "%s cpb size larger than level %d allows, clip to %d\n",
705*4882a593Smuzhiyun pctx->name, td->cpb_buffer_size, max_cpb_buffer_size);
706*4882a593Smuzhiyun td->cpb_buffer_size = max_cpb_buffer_size;
707*4882a593Smuzhiyun }
708*4882a593Smuzhiyun
709*4882a593Smuzhiyun /* enable skipping in the Bitrate Controller */
710*4882a593Smuzhiyun td->brc_no_skip = 0;
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun /* initial delay */
713*4882a593Smuzhiyun if ((ctrls->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) &&
714*4882a593Smuzhiyun td->bit_rate)
715*4882a593Smuzhiyun td->delay = 1000 * (td->cpb_buffer_size / td->bit_rate);
716*4882a593Smuzhiyun else
717*4882a593Smuzhiyun td->delay = 0;
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun switch (frame->info.pixelformat) {
720*4882a593Smuzhiyun case V4L2_PIX_FMT_NV12:
721*4882a593Smuzhiyun td->sampling_mode = SAMPLING_MODE_NV12;
722*4882a593Smuzhiyun break;
723*4882a593Smuzhiyun case V4L2_PIX_FMT_NV21:
724*4882a593Smuzhiyun td->sampling_mode = SAMPLING_MODE_NV21;
725*4882a593Smuzhiyun break;
726*4882a593Smuzhiyun default:
727*4882a593Smuzhiyun dev_err(dev, "%s invalid source pixel format\n",
728*4882a593Smuzhiyun pctx->name);
729*4882a593Smuzhiyun pctx->frame_errors++;
730*4882a593Smuzhiyun return -EINVAL;
731*4882a593Smuzhiyun }
732*4882a593Smuzhiyun
733*4882a593Smuzhiyun /*
734*4882a593Smuzhiyun * fill matrix color converter (RGB to YUV)
735*4882a593Smuzhiyun * Y = 0,299 R + 0,587 G + 0,114 B
736*4882a593Smuzhiyun * Cb = -0,1687 R -0,3313 G + 0,5 B + 128
737*4882a593Smuzhiyun * Cr = 0,5 R - 0,4187 G - 0,0813 B + 128
738*4882a593Smuzhiyun */
739*4882a593Smuzhiyun td->rgb2_yuv_y_coeff = 0x12031008;
740*4882a593Smuzhiyun td->rgb2_yuv_u_coeff = 0x800EF7FB;
741*4882a593Smuzhiyun td->rgb2_yuv_v_coeff = 0x80FEF40E;
742*4882a593Smuzhiyun
743*4882a593Smuzhiyun /* enable/disable transform mode */
744*4882a593Smuzhiyun td->transform_mode = ctrls->dct8x8;
745*4882a593Smuzhiyun
746*4882a593Smuzhiyun /* encoder complexity fix to 2, ENCODE_I_16x16_I_NxN_P_16x16_P_WxH */
747*4882a593Smuzhiyun td->encoder_complexity = 2;
748*4882a593Smuzhiyun
749*4882a593Smuzhiyun /* quant fix to 28, default VBR value */
750*4882a593Smuzhiyun td->quant = 28;
751*4882a593Smuzhiyun
752*4882a593Smuzhiyun if (td->framerate_den == 0) {
753*4882a593Smuzhiyun dev_err(dev, "%s invalid framerate\n", pctx->name);
754*4882a593Smuzhiyun pctx->frame_errors++;
755*4882a593Smuzhiyun return -EINVAL;
756*4882a593Smuzhiyun }
757*4882a593Smuzhiyun
758*4882a593Smuzhiyun /* if automatic framerate, deactivate bitrate controller */
759*4882a593Smuzhiyun if (td->framerate_num == 0)
760*4882a593Smuzhiyun td->brc_type = 0;
761*4882a593Smuzhiyun
762*4882a593Smuzhiyun /* compliancy fix to true */
763*4882a593Smuzhiyun td->strict_hrd_compliancy = 1;
764*4882a593Smuzhiyun
765*4882a593Smuzhiyun /* set minimum & maximum quantizers */
766*4882a593Smuzhiyun td->qp_min = clamp_val(ctrls->qpmin, 0, 51);
767*4882a593Smuzhiyun td->qp_max = clamp_val(ctrls->qpmax, 0, 51);
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun td->addr_source_buffer = frame->paddr;
770*4882a593Smuzhiyun td->addr_fwd_ref_buffer = fwd_ref_frame->paddr;
771*4882a593Smuzhiyun td->addr_rec_buffer = loc_rec_frame->paddr;
772*4882a593Smuzhiyun
773*4882a593Smuzhiyun td->addr_output_bitstream_end = (u32)stream->paddr + stream->size;
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun td->addr_output_bitstream_start = (u32)stream->paddr;
776*4882a593Smuzhiyun td->bitstream_offset = (((u32)stream->paddr & 0xF) << 3) &
777*4882a593Smuzhiyun BITSTREAM_OFFSET_MASK;
778*4882a593Smuzhiyun
779*4882a593Smuzhiyun td->addr_param_out = (u32)ctx->task->paddr +
780*4882a593Smuzhiyun offsetof(struct hva_h264_task, po);
781*4882a593Smuzhiyun
782*4882a593Smuzhiyun /* swap spatial and temporal context */
783*4882a593Smuzhiyun if (frame_num % 2) {
784*4882a593Smuzhiyun paddr = seq_info->paddr;
785*4882a593Smuzhiyun td->addr_spatial_context = ALIGN(paddr, 0x100);
786*4882a593Smuzhiyun paddr = seq_info->paddr + DATA_SIZE(frame_width,
787*4882a593Smuzhiyun frame_height);
788*4882a593Smuzhiyun td->addr_temporal_context = ALIGN(paddr, 0x100);
789*4882a593Smuzhiyun } else {
790*4882a593Smuzhiyun paddr = seq_info->paddr;
791*4882a593Smuzhiyun td->addr_temporal_context = ALIGN(paddr, 0x100);
792*4882a593Smuzhiyun paddr = seq_info->paddr + DATA_SIZE(frame_width,
793*4882a593Smuzhiyun frame_height);
794*4882a593Smuzhiyun td->addr_spatial_context = ALIGN(paddr, 0x100);
795*4882a593Smuzhiyun }
796*4882a593Smuzhiyun
797*4882a593Smuzhiyun paddr = seq_info->paddr + 2 * DATA_SIZE(frame_width, frame_height);
798*4882a593Smuzhiyun
799*4882a593Smuzhiyun td->addr_brc_in_out_parameter = ALIGN(paddr, 0x100);
800*4882a593Smuzhiyun
801*4882a593Smuzhiyun paddr = td->addr_brc_in_out_parameter + BRC_DATA_SIZE;
802*4882a593Smuzhiyun td->addr_slice_header = ALIGN(paddr, 0x100);
803*4882a593Smuzhiyun td->addr_external_sw = ALIGN(addr_esram, 0x100);
804*4882a593Smuzhiyun
805*4882a593Smuzhiyun addr_esram += SEARCH_WINDOW_BUFFER_MAX_SIZE(frame_width);
806*4882a593Smuzhiyun td->addr_local_rec_buffer = ALIGN(addr_esram, 0x100);
807*4882a593Smuzhiyun
808*4882a593Smuzhiyun addr_esram += LOCAL_RECONSTRUCTED_BUFFER_MAX_SIZE(frame_width);
809*4882a593Smuzhiyun td->addr_lctx = ALIGN(addr_esram, 0x100);
810*4882a593Smuzhiyun
811*4882a593Smuzhiyun addr_esram += CTX_MB_BUFFER_MAX_SIZE(max(frame_width, frame_height));
812*4882a593Smuzhiyun td->addr_cabac_context_buffer = ALIGN(addr_esram, 0x100);
813*4882a593Smuzhiyun
814*4882a593Smuzhiyun if (!(frame_num % ctrls->gop_size)) {
815*4882a593Smuzhiyun td->picture_coding_type = PICTURE_CODING_TYPE_I;
816*4882a593Smuzhiyun stream->vbuf.flags |= V4L2_BUF_FLAG_KEYFRAME;
817*4882a593Smuzhiyun } else {
818*4882a593Smuzhiyun td->picture_coding_type = PICTURE_CODING_TYPE_P;
819*4882a593Smuzhiyun stream->vbuf.flags &= ~V4L2_BUF_FLAG_KEYFRAME;
820*4882a593Smuzhiyun }
821*4882a593Smuzhiyun
822*4882a593Smuzhiyun /* fill the slice header part */
823*4882a593Smuzhiyun slice_header_vaddr = seq_info->vaddr + (td->addr_slice_header -
824*4882a593Smuzhiyun seq_info->paddr);
825*4882a593Smuzhiyun
826*4882a593Smuzhiyun hva_h264_fill_slice_header(pctx, slice_header_vaddr, ctrls, frame_num,
827*4882a593Smuzhiyun &td->slice_header_size_in_bits,
828*4882a593Smuzhiyun &td->slice_header_offset0,
829*4882a593Smuzhiyun &td->slice_header_offset1,
830*4882a593Smuzhiyun &td->slice_header_offset2);
831*4882a593Smuzhiyun
832*4882a593Smuzhiyun td->chroma_qp_index_offset = 2;
833*4882a593Smuzhiyun td->slice_synchro_enable = 0;
834*4882a593Smuzhiyun td->max_slice_number = 1;
835*4882a593Smuzhiyun
836*4882a593Smuzhiyun /*
837*4882a593Smuzhiyun * check the sps/pps header size for key frame only
838*4882a593Smuzhiyun * sps/pps header was previously fill by libv4l
839*4882a593Smuzhiyun * during qbuf of stream buffer
840*4882a593Smuzhiyun */
841*4882a593Smuzhiyun if ((stream->vbuf.flags == V4L2_BUF_FLAG_KEYFRAME) &&
842*4882a593Smuzhiyun (payload > MAX_SPS_PPS_SIZE)) {
843*4882a593Smuzhiyun dev_err(dev, "%s invalid sps/pps size %d\n", pctx->name,
844*4882a593Smuzhiyun payload);
845*4882a593Smuzhiyun pctx->frame_errors++;
846*4882a593Smuzhiyun return -EINVAL;
847*4882a593Smuzhiyun }
848*4882a593Smuzhiyun
849*4882a593Smuzhiyun if (stream->vbuf.flags != V4L2_BUF_FLAG_KEYFRAME)
850*4882a593Smuzhiyun payload = 0;
851*4882a593Smuzhiyun
852*4882a593Smuzhiyun /* add SEI nal (video stereo info) */
853*4882a593Smuzhiyun if (ctrls->sei_fp && hva_h264_fill_sei_nal(pctx, SEI_STEREO_VIDEO_INFO,
854*4882a593Smuzhiyun (u8 *)stream->vaddr,
855*4882a593Smuzhiyun &payload)) {
856*4882a593Smuzhiyun dev_err(dev, "%s fail to get SEI nal\n", pctx->name);
857*4882a593Smuzhiyun pctx->frame_errors++;
858*4882a593Smuzhiyun return -EINVAL;
859*4882a593Smuzhiyun }
860*4882a593Smuzhiyun
861*4882a593Smuzhiyun /* fill size of non-VCL NAL units (SPS, PPS, filler and SEI) */
862*4882a593Smuzhiyun td->non_vcl_nalu_size = payload * 8;
863*4882a593Smuzhiyun
864*4882a593Smuzhiyun /* compute bitstream offset & new start address of bitstream */
865*4882a593Smuzhiyun td->addr_output_bitstream_start += ((payload >> 4) << 4);
866*4882a593Smuzhiyun td->bitstream_offset += (payload - ((payload >> 4) << 4)) * 8;
867*4882a593Smuzhiyun
868*4882a593Smuzhiyun stream->bytesused = payload;
869*4882a593Smuzhiyun
870*4882a593Smuzhiyun return 0;
871*4882a593Smuzhiyun }
872*4882a593Smuzhiyun
hva_h264_get_stream_size(struct hva_h264_task * task)873*4882a593Smuzhiyun static unsigned int hva_h264_get_stream_size(struct hva_h264_task *task)
874*4882a593Smuzhiyun {
875*4882a593Smuzhiyun struct hva_h264_po *po = &task->po;
876*4882a593Smuzhiyun
877*4882a593Smuzhiyun return po->bitstream_size;
878*4882a593Smuzhiyun }
879*4882a593Smuzhiyun
hva_h264_get_stuffing_bytes(struct hva_h264_task * task)880*4882a593Smuzhiyun static u32 hva_h264_get_stuffing_bytes(struct hva_h264_task *task)
881*4882a593Smuzhiyun {
882*4882a593Smuzhiyun struct hva_h264_po *po = &task->po;
883*4882a593Smuzhiyun
884*4882a593Smuzhiyun return po->stuffing_bits >> 3;
885*4882a593Smuzhiyun }
886*4882a593Smuzhiyun
hva_h264_open(struct hva_ctx * pctx)887*4882a593Smuzhiyun static int hva_h264_open(struct hva_ctx *pctx)
888*4882a593Smuzhiyun {
889*4882a593Smuzhiyun struct device *dev = ctx_to_dev(pctx);
890*4882a593Smuzhiyun struct hva_h264_ctx *ctx;
891*4882a593Smuzhiyun struct hva_dev *hva = ctx_to_hdev(pctx);
892*4882a593Smuzhiyun u32 frame_width = pctx->frameinfo.aligned_width;
893*4882a593Smuzhiyun u32 frame_height = pctx->frameinfo.aligned_height;
894*4882a593Smuzhiyun u32 size;
895*4882a593Smuzhiyun int ret;
896*4882a593Smuzhiyun
897*4882a593Smuzhiyun /* check esram size necessary to encode a frame */
898*4882a593Smuzhiyun size = SEARCH_WINDOW_BUFFER_MAX_SIZE(frame_width) +
899*4882a593Smuzhiyun LOCAL_RECONSTRUCTED_BUFFER_MAX_SIZE(frame_width) +
900*4882a593Smuzhiyun CTX_MB_BUFFER_MAX_SIZE(max(frame_width, frame_height)) +
901*4882a593Smuzhiyun CABAC_CONTEXT_BUFFER_MAX_SIZE(frame_width);
902*4882a593Smuzhiyun
903*4882a593Smuzhiyun if (hva->esram_size < size) {
904*4882a593Smuzhiyun dev_err(dev, "%s not enough esram (max:%d request:%d)\n",
905*4882a593Smuzhiyun pctx->name, hva->esram_size, size);
906*4882a593Smuzhiyun ret = -EINVAL;
907*4882a593Smuzhiyun goto err;
908*4882a593Smuzhiyun }
909*4882a593Smuzhiyun
910*4882a593Smuzhiyun /* allocate context for codec */
911*4882a593Smuzhiyun ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
912*4882a593Smuzhiyun if (!ctx) {
913*4882a593Smuzhiyun ret = -ENOMEM;
914*4882a593Smuzhiyun goto err;
915*4882a593Smuzhiyun }
916*4882a593Smuzhiyun
917*4882a593Smuzhiyun /* allocate sequence info buffer */
918*4882a593Smuzhiyun ret = hva_mem_alloc(pctx,
919*4882a593Smuzhiyun 2 * DATA_SIZE(frame_width, frame_height) +
920*4882a593Smuzhiyun SLICE_HEADER_SIZE +
921*4882a593Smuzhiyun BRC_DATA_SIZE,
922*4882a593Smuzhiyun "hva sequence info",
923*4882a593Smuzhiyun &ctx->seq_info);
924*4882a593Smuzhiyun if (ret) {
925*4882a593Smuzhiyun dev_err(dev,
926*4882a593Smuzhiyun "%s failed to allocate sequence info buffer\n",
927*4882a593Smuzhiyun pctx->name);
928*4882a593Smuzhiyun goto err_ctx;
929*4882a593Smuzhiyun }
930*4882a593Smuzhiyun
931*4882a593Smuzhiyun /* allocate reference frame buffer */
932*4882a593Smuzhiyun ret = hva_mem_alloc(pctx,
933*4882a593Smuzhiyun frame_width * frame_height * 3 / 2,
934*4882a593Smuzhiyun "hva reference frame",
935*4882a593Smuzhiyun &ctx->ref_frame);
936*4882a593Smuzhiyun if (ret) {
937*4882a593Smuzhiyun dev_err(dev, "%s failed to allocate reference frame buffer\n",
938*4882a593Smuzhiyun pctx->name);
939*4882a593Smuzhiyun goto err_seq_info;
940*4882a593Smuzhiyun }
941*4882a593Smuzhiyun
942*4882a593Smuzhiyun /* allocate reconstructed frame buffer */
943*4882a593Smuzhiyun ret = hva_mem_alloc(pctx,
944*4882a593Smuzhiyun frame_width * frame_height * 3 / 2,
945*4882a593Smuzhiyun "hva reconstructed frame",
946*4882a593Smuzhiyun &ctx->rec_frame);
947*4882a593Smuzhiyun if (ret) {
948*4882a593Smuzhiyun dev_err(dev,
949*4882a593Smuzhiyun "%s failed to allocate reconstructed frame buffer\n",
950*4882a593Smuzhiyun pctx->name);
951*4882a593Smuzhiyun goto err_ref_frame;
952*4882a593Smuzhiyun }
953*4882a593Smuzhiyun
954*4882a593Smuzhiyun /* allocate task descriptor */
955*4882a593Smuzhiyun ret = hva_mem_alloc(pctx,
956*4882a593Smuzhiyun sizeof(struct hva_h264_task),
957*4882a593Smuzhiyun "hva task descriptor",
958*4882a593Smuzhiyun &ctx->task);
959*4882a593Smuzhiyun if (ret) {
960*4882a593Smuzhiyun dev_err(dev,
961*4882a593Smuzhiyun "%s failed to allocate task descriptor\n",
962*4882a593Smuzhiyun pctx->name);
963*4882a593Smuzhiyun goto err_rec_frame;
964*4882a593Smuzhiyun }
965*4882a593Smuzhiyun
966*4882a593Smuzhiyun pctx->priv = (void *)ctx;
967*4882a593Smuzhiyun
968*4882a593Smuzhiyun return 0;
969*4882a593Smuzhiyun
970*4882a593Smuzhiyun err_rec_frame:
971*4882a593Smuzhiyun hva_mem_free(pctx, ctx->rec_frame);
972*4882a593Smuzhiyun err_ref_frame:
973*4882a593Smuzhiyun hva_mem_free(pctx, ctx->ref_frame);
974*4882a593Smuzhiyun err_seq_info:
975*4882a593Smuzhiyun hva_mem_free(pctx, ctx->seq_info);
976*4882a593Smuzhiyun err_ctx:
977*4882a593Smuzhiyun devm_kfree(dev, ctx);
978*4882a593Smuzhiyun err:
979*4882a593Smuzhiyun pctx->sys_errors++;
980*4882a593Smuzhiyun return ret;
981*4882a593Smuzhiyun }
982*4882a593Smuzhiyun
hva_h264_close(struct hva_ctx * pctx)983*4882a593Smuzhiyun static int hva_h264_close(struct hva_ctx *pctx)
984*4882a593Smuzhiyun {
985*4882a593Smuzhiyun struct hva_h264_ctx *ctx = (struct hva_h264_ctx *)pctx->priv;
986*4882a593Smuzhiyun struct device *dev = ctx_to_dev(pctx);
987*4882a593Smuzhiyun
988*4882a593Smuzhiyun if (ctx->seq_info)
989*4882a593Smuzhiyun hva_mem_free(pctx, ctx->seq_info);
990*4882a593Smuzhiyun
991*4882a593Smuzhiyun if (ctx->ref_frame)
992*4882a593Smuzhiyun hva_mem_free(pctx, ctx->ref_frame);
993*4882a593Smuzhiyun
994*4882a593Smuzhiyun if (ctx->rec_frame)
995*4882a593Smuzhiyun hva_mem_free(pctx, ctx->rec_frame);
996*4882a593Smuzhiyun
997*4882a593Smuzhiyun if (ctx->task)
998*4882a593Smuzhiyun hva_mem_free(pctx, ctx->task);
999*4882a593Smuzhiyun
1000*4882a593Smuzhiyun devm_kfree(dev, ctx);
1001*4882a593Smuzhiyun
1002*4882a593Smuzhiyun return 0;
1003*4882a593Smuzhiyun }
1004*4882a593Smuzhiyun
hva_h264_encode(struct hva_ctx * pctx,struct hva_frame * frame,struct hva_stream * stream)1005*4882a593Smuzhiyun static int hva_h264_encode(struct hva_ctx *pctx, struct hva_frame *frame,
1006*4882a593Smuzhiyun struct hva_stream *stream)
1007*4882a593Smuzhiyun {
1008*4882a593Smuzhiyun struct hva_h264_ctx *ctx = (struct hva_h264_ctx *)pctx->priv;
1009*4882a593Smuzhiyun struct hva_h264_task *task = (struct hva_h264_task *)ctx->task->vaddr;
1010*4882a593Smuzhiyun u32 stuffing_bytes = 0;
1011*4882a593Smuzhiyun int ret = 0;
1012*4882a593Smuzhiyun
1013*4882a593Smuzhiyun ret = hva_h264_prepare_task(pctx, task, frame, stream);
1014*4882a593Smuzhiyun if (ret)
1015*4882a593Smuzhiyun goto err;
1016*4882a593Smuzhiyun
1017*4882a593Smuzhiyun ret = hva_hw_execute_task(pctx, H264_ENC, ctx->task);
1018*4882a593Smuzhiyun if (ret)
1019*4882a593Smuzhiyun goto err;
1020*4882a593Smuzhiyun
1021*4882a593Smuzhiyun pctx->stream_num++;
1022*4882a593Smuzhiyun stream->bytesused += hva_h264_get_stream_size(task);
1023*4882a593Smuzhiyun
1024*4882a593Smuzhiyun stuffing_bytes = hva_h264_get_stuffing_bytes(task);
1025*4882a593Smuzhiyun
1026*4882a593Smuzhiyun if (stuffing_bytes)
1027*4882a593Smuzhiyun hva_h264_fill_data_nal(pctx, stuffing_bytes,
1028*4882a593Smuzhiyun (u8 *)stream->vaddr,
1029*4882a593Smuzhiyun stream->size,
1030*4882a593Smuzhiyun &stream->bytesused);
1031*4882a593Smuzhiyun
1032*4882a593Smuzhiyun /* switch reference & reconstructed frame */
1033*4882a593Smuzhiyun swap(ctx->ref_frame, ctx->rec_frame);
1034*4882a593Smuzhiyun
1035*4882a593Smuzhiyun return 0;
1036*4882a593Smuzhiyun err:
1037*4882a593Smuzhiyun stream->bytesused = 0;
1038*4882a593Smuzhiyun return ret;
1039*4882a593Smuzhiyun }
1040*4882a593Smuzhiyun
1041*4882a593Smuzhiyun const struct hva_enc nv12h264enc = {
1042*4882a593Smuzhiyun .name = "H264(NV12)",
1043*4882a593Smuzhiyun .pixelformat = V4L2_PIX_FMT_NV12,
1044*4882a593Smuzhiyun .streamformat = V4L2_PIX_FMT_H264,
1045*4882a593Smuzhiyun .max_width = H264_MAX_SIZE_W,
1046*4882a593Smuzhiyun .max_height = H264_MAX_SIZE_H,
1047*4882a593Smuzhiyun .open = hva_h264_open,
1048*4882a593Smuzhiyun .close = hva_h264_close,
1049*4882a593Smuzhiyun .encode = hva_h264_encode,
1050*4882a593Smuzhiyun };
1051*4882a593Smuzhiyun
1052*4882a593Smuzhiyun const struct hva_enc nv21h264enc = {
1053*4882a593Smuzhiyun .name = "H264(NV21)",
1054*4882a593Smuzhiyun .pixelformat = V4L2_PIX_FMT_NV21,
1055*4882a593Smuzhiyun .streamformat = V4L2_PIX_FMT_H264,
1056*4882a593Smuzhiyun .max_width = H264_MAX_SIZE_W,
1057*4882a593Smuzhiyun .max_height = H264_MAX_SIZE_H,
1058*4882a593Smuzhiyun .open = hva_h264_open,
1059*4882a593Smuzhiyun .close = hva_h264_close,
1060*4882a593Smuzhiyun .encode = hva_h264_encode,
1061*4882a593Smuzhiyun };
1062