xref: /rockchip-linux_mpp/mpp/codec/dec/h264/h264d_sei.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /*
2 *
3 * Copyright 2015 Rockchip Electronics Co. LTD
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 #define MODULE_TAG  "h264d_sei"
19 
20 #include <limits.h>
21 #include <stdio.h>
22 #include <string.h>
23 
24 #include "h264d_global.h"
25 #include "h264d_sps.h"
26 #include "h264d_sei.h"
27 #include "h2645d_sei.h"
28 
interpret_picture_timing_info(BitReadCtx_t * p_bitctx,H264_SEI_t * sei_msg,H264dVideoCtx_t * p_videoctx)29 static MPP_RET interpret_picture_timing_info(
30     BitReadCtx_t *p_bitctx,
31     H264_SEI_t *sei_msg,
32     H264dVideoCtx_t *p_videoctx)
33 {
34     RK_S32 cpb_removal_delay_length = 0;
35     RK_S32 dpb_output_delay_length = 0;
36     RK_S32 time_offset_length = 0;
37     RK_S32 cpb_dpb_delays_present_flag = 0;
38     RK_U32 i = 0;
39     H264_SEI_PIC_TIMING_t *pic_timing = NULL;
40     RK_U32 num_clock_ts[9] = {1, 1, 1, 2, 2, 3, 3, 2, 3};
41     struct h264_vui_t *vui_seq_parameters = NULL;
42     RK_U32 seq_parameter_set_id = sei_msg->seq_parameter_set_id;
43 
44     if (seq_parameter_set_id >= MAXSPS || !p_videoctx->spsSet[seq_parameter_set_id]) {
45         H264D_ERR("seq_parameter_set_id %d may be invalid\n", seq_parameter_set_id);
46         goto __BITREAD_ERR;
47     }
48     vui_seq_parameters = &(p_videoctx->spsSet[sei_msg->seq_parameter_set_id]->vui_seq_parameters);
49     pic_timing = &(sei_msg->pic_timing);
50 
51     if (vui_seq_parameters->nal_hrd_parameters_present_flag) {
52         cpb_removal_delay_length =
53             vui_seq_parameters->nal_hrd_parameters.cpb_removal_delay_length_minus1;
54         dpb_output_delay_length =
55             vui_seq_parameters->nal_hrd_parameters.dpb_output_delay_length_minus1;
56         time_offset_length =
57             vui_seq_parameters->nal_hrd_parameters.time_offset_length;
58         cpb_dpb_delays_present_flag = 1;
59     } else if (vui_seq_parameters->vcl_hrd_parameters_present_flag) {
60         cpb_removal_delay_length =
61             vui_seq_parameters->vcl_hrd_parameters.cpb_removal_delay_length_minus1;
62         dpb_output_delay_length =
63             vui_seq_parameters->vcl_hrd_parameters.dpb_output_delay_length_minus1;
64         time_offset_length =
65             vui_seq_parameters->vcl_hrd_parameters.time_offset_length;
66         cpb_dpb_delays_present_flag = 1;
67     }
68 
69     if (cpb_dpb_delays_present_flag) {
70         READ_BITS(p_bitctx, cpb_removal_delay_length, &pic_timing->cpb_removal_delay);
71         READ_BITS(p_bitctx, dpb_output_delay_length, &pic_timing->dpb_output_delay);
72     }
73 
74     if (vui_seq_parameters->pic_struct_present_flag) {
75         READ_BITS(p_bitctx, 4, &pic_timing->pic_struct);
76         if (pic_timing->pic_struct > 8 || pic_timing->pic_struct < 0) {
77             goto __BITREAD_ERR;
78         }
79 
80         for (i = 0; i < num_clock_ts[pic_timing->pic_struct]; i++) {
81             READ_BITS(p_bitctx, 1, &pic_timing->clock_timestamp_flag[i]);
82 
83             if (pic_timing->clock_timestamp_flag[i]) {
84                 READ_BITS(p_bitctx, 2, &pic_timing->ct_type[i]);
85                 READ_BITS(p_bitctx, 1, &pic_timing->nuit_field_based_flag[i]);
86 
87                 READ_BITS(p_bitctx, 5, &pic_timing->counting_type[i]);
88                 if (pic_timing->counting_type[i] > 6
89                     || pic_timing->counting_type[i] < 0) {
90                     goto __BITREAD_ERR;
91                 }
92 
93                 READ_BITS(p_bitctx, 1, &pic_timing->full_timestamp_flag[i]);
94                 READ_BITS(p_bitctx, 1, &pic_timing->discontinuity_flag[i]);
95                 READ_BITS(p_bitctx, 1, &pic_timing->cnt_dropped_flag[i]);
96 
97                 READ_BITS(p_bitctx, 8, &pic_timing->n_frames[i]);
98 
99                 if (pic_timing->full_timestamp_flag[i]) {
100                     READ_BITS(p_bitctx, 6, &pic_timing->seconds_value[i]);
101                     if (pic_timing->seconds_value[i] > 59) {
102                         goto __BITREAD_ERR;
103                     }
104 
105                     READ_BITS(p_bitctx, 6, &pic_timing->minutes_value[i]);
106                     if (pic_timing->minutes_value[i] > 59) {
107                         goto __BITREAD_ERR;
108                     }
109 
110                     READ_BITS(p_bitctx, 5, &pic_timing->hours_value[i]);
111                     if (pic_timing->hours_value[i] > 23) {
112                         goto __BITREAD_ERR;
113                     }
114                 } else {
115                     READ_BITS(p_bitctx, 1, &pic_timing->seconds_flag[i]);
116                     if (pic_timing->seconds_flag[i]) {
117                         READ_BITS(p_bitctx, 6, &pic_timing->seconds_value[i]);
118                         if (pic_timing->seconds_value[i] > 59) {
119                             goto __BITREAD_ERR;
120                         }
121 
122                         READ_BITS(p_bitctx, 1, &pic_timing->minutes_flag[i]);
123                         if (pic_timing->minutes_flag[i]) {
124                             READ_BITS(p_bitctx, 6, &pic_timing->minutes_value[i]);
125                             if (pic_timing->minutes_value[i] > 59) {
126                                 goto __BITREAD_ERR;
127                             }
128 
129                             READ_BITS(p_bitctx, 1, &pic_timing->hours_flag[i]);
130                             if (pic_timing->hours_flag[i]) {
131                                 READ_BITS(p_bitctx, 5, &pic_timing->hours_value[i]);
132                                 if (pic_timing->hours_value[i] > 23) {
133                                     goto __BITREAD_ERR;
134                                 }
135                             }
136                         }
137                     }
138                 }
139                 if (time_offset_length) {
140                     RK_S32 tmp;
141                     READ_BITS(p_bitctx, time_offset_length, &tmp);
142                     /* following "converts" timeOffsetLength-bit signed
143                      * integer into i32 */
144                     /*lint -save -e701 -e702 */
145                     tmp <<= (32 - time_offset_length);
146                     tmp >>= (32 - time_offset_length);
147                     /*lint -restore */
148                     pic_timing->time_offset[i] = tmp;
149                 } else
150                     pic_timing->time_offset[i] = 0;
151             }
152         }
153     }
154 
155     return MPP_OK;
156 __BITREAD_ERR:
157     return MPP_ERR_STREAM;
158 }
159 
interpret_buffering_period_info(BitReadCtx_t * p_bitctx,H264_SEI_t * sei_msg,H264dVideoCtx_t * p_videoctx)160 static MPP_RET interpret_buffering_period_info(
161     BitReadCtx_t *p_bitctx,
162     H264_SEI_t *sei_msg,
163     H264dVideoCtx_t *p_videoctx)
164 {
165     MPP_RET ret = MPP_ERR_UNKNOW;
166     RK_U32 i = 0;
167     RK_U32 seq_parameter_set_id = sei_msg->seq_parameter_set_id;
168     struct h264_vui_t *vui_seq_parameters = NULL;
169 
170     READ_UE(p_bitctx, &seq_parameter_set_id);
171 
172     if (seq_parameter_set_id >= MAXSPS || !p_videoctx->spsSet[seq_parameter_set_id]) {
173         H264D_ERR("seq_parameter_set_id %d may be invalid\n", seq_parameter_set_id);
174         goto __BITREAD_ERR;
175     }
176 
177     sei_msg->seq_parameter_set_id = seq_parameter_set_id;
178     vui_seq_parameters = &(p_videoctx->spsSet[sei_msg->seq_parameter_set_id]->vui_seq_parameters);
179 
180     if (vui_seq_parameters->nal_hrd_parameters_present_flag) {
181         for (i = 0; i < vui_seq_parameters->nal_hrd_parameters.cpb_cnt_minus1; i++) {
182             SKIP_BITS(p_bitctx,
183                       vui_seq_parameters->nal_hrd_parameters.initial_cpb_removal_delay_length_minus1); //initial_cpb_removal_delay
184             SKIP_BITS(p_bitctx,
185                       vui_seq_parameters->nal_hrd_parameters.initial_cpb_removal_delay_length_minus1); //initial_cpb_removal_delay_offset
186         }
187     }
188 
189     if (vui_seq_parameters->vcl_hrd_parameters_present_flag) {
190         for (i = 0; i < vui_seq_parameters->vcl_hrd_parameters.cpb_cnt_minus1; i++) {
191             SKIP_BITS(p_bitctx,
192                       vui_seq_parameters->vcl_hrd_parameters.initial_cpb_removal_delay_length_minus1); //initial_cpb_removal_delay
193             SKIP_BITS(p_bitctx,
194                       vui_seq_parameters->vcl_hrd_parameters.initial_cpb_removal_delay_length_minus1); //initial_cpb_removal_delay_offset
195         }
196     }
197 
198     return ret = MPP_OK;
199 __BITREAD_ERR:
200     ret = p_bitctx->ret;
201     return ret;
202 
203 }
204 
interpret_recovery_point(BitReadCtx_t * p_bitctx,H264dVideoCtx_t * p_videoctx)205 static MPP_RET interpret_recovery_point(BitReadCtx_t *p_bitctx, H264dVideoCtx_t *p_videoctx)
206 {
207     RK_S32 recovery_frame_cnt = 0;
208 
209     READ_UE(p_bitctx, &recovery_frame_cnt);
210 
211     if (recovery_frame_cnt >= (1 << 16) || recovery_frame_cnt < 0) {
212         H264D_DBG(H264D_DBG_SEI, "recovery_frame_cnt %d, is out of range %d",
213                   recovery_frame_cnt, p_videoctx->max_frame_num);
214         return MPP_ERR_STREAM;
215     }
216 
217     memset(&p_videoctx->recovery, 0, sizeof(RecoveryPoint));
218 
219     p_videoctx->recovery.valid_flag = 1;
220     p_videoctx->recovery.recovery_frame_cnt = recovery_frame_cnt;
221     H264D_DBG(H264D_DBG_SEI, "Recovery point: frame_cnt %d", p_videoctx->recovery.recovery_frame_cnt);
222     return MPP_OK;
223 __BITREAD_ERR:
224     return p_bitctx->ret;
225 }
226 
227 /*!
228 ***********************************************************************
229 * \brief
230 *    parse SEI information
231 ***********************************************************************
232 */
233 //extern "C"
process_sei(H264_SLICE_t * currSlice)234 MPP_RET process_sei(H264_SLICE_t *currSlice)
235 {
236     RK_S32  tmp_byte = 0;
237     MPP_RET ret = MPP_ERR_UNKNOW;
238     H264_SEI_t *sei_msg  = NULL;
239     BitReadCtx_t *p_bitctx = &currSlice->p_Cur->bitctx;
240     BitReadCtx_t payload_bitctx;
241     RK_S32 i = 0;
242 
243     if (!currSlice->p_Cur->sei)
244         currSlice->p_Cur->sei = mpp_calloc(H264_SEI_t, 1);
245 
246     sei_msg = currSlice->p_Cur->sei;
247     sei_msg->mvc_scalable_nesting_flag = 0;  //init to false
248     sei_msg->p_Dec = currSlice->p_Dec;
249     do {
250         tmp_byte = 0xFF;
251         sei_msg->type = 0;
252         while (tmp_byte == 0xFF) {
253             if (p_bitctx->bytes_left_ < 2 || sei_msg->type > INT_MAX - 255) {
254                 mpp_err("parse payload_type error: byte_left %d payload_type %d\n",
255                         p_bitctx->bytes_left_, sei_msg->type);
256                 return MPP_ERR_STREAM;
257             }
258 
259             READ_BITS(p_bitctx, 8, &tmp_byte);
260             sei_msg->type += tmp_byte;
261         }
262 
263         tmp_byte = 0xFF;
264         sei_msg->payload_size = 0;
265         while (tmp_byte == 0xFF) {
266             if ((RK_S32)p_bitctx->bytes_left_ < sei_msg->payload_size + 1) {
267                 mpp_err("parse payload_size error: byte_left %d payload_size %d\n",
268                         p_bitctx->bytes_left_, sei_msg->payload_size + 1);
269                 return MPP_ERR_STREAM;
270             }
271 
272             READ_BITS(p_bitctx, 8, &tmp_byte);
273             sei_msg->payload_size += tmp_byte;
274         }
275 
276         if ((RK_S32)p_bitctx->bytes_left_ < sei_msg->payload_size) {
277             mpp_err("parse payload_size error: byte_left %d payload_size %d\n",
278                     p_bitctx->bytes_left_, sei_msg->payload_size);
279             return MPP_ERR_STREAM;
280         }
281 
282         H264D_DBG(H264D_DBG_SEI, "SEI type %d, payload size: %d\n", sei_msg->type, sei_msg->payload_size);
283 
284         memset(&payload_bitctx, 0, sizeof(payload_bitctx));
285         mpp_set_bitread_ctx(&payload_bitctx, p_bitctx->data_, sei_msg->payload_size);
286         mpp_set_bitread_pseudo_code_type(&payload_bitctx, PSEUDO_CODE_H264_H265_SEI);
287 
288         switch (sei_msg->type) {
289         case H264_SEI_BUFFERING_PERIOD:
290             FUN_CHECK(ret = interpret_buffering_period_info(&payload_bitctx, sei_msg, currSlice->p_Vid));
291             break;
292         case H264_SEI_PIC_TIMING:
293             FUN_CHECK(interpret_picture_timing_info(&payload_bitctx, sei_msg, currSlice->p_Vid));
294             break;
295         case H264_SEI_USER_DATA_UNREGISTERED:
296             FUN_CHECK(check_encoder_sei_info(&payload_bitctx, sei_msg->payload_size, &currSlice->p_Vid->deny_flag));
297 
298             if (currSlice->p_Vid->deny_flag)
299                 H264D_DBG(H264D_DBG_SEI, "Bitstream is encoded by special encoder.");
300             break;
301         case H264_SEI_RECOVERY_POINT:
302             FUN_CHECK(interpret_recovery_point(&payload_bitctx, currSlice->p_Vid));
303             break;
304         default:
305             H264D_DBG(H264D_DBG_SEI, "Skip parsing SEI type %d\n", sei_msg->type);
306             break;
307         }
308 
309         H264D_DBG(H264D_DBG_SEI, "After parsing SEI %d, bits left int cur byte %d, bits_used %d, bytes left %d",
310                   sei_msg->type, payload_bitctx.num_remaining_bits_in_curr_byte_, payload_bitctx.used_bits,
311                   payload_bitctx.bytes_left_);
312 
313         for (i = 0; i < sei_msg->payload_size; i++)
314             SKIP_BITS(p_bitctx, 8);
315     } while (mpp_has_more_rbsp_data(p_bitctx));    // more_rbsp_data()  msg[offset] != 0x80
316 
317     return ret = MPP_OK;
318 __BITREAD_ERR:
319 __FAILED:
320     return ret;
321 }
322