xref: /rockchip-linux_mpp/mpp/codec/enc/h264/h264e_slice.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_slice"
18 
19 #include <string.h>
20 
21 #include "mpp_mem.h"
22 #include "mpp_bitread.h"
23 #include "mpp_bitwrite.h"
24 
25 #include "h264e_debug.h"
26 #include "h264e_slice.h"
27 #include "h264e_dpb.h"
28 
29 #define FP_FIFO_IS_FULL
30 
h264e_slice_init(H264eSlice * slice,H264eReorderInfo * reorder,H264eMarkingInfo * marking)31 void h264e_slice_init(H264eSlice *slice, H264eReorderInfo *reorder,
32                       H264eMarkingInfo *marking)
33 {
34     memset(slice, 0, sizeof(*slice));
35 
36     slice->num_ref_idx_active = 1;
37 
38     slice->reorder = reorder;
39     slice->marking = marking;
40 }
41 
h264e_slice_update(H264eSlice * slice,MppEncCfgSet * cfg,H264eSps * sps,H264ePps * pps,H264eDpbFrm * frm)42 RK_S32 h264e_slice_update(H264eSlice *slice, MppEncCfgSet *cfg,
43                           H264eSps *sps, H264ePps *pps, H264eDpbFrm *frm)
44 {
45     MppEncH264Cfg *h264 = &cfg->h264;
46     RK_S32 is_idr = frm->status.is_idr;
47 
48     slice->mb_w = sps->pic_width_in_mbs;
49     slice->mb_h = sps->pic_height_in_mbs;
50     slice->max_num_ref_frames = sps->num_ref_frames;
51     slice->log2_max_frame_num = sps->log2_max_frame_num_minus4 + 4;
52     slice->log2_max_poc_lsb = sps->log2_max_poc_lsb_minus4 + 4;
53     slice->entropy_coding_mode = h264->entropy_coding_mode;
54     slice->pic_order_cnt_type = sps->pic_order_cnt_type;
55     slice->qp_init = pps->pic_init_qp;
56 
57     slice->nal_reference_idc = (frm->status.is_non_ref) ? (H264_NALU_PRIORITY_DISPOSABLE) :
58                                (is_idr) ? (H264_NALU_PRIORITY_HIGHEST) :
59                                (H264_NALU_PRIORITY_HIGH);
60     slice->nalu_type = (is_idr) ? (H264_NALU_TYPE_IDR) : (H264_NALU_TYPE_SLICE);
61 
62     slice->first_mb_in_slice = 0;
63     slice->slice_type = (is_idr) ? (H264_I_SLICE) : (H264_P_SLICE);
64     slice->pic_parameter_set_id = 0;
65     slice->frame_num = frm->frame_num;
66     slice->num_ref_idx_override = 0;
67     slice->qp_delta = 0;
68     slice->cabac_init_idc = h264->entropy_coding_mode ? h264->cabac_init_idc : -1;
69     slice->disable_deblocking_filter_idc = h264->deblock_disable;
70     slice->slice_alpha_c0_offset_div2 = h264->deblock_offset_alpha;
71     slice->slice_beta_offset_div2 = h264->deblock_offset_beta;
72 
73     slice->idr_flag = is_idr;
74 
75     if (slice->idr_flag) {
76         slice->idr_pic_id = slice->next_idr_pic_id;
77         slice->next_idr_pic_id++;
78         if (slice->next_idr_pic_id >= 16)
79             slice->next_idr_pic_id = 0;
80     }
81 
82     slice->pic_order_cnt_lsb = frm->poc & ((1 << slice->log2_max_poc_lsb) - 1);
83     slice->num_ref_idx_active = 1;
84     slice->no_output_of_prior_pics = 0;
85     if (slice->idr_flag)
86         slice->long_term_reference_flag = frm->status.is_lt_ref;
87     else
88         slice->long_term_reference_flag = 0;
89 
90     return MPP_OK;
91 }
92 
h264e_reorder_init(H264eReorderInfo * reorder)93 MPP_RET h264e_reorder_init(H264eReorderInfo *reorder)
94 {
95     reorder->size = H264E_MAX_REFS_CNT;
96     reorder->rd_cnt = 0;
97     reorder->wr_cnt = 0;
98 
99     return MPP_OK;
100 }
101 
h264e_reorder_wr_rewind(H264eReorderInfo * info)102 MPP_RET h264e_reorder_wr_rewind(H264eReorderInfo *info)
103 {
104     info->wr_cnt = 0;
105     return MPP_OK;
106 }
107 
h264e_reorder_rd_rewind(H264eReorderInfo * info)108 MPP_RET h264e_reorder_rd_rewind(H264eReorderInfo *info)
109 {
110     info->rd_cnt = 0;
111     return MPP_OK;
112 }
113 
h264e_reorder_wr_op(H264eReorderInfo * info,H264eRplmo * op)114 MPP_RET h264e_reorder_wr_op(H264eReorderInfo *info, H264eRplmo *op)
115 {
116     if (info->wr_cnt >= info->size) {
117         mpp_err_f("write too many reorder op %d vs %d\n",
118                   info->wr_cnt, info->size);
119         return MPP_NOK;
120     }
121 
122     info->ops[info->wr_cnt++] = *op;
123     return MPP_OK;
124 }
125 
h264e_reorder_rd_op(H264eReorderInfo * info,H264eRplmo * op)126 MPP_RET h264e_reorder_rd_op(H264eReorderInfo *info, H264eRplmo *op)
127 {
128     if (info->rd_cnt >= info->wr_cnt)
129         return MPP_NOK;
130 
131     *op = info->ops[info->rd_cnt++];
132     return MPP_OK;
133 }
134 
h264e_marking_init(H264eMarkingInfo * marking)135 MPP_RET h264e_marking_init(H264eMarkingInfo *marking)
136 {
137     marking->idr_flag = 0;
138     marking->no_output_of_prior_pics = 0;
139     marking->long_term_reference_flag = 0;
140     marking->adaptive_ref_pic_buffering = 0;
141     marking->size = MAX_H264E_MMCO_CNT;
142     marking->wr_cnt = 0;
143     marking->rd_cnt = 0;
144 
145     return MPP_OK;
146 }
147 
h264e_marking_is_empty(H264eMarkingInfo * info)148 RK_S32 h264e_marking_is_empty(H264eMarkingInfo *info)
149 {
150     return info->rd_cnt >= info->wr_cnt;
151 }
152 
h264e_marking_wr_rewind(H264eMarkingInfo * marking)153 MPP_RET h264e_marking_wr_rewind(H264eMarkingInfo *marking)
154 {
155     marking->wr_cnt = 0;
156     return MPP_OK;
157 }
158 
h264e_marking_rd_rewind(H264eMarkingInfo * marking)159 MPP_RET h264e_marking_rd_rewind(H264eMarkingInfo *marking)
160 {
161     marking->rd_cnt = 0;
162     return MPP_OK;
163 }
164 
h264e_marking_wr_op(H264eMarkingInfo * info,H264eMmco * op)165 MPP_RET h264e_marking_wr_op(H264eMarkingInfo *info, H264eMmco *op)
166 {
167     if (info->wr_cnt >= info->size) {
168         mpp_err_f("write too many mmco op %d vs %d\n",
169                   info->wr_cnt, info->size);
170         return MPP_NOK;
171     }
172 
173     info->ops[info->wr_cnt++] = *op;
174     return MPP_OK;
175 }
176 
h264e_marking_rd_op(H264eMarkingInfo * info,H264eMmco * op)177 MPP_RET h264e_marking_rd_op(H264eMarkingInfo *info, H264eMmco *op)
178 {
179     if (h264e_marking_is_empty(info))
180         return MPP_NOK;
181 
182     *op = info->ops[info->rd_cnt++];
183     return MPP_OK;
184 }
185 
write_marking(MppWriteCtx * s,H264eMarkingInfo * marking)186 void write_marking(MppWriteCtx *s, H264eMarkingInfo *marking)
187 {
188     if (marking->idr_flag) {
189         /* no_output_of_prior_pics_flag */
190         mpp_writer_put_bits(s, marking->no_output_of_prior_pics, 1);
191         h264e_dbg_slice("used bit %2d no_output_of_prior_pics_flag %d\n",
192                         mpp_writer_bits(s), marking->no_output_of_prior_pics);
193 
194         /* long_term_reference_flag */
195         mpp_writer_put_bits(s, marking->long_term_reference_flag, 1);
196         h264e_dbg_slice("used bit %2d long_term_reference_flag %d\n",
197                         mpp_writer_bits(s), marking->long_term_reference_flag);
198     } else {
199         h264e_dbg_mmco("mmco count %d\n", marking->wr_cnt);
200 
201         h264e_marking_rd_rewind(marking);
202 
203         if (!h264e_marking_is_empty(marking)) {
204             H264eMmco mmco;
205 
206             /* adaptive_ref_pic_marking_mode_flag */
207             mpp_writer_put_bits(s, 1, 1);
208             h264e_dbg_slice("used bit %2d adaptive_ref_pic_marking_mode_flag 1\n",
209                             mpp_writer_bits(s));
210 
211             while (MPP_OK == h264e_marking_rd_op(marking, &mmco)) {
212                 /* memory_management_control_operation */
213                 mpp_writer_put_ue(s, mmco.mmco);
214                 h264e_dbg_slice("used bit %2d memory_management_control_operation %d\n",
215                                 mpp_writer_bits(s), mmco.mmco);
216 
217                 switch (mmco.mmco) {
218                 case 1 : {
219                     /* difference_of_pic_nums_minus1 */
220                     mpp_writer_put_ue(s, mmco.difference_of_pic_nums_minus1);
221                     h264e_dbg_slice("used bit %2d difference_of_pic_nums_minus1 %d\n",
222                                     mpp_writer_bits(s), mmco.difference_of_pic_nums_minus1);
223                 } break;
224                 case 2 : {
225                     /* long_term_pic_num */
226                     mpp_writer_put_ue(s, mmco.long_term_pic_num );
227                     h264e_dbg_slice("used bit %2d long_term_pic_num %d\n",
228                                     mpp_writer_bits(s), mmco.long_term_pic_num);
229                 } break;
230                 case 3 : {
231                     /* difference_of_pic_nums_minus1 */
232                     mpp_writer_put_ue(s, mmco.difference_of_pic_nums_minus1);
233                     h264e_dbg_slice("used bit %2d difference_of_pic_nums_minus1 %d\n",
234                                     mpp_writer_bits(s), mmco.difference_of_pic_nums_minus1);
235 
236                     /* long_term_frame_idx */
237                     mpp_writer_put_ue(s, mmco.long_term_frame_idx );
238                     h264e_dbg_slice("used bit %2d long_term_frame_idx %d\n",
239                                     mpp_writer_bits(s), mmco.long_term_frame_idx);
240                 } break;
241                 case 4 : {
242                     /* max_long_term_frame_idx_plus1 */
243                     mpp_writer_put_ue(s, mmco.max_long_term_frame_idx_plus1);
244                     h264e_dbg_slice("used bit %2d max_long_term_frame_idx_plus1 %d\n",
245                                     mpp_writer_bits(s), mmco.max_long_term_frame_idx_plus1);
246                 } break;
247                 case 5 : {
248                 } break;
249                 case 6 : {
250                     /* long_term_frame_idx */
251                     mpp_writer_put_ue(s, mmco.long_term_frame_idx);
252                     h264e_dbg_slice("used bit %2d long_term_frame_idx %d\n",
253                                     mpp_writer_bits(s), mmco.long_term_frame_idx);
254                 } break;
255                 default : {
256                     mpp_err_f("invalid mmco %d\n", mmco.mmco);
257                 } break;
258                 }
259             }
260 
261             /* memory_management_control_operation */
262             mpp_writer_put_ue(s, 0);
263             h264e_dbg_slice("used bit %2d memory_management_control_operation 0\n",
264                             mpp_writer_bits(s));
265         } else {
266             /* adaptive_ref_pic_marking_mode_flag */
267             mpp_writer_put_bits(s, 0, 1);
268             h264e_dbg_slice("used bit %2d adaptive_ref_pic_marking_mode_flag 0\n",
269                             mpp_writer_bits(s));
270         }
271     }
272 }
273 
274 /* vepu read slice */
h264e_slice_read(H264eSlice * slice,void * p,RK_S32 size)275 RK_S32 h264e_slice_read(H264eSlice *slice, void *p, RK_S32 size)
276 {
277     BitReadCtx_t bit;
278     RK_S32 ret = 0;
279     RK_S32 val = 0;
280     RK_S32 bit_cnt = 0;
281 
282     mpp_set_bitread_ctx(&bit, p, size);
283     /* enable remove 03 */
284     mpp_set_bitread_pseudo_code_type(&bit, PSEUDO_CODE_H264_H265);
285 
286     /* start_code */
287     ret |= mpp_read_longbits(&bit, 32, (RK_U32 *)&val);
288     h264e_dbg_slice("used bit %2d start_code %x\n",
289                     bit.used_bits, val);
290 
291     /* forbidden_zero_bit */
292     ret |= mpp_read_bits(&bit, 1, &val);
293     h264e_dbg_slice("used bit %2d forbidden_zero_bit %x\n",
294                     bit.used_bits, val);
295 
296     /* nal_ref_idc */
297     ret |= mpp_read_bits(&bit, 2, &slice->nal_reference_idc);
298     h264e_dbg_slice("used bit %2d nal_reference_idc %d\n",
299                     bit.used_bits, slice->nal_reference_idc);
300 
301     /* nal_unit_type */
302     ret |= mpp_read_bits(&bit, 5, &slice->nalu_type);
303     h264e_dbg_slice("used bit %2d nal_unit_type %d\n",
304                     bit.used_bits, slice->nalu_type);
305 
306     /* first_mb_nr */
307     ret = mpp_read_ue(&bit, &slice->first_mb_in_slice);
308     h264e_dbg_slice("used bit %2d first_mb_in_slice %d\n",
309                     bit.used_bits, slice->first_mb_in_slice);
310 
311     /* slice_type */
312     ret |= mpp_read_ue(&bit, &slice->slice_type);
313     h264e_dbg_slice("used bit %2d slice_type %d\n",
314                     bit.used_bits, slice->slice_type);
315 
316     /* pic_parameter_set_id */
317     ret |= mpp_read_ue(&bit, &slice->pic_parameter_set_id);
318     h264e_dbg_slice("used bit %2d pic_parameter_set_id %d\n",
319                     bit.used_bits, slice->pic_parameter_set_id);
320 
321     /* frame_num */
322     /* NOTE: vpu hardware fix 16 bit frame_num */
323     ret |= mpp_read_bits(&bit, slice->log2_max_frame_num, &slice->frame_num);
324     h264e_dbg_slice("used bit %2d frame_num %d\n",
325                     bit.used_bits, slice->frame_num);
326 
327     slice->idr_flag = (slice->nalu_type == 5);
328     if (slice->idr_flag) {
329         /* idr_pic_id */
330         ret |= mpp_read_ue(&bit, &slice->idr_pic_id);
331         h264e_dbg_slice("used bit %2d idr_pic_id %d\n",
332                         bit.used_bits, slice->idr_pic_id);
333     }
334 
335     /* pic_order_cnt_type */
336     if (slice->pic_order_cnt_type == 0) {
337         /* pic_order_cnt_lsb */
338         ret |= mpp_read_bits(&bit, slice->log2_max_poc_lsb,
339                              (RK_S32 *)&slice->pic_order_cnt_lsb);
340         h264e_dbg_slice("used bit %2d pic_order_cnt_lsb %d\n",
341                         bit.used_bits, slice->pic_order_cnt_lsb);
342     }
343 
344     // NOTE: Only P slice has num_ref_idx_override flag and ref_pic_list_modification flag
345     if (slice->slice_type == H264_P_SLICE) {
346         /* num_ref_idx_override */
347         ret |= mpp_read_bits(&bit, 1, &slice->num_ref_idx_override);
348         h264e_dbg_slice("used bit %2d num_ref_idx_override %d\n",
349                         bit.used_bits, slice->num_ref_idx_override);
350 
351         mpp_assert(slice->num_ref_idx_override == 0);
352 
353         // NOTE: vpu hardware is always zero
354         /* ref_pic_list_modification_flag */
355         ret |= mpp_read_bits(&bit, 1, &slice->ref_pic_list_modification_flag);
356         h264e_dbg_slice("used bit %2d ref_pic_list_modification_flag %d\n",
357                         bit.used_bits, slice->ref_pic_list_modification_flag);
358 
359         if (slice->ref_pic_list_modification_flag) {
360             RK_U32 modification_of_pic_nums_idc = 0;
361             H264eRplmo ops;
362 
363             h264e_reorder_wr_rewind(slice->reorder);
364 
365             do {
366                 /* modification_of_pic_nums_idc */
367                 ret |= mpp_read_ue(&bit, &modification_of_pic_nums_idc);
368                 ops.modification_of_pic_nums_idc = modification_of_pic_nums_idc;
369                 h264e_dbg_slice("used bit %2d modification_of_pic_nums_idc %d\n",
370                                 bit.used_bits, modification_of_pic_nums_idc);
371 
372                 switch (modification_of_pic_nums_idc) {
373                 case 0 :
374                 case 1 : {
375                     /* abs_diff_pic_num_minus1 */
376                     RK_U32 abs_diff_pic_num_minus1 = 0;
377 
378                     ret |= mpp_read_ue(&bit, &abs_diff_pic_num_minus1);
379                     ops.abs_diff_pic_num_minus1 = abs_diff_pic_num_minus1;
380                     h264e_dbg_slice("used bit %2d abs_diff_pic_num_minus1 %d\n",
381                                     bit.used_bits, abs_diff_pic_num_minus1);
382                 } break;
383                 case 2 : {
384                     /* long_term_pic_idx */
385                     RK_U32 long_term_pic_idx = 0;
386 
387                     ret |= mpp_read_ue(&bit, &long_term_pic_idx);
388                     ops.long_term_pic_idx = long_term_pic_idx;
389                     h264e_dbg_slice("used bit %2d long_term_pic_idx %d\n",
390                                     bit.used_bits, long_term_pic_idx);
391                 } break;
392                 case 3 : {
393                 } break;
394                 default : {
395                     mpp_err_f("invalid modification_of_pic_nums_idc %d\n",
396                               modification_of_pic_nums_idc);
397                 } break;
398                 }
399 
400                 h264e_reorder_wr_op(slice->reorder, &ops);
401                 memset(&ops, 0, sizeof(ops));
402             } while (modification_of_pic_nums_idc != 3);
403         }
404     }
405 
406     if (slice->nal_reference_idc) {
407         if (slice->idr_flag) {
408             /* no_output_of_prior_pics */
409             ret |= mpp_read_bits(&bit, 1, &slice->no_output_of_prior_pics);
410             slice->marking->no_output_of_prior_pics = slice->no_output_of_prior_pics;
411             h264e_dbg_slice("used bit %2d no_output_of_prior_pics %d\n",
412                             bit.used_bits, slice->no_output_of_prior_pics);
413 
414             /* long_term_reference_flag */
415             ret |= mpp_read_bits(&bit, 1, &slice->long_term_reference_flag);
416             slice->marking->long_term_reference_flag = slice->long_term_reference_flag;
417             h264e_dbg_slice("used bit %2d long_term_reference_flag %d\n",
418                             bit.used_bits, slice->long_term_reference_flag);
419         } else {
420             /* adaptive_ref_pic_buffering */
421             ret |= mpp_read_bits(&bit, 1, &slice->adaptive_ref_pic_buffering);
422             slice->marking->adaptive_ref_pic_buffering = slice->adaptive_ref_pic_buffering;
423             h264e_dbg_slice("used bit %2d adaptive_ref_pic_buffering %d\n",
424                             bit.used_bits, slice->adaptive_ref_pic_buffering);
425 
426             if (slice->adaptive_ref_pic_buffering) {
427                 RK_U32 mmco;
428                 H264eMmco opt;
429 
430                 h264e_marking_wr_rewind(slice->marking);
431 
432                 do {
433                     ret |= mpp_read_ue(&bit, &mmco);
434                     opt.mmco = mmco;
435                     h264e_dbg_slice("used bit %2d memory_management_control_operation %d\n",
436                                     bit.used_bits, mmco);
437 
438                     // avoidance of writing extra struct H264eMmco
439                     if (mmco == 0)
440                         break;
441 
442                     if (mmco == 1 || mmco == 3) {
443                         RK_U32 difference_of_pic_nums_minus1;
444 
445                         ret |= mpp_read_ue(&bit, &difference_of_pic_nums_minus1);
446                         opt.difference_of_pic_nums_minus1 = difference_of_pic_nums_minus1;
447                         h264e_dbg_slice("used bit %2d difference_of_pic_nums_minus1 %d\n",
448                                         bit.used_bits, difference_of_pic_nums_minus1);
449                     }
450 
451                     if (mmco == 2) {
452                         RK_U32 long_term_pic_num;
453 
454                         ret |= mpp_read_ue(&bit, &long_term_pic_num);
455                         opt.long_term_pic_num = long_term_pic_num;
456                         h264e_dbg_slice("used bit %2d long_term_pic_num %d\n",
457                                         bit.used_bits, long_term_pic_num);
458                     }
459 
460                     if (mmco == 3 || mmco == 6) {
461                         RK_U32 long_term_frame_idx;
462 
463                         ret |= mpp_read_ue(&bit, &long_term_frame_idx);
464                         opt.long_term_frame_idx = long_term_frame_idx;
465                         h264e_dbg_slice("used bit %2d long_term_frame_idx %d\n",
466                                         bit.used_bits, long_term_frame_idx);
467                     }
468 
469                     if (mmco == 4) {
470                         RK_U32 max_long_term_frame_idx_plus1;
471 
472                         ret |= mpp_read_ue(&bit, &max_long_term_frame_idx_plus1);
473                         opt.max_long_term_frame_idx_plus1 = max_long_term_frame_idx_plus1;
474                         h264e_dbg_slice("used bit %2d max_long_term_frame_idx_plus1 %d\n",
475                                         bit.used_bits, max_long_term_frame_idx_plus1);
476                     }
477 
478                     h264e_marking_wr_op(slice->marking, &opt);
479                     memset(&opt, 0, sizeof(opt));
480                 } while (mmco);
481             }
482         }
483     }
484 
485     if (slice->entropy_coding_mode && slice->slice_type != H264_I_SLICE) {
486         /* cabac_init_idc */
487         ret |= mpp_read_ue(&bit, &slice->cabac_init_idc);
488         h264e_dbg_slice("used bit %2d cabac_init_idc %d\n",
489                         bit.used_bits, slice->cabac_init_idc);
490     }
491 
492     /* qp_delta */
493     ret |= mpp_read_se(&bit, &slice->qp_delta);
494     h264e_dbg_slice("used bit %2d qp_delta %d\n",
495                     bit.used_bits, slice->qp_delta);
496 
497     /* disable_deblocking_filter_idc */
498     ret |= mpp_read_ue(&bit, &slice->disable_deblocking_filter_idc);
499     h264e_dbg_slice("used bit %2d disable_deblocking_filter_idc %d\n",
500                     bit.used_bits, slice->disable_deblocking_filter_idc);
501 
502     /* slice_alpha_c0_offset_div2 */
503     ret |= mpp_read_se(&bit, &slice->slice_alpha_c0_offset_div2);
504     h264e_dbg_slice("used bit %2d slice_alpha_c0_offset_div2 %d\n",
505                     bit.used_bits, slice->slice_alpha_c0_offset_div2);
506 
507     /* slice_beta_offset_div2 */
508     ret |= mpp_read_se(&bit, &slice->slice_beta_offset_div2);
509     h264e_dbg_slice("used bit %2d slice_beta_offset_div2 %d\n",
510                     bit.used_bits, slice->slice_beta_offset_div2);
511 
512     h264e_dbg_slice("used bit %2d non-aligned length\n", bit.used_bits);
513 
514     if (slice->entropy_coding_mode) {
515         if (bit.num_remaining_bits_in_curr_byte_) {
516             RK_U32 tmp = bit.num_remaining_bits_in_curr_byte_;
517 
518             /* cabac_aligned_bit */
519             ret |= mpp_read_bits(&bit, tmp, &val);
520             h264e_dbg_slice("used bit %2d cabac_aligned_bit %x\n",
521                             bit.used_bits, val);
522         }
523     }
524     bit_cnt = bit.used_bits;
525 
526     h264e_dbg_slice("used bit %2d total aligned length, read result %d\n", bit.used_bits, ret);
527 
528     if (h264e_debug & H264E_DBG_SLICE) {
529         RK_S32 pos = 0;
530         RK_S32 i;
531         char log[256];
532         RK_U8 *tmp = (RK_U8 *)p;
533 
534         pos = sprintf(log + pos, "hw stream: ");
535         for (i = 0; i < 16; i++) {
536             pos += sprintf(log + pos, "%02x ", tmp[i]);
537         }
538         pos += sprintf(log + pos, "\n");
539         h264e_dbg_slice(log);
540     }
541 
542     return bit_cnt;
543 }
544 
h264e_slice_write_header(H264eSlice * slice,MppWriteCtx * s)545 void h264e_slice_write_header(H264eSlice *slice, MppWriteCtx *s)
546 {
547     H264eMarkingInfo *marking = slice->marking;
548     H264eRplmo rplmo;
549     MPP_RET ret = MPP_OK;
550 
551     /* nal header */
552     /* start_code_prefix 00 00 00 01 */
553     mpp_writer_put_raw_bits(s, 0, 24);
554     mpp_writer_put_raw_bits(s, 1, 8);
555     h264e_dbg_slice("used bit %2d start_code_prefix\n",
556                     mpp_writer_bits(s));
557 
558     /* forbidden_zero_bit */
559     mpp_writer_put_raw_bits(s, 0, 1);
560     h264e_dbg_slice("used bit %2d forbidden_zero_bit\n",
561                     mpp_writer_bits(s));
562 
563     /* nal_reference_idc */
564     mpp_writer_put_raw_bits(s, slice->nal_reference_idc, 2);
565     h264e_dbg_slice("used bit %2d nal_reference_idc %d\n",
566                     mpp_writer_bits(s), slice->nal_reference_idc);
567     /* nalu_type */
568     mpp_writer_put_raw_bits(s, slice->nalu_type, 5);
569     h264e_dbg_slice("used bit %2d nalu_type %d\n",
570                     mpp_writer_bits(s), slice->nalu_type);
571 
572     /* slice header */
573     /* start_mb_nr */
574     mpp_writer_put_ue(s, slice->first_mb_in_slice);
575     h264e_dbg_slice("used bit %2d first_mb_in_slice %d\n",
576                     mpp_writer_bits(s), slice->first_mb_in_slice);
577 
578     /* slice_type */
579     mpp_writer_put_ue(s, slice->slice_type);
580     h264e_dbg_slice("used bit %2d slice_type %d\n",
581                     mpp_writer_bits(s), slice->slice_type);
582 
583     /* pic_parameter_set_id */
584     mpp_writer_put_ue(s, slice->pic_parameter_set_id);
585     h264e_dbg_slice("used bit %2d pic_parameter_set_id %d\n",
586                     mpp_writer_bits(s), slice->pic_parameter_set_id);
587 
588     /* frame_num */
589     mpp_writer_put_bits(s, slice->frame_num, slice->log2_max_frame_num);
590     h264e_dbg_slice("used bit %2d frame_num %d\n",
591                     mpp_writer_bits(s), slice->frame_num);
592 
593     if (slice->nalu_type == 5) {
594         /* idr_pic_id */
595         mpp_writer_put_ue(s, slice->idr_pic_id);
596         h264e_dbg_slice("used bit %2d idr_pic_id %d\n",
597                         mpp_writer_bits(s), slice->idr_pic_id);
598         marking->idr_flag = 1;
599     } else
600         marking->idr_flag = 0;
601 
602     // Force to use poc type 0 here
603     if (slice->pic_order_cnt_type == 0) {
604         RK_S32 pic_order_cnt_lsb = slice->pic_order_cnt_lsb;
605         RK_S32 max_poc_lsb = (1 << slice->log2_max_poc_lsb);
606 
607         if (pic_order_cnt_lsb >= max_poc_lsb)
608             pic_order_cnt_lsb &= (max_poc_lsb - 1);
609 
610         /* pic_order_cnt_lsb */
611         mpp_writer_put_bits(s, pic_order_cnt_lsb, slice->log2_max_poc_lsb);
612         h264e_dbg_slice("used bit %2d pic_order_cnt_lsb %d\n",
613                         mpp_writer_bits(s), pic_order_cnt_lsb);
614     } else {
615         mpp_assert(slice->pic_order_cnt_type == 2);
616     }
617 
618     /* num_ref_idx_override */
619     slice->ref_pic_list_modification_flag = 0;
620 
621     h264e_reorder_rd_rewind(slice->reorder);
622 
623     if (slice->slice_type == H264_P_SLICE) {
624         mpp_assert(slice->num_ref_idx_override == 0);
625 
626         mpp_writer_put_bits(s, slice->num_ref_idx_override, 1);
627         h264e_dbg_slice("used bit %2d num_ref_idx_override %d\n",
628                         mpp_writer_bits(s), slice->num_ref_idx_override);
629 
630 
631         /* read reorder and check */
632         ret = h264e_reorder_rd_op(slice->reorder, &rplmo);
633 
634         /* ref_pic_list_modification_flag */
635         slice->ref_pic_list_modification_flag = (ret == MPP_OK);
636         mpp_writer_put_bits(s, slice->ref_pic_list_modification_flag, 1);
637         h264e_dbg_slice("used bit %2d ref_pic_list_modification_flag %d\n",
638                         mpp_writer_bits(s), slice->ref_pic_list_modification_flag);
639 
640         if (slice->ref_pic_list_modification_flag) {
641             /* modification_of_pic_nums_idc */
642             mpp_writer_put_ue(s, rplmo.modification_of_pic_nums_idc);
643             h264e_dbg_slice("used bit %2d modification_of_pic_nums_idc %d\n",
644                             mpp_writer_bits(s),
645                             rplmo.modification_of_pic_nums_idc);
646 
647             switch (rplmo.modification_of_pic_nums_idc) {
648             case 0 :
649             case 1 : {
650                 /* abs_diff_pic_num_minus1 */
651                 mpp_writer_put_ue(s, rplmo.abs_diff_pic_num_minus1);
652                 h264e_dbg_slice("used bit %2d abs_diff_pic_num_minus1 %d\n",
653                                 mpp_writer_bits(s),
654                                 rplmo.abs_diff_pic_num_minus1);
655             } break;
656             case 2 : {
657                 /* long_term_pic_idx */
658                 mpp_writer_put_ue(s, rplmo.long_term_pic_idx);
659                 h264e_dbg_slice("used bit %2d long_term_pic_idx %d\n",
660                                 mpp_writer_bits(s),
661                                 rplmo.long_term_pic_idx);
662             } break;
663             default : {
664                 mpp_err_f("invalid modification_of_pic_nums_idc %d\n",
665                           rplmo.modification_of_pic_nums_idc);
666             } break;
667             }
668 
669             /* modification_of_pic_nums_idc */
670             mpp_writer_put_ue(s, 3);
671             h264e_dbg_slice("used bit %2d modification_of_pic_nums_idc 3\n",
672                             mpp_writer_bits(s));
673 
674         }
675     }
676 
677     // NOTE: ignore nal ref idc here
678     h264e_dbg_mmco("nal_reference_idc %d idr_flag %d\n",
679                    slice->nal_reference_idc, slice->idr_flag);
680 
681     if (slice->nal_reference_idc) {
682         /* In VEPU1/2, lt_ref_flag is fixed to 0, so it must be replaced by data in slice. */
683         if (slice->long_term_reference_flag != marking->long_term_reference_flag) {
684             marking->long_term_reference_flag = slice->long_term_reference_flag;
685             h264e_dbg_slice("warning: update lt_ref_flag from %d to %d\n",
686                             marking->long_term_reference_flag, slice->long_term_reference_flag);
687         }
688 
689         h264e_dbg_slice("get marking %p\n", marking);
690         write_marking(s, marking);
691     }
692 
693     if (slice->entropy_coding_mode && slice->slice_type != H264_I_SLICE) {
694         /* cabac_init_idc */
695         mpp_writer_put_ue(s, slice->cabac_init_idc);
696         h264e_dbg_slice("used bit %2d cabac_init_idc %d\n",
697                         mpp_writer_bits(s), slice->cabac_init_idc);
698     }
699 
700     /* qp_delta */
701     mpp_writer_put_se(s, slice->qp_delta);
702     h264e_dbg_slice("used bit %2d qp_delta %d\n",
703                     mpp_writer_bits(s), slice->qp_delta);
704 
705     /* disable_deblocking_filter_idc */
706     mpp_writer_put_ue(s, slice->disable_deblocking_filter_idc);
707     h264e_dbg_slice("used bit %2d disable_deblocking_filter_idc %d\n",
708                     mpp_writer_bits(s), slice->disable_deblocking_filter_idc);
709 
710     /* slice_alpha_c0_offset_div2 */
711     mpp_writer_put_se(s, slice->slice_alpha_c0_offset_div2);
712     h264e_dbg_slice("used bit %2d slice_alpha_c0_offset_div2 %d\n",
713                     mpp_writer_bits(s), slice->slice_alpha_c0_offset_div2);
714 
715     /* slice_beta_offset_div2 */
716     mpp_writer_put_se(s, slice->slice_beta_offset_div2);
717     h264e_dbg_slice("used bit %2d slice_beta_offset_div2 %d\n",
718                     mpp_writer_bits(s), slice->slice_beta_offset_div2);
719 
720     /* cabac_alignment_one_bit */
721     if (slice->entropy_coding_mode) {
722         mpp_writer_align_one(s);
723         h264e_dbg_slice("used bit %2d align_bit 1\n",
724                         mpp_writer_bits(s));
725     }
726 
727     mpp_writer_flush(s);
728 }
729 
h264e_slice_write(H264eSlice * slice,void * p,RK_U32 size)730 RK_S32 h264e_slice_write(H264eSlice *slice, void *p, RK_U32 size)
731 {
732     MppWriteCtx stream;
733     MppWriteCtx *s = &stream;
734     RK_S32 bitCnt = 0;
735 
736     mpp_writer_init(s, p, size);
737 
738     h264e_slice_write_header(slice, s);
739 
740     bitCnt = s->buffered_bits + s->byte_cnt * 8;
741 
742     // update on cabac mode
743     if (slice->entropy_coding_mode)
744         bitCnt = s->buffered_bits + s->byte_cnt * 8;
745 
746     if (h264e_debug & H264E_DBG_SLICE) {
747         RK_S32 i;
748         RK_U8 *tmp = p;
749         RK_S32 pos = 0;
750         char log[256];
751 
752         pos = sprintf(log + pos, "sw stream: ");
753         for (i = 0; i < 16; i ++) {
754             pos += sprintf(log + pos, "%02x ", tmp[i]);
755         }
756         pos += sprintf(log + pos, "\n");
757         h264e_dbg_slice(log);
758     }
759 
760     return bitCnt;
761 }
762 
763 /*
764  * For software force skip stream writing
765  * 3 contexts state for skip flag
766  * end_of_slice flag is equal to write bypass 1
767  */
768 typedef struct H264eCabac_t {
769     RK_S32      state;
770 
771     RK_S32      low;
772     RK_S32      range;
773     RK_S32      queue;
774     RK_S32      bytes_outstanding;
775 
776     MppWriteCtx *s;
777 } H264eCabac;
778 
779 static const RK_S8 skip_init_state[3][2] = {
780     //              skip_flag ctx 11
781     /* model 0 */   { 23, 33 },
782     /* model 1 */   { 22, 25 },
783     /* model 2 */   { 29, 16 },
784 };
785 
init_context(H264eCabac * ctx,RK_S32 qp,RK_S32 model,MppWriteCtx * s)786 static void init_context(H264eCabac *ctx, RK_S32 qp, RK_S32 model, MppWriteCtx *s)
787 {
788     const RK_S8 *init = &skip_init_state[model][0];
789     RK_S32 state = MPP_CLIP3(1, 126, ((init[0] * qp) >> 4) + init[1]);
790 
791     ctx->state = (MPP_MIN(state, 127 - state) << 1) | (state >> 6);
792 
793     ctx->low   = 0;
794     ctx->range = 0x01FE;
795     ctx->queue = -9;
796     ctx->bytes_outstanding = 0;
797     ctx->s     = s;
798 }
799 
h264e_cabac_putbyte(H264eCabac * ctx)800 static inline void h264e_cabac_putbyte(H264eCabac *ctx)
801 {
802     if (ctx->queue >= 0) {
803         RK_S32 out = ctx->low >> (ctx->queue + 10);
804 
805         ctx->low &= (0x400 << ctx->queue) - 1;
806         ctx->queue -= 8;
807 
808         if ((out & 0xff) == 0xff) {
809             ctx->bytes_outstanding++;
810         } else {
811             MppWriteCtx *s = ctx->s;
812             RK_S32 carry = out >> 8;
813             RK_S32 bytes_outstanding = ctx->bytes_outstanding;
814 
815             if (ctx->queue > 0)
816                 mpp_writer_put_bits(s, carry, ctx->queue & 0x7);
817 
818             while (bytes_outstanding > 0) {
819                 mpp_writer_put_bits(s, carry - 1, 8);
820                 bytes_outstanding--;
821             }
822 
823             mpp_writer_put_bits(s, out, MPP_MIN(8, 8 - ctx->queue));
824             ctx->bytes_outstanding = 0;
825         }
826     }
827 }
828 
h264e_cabac_renorm(H264eCabac * ctx)829 static inline void h264e_cabac_renorm(H264eCabac *ctx)
830 {
831     static const RK_U8 x264_cabac_renorm_shift[64] = {
832         6, 5, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2,
833         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
834         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
835         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
836     };
837 
838     RK_S32 shift = x264_cabac_renorm_shift[ctx->range >> 3];
839 
840     ctx->range <<= shift;
841     ctx->low   <<= shift;
842     ctx->queue  += shift;
843 
844     h264e_cabac_putbyte(ctx);
845 }
846 
h264e_cabac_write_skip_flag(H264eCabac * ctx)847 static void h264e_cabac_write_skip_flag(H264eCabac *ctx)
848 {
849     static const RK_U8 h264e_cabac_range_lps[64][4] = {
850         {  2,   2,   2,   2}, {  6,   7,   8,   9}, {  6,   7,   9,  10}, {  6,   8,   9,  11},
851         {  7,   8,  10,  11}, {  7,   9,  10,  12}, {  7,   9,  11,  12}, {  8,   9,  11,  13},
852         {  8,  10,  12,  14}, {  9,  11,  12,  14}, {  9,  11,  13,  15}, { 10,  12,  14,  16},
853         { 10,  12,  15,  17}, { 11,  13,  15,  18}, { 11,  14,  16,  19}, { 12,  14,  17,  20},
854         { 12,  15,  18,  21}, { 13,  16,  19,  22}, { 14,  17,  20,  23}, { 14,  18,  21,  24},
855         { 15,  19,  22,  25}, { 16,  20,  23,  27}, { 17,  21,  25,  28}, { 18,  22,  26,  30},
856         { 19,  23,  27,  31}, { 20,  24,  29,  33}, { 21,  26,  30,  35}, { 22,  27,  32,  37},
857         { 23,  28,  33,  39}, { 24,  30,  35,  41}, { 26,  31,  37,  43}, { 27,  33,  39,  45},
858         { 29,  35,  41,  48}, { 30,  37,  43,  50}, { 32,  39,  46,  53}, { 33,  41,  48,  56},
859         { 35,  43,  51,  59}, { 37,  45,  54,  62}, { 39,  48,  56,  65}, { 41,  50,  59,  69},
860         { 43,  53,  63,  72}, { 46,  56,  66,  76}, { 48,  59,  69,  80}, { 51,  62,  73,  85},
861         { 53,  65,  77,  89}, { 56,  69,  81,  94}, { 59,  72,  86,  99}, { 62,  76,  90, 104},
862         { 66,  80,  95, 110}, { 69,  85, 100, 116}, { 73,  89, 105, 122}, { 77,  94, 111, 128},
863         { 81,  99, 117, 135}, { 85, 104, 123, 142}, { 90, 110, 130, 150}, { 95, 116, 137, 158},
864         {100, 122, 144, 166}, {105, 128, 152, 175}, {111, 135, 160, 185}, {116, 142, 169, 195},
865         {123, 150, 178, 205}, {128, 158, 187, 216}, {128, 167, 197, 227}, {128, 176, 208, 240}
866     };
867 
868     static const RK_U8 h264e_cabac_transition[128][2] = {
869         {  0,   0}, {  1,   1}, {  2,  50}, { 51,   3}, {  2,  50}, { 51,   3}, {  4,  52}, { 53,   5},
870         {  6,  52}, { 53,   7}, {  8,  52}, { 53,   9}, { 10,  54}, { 55,  11}, { 12,  54}, { 55,  13},
871         { 14,  54}, { 55,  15}, { 16,  56}, { 57,  17}, { 18,  56}, { 57,  19}, { 20,  56}, { 57,  21},
872         { 22,  58}, { 59,  23}, { 24,  58}, { 59,  25}, { 26,  60}, { 61,  27}, { 28,  60}, { 61,  29},
873         { 30,  60}, { 61,  31}, { 32,  62}, { 63,  33}, { 34,  62}, { 63,  35}, { 36,  64}, { 65,  37},
874         { 38,  66}, { 67,  39}, { 40,  66}, { 67,  41}, { 42,  66}, { 67,  43}, { 44,  68}, { 69,  45},
875         { 46,  68}, { 69,  47}, { 48,  70}, { 71,  49}, { 50,  72}, { 73,  51}, { 52,  72}, { 73,  53},
876         { 54,  74}, { 75,  55}, { 56,  74}, { 75,  57}, { 58,  76}, { 77,  59}, { 60,  78}, { 79,  61},
877         { 62,  78}, { 79,  63}, { 64,  80}, { 81,  65}, { 66,  82}, { 83,  67}, { 68,  82}, { 83,  69},
878         { 70,  84}, { 85,  71}, { 72,  84}, { 85,  73}, { 74,  88}, { 89,  75}, { 76,  88}, { 89,  77},
879         { 78,  90}, { 91,  79}, { 80,  90}, { 91,  81}, { 82,  94}, { 95,  83}, { 84,  94}, { 95,  85},
880         { 86,  96}, { 97,  87}, { 88,  96}, { 97,  89}, { 90, 100}, {101,  91}, { 92, 100}, {101,  93},
881         { 94, 102}, {103,  95}, { 96, 104}, {105,  97}, { 98, 104}, {105,  99}, {100, 108}, {109, 101},
882         {102, 108}, {109, 103}, {104, 110}, {111, 105}, {106, 112}, {113, 107}, {108, 114}, {115, 109},
883         {110, 116}, {117, 111}, {112, 118}, {119, 113}, {114, 118}, {119, 115}, {116, 122}, {123, 117},
884         {118, 122}, {123, 119}, {120, 124}, {125, 121}, {122, 126}, {127, 123}, {124, 127}, {126, 125}
885     };
886 
887     RK_S32 skip = 1;
888     RK_S32 state = ctx->state;
889     RK_S32 range_lps = h264e_cabac_range_lps[state >> 1][(ctx->range >> 6) - 4];
890 
891     ctx->range -= range_lps;
892     if (skip != (state & 1) ) {
893         ctx->low += ctx->range;
894         ctx->range = range_lps;
895     }
896 
897     ctx->state = h264e_cabac_transition[state][skip];
898 
899     h264e_cabac_renorm(ctx);
900 }
901 
h264e_cabac_terminal(H264eCabac * ctx)902 static void h264e_cabac_terminal(H264eCabac *ctx)
903 {
904     ctx->range -= 2;
905     h264e_cabac_renorm(ctx);
906 }
907 
h264e_cabac_flush(H264eCabac * ctx)908 static void h264e_cabac_flush(H264eCabac *ctx)
909 {
910     /* end_of_slice_flag = 1 */
911     ctx->low += ctx->range - 2;
912     ctx->low |= 1;
913     ctx->low <<= 9;
914     ctx->queue += 9;
915 
916     h264e_cabac_putbyte( ctx );
917     h264e_cabac_putbyte( ctx );
918 
919     ctx->low <<= -ctx->queue;
920     ctx->low |= 1 << 10;
921     ctx->queue = 0;
922 
923     h264e_cabac_putbyte( ctx );
924 
925     while (ctx->bytes_outstanding > 0) {
926         mpp_writer_put_bits(ctx->s, 0xff, 8);
927         ctx->bytes_outstanding--;
928     }
929 }
930 
h264e_slice_write_pskip(H264eSlice * slice,void * p,RK_U32 size)931 RK_S32 h264e_slice_write_pskip(H264eSlice *slice, void *p, RK_U32 size)
932 {
933     MppWriteCtx stream;
934     MppWriteCtx *s = &stream;
935     RK_S32 bitCnt = 0;
936 
937     mpp_writer_init(s, p, size);
938 
939     h264e_slice_write_header(slice, s);
940     if (slice->entropy_coding_mode) {
941         /* cabac */
942         H264eCabac ctx;
943         RK_S32 i;
944 
945         init_context(&ctx, slice->qp_init, slice->cabac_init_idc, s);
946 
947         for (i = 0; i < slice->mb_w * slice->mb_h; i++) {
948             /* end_of_slice_flag = 0 */
949             if (i)
950                 h264e_cabac_terminal(&ctx);
951 
952             /* skip flag */
953             h264e_cabac_write_skip_flag(&ctx);
954         }
955 
956         /* end_of_slice_flag = 1 and flush */
957         h264e_cabac_flush(&ctx);
958     } else {
959         /* cavlc */
960         /* mb skip run */
961         mpp_writer_put_ue(s, slice->mb_w * slice->mb_h);
962         h264e_dbg_slice("used bit %d mb_skip_run %d\n",
963                         mpp_writer_bits(s), slice->mb_w * slice->mb_h);
964 
965         /* rbsp_stop_one_bit */
966         mpp_writer_trailing(s);
967         h264e_dbg_slice("used bit %d tailing %d\n", mpp_writer_bits(s));
968     }
969     mpp_writer_flush(s);
970 
971     bitCnt = s->buffered_bits + s->byte_cnt * 8;
972     return bitCnt;
973 }
974 
h264e_slice_move(RK_U8 * dst,RK_U8 * src,RK_S32 dst_bit,RK_S32 src_bit,RK_S32 src_size)975 RK_S32 h264e_slice_move(RK_U8 *dst, RK_U8 *src, RK_S32 dst_bit, RK_S32 src_bit, RK_S32 src_size)
976 {
977     RK_S32 dst_byte = dst_bit / 8;
978     RK_S32 src_byte = src_bit / 8;
979     RK_S32 dst_bit_r = dst_bit & 7;
980     RK_S32 src_bit_r = src_bit & 7;
981     RK_S32 src_len = src_size - src_byte;
982     RK_S32 diff_len = 0;
983     static RK_S32 frame_no = 0;
984 
985     if (src_bit_r == 0 && dst_bit_r == 0) {
986         // direct copy
987         if (h264e_debug & H264E_DBG_SLICE)
988             mpp_log_f("direct copy %p -> %p %d\n", src, dst, src_len);
989 
990         h264e_dbg_slice("bit [%d %d] [%d %d] [%d %d] len %d\n",
991                         src_bit, dst_bit, src_byte, dst_byte,
992                         src_bit_r, dst_bit_r, src_len);
993 
994         memcpy(dst + dst_byte, src + src_byte, src_len);
995         return diff_len;
996     }
997 
998     RK_U8 *psrc = src + src_byte;
999     RK_U8 *pdst = dst + dst_byte;
1000 
1001     RK_U16 tmp16a, tmp16b, tmp16c, last_tmp, dst_mask;
1002     RK_U8 tmp0, tmp1;
1003     RK_U32 loop = src_len + (src_bit_r > 0);
1004     RK_U32 i = 0;
1005     RK_U32 src_zero_cnt = 0;
1006     RK_U32 dst_zero_cnt = 0;
1007     RK_U32 dst_len = 0;
1008 
1009     last_tmp = (RK_U16)pdst[0];
1010     dst_mask = 0xFFFF << (8 - dst_bit_r);
1011 
1012     h264e_dbg_slice("bit [%d %d] [%d %d] [%d %d] loop %d mask %04x last %04x\n",
1013                     src_bit, dst_bit, src_byte, dst_byte,
1014                     src_bit_r, dst_bit_r, loop, dst_mask, last_tmp);
1015 
1016     for (i = 0; i < loop; i++) {
1017         if (psrc[0] == 0) {
1018             src_zero_cnt++;
1019         } else {
1020             src_zero_cnt = 0;
1021         }
1022 
1023         // tmp0 tmp1 is next two non-aligned bytes from src
1024         tmp0 = psrc[0];
1025         tmp1 = (i < loop - 1) ? psrc[1] : 0;
1026 
1027         if (src_zero_cnt >= 2 && tmp1 == 3) {
1028             if (h264e_debug & H264E_DBG_SLICE)
1029                 mpp_log("found 03 at src pos %d %02x %02x %02x %02x %02x %02x %02x %02x\n",
1030                         i, psrc[-2], psrc[-1], psrc[0], psrc[1], psrc[2],
1031                         psrc[3], psrc[4], psrc[5]);
1032 
1033             psrc++;
1034             i++;
1035             tmp1 = psrc[1];
1036             src_zero_cnt = 0;
1037             diff_len--;
1038         }
1039         // get U16 data
1040         tmp16a = ((RK_U16)tmp0 << 8) | (RK_U16)tmp1;
1041 
1042         if (src_bit_r) {
1043             tmp16b = tmp16a << src_bit_r;
1044         } else {
1045             tmp16b = tmp16a;
1046         }
1047 
1048         if (dst_bit_r)
1049             tmp16c = tmp16b >> dst_bit_r | ((last_tmp << 8) & dst_mask);
1050         else
1051             tmp16c = tmp16b;
1052 
1053         pdst[0] = (tmp16c >> 8) & 0xFF;
1054         pdst[1] = tmp16c & 0xFF;
1055 
1056         if (h264e_debug & H264E_DBG_SLICE) {
1057             if (i < 10) {
1058                 mpp_log("%03d src [%04x] -> [%04x] + last [%04x] -> %04x\n", i, tmp16a, tmp16b, last_tmp, tmp16c);
1059             }
1060             if (i >= loop - 10) {
1061                 mpp_log("%03d src [%04x] -> [%04x] + last [%04x] -> %04x\n", i, tmp16a, tmp16b, last_tmp, tmp16c);
1062             }
1063         }
1064 
1065         if (dst_zero_cnt == 2 && pdst[0] <= 0x3) {
1066             if (h264e_debug & H264E_DBG_SLICE)
1067                 mpp_log("found 03 at dst frame %d pos %d\n", frame_no, dst_len);
1068 
1069             pdst[2] = pdst[1];
1070             pdst[1] = pdst[0];
1071             pdst[0] = 0x3;
1072             pdst++;
1073             diff_len++;
1074             dst_len++;
1075             dst_zero_cnt = 0;
1076         }
1077 
1078         if (pdst[0] == 0)
1079             dst_zero_cnt++;
1080         else
1081             dst_zero_cnt = 0;
1082 
1083         last_tmp = tmp16c;
1084 
1085         psrc++;
1086         pdst++;
1087         dst_len++;
1088     }
1089 
1090     frame_no++;
1091 
1092     return diff_len;
1093 }
1094 
h264e_slice_write_prefix_nal_unit_svc(H264ePrefixNal * prefix,void * p,RK_S32 size)1095 RK_S32 h264e_slice_write_prefix_nal_unit_svc(H264ePrefixNal *prefix, void *p, RK_S32 size)
1096 {
1097     MppWriteCtx stream;
1098     MppWriteCtx *s = &stream;
1099     RK_S32 bitCnt = 0;
1100 
1101     mpp_writer_init(s, p, size);
1102 
1103     /* nal header */
1104     /* start_code_prefix 00 00 00 01 */
1105     mpp_writer_put_raw_bits(s, 0, 24);
1106     mpp_writer_put_raw_bits(s, 1, 8);
1107 
1108     /* forbidden_zero_bit */
1109     mpp_writer_put_raw_bits(s, 0, 1);
1110 
1111     /* nal_reference_idc */
1112     mpp_writer_put_raw_bits(s, prefix->nal_ref_idc, 2);
1113 
1114     /* nalu_type */
1115     mpp_writer_put_raw_bits(s, 14, 5);
1116 
1117     /* svc_extension_flag */
1118     mpp_writer_put_raw_bits(s, 1, 1);
1119 
1120     /* nal_unit_header_svc_extension */
1121     /* idr_flag */
1122     mpp_writer_put_raw_bits(s, prefix->idr_flag, 1);
1123 
1124     /* priority_id */
1125     mpp_writer_put_raw_bits(s, prefix->priority_id , 6);
1126 
1127     /* no_inter_layer_pred_flag */
1128     mpp_writer_put_raw_bits(s, prefix->no_inter_layer_pred_flag , 1);
1129 
1130     /* dependency_id */
1131     mpp_writer_put_raw_bits(s, prefix->dependency_id, 3);
1132 
1133     /* quality_id */
1134     mpp_writer_put_raw_bits(s, prefix->quality_id, 4);
1135 
1136     /* temporal_id */
1137     mpp_writer_put_raw_bits(s, prefix->temporal_id, 3);
1138 
1139     /* use_ref_base_pic_flag */
1140     mpp_writer_put_raw_bits(s, prefix->use_ref_base_pic_flag, 1);
1141 
1142     /* discardable_flag */
1143     mpp_writer_put_raw_bits(s, prefix->discardable_flag, 1);
1144 
1145     /* output_flag */
1146     mpp_writer_put_raw_bits(s, prefix->output_flag, 1);
1147 
1148     /* reserved_three_2bits */
1149     mpp_writer_put_raw_bits(s, 3, 2);
1150 
1151     /* prefix_nal_unit_svc */
1152     if (prefix->nal_ref_idc) {
1153         /* store_ref_base_pic_flag */
1154         mpp_writer_put_raw_bits(s, 0, 1);
1155 
1156         /* additional_prefix_nal_unit_extension_flag */
1157         mpp_writer_put_raw_bits(s, 0, 1);
1158 
1159         /* rbsp_trailing_bits */
1160         mpp_writer_trailing(s);
1161     }
1162 
1163     mpp_writer_flush(s);
1164 
1165     bitCnt = s->buffered_bits + s->byte_cnt * 8;
1166 
1167     return bitCnt;
1168 }
1169