blob: 1c3b73dfb7be81bea66eaf248180e4754974493c
1 | /* |
2 | * drivers/amlogic/media_modules/amvdec_ports/decoder/h264_parse.c |
3 | * |
4 | * Copyright (C) 2017 Amlogic, Inc. All rights reserved. |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, but WITHOUT |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
14 | * more details. |
15 | * |
16 | */ |
17 | |
18 | #include <linux/kernel.h> |
19 | #include "h264_parse.h" |
20 | #include "h264_stream.h" |
21 | |
22 | static unsigned char h264_exp_golomb_bits[256] = { |
23 | 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, |
24 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, |
25 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
26 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, |
27 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
28 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
29 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
30 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, |
31 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
32 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
33 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
34 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
35 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
36 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
37 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
38 | 0, |
39 | }; |
40 | |
41 | static unsigned char ZZ_SCAN[16] = { |
42 | 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 |
43 | }; |
44 | |
45 | static unsigned char ZZ_SCAN8[64] = { |
46 | 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, |
47 | 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, |
48 | 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, |
49 | 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 |
50 | }; |
51 | |
52 | unsigned int h264_u(struct h264_stream_t *s, unsigned int n) |
53 | { |
54 | //if (n % 8 == 0) { |
55 | // return h264_stream_read_bytes(s, n / 8); |
56 | //} |
57 | return h264_stream_read_bits(s, n); |
58 | } |
59 | |
60 | unsigned int h264_ue(struct h264_stream_t *s) |
61 | { |
62 | unsigned int bits, read; |
63 | unsigned char coded; |
64 | |
65 | bits = 0; |
66 | while (true) { |
67 | if (h264_stream_bytes_remaining(s) < 1) { |
68 | read = h264_stream_peek_bits(s, s->bit_pos) << |
69 | (8 - s->bit_pos); |
70 | break; |
71 | } |
72 | |
73 | read = h264_stream_peek_bits(s, 8); |
74 | if (bits > 16) |
75 | break; |
76 | |
77 | if (read) |
78 | break; |
79 | |
80 | h264_stream_read_bits(s, 8); |
81 | bits += 8; |
82 | } |
83 | |
84 | coded = h264_exp_golomb_bits[read]; |
85 | h264_stream_read_bits(s, coded); |
86 | bits += coded; |
87 | return h264_stream_read_bits(s, bits + 1) - 1; |
88 | } |
89 | |
90 | int h264_se(struct h264_stream_t *s) |
91 | { |
92 | unsigned int ret; |
93 | |
94 | ret = h264_ue(s); |
95 | if (!(ret & 0x1)) { |
96 | ret >>= 1; |
97 | return (int)(-ret); |
98 | } |
99 | |
100 | return (ret + 1) >> 1; |
101 | } |
102 | |
103 | void h264_f(struct h264_stream_t *s, unsigned int n, unsigned int pattern) |
104 | { |
105 | unsigned int val = h264_u(s, n); |
106 | |
107 | if (val != pattern) { |
108 | pr_err("fixed-pattern doesn't match. expected: %x actual: %x\n", |
109 | pattern, (unsigned int)val); |
110 | return; |
111 | } |
112 | } |
113 | |
114 | void h264_rbsp_trailing_bits(struct h264_stream_t *s) |
115 | { |
116 | h264_f(s, 1, 1); |
117 | h264_f(s, s->bit_pos, 0); |
118 | } |
119 | |
120 | // syntax for scaling list matrix values |
121 | void Scaling_List(int *scalingList, int sizeOfScalingList, |
122 | bool *UseDefaultScalingMatrix, struct h264_stream_t *s) |
123 | { |
124 | int j, scanj; |
125 | int delta_scale, lastScale, nextScale; |
126 | |
127 | lastScale = 8; |
128 | nextScale = 8; |
129 | |
130 | for (j = 0; j < sizeOfScalingList; j++) { |
131 | scanj = (sizeOfScalingList == 16) ? ZZ_SCAN[j] : ZZ_SCAN8[j]; |
132 | |
133 | if (nextScale != 0) { |
134 | delta_scale = h264_ue(s); |
135 | nextScale = (lastScale + delta_scale + 256) % 256; |
136 | *UseDefaultScalingMatrix = |
137 | (bool) (scanj == 0 && nextScale == 0); |
138 | } |
139 | |
140 | scalingList[scanj] = (nextScale == 0) ? lastScale : nextScale; |
141 | lastScale = scalingList[scanj]; |
142 | } |
143 | } |
144 | |
145 | void h264_sps_parse(struct h264_stream_t *s, struct h264_SPS_t *sps) |
146 | { |
147 | unsigned int i, n_ScalingList; |
148 | |
149 | sps->profile_idc = h264_u(s, 8); |
150 | |
151 | if ((sps->profile_idc != BASELINE) && |
152 | (sps->profile_idc != MAIN) && |
153 | (sps->profile_idc != EXTENDED) && |
154 | (sps->profile_idc != FREXT_HP) && |
155 | (sps->profile_idc != FREXT_Hi10P) && |
156 | (sps->profile_idc != FREXT_Hi422) && |
157 | (sps->profile_idc != FREXT_Hi444) && |
158 | (sps->profile_idc != FREXT_CAVLC444) |
159 | && (sps->profile_idc != MVC_HIGH) |
160 | && (sps->profile_idc != STEREO_HIGH)) { |
161 | pr_err("Invalid Profile IDC (%d) encountered.\n", |
162 | sps->profile_idc); |
163 | return; |
164 | } |
165 | |
166 | sps->constrained_set0_flag = h264_u(s, 1); |
167 | sps->constrained_set1_flag = h264_u(s, 1); |
168 | sps->constrained_set2_flag = h264_u(s, 1); |
169 | h264_u(s, 5); // reserved_zero_5bits |
170 | sps->level_idc = h264_u(s, 8); |
171 | sps->seq_parameter_set_id = h264_ue(s); |
172 | |
173 | // Fidelity Range Extensions stuff |
174 | sps->chroma_format_idc = 1; |
175 | sps->bit_depth_luma_minus8 = 0; |
176 | sps->bit_depth_chroma_minus8 = 0; |
177 | sps->lossless_qpprime_flag = 0; |
178 | sps->separate_colour_plane_flag = 0; |
179 | |
180 | if ((sps->profile_idc == FREXT_HP) || |
181 | (sps->profile_idc == FREXT_Hi10P) || |
182 | (sps->profile_idc == FREXT_Hi422) || |
183 | (sps->profile_idc == FREXT_Hi444) || |
184 | (sps->profile_idc == FREXT_CAVLC444)) { |
185 | sps->chroma_format_idc = h264_ue(s); |
186 | |
187 | if (sps->chroma_format_idc == YUV444) |
188 | sps->separate_colour_plane_flag = h264_u(s, 1); |
189 | |
190 | sps->bit_depth_luma_minus8 = h264_ue(s); |
191 | sps->bit_depth_chroma_minus8 = h264_ue(s); |
192 | //checking; |
193 | if ((sps->bit_depth_luma_minus8 + 8 > sizeof(unsigned short) * 8) || |
194 | (sps->bit_depth_chroma_minus8 + 8 > sizeof(unsigned short) * 8)) { |
195 | pr_err("Source picture has higher bit depth than imgpel data type.\n"); |
196 | pr_err("Please recompile with larger data type for imgpel.\n"); |
197 | } |
198 | |
199 | sps->lossless_qpprime_flag = h264_u(s, 1); |
200 | sps->seq_scaling_matrix_present_flag = h264_u(s, 1); |
201 | if (sps->seq_scaling_matrix_present_flag) { |
202 | n_ScalingList = (sps->chroma_format_idc != YUV444) ? 8 : 12; |
203 | for (i = 0; i < n_ScalingList; i++) { |
204 | sps->seq_scaling_list_present_flag[i] = h264_u(s, 1); |
205 | if (sps->seq_scaling_list_present_flag[i]) { |
206 | if (i < 6) |
207 | Scaling_List(sps->ScalingList4x4[i], 16, |
208 | &sps->UseDefaultScalingMatrix4x4Flag[i], s); |
209 | else |
210 | Scaling_List(sps->ScalingList8x8[i - 6], |
211 | 64, &sps->UseDefaultScalingMatrix8x8Flag[i - 6], s); |
212 | } |
213 | } |
214 | } |
215 | } |
216 | |
217 | sps->log2_max_frame_num_minus4 = h264_ue(s); |
218 | sps->pic_order_cnt_type = h264_ue(s); |
219 | if (sps->pic_order_cnt_type == 0) { |
220 | sps->log2_max_pic_order_cnt_lsb_minus4 = h264_ue(s); |
221 | } else if (sps->pic_order_cnt_type == 1) { |
222 | sps->delta_pic_order_always_zero_flag = h264_se(s); |
223 | sps->offset_for_non_ref_pic = h264_se(s); |
224 | sps->offset_for_top_to_bottom_field = h264_se(s); |
225 | sps->num_ref_frames_in_poc_cycle = h264_se(s); |
226 | for (i = 0; i < sps->num_ref_frames_in_poc_cycle; ++i) |
227 | sps->offset_for_ref_frame[i] = h264_se(s); |
228 | } |
229 | |
230 | sps->num_ref_frames = h264_ue(s); |
231 | sps->gaps_in_frame_num_value_allowed_flag = h264_u(s, 1); |
232 | sps->pic_width_in_mbs_minus1 = h264_ue(s); |
233 | sps->pic_height_in_map_units_minus1 = h264_ue(s); |
234 | sps->frame_mbs_only_flag = h264_u(s, 1); |
235 | if (!sps->frame_mbs_only_flag) |
236 | sps->mb_adaptive_frame_field_flag = h264_u(s, 1); |
237 | |
238 | sps->direct_8x8_inference_flag = h264_u(s, 1); |
239 | sps->frame_cropping_flag = h264_u(s, 1); |
240 | if (sps->frame_cropping_flag) { |
241 | sps->frame_crop_left_offset = h264_ue(s); |
242 | sps->frame_crop_right_offset = h264_ue(s); |
243 | sps->frame_crop_top_offset = h264_ue(s); |
244 | sps->frame_crop_bottom_offset = h264_ue(s); |
245 | } |
246 | |
247 | sps->vui_parameters_present_flag = h264_u(s, 1); |
248 | //if (sps->vui_parameters_present_flag) { |
249 | // sps->vui_parameters = h264_vui_parameters(s); |
250 | //} |
251 | h264_rbsp_trailing_bits(s); |
252 | } |
253 | |
254 | void h264_pps_parse(struct h264_stream_t *s, struct h264_PPS_t *pps) |
255 | { |
256 | pps->pic_parameter_set_id = h264_ue(s); |
257 | pps->seq_parameter_set_id = h264_ue(s); |
258 | pps->entropy_coding_mode_flag = h264_u(s, 1); |
259 | pps->pic_order_present_flag = h264_u(s, 1); |
260 | pps->num_slice_groups_minus1 = h264_ue(s); |
261 | if (pps->num_slice_groups_minus1 > 0) { |
262 | pps->slice_group_map_type = h264_ue(s); |
263 | if (pps->slice_group_map_type == 0) { |
264 | pps->run_length_minus1 = h264_ue(s); |
265 | } else if (pps->slice_group_map_type == 2) { |
266 | pps->top_left = h264_ue(s); |
267 | pps->bottom_right = h264_ue(s); |
268 | } else if (pps->slice_group_map_type == 3 || |
269 | pps->slice_group_map_type == 4 || |
270 | pps->slice_group_map_type == 5) { |
271 | pps->slice_group_change_direction_flag = h264_u(s, 1); |
272 | pps->slice_group_change_rate_minus1 = h264_ue(s); |
273 | } else if (pps->slice_group_map_type == 6) { |
274 | pps->pic_size_in_map_units_minus1 = h264_ue(s); |
275 | pps->slice_group_id = h264_ue(s); |
276 | } |
277 | } |
278 | pps->num_ref_idx_l0_active_minus1 = h264_ue(s); |
279 | pps->num_ref_idx_l1_active_minus1 = h264_ue(s); |
280 | pps->weighted_pred_flag = h264_u(s, 1); |
281 | pps->weighted_bipred_idc = h264_u(s, 2); |
282 | pps->pic_init_qp_minus26 = h264_se(s); |
283 | pps->pic_init_qs_minus26 = h264_se(s); |
284 | pps->chroma_qp_index_offset = h264_se(s); |
285 | pps->deblocking_filter_control_present_flag = h264_u(s, 1); |
286 | pps->constrained_intra_pred_flag = h264_u(s, 1); |
287 | pps->redundant_pic_cnt_present_flag = h264_u(s, 1); |
288 | h264_rbsp_trailing_bits(s); |
289 | } |
290 | |
291 | void h264_sps_info(struct h264_SPS_t *sps) |
292 | { |
293 | int i; |
294 | |
295 | pr_info("sequence_parameter_set {\n"); |
296 | pr_info(" profile_idc: %d\n", sps->profile_idc); |
297 | pr_info(" constraint_set0_flag: %d\n", sps->constrained_set0_flag); |
298 | pr_info(" constraint_set1_flag: %d\n", sps->constrained_set1_flag); |
299 | pr_info(" constraint_set2_flag: %d\n", sps->constrained_set2_flag); |
300 | pr_info(" level_idc: %d\n", sps->level_idc); |
301 | pr_info(" seq_parameter_set_id: %d\n", sps->seq_parameter_set_id); |
302 | |
303 | pr_info(" log2_max_frame_num_minus4: %d\n", |
304 | sps->log2_max_frame_num_minus4); |
305 | pr_info(" pic_order_cnt_type: %d\n", sps->pic_order_cnt_type); |
306 | if (sps->pic_order_cnt_type == 0) { |
307 | pr_info(" log2_max_pic_order_cnt_lsb_minus4: %d\n", |
308 | sps->log2_max_pic_order_cnt_lsb_minus4); |
309 | } else if (sps->pic_order_cnt_type == 1) { |
310 | pr_info(" delta_pic_order_always_zero_flag: %d\n", |
311 | sps->delta_pic_order_always_zero_flag); |
312 | pr_info(" offset_for_non_ref_pic: %d\n", |
313 | sps->offset_for_non_ref_pic); |
314 | pr_info(" offset_for_top_to_bottom_field: %d\n", |
315 | sps->offset_for_top_to_bottom_field); |
316 | pr_info(" num_ref_frames_in_pic_order_cnt_cycle: %d\n", |
317 | sps->num_ref_frames_in_poc_cycle); |
318 | for (i = 0; i < sps->num_ref_frames_in_poc_cycle; ++i) { |
319 | pr_info(" offset_for_ref_frame[%d]: %d\n", i, |
320 | sps->offset_for_ref_frame[i]); |
321 | } |
322 | } |
323 | pr_info(" num_ref_frames: %d\n", sps->num_ref_frames); |
324 | pr_info(" gaps_in_frame_num_value_allowed_flag: %d\n", |
325 | sps->gaps_in_frame_num_value_allowed_flag); |
326 | pr_info(" pic_width_in_mbs_minus1: %d\n", |
327 | sps->pic_width_in_mbs_minus1); |
328 | pr_info(" pic_height_in_map_units_minus1: %d\n", |
329 | sps->pic_height_in_map_units_minus1); |
330 | pr_info(" frame_mbs_only_flag: %d\n", |
331 | sps->frame_mbs_only_flag); |
332 | pr_info(" mb_adaptive_frame_field_flag: %d\n", |
333 | sps->mb_adaptive_frame_field_flag); |
334 | pr_info(" direct_8x8_inference_flag: %d\n", |
335 | sps->direct_8x8_inference_flag); |
336 | pr_info(" frame_cropping_flag: %d\n", |
337 | sps->frame_cropping_flag); |
338 | if (sps->frame_cropping_flag) { |
339 | pr_info(" frame_crop_left_offset: %d\n", |
340 | sps->frame_crop_left_offset); |
341 | pr_info(" frame_crop_right_offset: %d\n", |
342 | sps->frame_crop_right_offset); |
343 | pr_info(" frame_crop_top_offset: %d\n", |
344 | sps->frame_crop_top_offset); |
345 | pr_info(" frame_crop_bottom_offset: %d\n", |
346 | sps->frame_crop_bottom_offset); |
347 | } |
348 | pr_info(" vui_parameters_present_flag: %d\n", |
349 | sps->vui_parameters_present_flag); |
350 | //if (sps->vui_parameters_present_flag) { |
351 | // h264_print_vui_parameters(sps->vui_parameters); |
352 | //} |
353 | |
354 | pr_info(" }\n"); |
355 | } |
356 | |
357 | void h264_pps_info(struct h264_PPS_t *pps) |
358 | { |
359 | pr_info("pic_parameter_set {\n"); |
360 | pr_info(" pic_parameter_set_id: %d\n", |
361 | pps->pic_parameter_set_id); |
362 | pr_info(" seq_parameter_set_id: %d\n", |
363 | pps->seq_parameter_set_id); |
364 | pr_info(" entropy_coding_mode_flag: %d\n", |
365 | pps->entropy_coding_mode_flag); |
366 | pr_info(" pic_order_present_flag: %d\n", |
367 | pps->pic_order_present_flag); |
368 | pr_info(" num_slice_groups_minus1: %d\n", |
369 | pps->num_slice_groups_minus1); |
370 | // FIXME: Code for slice groups is missing here. |
371 | pr_info(" num_ref_idx_l0_active_minus1: %d\n", |
372 | pps->num_ref_idx_l0_active_minus1); |
373 | pr_info(" num_ref_idx_l1_active_minus1: %d\n", |
374 | pps->num_ref_idx_l1_active_minus1); |
375 | pr_info(" weighted_pred_flag: %d\n", pps->weighted_pred_flag); |
376 | pr_info(" weighted_bipred_idc: %d\n", pps->weighted_bipred_idc); |
377 | pr_info(" pic_init_qp_minus26: %d\n", pps->pic_init_qp_minus26); |
378 | pr_info(" pic_init_qs_minus26: %d\n", pps->pic_init_qs_minus26); |
379 | pr_info(" chroma_qp_index_offset: %d\n", |
380 | pps->chroma_qp_index_offset); |
381 | pr_info(" deblocking_filter_control_present_flag: %d\n", |
382 | pps->deblocking_filter_control_present_flag); |
383 | pr_info(" constrained_intra_pred_flag: %d\n", |
384 | pps->constrained_intra_pred_flag); |
385 | pr_info(" redundant_pic_cnt_present_flag: %d\n", |
386 | pps->redundant_pic_cnt_present_flag); |
387 | pr_info(" }\n"); |
388 | } |
389 | |
390 |