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