xref: /rockchip-linux_mpp/mpp/hal/common/h264/hal_h264e_stream_amend.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2022 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 "hal_h264e_amend"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <stdio.h>
20*437bfbebSnyanmisaka #include <string.h>
21*437bfbebSnyanmisaka #include <unistd.h>
22*437bfbebSnyanmisaka 
23*437bfbebSnyanmisaka #include "mpp_mem.h"
24*437bfbebSnyanmisaka #include "mpp_common.h"
25*437bfbebSnyanmisaka #include "mpp_dmabuf.h"
26*437bfbebSnyanmisaka #include "mpp_packet_impl.h"
27*437bfbebSnyanmisaka 
28*437bfbebSnyanmisaka #include "mpp_enc_cfg.h"
29*437bfbebSnyanmisaka #include "mpp_enc_refs.h"
30*437bfbebSnyanmisaka 
31*437bfbebSnyanmisaka #include "hal_h264e_debug.h"
32*437bfbebSnyanmisaka #include "hal_h264e_stream_amend.h"
33*437bfbebSnyanmisaka 
34*437bfbebSnyanmisaka #include "h264e_sps.h"
35*437bfbebSnyanmisaka #include "h264e_pps.h"
36*437bfbebSnyanmisaka #include "h264e_slice.h"
37*437bfbebSnyanmisaka 
38*437bfbebSnyanmisaka #define START_CODE 0x000001 ///< start_code_prefix_one_3bytes
39*437bfbebSnyanmisaka 
get_next_nal(RK_U8 * buf,RK_S32 * length)40*437bfbebSnyanmisaka static RK_S32 get_next_nal(RK_U8 *buf, RK_S32 *length)
41*437bfbebSnyanmisaka {
42*437bfbebSnyanmisaka     RK_S32 i, consumed = 0;
43*437bfbebSnyanmisaka     RK_S32 len = *length;
44*437bfbebSnyanmisaka     RK_U8 *tmp_buf = buf;
45*437bfbebSnyanmisaka 
46*437bfbebSnyanmisaka     /* search start code */
47*437bfbebSnyanmisaka     while (len >= 4) {
48*437bfbebSnyanmisaka         if (tmp_buf[2] == 0) {
49*437bfbebSnyanmisaka             len--;
50*437bfbebSnyanmisaka             tmp_buf++;
51*437bfbebSnyanmisaka             continue;
52*437bfbebSnyanmisaka         }
53*437bfbebSnyanmisaka 
54*437bfbebSnyanmisaka         if (tmp_buf[0] != 0 || tmp_buf[1] != 0 || tmp_buf[2] != 1) {
55*437bfbebSnyanmisaka             RK_U32 state = (RK_U32) - 1;
56*437bfbebSnyanmisaka             RK_S32 has_nal = 0;
57*437bfbebSnyanmisaka 
58*437bfbebSnyanmisaka             for (i = 0; i < (RK_S32)len; i++) {
59*437bfbebSnyanmisaka                 state = (state << 8) | tmp_buf[i];
60*437bfbebSnyanmisaka                 if (((state >> 8) & 0xFFFFFF) == START_CODE) {
61*437bfbebSnyanmisaka                     has_nal = 1;
62*437bfbebSnyanmisaka                     i = i - 3;
63*437bfbebSnyanmisaka                     break;
64*437bfbebSnyanmisaka                 }
65*437bfbebSnyanmisaka             }
66*437bfbebSnyanmisaka 
67*437bfbebSnyanmisaka             if (has_nal) {
68*437bfbebSnyanmisaka                 len -= i;
69*437bfbebSnyanmisaka                 tmp_buf += i;
70*437bfbebSnyanmisaka                 consumed = *length - len - 1;
71*437bfbebSnyanmisaka                 break;
72*437bfbebSnyanmisaka             }
73*437bfbebSnyanmisaka 
74*437bfbebSnyanmisaka             consumed = *length;
75*437bfbebSnyanmisaka             break;
76*437bfbebSnyanmisaka         }
77*437bfbebSnyanmisaka         tmp_buf   += 3;
78*437bfbebSnyanmisaka         len       -= 3;
79*437bfbebSnyanmisaka     }
80*437bfbebSnyanmisaka 
81*437bfbebSnyanmisaka     *length = *length - consumed;
82*437bfbebSnyanmisaka     return consumed;
83*437bfbebSnyanmisaka }
84*437bfbebSnyanmisaka 
h264e_vepu_stream_amend_init(HalH264eVepuStreamAmend * ctx)85*437bfbebSnyanmisaka MPP_RET h264e_vepu_stream_amend_init(HalH264eVepuStreamAmend *ctx)
86*437bfbebSnyanmisaka {
87*437bfbebSnyanmisaka     memset(ctx, 0, sizeof(*ctx));
88*437bfbebSnyanmisaka     ctx->buf_size = SZ_128K;
89*437bfbebSnyanmisaka     return MPP_OK;
90*437bfbebSnyanmisaka }
91*437bfbebSnyanmisaka 
h264e_vepu_stream_amend_deinit(HalH264eVepuStreamAmend * ctx)92*437bfbebSnyanmisaka MPP_RET h264e_vepu_stream_amend_deinit(HalH264eVepuStreamAmend *ctx)
93*437bfbebSnyanmisaka {
94*437bfbebSnyanmisaka     MPP_FREE(ctx->src_buf);
95*437bfbebSnyanmisaka     MPP_FREE(ctx->dst_buf);
96*437bfbebSnyanmisaka     return MPP_OK;
97*437bfbebSnyanmisaka }
98*437bfbebSnyanmisaka 
h264e_vepu_stream_amend_config(HalH264eVepuStreamAmend * ctx,MppPacket packet,MppEncCfgSet * cfg,H264eSlice * slice,H264ePrefixNal * prefix)99*437bfbebSnyanmisaka MPP_RET h264e_vepu_stream_amend_config(HalH264eVepuStreamAmend *ctx,
100*437bfbebSnyanmisaka                                        MppPacket packet, MppEncCfgSet *cfg,
101*437bfbebSnyanmisaka                                        H264eSlice *slice, H264ePrefixNal *prefix)
102*437bfbebSnyanmisaka {
103*437bfbebSnyanmisaka     MppEncRefCfgImpl *ref = (MppEncRefCfgImpl *)cfg->ref_cfg;
104*437bfbebSnyanmisaka     MppEncH264Cfg    *h264 = &cfg->h264;
105*437bfbebSnyanmisaka     MppEncH264HwCfg  *hw_cfg = &h264->hw_cfg;
106*437bfbebSnyanmisaka 
107*437bfbebSnyanmisaka     if (ref->lt_cfg_cnt || ref->st_cfg_cnt > 1 ||
108*437bfbebSnyanmisaka         hw_cfg->hw_poc_type != h264->poc_type ||
109*437bfbebSnyanmisaka         hw_cfg->hw_log2_max_frame_num_minus4 != h264->log2_max_frame_num) {
110*437bfbebSnyanmisaka         ctx->enable = 1;
111*437bfbebSnyanmisaka         ctx->slice_enabled = 0;
112*437bfbebSnyanmisaka 
113*437bfbebSnyanmisaka         if (NULL == ctx->dst_buf)
114*437bfbebSnyanmisaka             ctx->dst_buf = mpp_calloc(RK_U8, ctx->buf_size);
115*437bfbebSnyanmisaka         if (NULL == ctx->src_buf)
116*437bfbebSnyanmisaka             ctx->src_buf = mpp_calloc(RK_U8, ctx->buf_size);
117*437bfbebSnyanmisaka     } else {
118*437bfbebSnyanmisaka         MPP_FREE(ctx->dst_buf);
119*437bfbebSnyanmisaka         MPP_FREE(ctx->src_buf);
120*437bfbebSnyanmisaka         h264e_vepu_stream_amend_init(ctx);
121*437bfbebSnyanmisaka     }
122*437bfbebSnyanmisaka 
123*437bfbebSnyanmisaka     slice->pic_order_cnt_type = cfg->h264.poc_type;
124*437bfbebSnyanmisaka 
125*437bfbebSnyanmisaka     ctx->slice = slice;
126*437bfbebSnyanmisaka     if (ref->lt_cfg_cnt || ref->st_cfg_cnt > 1)
127*437bfbebSnyanmisaka         ctx->prefix = prefix;
128*437bfbebSnyanmisaka 
129*437bfbebSnyanmisaka     ctx->packet = packet;
130*437bfbebSnyanmisaka     ctx->buf_base = mpp_packet_get_length(packet);
131*437bfbebSnyanmisaka     ctx->old_length = 0;
132*437bfbebSnyanmisaka     ctx->new_length = 0;
133*437bfbebSnyanmisaka 
134*437bfbebSnyanmisaka     return MPP_OK;
135*437bfbebSnyanmisaka }
136*437bfbebSnyanmisaka 
h264e_vepu_stream_amend_proc(HalH264eVepuStreamAmend * ctx,MppEncH264HwCfg * hw_cfg)137*437bfbebSnyanmisaka MPP_RET h264e_vepu_stream_amend_proc(HalH264eVepuStreamAmend *ctx, MppEncH264HwCfg *hw_cfg)
138*437bfbebSnyanmisaka {
139*437bfbebSnyanmisaka     H264ePrefixNal *prefix = ctx->prefix;
140*437bfbebSnyanmisaka     H264eSlice *slice = ctx->slice;
141*437bfbebSnyanmisaka     MppPacket pkt = ctx->packet;
142*437bfbebSnyanmisaka     RK_U8 *p = mpp_packet_get_pos(pkt);
143*437bfbebSnyanmisaka     RK_S32 base = ctx->buf_base;
144*437bfbebSnyanmisaka     RK_S32 len = ctx->old_length;
145*437bfbebSnyanmisaka     RK_S32 hw_len_bit = 0;
146*437bfbebSnyanmisaka     RK_S32 sw_len_bit = 0;
147*437bfbebSnyanmisaka     RK_S32 hw_len_byte = 0;
148*437bfbebSnyanmisaka     RK_S32 sw_len_byte = 0;
149*437bfbebSnyanmisaka     RK_S32 diff_size = 0;
150*437bfbebSnyanmisaka     RK_S32 tail_0bit = 0;
151*437bfbebSnyanmisaka     RK_U8  tail_byte = 0;
152*437bfbebSnyanmisaka     RK_U8  tail_tmp = 0;
153*437bfbebSnyanmisaka     RK_U8 *dst_buf = NULL;
154*437bfbebSnyanmisaka     RK_S32 buf_size;
155*437bfbebSnyanmisaka     RK_S32 final_len = 0;
156*437bfbebSnyanmisaka     RK_S32 last_slice = 0;
157*437bfbebSnyanmisaka     const MppPktSeg *seg = mpp_packet_get_segment_info(pkt);
158*437bfbebSnyanmisaka     MppPacket pkt_tmp;
159*437bfbebSnyanmisaka     RK_S32 offset = 0;
160*437bfbebSnyanmisaka     RK_U32 is_cabac = ctx->slice->entropy_coding_mode;
161*437bfbebSnyanmisaka 
162*437bfbebSnyanmisaka     mpp_packet_new(&pkt_tmp);
163*437bfbebSnyanmisaka 
164*437bfbebSnyanmisaka     if (seg) {
165*437bfbebSnyanmisaka         while (seg && seg->type != 1 && seg->type != 5) {
166*437bfbebSnyanmisaka             mpp_packet_add_segment_info(pkt_tmp, seg->type, offset, seg->len);
167*437bfbebSnyanmisaka             offset += seg->len;
168*437bfbebSnyanmisaka 
169*437bfbebSnyanmisaka             seg = seg->next;
170*437bfbebSnyanmisaka         }
171*437bfbebSnyanmisaka     }
172*437bfbebSnyanmisaka 
173*437bfbebSnyanmisaka     {
174*437bfbebSnyanmisaka         MppBuffer buf = mpp_packet_get_buffer(pkt);
175*437bfbebSnyanmisaka         RK_S32 fd = mpp_buffer_get_fd(buf);
176*437bfbebSnyanmisaka 
177*437bfbebSnyanmisaka         mpp_dmabuf_sync_partial_begin(fd, 1, base, len, __FUNCTION__);
178*437bfbebSnyanmisaka     }
179*437bfbebSnyanmisaka 
180*437bfbebSnyanmisaka     {
181*437bfbebSnyanmisaka         RK_S32 more_buf = 0;
182*437bfbebSnyanmisaka         while (len > ctx->buf_size - 16) {
183*437bfbebSnyanmisaka             ctx->buf_size *= 2;
184*437bfbebSnyanmisaka             more_buf = 1;
185*437bfbebSnyanmisaka         }
186*437bfbebSnyanmisaka 
187*437bfbebSnyanmisaka         if (more_buf) {
188*437bfbebSnyanmisaka             MPP_FREE(ctx->src_buf);
189*437bfbebSnyanmisaka             MPP_FREE(ctx->dst_buf);
190*437bfbebSnyanmisaka             ctx->src_buf = mpp_malloc(RK_U8, ctx->buf_size);
191*437bfbebSnyanmisaka             ctx->dst_buf = mpp_malloc(RK_U8, ctx->buf_size);
192*437bfbebSnyanmisaka         }
193*437bfbebSnyanmisaka     }
194*437bfbebSnyanmisaka 
195*437bfbebSnyanmisaka     memset(ctx->dst_buf, 0, ctx->buf_size);
196*437bfbebSnyanmisaka     memset(ctx->src_buf, 0, ctx->buf_size);
197*437bfbebSnyanmisaka     dst_buf = ctx->dst_buf;
198*437bfbebSnyanmisaka     buf_size = ctx->buf_size;
199*437bfbebSnyanmisaka     p += base;
200*437bfbebSnyanmisaka 
201*437bfbebSnyanmisaka     do {
202*437bfbebSnyanmisaka         RK_U32 nal_len = 0;
203*437bfbebSnyanmisaka 
204*437bfbebSnyanmisaka         tail_0bit = 0;
205*437bfbebSnyanmisaka         // copy hw stream to stream buffer first
206*437bfbebSnyanmisaka         if (slice->is_multi_slice) {
207*437bfbebSnyanmisaka             if ((!seg) || !hw_cfg->hw_split_out || !is_cabac) {
208*437bfbebSnyanmisaka                 nal_len = get_next_nal(p, &len);
209*437bfbebSnyanmisaka                 last_slice = (len == 0);
210*437bfbebSnyanmisaka             } else {
211*437bfbebSnyanmisaka                 nal_len = seg->len;
212*437bfbebSnyanmisaka                 len -= seg->len;
213*437bfbebSnyanmisaka                 seg = seg->next;
214*437bfbebSnyanmisaka                 if (!seg || !len)
215*437bfbebSnyanmisaka                     last_slice = 1;
216*437bfbebSnyanmisaka             }
217*437bfbebSnyanmisaka             memcpy(ctx->src_buf, p, nal_len);
218*437bfbebSnyanmisaka             p += nal_len;
219*437bfbebSnyanmisaka         } else {
220*437bfbebSnyanmisaka             memcpy(ctx->src_buf, p, len);
221*437bfbebSnyanmisaka             nal_len = len;
222*437bfbebSnyanmisaka             last_slice = 1;
223*437bfbebSnyanmisaka         }
224*437bfbebSnyanmisaka 
225*437bfbebSnyanmisaka         hal_h264e_dbg_amend("nal_len %d multi %d last %d prefix %p\n",
226*437bfbebSnyanmisaka                             nal_len, slice->is_multi_slice, last_slice, prefix);
227*437bfbebSnyanmisaka 
228*437bfbebSnyanmisaka         if (prefix) {
229*437bfbebSnyanmisaka             /* add prefix for each slice */
230*437bfbebSnyanmisaka             RK_S32 prefix_bit = h264e_slice_write_prefix_nal_unit_svc(prefix, dst_buf, buf_size);
231*437bfbebSnyanmisaka 
232*437bfbebSnyanmisaka             prefix_bit = (prefix_bit + 7) / 8;
233*437bfbebSnyanmisaka 
234*437bfbebSnyanmisaka             dst_buf += prefix_bit;
235*437bfbebSnyanmisaka             buf_size -= prefix_bit;
236*437bfbebSnyanmisaka             final_len += prefix_bit;
237*437bfbebSnyanmisaka 
238*437bfbebSnyanmisaka             mpp_packet_add_segment_info(pkt_tmp, H264_NALU_TYPE_PREFIX, offset, prefix_bit);
239*437bfbebSnyanmisaka             offset += prefix_bit;
240*437bfbebSnyanmisaka         }
241*437bfbebSnyanmisaka 
242*437bfbebSnyanmisaka         H264eSlice slice_rd;
243*437bfbebSnyanmisaka 
244*437bfbebSnyanmisaka         memcpy(&slice_rd, slice, sizeof(slice_rd));
245*437bfbebSnyanmisaka 
246*437bfbebSnyanmisaka         /* update slice by hw_cfg */
247*437bfbebSnyanmisaka         slice_rd.pic_order_cnt_type = hw_cfg->hw_poc_type;
248*437bfbebSnyanmisaka         slice_rd.log2_max_frame_num = hw_cfg->hw_log2_max_frame_num_minus4 + 4;
249*437bfbebSnyanmisaka 
250*437bfbebSnyanmisaka         if (ctx->reorder) {
251*437bfbebSnyanmisaka             slice_rd.reorder = ctx->reorder;
252*437bfbebSnyanmisaka             h264e_reorder_init(slice_rd.reorder);
253*437bfbebSnyanmisaka         }
254*437bfbebSnyanmisaka         if (ctx->marking) {
255*437bfbebSnyanmisaka             slice_rd.marking = ctx->marking;
256*437bfbebSnyanmisaka             h264e_marking_init(slice_rd.marking);
257*437bfbebSnyanmisaka         }
258*437bfbebSnyanmisaka 
259*437bfbebSnyanmisaka         hw_len_bit = h264e_slice_read(&slice_rd, ctx->src_buf, nal_len);
260*437bfbebSnyanmisaka 
261*437bfbebSnyanmisaka         // write new header to header buffer
262*437bfbebSnyanmisaka         slice->qp_delta = slice_rd.qp_delta;
263*437bfbebSnyanmisaka         slice->first_mb_in_slice = slice_rd.first_mb_in_slice;
264*437bfbebSnyanmisaka 
265*437bfbebSnyanmisaka         if (ctx->reorder)
266*437bfbebSnyanmisaka             slice->reorder = slice_rd.reorder;
267*437bfbebSnyanmisaka         if (ctx->marking)
268*437bfbebSnyanmisaka             slice->marking = slice_rd.marking;
269*437bfbebSnyanmisaka 
270*437bfbebSnyanmisaka         sw_len_bit = h264e_slice_write(slice, dst_buf, buf_size);
271*437bfbebSnyanmisaka 
272*437bfbebSnyanmisaka         hw_len_byte = (hw_len_bit + 7) / 8;
273*437bfbebSnyanmisaka         sw_len_byte = (sw_len_bit + 7) / 8;
274*437bfbebSnyanmisaka 
275*437bfbebSnyanmisaka         tail_byte = ctx->src_buf[nal_len - 1];
276*437bfbebSnyanmisaka         tail_tmp = tail_byte;
277*437bfbebSnyanmisaka 
278*437bfbebSnyanmisaka         while (!(tail_tmp & 1) && tail_0bit < 8) {
279*437bfbebSnyanmisaka             tail_tmp >>= 1;
280*437bfbebSnyanmisaka             tail_0bit++;
281*437bfbebSnyanmisaka         }
282*437bfbebSnyanmisaka 
283*437bfbebSnyanmisaka         mpp_assert(tail_0bit < 8);
284*437bfbebSnyanmisaka 
285*437bfbebSnyanmisaka         // move the reset slice data from src buffer to dst buffer
286*437bfbebSnyanmisaka         diff_size = h264e_slice_move(dst_buf, ctx->src_buf,
287*437bfbebSnyanmisaka                                      sw_len_bit, hw_len_bit, nal_len);
288*437bfbebSnyanmisaka 
289*437bfbebSnyanmisaka         hal_h264e_dbg_amend("tail 0x%02x %d hw_hdr %d sw_hdr %d len %d hw_byte %d sw_byte %d diff %d\n",
290*437bfbebSnyanmisaka                             tail_byte, tail_0bit, hw_len_bit, sw_len_bit, nal_len, hw_len_byte, sw_len_byte, diff_size);
291*437bfbebSnyanmisaka 
292*437bfbebSnyanmisaka         if (slice->entropy_coding_mode) {
293*437bfbebSnyanmisaka             memcpy(dst_buf + sw_len_byte, ctx->src_buf + hw_len_byte,
294*437bfbebSnyanmisaka                    nal_len - hw_len_byte);
295*437bfbebSnyanmisaka             final_len += nal_len - hw_len_byte + sw_len_byte;
296*437bfbebSnyanmisaka             nal_len = nal_len - hw_len_byte + sw_len_byte;
297*437bfbebSnyanmisaka         } else {
298*437bfbebSnyanmisaka             RK_S32 hdr_diff_bit = sw_len_bit - hw_len_bit;
299*437bfbebSnyanmisaka             RK_S32 bit_len = nal_len * 8 - tail_0bit + hdr_diff_bit;
300*437bfbebSnyanmisaka             RK_S32 new_len = (bit_len + diff_size * 8 + 7) / 8;
301*437bfbebSnyanmisaka 
302*437bfbebSnyanmisaka             hal_h264e_dbg_amend("frm %4d %c len %d bit hw %d sw %d byte hw %d sw %d diff %d -> %d\n",
303*437bfbebSnyanmisaka                                 slice->frame_num, (slice->idr_flag ? 'I' : 'P'),
304*437bfbebSnyanmisaka                                 nal_len, hw_len_bit, sw_len_bit,
305*437bfbebSnyanmisaka                                 hw_len_byte, sw_len_byte, diff_size, new_len);
306*437bfbebSnyanmisaka 
307*437bfbebSnyanmisaka             hal_h264e_dbg_amend("%02x %02x %02x %02x -> %02x %02x %02x %02x\n",
308*437bfbebSnyanmisaka                                 ctx->src_buf[nal_len - 4], ctx->src_buf[nal_len - 3],
309*437bfbebSnyanmisaka                                 ctx->src_buf[nal_len - 2], ctx->src_buf[nal_len - 1],
310*437bfbebSnyanmisaka                                 dst_buf[new_len - 4], dst_buf[new_len - 3],
311*437bfbebSnyanmisaka                                 dst_buf[new_len - 2], dst_buf[new_len - 1]);
312*437bfbebSnyanmisaka             nal_len = new_len;
313*437bfbebSnyanmisaka             final_len += new_len;
314*437bfbebSnyanmisaka         }
315*437bfbebSnyanmisaka 
316*437bfbebSnyanmisaka         {
317*437bfbebSnyanmisaka             H264NaluType type = slice->idr_flag ?  H264_NALU_TYPE_IDR : H264_NALU_TYPE_SLICE;
318*437bfbebSnyanmisaka 
319*437bfbebSnyanmisaka             mpp_packet_add_segment_info(pkt_tmp, type, offset, nal_len);
320*437bfbebSnyanmisaka             offset += nal_len;
321*437bfbebSnyanmisaka         }
322*437bfbebSnyanmisaka 
323*437bfbebSnyanmisaka         if (last_slice) {
324*437bfbebSnyanmisaka             p = mpp_packet_get_pos(pkt);
325*437bfbebSnyanmisaka             p += base;
326*437bfbebSnyanmisaka             memcpy(p, ctx->dst_buf, final_len);
327*437bfbebSnyanmisaka 
328*437bfbebSnyanmisaka             if (slice->entropy_coding_mode) {
329*437bfbebSnyanmisaka                 if (final_len < ctx->old_length)
330*437bfbebSnyanmisaka                     memset(p + final_len, 0,  ctx->old_length - final_len);
331*437bfbebSnyanmisaka             } else
332*437bfbebSnyanmisaka                 p[final_len] = 0;
333*437bfbebSnyanmisaka 
334*437bfbebSnyanmisaka             break;
335*437bfbebSnyanmisaka         }
336*437bfbebSnyanmisaka 
337*437bfbebSnyanmisaka         dst_buf += nal_len;
338*437bfbebSnyanmisaka         buf_size -= nal_len;
339*437bfbebSnyanmisaka     } while (1);
340*437bfbebSnyanmisaka 
341*437bfbebSnyanmisaka     ctx->new_length = final_len;
342*437bfbebSnyanmisaka 
343*437bfbebSnyanmisaka     /* update segment */
344*437bfbebSnyanmisaka     mpp_packet_copy_segment_info(pkt, pkt_tmp);
345*437bfbebSnyanmisaka 
346*437bfbebSnyanmisaka     mpp_packet_deinit(&pkt_tmp);
347*437bfbebSnyanmisaka 
348*437bfbebSnyanmisaka     return MPP_OK;
349*437bfbebSnyanmisaka }
350*437bfbebSnyanmisaka 
h264e_vepu_stream_amend_sync_ref_idc(HalH264eVepuStreamAmend * ctx)351*437bfbebSnyanmisaka MPP_RET h264e_vepu_stream_amend_sync_ref_idc(HalH264eVepuStreamAmend *ctx)
352*437bfbebSnyanmisaka {
353*437bfbebSnyanmisaka     H264eSlice *slice = ctx->slice;
354*437bfbebSnyanmisaka     MppPacket pkt = ctx->packet;
355*437bfbebSnyanmisaka     RK_S32 base = ctx->buf_base;
356*437bfbebSnyanmisaka     RK_S32 len = ctx->old_length;
357*437bfbebSnyanmisaka     RK_U8 *p = mpp_packet_get_pos(pkt) + base;
358*437bfbebSnyanmisaka     RK_U8 val = 0;
359*437bfbebSnyanmisaka     RK_S32 hw_nal_ref_idc = 0;
360*437bfbebSnyanmisaka     RK_S32 sw_nal_ref_idc = 0;
361*437bfbebSnyanmisaka 
362*437bfbebSnyanmisaka     {
363*437bfbebSnyanmisaka         MppBuffer buf = mpp_packet_get_buffer(pkt);
364*437bfbebSnyanmisaka         RK_S32 fd = mpp_buffer_get_fd(buf);
365*437bfbebSnyanmisaka 
366*437bfbebSnyanmisaka         mpp_dmabuf_sync_partial_begin(fd, 1, base, len, __FUNCTION__);
367*437bfbebSnyanmisaka     }
368*437bfbebSnyanmisaka 
369*437bfbebSnyanmisaka     val = p[4];
370*437bfbebSnyanmisaka     hw_nal_ref_idc = (val >> 5) & 0x3;
371*437bfbebSnyanmisaka     sw_nal_ref_idc = slice->nal_reference_idc;
372*437bfbebSnyanmisaka 
373*437bfbebSnyanmisaka     if (hw_nal_ref_idc == sw_nal_ref_idc)
374*437bfbebSnyanmisaka         return MPP_OK;
375*437bfbebSnyanmisaka 
376*437bfbebSnyanmisaka     /* fix nal_ref_idc in all slice */
377*437bfbebSnyanmisaka     if (!slice->is_multi_slice) {
378*437bfbebSnyanmisaka         /* single slice do NOT scan */
379*437bfbebSnyanmisaka         val = val & (~0x60);
380*437bfbebSnyanmisaka         val |= (sw_nal_ref_idc << 5) & 0x60;
381*437bfbebSnyanmisaka         p[4] = val;
382*437bfbebSnyanmisaka         return MPP_OK;
383*437bfbebSnyanmisaka     }
384*437bfbebSnyanmisaka 
385*437bfbebSnyanmisaka     /* multi-slice fix each nal_ref_idc */
386*437bfbebSnyanmisaka     do {
387*437bfbebSnyanmisaka         RK_U32 nal_len = get_next_nal(p, &len);
388*437bfbebSnyanmisaka 
389*437bfbebSnyanmisaka         val = p[4];
390*437bfbebSnyanmisaka         val = val & (~0x60);
391*437bfbebSnyanmisaka         val |= (sw_nal_ref_idc << 5) & 0x60;
392*437bfbebSnyanmisaka         p[4] = val;
393*437bfbebSnyanmisaka 
394*437bfbebSnyanmisaka         if (len == 0)
395*437bfbebSnyanmisaka             break;
396*437bfbebSnyanmisaka 
397*437bfbebSnyanmisaka         p += nal_len;
398*437bfbebSnyanmisaka     } while (1);
399*437bfbebSnyanmisaka 
400*437bfbebSnyanmisaka     return MPP_OK;
401*437bfbebSnyanmisaka }
402