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