xref: /rockchip-linux_mpp/mpp/codec/enc/h264/h264e_sei.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2015 Rockchip Electronics Co. LTD
3*437bfbebSnyanmisaka  *
4*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
5*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
6*437bfbebSnyanmisaka  * You may obtain a copy of the License at
7*437bfbebSnyanmisaka  *
8*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
9*437bfbebSnyanmisaka  *
10*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
11*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
12*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
14*437bfbebSnyanmisaka  * limitations under the License.
15*437bfbebSnyanmisaka  */
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #define MODULE_TAG "h264e_sei"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <string.h>
20*437bfbebSnyanmisaka 
21*437bfbebSnyanmisaka #include "mpp_common.h"
22*437bfbebSnyanmisaka 
23*437bfbebSnyanmisaka #include "mpp_bitwrite.h"
24*437bfbebSnyanmisaka #include "mpp_packet_impl.h"
25*437bfbebSnyanmisaka #include "h264e_debug.h"
26*437bfbebSnyanmisaka 
27*437bfbebSnyanmisaka #include "h264_syntax.h"
28*437bfbebSnyanmisaka #include "h264e_sei.h"
29*437bfbebSnyanmisaka 
write_recovery_point(MppWriteCtx * bit,RK_U32 recovery_frame_cnt)30*437bfbebSnyanmisaka static MPP_RET write_recovery_point(MppWriteCtx *bit, RK_U32 recovery_frame_cnt)
31*437bfbebSnyanmisaka {
32*437bfbebSnyanmisaka     mpp_writer_put_ue(bit, recovery_frame_cnt);
33*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, 1, 1);
34*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, 0, 1);
35*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, 0, 2);
36*437bfbebSnyanmisaka     mpp_writer_trailing(bit);
37*437bfbebSnyanmisaka     return MPP_OK;
38*437bfbebSnyanmisaka }
39*437bfbebSnyanmisaka 
h264e_sei_recovery_point_to_packet(MppPacket packet,RK_S32 * len,RK_U32 recovery_frame_cnt)40*437bfbebSnyanmisaka MPP_RET h264e_sei_recovery_point_to_packet(MppPacket packet, RK_S32 *len, RK_U32 recovery_frame_cnt)
41*437bfbebSnyanmisaka {
42*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
43*437bfbebSnyanmisaka     void *pos = mpp_packet_get_pos(packet);
44*437bfbebSnyanmisaka     void *pkt_base = mpp_packet_get_data(packet);
45*437bfbebSnyanmisaka     size_t pkt_size = mpp_packet_get_size(packet);
46*437bfbebSnyanmisaka     size_t length = mpp_packet_get_length(packet);
47*437bfbebSnyanmisaka     void *dst = pos + length;
48*437bfbebSnyanmisaka     RK_S32 buf_size = (pkt_base + pkt_size) - (pos + length);
49*437bfbebSnyanmisaka     MppWriteCtx bit_ctx;
50*437bfbebSnyanmisaka     MppWriteCtx *bit = &bit_ctx;
51*437bfbebSnyanmisaka     RK_S32 payload_size = 0;
52*437bfbebSnyanmisaka     RK_S32 type = H264_SEI_RECOVERY_POINT;
53*437bfbebSnyanmisaka     RK_U8 src[100] = {0};
54*437bfbebSnyanmisaka     RK_S32 sei_size = 0;
55*437bfbebSnyanmisaka     RK_S32 i;
56*437bfbebSnyanmisaka     mpp_writer_init(bit, src, 100);
57*437bfbebSnyanmisaka     write_recovery_point(bit, recovery_frame_cnt);
58*437bfbebSnyanmisaka     payload_size = mpp_writer_bytes(bit);
59*437bfbebSnyanmisaka 
60*437bfbebSnyanmisaka     mpp_writer_init(bit, dst, buf_size);
61*437bfbebSnyanmisaka 
62*437bfbebSnyanmisaka     /* start_code_prefix 00 00 00 01 */
63*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bit, 0, 24);
64*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bit, 1, 8);
65*437bfbebSnyanmisaka     /* forbidden_zero_bit */
66*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bit, 0, 1);
67*437bfbebSnyanmisaka     /* nal_ref_idc */
68*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bit, H264_NALU_PRIORITY_DISPOSABLE, 2);
69*437bfbebSnyanmisaka     /* nal_unit_type */
70*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bit, H264_NALU_TYPE_SEI, 5);
71*437bfbebSnyanmisaka 
72*437bfbebSnyanmisaka     /* sei_payload_type_ff_byte */
73*437bfbebSnyanmisaka     for (i = 0; i <= type - 255; i += 255)
74*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, 0xff, 8);
75*437bfbebSnyanmisaka 
76*437bfbebSnyanmisaka     /* sei_last_payload_type_byte */
77*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, type - i, 8);
78*437bfbebSnyanmisaka 
79*437bfbebSnyanmisaka     /* sei_payload_size_ff_byte */
80*437bfbebSnyanmisaka     for (i = 0; i <= payload_size - 255; i += 255)
81*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, 0xff, 8);
82*437bfbebSnyanmisaka 
83*437bfbebSnyanmisaka     /* sei_last_payload_size_byte */
84*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, payload_size - i, 8);
85*437bfbebSnyanmisaka 
86*437bfbebSnyanmisaka     write_recovery_point(bit, recovery_frame_cnt);
87*437bfbebSnyanmisaka 
88*437bfbebSnyanmisaka     sei_size = mpp_writer_bytes(bit);
89*437bfbebSnyanmisaka     if (len)
90*437bfbebSnyanmisaka         *len = sei_size;
91*437bfbebSnyanmisaka 
92*437bfbebSnyanmisaka     mpp_packet_set_length(packet, length + sei_size);
93*437bfbebSnyanmisaka     mpp_packet_add_segment_info(packet, H264_NALU_TYPE_SEI, length, sei_size);
94*437bfbebSnyanmisaka 
95*437bfbebSnyanmisaka     h264e_dbg_sei("sei data length %d pkt len %d -> %d\n", sei_size,
96*437bfbebSnyanmisaka                   length, length + sei_size);
97*437bfbebSnyanmisaka 
98*437bfbebSnyanmisaka     return ret;
99*437bfbebSnyanmisaka 
100*437bfbebSnyanmisaka }
101*437bfbebSnyanmisaka 
h264e_sei_to_packet(MppPacket packet,RK_S32 * len,RK_S32 type,RK_U8 uuid[16],const void * data,RK_S32 size)102*437bfbebSnyanmisaka MPP_RET h264e_sei_to_packet(MppPacket packet, RK_S32 *len, RK_S32 type,
103*437bfbebSnyanmisaka                             RK_U8 uuid[16], const void *data, RK_S32 size)
104*437bfbebSnyanmisaka {
105*437bfbebSnyanmisaka     void *pos = mpp_packet_get_pos(packet);
106*437bfbebSnyanmisaka     void *pkt_base = mpp_packet_get_data(packet);
107*437bfbebSnyanmisaka     size_t pkt_size = mpp_packet_get_size(packet);
108*437bfbebSnyanmisaka     size_t length = mpp_packet_get_length(packet);
109*437bfbebSnyanmisaka     const RK_U8 *src = (RK_U8 *)data;
110*437bfbebSnyanmisaka     void *dst = pos + length;
111*437bfbebSnyanmisaka     RK_S32 buf_size = (pkt_base + pkt_size) - (pos + length);
112*437bfbebSnyanmisaka     MppWriteCtx bit_ctx;
113*437bfbebSnyanmisaka     MppWriteCtx *bit = &bit_ctx;
114*437bfbebSnyanmisaka     RK_S32 uuid_size = uuid ? 16 : 0;
115*437bfbebSnyanmisaka     RK_S32 payload_size = size + uuid_size;
116*437bfbebSnyanmisaka     RK_S32 sei_size = 0;
117*437bfbebSnyanmisaka     RK_S32 i;
118*437bfbebSnyanmisaka 
119*437bfbebSnyanmisaka     h264e_dbg_sei("write sei to pkt [%p:%u] [%p:%u]\n", pkt_base, pkt_size,
120*437bfbebSnyanmisaka                   pos, length);
121*437bfbebSnyanmisaka 
122*437bfbebSnyanmisaka     mpp_writer_init(bit, dst, buf_size);
123*437bfbebSnyanmisaka 
124*437bfbebSnyanmisaka     /* start_code_prefix 00 00 00 01 */
125*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bit, 0, 24);
126*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bit, 1, 8);
127*437bfbebSnyanmisaka     /* forbidden_zero_bit */
128*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bit, 0, 1);
129*437bfbebSnyanmisaka     /* nal_ref_idc */
130*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bit, H264_NALU_PRIORITY_DISPOSABLE, 2);
131*437bfbebSnyanmisaka     /* nal_unit_type */
132*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bit, H264_NALU_TYPE_SEI, 5);
133*437bfbebSnyanmisaka 
134*437bfbebSnyanmisaka     /* sei_payload_type_ff_byte */
135*437bfbebSnyanmisaka     for (i = 0; i <= type - 255; i += 255)
136*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, 0xff, 8);
137*437bfbebSnyanmisaka 
138*437bfbebSnyanmisaka     /* sei_last_payload_type_byte */
139*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, type - i, 8);
140*437bfbebSnyanmisaka 
141*437bfbebSnyanmisaka     /* sei_payload_size_ff_byte */
142*437bfbebSnyanmisaka     for (i = 0; i <= payload_size - 255; i += 255)
143*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, 0xff, 8);
144*437bfbebSnyanmisaka 
145*437bfbebSnyanmisaka     /* sei_last_payload_size_byte */
146*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, payload_size - i, 8);
147*437bfbebSnyanmisaka 
148*437bfbebSnyanmisaka     /* uuid_iso_iec_11578 */
149*437bfbebSnyanmisaka     for (i = 0; i < uuid_size; i++)
150*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, uuid[i], 8);
151*437bfbebSnyanmisaka 
152*437bfbebSnyanmisaka     /* sei_payload_data */
153*437bfbebSnyanmisaka     for (i = 0; i < size; i++)
154*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, src[i], 8);
155*437bfbebSnyanmisaka 
156*437bfbebSnyanmisaka     mpp_writer_trailing(bit);
157*437bfbebSnyanmisaka 
158*437bfbebSnyanmisaka     sei_size = mpp_writer_bytes(bit);
159*437bfbebSnyanmisaka     if (len)
160*437bfbebSnyanmisaka         *len = sei_size;
161*437bfbebSnyanmisaka 
162*437bfbebSnyanmisaka     mpp_packet_set_length(packet, length + sei_size);
163*437bfbebSnyanmisaka     mpp_packet_add_segment_info(packet, H264_NALU_TYPE_SEI, length, sei_size);
164*437bfbebSnyanmisaka 
165*437bfbebSnyanmisaka     h264e_dbg_sei("sei data length %d pkt len %d -> %d\n", sei_size,
166*437bfbebSnyanmisaka                   length, length + sei_size);
167*437bfbebSnyanmisaka 
168*437bfbebSnyanmisaka     return MPP_OK;
169*437bfbebSnyanmisaka }
170