1 /*
2 * Copyright 2015 Rockchip Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define MODULE_TAG "h265e_header_gen"
18
19 #include <string.h>
20
21 #include "mpp_mem.h"
22 #include "mpp_common.h"
23
24 #include "mpp_packet_impl.h"
25
26 #include "h265e_ps.h"
27 #include "h265e_header_gen.h"
28
h265e_nals_init(H265eExtraInfo * out)29 static void h265e_nals_init(H265eExtraInfo *out)
30 {
31 out->nal_buf = mpp_calloc(RK_U8, H265E_EXTRA_INFO_BUF_SIZE);
32 out->nal_num = 0;
33 }
34
h265e_nals_deinit(H265eExtraInfo * out)35 static void h265e_nals_deinit(H265eExtraInfo *out)
36 {
37 MPP_FREE(out->nal_buf);
38
39 out->nal_num = 0;
40 }
41
h265e_nal_escape_c(RK_U8 * dst,RK_U8 * src,RK_U8 * end)42 static RK_U8 *h265e_nal_escape_c(RK_U8 *dst, RK_U8 *src, RK_U8 *end)
43 {
44 if (src < end) *dst++ = *src++;
45 if (src < end) *dst++ = *src++;
46 while (src < end) {
47 // if (src[0] <= 0x03 && !dst[-2] && !dst[-1])
48 // *dst++ = 0x03;
49 *dst++ = *src++;
50 }
51 return dst;
52 }
53
h265e_nal_encode(RK_U8 * dst,H265eNal * nal)54 static void h265e_nal_encode(RK_U8 *dst, H265eNal *nal)
55 {
56 RK_S32 b_annexb = 1;
57 RK_S32 size = 0;
58 RK_U8 *src = nal->p_payload;
59 RK_U8 *end = nal->p_payload + nal->i_payload;
60 RK_U8 *orig_dst = dst;
61 MppWriteCtx s;
62
63 if (b_annexb) {
64 *dst++ = 0x00;
65 *dst++ = 0x00;
66 *dst++ = 0x00;
67 *dst++ = 0x01;
68 } else /* save room for size later */
69 dst += 4;
70
71 /* nal header */
72 mpp_writer_init(&s, dst, 10);
73 mpp_writer_put_bits(&s, 0, 1); //forbidden_zero_bit
74 mpp_writer_put_bits(&s, nal->i_type, 6);//nal_unit_type
75 mpp_writer_put_bits(&s, 0, 6); //nuh_reserved_zero_6bits
76 mpp_writer_put_bits(&s, nal->temporal_id + 1, 3); //nuh_temporal_id_plus1
77 dst += 2;
78 dst = h265e_nal_escape_c(dst, src, end);
79 size = (RK_S32)((dst - orig_dst) - 4);
80
81 /* Write the size header for mp4/etc */
82 if (!b_annexb) {
83 /* Size doesn't include the size of the header we're writing now. */
84 orig_dst[0] = size >> 24;
85 orig_dst[1] = size >> 16;
86 orig_dst[2] = size >> 8;
87 orig_dst[3] = size >> 0;
88 }
89
90 nal->i_payload = size + 4;
91 nal->p_payload = orig_dst;
92 }
93
h265e_encapsulate_nals(H265eExtraInfo * out)94 static MPP_RET h265e_encapsulate_nals(H265eExtraInfo *out)
95 {
96 RK_S32 i = 0;
97 RK_S32 i_avcintra_class = 0;
98 RK_S32 nal_size = 0;
99 RK_S32 necessary_size = 0;
100 RK_U8 *nal_buffer = out->nal_buf;
101 RK_S32 nal_num = out->nal_num;
102 H265eNal *nal = out->nal;
103
104 h265e_dbg_func("enter\n");
105 for (i = 0; i < nal_num; i++)
106 nal_size += nal[i].i_payload;
107
108 /* Worst-case NAL unit escaping: reallocate the buffer if it's too small. */
109 necessary_size = nal_size * 3 / 2 + nal_num * 4 + 4 + 64;
110 for (i = 0; i < nal_num; i++)
111 necessary_size += nal[i].i_padding;
112
113 for (i = 0; i < nal_num; i++) {
114 nal[i].b_long_startcode = !i ||
115 nal[i].i_type == NAL_VPS ||
116 nal[i].i_type == NAL_SPS ||
117 nal[i].i_type == NAL_PPS ||
118 i_avcintra_class;
119 h265e_nal_encode(nal_buffer, &nal[i]);
120 nal_buffer += nal[i].i_payload;
121 }
122
123 h265e_dbg(H265E_DBG_HEADER, "nals total size: %d bytes, necessary_size %d",
124 nal_buffer - out->nal_buf, necessary_size);
125
126 h265e_dbg_func("leave\n");
127 return MPP_OK;
128 }
129
h265e_write_recovery_point(H265eStream * s,RK_U32 recovery_frame_cnt)130 static MPP_RET h265e_write_recovery_point(H265eStream * s, RK_U32 recovery_frame_cnt)
131 {
132 h265e_stream_write_se_with_log(s, recovery_frame_cnt, NULL);
133 h265e_stream_write1_with_log(s, 1, NULL);
134 h265e_stream_write1_with_log(s, 0, NULL);
135 h265e_stream_rbsp_trailing(s);
136 return MPP_OK;
137 }
138
h265e_sei_write(H265eStream * s,RK_U8 uuid[16],const RK_U8 * payload,RK_S32 payload_size,RK_S32 payload_type)139 static MPP_RET h265e_sei_write(H265eStream *s, RK_U8 uuid[16], const RK_U8 *payload,
140 RK_S32 payload_size, RK_S32 payload_type)
141 {
142 RK_S32 i = 0;
143 RK_S32 uuid_len = H265E_UUID_LENGTH;
144 RK_S32 data_len = payload_size;
145
146 h265e_dbg_func("enter\n");
147
148 h265e_stream_realign(s);
149
150 switch (payload_type) {
151 case H265_SEI_USER_DATA_UNREGISTERED : {
152 payload_size += uuid_len;
153 } break;
154 case H265_SEI_RECOVERY_POINT: {
155 H265eStream stream;
156 h265e_stream_init(&stream);
157 h265e_write_recovery_point(&stream, ((RK_U32 *)payload)[0]);
158 payload_size = stream.enc_stream.byte_cnt;
159 h265e_stream_deinit(&stream);
160 } break;
161 default: {
162 mpp_err_f("payload_type %d is no process ", payload_type);
163 } break;
164 }
165
166 for (i = 0; i <= payload_type - 255; i += 255)
167 h265e_stream_write_with_log(s, 0xff, 8,
168 "sei_payload_type_ff_byte");
169
170 h265e_stream_write_with_log(s, payload_type - i, 8,
171 "sei_last_payload_type_byte");
172
173 for (i = 0; i <= payload_size - 255; i += 255)
174 h265e_stream_write_with_log(s, 0xff, 8,
175 "sei_payload_size_ff_byte");
176
177 h265e_stream_write_with_log(s, payload_size - i, 8,
178 "sei_last_payload_size_byte");
179
180 switch (payload_type) {
181 case H265_SEI_USER_DATA_UNREGISTERED : {
182 for (i = 0; i < uuid_len; i++)
183 h265e_stream_write_with_log(s, uuid[i], 8, NULL);
184 for (i = 0; i < data_len; i++)
185 h265e_stream_write_with_log(s, (RK_U32) payload[i], 8, NULL);
186 h265e_stream_rbsp_trailing(s);
187 } break;
188 case H265_SEI_RECOVERY_POINT: {
189 h265e_write_recovery_point(s, ((RK_U32 *)payload)[0]);
190 } break;
191 default: {
192 mpp_err_f("payload_type %d is no process ", payload_type);
193 } break;
194 }
195
196 h265e_dbg_func("leave\n");
197
198 return MPP_OK;
199 }
200
h265e_sei_recovery_point(void * dst,RK_U8 uuid[16],const void * payload,RK_S32 size)201 MPP_RET h265e_sei_recovery_point(void *dst, RK_U8 uuid[16], const void *payload,
202 RK_S32 size)
203 {
204 H265eNal sei_nal;
205 H265eStream stream;
206 RK_U8 *end = 0;
207
208 h265e_dbg_func("enter\n");
209
210 h265e_stream_init(&stream);
211 memset(&sei_nal, 0, sizeof(H265eNal));
212
213 sei_nal.i_type = NAL_SEI_PREFIX;
214 sei_nal.p_payload = &stream.buf[stream.enc_stream.byte_cnt];
215
216 h265e_sei_write(&stream, uuid, payload, size,
217 H265_SEI_RECOVERY_POINT);
218
219 end = &stream.buf[stream.enc_stream.byte_cnt];
220 sei_nal.i_payload = (RK_S32) (end - sei_nal.p_payload);
221
222 h265e_nal_encode(dst, &sei_nal);
223
224 h265e_stream_deinit(&stream);
225
226 h265e_dbg_func("leave\n");
227 return sei_nal.i_payload;
228
229 return MPP_OK;
230 }
231
codeProfileTier(H265eStream * s,ProfileTierLevel * ptl)232 void codeProfileTier(H265eStream *s, ProfileTierLevel* ptl)
233 {
234 RK_S32 j;
235 h265e_stream_write_with_log(s, ptl->m_profileSpace, 2, "profile_space[]");
236 h265e_stream_write1_with_log(s, ptl->m_tierFlag, "tier_flag[]");
237 h265e_stream_write_with_log(s, ptl->m_profileIdc, 5, "profile_idc[]");
238 for (j = 0; j < 32; j++) {
239 h265e_stream_write1_with_log(s, ptl->m_profileCompatibilityFlag[j], "profile_compatibility_flag[][j]");
240 }
241
242 h265e_stream_write1_with_log(s, ptl->m_progressiveSourceFlag, "general_progressive_source_flag");
243 h265e_stream_write1_with_log(s, ptl->m_interlacedSourceFlag, "general_interlaced_source_flag");
244 h265e_stream_write1_with_log(s, ptl->m_nonPackedConstraintFlag, "general_non_packed_constraint_flag");
245 h265e_stream_write1_with_log(s, ptl->m_frameOnlyConstraintFlag, "general_frame_only_constraint_flag");
246
247 if (ptl->m_profileIdc == MPP_PROFILE_HEVC_FORMAT_RANGE_EXTENDIONS) {
248 h265e_stream_write1_with_log(s, ptl->m_max12bitConstraintFlag , "general_max_12_bit_constraint_flag");
249 h265e_stream_write1_with_log(s, ptl->m_max10bitConstraintFlag, "general_max_10_bit_constraint_flag");
250 h265e_stream_write1_with_log(s, ptl->m_max8bitConstraintFlag, "general_max_8_bit_constraint_flag");
251 h265e_stream_write1_with_log(s, ptl->m_max422chromaConstraintFlag, "general_max_422chroma_constraint_flag");
252 h265e_stream_write1_with_log(s, ptl->m_max420chromaConstraintFlag, "general_max_420chroma_constraint_flag");
253 h265e_stream_write1_with_log(s, ptl->m_maxMonochromaConstraintFlag, "general_max_monochroma_constraint_flag");
254 h265e_stream_write1_with_log(s, ptl->m_intraConstraintFlag, "general_intra_constraint_flag");
255 h265e_stream_write1_with_log(s, ptl->m_onePictureConstraintFlag, "general_one_picture_constraint_flag");
256 h265e_stream_write1_with_log(s, ptl->m_lowerBitRateConstraintFlag, "general_lower_bit_rate_constraint_flag");
257 h265e_stream_write_with_log(s, 0, 16, "reserved_zero_35bits[0..15]");
258 h265e_stream_write_with_log(s, 0, 16, "reserved_zero_35bits[16..31]");
259 h265e_stream_write_with_log(s, 0, 3, "eserved_zero_35bits[32..34]");
260 } else {
261 h265e_stream_write_with_log(s, 0, 16, "reserved_zero_44bits[0..15]");
262 h265e_stream_write_with_log(s, 0, 16, "reserved_zero_44bits[16..31]");
263 h265e_stream_write_with_log(s, 0, 12, "eserved_zero_44bits[32..43]");
264 }
265 }
266
codePTL(H265eStream * s,H265ePTL * ptl,RK_U32 profilePresentFlag,int maxNumSubLayersMinus1)267 void codePTL(H265eStream *s, H265ePTL* ptl, RK_U32 profilePresentFlag, int maxNumSubLayersMinus1)
268 {
269 RK_S32 i;
270 if (profilePresentFlag) {
271 codeProfileTier(s, &ptl->m_generalPTL);
272 }
273 h265e_stream_write_with_log(s, ptl->m_generalPTL.m_levelIdc, 8, "general_level_idc");
274
275 for (i = 0; i < maxNumSubLayersMinus1; i++) {
276 if (profilePresentFlag) {
277 h265e_stream_write1_with_log(s, ptl->m_subLayerProfilePresentFlag[i], "sub_layer_profile_present_flag[i]");
278 }
279
280 h265e_stream_write1_with_log(s, ptl->m_subLayerLevelPresentFlag[i], "sub_layer_level_present_flag[i]");
281 }
282
283 if (maxNumSubLayersMinus1 > 0) {
284 for (i = maxNumSubLayersMinus1; i < 8; i++) {
285 h265e_stream_write_with_log(s, 0, 2, "reserved_zero_2bits");
286 }
287 }
288
289 for (i = 0; i < maxNumSubLayersMinus1; i++) {
290 if (profilePresentFlag && ptl->m_subLayerProfilePresentFlag[i]) {
291 codeProfileTier(s, &ptl->m_subLayerPTL[i]); // sub_layer_...
292 }
293 if (ptl->m_subLayerLevelPresentFlag[i]) {
294 h265e_stream_write_with_log(s, ptl->m_subLayerPTL[i].m_levelIdc, 8, "sub_layer_level_idc[i]");
295 }
296 }
297 }
298
h265e_vps_write(H265eVps * vps,H265eStream * s)299 static MPP_RET h265e_vps_write(H265eVps *vps, H265eStream *s)
300 {
301 RK_S32 vps_byte_start = 0;
302 RK_U32 i, opsIdx;
303
304 h265e_dbg_func("enter\n");
305 h265e_stream_realign(s);
306 vps_byte_start = s->enc_stream.byte_cnt;
307 h265e_stream_write_with_log(s, vps->m_VPSId, 4, "vps_video_parameter_set_id");
308 h265e_stream_write_with_log(s, 3, 2, "vps_reserved_three_2bits");
309 h265e_stream_write_with_log(s, 0, 6, "vps_reserved_zero_6bits");
310 h265e_stream_write_with_log(s, vps->m_maxTLayers - 1, 3, "vps_max_sub_layers_minus1");
311 h265e_stream_write1_with_log(s, vps->m_bTemporalIdNestingFlag, "vps_temporal_id_nesting_flag");
312
313 h265e_stream_write_with_log(s, 0xffff, 16, "vps_reserved_ffff_16bits");
314
315 codePTL(s, &vps->m_ptl, 1, vps->m_maxTLayers - 1);
316
317 h265e_stream_write1_with_log(s, 1, "vps_sub_layer_ordering_info_present_flag");
318 for (i = 0; i <= vps->m_maxTLayers - 1; i++) {
319 h265e_stream_write_ue_with_log(s, vps->m_maxDecPicBuffering[i] - 1, "vps_max_dec_pic_buffering_minus1[i]");
320 h265e_stream_write_ue_with_log(s, vps->m_numReorderPics[i], "vps_num_reorder_pics[i]");
321 h265e_stream_write_ue_with_log(s, vps->m_maxLatencyIncrease[i], "vps_max_latency_increase_plus1[i]");
322 }
323
324 mpp_assert(vps->m_numHrdParameters <= MAX_VPS_NUM_HRD_PARAMETERS);
325 mpp_assert(vps->m_maxNuhReservedZeroLayerId < MAX_VPS_NUH_RESERVED_ZERO_LAYER_ID_PLUS1);
326 h265e_stream_write_with_log(s, vps->m_maxNuhReservedZeroLayerId, 6, "vps_max_nuh_reserved_zero_layer_id");
327 vps->m_numOpSets = 1;
328 h265e_stream_write_ue_with_log(s, vps->m_numOpSets - 1, "vps_max_op_sets_minus1");
329 for (opsIdx = 1; opsIdx <= (vps->m_numOpSets - 1); opsIdx++) {
330 // Operation point set
331 for (i = 0; i <= vps->m_maxNuhReservedZeroLayerId; i++) {
332 // Only applicable for version 1
333 vps->m_layerIdIncludedFlag[opsIdx][i] = 1;
334 h265e_stream_write1_with_log(s, vps->m_layerIdIncludedFlag[opsIdx][i] ? 1 : 0, "layer_id_included_flag[opsIdx][i]");
335 }
336 }
337
338 TimingInfo *timingInfo = &vps->m_timingInfo;
339 h265e_stream_write1_with_log(s, timingInfo->m_timingInfoPresentFlag, "vps_timing_info_present_flag");
340 if (timingInfo->m_timingInfoPresentFlag) {
341 h265e_stream_write_with_log(s, timingInfo->m_numUnitsInTick, 32, "vps_num_units_in_tick");
342 h265e_stream_write_with_log(s, timingInfo->m_timeScale, 32, "vps_time_scale");
343 h265e_stream_write1_with_log(s, timingInfo->m_pocProportionalToTimingFlag, "vps_poc_proportional_to_timing_flag");
344 if (timingInfo->m_pocProportionalToTimingFlag) {
345 h265e_stream_write_ue_with_log(s, timingInfo->m_numTicksPocDiffOneMinus1, "vps_num_ticks_poc_diff_one_minus1");
346 }
347 vps->m_numHrdParameters = 0;
348 h265e_stream_write_ue_with_log(s, vps->m_numHrdParameters, "vps_num_hrd_parameters");
349 #if 0
350 if (vps->m_numHrdParameters > 0) {
351 vps->createHrdParamBuffer();
352 }
353 for (uint32_t i = 0; i < vps->getNumHrdParameters(); i++) {
354 // Only applicable for version 1
355 vps->setHrdOpSetIdx(0, i);
356 h265e_stream_write_ue_with_log(s, vps->getHrdOpSetIdx(i), "hrd_op_set_idx");
357 if (i > 0) {
358 h265e_stream_write1_with_log(s, vps->getCprmsPresentFlag(i) ? 1 : 0, "cprms_present_flag[i]");
359 }
360 codeHrdParameters(vps->getHrdParameters(i), vps->getCprmsPresentFlag(i), vps->getMaxTLayers() - 1);
361 }
362 #endif
363 }
364 h265e_stream_write1_with_log(s, 0, "vps_extension_flag");
365 h265e_stream_rbsp_trailing(s);
366 h265e_stream_flush(s);
367 h265e_dbg(H265E_DBG_HEADER, "write pure vps head size: %d bits", (s->enc_stream.byte_cnt - vps_byte_start) * 8);
368 //future extensions here..
369 h265e_dbg_func("leave\n");
370 return MPP_OK;
371 }
372
codeVUI(H265eStream * s,H265eVuiInfo * vui)373 void codeVUI(H265eStream *s, H265eVuiInfo *vui)
374 {
375 h265e_stream_write1_with_log(s, vui->m_aspectRatioInfoPresentFlag, "aspect_ratio_info_present_flag");
376 if (vui->m_aspectRatioInfoPresentFlag) {
377 h265e_stream_write_with_log(s, vui->m_aspectRatioIdc, 8, "aspect_ratio_idc");
378 if (vui->m_aspectRatioIdc == 255) {
379 h265e_stream_write_with_log(s, vui->m_sarWidth, 16, "sar_width");
380 h265e_stream_write_with_log(s, vui->m_sarHeight, 16, "sar_height");
381 }
382 }
383 h265e_stream_write1_with_log(s, vui->m_overscanInfoPresentFlag, "overscan_info_present_flag");
384 if (vui->m_overscanInfoPresentFlag) {
385 h265e_stream_write1_with_log(s, vui->m_overscanAppropriateFlag, "overscan_appropriate_flag");
386 }
387 h265e_stream_write1_with_log(s, vui->m_videoSignalTypePresentFlag, "video_signal_type_present_flag");
388 if (vui->m_videoSignalTypePresentFlag) {
389 h265e_stream_write_with_log(s, vui->m_videoFormat, 3, "video_format");
390 h265e_stream_write1_with_log(s, vui->m_videoFullRangeFlag, "video_full_range_flag");
391 h265e_stream_write1_with_log(s, vui->m_colourDescriptionPresentFlag, "colour_description_present_flag");
392 if (vui->m_colourDescriptionPresentFlag) {
393 h265e_stream_write_with_log(s, vui->m_colourPrimaries, 8, "colour_primaries");
394 h265e_stream_write_with_log(s, vui->m_transferCharacteristics, 8, "transfer_characteristics");
395 h265e_stream_write_with_log(s, vui->m_matrixCoefficients, 8, "matrix_coefficients");
396 }
397 }
398
399 h265e_stream_write1_with_log(s, vui->m_chromaLocInfoPresentFlag, "chroma_loc_info_present_flag");
400 if (vui->m_chromaLocInfoPresentFlag) {
401 h265e_stream_write_ue_with_log(s, vui->m_chromaSampleLocTypeTopField, "chroma_sample_loc_type_top_field");
402 h265e_stream_write_ue_with_log(s, vui->m_chromaSampleLocTypeBottomField, "chroma_sample_loc_type_bottom_field");
403 }
404
405 h265e_stream_write1_with_log(s, vui->m_neutralChromaIndicationFlag, "neutral_chroma_indication_flag");
406 h265e_stream_write1_with_log(s, vui->m_fieldSeqFlag, "field_seq_flag");
407 h265e_stream_write1_with_log(s, vui->m_frameFieldInfoPresentFlag, "frame_field_info_present_flag");
408
409 H265eCropInfo defaultDisplayWindow = vui->m_defaultDisplayWindow;
410 h265e_stream_write1_with_log(s, defaultDisplayWindow.m_enabledFlag, "default_display_window_flag");
411 if (defaultDisplayWindow.m_enabledFlag) {
412 h265e_stream_write_ue_with_log(s, defaultDisplayWindow.m_winLeftOffset, "def_disp_win_left_offset");
413 h265e_stream_write_ue_with_log(s, defaultDisplayWindow.m_winRightOffset, "def_disp_win_right_offset");
414 h265e_stream_write_ue_with_log(s, defaultDisplayWindow.m_winTopOffset, "def_disp_win_top_offset");
415 h265e_stream_write_ue_with_log(s, defaultDisplayWindow.m_winBottomOffset, "def_disp_win_bottom_offset");
416 }
417 TimingInfo *timingInfo = &vui->m_timingInfo;
418 h265e_stream_write1_with_log(s, timingInfo->m_timingInfoPresentFlag, "vui_timing_info_present_flag");
419 if (timingInfo->m_timingInfoPresentFlag) {
420 h265e_stream_write32(s, timingInfo->m_numUnitsInTick, "vui_num_units_in_tick");
421 h265e_stream_write32(s, timingInfo->m_timeScale, "vui_time_scale");
422 h265e_stream_write1_with_log(s, timingInfo->m_pocProportionalToTimingFlag, "vui_poc_proportional_to_timing_flag");
423 if (timingInfo->m_pocProportionalToTimingFlag) {
424 h265e_stream_write_ue_with_log(s, timingInfo->m_numTicksPocDiffOneMinus1, "vui_num_ticks_poc_diff_one_minus1");
425 }
426 h265e_stream_write1_with_log(s, vui->m_hrdParametersPresentFlag, "hrd_parameters_present_flag");
427 if (vui->m_hrdParametersPresentFlag) {
428 // codeHrdParameters(vui->getHrdParameters(), 1, sps->getMaxTLayers() - 1); //todo
429 }
430 }
431 h265e_stream_write1_with_log(s, vui->m_bitstreamRestrictionFlag, "bitstream_restriction_flag");
432 if (vui->m_bitstreamRestrictionFlag) {
433 h265e_stream_write1_with_log(s, vui->m_tilesFixedStructureFlag, "tiles_fixed_structure_flag");
434 h265e_stream_write1_with_log(s, vui->m_motionVectorsOverPicBoundariesFlag, "motion_vectors_over_pic_boundaries_flag");
435 h265e_stream_write1_with_log(s, vui->m_restrictedRefPicListsFlag, "restricted_ref_pic_lists_flag");
436 h265e_stream_write_ue_with_log(s, vui->m_minSpatialSegmentationIdc, "min_spatial_segmentation_idc");
437 h265e_stream_write_ue_with_log(s, vui->m_maxBytesPerPicDenom, "max_bytes_per_pic_denom");
438 h265e_stream_write_ue_with_log(s, vui->m_maxBitsPerMinCuDenom, "max_bits_per_mincu_denom");
439 h265e_stream_write_ue_with_log(s, vui->m_log2MaxMvLengthHorizontal, "log2_max_mv_length_horizontal");
440 h265e_stream_write_ue_with_log(s, vui->m_log2MaxMvLengthHorizontal, "log2_max_mv_length_vertical");
441 }
442 }
443
h265e_sps_write(H265eSps * sps,H265eStream * s)444 static MPP_RET h265e_sps_write(H265eSps *sps, H265eStream *s)
445 {
446 RK_S32 sps_byte_start = 0;
447 RK_U32 i, k;
448 const RK_S32 winUnitX[] = { 1, 2, 2, 1 };
449 const RK_S32 winUnitY[] = { 1, 2, 1, 1 };
450 H265eCropInfo *conf = &sps->m_conformanceWindow;
451
452 h265e_dbg_func("enter\n");
453 h265e_stream_realign(s);
454 sps_byte_start = s->enc_stream.byte_cnt;
455
456 h265e_stream_write_with_log(s, sps->m_VPSId, 4, "sps_video_parameter_set_id");
457 h265e_stream_write_with_log(s, sps->m_maxTLayers - 1, 3, "sps_max_sub_layers_minus1");
458 h265e_stream_write1_with_log(s, sps->m_bTemporalIdNestingFlag ? 1 : 0, "sps_temporal_id_nesting_flag");
459 codePTL(s, sps->m_ptl, 1, sps->m_maxTLayers - 1);
460 h265e_stream_write_ue_with_log(s, sps->m_SPSId, "sps_seq_parameter_set_id");
461 h265e_stream_write_ue_with_log(s, sps->m_chromaFormatIdc, "chroma_format_idc");
462
463 if (sps->m_chromaFormatIdc == 4) {
464 h265e_stream_write1_with_log(s, 0, "separate_colour_plane_flag");
465 }
466
467 h265e_stream_write_ue_with_log(s, sps->m_picWidthInLumaSamples, "pic_width_in_luma_samples");
468 h265e_stream_write_ue_with_log(s, sps->m_picHeightInLumaSamples, "pic_height_in_luma_samples");
469
470 h265e_stream_write1_with_log(s, conf->m_enabledFlag, "conformance_window_flag");
471 if (conf->m_enabledFlag) {
472 h265e_stream_write_ue_with_log(s, conf->m_winLeftOffset / winUnitX[sps->m_chromaFormatIdc], "conf_win_left_offset");
473 h265e_stream_write_ue_with_log(s, conf->m_winRightOffset / winUnitX[sps->m_chromaFormatIdc], "conf_win_right_offset");
474 h265e_stream_write_ue_with_log(s, conf->m_winTopOffset / winUnitY[sps->m_chromaFormatIdc], "conf_win_top_offset");
475 h265e_stream_write_ue_with_log(s, conf->m_winBottomOffset / winUnitY[sps->m_chromaFormatIdc], "conf_win_bottom_offset");
476 }
477
478 h265e_stream_write_ue_with_log(s, sps->m_bitDepthY - 8, "bit_depth_luma_minus8");
479 h265e_stream_write_ue_with_log(s, sps->m_bitDepthC - 8, "bit_depth_chroma_minus8");
480
481 h265e_stream_write_ue_with_log(s, sps->m_bitsForPOC - 4, "log2_max_pic_order_cnt_lsb_minus4");
482
483 h265e_stream_write1_with_log(s, 1, "sps_sub_layer_ordering_info_present_flag");
484 for (i = 0; i <= sps->m_maxTLayers - 1; i++) {
485 h265e_stream_write_ue_with_log(s, sps->m_maxDecPicBuffering[i] - 1, "sps_max_dec_pic_buffering_minus1[i]");
486 h265e_stream_write_ue_with_log(s, sps->m_numReorderPics[i], "sps_num_reorder_pics[i]");
487 h265e_stream_write_ue_with_log(s, sps->m_maxLatencyIncrease[i], "sps_max_latency_increase_plus1[i]");
488 }
489
490 h265e_stream_write_ue_with_log(s, sps->m_log2MinCodingBlockSize - 3, "log2_min_coding_block_size_minus3");
491 h265e_stream_write_ue_with_log(s, sps->m_log2DiffMaxMinCodingBlockSize, "log2_diff_max_min_coding_block_size");
492 h265e_stream_write_ue_with_log(s, sps->m_quadtreeTULog2MinSize - 2, "log2_min_transform_block_size_minus2");
493 h265e_stream_write_ue_with_log(s, sps->m_quadtreeTULog2MaxSize - sps->m_quadtreeTULog2MinSize, "log2_diff_max_min_transform_block_size");
494 h265e_stream_write_ue_with_log(s, sps->m_quadtreeTUMaxDepthInter - 1, "max_transform_hierarchy_depth_inter");
495 h265e_stream_write_ue_with_log(s, sps->m_quadtreeTUMaxDepthIntra - 1, "max_transform_hierarchy_depth_intra");
496 h265e_stream_write1_with_log(s, sps->m_scalingListEnabledFlag ? 1 : 0, "scaling_list_enabled_flag");
497 if (sps->m_scalingListEnabledFlag == 1)
498 h265e_stream_write1_with_log(s, 0, "sps_scaling_list_data_present_flag");
499 else if (sps->m_scalingListEnabledFlag == 2) {
500 //TODO:
501 mpp_err_f("m_scalingListEnabledFlag == 2 not supported yet\n");
502 }
503 h265e_stream_write1_with_log(s, sps->m_useAMP ? 1 : 0, "amp_enabled_flag");
504 h265e_stream_write1_with_log(s, sps->m_bUseSAO ? 1 : 0, "sample_adaptive_offset_enabled_flag");
505
506 h265e_stream_write1_with_log(s, sps->m_usePCM ? 1 : 0, "pcm_enabled_flag");
507 if (sps->m_usePCM) {
508 h265e_stream_write_with_log(s, sps->m_pcmBitDepthLuma - 1, 4, "pcm_sample_bit_depth_luma_minus1");
509 h265e_stream_write_with_log(s, sps->m_pcmBitDepthChroma - 1, 4, "pcm_sample_bit_depth_chroma_minus1");
510 h265e_stream_write_ue_with_log(s, sps->m_pcmLog2MinSize - 3, "log2_min_pcm_luma_coding_block_size_minus3");
511 h265e_stream_write_ue_with_log(s, sps->m_pcmLog2MaxSize - sps->m_pcmLog2MinSize, "log2_diff_max_min_pcm_luma_coding_block_size");
512 h265e_stream_write1_with_log(s, sps->m_bPCMFilterDisableFlag ? 1 : 0, "pcm_loop_filter_disable_flag");
513 }
514
515 mpp_assert(sps->m_maxTLayers > 0);
516
517 H265eRPSList* rpsList = &sps->m_RPSList;
518 // H265eReferencePictureSet* rps;
519
520 h265e_stream_write_ue_with_log(s, rpsList->m_numberOfReferencePictureSets, "num_short_term_ref_pic_sets");
521 for ( i = 0; i < (RK_U32)rpsList->m_numberOfReferencePictureSets; i++) {
522 mpp_log("todo m_numberOfReferencePictureSets");
523 //rps = &rpsList->m_referencePictureSets[i];
524 // codeShortTermRefPicSet(rps, false, i); //todo no support
525 }
526 h265e_stream_write1_with_log(s, sps->m_bLongTermRefsPresent ? 1 : 0, "long_term_ref_pics_present_flag");
527 if (sps->m_bLongTermRefsPresent) {
528 h265e_stream_write_ue_with_log(s, sps->m_numLongTermRefPicSPS, "num_long_term_ref_pic_sps");
529 for (k = 0; k < sps->m_numLongTermRefPicSPS; k++) {
530 h265e_stream_write_with_log(s, sps->m_ltRefPicPocLsbSps[k], sps->m_bitsForPOC, "lt_ref_pic_poc_lsb_sps");
531 h265e_stream_write1_with_log(s, sps->m_usedByCurrPicLtSPSFlag[k], "used_by_curr_pic_lt_sps_flag");
532 }
533 }
534 h265e_stream_write1_with_log(s, sps->m_TMVPFlagsPresent ? 1 : 0, "sps_temporal_mvp_enable_flag");
535
536 h265e_stream_write1_with_log(s, sps->m_useStrongIntraSmoothing, "sps_strong_intra_smoothing_enable_flag");
537
538 h265e_stream_write1_with_log(s, sps->m_vuiParametersPresentFlag, "vui_parameters_present_flag");
539 if (sps->m_vuiParametersPresentFlag) {
540 codeVUI(s, &sps->vui);
541 }
542 h265e_stream_write1_with_log(s, 0, "sps_extension_flag");
543 h265e_stream_rbsp_trailing(s);
544 h265e_stream_flush(s);
545 h265e_dbg(H265E_DBG_HEADER, "write pure sps head size: %d bits", (s->enc_stream.byte_cnt - sps_byte_start) * 8);
546
547 h265e_dbg_func("leave\n");
548 return MPP_OK;
549 }
550
551 #if 0
552 static void h265e_rkv_scaling_list_write( H265eRkvStream *s,
553 H265ePps *pps, RK_S32 idx )
554 {
555
556 }
557 #endif
558
h265e_pps_write(H265ePps * pps,H265eSps * sps,H265eStream * s)559 static MPP_RET h265e_pps_write(H265ePps *pps, H265eSps *sps, H265eStream *s)
560 {
561 (void) sps;
562 RK_S32 pps_byte_start = 0;
563 RK_S32 i;
564 h265e_stream_realign(s);
565 pps_byte_start = s->enc_stream.byte_cnt;
566
567 h265e_dbg_func("enter\n");
568 h265e_stream_write_ue_with_log(s, pps->m_PPSId, "pps_pic_parameter_set_id");
569 h265e_stream_write_ue_with_log(s, pps->m_SPSId, "pps_seq_parameter_set_id");
570 h265e_stream_write1_with_log(s, 0, "dependent_slice_segments_enabled_flag");
571 h265e_stream_write1_with_log(s, pps->m_outputFlagPresentFlag ? 1 : 0, "output_flag_present_flag");
572 h265e_stream_write_with_log(s, pps->m_numExtraSliceHeaderBits, 3, "num_extra_slice_header_bits");
573 h265e_stream_write1_with_log(s, pps->m_signHideFlag, "sign_data_hiding_flag");
574 h265e_stream_write1_with_log(s, pps->m_cabacInitPresentFlag ? 1 : 0, "cabac_init_present_flag");
575 h265e_stream_write_ue_with_log(s, pps->m_numRefIdxL0DefaultActive - 1, "num_ref_idx_l0_default_active_minus1");
576 h265e_stream_write_ue_with_log(s, pps->m_numRefIdxL1DefaultActive - 1, "num_ref_idx_l1_default_active_minus1");
577
578 h265e_stream_write_se_with_log(s, pps->m_picInitQPMinus26, "init_qp_minus26");
579 h265e_stream_write1_with_log(s, pps->m_bConstrainedIntraPred ? 1 : 0, "constrained_intra_pred_flag");
580 h265e_stream_write1_with_log(s, pps->m_useTransformSkip ? 1 : 0, "transform_skip_enabled_flag");
581 h265e_stream_write1_with_log(s, pps->m_useDQP ? 1 : 0, "cu_qp_delta_enabled_flag");
582 if (pps->m_useDQP) {
583 h265e_stream_write_ue_with_log(s, pps->m_maxCuDQPDepth, "diff_cu_qp_delta_depth");
584 }
585 h265e_stream_write_se_with_log(s, pps->m_chromaCbQpOffset, "pps_cb_qp_offset");
586 h265e_stream_write_se_with_log(s, pps->m_chromaCrQpOffset, "pps_cr_qp_offset");
587 h265e_stream_write1_with_log(s, pps->m_bSliceChromaQpFlag ? 1 : 0, "pps_slice_chroma_qp_offsets_present_flag");
588
589 h265e_stream_write1_with_log(s, pps->m_bUseWeightPred ? 1 : 0, "weighted_pred_flag"); // Use of Weighting Prediction (P_SLICE)
590 h265e_stream_write1_with_log(s, pps->m_useWeightedBiPred ? 1 : 0, "weighted_bipred_flag"); // Use of Weighting Bi-Prediction (B_SLICE)
591 h265e_stream_write1_with_log(s, pps->m_transquantBypassEnableFlag ? 1 : 0, "transquant_bypass_enable_flag");
592 h265e_stream_write1_with_log(s, pps->m_tiles_enabled_flag, "tiles_enabled_flag");
593 h265e_stream_write1_with_log(s, pps->m_entropyCodingSyncEnabledFlag ? 1 : 0, "entropy_coding_sync_enabled_flag");
594 if (pps->m_tiles_enabled_flag) {
595 h265e_stream_write_ue_with_log(s, pps->m_nNumTileColumnsMinus1, "num_tile_columns_minus1");
596 h265e_stream_write_ue_with_log(s, pps->m_nNumTileRowsMinus1, "num_tile_rows_minus1");
597 h265e_stream_write1_with_log(s, pps->m_bTileUniformSpacing, "uniform_spacing_flag");
598 if (!pps->m_bTileUniformSpacing) {
599 for ( i = 0; i < pps->m_nNumTileColumnsMinus1; i++) {
600 h265e_stream_write_ue_with_log(s, pps->m_nTileColumnWidthArray[i] - 1, "column_width_minus1");
601 }
602 for (i = 0; i < pps->m_nNumTileRowsMinus1; i++) {
603 h265e_stream_write_ue_with_log(s, pps->m_nTileRowHeightArray[i] - 1, "row_height_minus1");
604 }
605 }
606 mpp_assert((pps->m_nNumTileColumnsMinus1 + pps->m_nNumTileRowsMinus1) != 0);
607 h265e_stream_write1_with_log(s, pps->m_loopFilterAcrossTilesEnabledFlag ? 1 : 0, "loop_filter_across_tiles_enabled_flag");
608 }
609 h265e_stream_write1_with_log(s, pps->m_LFCrossSliceBoundaryFlag ? 1 : 0, "loop_filter_across_slices_enabled_flag");
610
611 // TODO: Here have some time sequence problem, we set below field in initEncSlice(), but use them in getStreamHeaders() early
612 h265e_stream_write1_with_log(s, pps->m_deblockingFilterControlPresentFlag ? 1 : 0, "deblocking_filter_control_present_flag");
613 if (pps->m_deblockingFilterControlPresentFlag) {
614 h265e_stream_write1_with_log(s, pps->m_deblockingFilterOverrideEnabledFlag ? 1 : 0, "deblocking_filter_override_enabled_flag");
615 h265e_stream_write1_with_log(s, pps->m_picDisableDeblockingFilterFlag ? 1 : 0, "pps_disable_deblocking_filter_flag");
616 if (!pps->m_picDisableDeblockingFilterFlag) {
617 h265e_stream_write_se_with_log(s, pps->m_deblockingFilterBetaOffsetDiv2, "pps_beta_offset_div2");
618 h265e_stream_write_se_with_log(s, pps->m_deblockingFilterTcOffsetDiv2, "pps_tc_offset_div2");
619 }
620 }
621 h265e_stream_write1_with_log(s, pps->m_scalingListPresentFlag ? 1 : 0, "pps_scaling_list_data_present_flag");
622 if (pps->m_scalingListPresentFlag) {
623 ;//codeScalingList(m_slice->getScalingList()); //todo
624 }
625 h265e_stream_write1_with_log(s, pps->m_listsModificationPresentFlag, "lists_modification_present_flag");
626 h265e_stream_write_ue_with_log(s, pps->m_log2ParallelMergeLevelMinus2, "log2_parallel_merge_level_minus2");
627 h265e_stream_write1_with_log(s, pps->m_sliceHeaderExtensionPresentFlag ? 1 : 0, "slice_segment_header_extension_present_flag");
628 h265e_stream_write1_with_log(s, 0, "pps_extension_flag");
629
630 h265e_stream_rbsp_trailing( s );
631 h265e_stream_flush( s );
632
633 h265e_dbg(H265E_DBG_HEADER, "write pure pps size: %d bits", (s->enc_stream.byte_cnt - pps_byte_start) * 8);
634 h265e_dbg_func("leave\n");
635
636 return MPP_OK;
637 }
638
h265e_nal_start(H265eExtraInfo * out,RK_S32 i_type,RK_S32 i_ref_idc)639 void h265e_nal_start(H265eExtraInfo *out, RK_S32 i_type,
640 RK_S32 i_ref_idc)
641 {
642 H265eStream *s = &out->stream;
643 H265eNal *nal = &out->nal[out->nal_num];
644
645 nal->i_ref_idc = i_ref_idc;
646 nal->i_type = i_type;
647 nal->b_long_startcode = 1;
648
649 nal->i_payload = 0;
650 /* NOTE: consistent with stream_init */
651 nal->p_payload = &s->buf[s->enc_stream.byte_cnt];
652 nal->i_padding = 0;
653
654 nal->temporal_id = out->temporal_id;
655 }
656
h265e_nal_end(H265eExtraInfo * out)657 void h265e_nal_end(H265eExtraInfo *out)
658 {
659 H265eNal *nal = &(out->nal[out->nal_num]);
660 H265eStream *s = &out->stream;
661 /* NOTE: consistent with stream_init */
662 RK_U8 *end = &s->buf[s->enc_stream.byte_cnt];
663 nal->i_payload = (RK_S32)(end - nal->p_payload);
664 /*
665 * Assembly implementation of nal_escape reads past the end of the input.
666 * While undefined padding wouldn't actually affect the output,
667 * it makes valgrind unhappy.
668 */
669 memset(end, 0xff, 64);
670 out->nal_num++;
671 }
672
h265e_init_extra_info(void * extra_info)673 MPP_RET h265e_init_extra_info(void *extra_info)
674 {
675
676 H265eExtraInfo *info = (H265eExtraInfo *)extra_info;
677 // random ID number generated according to ISO-11578
678 // NOTE: any element of h264e_sei_uuid should NOT be 0x00,
679 // otherwise the string length of sei_buf will always be the distance between the
680 // element 0x00 address and the sei_buf start address.
681 static const RK_U8 h265e_sei_uuid[H265E_UUID_LENGTH] = {
682 0x67, 0xfc, 0x6a, 0x3c, 0xd8, 0x5c, 0x44, 0x1e,
683 0x87, 0xfb, 0x3f, 0xab, 0xec, 0xb3, 0x36, 0x77
684 };
685
686 h265e_nals_init(info);
687 h265e_stream_init(&info->stream);
688
689 info->sei_buf = mpp_calloc_size(RK_U8, H265E_SEI_BUF_SIZE);
690 memcpy(info->sei_buf, h265e_sei_uuid, H265E_UUID_LENGTH);
691
692 return MPP_OK;
693 }
694
h265e_deinit_extra_info(void * extra_info)695 MPP_RET h265e_deinit_extra_info(void *extra_info)
696 {
697 H265eExtraInfo *info = (H265eExtraInfo *)extra_info;
698 h265e_stream_deinit(&info->stream);
699 h265e_nals_deinit(info);
700
701 MPP_FREE(info->sei_buf);
702
703 return MPP_OK;
704 }
705
h265e_set_extra_info(H265eCtx * ctx)706 MPP_RET h265e_set_extra_info(H265eCtx *ctx)
707 {
708 H265eExtraInfo *info = (H265eExtraInfo *)ctx->extra_info;
709 H265eSps *sps = &ctx->sps;
710 H265ePps *pps = &ctx->pps;
711 H265eVps *vps = &ctx->vps;
712
713 h265e_dbg_func("enter\n");
714 info->nal_num = 0;
715 info->temporal_id = 0;
716 h265e_stream_reset(&info->stream);
717
718 h265e_nal_start(info, NAL_VPS, H265_NAL_PRIORITY_HIGHEST);
719 h265e_set_vps(ctx, vps);
720 h265e_vps_write(vps, &info->stream);
721 h265e_nal_end(info);
722
723 h265e_nal_start(info, NAL_SPS, H265_NAL_PRIORITY_HIGHEST);
724 h265e_set_sps(ctx, sps, vps);
725 h265e_sps_write(sps, &info->stream);
726 h265e_nal_end(info);
727
728 h265e_nal_start(info, NAL_PPS, H265_NAL_PRIORITY_HIGHEST);
729 h265e_set_pps(ctx, pps, sps);
730 h265e_pps_write(pps, sps, &info->stream);
731 h265e_nal_end(info);
732
733 h265e_encapsulate_nals(info);
734
735 h265e_dbg_func("leave\n");
736 return MPP_OK;
737 }
738
h265e_data_to_sei(void * dst,RK_U8 uuid[16],const void * payload,RK_S32 size)739 RK_U32 h265e_data_to_sei(void *dst, RK_U8 uuid[16], const void *payload, RK_S32 size)
740 {
741 H265eNal sei_nal;
742 H265eStream stream;
743
744 h265e_dbg_func("enter\n");
745
746 h265e_stream_init(&stream);
747 memset(&sei_nal, 0 , sizeof(H265eNal));
748
749 sei_nal.i_type = NAL_SEI_PREFIX;
750 sei_nal.p_payload = &stream.buf[stream.enc_stream.byte_cnt];
751
752 h265e_sei_write(&stream, uuid, payload, size, H265_SEI_USER_DATA_UNREGISTERED);
753
754 RK_U8 *end = &stream.buf[stream.enc_stream.byte_cnt];
755 sei_nal.i_payload = (RK_S32)(end - sei_nal.p_payload);
756
757 h265e_nal_encode(dst, &sei_nal);
758
759 h265e_stream_deinit(&stream);
760
761 h265e_dbg_func("leave\n");
762 return sei_nal.i_payload;
763 }
764
h265e_get_extra_info(H265eCtx * ctx,MppPacket pkt_out)765 MPP_RET h265e_get_extra_info(H265eCtx *ctx, MppPacket pkt_out)
766 {
767 RK_S32 k = 0;
768 size_t offset = 0;
769
770 if (pkt_out == NULL)
771 return MPP_NOK;
772
773 h265e_dbg_func("enter\n");
774
775 H265eExtraInfo *src = (H265eExtraInfo *)ctx->extra_info;
776
777 for (k = 0; k < src->nal_num; k++) {
778 h265e_dbg(H265E_DBG_HEADER, "get extra info nal type %d, size %d bytes",
779 src->nal[k].i_type, src->nal[k].i_payload);
780 mpp_packet_write(pkt_out, offset, src->nal[k].p_payload, src->nal[k].i_payload);
781 mpp_packet_add_segment_info(pkt_out, src->nal[k].i_type,
782 offset, src->nal[k].i_payload);
783 offset += src->nal[k].i_payload;
784 }
785 mpp_packet_set_length(pkt_out, offset);
786
787 h265e_dbg_func("leave\n");
788 return MPP_OK;
789 }
790