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