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