1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Coda multi-standard codec IP - H.264 helper functions
5 * Copyright (C) 2012 Vista Silicon S.L.
6 * Javier Martin, <javier.martin@vista-silicon.com>
10 #include <linux/kernel.h>
11 #include <linux/string.h>
12 #include <linux/videodev2.h>
16 static const u8 coda_filler_size
[8] = { 0, 7, 14, 13, 12, 11, 10, 9 };
18 static const u8
*coda_find_nal_header(const u8
*buf
, const u8
*end
)
23 val
= val
<< 8 | *buf
++;
26 } while (val
!= 0x00000001);
31 int coda_sps_parse_profile(struct coda_ctx
*ctx
, struct vb2_buffer
*vb
)
33 const u8
*buf
= vb2_plane_vaddr(vb
, 0);
34 const u8
*end
= buf
+ vb2_get_plane_payload(vb
, 0);
38 buf
= coda_find_nal_header(buf
, end
);
41 } while ((*buf
++ & 0x1f) != 0x7);
43 ctx
->params
.h264_profile_idc
= buf
[0];
44 ctx
->params
.h264_level_idc
= buf
[2];
49 int coda_h264_filler_nal(int size
, char *p
)
59 memset(p
+ 5, 0xff, size
- 6);
60 /* Add rbsp stop bit and trailing at the end */
66 int coda_h264_padding(int size
, char *p
)
71 diff
= size
- (size
& ~0x7);
75 nal_size
= coda_filler_size
[diff
];
76 coda_h264_filler_nal(nal_size
, p
);
81 int coda_h264_profile(int profile_idc
)
83 switch (profile_idc
) {
84 case 66: return V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE
;
85 case 77: return V4L2_MPEG_VIDEO_H264_PROFILE_MAIN
;
86 case 88: return V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED
;
87 case 100: return V4L2_MPEG_VIDEO_H264_PROFILE_HIGH
;
88 default: return -EINVAL
;
92 int coda_h264_level(int level_idc
)
95 case 10: return V4L2_MPEG_VIDEO_H264_LEVEL_1_0
;
96 case 9: return V4L2_MPEG_VIDEO_H264_LEVEL_1B
;
97 case 11: return V4L2_MPEG_VIDEO_H264_LEVEL_1_1
;
98 case 12: return V4L2_MPEG_VIDEO_H264_LEVEL_1_2
;
99 case 13: return V4L2_MPEG_VIDEO_H264_LEVEL_1_3
;
100 case 20: return V4L2_MPEG_VIDEO_H264_LEVEL_2_0
;
101 case 21: return V4L2_MPEG_VIDEO_H264_LEVEL_2_1
;
102 case 22: return V4L2_MPEG_VIDEO_H264_LEVEL_2_2
;
103 case 30: return V4L2_MPEG_VIDEO_H264_LEVEL_3_0
;
104 case 31: return V4L2_MPEG_VIDEO_H264_LEVEL_3_1
;
105 case 32: return V4L2_MPEG_VIDEO_H264_LEVEL_3_2
;
106 case 40: return V4L2_MPEG_VIDEO_H264_LEVEL_4_0
;
107 case 41: return V4L2_MPEG_VIDEO_H264_LEVEL_4_1
;
108 case 42: return V4L2_MPEG_VIDEO_H264_LEVEL_4_2
;
109 case 50: return V4L2_MPEG_VIDEO_H264_LEVEL_5_0
;
110 case 51: return V4L2_MPEG_VIDEO_H264_LEVEL_5_1
;
111 default: return -EINVAL
;
121 static inline int rbsp_read_bit(struct rbsp
*rbsp
)
123 int shift
= 7 - (rbsp
->pos
% 8);
124 int ofs
= rbsp
->pos
++ / 8;
126 if (ofs
>= rbsp
->size
)
129 return (rbsp
->buf
[ofs
] >> shift
) & 1;
132 static inline int rbsp_write_bit(struct rbsp
*rbsp
, int bit
)
134 int shift
= 7 - (rbsp
->pos
% 8);
135 int ofs
= rbsp
->pos
++ / 8;
137 if (ofs
>= rbsp
->size
)
140 rbsp
->buf
[ofs
] &= ~(1 << shift
);
141 rbsp
->buf
[ofs
] |= bit
<< shift
;
146 static inline int rbsp_read_bits(struct rbsp
*rbsp
, int num
, int *val
)
154 for (i
= 0; i
< num
; i
++) {
155 ret
= rbsp_read_bit(rbsp
);
158 tmp
|= ret
<< (num
- i
- 1);
167 static int rbsp_write_bits(struct rbsp
*rbsp
, int num
, int value
)
172 ret
= rbsp_write_bit(rbsp
, (value
>> num
) & 1);
180 static int rbsp_read_uev(struct rbsp
*rbsp
, unsigned int *val
)
182 int leading_zero_bits
= 0;
183 unsigned int tmp
= 0;
186 while ((ret
= rbsp_read_bit(rbsp
)) == 0)
191 if (leading_zero_bits
> 0) {
192 ret
= rbsp_read_bits(rbsp
, leading_zero_bits
, &tmp
);
198 *val
= (1 << leading_zero_bits
) - 1 + tmp
;
203 static int rbsp_write_uev(struct rbsp
*rbsp
, unsigned int value
)
208 int leading_zero_bits
= fls(tmp
) - 1;
210 for (i
= 0; i
< leading_zero_bits
; i
++) {
211 ret
= rbsp_write_bit(rbsp
, 0);
216 return rbsp_write_bits(rbsp
, leading_zero_bits
+ 1, tmp
);
219 static int rbsp_read_sev(struct rbsp
*rbsp
, int *val
)
224 ret
= rbsp_read_uev(rbsp
, &tmp
);
230 *val
= (tmp
+ 1) / 2;
239 * coda_h264_sps_fixup - fixes frame cropping values in h.264 SPS
240 * @ctx: encoder context
241 * @width: visible width
242 * @height: visible height
243 * @buf: buffer containing h.264 SPS RBSP, starting with NAL header
244 * @size: modified RBSP size return value
245 * @max_size: available size in buf
247 * Rewrites the frame cropping values in an h.264 SPS RBSP correctly for the
248 * given visible width and height.
250 int coda_h264_sps_fixup(struct coda_ctx
*ctx
, int width
, int height
, char *buf
,
251 int *size
, int max_size
)
254 unsigned int pic_order_cnt_type
;
255 int pic_width_in_mbs_minus1
, pic_height_in_map_units_minus1
;
256 int frame_mbs_only_flag
, frame_cropping_flag
;
257 int vui_parameters_present_flag
;
258 unsigned int crop_right
, crop_bottom
;
263 if (*size
< 8 || *size
>= max_size
)
266 sps
.buf
= buf
+ 5; /* Skip NAL header */
267 sps
.size
= *size
- 5;
269 profile_idc
= sps
.buf
[0];
270 /* Skip constraint_set[0-5]_flag, reserved_zero_2bits */
274 /* seq_parameter_set_id */
275 ret
= rbsp_read_uev(&sps
, NULL
);
279 if (profile_idc
== 100 || profile_idc
== 110 || profile_idc
== 122 ||
280 profile_idc
== 244 || profile_idc
== 44 || profile_idc
== 83 ||
281 profile_idc
== 86 || profile_idc
== 118 || profile_idc
== 128 ||
282 profile_idc
== 138 || profile_idc
== 139 || profile_idc
== 134 ||
283 profile_idc
== 135) {
284 dev_err(ctx
->fh
.vdev
->dev_parent
,
285 "%s: Handling profile_idc %d not implemented\n",
286 __func__
, profile_idc
);
290 /* log2_max_frame_num_minus4 */
291 ret
= rbsp_read_uev(&sps
, NULL
);
295 ret
= rbsp_read_uev(&sps
, &pic_order_cnt_type
);
299 if (pic_order_cnt_type
== 0) {
300 /* log2_max_pic_order_cnt_lsb_minus4 */
301 ret
= rbsp_read_uev(&sps
, NULL
);
304 } else if (pic_order_cnt_type
== 1) {
305 unsigned int i
, num_ref_frames_in_pic_order_cnt_cycle
;
307 /* delta_pic_order_always_zero_flag */
308 ret
= rbsp_read_bit(&sps
);
311 /* offset_for_non_ref_pic */
312 ret
= rbsp_read_sev(&sps
, NULL
);
315 /* offset_for_top_to_bottom_field */
316 ret
= rbsp_read_sev(&sps
, NULL
);
320 ret
= rbsp_read_uev(&sps
,
321 &num_ref_frames_in_pic_order_cnt_cycle
);
324 for (i
= 0; i
< num_ref_frames_in_pic_order_cnt_cycle
; i
++) {
325 /* offset_for_ref_frame */
326 ret
= rbsp_read_sev(&sps
, NULL
);
332 /* max_num_ref_frames */
333 ret
= rbsp_read_uev(&sps
, NULL
);
337 /* gaps_in_frame_num_value_allowed_flag */
338 ret
= rbsp_read_bit(&sps
);
341 ret
= rbsp_read_uev(&sps
, &pic_width_in_mbs_minus1
);
344 ret
= rbsp_read_uev(&sps
, &pic_height_in_map_units_minus1
);
347 frame_mbs_only_flag
= ret
= rbsp_read_bit(&sps
);
350 if (!frame_mbs_only_flag
) {
351 /* mb_adaptive_frame_field_flag */
352 ret
= rbsp_read_bit(&sps
);
356 /* direct_8x8_inference_flag */
357 ret
= rbsp_read_bit(&sps
);
361 /* Mark position of the frame cropping flag */
363 frame_cropping_flag
= ret
= rbsp_read_bit(&sps
);
366 if (frame_cropping_flag
) {
367 unsigned int crop_left
, crop_top
;
369 ret
= rbsp_read_uev(&sps
, &crop_left
);
372 ret
= rbsp_read_uev(&sps
, &crop_right
);
375 ret
= rbsp_read_uev(&sps
, &crop_top
);
378 ret
= rbsp_read_uev(&sps
, &crop_bottom
);
382 vui_parameters_present_flag
= ret
= rbsp_read_bit(&sps
);
385 if (vui_parameters_present_flag
) {
386 dev_err(ctx
->fh
.vdev
->dev_parent
,
387 "%s: Handling vui_parameters not implemented\n",
392 crop_right
= round_up(width
, 16) - width
;
393 crop_bottom
= round_up(height
, 16) - height
;
395 if (frame_mbs_only_flag
)
401 sps
.size
= max_size
- 5;
403 frame_cropping_flag
= 1;
404 ret
= rbsp_write_bit(&sps
, frame_cropping_flag
);
407 ret
= rbsp_write_uev(&sps
, 0); /* crop_left */
410 ret
= rbsp_write_uev(&sps
, crop_right
);
413 ret
= rbsp_write_uev(&sps
, 0); /* crop_top */
416 ret
= rbsp_write_uev(&sps
, crop_bottom
);
419 ret
= rbsp_write_bit(&sps
, 0); /* vui_parameters_present_flag */
422 ret
= rbsp_write_bit(&sps
, 1);
426 *size
= 5 + DIV_ROUND_UP(sps
.pos
, 8);