• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright (C) 2015 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 
21 /**
22 *******************************************************************************
23 * @file
24 *  ih264e_process.c
25 *
26 * @brief
27 *  Contains functions for codec thread
28 *
29 * @author
30 *  Harish
31 *
32 * @par List of Functions:
33 * - ih264e_generate_sps_pps()
34 * - ih264e_init_entropy_ctxt()
35 * - ih264e_entropy()
36 * - ih264e_pack_header_data()
37 * - ih264e_update_proc_ctxt()
38 * - ih264e_init_proc_ctxt()
39 * - ih264e_pad_recon_buffer()
40 * - ih264e_dblk_pad_hpel_processing_n_mbs()
41 * - ih264e_process()
42 * - ih264e_set_rc_pic_params()
43 * - ih264e_update_rc_post_enc()
44 * - ih264e_process_thread()
45 *
46 * @remarks
47 *  None
48 *
49 *******************************************************************************
50 */
51 
52 /*****************************************************************************/
53 /* File Includes                                                             */
54 /*****************************************************************************/
55 
56 /* System include files */
57 #include <stdio.h>
58 #include <stddef.h>
59 #include <stdlib.h>
60 #include <string.h>
61 #include <limits.h>
62 #include <assert.h>
63 
64 /* User include files */
65 #include "ih264_typedefs.h"
66 #include "iv2.h"
67 #include "ive2.h"
68 #include "ih264_defs.h"
69 #include "ih264_debug.h"
70 #include "ime_distortion_metrics.h"
71 #include "ime_defs.h"
72 #include "ime_structs.h"
73 #include "ih264_error.h"
74 #include "ih264_structs.h"
75 #include "ih264_trans_quant_itrans_iquant.h"
76 #include "ih264_inter_pred_filters.h"
77 #include "ih264_mem_fns.h"
78 #include "ih264_padding.h"
79 #include "ih264_intra_pred_filters.h"
80 #include "ih264_deblk_edge_filters.h"
81 #include "ih264_cabac_tables.h"
82 #include "ih264_platform_macros.h"
83 #include "ih264_macros.h"
84 #include "ih264_buf_mgr.h"
85 #include "ih264e_error.h"
86 #include "ih264e_bitstream.h"
87 #include "ih264_common_tables.h"
88 #include "ih264_list.h"
89 #include "ih264e_defs.h"
90 #include "irc_cntrl_param.h"
91 #include "irc_frame_info_collector.h"
92 #include "ih264e_rate_control.h"
93 #include "ih264e_cabac_structs.h"
94 #include "ih264e_structs.h"
95 #include "ih264e_cabac.h"
96 #include "ih264e_process.h"
97 #include "ithread.h"
98 #include "ih264e_intra_modes_eval.h"
99 #include "ih264e_encode_header.h"
100 #include "ih264e_globals.h"
101 #include "ih264e_config.h"
102 #include "ih264e_trace.h"
103 #include "ih264e_statistics.h"
104 #include "ih264_cavlc_tables.h"
105 #include "ih264e_cavlc.h"
106 #include "ih264e_deblk.h"
107 #include "ih264e_me.h"
108 #include "ih264e_debug.h"
109 #include "ih264e_master.h"
110 #include "ih264e_utils.h"
111 #include "irc_mem_req_and_acq.h"
112 #include "irc_rate_control_api.h"
113 #include "ih264e_platform_macros.h"
114 #include "ime_statistics.h"
115 
116 
117 /*****************************************************************************/
118 /* Function Definitions                                                      */
119 /*****************************************************************************/
120 
121 /**
122 ******************************************************************************
123 *
124 *  @brief This function generates sps, pps set on request
125 *
126 *  @par   Description
127 *  When the encoder is set in header generation mode, the following function
128 *  is called. This generates sps and pps headers and returns the control back
129 *  to caller.
130 *
131 *  @param[in]    ps_codec
132 *  pointer to codec context
133 *
134 *  @return      success or failure error code
135 *
136 ******************************************************************************
137 */
ih264e_generate_sps_pps(codec_t * ps_codec)138 IH264E_ERROR_T ih264e_generate_sps_pps(codec_t *ps_codec)
139 {
140     /* choose between ping-pong process buffer set */
141     WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
142 
143     /* entropy ctxt */
144     entropy_ctxt_t *ps_entropy = &ps_codec->as_process[ctxt_sel * MAX_PROCESS_THREADS].s_entropy;
145 
146     /* Bitstream structure */
147     bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm;
148 
149     /* sps */
150     sps_t *ps_sps = NULL;
151 
152     /* pps */
153     pps_t *ps_pps = NULL;
154 
155     /* output buff */
156     out_buf_t *ps_out_buf = &ps_codec->as_out_buf[ctxt_sel];
157 
158 
159     /********************************************************************/
160     /*      initialize the bit stream buffer                            */
161     /********************************************************************/
162     ih264e_bitstrm_init(ps_bitstrm, ps_out_buf->s_bits_buf.pv_buf, ps_out_buf->s_bits_buf.u4_bufsize);
163 
164     /********************************************************************/
165     /*                    BEGIN HEADER GENERATION                       */
166     /********************************************************************/
167     /*ps_codec->i4_pps_id ++;*/
168     ps_codec->i4_pps_id %= MAX_PPS_CNT;
169 
170     /*ps_codec->i4_sps_id ++;*/
171     ps_codec->i4_sps_id %= MAX_SPS_CNT;
172 
173     /* populate sps header */
174     ps_sps = ps_codec->ps_sps_base + ps_codec->i4_sps_id;
175     ih264e_populate_sps(ps_codec, ps_sps);
176 
177     /* populate pps header */
178     ps_pps = ps_codec->ps_pps_base + ps_codec->i4_pps_id;
179     ih264e_populate_pps(ps_codec, ps_pps);
180 
181     ps_entropy->i4_error_code = IH264E_SUCCESS;
182 
183     /* generate sps */
184     ps_entropy->i4_error_code = ih264e_generate_sps(ps_bitstrm, ps_sps,
185                                                      &ps_codec->s_cfg.s_vui);
186     if(ps_entropy->i4_error_code != IH264E_SUCCESS)
187     {
188         return ps_entropy->i4_error_code;
189     }
190     /* generate pps */
191     ps_entropy->i4_error_code = ih264e_generate_pps(ps_bitstrm, ps_pps, ps_sps);
192 
193     /* queue output buffer */
194     ps_out_buf->s_bits_buf.u4_bytes = ps_bitstrm->u4_strm_buf_offset;
195 
196     return ps_entropy->i4_error_code;
197 }
198 
199 /**
200 *******************************************************************************
201 *
202 * @brief   initialize entropy context.
203 *
204 * @par Description:
205 *  Before invoking the call to perform to entropy coding the entropy context
206 *  associated with the job needs to be initialized. This involves the start
207 *  mb address, end mb address, slice index and the pointer to location at
208 *  which the mb residue info and mb header info are packed.
209 *
210 * @param[in] ps_proc
211 *  Pointer to the current process context
212 *
213 * @returns error status
214 *
215 * @remarks none
216 *
217 *******************************************************************************
218 */
ih264e_init_entropy_ctxt(process_ctxt_t * ps_proc)219 IH264E_ERROR_T ih264e_init_entropy_ctxt(process_ctxt_t *ps_proc)
220 {
221     /* codec context */
222     codec_t *ps_codec = ps_proc->ps_codec;
223 
224     /* entropy ctxt */
225     entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
226 
227     /* start address */
228     ps_entropy->i4_mb_start_add = ps_entropy->i4_mb_y * ps_entropy->i4_wd_mbs + ps_entropy->i4_mb_x;
229 
230     /* end address */
231     ps_entropy->i4_mb_end_add = ps_entropy->i4_mb_start_add + ps_entropy->i4_mb_cnt;
232 
233     /* slice index */
234     ps_entropy->i4_cur_slice_idx = ps_proc->pu1_slice_idx[ps_entropy->i4_mb_start_add];
235 
236     /* sof */
237     /* @ start of frame or start of a new slice, set sof flag */
238     if (ps_entropy->i4_mb_start_add == 0)
239     {
240         ps_entropy->i4_sof = 1;
241     }
242 
243     if (ps_entropy->i4_mb_x == 0)
244     {
245         /* packed mb coeff data */
246         ps_entropy->pv_mb_coeff_data = ((UWORD8 *)ps_entropy->pv_pic_mb_coeff_data) +
247                         ps_entropy->i4_mb_y * ps_codec->u4_size_coeff_data;
248 
249         /* packed mb header data */
250         ps_entropy->pv_mb_header_data = ((UWORD8 *)ps_entropy->pv_pic_mb_header_data) +
251                         ps_entropy->i4_mb_y * ps_codec->u4_size_header_data;
252     }
253 
254     return IH264E_SUCCESS;
255 }
256 
257 /**
258 *******************************************************************************
259 *
260 * @brief entry point for entropy coding
261 *
262 * @par Description
263 *  This function calls lower level functions to perform entropy coding for a
264 *  group (n rows) of mb's. After encoding 1 row of mb's,  the function takes
265 *  back the control, updates the ctxt and calls lower level functions again.
266 *  This process is repeated till all the rows or group of mb's (which ever is
267 *  minimum) are coded
268 *
269 * @param[in] ps_proc
270 *  process context
271 *
272 * @returns  error status
273 *
274 * @remarks
275 *
276 *******************************************************************************
277 */
278 
ih264e_entropy(process_ctxt_t * ps_proc)279 IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc)
280 {
281     /* codec context */
282     codec_t *ps_codec = ps_proc->ps_codec;
283 
284     /* entropy context */
285     entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
286 
287     /* cabac context */
288     cabac_ctxt_t *ps_cabac_ctxt = ps_entropy->ps_cabac;
289 
290     /* sps */
291     sps_t *ps_sps = ps_entropy->ps_sps_base + (ps_entropy->u4_sps_id % MAX_SPS_CNT);
292 
293     /* pps */
294     pps_t *ps_pps = ps_entropy->ps_pps_base + (ps_entropy->u4_pps_id % MAX_PPS_CNT);
295 
296     /* slice header */
297     slice_header_t *ps_slice_hdr = ps_entropy->ps_slice_hdr_base + (ps_entropy->i4_cur_slice_idx % MAX_SLICE_HDR_CNT);
298 
299     /* slice type */
300     WORD32 i4_slice_type = ps_proc->i4_slice_type;
301 
302     /* Bitstream structure */
303     bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm;
304 
305     /* output buff */
306     out_buf_t s_out_buf;
307 
308     /* sei params */
309     sei_params_t s_sei;
310 
311     /* proc map */
312     UWORD8  *pu1_proc_map;
313 
314     /* entropy map */
315     UWORD8  *pu1_entropy_map_curr;
316 
317     /* proc base idx */
318     WORD32 ctxt_sel = ps_proc->i4_encode_api_call_cnt % MAX_CTXT_SETS;
319 
320     /* temp var */
321     WORD32 i4_wd_mbs, i4_ht_mbs;
322     UWORD32 u4_mb_cnt, u4_mb_idx, u4_mb_end_idx, u4_insert_per_idr;
323     WORD32 bitstream_start_offset, bitstream_end_offset;
324     /********************************************************************/
325     /*                            BEGIN INIT                            */
326     /********************************************************************/
327 
328     /* entropy encode start address */
329     u4_mb_idx = ps_entropy->i4_mb_start_add;
330 
331     /* entropy encode end address */
332     u4_mb_end_idx = ps_entropy->i4_mb_end_add;
333 
334     /* width in mbs */
335     i4_wd_mbs = ps_entropy->i4_wd_mbs;
336 
337     /* height in mbs */
338     i4_ht_mbs = ps_entropy->i4_ht_mbs;
339 
340     /* total mb cnt */
341     u4_mb_cnt = i4_wd_mbs * i4_ht_mbs;
342 
343     /* proc map */
344     pu1_proc_map = ps_proc->pu1_proc_map + ps_entropy->i4_mb_y * i4_wd_mbs;
345 
346     /* entropy map */
347     pu1_entropy_map_curr = ps_entropy->pu1_entropy_map + ps_entropy->i4_mb_y * i4_wd_mbs;
348 
349     /********************************************************************/
350     /* @ start of frame / slice,                                        */
351     /*      initialize the output buffer,                               */
352     /*      initialize the bit stream buffer,                           */
353     /*      check if sps and pps headers have to be generated,          */
354     /*      populate and generate slice header                          */
355     /********************************************************************/
356     if (ps_entropy->i4_sof)
357     {
358         /********************************************************************/
359         /*      initialize the output buffer                                */
360         /********************************************************************/
361         s_out_buf = ps_codec->as_out_buf[ctxt_sel];
362 
363         /* is last frame to encode */
364         s_out_buf.u4_is_last = ps_entropy->u4_is_last;
365 
366         /* frame idx */
367         s_out_buf.u4_timestamp_high = ps_entropy->u4_timestamp_high;
368         s_out_buf.u4_timestamp_low = ps_entropy->u4_timestamp_low;
369 
370         /********************************************************************/
371         /*      initialize the bit stream buffer                            */
372         /********************************************************************/
373         ih264e_bitstrm_init(ps_bitstrm, s_out_buf.s_bits_buf.pv_buf, s_out_buf.s_bits_buf.u4_bufsize);
374 
375         /********************************************************************/
376         /*                    BEGIN HEADER GENERATION                       */
377         /********************************************************************/
378         if (1 == ps_entropy->i4_gen_header)
379         {
380             /* generate sps */
381             ps_entropy->i4_error_code = ih264e_generate_sps(ps_bitstrm, ps_sps,
382                                                              &ps_codec->s_cfg.s_vui);
383             RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
384             /* generate pps */
385             ps_entropy->i4_error_code = ih264e_generate_pps(ps_bitstrm, ps_pps, ps_sps);
386             RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
387 
388             /* reset i4_gen_header */
389             ps_entropy->i4_gen_header = 0;
390         }
391 
392         /* populate slice header */
393         ih264e_populate_slice_header(ps_proc, ps_slice_hdr, ps_pps, ps_sps);
394 
395         /* generate sei */
396         u4_insert_per_idr = (NAL_SLICE_IDR == ps_slice_hdr->i1_nal_unit_type);
397 
398         memset(&s_sei, 0, sizeof(sei_params_t));
399         s_sei.u1_sei_mdcv_params_present_flag =
400                     ps_codec->s_cfg.s_sei.u1_sei_mdcv_params_present_flag;
401         s_sei.s_sei_mdcv_params = ps_codec->s_cfg.s_sei.s_sei_mdcv_params;
402         s_sei.u1_sei_cll_params_present_flag =
403                     ps_codec->s_cfg.s_sei.u1_sei_cll_params_present_flag;
404         s_sei.s_sei_cll_params = ps_codec->s_cfg.s_sei.s_sei_cll_params;
405         s_sei.u1_sei_ave_params_present_flag =
406                     ps_codec->s_cfg.s_sei.u1_sei_ave_params_present_flag;
407         s_sei.s_sei_ave_params = ps_codec->s_cfg.s_sei.s_sei_ave_params;
408         s_sei.u1_sei_ccv_params_present_flag = 0;
409         s_sei.s_sei_ccv_params =
410                     ps_codec->as_inp_list[ps_codec->i4_poc % MAX_NUM_BFRAMES].s_sei_ccv;
411 
412         if((1 == ps_sps->i1_vui_parameters_present_flag) &&
413            (1 == ps_codec->s_cfg.s_vui.u1_video_signal_type_present_flag) &&
414            (1 == ps_codec->s_cfg.s_vui.u1_colour_description_present_flag) &&
415            (2 != ps_codec->s_cfg.s_vui.u1_colour_primaries) &&
416            (2 != ps_codec->s_cfg.s_vui.u1_matrix_coefficients) &&
417            (2 != ps_codec->s_cfg.s_vui.u1_transfer_characteristics) &&
418            (4 != ps_codec->s_cfg.s_vui.u1_transfer_characteristics) &&
419            (5 != ps_codec->s_cfg.s_vui.u1_transfer_characteristics))
420         {
421             s_sei.u1_sei_ccv_params_present_flag =
422             ps_codec->as_inp_list[ps_codec->i4_poc % MAX_NUM_BFRAMES].u1_sei_ccv_params_present_flag;
423         }
424 
425         if((1 == s_sei.u1_sei_mdcv_params_present_flag && u4_insert_per_idr) ||
426            (1 == s_sei.u1_sei_cll_params_present_flag && u4_insert_per_idr) ||
427            (1 == s_sei.u1_sei_ave_params_present_flag && u4_insert_per_idr) ||
428            (1 == s_sei.u1_sei_ccv_params_present_flag))
429         {
430             ps_entropy->i4_error_code =
431                     ih264e_generate_sei(ps_bitstrm, &s_sei, u4_insert_per_idr);
432             RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
433         }
434         ps_codec->as_inp_list[ps_codec->i4_poc % MAX_NUM_BFRAMES].u1_sei_ccv_params_present_flag = 0;
435 
436         /* generate slice header */
437         ps_entropy->i4_error_code = ih264e_generate_slice_header(ps_bitstrm, ps_slice_hdr,
438                                                                   ps_pps, ps_sps);
439         RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
440         /* once start of frame / slice is done, you can reset it */
441         /* it is the responsibility of the caller to set this flag */
442         ps_entropy->i4_sof = 0;
443 
444         if (CABAC == ps_entropy->u1_entropy_coding_mode_flag)
445         {
446             BITSTREAM_BYTE_ALIGN(ps_bitstrm);
447             BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code);
448             ih264e_init_cabac_ctxt(ps_entropy);
449         }
450     }
451 
452     /* begin entropy coding for the mb set */
453     while (u4_mb_idx < u4_mb_end_idx)
454     {
455         /* init ptrs/indices */
456         if (ps_entropy->i4_mb_x == i4_wd_mbs)
457         {
458             ps_entropy->i4_mb_y++;
459             ps_entropy->i4_mb_x = 0;
460 
461             /* packed mb coeff data */
462             ps_entropy->pv_mb_coeff_data = ((UWORD8 *)ps_entropy->pv_pic_mb_coeff_data) +
463                             ps_entropy->i4_mb_y * ps_codec->u4_size_coeff_data;
464 
465             /* packed mb header data */
466             ps_entropy->pv_mb_header_data = ((UWORD8 *)ps_entropy->pv_pic_mb_header_data) +
467                             ps_entropy->i4_mb_y * ps_codec->u4_size_header_data;
468 
469             /* proc map */
470             pu1_proc_map = ps_proc->pu1_proc_map + ps_entropy->i4_mb_y * i4_wd_mbs;
471 
472             /* entropy map */
473             pu1_entropy_map_curr = ps_entropy->pu1_entropy_map + ps_entropy->i4_mb_y * i4_wd_mbs;
474         }
475 
476         DEBUG("\nmb indices x, y %d, %d", ps_entropy->i4_mb_x, ps_entropy->i4_mb_y);
477         ENTROPY_TRACE("mb index x %d", ps_entropy->i4_mb_x);
478         ENTROPY_TRACE("mb index y %d", ps_entropy->i4_mb_y);
479 
480         /* wait until the curr mb is core coded */
481         /* The wait for curr mb to be core coded is essential when entropy is launched
482          * as a separate job
483          */
484         while (1)
485         {
486             volatile UWORD8 *pu1_buf1;
487             WORD32 idx = ps_entropy->i4_mb_x;
488 
489             pu1_buf1 = pu1_proc_map + idx;
490             if (*pu1_buf1)
491                 break;
492             ithread_yield();
493         }
494 
495 
496         /* write mb layer */
497         ps_entropy->i4_error_code = ps_codec->pf_write_mb_syntax_layer
498                         [ps_entropy->u1_entropy_coding_mode_flag][i4_slice_type](ps_entropy);
499         RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
500 
501         /* Starting bitstream offset for header in bits */
502         bitstream_start_offset = GET_NUM_BITS(ps_bitstrm);
503 
504         /* set entropy map */
505         pu1_entropy_map_curr[ps_entropy->i4_mb_x] = 1;
506 
507         u4_mb_idx++;
508         ps_entropy->i4_mb_x++;
509         /* check for eof */
510         if (CABAC == ps_entropy->u1_entropy_coding_mode_flag)
511         {
512             if (ps_entropy->i4_mb_x < i4_wd_mbs)
513             {
514                 ih264e_cabac_encode_terminate(ps_cabac_ctxt, 0);
515             }
516         }
517 
518         if (ps_entropy->i4_mb_x == i4_wd_mbs)
519         {
520             /* if slices are enabled */
521             if (ps_codec->s_cfg.e_slice_mode == IVE_SLICE_MODE_BLOCKS)
522             {
523                 /* current slice index */
524                 WORD32 i4_curr_slice_idx = ps_entropy->i4_cur_slice_idx;
525 
526                 /* slice map */
527                 UWORD8 *pu1_slice_idx = ps_entropy->pu1_slice_idx;
528 
529                 /* No need to open a slice at end of frame. The current slice can be closed at the time
530                  * of signaling eof flag.
531                  */
532                 if ((u4_mb_idx != u4_mb_cnt) && (i4_curr_slice_idx
533                                                 != pu1_slice_idx[u4_mb_idx]))
534                 {
535                     if (CAVLC == ps_entropy->u1_entropy_coding_mode_flag)
536                     { /* mb skip run */
537                         if ((i4_slice_type != ISLICE)
538                                         && *ps_entropy->pi4_mb_skip_run)
539                         {
540                             if (*ps_entropy->pi4_mb_skip_run)
541                             {
542                                 PUT_BITS_UEV(ps_bitstrm, *ps_entropy->pi4_mb_skip_run,
543                                             ps_entropy->i4_error_code, "mb skip run");
544                                 *ps_entropy->pi4_mb_skip_run = 0;
545                                 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
546                             }
547                         }
548                         /* put rbsp trailing bits for the previous slice */
549                         ps_entropy->i4_error_code = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
550                         RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
551                     }
552                     else
553                     {
554                         ih264e_cabac_encode_terminate(ps_cabac_ctxt, 1);
555                     }
556 
557                     /* update slice header pointer */
558                     i4_curr_slice_idx = pu1_slice_idx[u4_mb_idx];
559                     ps_entropy->i4_cur_slice_idx = i4_curr_slice_idx;
560                     ps_slice_hdr = ps_entropy->ps_slice_hdr_base+ (i4_curr_slice_idx % MAX_SLICE_HDR_CNT);
561 
562                     /* populate slice header */
563                     ps_entropy->i4_mb_start_add = u4_mb_idx;
564                     ih264e_populate_slice_header(ps_proc, ps_slice_hdr, ps_pps,
565                                                  ps_sps);
566 
567                     /* generate slice header */
568                     ps_entropy->i4_error_code = ih264e_generate_slice_header(
569                                     ps_bitstrm, ps_slice_hdr, ps_pps, ps_sps);
570                     RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
571                     if (CABAC == ps_entropy->u1_entropy_coding_mode_flag)
572                     {
573                         BITSTREAM_BYTE_ALIGN(ps_bitstrm);
574                         BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code);
575                         ih264e_init_cabac_ctxt(ps_entropy);
576                     }
577                 }
578                 else
579                 {
580                     if (CABAC == ps_entropy->u1_entropy_coding_mode_flag
581                                     && u4_mb_idx != u4_mb_cnt)
582                     {
583                         ih264e_cabac_encode_terminate(ps_cabac_ctxt, 0);
584                     }
585                 }
586             }
587         }
588 
589         /* Ending bitstream offset for header in bits */
590         bitstream_end_offset = GET_NUM_BITS(ps_bitstrm);
591         ps_entropy->u4_header_bits[i4_slice_type == PSLICE] +=
592                         bitstream_end_offset - bitstream_start_offset;
593     }
594 
595     /* check for eof */
596     if (u4_mb_idx == u4_mb_cnt)
597     {
598         /* set end of frame flag */
599         ps_entropy->i4_eof = 1;
600     }
601     else
602     {
603         if (CABAC == ps_entropy->u1_entropy_coding_mode_flag
604                         && ps_codec->s_cfg.e_slice_mode
605                                         != IVE_SLICE_MODE_BLOCKS)
606         {
607             ih264e_cabac_encode_terminate(ps_cabac_ctxt, 0);
608         }
609     }
610 
611     if (ps_entropy->i4_eof)
612     {
613         if (CAVLC == ps_entropy->u1_entropy_coding_mode_flag)
614         {
615             /* mb skip run */
616             if ((i4_slice_type != ISLICE) && *ps_entropy->pi4_mb_skip_run)
617             {
618                 if (*ps_entropy->pi4_mb_skip_run)
619                 {
620                     PUT_BITS_UEV(ps_bitstrm, *ps_entropy->pi4_mb_skip_run,
621                                  ps_entropy->i4_error_code, "mb skip run");
622                     *ps_entropy->pi4_mb_skip_run = 0;
623                     RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
624                 }
625             }
626             /* put rbsp trailing bits */
627              ps_entropy->i4_error_code = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
628              RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
629         }
630         else
631         {
632             ih264e_cabac_encode_terminate(ps_cabac_ctxt, 1);
633         }
634 
635         /* update current frame stats to rc library */
636         {
637             /* number of bytes to stuff */
638             WORD32 i4_stuff_bytes;
639 
640             /* update */
641             i4_stuff_bytes = ih264e_update_rc_post_enc(
642                             ps_codec, ctxt_sel,
643                             (ps_proc->ps_codec->i4_poc == 0));
644 
645             /* cbr rc - house keeping */
646             if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel])
647             {
648                  ps_entropy->ps_bitstrm->u4_strm_buf_offset = 0;
649             }
650             else if (i4_stuff_bytes)
651             {
652                 /* add filler nal units */
653                  ps_entropy->i4_error_code = ih264e_add_filler_nal_unit(ps_bitstrm, i4_stuff_bytes);
654                  RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
655             }
656         }
657 
658         /*
659          *Frame number is to be incremented only if the current frame is a
660          * reference frame. After each successful frame encode, we increment
661          * frame number by 1
662          */
663         if (!ps_codec->s_rate_control.post_encode_skip[ctxt_sel]
664                         && ps_codec->u4_is_curr_frm_ref)
665         {
666             ps_codec->i4_frame_num++;
667         }
668         /********************************************************************/
669         /*      signal the output                                           */
670         /********************************************************************/
671         ps_codec->as_out_buf[ctxt_sel].s_bits_buf.u4_bytes =
672                         ps_entropy->ps_bitstrm->u4_strm_buf_offset;
673 
674         DEBUG("entropy status %x", ps_entropy->i4_error_code);
675     }
676 
677     /* Dont execute any further instructions until store synchronization took place */
678     DATA_SYNC();
679 
680     /* allow threads to dequeue entropy jobs */
681     ps_codec->au4_entropy_thread_active[ctxt_sel] = 0;
682 
683     return ps_entropy->i4_error_code;
684 }
685 
686 /**
687 *******************************************************************************
688 *
689 * @brief Packs header information of a mb in to a buffer
690 *
691 * @par Description:
692 *  After the deciding the mode info of a macroblock, the syntax elements
693 *  associated with the mb are packed and stored. The entropy thread unpacks
694 *  this buffer and generates the end bit stream.
695 *
696 * @param[in] ps_proc
697 *  Pointer to the current process context
698 *
699 * @returns error status
700 *
701 * @remarks none
702 *
703 *******************************************************************************
704 */
ih264e_pack_header_data(process_ctxt_t * ps_proc)705 IH264E_ERROR_T ih264e_pack_header_data(process_ctxt_t *ps_proc)
706 {
707     /* curr mb type */
708     UWORD32 u4_mb_type = ps_proc->u4_mb_type;
709 
710     /* pack mb syntax layer of curr mb (used for entropy coding) */
711     if (u4_mb_type == I4x4)
712     {
713         /* pointer to mb header storage space */
714         UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
715         mb_hdr_i4x4_t *ps_mb_hdr = (mb_hdr_i4x4_t *)ps_proc->pv_mb_header_data;
716 
717         /* temp var */
718         WORD32 i4, byte;
719 
720         /* mb type plus mode */
721         ps_mb_hdr->common.u1_mb_type_mode = (ps_proc->u1_c_i8_mode << 6) + u4_mb_type;
722 
723         /* cbp */
724         ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
725 
726         /* mb qp delta */
727         ps_mb_hdr->common.u1_mb_qp_delta = ps_proc->u4_mb_qp - ps_proc->u4_mb_qp_prev;
728 
729         /* sub mb modes */
730         for (i4 = 0; i4 < 16; i4 ++)
731         {
732             byte = 0;
733 
734             if (ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4] ==
735                             ps_proc->au1_intra_luma_mb_4x4_modes[i4])
736             {
737                 byte |= 1;
738             }
739             else
740             {
741 
742                 if (ps_proc->au1_intra_luma_mb_4x4_modes[i4] <
743                                 ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4])
744                 {
745                     byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] << 1);
746                 }
747                 else
748                 {
749                     byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] - 1) << 1;
750                 }
751             }
752 
753             i4++;
754 
755             if (ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4] ==
756                             ps_proc->au1_intra_luma_mb_4x4_modes[i4])
757             {
758                 byte |= 16;
759             }
760             else
761             {
762 
763                 if (ps_proc->au1_intra_luma_mb_4x4_modes[i4] <
764                                 ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4])
765                 {
766                     byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] << 5);
767                 }
768                 else
769                 {
770                     byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] - 1) << 5;
771                 }
772             }
773 
774             ps_mb_hdr->au1_sub_blk_modes[i4 >> 1] =  byte;
775         }
776 
777         /* end of mb layer */
778         pu1_ptr += sizeof(mb_hdr_i4x4_t);
779         ps_proc->pv_mb_header_data = pu1_ptr;
780     }
781     else if (u4_mb_type == I16x16)
782     {
783         /* pointer to mb header storage space */
784         UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
785         mb_hdr_i16x16_t *ps_mb_hdr = (mb_hdr_i16x16_t *)ps_proc->pv_mb_header_data;
786 
787         /* mb type plus mode */
788         ps_mb_hdr->common.u1_mb_type_mode = (ps_proc->u1_c_i8_mode << 6) + (ps_proc->u1_l_i16_mode << 4) + u4_mb_type;
789 
790         /* cbp */
791         ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
792 
793         /* mb qp delta */
794         ps_mb_hdr->common.u1_mb_qp_delta = ps_proc->u4_mb_qp - ps_proc->u4_mb_qp_prev;
795 
796         /* end of mb layer */
797         pu1_ptr += sizeof(mb_hdr_i16x16_t);
798         ps_proc->pv_mb_header_data = pu1_ptr;
799     }
800     else if (u4_mb_type == P16x16)
801     {
802         /* pointer to mb header storage space */
803         UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
804         mb_hdr_p16x16_t *ps_mb_hdr = (mb_hdr_p16x16_t *)ps_proc->pv_mb_header_data;
805 
806         /* mb type */
807         ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
808 
809         /* cbp */
810         ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
811 
812         /* mb qp delta */
813         ps_mb_hdr->common.u1_mb_qp_delta = ps_proc->u4_mb_qp - ps_proc->u4_mb_qp_prev;
814 
815         ps_mb_hdr->ai2_mv[0] = ps_proc->ps_pu->s_me_info[0].s_mv.i2_mvx - ps_proc->ps_pred_mv[0].s_mv.i2_mvx;
816 
817         ps_mb_hdr->ai2_mv[1] = ps_proc->ps_pu->s_me_info[0].s_mv.i2_mvy - ps_proc->ps_pred_mv[0].s_mv.i2_mvy;
818 
819         /* end of mb layer */
820         pu1_ptr += sizeof(mb_hdr_p16x16_t);
821         ps_proc->pv_mb_header_data = pu1_ptr;
822     }
823     else if (u4_mb_type == PSKIP)
824     {
825         /* pointer to mb header storage space */
826         UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
827         mb_hdr_pskip_t *ps_mb_hdr = (mb_hdr_pskip_t *)ps_proc->pv_mb_header_data;
828 
829         /* mb type */
830         ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
831 
832         /* end of mb layer */
833         pu1_ptr += sizeof(mb_hdr_pskip_t);
834         ps_proc->pv_mb_header_data = pu1_ptr;
835     }
836     else if(u4_mb_type == B16x16)
837     {
838 
839         /* pointer to mb header storage space */
840         UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
841         mb_hdr_b16x16_t *ps_mb_hdr = (mb_hdr_b16x16_t *)ps_proc->pv_mb_header_data;
842 
843         UWORD32 u4_pred_mode = ps_proc->ps_pu->b2_pred_mode;
844 
845         /* mb type plus mode */
846         ps_mb_hdr->common.u1_mb_type_mode = (u4_pred_mode << 4) + u4_mb_type;
847 
848         /* cbp */
849         ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
850 
851         /* mb qp delta */
852         ps_mb_hdr->common.u1_mb_qp_delta = ps_proc->u4_mb_qp - ps_proc->u4_mb_qp_prev;
853 
854         /* l0 & l1 me data */
855         if (u4_pred_mode != PRED_L1)
856         {
857             ps_mb_hdr->ai2_mv[0][0] = ps_proc->ps_pu->s_me_info[0].s_mv.i2_mvx
858                             - ps_proc->ps_pred_mv[0].s_mv.i2_mvx;
859 
860             ps_mb_hdr->ai2_mv[0][1] = ps_proc->ps_pu->s_me_info[0].s_mv.i2_mvy
861                             - ps_proc->ps_pred_mv[0].s_mv.i2_mvy;
862         }
863         if (u4_pred_mode != PRED_L0)
864         {
865             ps_mb_hdr->ai2_mv[1][0] = ps_proc->ps_pu->s_me_info[1].s_mv.i2_mvx
866                             - ps_proc->ps_pred_mv[1].s_mv.i2_mvx;
867 
868             ps_mb_hdr->ai2_mv[1][1] = ps_proc->ps_pu->s_me_info[1].s_mv.i2_mvy
869                             - ps_proc->ps_pred_mv[1].s_mv.i2_mvy;
870         }
871 
872         /* end of mb layer */
873         pu1_ptr += sizeof(mb_hdr_b16x16_t);
874         ps_proc->pv_mb_header_data = pu1_ptr;
875 
876     }
877     else if(u4_mb_type == BDIRECT)
878     {
879         /* pointer to mb header storage space */
880         UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
881         mb_hdr_bdirect_t *ps_mb_hdr = (mb_hdr_bdirect_t *)ps_proc->pv_mb_header_data;
882 
883         /* mb type plus mode */
884         ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
885 
886         /* cbp */
887         ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
888 
889         /* mb qp delta */
890         ps_mb_hdr->common.u1_mb_qp_delta = ps_proc->u4_mb_qp - ps_proc->u4_mb_qp_prev;
891 
892         /* end of mb layer */
893         pu1_ptr += sizeof(mb_hdr_bdirect_t);
894         ps_proc->pv_mb_header_data = pu1_ptr;
895 
896     }
897     else if(u4_mb_type == BSKIP)
898     {
899         UWORD32 u4_pred_mode = ps_proc->ps_pu->b2_pred_mode;
900 
901         /* pointer to mb header storage space */
902         UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
903         mb_hdr_bskip_t *ps_mb_hdr = (mb_hdr_bskip_t *)ps_proc->pv_mb_header_data;
904 
905         /* mb type plus mode */
906         ps_mb_hdr->common.u1_mb_type_mode = (u4_pred_mode << 4) + u4_mb_type;
907 
908         /* end of mb layer */
909         pu1_ptr += sizeof(mb_hdr_bskip_t);
910         ps_proc->pv_mb_header_data = pu1_ptr;
911     }
912 
913     return IH264E_SUCCESS;
914 }
915 
916 /**
917 *******************************************************************************
918 *
919 * @brief   update process context after encoding an mb. This involves preserving
920 * the current mb information for later use, initialize the proc ctxt elements to
921 * encode next mb.
922 *
923 * @par Description:
924 *  This function performs house keeping tasks after encoding an mb.
925 *  After encoding an mb, various elements of the process context needs to be
926 *  updated to encode the next mb. For instance, the source, recon and reference
927 *  pointers, mb indices have to be adjusted to the next mb. The slice index of
928 *  the current mb needs to be updated. If mb qp modulation is enabled, then if
929 *  the qp changes the quant param structure needs to be updated. Also to encoding
930 *  the next mb, the current mb info is used as part of mode prediction or mv
931 *  prediction. Hence the current mb info has to preserved at top/top left/left
932 *  locations.
933 *
934 * @param[in] ps_proc
935 *  Pointer to the current process context
936 *
937 * @returns none
938 *
939 * @remarks none
940 *
941 *******************************************************************************
942 */
ih264e_update_proc_ctxt(process_ctxt_t * ps_proc)943 WORD32 ih264e_update_proc_ctxt(process_ctxt_t *ps_proc)
944 {
945     /* error status */
946     WORD32 error_status = IH264_SUCCESS;
947 
948     /* codec context */
949     codec_t *ps_codec = ps_proc->ps_codec;
950 
951     /* curr mb indices */
952     WORD32 i4_mb_x = ps_proc->i4_mb_x;
953     WORD32 i4_mb_y = ps_proc->i4_mb_y;
954 
955     /* mb syntax elements of neighbors */
956     mb_info_t *ps_left_syn =  &ps_proc->s_left_mb_syntax_ele;
957     mb_info_t *ps_top_syn = ps_proc->ps_top_row_mb_syntax_ele + i4_mb_x;
958     mb_info_t *ps_top_left_syn = &ps_proc->s_top_left_mb_syntax_ele;
959 
960     /* curr mb type */
961     UWORD32 u4_mb_type = ps_proc->u4_mb_type;
962 
963     /* curr mb type */
964     UWORD32 u4_is_intra = ps_proc->u4_is_intra;
965 
966     /* width in mbs */
967     WORD32 i4_wd_mbs = ps_proc->i4_wd_mbs;
968 
969     /*height in mbs*/
970     WORD32 i4_ht_mbs = ps_proc->i4_ht_mbs;
971 
972     /* proc map */
973     UWORD8 *pu1_proc_map = ps_proc->pu1_proc_map + (i4_mb_y * i4_wd_mbs);
974 
975     /* deblk context */
976     deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
977 
978     /* deblk bs context */
979     bs_ctxt_t *ps_bs = &(ps_deblk->s_bs_ctxt);
980 
981     /* top row motion vector info */
982     enc_pu_t *ps_top_row_pu = ps_proc->ps_top_row_pu + i4_mb_x;
983 
984     /* top left mb motion vector */
985     enc_pu_t *ps_top_left_mb_pu = &ps_proc->s_top_left_mb_pu;
986 
987     /* left mb motion vector */
988     enc_pu_t *ps_left_mb_pu = &ps_proc->s_left_mb_pu;
989 
990     /* sub mb modes */
991     UWORD8 *pu1_top_mb_intra_modes = ps_proc->pu1_top_mb_intra_modes + (i4_mb_x << 4);
992 
993     /*************************************************************/
994     /* During MV prediction, when top right mb is not available, */
995     /* top left mb info. is used for prediction. Hence the curr  */
996     /* top, which will be top left for the next mb needs to be   */
997     /* preserved before updating it with curr mb info.           */
998     /*************************************************************/
999 
1000     /* mb type, mb class, csbp */
1001     *ps_top_left_syn = *ps_top_syn;
1002 
1003     if (ps_proc->i4_slice_type != ISLICE)
1004     {
1005         /*****************************************/
1006         /* update top left with top info results */
1007         /*****************************************/
1008         /* mv */
1009         *ps_top_left_mb_pu = *ps_top_row_pu;
1010     }
1011 
1012     /*************************************************/
1013     /* update top and left with curr mb info results */
1014     /*************************************************/
1015 
1016     /* mb type */
1017     ps_left_syn->u2_mb_type = ps_top_syn->u2_mb_type = u4_mb_type;
1018 
1019     /* mb class */
1020     ps_left_syn->u2_is_intra = ps_top_syn->u2_is_intra = u4_is_intra;
1021 
1022     /* csbp */
1023     ps_left_syn->u4_csbp = ps_top_syn->u4_csbp = ps_proc->u4_csbp;
1024 
1025     /* distortion */
1026     ps_left_syn->i4_mb_distortion = ps_top_syn->i4_mb_distortion = ps_proc->i4_mb_distortion;
1027 
1028     if (u4_is_intra)
1029     {
1030         /* mb / sub mb modes */
1031         if (I16x16 == u4_mb_type)
1032         {
1033             pu1_top_mb_intra_modes[0] = ps_proc->au1_left_mb_intra_modes[0] = ps_proc->u1_l_i16_mode;
1034         }
1035         else if (I4x4 == u4_mb_type)
1036         {
1037             ps_codec->pf_mem_cpy_mul8(ps_proc->au1_left_mb_intra_modes, ps_proc->au1_intra_luma_mb_4x4_modes, 16);
1038             ps_codec->pf_mem_cpy_mul8(pu1_top_mb_intra_modes, ps_proc->au1_intra_luma_mb_4x4_modes, 16);
1039         }
1040         else if (I8x8 == u4_mb_type)
1041         {
1042             memcpy(ps_proc->au1_left_mb_intra_modes, ps_proc->au1_intra_luma_mb_8x8_modes, 4);
1043             memcpy(pu1_top_mb_intra_modes, ps_proc->au1_intra_luma_mb_8x8_modes, 4);
1044         }
1045 
1046         if ((ps_proc->i4_slice_type == PSLICE) ||(ps_proc->i4_slice_type == BSLICE))
1047         {
1048             /* mv */
1049             *ps_left_mb_pu = *ps_top_row_pu = *(ps_proc->ps_pu);
1050         }
1051 
1052         *ps_proc->pu4_mb_pu_cnt = 1;
1053     }
1054     else
1055     {
1056         /* mv */
1057         *ps_left_mb_pu = *ps_top_row_pu = *(ps_proc->ps_pu);
1058     }
1059 
1060     /*
1061      * Mark that the MB has been coded intra
1062      * So that future AIRs can skip it
1063      */
1064     ps_proc->pu1_is_intra_coded[i4_mb_x + (i4_mb_y * i4_wd_mbs)] = u4_is_intra;
1065 
1066     /**************************************************/
1067     /* pack mb header info. for entropy coding        */
1068     /**************************************************/
1069     ih264e_pack_header_data(ps_proc);
1070 
1071     /* update previous mb qp */
1072     ps_proc->u4_mb_qp_prev = ps_proc->u4_mb_qp;
1073 
1074     /* store qp */
1075     ps_proc->s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp[(i4_mb_y * i4_wd_mbs) + i4_mb_x] = ps_proc->u4_mb_qp;
1076 
1077     /*
1078      * We need to sync the cache to make sure that the nmv content of proc
1079      * is updated to cache properly
1080      */
1081     DATA_SYNC();
1082 
1083     /* Just before finishing the row, enqueue the job in to entropy queue.
1084      * The master thread depending on its convenience shall dequeue it and
1085      * performs entropy.
1086      *
1087      * WARN !! Placing this block post proc map update can cause queuing of
1088      * entropy jobs in out of order.
1089      */
1090     if (i4_mb_x == i4_wd_mbs - 1)
1091     {
1092         /* job structures */
1093         job_t s_job;
1094 
1095         /* job class */
1096         s_job.i4_cmd = CMD_ENTROPY;
1097 
1098         /* number of mbs to be processed in the current job */
1099         s_job.i2_mb_cnt = ps_codec->s_cfg.i4_wd_mbs;
1100 
1101         /* job start index x */
1102         s_job.i2_mb_x = 0;
1103 
1104         /* job start index y */
1105         s_job.i2_mb_y = ps_proc->i4_mb_y;
1106 
1107         /* proc base idx */
1108         s_job.i2_proc_base_idx = (ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS) ? (MAX_PROCESS_CTXT / 2) : 0;
1109 
1110         /* queue the job */
1111         error_status = ih264_list_queue(ps_proc->pv_entropy_jobq, &s_job, 1);
1112         if(error_status != IH264_SUCCESS)
1113         {
1114             return error_status;
1115         }
1116         if(ps_proc->i4_mb_y == (i4_ht_mbs - 1))
1117             ih264_list_terminate(ps_codec->pv_entropy_jobq);
1118     }
1119 
1120     /* update proc map */
1121     pu1_proc_map[i4_mb_x] = 1;
1122 
1123     /**************************************************/
1124     /* update proc ctxt elements for encoding next mb */
1125     /**************************************************/
1126     /* update indices */
1127     i4_mb_x ++;
1128     ps_proc->i4_mb_x = i4_mb_x;
1129 
1130     if (ps_proc->i4_mb_x == i4_wd_mbs)
1131     {
1132         ps_proc->i4_mb_y++;
1133         ps_proc->i4_mb_x = 0;
1134     }
1135 
1136     /* update slice index */
1137     ps_proc->i4_cur_slice_idx = ps_proc->pu1_slice_idx[ps_proc->i4_mb_y * i4_wd_mbs + ps_proc->i4_mb_x];
1138 
1139     /* update buffers pointers */
1140     ps_proc->pu1_src_buf_luma += MB_SIZE;
1141     ps_proc->pu1_rec_buf_luma += MB_SIZE;
1142     ps_proc->apu1_ref_buf_luma[0] += MB_SIZE;
1143     ps_proc->apu1_ref_buf_luma[1] += MB_SIZE;
1144 
1145     /*
1146      * Note: Although chroma mb size is 8, as the chroma buffers are interleaved,
1147      * the stride per MB is MB_SIZE
1148      */
1149     ps_proc->pu1_src_buf_chroma += MB_SIZE;
1150     ps_proc->pu1_rec_buf_chroma += MB_SIZE;
1151     ps_proc->apu1_ref_buf_chroma[0] += MB_SIZE;
1152     ps_proc->apu1_ref_buf_chroma[1] += MB_SIZE;
1153 
1154 
1155 
1156     /* Reset cost, distortion params */
1157     ps_proc->i4_mb_cost = INT_MAX;
1158     ps_proc->i4_mb_distortion = SHRT_MAX;
1159 
1160     ps_proc->ps_pu += *ps_proc->pu4_mb_pu_cnt;
1161 
1162     ps_proc->pu4_mb_pu_cnt += 1;
1163 
1164     /* Update colocated pu */
1165     if (ps_proc->i4_slice_type == BSLICE)
1166         ps_proc->ps_colpu += *(ps_proc->aps_mv_buf[1]->pu4_mb_pu_cnt +  (i4_mb_y * ps_proc->i4_wd_mbs) + i4_mb_x);
1167 
1168     /* deblk ctxts */
1169     if (ps_proc->u4_disable_deblock_level != 1)
1170     {
1171         /* indices */
1172         ps_bs->i4_mb_x = ps_proc->i4_mb_x;
1173         ps_bs->i4_mb_y = ps_proc->i4_mb_y;
1174 
1175 #ifndef N_MB_ENABLE /* For N MB processing update take place inside deblocking function */
1176         ps_deblk->i4_mb_x ++;
1177 
1178         ps_deblk->pu1_cur_pic_luma += MB_SIZE;
1179         /*
1180          * Note: Although chroma mb size is 8, as the chroma buffers are interleaved,
1181          * the stride per MB is MB_SIZE
1182          */
1183         ps_deblk->pu1_cur_pic_chroma += MB_SIZE;
1184 #endif
1185     }
1186 
1187     return error_status;
1188 }
1189 
1190 /**
1191 *******************************************************************************
1192 *
1193 * @brief   initialize process context.
1194 *
1195 * @par Description:
1196 *  Before dispatching the current job to process thread, the process context
1197 *  associated with the job is initialized. Usually every job aims to encode one
1198 *  row of mb's. Basing on the row indices provided by the job, the process
1199 *  context's buffer ptrs, slice indices and other elements that are necessary
1200 *  during core-coding are initialized.
1201 *
1202 * @param[in] ps_proc
1203 *  Pointer to the current process context
1204 *
1205 * @returns error status
1206 *
1207 * @remarks none
1208 *
1209 *******************************************************************************
1210 */
ih264e_init_proc_ctxt(process_ctxt_t * ps_proc)1211 IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc)
1212 {
1213     /* codec context */
1214     codec_t *ps_codec = ps_proc->ps_codec;
1215 
1216     /* nmb processing context*/
1217     n_mb_process_ctxt_t *ps_n_mb_ctxt = &ps_proc->s_n_mb_ctxt;
1218 
1219     /* indices */
1220     WORD32 i4_mb_x, i4_mb_y;
1221 
1222     /* strides */
1223     WORD32 i4_src_strd = ps_proc->i4_src_strd;
1224     WORD32 i4_src_chroma_strd = ps_proc->i4_src_chroma_strd;
1225     WORD32 i4_rec_strd = ps_proc->i4_rec_strd;
1226 
1227     /* quant params */
1228     quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
1229 
1230     /* deblk ctxt */
1231     deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
1232 
1233     /* deblk bs context */
1234     bs_ctxt_t *ps_bs = &(ps_deblk->s_bs_ctxt);
1235 
1236     /* Pointer to mv_buffer of current frame */
1237     mv_buf_t *ps_cur_mv_buf = ps_proc->ps_cur_mv_buf;
1238 
1239     /* Pointers for color space conversion */
1240     UWORD8 *pu1_y_buf_base, *pu1_u_buf_base, *pu1_v_buf_base;
1241 
1242     /* Pad the MB to support non standard sizes */
1243     UWORD32 u4_pad_right_sz = ps_codec->s_cfg.u4_wd - ps_codec->s_cfg.u4_disp_wd;
1244     UWORD32 u4_pad_bottom_sz = ps_codec->s_cfg.u4_ht - ps_codec->s_cfg.u4_disp_ht;
1245     UWORD16 u2_num_rows = MB_SIZE;
1246     WORD32 convert_uv_only;
1247 
1248     /********************************************************************/
1249     /*                            BEGIN INIT                            */
1250     /********************************************************************/
1251 
1252     i4_mb_x = ps_proc->i4_mb_x;
1253     i4_mb_y = ps_proc->i4_mb_y;
1254 
1255     /* Number of mbs processed in one loop of process function */
1256     ps_proc->i4_nmb_ntrpy = ps_proc->i4_wd_mbs;
1257     ps_proc->u4_nmb_me = ps_proc->i4_wd_mbs;
1258 
1259     /* init buffer pointers */
1260     convert_uv_only = 1;
1261     if (u4_pad_bottom_sz || u4_pad_right_sz ||
1262         ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_422ILE)
1263     {
1264         if (ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1)
1265             u2_num_rows = (UWORD16) MB_SIZE - u4_pad_bottom_sz;
1266         ps_proc->pu1_src_buf_luma_base = ps_codec->pu1_y_csc_buf_base;
1267         i4_src_strd = ps_proc->i4_src_strd = ps_codec->s_cfg.u4_max_wd;
1268         ps_proc->pu1_src_buf_luma = ps_proc->pu1_src_buf_luma_base + (i4_mb_x * MB_SIZE) + ps_codec->s_cfg.u4_max_wd * (i4_mb_y * MB_SIZE);
1269         convert_uv_only = 0;
1270     }
1271     else
1272     {
1273         i4_src_strd = ps_proc->i4_src_strd = ps_proc->s_inp_buf.s_raw_buf.au4_strd[0];
1274         ps_proc->pu1_src_buf_luma = ps_proc->pu1_src_buf_luma_base + (i4_mb_x * MB_SIZE) + i4_src_strd * (i4_mb_y * MB_SIZE);
1275     }
1276 
1277 
1278     if (ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_422ILE ||
1279         ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420P ||
1280         ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1) ||
1281         u4_pad_bottom_sz || u4_pad_right_sz)
1282     {
1283         if ((ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420SP_UV) ||
1284             (ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420SP_VU))
1285             ps_proc->pu1_src_buf_chroma_base = ps_codec->pu1_uv_csc_buf_base;
1286 
1287         ps_proc->pu1_src_buf_chroma = ps_proc->pu1_src_buf_chroma_base + (i4_mb_x * MB_SIZE) + ps_codec->s_cfg.u4_max_wd * (i4_mb_y * BLK8x8SIZE);
1288         i4_src_chroma_strd = ps_proc->i4_src_chroma_strd = ps_codec->s_cfg.u4_max_wd;
1289     }
1290     else
1291     {
1292         i4_src_chroma_strd = ps_proc->i4_src_chroma_strd = ps_proc->s_inp_buf.s_raw_buf.au4_strd[1];
1293         ps_proc->pu1_src_buf_chroma = ps_proc->pu1_src_buf_chroma_base + (i4_mb_x * MB_SIZE) + i4_src_chroma_strd * (i4_mb_y * BLK8x8SIZE);
1294     }
1295 
1296     ps_proc->pu1_rec_buf_luma = ps_proc->pu1_rec_buf_luma_base + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * MB_SIZE);
1297     ps_proc->pu1_rec_buf_chroma = ps_proc->pu1_rec_buf_chroma_base + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * BLK8x8SIZE);
1298 
1299     /* Tempral back and forward reference buffer */
1300     ps_proc->apu1_ref_buf_luma[0] = ps_proc->apu1_ref_buf_luma_base[0] + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * MB_SIZE);
1301     ps_proc->apu1_ref_buf_chroma[0] = ps_proc->apu1_ref_buf_chroma_base[0] + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * BLK8x8SIZE);
1302     ps_proc->apu1_ref_buf_luma[1] = ps_proc->apu1_ref_buf_luma_base[1] + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * MB_SIZE);
1303     ps_proc->apu1_ref_buf_chroma[1] = ps_proc->apu1_ref_buf_chroma_base[1] + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * BLK8x8SIZE);
1304 
1305     /*
1306      * Do color space conversion
1307      * NOTE : We assume there that the number of MB's to process will not span multiple rows
1308      */
1309     switch (ps_codec->s_cfg.e_inp_color_fmt)
1310     {
1311         case IV_YUV_420SP_UV:
1312         case IV_YUV_420SP_VU:
1313             /* In case of 420 semi-planar input, copy last few rows to intermediate
1314                buffer as chroma trans functions access one extra byte due to interleaved input.
1315                This data will be padded if required */
1316             if (ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1) || u4_pad_bottom_sz || u4_pad_right_sz)
1317             {
1318                 WORD32 num_rows = MB_SIZE;
1319                 UWORD8 *pu1_src;
1320                 UWORD8 *pu1_dst;
1321                 WORD32 i;
1322                 pu1_src = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[0] + (i4_mb_x * MB_SIZE) +
1323                           ps_proc->s_inp_buf.s_raw_buf.au4_strd[0] * (i4_mb_y * MB_SIZE);
1324 
1325                 pu1_dst = ps_proc->pu1_src_buf_luma;
1326 
1327                 /* If padding is required, we always copy luma, if padding isn't required we never copy luma. */
1328                 if (u4_pad_bottom_sz || u4_pad_right_sz) {
1329                     if (ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1))
1330                         num_rows = MB_SIZE - u4_pad_bottom_sz;
1331                     for (i = 0; i < num_rows; i++)
1332                     {
1333                         memcpy(pu1_dst, pu1_src, ps_codec->s_cfg.u4_wd);
1334                         pu1_src += ps_proc->s_inp_buf.s_raw_buf.au4_strd[0];
1335                         pu1_dst += ps_proc->i4_src_strd;
1336                     }
1337                 }
1338                 pu1_src = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[1] + (i4_mb_x * BLK8x8SIZE) +
1339                           ps_proc->s_inp_buf.s_raw_buf.au4_strd[1] * (i4_mb_y * BLK8x8SIZE);
1340                 pu1_dst = ps_proc->pu1_src_buf_chroma;
1341 
1342                 /* Last MB row of chroma is copied unconditionally, since trans functions access an extra byte
1343                  * due to interleaved input
1344                  */
1345                 if (ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1))
1346                     num_rows = (ps_codec->s_cfg.u4_disp_ht >> 1) - (ps_proc->i4_mb_y * BLK8x8SIZE);
1347                 else
1348                     num_rows = BLK8x8SIZE;
1349                 for (i = 0; i < num_rows; i++)
1350                 {
1351                     memcpy(pu1_dst, pu1_src, ps_codec->s_cfg.u4_wd);
1352                     pu1_src += ps_proc->s_inp_buf.s_raw_buf.au4_strd[1];
1353                     pu1_dst += ps_proc->i4_src_chroma_strd;
1354                 }
1355 
1356             }
1357             break;
1358 
1359         case IV_YUV_420P :
1360             pu1_y_buf_base = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[0] + (i4_mb_x * MB_SIZE) +
1361                             ps_proc->s_inp_buf.s_raw_buf.au4_strd[0] * (i4_mb_y * MB_SIZE);
1362 
1363             pu1_u_buf_base = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[1] + (i4_mb_x * BLK8x8SIZE) +
1364                             ps_proc->s_inp_buf.s_raw_buf.au4_strd[1] * (i4_mb_y * BLK8x8SIZE);
1365 
1366             pu1_v_buf_base = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[2] + (i4_mb_x * BLK8x8SIZE) +
1367                             ps_proc->s_inp_buf.s_raw_buf.au4_strd[2] * (i4_mb_y * BLK8x8SIZE);
1368 
1369             ps_codec->pf_ih264e_conv_420p_to_420sp(
1370                             pu1_y_buf_base, pu1_u_buf_base, pu1_v_buf_base,
1371                             ps_proc->pu1_src_buf_luma,
1372                             ps_proc->pu1_src_buf_chroma, u2_num_rows,
1373                             ps_codec->s_cfg.u4_disp_wd,
1374                             ps_proc->s_inp_buf.s_raw_buf.au4_strd[0],
1375                             ps_proc->s_inp_buf.s_raw_buf.au4_strd[1],
1376                             ps_proc->s_inp_buf.s_raw_buf.au4_strd[2],
1377                             ps_proc->i4_src_strd, ps_proc->i4_src_chroma_strd,
1378                             convert_uv_only);
1379             break;
1380 
1381         case IV_YUV_422ILE :
1382             pu1_y_buf_base =  (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[0] + (i4_mb_x * MB_SIZE * 2)
1383                               + ps_proc->s_inp_buf.s_raw_buf.au4_strd[0] * (i4_mb_y * MB_SIZE);
1384 
1385             ps_codec->pf_ih264e_fmt_conv_422i_to_420sp(
1386                             ps_proc->pu1_src_buf_luma,
1387                             ps_proc->pu1_src_buf_chroma,
1388                             ps_proc->pu1_src_buf_chroma + 1, pu1_y_buf_base,
1389                             ps_codec->s_cfg.u4_disp_wd, u2_num_rows,
1390                             ps_proc->i4_src_strd, ps_proc->i4_src_chroma_strd,
1391                             ps_proc->i4_src_chroma_strd,
1392                             ps_proc->s_inp_buf.s_raw_buf.au4_strd[0] >> 1);
1393             break;
1394 
1395         default:
1396             break;
1397     }
1398 
1399     if (u4_pad_right_sz && (ps_proc->i4_mb_x == 0))
1400     {
1401         UWORD32 u4_pad_wd, u4_pad_ht;
1402         u4_pad_wd = (UWORD32)(ps_proc->i4_src_strd - ps_codec->s_cfg.u4_disp_wd);
1403         u4_pad_wd = MIN(u4_pad_right_sz, u4_pad_wd);
1404         u4_pad_ht = MB_SIZE;
1405         if(ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1)
1406             u4_pad_ht = MIN(MB_SIZE, (MB_SIZE - u4_pad_bottom_sz));
1407 
1408         ih264_pad_right_luma(
1409                         ps_proc->pu1_src_buf_luma + ps_codec->s_cfg.u4_disp_wd,
1410                         ps_proc->i4_src_strd, u4_pad_ht, u4_pad_wd);
1411 
1412         ih264_pad_right_chroma(
1413                         ps_proc->pu1_src_buf_chroma + ps_codec->s_cfg.u4_disp_wd,
1414                         ps_proc->i4_src_chroma_strd, u4_pad_ht / 2, u4_pad_wd);
1415     }
1416 
1417     /* pad bottom edge */
1418     if (u4_pad_bottom_sz && (ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1) && ps_proc->i4_mb_x == 0)
1419     {
1420         ih264_pad_bottom(ps_proc->pu1_src_buf_luma + (MB_SIZE - u4_pad_bottom_sz) * ps_proc->i4_src_strd,
1421                          ps_proc->i4_src_strd, ps_proc->i4_src_strd, u4_pad_bottom_sz);
1422 
1423         ih264_pad_bottom(ps_proc->pu1_src_buf_chroma + (MB_SIZE - u4_pad_bottom_sz) * ps_proc->i4_src_chroma_strd / 2,
1424                          ps_proc->i4_src_chroma_strd, ps_proc->i4_src_chroma_strd, (u4_pad_bottom_sz / 2));
1425     }
1426 
1427 
1428     /* packed mb coeff data */
1429     ps_proc->pv_mb_coeff_data = ((UWORD8 *)ps_proc->pv_pic_mb_coeff_data) + i4_mb_y * ps_codec->u4_size_coeff_data;
1430 
1431     /* packed mb header data */
1432     ps_proc->pv_mb_header_data = ((UWORD8 *)ps_proc->pv_pic_mb_header_data) + i4_mb_y * ps_codec->u4_size_header_data;
1433 
1434     /* slice index */
1435     ps_proc->i4_cur_slice_idx = ps_proc->pu1_slice_idx[i4_mb_y * ps_proc->i4_wd_mbs + i4_mb_x];
1436 
1437     /*********************************************************************/
1438     /* ih264e_init_quant_params() routine is called at the pic init level*/
1439     /* this would have initialized the qp.                               */
1440     /* TODO_LATER: currently it is assumed that quant params donot change*/
1441     /* across mb's. When they do calculate update ps_qp_params accordingly*/
1442     /*********************************************************************/
1443 
1444     /* init mv buffer ptr */
1445     ps_proc->ps_pu = ps_cur_mv_buf->ps_pic_pu + (i4_mb_y * ps_proc->i4_wd_mbs *
1446                      ((MB_SIZE * MB_SIZE) / (ENC_MIN_PU_SIZE * ENC_MIN_PU_SIZE)));
1447 
1448     /* Init co-located mv buffer */
1449     ps_proc->ps_colpu = ps_proc->aps_mv_buf[1]->ps_pic_pu + (i4_mb_y * ps_proc->i4_wd_mbs *
1450                         ((MB_SIZE * MB_SIZE) / (ENC_MIN_PU_SIZE * ENC_MIN_PU_SIZE)));
1451 
1452     if (i4_mb_y == 0)
1453     {
1454         ps_proc->ps_top_row_pu_ME = ps_cur_mv_buf->ps_pic_pu;
1455     }
1456     else
1457     {
1458         ps_proc->ps_top_row_pu_ME = ps_cur_mv_buf->ps_pic_pu + ((i4_mb_y - 1) * ps_proc->i4_wd_mbs *
1459                                     ((MB_SIZE * MB_SIZE) / (ENC_MIN_PU_SIZE * ENC_MIN_PU_SIZE)));
1460     }
1461 
1462     ps_proc->pu4_mb_pu_cnt = ps_cur_mv_buf->pu4_mb_pu_cnt + (i4_mb_y * ps_proc->i4_wd_mbs);
1463 
1464     /* mb type */
1465     ps_proc->u4_mb_type = I16x16;
1466 
1467     /* lambda */
1468     ps_proc->u4_lambda = gu1_qp0[ps_qp_params->u1_mb_qp];
1469 
1470     /* mb distortion */
1471     ps_proc->i4_mb_distortion = SHRT_MAX;
1472 
1473     if (i4_mb_x == 0)
1474     {
1475         ps_proc->s_left_mb_syntax_ele.i4_mb_distortion = 0;
1476 
1477         ps_proc->s_top_left_mb_syntax_ele.i4_mb_distortion = 0;
1478 
1479         ps_proc->s_top_left_mb_syntax_ME.i4_mb_distortion = 0;
1480 
1481         if (i4_mb_y == 0)
1482         {
1483             memset(ps_proc->ps_top_row_mb_syntax_ele, 0, (ps_proc->i4_wd_mbs + 1)*sizeof(mb_info_t));
1484         }
1485     }
1486 
1487     /* mb cost */
1488     ps_proc->i4_mb_cost = INT_MAX;
1489 
1490     /**********************/
1491     /* init deblk context */
1492     /**********************/
1493     ps_deblk->i4_mb_x = ps_proc->i4_mb_x;
1494     /* deblk lags the current mb proc by 1 row */
1495     /* NOTE: Intra prediction has to happen with non deblocked samples used as reference */
1496     /* Hence to deblk MB 0 of row 0, you have wait till MB 0 of row 1 is encoded. */
1497     /* For simplicity, we chose to lag deblking by 1 Row wrt to proc */
1498     ps_deblk->i4_mb_y = ps_proc->i4_mb_y - 1;
1499 
1500     /* buffer ptrs */
1501     ps_deblk->pu1_cur_pic_luma = ps_proc->pu1_rec_buf_luma_base + i4_rec_strd * (ps_deblk->i4_mb_y * MB_SIZE);
1502     ps_deblk->pu1_cur_pic_chroma = ps_proc->pu1_rec_buf_chroma_base + i4_rec_strd * (ps_deblk->i4_mb_y * BLK8x8SIZE);
1503 
1504     /* init deblk bs context */
1505     /* mb indices */
1506     ps_bs->i4_mb_x = ps_proc->i4_mb_x;
1507     ps_bs->i4_mb_y = ps_proc->i4_mb_y;
1508 
1509     /* init n_mb_process  context */
1510     ps_n_mb_ctxt->i4_mb_x = 0;
1511     ps_n_mb_ctxt->i4_mb_y = ps_deblk->i4_mb_y;
1512     ps_n_mb_ctxt->i4_n_mbs = ps_proc->i4_nmb_ntrpy;
1513 
1514     return IH264E_SUCCESS;
1515 }
1516 
1517 /**
1518 *******************************************************************************
1519 *
1520 * @brief This function performs luma & chroma padding
1521 *
1522 * @par Description:
1523 *
1524 * @param[in] ps_proc
1525 *  Process context corresponding to the job
1526 *
1527 * @param[in] pu1_curr_pic_luma
1528 *  Pointer to luma buffer
1529 *
1530 * @param[in] pu1_curr_pic_chroma
1531 *  Pointer to chroma buffer
1532 *
1533 * @param[in] i4_mb_x
1534 *  mb index x
1535 *
1536 * @param[in] i4_mb_y
1537 *  mb index y
1538 *
1539 *  @param[in] i4_pad_ht
1540 *  number of rows to be padded
1541 *
1542 * @returns  error status
1543 *
1544 * @remarks none
1545 *
1546 *******************************************************************************
1547 */
ih264e_pad_recon_buffer(process_ctxt_t * ps_proc,UWORD8 * pu1_curr_pic_luma,UWORD8 * pu1_curr_pic_chroma,WORD32 i4_mb_x,WORD32 i4_mb_y,WORD32 i4_pad_ht)1548 IH264E_ERROR_T ih264e_pad_recon_buffer(process_ctxt_t *ps_proc,
1549                                        UWORD8 *pu1_curr_pic_luma,
1550                                        UWORD8 *pu1_curr_pic_chroma,
1551                                        WORD32 i4_mb_x,
1552                                        WORD32 i4_mb_y,
1553                                        WORD32 i4_pad_ht)
1554 {
1555     /* codec context */
1556     codec_t *ps_codec = ps_proc->ps_codec;
1557 
1558     /* strides */
1559     WORD32 i4_rec_strd = ps_proc->i4_rec_strd;
1560 
1561     if (i4_mb_x == 0)
1562     {
1563         /* padding left luma */
1564         ps_codec->pf_pad_left_luma(pu1_curr_pic_luma, i4_rec_strd, i4_pad_ht, PAD_LEFT);
1565 
1566         /* padding left chroma */
1567         ps_codec->pf_pad_left_chroma(pu1_curr_pic_chroma, i4_rec_strd, i4_pad_ht >> 1, PAD_LEFT);
1568     }
1569     if (i4_mb_x == ps_proc->i4_wd_mbs - 1)
1570     {
1571         /* padding right luma */
1572         ps_codec->pf_pad_right_luma(pu1_curr_pic_luma + MB_SIZE, i4_rec_strd, i4_pad_ht, PAD_RIGHT);
1573 
1574         /* padding right chroma */
1575         ps_codec->pf_pad_right_chroma(pu1_curr_pic_chroma + MB_SIZE, i4_rec_strd, i4_pad_ht >> 1, PAD_RIGHT);
1576 
1577         if (i4_mb_y == ps_proc->i4_ht_mbs - 1)
1578         {
1579             UWORD8 *pu1_rec_luma = pu1_curr_pic_luma + MB_SIZE + PAD_RIGHT + ((i4_pad_ht - 1) * i4_rec_strd);
1580             UWORD8 *pu1_rec_chroma = pu1_curr_pic_chroma + MB_SIZE + PAD_RIGHT + (((i4_pad_ht >> 1) - 1) * i4_rec_strd);
1581 
1582             /* padding bottom luma */
1583             ps_codec->pf_pad_bottom(pu1_rec_luma, i4_rec_strd, i4_rec_strd, PAD_BOT);
1584 
1585             /* padding bottom chroma */
1586             ps_codec->pf_pad_bottom(pu1_rec_chroma, i4_rec_strd, i4_rec_strd, (PAD_BOT >> 1));
1587         }
1588     }
1589 
1590     if (i4_mb_y == 0)
1591     {
1592         UWORD8 *pu1_rec_luma = pu1_curr_pic_luma;
1593         UWORD8 *pu1_rec_chroma = pu1_curr_pic_chroma;
1594         WORD32 wd = MB_SIZE;
1595 
1596         if (i4_mb_x == 0)
1597         {
1598             pu1_rec_luma -= PAD_LEFT;
1599             pu1_rec_chroma -= PAD_LEFT;
1600 
1601             wd += PAD_LEFT;
1602         }
1603         if (i4_mb_x == ps_proc->i4_wd_mbs - 1)
1604         {
1605             wd += PAD_RIGHT;
1606         }
1607 
1608         /* padding top luma */
1609         ps_codec->pf_pad_top(pu1_rec_luma, i4_rec_strd, wd, PAD_TOP);
1610 
1611         /* padding top chroma */
1612         ps_codec->pf_pad_top(pu1_rec_chroma, i4_rec_strd, wd, (PAD_TOP >> 1));
1613     }
1614 
1615     return IH264E_SUCCESS;
1616 }
1617 
1618 
1619 
1620 
1621 /**
1622 *******************************************************************************
1623 *
1624 * @brief This function performs deblocking, padding and halfpel generation for
1625 *  'n' MBs
1626 *
1627 * @par Description:
1628 *
1629 * @param[in] ps_proc
1630 *  Process context corresponding to the job
1631 *
1632 * @param[in] pu1_curr_pic_luma
1633 * Current MB being processed(Luma)
1634 *
1635 * @param[in] pu1_curr_pic_chroma
1636 * Current MB being processed(Chroma)
1637 *
1638 * @param[in] i4_mb_x
1639 * Column value of current MB processed
1640 *
1641 * @param[in] i4_mb_y
1642 * Curent row processed
1643 *
1644 * @returns  error status
1645 *
1646 * @remarks none
1647 *
1648 *******************************************************************************
1649 */
ih264e_dblk_pad_hpel_processing_n_mbs(process_ctxt_t * ps_proc,UWORD8 * pu1_curr_pic_luma,UWORD8 * pu1_curr_pic_chroma,WORD32 i4_mb_x,WORD32 i4_mb_y)1650 IH264E_ERROR_T ih264e_dblk_pad_hpel_processing_n_mbs(process_ctxt_t *ps_proc,
1651                                                      UWORD8 *pu1_curr_pic_luma,
1652                                                      UWORD8 *pu1_curr_pic_chroma,
1653                                                      WORD32 i4_mb_x,
1654                                                      WORD32 i4_mb_y)
1655 {
1656     /* codec context */
1657     codec_t *ps_codec = ps_proc->ps_codec;
1658 
1659     /* n_mb processing context */
1660     n_mb_process_ctxt_t *ps_n_mb_ctxt = &ps_proc->s_n_mb_ctxt;
1661 
1662     /* deblk context */
1663     deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
1664 
1665     /* strides */
1666     WORD32 i4_rec_strd = ps_proc->i4_rec_strd;
1667 
1668     /* loop variables */
1669     WORD32 row, i, j, col;
1670 
1671     /* Padding Width */
1672     UWORD32 u4_pad_wd;
1673 
1674     /* deblk_map of the row being deblocked */
1675     UWORD8 *pu1_deblk_map = ps_proc->pu1_deblk_map + ps_deblk->i4_mb_y * ps_proc->i4_wd_mbs;
1676 
1677     /* deblk_map_previous row */
1678     UWORD8 *pu1_deblk_map_prev_row = pu1_deblk_map - ps_proc->i4_wd_mbs;
1679 
1680     WORD32 u4_pad_top = 0;
1681 
1682     WORD32 u4_deblk_prev_row = 0;
1683 
1684     /* Number of mbs to be processed */
1685     WORD32 i4_n_mbs = ps_n_mb_ctxt->i4_n_mbs;
1686 
1687     /* Number of mbs  actually processed
1688      * (at the end of a row, when remaining number of MBs are less than i4_n_mbs) */
1689     WORD32 i4_n_mb_process_count = 0;
1690 
1691     UWORD8 *pu1_pad_bottom_src = NULL;
1692 
1693     UWORD8 *pu1_pad_src_luma = NULL;
1694     UWORD8 *pu1_pad_src_chroma = NULL;
1695 
1696     if (ps_proc->u4_disable_deblock_level == 1)
1697     {
1698         /* If left most MB is processed, then pad left */
1699         if (i4_mb_x == 0)
1700         {
1701             /* padding left luma */
1702             ps_codec->pf_pad_left_luma(pu1_curr_pic_luma, i4_rec_strd, MB_SIZE, PAD_LEFT);
1703 
1704             /* padding left chroma */
1705             ps_codec->pf_pad_left_chroma(pu1_curr_pic_chroma, i4_rec_strd, MB_SIZE >> 1, PAD_LEFT);
1706         }
1707         /*last col*/
1708         if (i4_mb_x == (ps_proc->i4_wd_mbs - 1))
1709         {
1710             /* padding right luma */
1711             ps_codec->pf_pad_right_luma(pu1_curr_pic_luma + MB_SIZE, i4_rec_strd, MB_SIZE, PAD_RIGHT);
1712 
1713             /* padding right chroma */
1714             ps_codec->pf_pad_right_chroma(pu1_curr_pic_chroma + MB_SIZE, i4_rec_strd, MB_SIZE >> 1, PAD_RIGHT);
1715         }
1716     }
1717 
1718     if ((i4_mb_y > 0) || (i4_mb_y == (ps_proc->i4_ht_mbs - 1)))
1719     {
1720         /* if number of mb's to be processed are less than 'N', go back.
1721          * exception to the above clause is end of row */
1722         if ( ((i4_mb_x - (ps_n_mb_ctxt->i4_mb_x - 1)) < i4_n_mbs) && (i4_mb_x < (ps_proc->i4_wd_mbs - 1)) )
1723         {
1724             return IH264E_SUCCESS;
1725         }
1726         else
1727         {
1728             i4_n_mb_process_count = MIN(i4_mb_x - (ps_n_mb_ctxt->i4_mb_x - 1), i4_n_mbs);
1729 
1730             /* performing deblocking for required number of MBs */
1731             if ((i4_mb_y > 0) && (ps_proc->u4_disable_deblock_level != 1))
1732             {
1733                 u4_deblk_prev_row = 1;
1734 
1735                 /* checking whether the top rows are deblocked */
1736                 for (col = 0; col < i4_n_mb_process_count; col++)
1737                 {
1738                     u4_deblk_prev_row &= pu1_deblk_map_prev_row[ps_deblk->i4_mb_x + col];
1739                 }
1740 
1741                 /* checking whether the top right MB is deblocked */
1742                 if ((ps_deblk->i4_mb_x + i4_n_mb_process_count) != ps_proc->i4_wd_mbs)
1743                 {
1744                     u4_deblk_prev_row &= pu1_deblk_map_prev_row[ps_deblk->i4_mb_x + i4_n_mb_process_count];
1745                 }
1746 
1747                 /* Top or Top right MBs not deblocked */
1748                 if ((u4_deblk_prev_row != 1) && (i4_mb_y > 0))
1749                 {
1750                     return IH264E_SUCCESS;
1751                 }
1752 
1753                 for (row = 0; row < i4_n_mb_process_count; row++)
1754                 {
1755                     ih264e_deblock_mb(ps_proc, ps_deblk);
1756 
1757                     pu1_deblk_map[ps_deblk->i4_mb_x] = 1;
1758 
1759                     if (ps_deblk->i4_mb_y > 0)
1760                     {
1761                         if (ps_deblk->i4_mb_x == 0)/* If left most MB is processed, then pad left*/
1762                         {
1763                             /* padding left luma */
1764                             ps_codec->pf_pad_left_luma(ps_deblk->pu1_cur_pic_luma - i4_rec_strd * MB_SIZE, i4_rec_strd, MB_SIZE, PAD_LEFT);
1765 
1766                             /* padding left chroma */
1767                             ps_codec->pf_pad_left_chroma(ps_deblk->pu1_cur_pic_chroma - i4_rec_strd * BLK8x8SIZE, i4_rec_strd, MB_SIZE >> 1, PAD_LEFT);
1768                         }
1769 
1770                         if (ps_deblk->i4_mb_x == (ps_proc->i4_wd_mbs - 1))/*last column*/
1771                         {
1772                             /* padding right luma */
1773                             ps_codec->pf_pad_right_luma(ps_deblk->pu1_cur_pic_luma - i4_rec_strd * MB_SIZE + MB_SIZE, i4_rec_strd, MB_SIZE, PAD_RIGHT);
1774 
1775                             /* padding right chroma */
1776                             ps_codec->pf_pad_right_chroma(ps_deblk->pu1_cur_pic_chroma - i4_rec_strd * BLK8x8SIZE + MB_SIZE, i4_rec_strd, MB_SIZE >> 1, PAD_RIGHT);
1777                         }
1778                     }
1779                     ps_deblk->i4_mb_x++;
1780 
1781                     ps_deblk->pu1_cur_pic_luma += MB_SIZE;
1782                     ps_deblk->pu1_cur_pic_chroma += MB_SIZE;
1783 
1784                 }
1785             }
1786             else if(i4_mb_y > 0)
1787             {
1788                 ps_deblk->i4_mb_x += i4_n_mb_process_count;
1789 
1790                 ps_deblk->pu1_cur_pic_luma += i4_n_mb_process_count * MB_SIZE;
1791                 ps_deblk->pu1_cur_pic_chroma += i4_n_mb_process_count * MB_SIZE;
1792             }
1793 
1794             if (i4_mb_y == 2)
1795             {
1796                 u4_pad_wd = i4_n_mb_process_count * MB_SIZE;
1797                 u4_pad_top = ps_n_mb_ctxt->i4_mb_x * MB_SIZE;
1798 
1799                 if (ps_n_mb_ctxt->i4_mb_x == 0)
1800                 {
1801                     u4_pad_wd += PAD_LEFT;
1802                     u4_pad_top = -PAD_LEFT;
1803                 }
1804 
1805                 if (i4_mb_x == ps_proc->i4_wd_mbs - 1)
1806                 {
1807                     u4_pad_wd += PAD_RIGHT;
1808                 }
1809 
1810                 /* padding top luma */
1811                 ps_codec->pf_pad_top(ps_proc->pu1_rec_buf_luma_base + u4_pad_top, i4_rec_strd, u4_pad_wd, PAD_TOP);
1812 
1813                 /* padding top chroma */
1814                 ps_codec->pf_pad_top(ps_proc->pu1_rec_buf_chroma_base + u4_pad_top, i4_rec_strd, u4_pad_wd, (PAD_TOP >> 1));
1815             }
1816 
1817             ps_n_mb_ctxt->i4_mb_x += i4_n_mb_process_count;
1818 
1819             if (i4_mb_x == ps_proc->i4_wd_mbs - 1)
1820             {
1821                 if (ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1)
1822                 {
1823                     /* Bottom Padding is done in one stretch for the entire width */
1824                     if (ps_proc->u4_disable_deblock_level != 1)
1825                     {
1826                         ps_deblk->pu1_cur_pic_luma = ps_proc->pu1_rec_buf_luma_base + (ps_proc->i4_ht_mbs - 1) * i4_rec_strd * MB_SIZE;
1827 
1828                         ps_deblk->pu1_cur_pic_chroma = ps_proc->pu1_rec_buf_chroma_base + (ps_proc->i4_ht_mbs - 1) * i4_rec_strd * BLK8x8SIZE;
1829 
1830                         ps_n_mb_ctxt->i4_mb_x = 0;
1831                         ps_n_mb_ctxt->i4_mb_y = ps_proc->i4_mb_y;
1832                         ps_deblk->i4_mb_x = 0;
1833                         ps_deblk->i4_mb_y = ps_proc->i4_mb_y;
1834 
1835                         /* update pic qp map (as update_proc_ctxt is still not called for the last MB) */
1836                         ps_proc->s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp[(i4_mb_y * ps_proc->i4_wd_mbs) + i4_mb_x] = ps_proc->u4_mb_qp;
1837 
1838                         i4_n_mb_process_count = (ps_proc->i4_wd_mbs) % i4_n_mbs;
1839 
1840                         j = (ps_proc->i4_wd_mbs) / i4_n_mbs;
1841 
1842                         for (i = 0; i < j; i++)
1843                         {
1844                             for (col = 0; col < i4_n_mbs; col++)
1845                             {
1846                                 ih264e_deblock_mb(ps_proc, ps_deblk);
1847 
1848                                 pu1_deblk_map[ps_deblk->i4_mb_x] = 1;
1849 
1850                                 ps_deblk->i4_mb_x++;
1851                                 ps_deblk->pu1_cur_pic_luma += MB_SIZE;
1852                                 ps_deblk->pu1_cur_pic_chroma += MB_SIZE;
1853                                 ps_n_mb_ctxt->i4_mb_x++;
1854                             }
1855                         }
1856 
1857                         for (col = 0; col < i4_n_mb_process_count; col++)
1858                         {
1859                             ih264e_deblock_mb(ps_proc, ps_deblk);
1860 
1861                             pu1_deblk_map[ps_deblk->i4_mb_x] = 1;
1862 
1863                             ps_deblk->i4_mb_x++;
1864                             ps_deblk->pu1_cur_pic_luma += MB_SIZE;
1865                             ps_deblk->pu1_cur_pic_chroma += MB_SIZE;
1866                             ps_n_mb_ctxt->i4_mb_x++;
1867                         }
1868 
1869                         pu1_pad_src_luma = ps_proc->pu1_rec_buf_luma_base + (ps_proc->i4_ht_mbs - 2) * MB_SIZE * i4_rec_strd;
1870 
1871                         pu1_pad_src_chroma = ps_proc->pu1_rec_buf_chroma_base + (ps_proc->i4_ht_mbs - 2) * BLK8x8SIZE * i4_rec_strd;
1872 
1873                         /* padding left luma */
1874                         ps_codec->pf_pad_left_luma(pu1_pad_src_luma, i4_rec_strd, MB_SIZE, PAD_LEFT);
1875 
1876                         /* padding left chroma */
1877                         ps_codec->pf_pad_left_chroma(pu1_pad_src_chroma, i4_rec_strd, BLK8x8SIZE, PAD_LEFT);
1878 
1879                         pu1_pad_src_luma += i4_rec_strd * MB_SIZE;
1880                         pu1_pad_src_chroma += i4_rec_strd * BLK8x8SIZE;
1881 
1882                         /* padding left luma */
1883                         ps_codec->pf_pad_left_luma(pu1_pad_src_luma, i4_rec_strd, MB_SIZE, PAD_LEFT);
1884 
1885                         /* padding left chroma */
1886                         ps_codec->pf_pad_left_chroma(pu1_pad_src_chroma, i4_rec_strd, BLK8x8SIZE, PAD_LEFT);
1887 
1888                         pu1_pad_src_luma = ps_proc->pu1_rec_buf_luma_base + (ps_proc->i4_ht_mbs - 2) * MB_SIZE * i4_rec_strd + (ps_proc->i4_wd_mbs) * MB_SIZE;
1889 
1890                         pu1_pad_src_chroma = ps_proc->pu1_rec_buf_chroma_base + (ps_proc->i4_ht_mbs - 2) * BLK8x8SIZE * i4_rec_strd + (ps_proc->i4_wd_mbs) * MB_SIZE;
1891 
1892                         /* padding right luma */
1893                         ps_codec->pf_pad_right_luma(pu1_pad_src_luma, i4_rec_strd, MB_SIZE, PAD_RIGHT);
1894 
1895                         /* padding right chroma */
1896                         ps_codec->pf_pad_right_chroma(pu1_pad_src_chroma, i4_rec_strd, BLK8x8SIZE, PAD_RIGHT);
1897 
1898                         pu1_pad_src_luma += i4_rec_strd * MB_SIZE;
1899                         pu1_pad_src_chroma += i4_rec_strd * BLK8x8SIZE;
1900 
1901                         /* padding right luma */
1902                         ps_codec->pf_pad_right_luma(pu1_pad_src_luma, i4_rec_strd, MB_SIZE, PAD_RIGHT);
1903 
1904                         /* padding right chroma */
1905                         ps_codec->pf_pad_right_chroma(pu1_pad_src_chroma, i4_rec_strd, BLK8x8SIZE, PAD_RIGHT);
1906 
1907                     }
1908 
1909                     /* In case height is less than 2 MBs pad top */
1910                     if (ps_proc->i4_ht_mbs <= 2)
1911                     {
1912                         UWORD8 *pu1_pad_top_src;
1913                         /* padding top luma */
1914                         pu1_pad_top_src = ps_proc->pu1_rec_buf_luma_base - PAD_LEFT;
1915                         ps_codec->pf_pad_top(pu1_pad_top_src, i4_rec_strd, i4_rec_strd, PAD_TOP);
1916 
1917                         /* padding top chroma */
1918                         pu1_pad_top_src = ps_proc->pu1_rec_buf_chroma_base - PAD_LEFT;
1919                         ps_codec->pf_pad_top(pu1_pad_top_src, i4_rec_strd, i4_rec_strd, (PAD_TOP >> 1));
1920                     }
1921 
1922                     /* padding bottom luma */
1923                     pu1_pad_bottom_src = ps_proc->pu1_rec_buf_luma_base + ps_proc->i4_ht_mbs * MB_SIZE * i4_rec_strd - PAD_LEFT;
1924                     ps_codec->pf_pad_bottom(pu1_pad_bottom_src, i4_rec_strd, i4_rec_strd, PAD_BOT);
1925 
1926                     /* padding bottom chroma */
1927                     pu1_pad_bottom_src = ps_proc->pu1_rec_buf_chroma_base + ps_proc->i4_ht_mbs * (MB_SIZE >> 1) * i4_rec_strd - PAD_LEFT;
1928                     ps_codec->pf_pad_bottom(pu1_pad_bottom_src, i4_rec_strd, i4_rec_strd, (PAD_BOT >> 1));
1929                 }
1930             }
1931         }
1932     }
1933 
1934     return IH264E_SUCCESS;
1935 }
1936 
1937 
1938 /**
1939 *******************************************************************************
1940 *
1941 * @brief This function performs luma & chroma core coding for a set of mb's.
1942 *
1943 * @par Description:
1944 *  The mb to be coded is taken and is evaluated over a predefined set of modes
1945 *  (intra (i16, i4, i8)/inter (mv, skip)) for best cost. The mode with least cost
1946 *  is selected and using intra/inter prediction filters, prediction is carried out.
1947 *  The deviation between src and pred signal constitutes error signal. This error
1948 *  signal is transformed (hierarchical transform if necessary) and quantized. The
1949 *  quantized residue is packed in to entropy buffer for entropy coding. This is
1950 *  repeated for all the mb's enlisted under the job.
1951 *
1952 * @param[in] ps_proc
1953 *  Process context corresponding to the job
1954 *
1955 * @returns  error status
1956 *
1957 * @remarks none
1958 *
1959 *******************************************************************************
1960 */
ih264e_process(process_ctxt_t * ps_proc)1961 WORD32 ih264e_process(process_ctxt_t *ps_proc)
1962 {
1963     /* error status */
1964     WORD32 error_status = IH264_SUCCESS;
1965 
1966     /* codec context */
1967     codec_t *ps_codec = ps_proc->ps_codec;
1968 
1969     /* cbp luma, chroma */
1970     UWORD32 u4_cbp_l, u4_cbp_c;
1971 
1972     /* width in mbs */
1973     WORD32 i4_wd_mbs = ps_proc->i4_wd_mbs;
1974 
1975     /* loop var */
1976     WORD32  i4_mb_idx, i4_mb_cnt = ps_proc->i4_mb_cnt;
1977 
1978     /* valid modes */
1979     UWORD32 u4_valid_modes = 0;
1980 
1981     /* gate threshold */
1982     WORD32 i4_gate_threshold = 0;
1983 
1984     /* is intra */
1985     WORD32 luma_idx, chroma_idx, is_intra;
1986 
1987     /* temp variables */
1988     WORD32 ctxt_sel = ps_proc->i4_encode_api_call_cnt % MAX_CTXT_SETS;
1989 
1990     /*
1991      * list of modes for evaluation
1992      * -------------------------------------------------------------------------
1993      * Note on enabling I4x4 and I16x16
1994      * At very low QP's the hadamard transform in I16x16 will push up the maximum
1995      * coeff value very high. CAVLC may not be able to represent the value and
1996      * hence the stream may not be decodable in some clips.
1997      * Hence at low QPs, we will enable I4x4 and disable I16x16 irrespective of preset.
1998      */
1999     if (ps_proc->i4_slice_type == ISLICE)
2000     {
2001         if (ps_proc->u4_frame_qp > 10)
2002         {
2003             /* enable intra 16x16 */
2004             u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
2005 
2006             /* enable intra 8x8 */
2007             u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_8x8 ? (1 << I8x8) : 0;
2008         }
2009 
2010         /* enable intra 4x4 */
2011         u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
2012         u4_valid_modes |= (ps_proc->u4_frame_qp <= 10) << I4x4;
2013 
2014     }
2015     else if (ps_proc->i4_slice_type == PSLICE)
2016     {
2017         if (ps_proc->u4_frame_qp > 10)
2018         {
2019             /* enable intra 16x16 */
2020             u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
2021         }
2022 
2023         /* enable intra 4x4 */
2024         if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
2025         {
2026             u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
2027         }
2028         u4_valid_modes |= (ps_proc->u4_frame_qp <= 10) << I4x4;
2029 
2030         /* enable inter P16x16 */
2031         u4_valid_modes |= (1 << P16x16);
2032     }
2033     else if (ps_proc->i4_slice_type == BSLICE)
2034     {
2035         if (ps_proc->u4_frame_qp > 10)
2036         {
2037             /* enable intra 16x16 */
2038             u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
2039         }
2040 
2041         /* enable intra 4x4 */
2042         if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
2043         {
2044             u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
2045         }
2046         u4_valid_modes |= (ps_proc->u4_frame_qp <= 10) << I4x4;
2047 
2048         /* enable inter B16x16 */
2049         u4_valid_modes |= (1 << B16x16);
2050     }
2051 
2052 
2053     /* init entropy */
2054     ps_proc->s_entropy.i4_mb_x = ps_proc->i4_mb_x;
2055     ps_proc->s_entropy.i4_mb_y = ps_proc->i4_mb_y;
2056     ps_proc->s_entropy.i4_mb_cnt = MIN(ps_proc->i4_nmb_ntrpy, i4_wd_mbs - ps_proc->i4_mb_x);
2057 
2058     /* compute recon when :
2059      *   1. current frame is to be used as a reference
2060      *   2. dump recon for bit stream sanity check
2061      */
2062     ps_proc->u4_compute_recon = ps_codec->u4_is_curr_frm_ref ||
2063                                 ps_codec->s_cfg.u4_enable_recon;
2064 
2065     /* Encode 'n' macroblocks,
2066      * 'n' being the number of mbs dictated by current proc ctxt */
2067     for (i4_mb_idx = 0; i4_mb_idx < i4_mb_cnt; i4_mb_idx ++)
2068     {
2069         /* since we have not yet found sad, we have not yet got min sad */
2070         /* we need to initialize these variables for each MB */
2071         /* TODO how to get the min sad into the codec */
2072         ps_proc->u4_min_sad = ps_codec->s_cfg.i4_min_sad;
2073         ps_proc->u4_min_sad_reached = 0;
2074 
2075         /* mb analysis */
2076         {
2077             /* temp var */
2078             WORD32 i4_mb_id = ps_proc->i4_mb_x + ps_proc->i4_mb_y * i4_wd_mbs;
2079 
2080             /* force intra refresh ? */
2081             WORD32 i4_air_enable_inter = (ps_codec->s_cfg.e_air_mode == IVE_AIR_MODE_NONE) ||
2082                             (ps_codec->pu2_intr_rfrsh_map[i4_mb_id] != ps_codec->i4_air_pic_cnt);
2083 
2084             /* evaluate inter 16x16 modes */
2085             if ((u4_valid_modes & (1 << P16x16)) || (u4_valid_modes & (1 << B16x16)))
2086             {
2087                 /* compute nmb me */
2088                 if (ps_proc->i4_mb_x % ps_proc->u4_nmb_me == 0)
2089                 {
2090                     ih264e_compute_me_nmb(ps_proc, MIN((WORD32)ps_proc->u4_nmb_me,
2091                                                        i4_wd_mbs - ps_proc->i4_mb_x));
2092                 }
2093 
2094                 /* set pointers to ME data appropriately for other modules to use */
2095                 {
2096                     UWORD32 u4_mb_index = ps_proc->i4_mb_x % ps_proc->u4_nmb_me ;
2097 
2098                     /* get the min sad condition for current mb */
2099                     ps_proc->u4_min_sad_reached = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad_reached;
2100                     ps_proc->u4_min_sad = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad;
2101 
2102                     ps_proc->ps_skip_mv = &(ps_proc->ps_nmb_info[u4_mb_index].as_skip_mv[0]);
2103                     ps_proc->ps_ngbr_avbl = &(ps_proc->ps_nmb_info[u4_mb_index].s_ngbr_avbl);
2104                     ps_proc->ps_pred_mv = &(ps_proc->ps_nmb_info[u4_mb_index].as_pred_mv[0]);
2105 
2106                     ps_proc->i4_mb_distortion = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_distortion;
2107                     ps_proc->i4_mb_cost = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_cost;
2108                     ps_proc->u4_min_sad = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad;
2109                     ps_proc->u4_min_sad_reached = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad_reached;
2110                     ps_proc->u4_mb_type = ps_proc->ps_nmb_info[u4_mb_index].u4_mb_type;
2111 
2112                     /* get the best sub pel buffer */
2113                     ps_proc->pu1_best_subpel_buf = ps_proc->ps_nmb_info[u4_mb_index].pu1_best_sub_pel_buf;
2114                     ps_proc->u4_bst_spel_buf_strd = ps_proc->ps_nmb_info[u4_mb_index].u4_bst_spel_buf_strd;
2115                 }
2116                 ih264e_derive_nghbr_avbl_of_mbs(ps_proc);
2117             }
2118             else
2119             {
2120                 /* Derive neighbor availability for the current macroblock */
2121                 ps_proc->ps_ngbr_avbl = &ps_proc->s_ngbr_avbl;
2122 
2123                 ih264e_derive_nghbr_avbl_of_mbs(ps_proc);
2124             }
2125 
2126             /*
2127              * If air says intra, we need to force the following code path to evaluate intra
2128              * The easy way is just to say that the inter cost is too much
2129              */
2130             if (!i4_air_enable_inter)
2131             {
2132                 ps_proc->u4_min_sad_reached = 0;
2133                 ps_proc->i4_mb_cost = INT_MAX;
2134                 ps_proc->i4_mb_distortion = INT_MAX;
2135             }
2136             else if (ps_proc->u4_mb_type == PSKIP)
2137             {
2138                 goto UPDATE_MB_INFO;
2139             }
2140 
2141             /* wait until the proc of [top + 1] mb is computed.
2142              * We wait till the proc dependencies are satisfied */
2143              if(ps_proc->i4_mb_y > 0)
2144              {
2145                 /* proc map */
2146                 UWORD8  *pu1_proc_map_top;
2147 
2148                 pu1_proc_map_top = ps_proc->pu1_proc_map + ((ps_proc->i4_mb_y - 1) * i4_wd_mbs);
2149 
2150                 while (1)
2151                 {
2152                     volatile UWORD8 *pu1_buf;
2153                     WORD32 idx = i4_mb_idx + 1;
2154 
2155                     idx = MIN(idx, ((WORD32)ps_codec->s_cfg.i4_wd_mbs - 1));
2156                     pu1_buf =  pu1_proc_map_top + idx;
2157                     if(*pu1_buf)
2158                         break;
2159                     ithread_yield();
2160                 }
2161             }
2162 
2163             /* If we already have the minimum sad, there is no point in searching for sad again */
2164             if (ps_proc->u4_min_sad_reached == 0 || ps_codec->s_cfg.u4_enc_speed_preset != IVE_FASTEST)
2165             {
2166                 /* intra gating in inter slices */
2167                 /* No need of gating if we want to force intra, we need to find the threshold only if inter is enabled by AIR*/
2168                 if (i4_air_enable_inter && ps_proc->i4_slice_type != ISLICE && ps_codec->u4_inter_gate)
2169                 {
2170                     /* distortion of neighboring blocks */
2171                     WORD32 i4_distortion[4];
2172 
2173                     i4_distortion[0] = ps_proc->s_left_mb_syntax_ele.i4_mb_distortion;
2174 
2175                     i4_distortion[1] = ps_proc->ps_top_row_mb_syntax_ele[ps_proc->i4_mb_x].i4_mb_distortion;
2176 
2177                     i4_distortion[2] = ps_proc->ps_top_row_mb_syntax_ele[ps_proc->i4_mb_x + 1].i4_mb_distortion;
2178 
2179                     i4_distortion[3] = ps_proc->s_top_left_mb_syntax_ele.i4_mb_distortion;
2180 
2181                     i4_gate_threshold = (i4_distortion[0] + i4_distortion[1] + i4_distortion[2] + i4_distortion[3]) >> 2;
2182 
2183                 }
2184 
2185 
2186                 /* If we are going to force intra we need to evaluate intra irrespective of gating */
2187                 if ( (!i4_air_enable_inter) || ((i4_gate_threshold + 16 *((WORD32) ps_proc->u4_lambda)) < ps_proc->i4_mb_distortion))
2188                 {
2189                     /* evaluate intra 4x4 modes */
2190                     if (u4_valid_modes & (1 << I4x4))
2191                     {
2192                         if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
2193                         {
2194                             ih264e_evaluate_intra4x4_modes_for_least_cost_rdopton(ps_proc);
2195                         }
2196                         else
2197                         {
2198                             ih264e_evaluate_intra4x4_modes_for_least_cost_rdoptoff(ps_proc);
2199                         }
2200                     }
2201 
2202                     /* evaluate intra 16x16 modes */
2203                     if (u4_valid_modes & (1 << I16x16))
2204                     {
2205                         ih264e_evaluate_intra16x16_modes_for_least_cost_rdoptoff(ps_proc);
2206                     }
2207 
2208                     /* evaluate intra 8x8 modes */
2209                     if (u4_valid_modes & (1 << I8x8))
2210                     {
2211                         ih264e_evaluate_intra8x8_modes_for_least_cost_rdoptoff(ps_proc);
2212                     }
2213 
2214                 }
2215         }
2216      }
2217 
2218         /* is intra */
2219         if (ps_proc->u4_mb_type == I4x4 || ps_proc->u4_mb_type == I16x16 || ps_proc->u4_mb_type == I8x8)
2220         {
2221             luma_idx = ps_proc->u4_mb_type;
2222             chroma_idx = 0;
2223             is_intra = 1;
2224 
2225             /* evaluate chroma blocks for intra */
2226             ih264e_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff(ps_proc);
2227         }
2228         else
2229         {
2230             luma_idx = 3;
2231             chroma_idx = 1;
2232             is_intra = 0;
2233         }
2234         ps_proc->u4_is_intra = is_intra;
2235         ps_proc->ps_pu->b1_intra_flag = is_intra;
2236 
2237         /* redo MV pred of neighbors in the case intra mb */
2238         /* TODO : currently called unconditionally, needs to be called only in the case of intra
2239          * to modify neighbors */
2240         if (ps_proc->i4_slice_type != ISLICE)
2241         {
2242             ih264e_mv_pred(ps_proc, ps_proc->i4_slice_type);
2243         }
2244 
2245         /* Perform luma mb core coding */
2246         u4_cbp_l = (ps_codec->luma_energy_compaction)[luma_idx](ps_proc);
2247 
2248         /* Perform luma mb core coding */
2249         u4_cbp_c = (ps_codec->chroma_energy_compaction)[chroma_idx](ps_proc);
2250 
2251         /* coded block pattern */
2252         ps_proc->u4_cbp = (u4_cbp_c << 4) | u4_cbp_l;
2253 
2254         if (!ps_proc->u4_is_intra)
2255         {
2256             if (ps_proc->i4_slice_type == BSLICE)
2257             {
2258                 if (ih264e_find_bskip_params(ps_proc, PRED_L0))
2259                 {
2260                     ps_proc->u4_mb_type = (ps_proc->u4_cbp) ? BDIRECT : BSKIP;
2261                 }
2262             }
2263             else if(!ps_proc->u4_cbp)
2264             {
2265                 if (ih264e_find_pskip_params(ps_proc, PRED_L0))
2266                 {
2267                     ps_proc->u4_mb_type = PSKIP;
2268                 }
2269             }
2270         }
2271 
2272 UPDATE_MB_INFO:
2273 
2274         /* Update mb sad, mb qp and intra mb cost. Will be used by rate control */
2275         ih264e_update_rc_mb_info(&ps_proc->s_frame_info, ps_proc);
2276 
2277         /**********************************************************************/
2278         /* if disable deblock level is '0' this implies enable deblocking for */
2279         /* all edges of all macroblocks with out any restrictions             */
2280         /*                                                                    */
2281         /* if disable deblock level is '1' this implies disable deblocking for*/
2282         /* all edges of all macroblocks with out any restrictions             */
2283         /*                                                                    */
2284         /* if disable deblock level is '2' this implies enable deblocking for */
2285         /* all edges of all macroblocks except edges overlapping with slice   */
2286         /* boundaries. This option is not currently supported by the encoder  */
2287         /* hence the slice map should be of no significance to perform debloc */
2288         /* king                                                               */
2289         /**********************************************************************/
2290 
2291         if (ps_proc->u4_compute_recon)
2292         {
2293             /* deblk context */
2294             /* src pointers */
2295             UWORD8 *pu1_cur_pic_luma = ps_proc->pu1_rec_buf_luma;
2296             UWORD8 *pu1_cur_pic_chroma = ps_proc->pu1_rec_buf_chroma;
2297 
2298             /* src indices */
2299             UWORD32 i4_mb_x = ps_proc->i4_mb_x;
2300             UWORD32 i4_mb_y = ps_proc->i4_mb_y;
2301 
2302             /* compute blocking strength */
2303             if (ps_proc->u4_disable_deblock_level != 1)
2304             {
2305                 ih264e_compute_bs(ps_proc);
2306             }
2307 
2308             /* nmb deblocking and hpel and padding */
2309             ih264e_dblk_pad_hpel_processing_n_mbs(ps_proc, pu1_cur_pic_luma,
2310                                                   pu1_cur_pic_chroma, i4_mb_x,
2311                                                   i4_mb_y);
2312         }
2313 
2314         /* update the context after for coding next mb */
2315         error_status = ih264e_update_proc_ctxt(ps_proc);
2316         if(error_status != IH264E_SUCCESS)
2317         {
2318             return error_status;
2319         }
2320         /* Once the last row is processed, mark the buffer status appropriately */
2321         if (ps_proc->i4_ht_mbs == ps_proc->i4_mb_y)
2322         {
2323             /* Pointer to current picture buffer structure */
2324             pic_buf_t *ps_cur_pic = ps_proc->ps_cur_pic;
2325 
2326             /* Pointer to current picture's mv buffer structure */
2327             mv_buf_t *ps_cur_mv_buf = ps_proc->ps_cur_mv_buf;
2328 
2329             /**********************************************************************/
2330             /* if disable deblock level is '0' this implies enable deblocking for */
2331             /* all edges of all macroblocks with out any restrictions             */
2332             /*                                                                    */
2333             /* if disable deblock level is '1' this implies disable deblocking for*/
2334             /* all edges of all macroblocks with out any restrictions             */
2335             /*                                                                    */
2336             /* if disable deblock level is '2' this implies enable deblocking for */
2337             /* all edges of all macroblocks except edges overlapping with slice   */
2338             /* boundaries. This option is not currently supported by the encoder  */
2339             /* hence the slice map should be of no significance to perform debloc */
2340             /* king                                                               */
2341             /**********************************************************************/
2342             error_status = ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr,
2343                                                 ps_cur_mv_buf->i4_buf_id , BUF_MGR_CODEC);
2344             if(error_status != IH264E_SUCCESS)
2345             {
2346                 return error_status;
2347             }
2348             error_status = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr,
2349                                                 ps_cur_pic->i4_buf_id , BUF_MGR_CODEC);
2350             if(error_status != IH264E_SUCCESS)
2351             {
2352                 return error_status;
2353             }
2354             if (ps_codec->s_cfg.u4_enable_recon)
2355             {
2356                 /* pic cnt */
2357                 ps_codec->as_rec_buf[ctxt_sel].i4_pic_cnt = ps_proc->i4_pic_cnt;
2358 
2359                 /* rec buffers */
2360                 ps_codec->as_rec_buf[ctxt_sel].s_pic_buf  = *ps_proc->ps_cur_pic;
2361 
2362                 /* is last? */
2363                 ps_codec->as_rec_buf[ctxt_sel].u4_is_last = ps_proc->s_entropy.u4_is_last;
2364 
2365                 /* frame time stamp */
2366                 ps_codec->as_rec_buf[ctxt_sel].u4_timestamp_high = ps_proc->s_entropy.u4_timestamp_high;
2367                 ps_codec->as_rec_buf[ctxt_sel].u4_timestamp_low = ps_proc->s_entropy.u4_timestamp_low;
2368             }
2369 
2370         }
2371     }
2372 
2373     DEBUG_HISTOGRAM_DUMP(ps_codec->s_cfg.i4_ht_mbs == ps_proc->i4_mb_y);
2374 
2375     return error_status;
2376 }
2377 
2378 /**
2379 *******************************************************************************
2380 *
2381 * @brief
2382 *  Function to update rc context after encoding
2383 *
2384 * @par   Description
2385 *  This function updates the rate control context after the frame is encoded.
2386 *  Number of bits consumed by the current frame, frame distortion, frame cost,
2387 *  number of intra/inter mb's, ... are passed on to rate control context for
2388 *  updating the rc model.
2389 *
2390 * @param[in] ps_codec
2391 *  Handle to codec context
2392 *
2393 * @param[in] ctxt_sel
2394 *  frame context selector
2395 *
2396 * @param[in] pic_cnt
2397 *  pic count
2398 *
2399 * @returns i4_stuffing_byte
2400 *  number of stuffing bytes (if necessary)
2401 *
2402 * @remarks
2403 *
2404 *******************************************************************************
2405 */
ih264e_update_rc_post_enc(codec_t * ps_codec,WORD32 ctxt_sel,WORD32 i4_is_first_frm)2406 WORD32 ih264e_update_rc_post_enc(codec_t *ps_codec, WORD32 ctxt_sel, WORD32 i4_is_first_frm)
2407 {
2408     /* proc set base idx */
2409     WORD32 i4_proc_ctxt_sel_base = ctxt_sel ? (MAX_PROCESS_CTXT / 2) : 0;
2410 
2411     /* proc ctxt */
2412     process_ctxt_t *ps_proc = &ps_codec->as_process[i4_proc_ctxt_sel_base];
2413 
2414     /* frame qp */
2415     UWORD8 u1_frame_qp = ps_codec->u4_frame_qp;
2416 
2417     /* cbr rc return status */
2418     WORD32 i4_stuffing_byte = 0;
2419 
2420     /* current frame stats */
2421     frame_info_t s_frame_info;
2422     picture_type_e rc_pic_type;
2423 
2424     /* temp var */
2425     WORD32 i, j;
2426 
2427     /********************************************************************/
2428     /*                            BEGIN INIT                            */
2429     /********************************************************************/
2430 
2431     /* init frame info */
2432     irc_init_frame_info(&s_frame_info);
2433 
2434     /* get frame info */
2435     for (i = 0; i < (WORD32)ps_codec->s_cfg.u4_num_cores; i++)
2436     {
2437         /*****************************************************************/
2438         /* One frame can be encoded by max of u4_num_cores threads       */
2439         /* Accumulating the num mbs, sad, qp and intra_mb_cost from      */
2440         /* u4_num_cores threads                                          */
2441         /*****************************************************************/
2442         for (j = 0; j< MAX_MB_TYPE; j++)
2443         {
2444             s_frame_info.num_mbs[j] += ps_proc[i].s_frame_info.num_mbs[j];
2445 
2446             s_frame_info.tot_mb_sad[j] += ps_proc[i].s_frame_info.tot_mb_sad[j];
2447 
2448             s_frame_info.qp_sum[j] += ps_proc[i].s_frame_info.qp_sum[j];
2449         }
2450 
2451         s_frame_info.intra_mb_cost_sum += ps_proc[i].s_frame_info.intra_mb_cost_sum;
2452 
2453         s_frame_info.activity_sum += ps_proc[i].s_frame_info.activity_sum;
2454 
2455         /*****************************************************************/
2456         /* gather number of residue and header bits consumed by the frame*/
2457         /*****************************************************************/
2458         ih264e_update_rc_bits_info(&s_frame_info, &ps_proc[i].s_entropy);
2459     }
2460 
2461     /* get pic type */
2462     switch (ps_codec->pic_type)
2463     {
2464         case PIC_I:
2465         case PIC_IDR:
2466             rc_pic_type = I_PIC;
2467             break;
2468         case PIC_P:
2469             rc_pic_type = P_PIC;
2470             break;
2471         case PIC_B:
2472             rc_pic_type = B_PIC;
2473             break;
2474         default:
2475             assert(0);
2476             break;
2477     }
2478 
2479     /* update rc lib with current frame stats */
2480     i4_stuffing_byte =  ih264e_rc_post_enc(ps_codec->s_rate_control.pps_rate_control_api,
2481                                           &(s_frame_info),
2482                                           ps_codec->s_rate_control.pps_pd_frm_rate,
2483                                           ps_codec->s_rate_control.pps_time_stamp,
2484                                           ps_codec->s_rate_control.pps_frame_time,
2485                                           (ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs),
2486                                           &rc_pic_type,
2487                                           i4_is_first_frm,
2488                                           &ps_codec->s_rate_control.post_encode_skip[ctxt_sel],
2489                                           u1_frame_qp,
2490                                           &ps_codec->s_rate_control.num_intra_in_prev_frame,
2491                                           &ps_codec->s_rate_control.i4_avg_activity);
2492     return i4_stuffing_byte;
2493 }
2494 
2495 /**
2496 *******************************************************************************
2497 *
2498 * @brief
2499 *  entry point of a spawned encoder thread
2500 *
2501 * @par Description:
2502 *  The encoder thread dequeues a proc/entropy job from the encoder queue and
2503 *  calls necessary routines.
2504 *
2505 * @param[in] pv_proc
2506 *  Process context corresponding to the thread
2507 *
2508 * @returns  error status
2509 *
2510 * @remarks
2511 *
2512 *******************************************************************************
2513 */
ih264e_process_thread(void * pv_proc)2514 WORD32 ih264e_process_thread(void *pv_proc)
2515 {
2516     /* error status */
2517     IH264_ERROR_T ret = IH264_SUCCESS;
2518     WORD32 error_status = IH264_SUCCESS;
2519 
2520     /* proc ctxt */
2521     process_ctxt_t *ps_proc = pv_proc;
2522 
2523     /* codec ctxt */
2524     codec_t *ps_codec = ps_proc->ps_codec;
2525 
2526     /* structure to represent a processing job entry */
2527     job_t s_job;
2528 
2529     /* blocking call : entropy dequeue is non-blocking till all
2530      * the proc jobs are processed */
2531     WORD32 is_blocking = 0;
2532 
2533     /* set affinity */
2534     ithread_set_affinity(ps_proc->i4_id);
2535 
2536     ps_proc->i4_error_code = IH264_SUCCESS;
2537     while(1)
2538     {
2539         /* dequeue a job from the entropy queue */
2540         {
2541             int error = ithread_mutex_lock(ps_codec->pv_entropy_mutex);
2542 
2543             /* codec context selector */
2544             WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
2545 
2546             volatile UWORD32 *pu4_buf = &ps_codec->au4_entropy_thread_active[ctxt_sel];
2547 
2548             /* have the lock */
2549             if (error == 0)
2550             {
2551                 if (*pu4_buf == 0)
2552                 {
2553                     /* no entropy threads are active, try dequeuing a job from the entropy queue */
2554                     ret = ih264_list_dequeue(ps_proc->pv_entropy_jobq, &s_job, is_blocking);
2555                     if (IH264_SUCCESS == ret)
2556                     {
2557                         *pu4_buf = 1;
2558                         ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
2559                         goto WORKER;
2560                     }
2561                     else if(is_blocking)
2562                     {
2563                         ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
2564                         break;
2565                     }
2566                 }
2567                 ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
2568             }
2569         }
2570 
2571         /* dequeue a job from the process queue */
2572         ret = ih264_list_dequeue(ps_proc->pv_proc_jobq, &s_job, 1);
2573         if (IH264_SUCCESS != ret)
2574         {
2575             if(ps_proc->i4_id)
2576                 break;
2577             else
2578             {
2579                 is_blocking = 1;
2580                 continue;
2581             }
2582         }
2583 
2584 WORKER:
2585         /* choose appropriate proc context based on proc_base_idx */
2586         ps_proc = &ps_codec->as_process[ps_proc->i4_id + s_job.i2_proc_base_idx];
2587 
2588         switch (s_job.i4_cmd)
2589         {
2590             case CMD_PROCESS:
2591                 ps_proc->i4_mb_cnt = s_job.i2_mb_cnt;
2592                 ps_proc->i4_mb_x = s_job.i2_mb_x;
2593                 ps_proc->i4_mb_y = s_job.i2_mb_y;
2594 
2595                 /* init process context */
2596                 ih264e_init_proc_ctxt(ps_proc);
2597 
2598                 /* core code all mbs enlisted under the current job */
2599                 error_status = ih264e_process(ps_proc);
2600                 if(error_status !=IH264_SUCCESS)
2601                 {
2602                     ps_proc->i4_error_code = error_status;
2603                     return ret;
2604                 }
2605                 break;
2606 
2607             case CMD_ENTROPY:
2608                 ps_proc->s_entropy.i4_mb_x = s_job.i2_mb_x;
2609                 ps_proc->s_entropy.i4_mb_y = s_job.i2_mb_y;
2610                 ps_proc->s_entropy.i4_mb_cnt = s_job.i2_mb_cnt;
2611 
2612                 /* init entropy */
2613                 ih264e_init_entropy_ctxt(ps_proc);
2614 
2615                 /* entropy code all mbs enlisted under the current job */
2616                 error_status = ih264e_entropy(ps_proc);
2617                 if(error_status !=IH264_SUCCESS)
2618                 {
2619                     ps_proc->i4_error_code = error_status;
2620                     return ret;
2621                 }
2622                 break;
2623 
2624             default:
2625                 ps_proc->i4_error_code = IH264_FAIL;
2626                 return ret;
2627         }
2628     }
2629 
2630     return ret;
2631 }
2632