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_stream"
18
19 #include "mpp_common.h"
20 #include "mpp_mem.h"
21
22 #include "h265e_stream.h"
23 #include "h265e_codec.h"
24
25 static const RK_U8 ue_size_tab[256] = {
26 1, 1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7,
27 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
28 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
29 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
30 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
31 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
32 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
33 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
34 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
35 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
36 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
37 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
38 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
39 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
40 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
41 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
42 };
43
h265e_stream_init(H265eStream * s)44 MPP_RET h265e_stream_init(H265eStream *s)
45 {
46 s->buf = mpp_calloc(RK_U8, H265E_EXTRA_INFO_BUF_SIZE);
47 s->size = H265E_EXTRA_INFO_BUF_SIZE;
48 mpp_writer_init(&s->enc_stream, s->buf, s->size);
49 return MPP_OK;
50 }
51
h265e_stream_deinit(H265eStream * s)52 MPP_RET h265e_stream_deinit(H265eStream *s)
53 {
54 MPP_FREE(s->buf);
55 mpp_writer_reset(&s->enc_stream);
56 return MPP_OK;
57 }
58
h265e_stream_reset(H265eStream * s)59 MPP_RET h265e_stream_reset(H265eStream *s)
60 {
61 mpp_writer_reset(&s->enc_stream);
62 return MPP_OK;
63 }
64
h265e_stream_realign(H265eStream * s)65 MPP_RET h265e_stream_realign(H265eStream *s)
66 {
67 if (s->enc_stream.buffered_bits)
68 mpp_writer_trailing(&s->enc_stream);
69 return MPP_OK;
70 }
71
h265e_stream_write_with_log(H265eStream * s,RK_U32 val,RK_S32 i_count,char * name)72 MPP_RET h265e_stream_write_with_log(H265eStream *s,
73 RK_U32 val, RK_S32 i_count, char *name)
74 {
75
76 h265e_dbg(H265E_DBG_HEADER, "write bits name %s, count %d, val %d",
77 name, i_count, val);
78
79 mpp_writer_put_bits(&s->enc_stream, val, i_count);
80 return MPP_OK;
81 }
82
h265e_stream_write1_with_log(H265eStream * s,RK_U32 val,char * name)83 MPP_RET h265e_stream_write1_with_log(H265eStream *s,
84 RK_U32 val, char *name)
85 {
86 h265e_dbg(H265E_DBG_HEADER, "write 1 bit name %s, val %d", name, val);
87
88 mpp_writer_put_bits(&s->enc_stream, val, 1);
89
90 return MPP_OK;
91 }
92
h265e_stream_write_ue_with_log(H265eStream * s,RK_U32 val,char * name)93 MPP_RET h265e_stream_write_ue_with_log(H265eStream *s,
94 RK_U32 val, char *name)
95 {
96
97 h265e_dbg(H265E_DBG_HEADER,
98 "write UE bits name %s, val %d ",
99 name, val);
100 #if 1
101 RK_S32 size = 0;
102 RK_S32 tmp = ++val;
103
104 h265e_dbg(H265E_DBG_HEADER,
105 "write UE bits name %s, val %d ",
106 name, val);
107 if (tmp >= 0x10000) {
108 size = 32;
109 tmp >>= 16;
110 }
111 if (tmp >= 0x100) {
112 size += 16;
113 tmp >>= 8;
114 }
115 size += ue_size_tab[tmp];
116
117 h265e_stream_write_with_log(s, 0, size >> 1, name);
118 h265e_stream_write_with_log(s, val, (size >> 1) + 1, name);
119 #else
120 mpp_writer_write_ue(&s->enc_stream, val, name);
121 #endif
122 return MPP_OK;
123 }
124
h265e_stream_write_se_with_log(H265eStream * s,RK_S32 val,char * name)125 MPP_RET h265e_stream_write_se_with_log(H265eStream *s,
126 RK_S32 val, char *name)
127 {
128 RK_S32 size = 0;
129 RK_S32 tmp = 1 - val * 2;
130 if (tmp < 0)
131 tmp = val * 2;
132
133 val = tmp;
134 if (tmp >= 0x100) {
135 size = 16;
136 tmp >>= 8;
137 }
138 size += ue_size_tab[tmp];
139
140 h265e_dbg(H265E_DBG_HEADER,
141 "write SE bits name %s, val %d ",
142 name, val);
143
144 return h265e_stream_write_with_log(s, val, size, name);;
145 }
146
h265e_stream_write32(H265eStream * s,RK_U32 i_bits,char * name)147 MPP_RET h265e_stream_write32(H265eStream *s, RK_U32 i_bits,
148 char *name)
149 {
150 h265e_stream_write_with_log(s, i_bits >> 16, 16, name);
151 h265e_stream_write_with_log(s, i_bits, 16, name);
152 return MPP_OK;
153 }
154
h265e_stream_size_se(RK_S32 val)155 RK_S32 h265e_stream_size_se( RK_S32 val )
156 {
157 RK_S32 tmp = 1 - val * 2;
158 if ( tmp < 0 ) tmp = val * 2;
159 if ( tmp < 256 )
160 return ue_size_tab[tmp];
161 else
162 return ue_size_tab[tmp >> 8] + 16;
163 }
164
h265e_stream_rbsp_trailing(H265eStream * s)165 MPP_RET h265e_stream_rbsp_trailing(H265eStream *s)
166 {
167 //align bits, 1+N zeros.
168 mpp_writer_trailing(&s->enc_stream);
169 return MPP_OK;
170 }
171
172 /*
173 * Write the rest of cur_bits to the bitstream;
174 * results in a bitstream no longer 32-bit aligned.
175 */
h265e_stream_flush(H265eStream * s)176 MPP_RET h265e_stream_flush(H265eStream *s)
177 {
178 if (s->enc_stream.buffered_bits)
179 mpp_writer_trailing(&s->enc_stream);
180 return MPP_OK;
181 }
182