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