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
24 *  ih264e_sei.c
25 *
26 * @brief
27 *  This file contains function definitions related to SEI NAL's header encoding
28 *
29 * @author
30 *  ittiam
31 *
32 * @par List of Functions:
33 *  - ih264e_put_sei_mdcv_params
34 *  - ih264e_put_sei_cll_params
35 *  - ih264e_put_sei_ave_params
36 *  - ih264e_put_sei_ccv_params
37 *  - ih264e_put_sei_msg
38 *
39 * @remarks
40 *  None
41 *
42 *******************************************************************************
43 */
44 
45 /*****************************************************************************/
46 /* File Includes                                                             */
47 /*****************************************************************************/
48 
49 /* System include files */
50 #include <stdio.h>
51 #include <stddef.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <assert.h>
55 
56 /* User include files */
57 #include "ih264_typedefs.h"
58 #include "iv2.h"
59 #include "ive2.h"
60 #include "ih264_macros.h"
61 #include "ih264_platform_macros.h"
62 #include "ih264e_trace.h"
63 #include "ih264e_error.h"
64 #include "ih264e_bitstream.h"
65 #include "ih264_defs.h"
66 #include "ih264_structs.h"
67 #include "ih264_cabac_tables.h"
68 #include "ih264e_cabac_structs.h"
69 #include "irc_cntrl_param.h"
70 #include "ime_distortion_metrics.h"
71 #include "ime_defs.h"
72 #include "ime_structs.h"
73 #include "ih264e_defs.h"
74 #include "irc_cntrl_param.h"
75 #include "irc_frame_info_collector.h"
76 #include "ih264_trans_quant_itrans_iquant.h"
77 #include "ih264_inter_pred_filters.h"
78 #include "ih264_deblk_edge_filters.h"
79 #include "ih264e_structs.h"
80 #include "ih264e_encode_header.h"
81 #include "ih264e_sei.h"
82 
83 /*****************************************************************************/
84 /* Function Definitions                                                      */
85 /*****************************************************************************/
86 
87 /**
88 ******************************************************************************
89 *
90 *  @brief Generates Mastering Display Color Volume (Supplemental Enhancement Information )
91 *
92 *  @par   Description
93 *  Parse Supplemental Enhancement Information
94 *
95 *  @param[in]   ps_bitstrm
96 *  pointer to bitstream context (handle)
97 *
98 *  @param[in]   ps_sei_mdcv
99 *  pointer to structure containing mdcv SEI data
100 *
101 *  @return      success or failure error code
102 *
103 ******************************************************************************
104 */
ih264e_put_sei_mdcv_params(sei_mdcv_params_t * ps_sei_mdcv,bitstrm_t * ps_bitstrm)105 IH264E_ERROR_T ih264e_put_sei_mdcv_params(sei_mdcv_params_t *ps_sei_mdcv,
106                                  bitstrm_t *ps_bitstrm)
107 {
108     WORD32 return_status = IH264E_SUCCESS;
109     UWORD8 u1_payload_size = 0;
110     UWORD32 u4_count;
111 
112     if(ps_sei_mdcv == NULL)
113     {
114         return IH264E_FAIL;
115     }
116 
117     u1_payload_size += (NUM_SEI_MDCV_PRIMARIES * 2); /* display primaries x */
118     u1_payload_size += (NUM_SEI_MDCV_PRIMARIES * 2); /* display primaries y */
119     u1_payload_size += 2; /* white point x */
120     u1_payload_size += 2; /* white point y */
121     u1_payload_size += 4; /* max display mastering luminance */
122     u1_payload_size += 4; /* min display mastering luminance */
123 
124     /************************************************************************/
125     /* PayloadSize : This is the size of the payload in bytes               */
126     /************************************************************************/
127     PUT_BITS(ps_bitstrm, u1_payload_size, 8, return_status, "u1_payload_size");
128 
129     /*******************************************************************************/
130     /* Put the mastering display color volume SEI parameters into the bitstream.   */
131     /*******************************************************************************/
132 
133     /* display primaries x */
134     for(u4_count = 0; u4_count < NUM_SEI_MDCV_PRIMARIES; u4_count++)
135     {
136         PUT_BITS(ps_bitstrm, ps_sei_mdcv->au2_display_primaries_x[u4_count], 16,
137                                 return_status, "u2_display_primaries_x");
138 
139         PUT_BITS(ps_bitstrm, ps_sei_mdcv->au2_display_primaries_y[u4_count], 16,
140                                 return_status, "u2_display_primaries_y");
141     }
142 
143     /* white point x */
144     PUT_BITS(ps_bitstrm, ps_sei_mdcv->u2_white_point_x, 16, return_status, "u2_white point x");
145 
146     /* white point y */
147     PUT_BITS(ps_bitstrm, ps_sei_mdcv->u2_white_point_y, 16, return_status, "u2_white point y");
148 
149     /* max display mastering luminance */
150     PUT_BITS(ps_bitstrm, ps_sei_mdcv->u4_max_display_mastering_luminance, 32,
151                                 return_status, "u4_max_display_mastering_luminance");
152 
153     /* min display mastering luminance */
154     PUT_BITS(ps_bitstrm, ps_sei_mdcv->u4_min_display_mastering_luminance, 32,
155                                 return_status, "u4_max_display_mastering_luminance");
156 
157     return (return_status);
158 }
159 
160 /**
161 ******************************************************************************
162 *
163 *  @brief Stores content light level info in bitstream
164 *
165 *  @par   Description
166 *  Parse Supplemental Enhancement Information
167 *
168 *  @param[in]   ps_bitstrm
169 *  pointer to bitstream context (handle)
170 *
171 *  @param[in]   ps_sei_cll
172 *  Pinter to structure containing cll sei params
173 *
174 *  @return      success or failure error code
175 *
176 ******************************************************************************
177 */
ih264e_put_sei_cll_params(sei_cll_params_t * ps_sei_cll,bitstrm_t * ps_bitstrm)178 IH264E_ERROR_T ih264e_put_sei_cll_params(sei_cll_params_t *ps_sei_cll,
179                                 bitstrm_t *ps_bitstrm)
180 {
181     WORD32 return_status = IH264E_SUCCESS;
182     UWORD8 u1_payload_size = 0;
183 
184     if(ps_sei_cll == NULL)
185     {
186         return IH264E_FAIL;
187     }
188 
189     u1_payload_size += 2; /* max pic average light level */
190     u1_payload_size += 2; /* max content light level */
191 
192     /************************************************************************/
193     /* PayloadSize : This is the size of the payload in bytes               */
194     /************************************************************************/
195     PUT_BITS(ps_bitstrm, u1_payload_size, 8, return_status, "u1_payload_size");
196 
197     PUT_BITS(ps_bitstrm, ps_sei_cll->u2_max_content_light_level, 16,
198                                 return_status, "u2_max_content_light_level");
199     PUT_BITS(ps_bitstrm, ps_sei_cll->u2_max_pic_average_light_level, 16,
200                                 return_status, "u2_max_pic_average_light_level");
201 
202     return (return_status);
203 }
204 
205 /**
206 ******************************************************************************
207 *
208 *  @brief Stores ambient viewing environment info in bitstream
209 *
210 *  @par   Description
211 *  Parse Supplemental Enhancement Information
212 *
213 *  @param[in]   ps_bitstrm
214 *  pointer to bitstream context (handle)
215 *
216 *  @param[in]   ps_sei_ave
217 *  pointer to ambient viewing environment info
218 *
219 *  @return      success or failure error code
220 *
221 ******************************************************************************
222 */
ih264e_put_sei_ave_params(sei_ave_params_t * ps_sei_ave,bitstrm_t * ps_bitstrm)223 IH264E_ERROR_T ih264e_put_sei_ave_params(sei_ave_params_t *ps_sei_ave,
224                                 bitstrm_t *ps_bitstrm)
225 {
226     WORD32 return_status = IH264E_SUCCESS;
227     UWORD8 u1_payload_size = 0;
228 
229     if(ps_sei_ave == NULL)
230     {
231         return IH264E_FAIL;
232     }
233 
234     u1_payload_size += 4; /* ambient illuminance */
235     u1_payload_size += 2; /* ambient light x */
236     u1_payload_size += 2; /* ambient light y */
237 
238     /************************************************************************/
239     /* PayloadSize : This is the size of the payload in bytes               */
240     /************************************************************************/
241     PUT_BITS(ps_bitstrm, u1_payload_size, 8, return_status, "u1_payload_size");
242 
243     PUT_BITS(ps_bitstrm, ps_sei_ave->u4_ambient_illuminance, 32,
244                                 return_status, "u4_ambient_illuminance");
245     PUT_BITS(ps_bitstrm, ps_sei_ave->u2_ambient_light_x, 16,
246                                 return_status, "u2_ambient_light_x");
247     PUT_BITS(ps_bitstrm, ps_sei_ave->u2_ambient_light_y, 16,
248                                 return_status, "u2_ambient_light_y");
249 
250     return (return_status);
251 }
252 
253 /**
254 ******************************************************************************
255 *
256 *  @brief Generates Content Color Volume info (Supplemental Enhancement Information )
257 *
258 *  @par   Description
259 *  Parse Supplemental Enhancement Information
260 *
261 *  @param[in]   ps_bitstrm
262 *  pointer to bitstream context (handle)
263 *
264 *  @param[in]   ps_sei_ccv
265 *  pointer to structure containing CCV SEI data
266 *
267 *  @return      success or failure error code
268 *
269 ******************************************************************************
270 */
ih264e_put_sei_ccv_params(sei_ccv_params_t * ps_sei_ccv,bitstrm_t * ps_bitstrm)271 IH264E_ERROR_T ih264e_put_sei_ccv_params(sei_ccv_params_t *ps_sei_ccv,
272                                 bitstrm_t *ps_bitstrm)
273 {
274     WORD32 return_status = IH264E_SUCCESS;
275     UWORD16 u2_payload_bits = 0;
276     UWORD8  u1_payload_bytes = 0;
277     UWORD32 u4_count;
278 
279     if(ps_sei_ccv == NULL)
280     {
281         return IH264E_FAIL;
282     }
283 
284     u2_payload_bits += 1;   /* ccv cancel flag */
285     if(0 == (UWORD32)ps_sei_ccv->u1_ccv_cancel_flag)
286     {
287         u2_payload_bits += 1;   /* ccv persistence flag */
288         u2_payload_bits += 1;   /* ccv primaries present flag */
289         u2_payload_bits += 1;   /* ccv min luminance value present flag */
290         u2_payload_bits += 1;   /* ccv max luminance value present flag */
291         u2_payload_bits += 1;   /* ccv avg luminance value present flag */
292         u2_payload_bits += 2;   /* ccv reserved zero 2bits */
293         if(1 == ps_sei_ccv->u1_ccv_primaries_present_flag)
294         {
295             u2_payload_bits += (NUM_SEI_CCV_PRIMARIES * 32);  /* ccv primaries x[ c ] */
296             u2_payload_bits += (NUM_SEI_CCV_PRIMARIES * 32);  /* ccv primaries y[ c ] */
297         }
298         if(1 == ps_sei_ccv->u1_ccv_min_luminance_value_present_flag)
299         {
300             u2_payload_bits += 32;  /* ccv min luminance value */
301         }
302         if(1 == ps_sei_ccv->u1_ccv_max_luminance_value_present_flag)
303         {
304             u2_payload_bits += 32;  /* ccv max luminance value */
305         }
306         if(1 == ps_sei_ccv->u1_ccv_avg_luminance_value_present_flag)
307         {
308             u2_payload_bits += 32;  /* ccv avg luminance value */
309         }
310     }
311 
312     u1_payload_bytes = (UWORD8)((u2_payload_bits + 7) >> 3);
313     /************************************************************************/
314     /* PayloadSize : This is the size of the payload in bytes               */
315     /************************************************************************/
316     PUT_BITS(ps_bitstrm, u1_payload_bytes, 8, return_status, "u1_payload_bytes");
317 
318     /*******************************************************************************/
319     /* Put the Content Color Volume SEI parameters into the bitstream.  */
320     /*******************************************************************************/
321 
322     PUT_BITS(ps_bitstrm, ps_sei_ccv->u1_ccv_cancel_flag, 1,
323                             return_status, "u1_ccv_cancel_flag");
324 
325     if(0 == ps_sei_ccv->u1_ccv_cancel_flag)
326     {
327         PUT_BITS(ps_bitstrm, ps_sei_ccv->u1_ccv_persistence_flag, 1,
328                                 return_status, "u1_ccv_persistence_flag");
329         PUT_BITS(ps_bitstrm, ps_sei_ccv->u1_ccv_primaries_present_flag, 1,
330                                 return_status, "u1_ccv_primaries_present_flag");
331         PUT_BITS(ps_bitstrm, ps_sei_ccv->u1_ccv_min_luminance_value_present_flag, 1,
332                                 return_status, "u1_ccv_min_luminance_value_present_flag");
333         PUT_BITS(ps_bitstrm, ps_sei_ccv->u1_ccv_max_luminance_value_present_flag, 1,
334                                 return_status, "u1_ccv_max_luminance_value_present_flag");
335         PUT_BITS(ps_bitstrm, ps_sei_ccv->u1_ccv_avg_luminance_value_present_flag, 1,
336                                 return_status, "u1_ccv_avg_luminance_value_present_flag");
337         PUT_BITS(ps_bitstrm, ps_sei_ccv->u1_ccv_reserved_zero_2bits, 2,
338                                 return_status, "u1_ccv_reserved_zero_2bits");
339 
340         /* ccv primaries */
341         if(1 == ps_sei_ccv->u1_ccv_primaries_present_flag)
342         {
343             for(u4_count = 0; u4_count < NUM_SEI_CCV_PRIMARIES; u4_count++)
344             {
345                 PUT_BITS(ps_bitstrm, ps_sei_ccv->ai4_ccv_primaries_x[u4_count], 32,
346                                 return_status, "i4_ccv_primaries_x");
347                 PUT_BITS(ps_bitstrm, ps_sei_ccv->ai4_ccv_primaries_y[u4_count], 32,
348                                 return_status, "i4_ccv_primaries_y");
349             }
350         }
351 
352         if(1 == ps_sei_ccv->u1_ccv_min_luminance_value_present_flag)
353         {
354             PUT_BITS(ps_bitstrm, ps_sei_ccv->u4_ccv_min_luminance_value, 32,
355                                 return_status, "u4_ccv_min_luminance_value");
356         }
357         if(1 == ps_sei_ccv->u1_ccv_max_luminance_value_present_flag)
358         {
359             PUT_BITS(ps_bitstrm, ps_sei_ccv->u4_ccv_max_luminance_value, 32,
360                                 return_status, "u4_ccv_max_luminance_value");
361         }
362         if(1 == ps_sei_ccv->u1_ccv_avg_luminance_value_present_flag)
363         {
364             PUT_BITS(ps_bitstrm, ps_sei_ccv->u4_ccv_avg_luminance_value, 32,
365                                 return_status, "u4_ccv_avg_luminance_value");
366         }
367     }
368 
369     return (return_status);
370 }
371 
372 /**
373 ******************************************************************************
374 *
375 *  @brief Generates SEI (Supplemental Enhancement Information )
376 *
377 *  @par   Description
378 *  Parse Supplemental Enhancement Information
379 *
380 *  @param[in]   e_payload_type
381 *  Determines the type of SEI msg
382 *
383 *  @param[in]   ps_bitstrm
384 *  pointer to bitstream context (handle)
385 *
386 *  @param[in]   ps_sei_params
387 *  pointer to structure containing SEI data
388 *               buffer period, recovery point, picture timing
389 *
390 *  @return      success or failure error code
391 *
392 ******************************************************************************
393 */
ih264e_put_sei_msg(IH264_SEI_TYPE e_payload_type,sei_params_t * ps_sei_params,bitstrm_t * ps_bitstrm)394 IH264E_ERROR_T ih264e_put_sei_msg(IH264_SEI_TYPE e_payload_type,
395                          sei_params_t *ps_sei_params,
396                          bitstrm_t *ps_bitstrm)
397 {
398     WORD32 return_status = IH264E_SUCCESS;
399 
400     /************************************************************************/
401     /* PayloadType : Send in the SEI type in the stream                     */
402     /************************************************************************/
403 
404     UWORD32 u4_payload_type = e_payload_type;
405 
406     while(u4_payload_type > 0xFF)
407     {
408         PUT_BITS(ps_bitstrm, 0xFF, 8, return_status, "payload");
409         u4_payload_type -= 0xFF;
410     }
411 
412     PUT_BITS(ps_bitstrm, (UWORD32)u4_payload_type, 8, return_status, "e_payload_type");
413 
414     switch(e_payload_type)
415     {
416     case IH264_SEI_MASTERING_DISP_COL_VOL :
417         return_status = ih264e_put_sei_mdcv_params(&(ps_sei_params->s_sei_mdcv_params),
418                                                     ps_bitstrm);
419         break;
420 
421     case IH264_SEI_CONTENT_LIGHT_LEVEL_DATA :
422         return_status = ih264e_put_sei_cll_params(&(ps_sei_params->s_sei_cll_params),
423                                                     ps_bitstrm);
424         break;
425 
426     case IH264_SEI_AMBIENT_VIEWING_ENVIRONMENT :
427         return_status = ih264e_put_sei_ave_params(&(ps_sei_params->s_sei_ave_params),
428                                                     ps_bitstrm);
429         break;
430 
431     case IH264_SEI_CONTENT_COLOR_VOLUME :
432          return_status = ih264e_put_sei_ccv_params(&(ps_sei_params->s_sei_ccv_params),
433                                                     ps_bitstrm);
434          break;
435 
436     default :
437         return_status = IH264E_FAIL;
438     }
439 
440     /* rbsp trailing bits */
441     if((IH264E_SUCCESS == return_status) && (ps_bitstrm->i4_bits_left_in_cw & 0x7))
442         return_status = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
443 
444     return(return_status);
445 }
446 
447 
448