xref: /rockchip-linux_mpp/mpp/codec/enc/h264/h264e_sei.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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 "h264e_sei"
18 
19 #include <string.h>
20 
21 #include "mpp_common.h"
22 
23 #include "mpp_bitwrite.h"
24 #include "mpp_packet_impl.h"
25 #include "h264e_debug.h"
26 
27 #include "h264_syntax.h"
28 #include "h264e_sei.h"
29 
write_recovery_point(MppWriteCtx * bit,RK_U32 recovery_frame_cnt)30 static MPP_RET write_recovery_point(MppWriteCtx *bit, RK_U32 recovery_frame_cnt)
31 {
32     mpp_writer_put_ue(bit, recovery_frame_cnt);
33     mpp_writer_put_bits(bit, 1, 1);
34     mpp_writer_put_bits(bit, 0, 1);
35     mpp_writer_put_bits(bit, 0, 2);
36     mpp_writer_trailing(bit);
37     return MPP_OK;
38 }
39 
h264e_sei_recovery_point_to_packet(MppPacket packet,RK_S32 * len,RK_U32 recovery_frame_cnt)40 MPP_RET h264e_sei_recovery_point_to_packet(MppPacket packet, RK_S32 *len, RK_U32 recovery_frame_cnt)
41 {
42     MPP_RET ret = MPP_OK;
43     void *pos = mpp_packet_get_pos(packet);
44     void *pkt_base = mpp_packet_get_data(packet);
45     size_t pkt_size = mpp_packet_get_size(packet);
46     size_t length = mpp_packet_get_length(packet);
47     void *dst = pos + length;
48     RK_S32 buf_size = (pkt_base + pkt_size) - (pos + length);
49     MppWriteCtx bit_ctx;
50     MppWriteCtx *bit = &bit_ctx;
51     RK_S32 payload_size = 0;
52     RK_S32 type = H264_SEI_RECOVERY_POINT;
53     RK_U8 src[100] = {0};
54     RK_S32 sei_size = 0;
55     RK_S32 i;
56     mpp_writer_init(bit, src, 100);
57     write_recovery_point(bit, recovery_frame_cnt);
58     payload_size = mpp_writer_bytes(bit);
59 
60     mpp_writer_init(bit, dst, buf_size);
61 
62     /* start_code_prefix 00 00 00 01 */
63     mpp_writer_put_raw_bits(bit, 0, 24);
64     mpp_writer_put_raw_bits(bit, 1, 8);
65     /* forbidden_zero_bit */
66     mpp_writer_put_raw_bits(bit, 0, 1);
67     /* nal_ref_idc */
68     mpp_writer_put_raw_bits(bit, H264_NALU_PRIORITY_DISPOSABLE, 2);
69     /* nal_unit_type */
70     mpp_writer_put_raw_bits(bit, H264_NALU_TYPE_SEI, 5);
71 
72     /* sei_payload_type_ff_byte */
73     for (i = 0; i <= type - 255; i += 255)
74         mpp_writer_put_bits(bit, 0xff, 8);
75 
76     /* sei_last_payload_type_byte */
77     mpp_writer_put_bits(bit, type - i, 8);
78 
79     /* sei_payload_size_ff_byte */
80     for (i = 0; i <= payload_size - 255; i += 255)
81         mpp_writer_put_bits(bit, 0xff, 8);
82 
83     /* sei_last_payload_size_byte */
84     mpp_writer_put_bits(bit, payload_size - i, 8);
85 
86     write_recovery_point(bit, recovery_frame_cnt);
87 
88     sei_size = mpp_writer_bytes(bit);
89     if (len)
90         *len = sei_size;
91 
92     mpp_packet_set_length(packet, length + sei_size);
93     mpp_packet_add_segment_info(packet, H264_NALU_TYPE_SEI, length, sei_size);
94 
95     h264e_dbg_sei("sei data length %d pkt len %d -> %d\n", sei_size,
96                   length, length + sei_size);
97 
98     return ret;
99 
100 }
101 
h264e_sei_to_packet(MppPacket packet,RK_S32 * len,RK_S32 type,RK_U8 uuid[16],const void * data,RK_S32 size)102 MPP_RET h264e_sei_to_packet(MppPacket packet, RK_S32 *len, RK_S32 type,
103                             RK_U8 uuid[16], const void *data, RK_S32 size)
104 {
105     void *pos = mpp_packet_get_pos(packet);
106     void *pkt_base = mpp_packet_get_data(packet);
107     size_t pkt_size = mpp_packet_get_size(packet);
108     size_t length = mpp_packet_get_length(packet);
109     const RK_U8 *src = (RK_U8 *)data;
110     void *dst = pos + length;
111     RK_S32 buf_size = (pkt_base + pkt_size) - (pos + length);
112     MppWriteCtx bit_ctx;
113     MppWriteCtx *bit = &bit_ctx;
114     RK_S32 uuid_size = uuid ? 16 : 0;
115     RK_S32 payload_size = size + uuid_size;
116     RK_S32 sei_size = 0;
117     RK_S32 i;
118 
119     h264e_dbg_sei("write sei to pkt [%p:%u] [%p:%u]\n", pkt_base, pkt_size,
120                   pos, length);
121 
122     mpp_writer_init(bit, dst, buf_size);
123 
124     /* start_code_prefix 00 00 00 01 */
125     mpp_writer_put_raw_bits(bit, 0, 24);
126     mpp_writer_put_raw_bits(bit, 1, 8);
127     /* forbidden_zero_bit */
128     mpp_writer_put_raw_bits(bit, 0, 1);
129     /* nal_ref_idc */
130     mpp_writer_put_raw_bits(bit, H264_NALU_PRIORITY_DISPOSABLE, 2);
131     /* nal_unit_type */
132     mpp_writer_put_raw_bits(bit, H264_NALU_TYPE_SEI, 5);
133 
134     /* sei_payload_type_ff_byte */
135     for (i = 0; i <= type - 255; i += 255)
136         mpp_writer_put_bits(bit, 0xff, 8);
137 
138     /* sei_last_payload_type_byte */
139     mpp_writer_put_bits(bit, type - i, 8);
140 
141     /* sei_payload_size_ff_byte */
142     for (i = 0; i <= payload_size - 255; i += 255)
143         mpp_writer_put_bits(bit, 0xff, 8);
144 
145     /* sei_last_payload_size_byte */
146     mpp_writer_put_bits(bit, payload_size - i, 8);
147 
148     /* uuid_iso_iec_11578 */
149     for (i = 0; i < uuid_size; i++)
150         mpp_writer_put_bits(bit, uuid[i], 8);
151 
152     /* sei_payload_data */
153     for (i = 0; i < size; i++)
154         mpp_writer_put_bits(bit, src[i], 8);
155 
156     mpp_writer_trailing(bit);
157 
158     sei_size = mpp_writer_bytes(bit);
159     if (len)
160         *len = sei_size;
161 
162     mpp_packet_set_length(packet, length + sei_size);
163     mpp_packet_add_segment_info(packet, H264_NALU_TYPE_SEI, length, sei_size);
164 
165     h264e_dbg_sei("sei data length %d pkt len %d -> %d\n", sei_size,
166                   length, length + sei_size);
167 
168     return MPP_OK;
169 }
170