1 /******************************************************************************
2 *
3 * Copyright (C) 2015 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20
21 /*****************************************************************************/
22 /* */
23 /* File Name : ih264d_sei.c */
24 /* */
25 /* Description : This file contains routines to parse SEI NAL's */
26 /* */
27 /* List of Functions : <List the functions defined in this file> */
28 /* */
29 /* Issues / Problems : None */
30 /* */
31 /* Revision History : */
32 /* */
33 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
34 /* 25 05 2005 NS Draft */
35 /* */
36 /*****************************************************************************/
37
38 #include <string.h>
39
40 #include "ih264_typedefs.h"
41 #include "ih264_macros.h"
42 #include "ih264_platform_macros.h"
43 #include "ih264d_bitstrm.h"
44 #include "ih264d_structs.h"
45 #include "ih264d_error_handler.h"
46 #include "ih264d_vui.h"
47 #include "ih264d_parse_cavlc.h"
48 #include "ih264d_defs.h"
49
50 /*****************************************************************************/
51 /* */
52 /* Function Name : ih264d_parse_buffering_period */
53 /* */
54 /* Description : This function parses SEI message buffering_period */
55 /* Inputs : ps_buf_prd pointer to struct buf_period_t */
56 /* ps_bitstrm Bitstream */
57 /* Globals : None */
58 /* Processing : Parses SEI payload buffering period. */
59 /* Outputs : None */
60 /* Return : 0 for successfull parsing, else error message */
61 /* */
62 /* Issues : Not implemented fully */
63 /* */
64 /* Revision History: */
65 /* */
66 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
67 /* 06 05 2002 NS Draft */
68 /* */
69 /*****************************************************************************/
70
ih264d_parse_buffering_period(buf_period_t * ps_buf_prd,dec_bit_stream_t * ps_bitstrm,dec_struct_t * ps_dec)71 WORD32 ih264d_parse_buffering_period(buf_period_t *ps_buf_prd,
72 dec_bit_stream_t *ps_bitstrm,
73 dec_struct_t *ps_dec)
74 {
75 UWORD8 u1_seq_parameter_set_id;
76 dec_seq_params_t *ps_seq;
77 UWORD8 u1_nal_hrd_present, u1_vcl_hrd_present;
78 UWORD32 i;
79 UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
80 UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
81 UNUSED(ps_buf_prd);
82 u1_seq_parameter_set_id = ih264d_uev(pu4_bitstrm_ofst,
83 pu4_bitstrm_buf);
84 if(u1_seq_parameter_set_id >= MAX_NUM_SEQ_PARAMS)
85 return ERROR_INVALID_SEQ_PARAM;
86 ps_seq = &ps_dec->ps_sps[u1_seq_parameter_set_id];
87 if(TRUE != ps_seq->u1_is_valid)
88 return ERROR_INVALID_SEQ_PARAM;
89
90 ps_dec->ps_sei->u1_seq_param_set_id = u1_seq_parameter_set_id;
91 ps_dec->ps_cur_sps = ps_seq;
92 if(FALSE == ps_seq->u1_is_valid)
93 return ERROR_INVALID_SEQ_PARAM;
94 if(1 == ps_seq->u1_vui_parameters_present_flag)
95 {
96 u1_nal_hrd_present = ps_seq->s_vui.u1_nal_hrd_params_present;
97 if(u1_nal_hrd_present)
98 {
99 for(i = 0; i < ps_seq->s_vui.s_nal_hrd.u4_cpb_cnt; i++)
100 {
101 ih264d_get_bits_h264(
102 ps_bitstrm,
103 ps_seq->s_vui.s_nal_hrd.u1_initial_cpb_removal_delay);
104 ih264d_get_bits_h264(
105 ps_bitstrm,
106 ps_seq->s_vui.s_nal_hrd.u1_initial_cpb_removal_delay);
107 }
108 }
109
110 u1_vcl_hrd_present = ps_seq->s_vui.u1_vcl_hrd_params_present;
111 if(u1_vcl_hrd_present)
112 {
113 for(i = 0; i < ps_seq->s_vui.s_vcl_hrd.u4_cpb_cnt; i++)
114 {
115 ih264d_get_bits_h264(
116 ps_bitstrm,
117 ps_seq->s_vui.s_vcl_hrd.u1_initial_cpb_removal_delay);
118 ih264d_get_bits_h264(
119 ps_bitstrm,
120 ps_seq->s_vui.s_vcl_hrd.u1_initial_cpb_removal_delay);
121 }
122 }
123 }
124 return (OK);
125 }
126
127 /*****************************************************************************/
128 /* */
129 /* Function Name : ih264d_parse_pic_timing */
130 /* */
131 /* Description : This function parses SEI message pic_timing */
132 /* Inputs : ps_bitstrm Bitstream */
133 /* ps_dec Poniter decoder context */
134 /* ui4_payload_size pay load i4_size */
135 /* Globals : None */
136 /* Processing : Parses SEI payload picture timing */
137 /* Outputs : None */
138 /* Return : 0 */
139 /* */
140 /* Issues : Not implemented fully */
141 /* */
142 /* Revision History: */
143 /* */
144 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
145 /* 06 05 2002 NS Draft */
146 /* */
147 /*****************************************************************************/
ih264d_parse_pic_timing(dec_bit_stream_t * ps_bitstrm,dec_struct_t * ps_dec,UWORD32 ui4_payload_size)148 WORD32 ih264d_parse_pic_timing(dec_bit_stream_t *ps_bitstrm,
149 dec_struct_t *ps_dec,
150 UWORD32 ui4_payload_size)
151 {
152 sei *ps_sei;
153 vui_t *ps_vu4;
154 UWORD8 u1_cpb_dpb_present;
155 UWORD8 u1_pic_struct_present_flag;
156 UWORD32 u4_start_offset, u4_bits_consumed;
157 UWORD8 u1_cpb_removal_delay_length, u1_dpb_output_delay_length;
158
159 ps_sei = (sei *)ps_dec->ps_sei;
160 ps_vu4 = &ps_dec->ps_cur_sps->s_vui;
161
162 u1_cpb_dpb_present = ps_vu4->u1_vcl_hrd_params_present
163 + ps_vu4->u1_nal_hrd_params_present;
164
165 if(ps_vu4->u1_vcl_hrd_params_present)
166 {
167 u1_cpb_removal_delay_length =
168 ps_vu4->s_vcl_hrd.u1_cpb_removal_delay_length;
169 u1_dpb_output_delay_length =
170 ps_vu4->s_vcl_hrd.u1_dpb_output_delay_length;
171 }
172 else if(ps_vu4->u1_nal_hrd_params_present)
173 {
174 u1_cpb_removal_delay_length =
175 ps_vu4->s_nal_hrd.u1_cpb_removal_delay_length;
176 u1_dpb_output_delay_length =
177 ps_vu4->s_nal_hrd.u1_dpb_output_delay_length;
178 }
179 else
180 {
181 u1_cpb_removal_delay_length = 24;
182 u1_dpb_output_delay_length = 24;
183
184 }
185
186 u4_start_offset = ps_bitstrm->u4_ofst;
187 if(u1_cpb_dpb_present)
188 {
189 ih264d_get_bits_h264(ps_bitstrm, u1_cpb_removal_delay_length);
190 ih264d_get_bits_h264(ps_bitstrm, u1_dpb_output_delay_length);
191 }
192
193 u1_pic_struct_present_flag = ps_vu4->u1_pic_struct_present_flag;
194 if(u1_pic_struct_present_flag)
195 {
196 ps_sei->u1_pic_struct = ih264d_get_bits_h264(ps_bitstrm, 4);
197 ps_dec->u1_pic_struct_copy = ps_sei->u1_pic_struct;
198 ps_sei->u1_is_valid = 1;
199 }
200 u4_bits_consumed = ps_bitstrm->u4_ofst - u4_start_offset;
201
202 if((ui4_payload_size << 3) < u4_bits_consumed)
203 return ERROR_CORRUPTED_SLICE;
204
205 ih264d_flush_bits_h264(ps_bitstrm,
206 (ui4_payload_size << 3) - u4_bits_consumed);
207
208 return (OK);
209 }
210
211 /*****************************************************************************/
212 /* */
213 /* Function Name : ih264d_parse_recovery_point */
214 /* */
215 /* Description : This function parses SEI message recovery point */
216 /* Inputs : ps_bitstrm Bitstream */
217 /* ps_dec Poniter decoder context */
218 /* ui4_payload_size pay load i4_size */
219 /* Globals : None */
220 /* Processing : Parses SEI payload picture timing */
221 /* Outputs : None */
222 /* Return : 0 */
223 /* */
224 /* Issues : Not implemented fully */
225 /* */
226 /* Revision History: */
227 /* */
228 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
229 /* 06 05 2002 NS Draft */
230 /* */
231 /*****************************************************************************/
ih264d_parse_recovery_point(dec_bit_stream_t * ps_bitstrm,dec_struct_t * ps_dec,UWORD32 ui4_payload_size)232 WORD32 ih264d_parse_recovery_point(dec_bit_stream_t *ps_bitstrm,
233 dec_struct_t *ps_dec,
234 UWORD32 ui4_payload_size)
235 {
236 sei *ps_sei = ps_dec->ps_sei;
237 dec_err_status_t *ps_err = ps_dec->ps_dec_err_status;
238 UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
239 UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
240 UNUSED(ui4_payload_size);
241 ps_sei->u2_recovery_frame_cnt = ih264d_uev(pu4_bitstrm_ofst,
242 pu4_bitstrm_buf);
243 ps_err->u4_frm_sei_sync = ps_err->u4_cur_frm
244 + ps_sei->u2_recovery_frame_cnt;
245 ps_sei->u1_exact_match_flag = ih264d_get_bit_h264(ps_bitstrm);
246 ps_sei->u1_broken_link_flag = ih264d_get_bit_h264(ps_bitstrm);
247 ps_sei->u1_changing_slice_grp_idc = ih264d_get_bits_h264(ps_bitstrm, 2);
248
249 return (OK);
250 }
251
252 /*****************************************************************************/
253 /* */
254 /* Function Name : ih264d_parse_mdcv */
255 /* */
256 /* Description : This function parses SEI message mdcv */
257 /* Inputs : ps_bitstrm Bitstream */
258 /* ps_dec Poniter decoder context */
259 /* ui4_payload_size pay load i4_size */
260 /* Globals : None */
261 /* Processing : */
262 /* Outputs : None */
263 /* Return : 0 for successfull parsing, else -1 */
264 /* */
265 /* Issues : */
266 /* */
267 /* Revision History: */
268 /* */
269 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
270 /* Draft */
271 /* */
272 /*****************************************************************************/
ih264d_parse_mdcv(dec_bit_stream_t * ps_bitstrm,dec_struct_t * ps_dec,UWORD32 ui4_payload_size)273 WORD32 ih264d_parse_mdcv(dec_bit_stream_t *ps_bitstrm,
274 dec_struct_t *ps_dec,
275 UWORD32 ui4_payload_size)
276 {
277 sei *ps_sei = ps_dec->ps_sei_parse;
278 dec_err_status_t *ps_err = ps_dec->ps_dec_err_status;
279 UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
280 UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
281 UWORD32 u4_count;
282 UNUSED(ui4_payload_size);
283
284 if((ps_dec == NULL) || (ps_sei == NULL))
285 {
286 return NOT_OK;
287 }
288
289 ps_sei->u1_sei_mdcv_params_present_flag = 1;
290
291 /* display primaries x */
292 for(u4_count = 0; u4_count < NUM_SEI_MDCV_PRIMARIES; u4_count++)
293 {
294 ps_sei->s_sei_mdcv_params.au2_display_primaries_x[u4_count] =
295 (UWORD16)ih264d_get_bits_h264(ps_bitstrm, 16);
296
297 if((ps_sei->s_sei_mdcv_params.au2_display_primaries_x[u4_count] >
298 DISPLAY_PRIMARIES_X_UPPER_LIMIT) ||
299 (ps_sei->s_sei_mdcv_params.au2_display_primaries_x[u4_count] <
300 DISPLAY_PRIMARIES_X_LOWER_LIMIT) ||
301 ((ps_sei->s_sei_mdcv_params.au2_display_primaries_x[u4_count] %
302 DISPLAY_PRIMARIES_X_DIVISION_FACTOR) != 0))
303 {
304 ps_sei->u1_sei_mdcv_params_present_flag = 0;
305 return ERROR_INV_SEI_MDCV_PARAMS;
306 }
307
308 ps_sei->s_sei_mdcv_params.au2_display_primaries_y[u4_count] =
309 (UWORD16)ih264d_get_bits_h264(ps_bitstrm, 16);
310
311 if((ps_sei->s_sei_mdcv_params.au2_display_primaries_y[u4_count] >
312 DISPLAY_PRIMARIES_Y_UPPER_LIMIT) ||
313 (ps_sei->s_sei_mdcv_params.au2_display_primaries_y[u4_count] <
314 DISPLAY_PRIMARIES_Y_LOWER_LIMIT) ||
315 ((ps_sei->s_sei_mdcv_params.au2_display_primaries_y[u4_count] %
316 DISPLAY_PRIMARIES_Y_DIVISION_FACTOR) != 0))
317 {
318 ps_sei->u1_sei_mdcv_params_present_flag = 0;
319 return ERROR_INV_SEI_MDCV_PARAMS;
320 }
321 }
322
323 /* white point x */
324 ps_sei->s_sei_mdcv_params.u2_white_point_x = (UWORD16)ih264d_get_bits_h264(ps_bitstrm, 16);
325
326 if((ps_sei->s_sei_mdcv_params.u2_white_point_x > WHITE_POINT_X_UPPER_LIMIT) ||
327 (ps_sei->s_sei_mdcv_params.u2_white_point_x < WHITE_POINT_X_LOWER_LIMIT) ||
328 ((ps_sei->s_sei_mdcv_params.u2_white_point_x % WHITE_POINT_X_DIVISION_FACTOR) != 0))
329 {
330 ps_sei->u1_sei_mdcv_params_present_flag = 0;
331 return ERROR_INV_SEI_MDCV_PARAMS;
332 }
333 /* white point y */
334 ps_sei->s_sei_mdcv_params.u2_white_point_y = (UWORD16)ih264d_get_bits_h264(ps_bitstrm, 16);
335
336 if((ps_sei->s_sei_mdcv_params.u2_white_point_y > WHITE_POINT_Y_UPPER_LIMIT) ||
337 (ps_sei->s_sei_mdcv_params.u2_white_point_y < WHITE_POINT_Y_LOWER_LIMIT) ||
338 ((ps_sei->s_sei_mdcv_params.u2_white_point_y % WHITE_POINT_Y_DIVISION_FACTOR) != 0))
339 {
340 ps_sei->u1_sei_mdcv_params_present_flag = 0;
341 return ERROR_INV_SEI_MDCV_PARAMS;
342 }
343 /* max display mastering luminance */
344 ps_sei->s_sei_mdcv_params.u4_max_display_mastering_luminance =
345 (UWORD32)ih264d_get_bits_h264(ps_bitstrm, 32);
346
347 if((ps_sei->s_sei_mdcv_params.u4_max_display_mastering_luminance >
348 MAX_DISPLAY_MASTERING_LUMINANCE_UPPER_LIMIT) ||
349 (ps_sei->s_sei_mdcv_params.u4_max_display_mastering_luminance <
350 MAX_DISPLAY_MASTERING_LUMINANCE_LOWER_LIMIT) ||
351 ((ps_sei->s_sei_mdcv_params.u4_max_display_mastering_luminance %
352 MAX_DISPLAY_MASTERING_LUMINANCE_DIVISION_FACTOR) != 0))
353 {
354 ps_sei->u1_sei_mdcv_params_present_flag = 0;
355 return ERROR_INV_SEI_MDCV_PARAMS;
356 }
357 /* min display mastering luminance */
358 ps_sei->s_sei_mdcv_params.u4_min_display_mastering_luminance =
359 (UWORD32)ih264d_get_bits_h264(ps_bitstrm, 32);
360
361 if((ps_sei->s_sei_mdcv_params.u4_min_display_mastering_luminance >
362 MIN_DISPLAY_MASTERING_LUMINANCE_UPPER_LIMIT) ||
363 (ps_sei->s_sei_mdcv_params.u4_min_display_mastering_luminance <
364 MIN_DISPLAY_MASTERING_LUMINANCE_LOWER_LIMIT))
365 {
366 ps_sei->u1_sei_mdcv_params_present_flag = 0;
367 return ERROR_INV_SEI_MDCV_PARAMS;
368 }
369 if(ps_sei->s_sei_mdcv_params.u4_max_display_mastering_luminance <=
370 ps_sei->s_sei_mdcv_params.u4_min_display_mastering_luminance)
371 {
372 ps_sei->u1_sei_mdcv_params_present_flag = 0;
373 return ERROR_INV_SEI_MDCV_PARAMS;
374 }
375 return (OK);
376 }
377
378 /*****************************************************************************/
379 /* */
380 /* Function Name : ih264d_parse_cll */
381 /* */
382 /* Description : This function parses SEI message cll */
383 /* Inputs : ps_bitstrm Bitstream */
384 /* ps_dec Poniter decoder context */
385 /* ui4_payload_size pay load i4_size */
386 /* Globals : None */
387 /* Processing : */
388 /* Outputs : None */
389 /* Return : 0 for successfull parsing, else -1 */
390 /* */
391 /* Issues : */
392 /* */
393 /* Revision History: */
394 /* */
395 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
396 /* Draft */
397 /* */
398 /*****************************************************************************/
ih264d_parse_cll(dec_bit_stream_t * ps_bitstrm,dec_struct_t * ps_dec,UWORD32 ui4_payload_size)399 WORD32 ih264d_parse_cll(dec_bit_stream_t *ps_bitstrm,
400 dec_struct_t *ps_dec,
401 UWORD32 ui4_payload_size)
402 {
403 sei *ps_sei = ps_dec->ps_sei_parse;
404 dec_err_status_t *ps_err = ps_dec->ps_dec_err_status;
405 UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
406 UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
407 UNUSED(ui4_payload_size);
408
409 if((ps_dec == NULL) || (ps_sei == NULL))
410 {
411 return NOT_OK;
412 }
413
414 ps_sei->u1_sei_cll_params_present_flag = 1;
415
416 ps_sei->s_sei_cll_params.u2_max_content_light_level =
417 (UWORD16)ih264d_get_bits_h264(ps_bitstrm, 16);
418 ps_sei->s_sei_cll_params.u2_max_pic_average_light_level =
419 (UWORD16)ih264d_get_bits_h264(ps_bitstrm, 16);
420 /*No any sanity checks done for CLL params*/
421
422 return (OK);
423 }
424
425 /*****************************************************************************/
426 /* */
427 /* Function Name : ih264d_parse_ave */
428 /* */
429 /* Description : This function parses SEI message ave */
430 /* Inputs : ps_bitstrm Bitstream */
431 /* ps_dec Poniter decoder context */
432 /* ui4_payload_size pay load i4_size */
433 /* Globals : None */
434 /* Processing : */
435 /* Outputs : None */
436 /* Return : 0 for successfull parsing, else -1 */
437 /* */
438 /* Issues : */
439 /* */
440 /* Revision History: */
441 /* */
442 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
443 /* Draft */
444 /* */
445 /*****************************************************************************/
ih264d_parse_ave(dec_bit_stream_t * ps_bitstrm,dec_struct_t * ps_dec,UWORD32 ui4_payload_size)446 WORD32 ih264d_parse_ave(dec_bit_stream_t *ps_bitstrm,
447 dec_struct_t *ps_dec,
448 UWORD32 ui4_payload_size)
449 {
450 sei *ps_sei = ps_dec->ps_sei_parse;
451 dec_err_status_t *ps_err = ps_dec->ps_dec_err_status;
452 UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
453 UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
454 UNUSED(ui4_payload_size);
455
456 if((ps_dec == NULL) || (ps_sei == NULL))
457 {
458 return NOT_OK;
459 }
460
461 ps_sei->u1_sei_ave_params_present_flag = 1;
462
463 ps_sei->s_sei_ave_params.u4_ambient_illuminance = (UWORD32)ih264d_get_bits_h264(ps_bitstrm, 32);
464 if(0 == ps_sei->s_sei_ave_params.u4_ambient_illuminance)
465 {
466 ps_sei->u1_sei_ave_params_present_flag = 0;
467 return ERROR_INV_SEI_AVE_PARAMS;
468 }
469
470 ps_sei->s_sei_ave_params.u2_ambient_light_x = (UWORD16)ih264d_get_bits_h264(ps_bitstrm, 16);
471 if(ps_sei->s_sei_ave_params.u2_ambient_light_x > AMBIENT_LIGHT_X_UPPER_LIMIT)
472 {
473 ps_sei->u1_sei_ave_params_present_flag = 0;
474 return ERROR_INV_SEI_AVE_PARAMS;
475 }
476
477 ps_sei->s_sei_ave_params.u2_ambient_light_y = (UWORD16)ih264d_get_bits_h264(ps_bitstrm, 16);
478 if(ps_sei->s_sei_ave_params.u2_ambient_light_y > AMBIENT_LIGHT_Y_UPPER_LIMIT)
479 {
480 ps_sei->u1_sei_ave_params_present_flag = 0;
481 return ERROR_INV_SEI_AVE_PARAMS;
482 }
483 return (OK);
484 }
485
486 /*****************************************************************************/
487 /* */
488 /* Function Name : ih264d_parse_ccv */
489 /* */
490 /* Description : This function parses SEI message ccv */
491 /* Inputs : ps_bitstrm Bitstream */
492 /* ps_dec Poniter decoder context */
493 /* ui4_payload_size pay load i4_size */
494 /* Globals : None */
495 /* Processing : */
496 /* Outputs : None */
497 /* Return : 0 for successfull parsing, else -1 */
498 /* */
499 /* Issues : */
500 /* */
501 /* Revision History: */
502 /* */
503 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
504 /* Draft */
505 /* */
506 /*****************************************************************************/
ih264d_parse_ccv(dec_bit_stream_t * ps_bitstrm,dec_struct_t * ps_dec,UWORD32 ui4_payload_size)507 WORD32 ih264d_parse_ccv(dec_bit_stream_t *ps_bitstrm,
508 dec_struct_t *ps_dec,
509 UWORD32 ui4_payload_size)
510 {
511 sei *ps_sei = ps_dec->ps_sei_parse;
512 dec_err_status_t *ps_err = ps_dec->ps_dec_err_status;
513 UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
514 UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
515 UWORD32 u4_count;
516 UNUSED(ui4_payload_size);
517
518 if((ps_dec == NULL) || (ps_sei == NULL))
519 {
520 return NOT_OK;
521 }
522
523 ps_sei->u1_sei_ccv_params_present_flag = 0;
524
525 ps_sei->s_sei_ccv_params.u1_ccv_cancel_flag = (UWORD8)ih264d_get_bit_h264(ps_bitstrm);
526
527 if(ps_sei->s_sei_ccv_params.u1_ccv_cancel_flag > 1)
528 {
529 return ERROR_INV_SEI_CCV_PARAMS;
530 }
531 if(0 == ps_sei->s_sei_ccv_params.u1_ccv_cancel_flag)
532 {
533 ps_sei->s_sei_ccv_params.u1_ccv_persistence_flag =
534 (UWORD8)ih264d_get_bit_h264(ps_bitstrm);
535 if(ps_sei->s_sei_ccv_params.u1_ccv_persistence_flag > 1)
536 {
537 return ERROR_INV_SEI_CCV_PARAMS;
538 }
539 ps_sei->s_sei_ccv_params.u1_ccv_primaries_present_flag =
540 (UWORD8)ih264d_get_bit_h264(ps_bitstrm);
541 if(ps_sei->s_sei_ccv_params.u1_ccv_primaries_present_flag > 1)
542 {
543 return ERROR_INV_SEI_CCV_PARAMS;
544 }
545 ps_sei->s_sei_ccv_params.u1_ccv_min_luminance_value_present_flag =
546 (UWORD8)ih264d_get_bit_h264(ps_bitstrm);
547 if(ps_sei->s_sei_ccv_params.u1_ccv_min_luminance_value_present_flag > 1)
548 {
549 return ERROR_INV_SEI_CCV_PARAMS;
550 }
551 ps_sei->s_sei_ccv_params.u1_ccv_max_luminance_value_present_flag =
552 (UWORD8)ih264d_get_bit_h264(ps_bitstrm);
553 if(ps_sei->s_sei_ccv_params.u1_ccv_max_luminance_value_present_flag > 1)
554 {
555 return ERROR_INV_SEI_CCV_PARAMS;
556 }
557 ps_sei->s_sei_ccv_params.u1_ccv_avg_luminance_value_present_flag =
558 (UWORD8)ih264d_get_bit_h264(ps_bitstrm);
559 if(ps_sei->s_sei_ccv_params.u1_ccv_avg_luminance_value_present_flag > 1)
560 {
561 return ERROR_INV_SEI_CCV_PARAMS;
562 }
563
564 if((ps_sei->s_sei_ccv_params.u1_ccv_primaries_present_flag == 0) &&
565 (ps_sei->s_sei_ccv_params.u1_ccv_min_luminance_value_present_flag == 0) &&
566 (ps_sei->s_sei_ccv_params.u1_ccv_max_luminance_value_present_flag == 0) &&
567 (ps_sei->s_sei_ccv_params.u1_ccv_avg_luminance_value_present_flag == 0))
568 {
569 return ERROR_INV_SEI_CCV_PARAMS;
570 }
571
572 ps_sei->s_sei_ccv_params.u1_ccv_reserved_zero_2bits =
573 (UWORD8)ih264d_get_bits_h264(ps_bitstrm, 2);
574 if((ps_sei->s_sei_ccv_params.u1_ccv_reserved_zero_2bits != 0))
575 {
576 return ERROR_INV_SEI_CCV_PARAMS;
577 }
578
579 /* ccv primaries */
580 if(1 == ps_sei->s_sei_ccv_params.u1_ccv_primaries_present_flag)
581 {
582 for(u4_count = 0; u4_count < NUM_SEI_CCV_PRIMARIES; u4_count++)
583 {
584 ps_sei->s_sei_ccv_params.ai4_ccv_primaries_x[u4_count] =
585 (WORD32)ih264d_get_bits_h264(ps_bitstrm, 32);
586 if((ps_sei->s_sei_ccv_params.ai4_ccv_primaries_x[u4_count] >
587 CCV_PRIMARIES_X_UPPER_LIMIT) ||
588 (ps_sei->s_sei_ccv_params.ai4_ccv_primaries_x[u4_count] <
589 CCV_PRIMARIES_X_LOWER_LIMIT))
590 {
591 return ERROR_INV_SEI_CCV_PARAMS;
592 }
593
594 ps_sei->s_sei_ccv_params.ai4_ccv_primaries_y[u4_count] =
595 (WORD32)ih264d_get_bits_h264(ps_bitstrm, 32);
596 if((ps_sei->s_sei_ccv_params.ai4_ccv_primaries_y[u4_count] >
597 CCV_PRIMARIES_Y_UPPER_LIMIT) ||
598 (ps_sei->s_sei_ccv_params.ai4_ccv_primaries_y[u4_count] <
599 CCV_PRIMARIES_Y_LOWER_LIMIT))
600 {
601 return ERROR_INV_SEI_CCV_PARAMS;
602 }
603 }
604 }
605
606 if(1 == ps_sei->s_sei_ccv_params.u1_ccv_min_luminance_value_present_flag)
607 {
608 ps_sei->s_sei_ccv_params.u4_ccv_min_luminance_value =
609 (UWORD32)ih264d_get_bits_h264(ps_bitstrm, 32);
610 }
611
612 if(1 == ps_sei->s_sei_ccv_params.u1_ccv_max_luminance_value_present_flag)
613 {
614 ps_sei->s_sei_ccv_params.u4_ccv_max_luminance_value =
615 (UWORD32)ih264d_get_bits_h264(ps_bitstrm, 32);
616 if((1 == ps_sei->s_sei_ccv_params.u1_ccv_min_luminance_value_present_flag) &&
617 (ps_sei->s_sei_ccv_params.u4_ccv_max_luminance_value <
618 ps_sei->s_sei_ccv_params.u4_ccv_min_luminance_value))
619 {
620 return ERROR_INV_SEI_CCV_PARAMS;
621 }
622 }
623 if(1 == ps_sei->s_sei_ccv_params.u1_ccv_avg_luminance_value_present_flag)
624 {
625 ps_sei->s_sei_ccv_params.u4_ccv_avg_luminance_value =
626 (UWORD32)ih264d_get_bits_h264(ps_bitstrm, 32);
627 if((1 == ps_sei->s_sei_ccv_params.u1_ccv_min_luminance_value_present_flag) &&
628 (ps_sei->s_sei_ccv_params.u4_ccv_avg_luminance_value <
629 ps_sei->s_sei_ccv_params.u4_ccv_min_luminance_value))
630 {
631 return ERROR_INV_SEI_CCV_PARAMS;
632 }
633 if((1 == ps_sei->s_sei_ccv_params.u1_ccv_max_luminance_value_present_flag) &&
634 (ps_sei->s_sei_ccv_params.u4_ccv_max_luminance_value <
635 ps_sei->s_sei_ccv_params.u4_ccv_avg_luminance_value))
636 {
637 return ERROR_INV_SEI_CCV_PARAMS;
638 }
639 }
640 }
641 ps_sei->u1_sei_ccv_params_present_flag = 1;
642 return (OK);
643 }
644
645 /*****************************************************************************/
646 /* */
647 /* Function Name : ih264d_parse_sei_payload */
648 /* */
649 /* Description : This function parses SEI pay loads. Currently it's */
650 /* implemented partially. */
651 /* Inputs : ps_bitstrm Bitstream */
652 /* ui4_payload_type SEI payload type */
653 /* ui4_payload_size SEI payload i4_size */
654 /* Globals : None */
655 /* Processing : Parses SEI payloads units and stores the info */
656 /* Outputs : None */
657 /* Return : status for successful parsing, else -1 */
658 /* */
659 /* Issues : Not implemented fully */
660 /* */
661 /* Revision History: */
662 /* */
663 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
664 /* 06 05 2002 NS Draft */
665 /* */
666 /*****************************************************************************/
667
ih264d_parse_sei_payload(dec_bit_stream_t * ps_bitstrm,UWORD32 ui4_payload_type,UWORD32 ui4_payload_size,dec_struct_t * ps_dec)668 WORD32 ih264d_parse_sei_payload(dec_bit_stream_t *ps_bitstrm,
669 UWORD32 ui4_payload_type,
670 UWORD32 ui4_payload_size,
671 dec_struct_t *ps_dec)
672 {
673 sei *ps_sei;
674 WORD32 i4_status = 0;
675 ps_sei = (sei *)ps_dec->ps_sei_parse;
676
677 if(ui4_payload_size == 0)
678 return -1;
679 if(NULL == ps_bitstrm)
680 {
681 return NOT_OK;
682 }
683
684 switch(ui4_payload_type)
685 {
686 case SEI_BUF_PERIOD:
687
688 i4_status = ih264d_parse_buffering_period(&ps_sei->s_buf_period,
689 ps_bitstrm, ps_dec);
690 break;
691 case SEI_PIC_TIMING:
692 if(NULL == ps_dec->ps_cur_sps)
693 i4_status = ih264d_flush_bits_h264(ps_bitstrm, (ui4_payload_size << 3));
694 else
695 i4_status = ih264d_parse_pic_timing(ps_bitstrm, ps_dec,
696 ui4_payload_size);
697 break;
698 case SEI_RECOVERY_PT:
699 i4_status = ih264d_parse_recovery_point(ps_bitstrm, ps_dec,
700 ui4_payload_size);
701 break;
702 case SEI_MASTERING_DISP_COL_VOL:
703
704 i4_status = ih264d_parse_mdcv(ps_bitstrm, ps_dec,
705 ui4_payload_size);
706 break;
707 case SEI_CONTENT_LIGHT_LEVEL_DATA:
708
709 i4_status = ih264d_parse_cll(ps_bitstrm, ps_dec,
710 ui4_payload_size);
711 break;
712 case SEI_AMBIENT_VIEWING_ENVIRONMENT:
713
714 i4_status = ih264d_parse_ave(ps_bitstrm, ps_dec,
715 ui4_payload_size);
716 break;
717 case SEI_CONTENT_COLOR_VOLUME:
718
719 i4_status = ih264d_parse_ccv(ps_bitstrm, ps_dec,
720 ui4_payload_size);
721 break;
722 default:
723 i4_status = ih264d_flush_bits_h264(ps_bitstrm, (ui4_payload_size << 3));
724 break;
725 }
726 return (i4_status);
727 }
728
729 /*****************************************************************************/
730 /* */
731 /* Function Name : ih264d_parse_sei_message */
732 /* */
733 /* Description : This function is parses and decode SEI. Currently it's */
734 /* not implemented fully. */
735 /* Inputs : ps_dec Decoder parameters */
736 /* ps_bitstrm Bitstream */
737 /* Globals : None */
738 /* Processing : Parses SEI NAL units and stores the info */
739 /* Outputs : None */
740 /* Returns : None */
741 /* */
742 /* Issues : Not implemented fully */
743 /* */
744 /* Revision History: */
745 /* */
746 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
747 /* 06 05 2002 NS Draft */
748 /* */
749 /*****************************************************************************/
750
ih264d_parse_sei_message(dec_struct_t * ps_dec,dec_bit_stream_t * ps_bitstrm)751 WORD32 ih264d_parse_sei_message(dec_struct_t *ps_dec,
752 dec_bit_stream_t *ps_bitstrm)
753 {
754 UWORD32 ui4_payload_type, ui4_payload_size;
755 UWORD32 u4_bits;
756 WORD32 i4_status = 0;
757
758 do
759 {
760 ui4_payload_type = 0;
761
762 if(!CHECK_BITS_SUFFICIENT(ps_bitstrm, 8))
763 {
764 return ERROR_EOB_GETBITS_T;
765 }
766 u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8);
767 while(0xff == u4_bits && CHECK_BITS_SUFFICIENT(ps_bitstrm, 8))
768 {
769 u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8);
770 ui4_payload_type += 255;
771 }
772 ui4_payload_type += u4_bits;
773
774 ui4_payload_size = 0;
775 if(!CHECK_BITS_SUFFICIENT(ps_bitstrm, 8))
776 {
777 return ERROR_EOB_GETBITS_T;
778 }
779 u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8);
780 while(0xff == u4_bits && CHECK_BITS_SUFFICIENT(ps_bitstrm, 8))
781 {
782 u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8);
783 ui4_payload_size += 255;
784 }
785 ui4_payload_size += u4_bits;
786
787 if(!CHECK_BITS_SUFFICIENT(ps_bitstrm, (ui4_payload_size << 3)))
788 {
789 return ERROR_EOB_GETBITS_T;
790 }
791 i4_status = ih264d_parse_sei_payload(ps_bitstrm, ui4_payload_type,
792 ui4_payload_size, ps_dec);
793 if(i4_status != OK)
794 return i4_status;
795
796 if(ih264d_check_byte_aligned(ps_bitstrm) == 0)
797 {
798 u4_bits = ih264d_get_bit_h264(ps_bitstrm);
799 if(0 == u4_bits)
800 {
801 H264_DEC_DEBUG_PRINT("\nError in parsing SEI message");
802 }
803 while(0 == ih264d_check_byte_aligned(ps_bitstrm)
804 && CHECK_BITS_SUFFICIENT(ps_bitstrm, 1))
805 {
806 u4_bits = ih264d_get_bit_h264(ps_bitstrm);
807 if(u4_bits)
808 {
809 H264_DEC_DEBUG_PRINT("\nError in parsing SEI message");
810 }
811 }
812 }
813 }
814 while(MORE_RBSP_DATA(ps_bitstrm));
815 return (i4_status);
816 }
817
818 /*****************************************************************************/
819 /* */
820 /* Function Name : ih264d_export_sei_mdcv_params */
821 /* */
822 /* Description : This function populates SEI mdcv message in */
823 /* output structure */
824 /* Inputs : ps_sei_mdcv_op pointer to sei mdcv o\p struct */
825 /* : ps_sei pointer to decoded sei params */
826 /* Outputs : */
827 /* Returns : returns 0 for success; -1 for failure */
828 /* */
829 /* Issues : none */
830 /* */
831 /* Revision History: */
832 /* */
833 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
834 /* */
835 /* */
836 /*****************************************************************************/
ih264d_export_sei_mdcv_params(ivd_sei_decode_op_t * ps_sei_decode_op,sei * ps_sei,sei * ps_sei_export)837 WORD32 ih264d_export_sei_mdcv_params(ivd_sei_decode_op_t *ps_sei_decode_op,
838 sei *ps_sei, sei *ps_sei_export)
839 {
840 if((ps_sei_export == NULL) || (ps_sei == NULL))
841 {
842 return NOT_OK;
843 }
844
845 ps_sei_export->u1_sei_mdcv_params_present_flag = ps_sei->u1_sei_mdcv_params_present_flag;
846 ps_sei_decode_op->u1_sei_mdcv_params_present_flag = ps_sei->u1_sei_mdcv_params_present_flag;
847
848 if(0 == ps_sei_export->u1_sei_mdcv_params_present_flag)
849 {
850 memset(&ps_sei_export->s_sei_mdcv_params, 0, sizeof(sei_mdcv_params_t));
851 }
852 else
853 {
854 memcpy(&ps_sei_export->s_sei_mdcv_params, &ps_sei->s_sei_mdcv_params,
855 sizeof(sei_mdcv_params_t));
856 }
857
858 return (OK);
859 }
860
861 /*****************************************************************************/
862 /* */
863 /* Function Name : ih264d_export_sei_cll_params */
864 /* */
865 /* Description : This function populates SEI cll message in */
866 /* output structure */
867 /* Inputs : ps_sei_cll_op pointer to sei cll o\p struct */
868 /* : ps_sei pointer to decoded sei params */
869 /* Outputs : */
870 /* Returns : returns 0 for success; -1 for failure */
871 /* */
872 /* Issues : none */
873 /* */
874 /* Revision History: */
875 /* */
876 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
877 /* */
878 /* */
879 /*****************************************************************************/
ih264d_export_sei_cll_params(ivd_sei_decode_op_t * ps_sei_decode_op,sei * ps_sei,sei * ps_sei_export)880 WORD32 ih264d_export_sei_cll_params(ivd_sei_decode_op_t *ps_sei_decode_op,
881 sei *ps_sei, sei *ps_sei_export)
882 {
883 if((ps_sei_export == NULL) || (ps_sei == NULL))
884 {
885 return NOT_OK;
886 }
887
888 ps_sei_export->u1_sei_cll_params_present_flag = ps_sei->u1_sei_cll_params_present_flag;
889 ps_sei_decode_op->u1_sei_cll_params_present_flag = ps_sei->u1_sei_cll_params_present_flag;
890
891 if(0 == ps_sei_export->u1_sei_cll_params_present_flag)
892 {
893 memset(&ps_sei_export->s_sei_cll_params, 0, sizeof(sei_cll_params_t));
894 }
895 else
896 {
897 memcpy(&ps_sei_export->s_sei_cll_params, &ps_sei->s_sei_cll_params,
898 sizeof(sei_cll_params_t));
899 }
900 return (OK);
901 }
902
903 /*****************************************************************************/
904 /* */
905 /* Function Name : ih264d_export_sei_ave_params */
906 /* */
907 /* Description : This function populates SEI ave message in */
908 /* output structure */
909 /* Inputs : ps_sei_ave_op pointer to sei ave o\p struct */
910 /* : ps_sei pointer to decoded sei params */
911 /* Outputs : */
912 /* Returns : returns 0 for success; -1 for failure */
913 /* */
914 /* Issues : none */
915 /* */
916 /* Revision History: */
917 /* */
918 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
919 /* */
920 /* */
921 /*****************************************************************************/
ih264d_export_sei_ave_params(ivd_sei_decode_op_t * ps_sei_decode_op,sei * ps_sei,sei * ps_sei_export)922 WORD32 ih264d_export_sei_ave_params(ivd_sei_decode_op_t *ps_sei_decode_op,
923 sei *ps_sei, sei *ps_sei_export)
924 {
925 if((ps_sei_export == NULL) || (ps_sei == NULL))
926 {
927 return NOT_OK;
928 }
929
930 ps_sei_export->u1_sei_ave_params_present_flag = ps_sei->u1_sei_ave_params_present_flag;
931 ps_sei_decode_op->u1_sei_ave_params_present_flag = ps_sei->u1_sei_ave_params_present_flag;
932
933 if(0 == ps_sei_export->u1_sei_ave_params_present_flag)
934 {
935 memset(&ps_sei_export->s_sei_ave_params, 0, sizeof(sei_ave_params_t));
936 }
937 else
938 {
939 memcpy(&ps_sei_export->s_sei_ave_params, &ps_sei->s_sei_ave_params,
940 sizeof(sei_ave_params_t));
941 }
942
943 return (OK);
944 }
945
946 /*****************************************************************************/
947 /* */
948 /* Function Name : ih264d_export_sei_ccv_params */
949 /* */
950 /* Description : This function populates SEI ccv message in */
951 /* output structure */
952 /* Inputs : ps_sei_ccv_op pointer to sei ccv o\p struct */
953 /* : ps_sei pointer to decoded sei params */
954 /* Outputs : */
955 /* Returns : returns 0 for success; -1 for failure */
956 /* */
957 /* Issues : none */
958 /* */
959 /* Revision History: */
960 /* */
961 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
962 /* */
963 /* */
964 /*****************************************************************************/
ih264d_export_sei_ccv_params(ivd_sei_decode_op_t * ps_sei_decode_op,sei * ps_sei,sei * ps_sei_export)965 WORD32 ih264d_export_sei_ccv_params(ivd_sei_decode_op_t *ps_sei_decode_op,
966 sei *ps_sei, sei *ps_sei_export)
967 {
968 if((ps_sei_export == NULL) || (ps_sei == NULL))
969 {
970 return NOT_OK;
971 }
972
973 ps_sei_export->u1_sei_ccv_params_present_flag = ps_sei->u1_sei_ccv_params_present_flag;
974 ps_sei_decode_op->u1_sei_ccv_params_present_flag = ps_sei->u1_sei_ccv_params_present_flag;
975
976 if(0 == ps_sei_export->u1_sei_ccv_params_present_flag)
977 {
978 memset(&ps_sei_export->s_sei_ccv_params, 0, sizeof(sei_ccv_params_t));
979 }
980 else
981 {
982 memcpy(&ps_sei_export->s_sei_ccv_params, &ps_sei->s_sei_ccv_params,
983 sizeof(sei_ccv_params_t));
984 }
985 return (OK);
986 }
987
988