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