blob: 2196a6400e8ba6e079523ea58e4745d78306e8fe [file] [log] [blame]
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301/******************************************************************************
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_utils.c
25*
26* @brief
27* Contains miscellaneous utility functions used by the encoder
28*
29* @author
30* ittiam
31*
32* @par List of Functions:
33* - ih264e_get_min_level()
34* - ih264e_get_lvl_idx()
35* - ih264e_get_dpb_size()
36* - ih264e_get_total_pic_buf_size()
37* - ih264e_get_pic_mv_bank_size()
38* - ih264e_pic_buf_mgr_add_bufs()
39* - ih264e_mv_buf_mgr_add_bufs()
40* - ih264e_init_quant_params()
41* - ih264e_init_air_map()
42* - ih264e_codec_init()
43* - ih264e_pic_init()
44*
45* @remarks
46* None
47*
48*******************************************************************************
49*/
50
51/*****************************************************************************/
52/* File Includes */
53/*****************************************************************************/
54
55/* system include files */
56#include <stdio.h>
57#include <stddef.h>
58#include <stdlib.h>
59#include <string.h>
60#include <assert.h>
61
62/* user include files */
63#include "ih264_typedefs.h"
64#include "iv2.h"
65#include "ive2.h"
66#include "ih264e.h"
67#include "ithread.h"
68#include "ih264_defs.h"
69#include "ih264_size_defs.h"
70#include "ime_distortion_metrics.h"
Harinarayanan K K134291e2015-06-18 16:03:38 +053071#include "ime_defs.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053072#include "ime_structs.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053073#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"
Harinarayanan K K134291e2015-06-18 16:03:38 +053081#include "ih264_cabac_tables.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053082#include "ih264_macros.h"
83#include "ih264_common_tables.h"
84#include "ih264_debug.h"
85#include "ih264_trans_data.h"
86#include "ih264e_defs.h"
87#include "ih264e_globals.h"
88#include "ih264_buf_mgr.h"
89#include "ih264_dpb_mgr.h"
90#include "ih264e_error.h"
91#include "ih264e_bitstream.h"
92#include "irc_cntrl_param.h"
93#include "irc_frame_info_collector.h"
94#include "ih264e_rate_control.h"
Harinarayanan K K134291e2015-06-18 16:03:38 +053095#include "ih264e_cabac_structs.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053096#include "ih264e_structs.h"
Harinarayanan K K134291e2015-06-18 16:03:38 +053097#include "ih264e_cabac.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053098#include "ih264e_utils.h"
99#include "ih264e_config.h"
100#include "ih264e_statistics.h"
101#include "ih264e_trace.h"
102#include "ih264_list.h"
103#include "ih264e_encode_header.h"
104#include "ih264e_me.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530105#include "ime.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530106#include "ih264e_core_coding.h"
107#include "ih264e_rc_mem_interface.h"
108#include "ih264e_time_stamp.h"
109#include "ih264e_debug.h"
110#include "ih264e_process.h"
111#include "ih264e_master.h"
112#include "irc_rate_control_api.h"
113#include "ime_statistics.h"
114
115/*****************************************************************************/
116/* Function Definitions */
117/*****************************************************************************/
118
119/**
Harinarayanan K K134291e2015-06-18 16:03:38 +0530120 *******************************************************************************
121 *
122 * @brief
123 * Queues the current buffer, gets back a another buffer for encoding with corrent
124 * picture type
125 *
126 * @par Description:
127 * This function performs 3 distinct but related functions.
128 * 1) Maintains an input queue [Note the the term queue donot imply a
129 * first-in first-out logic here] that queues input and dequeues them so
130 * that input frames can be encoded at any predetermined encoding order
131 * 2) Uses RC library to decide which frame must be encoded in current pass
132 * and which picture type it must be encoded to.
133 * 3) Uses RC library to decide the QP at which current frame has to be
134 * encoded
135 * 4) Determines if the current picture must be encoded or not based on
136 * PRE-ENC skip
137 *
138 * Input queue is used for storing input buffers till they are used for
139 * encoding. This queue is maintained at ps_codec->as_inp_list. Whenever a
140 * valid input comes, it is added to the end of queue. This same input is
141 * added to RC queue using the identifier as ps_codec->i4_pic_cnt. Hence any
142 * pic from RC can be located in the input queue easily.
143 *
144 * The dequeue operation does not start till we have ps_codec->s_cfg.u4_max_num_bframes
145 * frames in the queue. THis is done in order to ensure that once output starts
146 * we will have a constant stream of output with no gaps.
147 *
148 * THe output frame order is governed by RC library. When ever we dequeue a
149 * buffer from RC library, it ensures that we will get them in encoding order
150 * With the output of RC library, we can use the picture id to dequeue the
151 * corresponding buffer from input queue and encode it.
152 *
153 * Condition at the end of stream.
154 * -------------------------------
155 * At the last valid buffer from the app, we will get ps_ive_ip->u4_is_last
156 * to be set. This will the given to lib when appropriate input buffer is
157 * given to encoding.
158 *
159 * Since we have to output is not in sync with input, we will have frames to
160 * encode even after we recive the last vaild input buffer. Hence we have to
161 * make sure that we donot queue any new buffers once we get the flag [It may
162 * mess up GOP ?]. This is acheived by setting ps_codec->i4_last_inp_buff_received
163 * to act as a permenent marker for last frame recived [This may not be needed,
164 * because in our current app, all buffers after the last are marked as last.
165 * But can we rely on that?] . Hence after this flgag is set no new buffers are
166 * queued.
167 *
168 * @param[in] ps_codec
169 * Pointer to codec descriptor
170 *
171 * @param[in] ps_ive_ip
172 * Current input buffer to the encoder
173 *
174 * @param[out] ps_inp
175 * Buffer to be encoded in the current pass
176 *
177 * @returns
178 * Flag indicating if we have a pre-enc skip or not
179 *
180 * @remarks
181 * TODO (bpic)
182 * The check for null ans is last is redudent.
183 * Need to see if we can remove it
184 *
185 *******************************************************************************
186 */
187WORD32 ih264e_input_queue_update(codec_t *ps_codec,
188 ive_video_encode_ip_t *ps_ive_ip,
189 inp_buf_t *ps_enc_buff)
190{
191
192 inp_buf_t *ps_inp_buf;
193 picture_type_e e_pictype;
194 WORD32 i4_skip;
195 UWORD32 ctxt_sel, u4_pic_id, u4_pic_disp_id;
Thomala Srinivas5c3b9922019-04-17 18:20:04 +0530196 UWORD8 u1_frame_qp, i;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530197 UWORD32 max_frame_bits = 0x7FFFFFFF;
198
199 /* Mark that the last input frame has been received */
200 if (ps_ive_ip->u4_is_last == 1)
201 {
202 ps_codec->i4_last_inp_buff_received = 1;
203 }
204
205 if (ps_ive_ip->s_inp_buf.apv_bufs[0] == NULL
206 && !ps_codec->i4_last_inp_buff_received)
207 {
208 ps_enc_buff->s_raw_buf.apv_bufs[0] = NULL;
Martin Storsjo8e78e302015-06-29 16:33:39 +0300209 ps_enc_buff->u4_is_last = ps_ive_ip->u4_is_last;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530210 return 0;
211 }
212
213 /***************************************************************************
214 * Check for pre enc skip
215 * When src and target frame rates donot match, we skip some frames to
216 * maintain the relation ship between them
217 **************************************************************************/
218 {
219 WORD32 skip_src;
220
221 skip_src = ih264e_update_rc_framerates(
222 ps_codec->s_rate_control.pps_rate_control_api,
223 ps_codec->s_rate_control.pps_pd_frm_rate,
224 ps_codec->s_rate_control.pps_time_stamp,
225 ps_codec->s_rate_control.pps_frame_time);
226
Martin Storsjo8e78e302015-06-29 16:33:39 +0300227 if (skip_src)
228 {
229 ps_enc_buff->u4_is_last = ps_ive_ip->u4_is_last;
230 return 1;
231 }
Harinarayanan K K134291e2015-06-18 16:03:38 +0530232 }
233
234 /***************************************************************************
235 *Queue the input to the queue
236 **************************************************************************/
237 ps_inp_buf = &(ps_codec->as_inp_list[ps_codec->i4_pic_cnt
Thomala Srinivas5c3b9922019-04-17 18:20:04 +0530238 % MAX_NUM_INP_FRAMES]);
Harinarayanan K K134291e2015-06-18 16:03:38 +0530239
240 /* copy input info. to internal structure */
241 ps_inp_buf->s_raw_buf = ps_ive_ip->s_inp_buf;
242 ps_inp_buf->u4_timestamp_low = ps_ive_ip->u4_timestamp_low;
243 ps_inp_buf->u4_timestamp_high = ps_ive_ip->u4_timestamp_high;
244 ps_inp_buf->u4_is_last = ps_ive_ip->u4_is_last;
245 ps_inp_buf->pv_mb_info = ps_ive_ip->pv_mb_info;
246 ps_inp_buf->u4_mb_info_type = ps_ive_ip->u4_mb_info_type;
247 ps_inp_buf->pv_pic_info = ps_ive_ip->pv_pic_info;
248 ps_inp_buf->u4_pic_info_type = ps_ive_ip->u4_pic_info_type;
249
Chamarthi Kishoread2eaf82019-10-01 11:59:43 +0530250 ps_inp_buf->u1_sei_ccv_params_present_flag =
251 ps_codec->s_cfg.s_sei.u1_sei_ccv_params_present_flag;
252 ps_inp_buf->s_sei_ccv = ps_codec->s_cfg.s_sei.s_sei_ccv_params;
253
Harinarayanan K K134291e2015-06-18 16:03:38 +0530254 /***************************************************************************
255 * Now we should add the picture to RC stack here
256 **************************************************************************/
Harinarayanan K K63f40a82015-06-19 11:35:16 +0530257 /*
258 * If an I frame has been requested, ask RC to force it
259 * For IDR requests, we have to ask RC to force I and set IDR by our selves
260 * since RC Donot know about IDR. For forcing an IDR at dequeue stage we
261 * should record that an IDR has been requested some where. Hence we will
262 * store it in the u4_idr_inp_list at a position same as that of input frame
263 */
264 {
265 WORD32 i4_force_idr, i4_force_i;
266
267 i4_force_idr = (ps_codec->force_curr_frame_type == IV_IDR_FRAME);
268 i4_force_idr |= !(ps_codec->i4_pic_cnt % ps_codec->s_cfg.u4_idr_frm_interval);
269
270 i4_force_i = (ps_codec->force_curr_frame_type == IV_I_FRAME);
271
Harinarayanan K Kaad45872015-06-26 15:20:33 +0530272 ps_codec->i4_pending_idr_flag |= i4_force_idr;
Harinarayanan K K63f40a82015-06-19 11:35:16 +0530273
Harinarayanan K Kaad45872015-06-26 15:20:33 +0530274 if ((ps_codec->i4_pic_cnt > 0) && (i4_force_idr || i4_force_i))
Harinarayanan K K63f40a82015-06-19 11:35:16 +0530275 {
276 irc_force_I_frame(ps_codec->s_rate_control.pps_rate_control_api);
277 }
278 ps_codec->force_curr_frame_type = IV_NA_FRAME;
279 }
280
Harinarayanan K K134291e2015-06-18 16:03:38 +0530281 irc_add_picture_to_stack(ps_codec->s_rate_control.pps_rate_control_api,
282 ps_codec->i4_pic_cnt);
283
Harinarayanan K K63f40a82015-06-19 11:35:16 +0530284
285 /* Delay */
Harinarayanan K K134291e2015-06-18 16:03:38 +0530286 if (ps_codec->i4_encode_api_call_cnt
287 < (WORD32)(ps_codec->s_cfg.u4_num_bframes))
288 {
289 ps_enc_buff->s_raw_buf.apv_bufs[0] = NULL;
Martin Storsjo8e78e302015-06-29 16:33:39 +0300290 ps_enc_buff->u4_is_last = 0;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530291 return 0;
292 }
293
294 /***************************************************************************
295 * Get a new pic to encode
296 **************************************************************************/
Harinarayanan K K134291e2015-06-18 16:03:38 +0530297 /* Query the picture_type */
298 e_pictype = ih264e_rc_get_picture_details(
299 ps_codec->s_rate_control.pps_rate_control_api, (WORD32 *)(&u4_pic_id),
300 (WORD32 *)(&u4_pic_disp_id));
301
302 switch (e_pictype)
303 {
304 case I_PIC:
305 ps_codec->pic_type = PIC_I;
306 break;
307 case P_PIC:
308 ps_codec->pic_type = PIC_P;
309 break;
310 case B_PIC:
311 ps_codec->pic_type = PIC_B;
312 break;
313 default:
314 ps_codec->pic_type = PIC_NA;
315 ps_enc_buff->s_raw_buf.apv_bufs[0] = NULL;
316 return 0;
317 }
318
Harinarayanan K Kaad45872015-06-26 15:20:33 +0530319 /* Set IDR if it has been requested */
320 if (ps_codec->pic_type == PIC_I)
321 {
322 ps_codec->pic_type = ps_codec->i4_pending_idr_flag ?
Harinarayanan K K63f40a82015-06-19 11:35:16 +0530323 PIC_IDR : ps_codec->pic_type;
Harinarayanan K Kaad45872015-06-26 15:20:33 +0530324 ps_codec->i4_pending_idr_flag = 0;
325 }
Harinarayanan K K134291e2015-06-18 16:03:38 +0530326
327 /* Get current frame Qp */
328 u1_frame_qp = (UWORD8)irc_get_frame_level_qp(
329 ps_codec->s_rate_control.pps_rate_control_api, e_pictype,
330 max_frame_bits);
331 ps_codec->u4_frame_qp = gau1_mpeg2_to_h264_qmap[u1_frame_qp];
332
333 /*
334 * copy the pic id to poc because the display order is assumed to be same
335 * as input order
336 */
337 ps_codec->i4_poc = u4_pic_id;
338
339 /***************************************************************************
340 * Now retrieve the correct picture from the queue
341 **************************************************************************/
342
343 /* Mark the skip flag */
344 i4_skip = 0;
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530345 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530346 ps_codec->s_rate_control.pre_encode_skip[ctxt_sel] = i4_skip;
347
348 /* Get a buffer to encode */
Thomala Srinivas5c3b9922019-04-17 18:20:04 +0530349 ps_inp_buf = &(ps_codec->as_inp_list[u4_pic_id % MAX_NUM_INP_FRAMES]);
Harinarayanan K K134291e2015-06-18 16:03:38 +0530350
351 /* copy dequeued input to output */
352 ps_enc_buff->s_raw_buf = ps_inp_buf->s_raw_buf;
353 ps_enc_buff->u4_timestamp_low = ps_inp_buf->u4_timestamp_low;
354 ps_enc_buff->u4_timestamp_high = ps_inp_buf->u4_timestamp_high;
355 ps_enc_buff->u4_is_last = ps_inp_buf->u4_is_last;
356 ps_enc_buff->pv_mb_info = ps_inp_buf->pv_mb_info;
357 ps_enc_buff->u4_mb_info_type = ps_inp_buf->u4_mb_info_type;
358 ps_enc_buff->pv_pic_info = ps_inp_buf->pv_pic_info;
359 ps_enc_buff->u4_pic_info_type = ps_inp_buf->u4_pic_info_type;
360
Chamarthi Kishoread2eaf82019-10-01 11:59:43 +0530361 ps_enc_buff->u1_sei_ccv_params_present_flag = ps_inp_buf->u1_sei_ccv_params_present_flag;
362 ps_enc_buff->s_sei_ccv = ps_inp_buf->s_sei_ccv;
363
Harinarayanan K K4d354382015-06-29 15:04:53 +0530364 /* Special case for encoding trailing B frames
365 *
366 * In encoding streams with B frames it may happen that we have a B frame
367 * at the end without a P/I frame after it. Hence when we are dequeing from
368 * the RC, it will return the P frame [next in display order but before in
369 * encoding order] first. Since the dequeue happens for an invalid frame we
370 * will get a frame with null buff and set u4_is_last. Hence lib with return
371 * last frame flag at this point and will stop encoding.
372 *
373 * Since for the last B frame, we does not have the forward ref frame
374 * it makes sense to force it into P.
375 *
376 * To solve this, in case the current frame is P and if the last frame flag
377 * is set, we need to see if there is and pending B frames. If there are any,
378 * we should just encode that picture as the current P frame and set
379 * that B frame as the last frame. Hence the encoder will terminate naturally
380 * once that B-frame is encoded after all the in between frames.
381 *
382 * Since we cannot touch RC stack directly, the option of actually swapping
383 * frames in RC is ruled out. We have to modify the as_inp_list to simulate
384 * such a behavior by RC. We can do that by
385 * 1) Search through as_inp_list to locate the largest u4_timestamp_low less
386 * than current u4_timestamp_low. This will give us the last B frame before
387 * the current P frame. Note that this will handle pre encode skip too since
388 * queue happens after pre enc skip.
389 * 2) Swap the position in as_inp_list. Hence now the last B frame is
390 * encoded as P frame. And the new last B frame will have u4_is_last
391 * set so that encoder will end naturally once we reached that B frame
392 * or any subsequent frame. Also the current GOP will have 1 less B frame
393 * Since we are swapping, the poc will also be in-order.
394 * 3) In case we have an IPP stream, the result of our search will be an
395 * I/P frame which is already encoded. Thus swap and encode will result
396 * in encoding of duplicate frames. Hence to avoid this we will only
397 * have this work around in case of u4_num_bframes > 0.
398 *
399 * In case we have forced an I/IDR frame In between this P frame and
400 * the last B frame -> This cannot happen as the current P frame is
401 * supposed to have u4_is_last set. Thus forcing an I/ IDR after this
402 * is illogical.
403 *
404 * In cae if we have forced an I such that the frame just before last frame
405 * in is I/P -> This case will never arise. Since we have a closed GOP now,
406 * once we force an I, the gop gets reset, hence there will be a B between
407 * I/P and I/P.
408 */
409 if (ps_enc_buff->u4_is_last && (ps_codec->pic_type == PIC_P)
Thomala Srinivas5c3b9922019-04-17 18:20:04 +0530410 && ps_codec->s_cfg.u4_num_bframes)
Harinarayanan K K4d354382015-06-29 15:04:53 +0530411 {
Thomala Srinivas5c3b9922019-04-17 18:20:04 +0530412 WORD32 cntr;
413 WORD32 lst_bframe = -1;
414 UWORD32 u4_timestamp_low = 0;
415 UWORD32 u4_timestamp_high = 0;
416 inp_buf_t *ps_swap_buff, *ps_inp_list;
Harinarayanan K K4d354382015-06-29 15:04:53 +0530417
418 ps_inp_list = &ps_codec->as_inp_list[0];
Harinarayanan K K4d354382015-06-29 15:04:53 +0530419
Thomala Srinivas5c3b9922019-04-17 18:20:04 +0530420 /* Now search the inp list for highest timestamp */
421 for(cntr = 0; cntr < MAX_NUM_INP_FRAMES; cntr++)
Harinarayanan K K4d354382015-06-29 15:04:53 +0530422 {
Thomala Srinivas5c3b9922019-04-17 18:20:04 +0530423 if(ps_inp_list[cntr].s_raw_buf.apv_bufs[0] != NULL)
Harinarayanan K K4d354382015-06-29 15:04:53 +0530424 {
Thomala Srinivas5c3b9922019-04-17 18:20:04 +0530425 if ((ps_inp_list[cntr].u4_timestamp_high > u4_timestamp_high) ||
426 (ps_inp_list[cntr].u4_timestamp_high == u4_timestamp_high &&
427 ps_inp_list[cntr].u4_timestamp_low > u4_timestamp_low))
428 {
429 u4_timestamp_low = ps_inp_list[cntr].u4_timestamp_low;
430 u4_timestamp_high = ps_inp_list[cntr].u4_timestamp_high;
431 lst_bframe = cntr;
432 }
Harinarayanan K K4d354382015-06-29 15:04:53 +0530433 }
434 }
435
Thomala Srinivas5c3b9922019-04-17 18:20:04 +0530436 if(lst_bframe != -1)
437 {
438 ps_swap_buff = &(ps_codec->as_inp_list[lst_bframe]);
Harinarayanan K K4d354382015-06-29 15:04:53 +0530439
Thomala Srinivas5c3b9922019-04-17 18:20:04 +0530440 /* copy the last B buffer to output */
441 *ps_enc_buff = *ps_swap_buff;
Harinarayanan K K4d354382015-06-29 15:04:53 +0530442
Thomala Srinivas5c3b9922019-04-17 18:20:04 +0530443 /* Store the current buf into the queue in place of last B buf */
444 *ps_swap_buff = *ps_inp_buf;
445 }
Harinarayanan K K4d354382015-06-29 15:04:53 +0530446 }
447
Harinarayanan K K134291e2015-06-18 16:03:38 +0530448 if (ps_enc_buff->u4_is_last)
449 {
450 ps_codec->pic_type = PIC_NA;
451 }
452
Thomala Srinivas5c3b9922019-04-17 18:20:04 +0530453 /* The buffer in the queue is set to NULL to specify that encoding is done for that frame */
454 for(i = 0; i < 3; i++)
455 {
456 ps_inp_buf->s_raw_buf.apv_bufs[i] = NULL;
457 }
458
Harinarayanan K K134291e2015-06-18 16:03:38 +0530459 /* Return the buffer status */
460 return (0);
461}
462
463/**
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530464*******************************************************************************
465*
466* @brief
467* Used to get minimum level index for a given picture size
468*
469* @par Description:
470* Gets the minimum level index and then gets corresponding level.
471* Also used to ignore invalid levels like 2.3, 3.3 etc
472*
473* @param[in] level
474* Level of the stream
475*
476* @returns Level index for a given level
477*
478* @remarks
479*
480*******************************************************************************
481*/
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530482WORD32 ih264e_get_min_level(WORD32 wd, WORD32 ht)
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530483{
484 WORD32 lvl_idx = MAX_LEVEL, i;
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530485 WORD32 pic_size = wd * ht;
486 WORD32 max = MAX(wd, ht);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530487 for (i = 0; i < MAX_LEVEL; i++)
488 {
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530489 if ((pic_size <= gai4_ih264_max_luma_pic_size[i]) &&
490 (max <= gai4_ih264_max_wd_ht[i]))
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530491 {
492 lvl_idx = i;
493 break;
494 }
495 }
496
497 return gai4_ih264_levels[lvl_idx];
498}
499
500/**
501*******************************************************************************
502*
503* @brief
504* Used to get level index for a given level
505*
506* @par Description:
507* Converts from level_idc (which is multiplied by 30) to an index that can be
508* used as a lookup. Also used to ignore invalid levels like 2.2 , 3.2 etc
509*
510* @param[in] level
511* Level of the stream
512*
513* @returns Level index for a given level
514*
515* @remarks
516*
517*******************************************************************************
518*/
519WORD32 ih264e_get_lvl_idx(WORD32 level)
520{
521 WORD32 lvl_idx = 0;
522
523 if (level < IH264_LEVEL_11)
524 {
525 lvl_idx = 0;
526 }
527 else if (level < IH264_LEVEL_12)
528 {
529 lvl_idx = 1;
530 }
531 else if (level < IH264_LEVEL_13)
532 {
533 lvl_idx = 2;
534 }
535 else if (level < IH264_LEVEL_20)
536 {
537 lvl_idx = 3;
538 }
539 else if (level < IH264_LEVEL_21)
540 {
541 lvl_idx = 4;
542 }
543 else if (level < IH264_LEVEL_22)
544 {
545 lvl_idx = 5;
546 }
547 else if (level < IH264_LEVEL_30)
548 {
549 lvl_idx = 6;
550 }
551 else if (level < IH264_LEVEL_31)
552 {
553 lvl_idx = 7;
554 }
555 else if (level < IH264_LEVEL_32)
556 {
557 lvl_idx = 8;
558 }
559 else if (level < IH264_LEVEL_40)
560 {
561 lvl_idx = 9;
562 }
563 else if (level < IH264_LEVEL_41)
564 {
565 lvl_idx = 10;
566 }
567 else if (level < IH264_LEVEL_42)
568 {
569 lvl_idx = 11;
570 }
571 else if (level < IH264_LEVEL_50)
572 {
573 lvl_idx = 12;
574 }
Martin Storsjobf9cd172015-05-15 14:23:46 +0300575 else if (level < IH264_LEVEL_51)
576 {
577 lvl_idx = 13;
578 }
579 else
580 {
581 lvl_idx = 14;
582 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530583
584 return (lvl_idx);
585}
586
587/**
588*******************************************************************************
589*
590* @brief returns maximum number of pictures allowed in dpb for a given level
591*
592* @par Description:
593* For given width, height and level, number of pictures allowed in decoder
594* picture buffer is computed as per Annex A.3.1
595*
596* @param[in] level
597* level of the bit-stream
598*
599* @param[in] pic_size
600* width * height
601*
602* @returns Number of buffers in DPB
603*
604* @remarks
605* From annexure A.3.1 of H264 specification,
606* max_dec_frame_buffering <= MaxDpbSize, where MaxDpbSize is equal to
607* Min( 1024 * MaxDPB / ( PicWidthInMbs * FrameHeightInMbs * 384 ), 16 ) and
608* MaxDPB is given in Table A-1 in units of 1024 bytes. However the MaxDPB size
609* presented in the look up table gas_ih264_lvl_tbl is in units of 512
610* bytes. Hence the expression is modified accordingly.
611*
612*******************************************************************************
613*/
614WORD32 ih264e_get_dpb_size(WORD32 level, WORD32 pic_size)
615{
616 /* dpb size */
617 WORD32 max_dpb_size_bytes = 0;
618
619 /* dec frame buffering */
620 WORD32 max_dpb_size_frames = 0;
621
622 /* temp var */
623 WORD32 i;
624
625 /* determine max luma samples */
626 for (i = 0; i < 16; i++)
627 if (level == (WORD32)gas_ih264_lvl_tbl[i].u4_level_idc)
628 max_dpb_size_bytes = gas_ih264_lvl_tbl[i].u4_max_dpb_size;
629
630 /* from Annexure A.3.1 h264 specification */
631 max_dpb_size_frames =
632 MIN( 1024 * max_dpb_size_bytes / ( pic_size * 3 ), MAX_DPB_SIZE );
633
634 return max_dpb_size_frames;
635}
636
637/**
638*******************************************************************************
639*
640* @brief
641* Used to get reference picture buffer size for a given level and
642* and padding used
643*
644* @par Description:
645* Used to get reference picture buffer size for a given level and padding used
646* Each picture is padded on all four sides
647*
648* @param[in] pic_size
649* Number of luma samples (Width * Height)
650*
651* @param[in] level
652* Level
653*
654* @param[in] horz_pad
655* Total padding used in horizontal direction
656*
657* @param[in] vert_pad
658* Total padding used in vertical direction
659*
660* @returns Total picture buffer size
661*
662* @remarks
663*
664*
665*******************************************************************************
666*/
667WORD32 ih264e_get_total_pic_buf_size(WORD32 pic_size,
668 WORD32 level,
669 WORD32 horz_pad,
670 WORD32 vert_pad,
671 WORD32 num_ref_frames,
672 WORD32 num_reorder_frames)
673{
674 WORD32 size;
675 WORD32 num_luma_samples;
676 WORD32 lvl_idx;
677 WORD32 max_wd, min_ht;
678 WORD32 num_samples;
679 WORD32 max_num_bufs;
680 WORD32 pad = MAX(horz_pad, vert_pad);
Harinarayanan K K134291e2015-06-18 16:03:38 +0530681
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530682 /*
683 * If num_ref_frames and num_reorder_frmaes is specified
684 * Use minimum value
685 */
686 max_num_bufs = (num_ref_frames + num_reorder_frames + MAX_CTXT_SETS);
687
688 /* Get level index */
689 lvl_idx = ih264e_get_lvl_idx(level);
690
691 /* Maximum number of luma samples in a picture at given level */
692 num_luma_samples = gai4_ih264_max_luma_pic_size[lvl_idx];
Harinarayanan K K134291e2015-06-18 16:03:38 +0530693 num_luma_samples = MAX(num_luma_samples, pic_size);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530694
695 /* Account for chroma */
696 num_samples = num_luma_samples * 3 / 2;
697
698 /* Maximum width of luma samples in a picture at given level */
699 max_wd = gai4_ih264_max_wd_ht[lvl_idx];
700
701 /* Minimum height of luma samples in a picture at given level */
702 min_ht = gai4_ih264_min_wd_ht[lvl_idx];
703
704 /* Allocation is required for
705 * (Wd + horz_pad) * (Ht + vert_pad) * (2 * max_dpb_size + 1)
706 *
707 * Above expanded as
708 * ((Wd * Ht) + (horz_pad * vert_pad) + Wd * vert_pad + Ht * horz_pad) * (2 * max_dpb_size + 1)
709 * (Wd * Ht) * (2 * max_dpb_size + 1) + ((horz_pad * vert_pad) + Wd * vert_pad + Ht * horz_pad) * (2 * max_dpb_size + 1)
710 * Now max_dpb_size increases with smaller Wd and Ht, but Wd * ht * max_dpb_size will still be lesser or equal to max_wd * max_ht * dpb_size
711 *
712 * In the above equation (Wd * Ht) * (2 * max_dpb_size + 1) is accounted by using num_samples * (2 * max_dpb_size + 1) below
713 *
714 * For the padded area use MAX(horz_pad, vert_pad) as pad
715 * ((pad * pad) + pad * (Wd + Ht)) * (2 * max_dpb_size + 1) has to accounted from the above for padding
716 *
717 * Since Width and Height can change worst Wd + Ht is when One of the dimensions is max and other is min
718 * So use max_wd and min_ht
719 */
720
721 /* Number of bytes in reference pictures */
722 size = num_samples * max_num_bufs;
723
724 /* Account for padding area */
Martin Storsjobc7164d2015-05-25 14:42:53 +0300725 size += ((pad * pad) + pad * (max_wd + min_ht)) * 3 / 2 * max_num_bufs;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530726
727 return size;
728}
729
730/**
731*******************************************************************************
732*
733* @brief Returns MV bank buffer size for a given number of luma samples
734*
735* @par Description:
736* For given number of luma samples one MV bank size is computed.
737* Each MV bank includes pu_map and enc_pu_t for all the min PUs(4x4) in a picture
738*
739* @param[in] num_luma_samples
740* Max number of luma pixels in the frame
741*
742* @returns Total MV Bank size
743*
744* @remarks
745*
746*******************************************************************************
747*/
748WORD32 ih264e_get_pic_mv_bank_size(WORD32 num_luma_samples)
749{
750 /* mv bank buffer size */
751 WORD32 mv_bank_size = 0;
752
753 /* number of sub mb partitions possible */
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530754 WORD32 num_pu = num_luma_samples / (ENC_MIN_PU_SIZE * ENC_MIN_PU_SIZE);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530755
756 /* number of mbs */
757 WORD32 num_mb = num_luma_samples / (MB_SIZE * MB_SIZE);
758
759 /* Size for storing enc_pu_t start index each MB */
760 /* One extra entry is needed to compute number of PUs in the last MB */
761 mv_bank_size += num_mb * sizeof(WORD32);
762
763 /* Size for pu_map */
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530764 mv_bank_size += ALIGN4(num_pu);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530765
766 /* Size for storing enc_pu_t for each PU */
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530767 mv_bank_size += ALIGN4(num_pu * sizeof(enc_pu_t));
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530768
769 return mv_bank_size;
770}
771
772/**
773*******************************************************************************
774*
775* @brief
776* Function to initialize ps_pic_buf structs add pic buffers to
777* buffer manager in case of non-shared mode
778*
779* @par Description:
780* Function to initialize ps_pic_buf structs add pic buffers to
781* buffer manager in case of non-shared mode
782* To be called once per stream or for every reset
783*
784* @param[in] ps_codec
785* Pointer to codec context
786*
787* @returns error status
788*
789* @remarks
790*
791*******************************************************************************
792*/
793IH264E_ERROR_T ih264e_pic_buf_mgr_add_bufs(codec_t *ps_codec)
794{
795 /* error status */
796 IH264E_ERROR_T ret = IH264E_SUCCESS;
797
798 /* max ref buffer cnt */
799 WORD32 max_num_bufs = ps_codec->i4_ref_buf_cnt;
800
801 /* total size for pic buffers */
802 WORD32 pic_buf_size_allocated = ps_codec->i4_total_pic_buf_size
803 - BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
804
805 /* temp var */
806 UWORD8 *pu1_buf = (UWORD8 *) ps_codec->ps_pic_buf;
807 pic_buf_t *ps_pic_buf = (pic_buf_t *) ps_codec->ps_pic_buf;
808 WORD32 i;
809
810 pu1_buf += BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
811
812 /* In case of non-shared mode, add picture buffers to buffer manager
813 * In case of shared mode, buffers are added in the run-time
814 */
815 {
816 WORD32 buf_ret;
817
818 WORD32 luma_samples = (ps_codec->i4_rec_strd)
819 * (ps_codec->s_cfg.u4_ht + PAD_HT);
820
821 WORD32 chroma_samples = luma_samples >> 1;
822
823 /* Try and add as many buffers as possible for the memory that is allocated */
824 /* If the number of buffers that can be added is less than max_num_bufs
825 * return with an error */
826 for (i = 0; i < max_num_bufs; i++)
827 {
828 pic_buf_size_allocated -= (luma_samples + chroma_samples);
829
830 if (pic_buf_size_allocated < 0)
831 {
832 ps_codec->i4_error_code = IH264E_INSUFFICIENT_MEM_PICBUF;
833 return IH264E_INSUFFICIENT_MEM_PICBUF;
834 }
835
836 ps_pic_buf->pu1_luma = pu1_buf + ps_codec->i4_rec_strd * PAD_TOP
837 + PAD_LEFT;
838 pu1_buf += luma_samples;
839
840 ps_pic_buf->pu1_chroma = pu1_buf
841 + ps_codec->i4_rec_strd * (PAD_TOP / 2)+ PAD_LEFT;
842 pu1_buf += chroma_samples;
843
844 buf_ret = ih264_buf_mgr_add((buf_mgr_t *) ps_codec->pv_ref_buf_mgr,
845 ps_pic_buf, i);
846
847 if (0 != buf_ret)
848 {
849 ps_codec->i4_error_code = IH264E_BUF_MGR_ERROR;
850 return IH264E_BUF_MGR_ERROR;
851 }
852 pu1_buf += (HPEL_PLANES_CNT - 1) * (chroma_samples + luma_samples);
853 ps_pic_buf++;
854 }
855 }
856
857 return ret;
858}
859
860/**
861*******************************************************************************
862*
863* @brief Function to add buffers to MV Bank buffer manager
864*
865* @par Description:
866* Function to add buffers to MV Bank buffer manager. To be called once per
867* stream or for every reset
868*
869* @param[in] ps_codec
870* Pointer to codec context
871*
872* @returns error status
873*
874* @remarks
875*
876*******************************************************************************
877*/
878IH264E_ERROR_T ih264e_mv_buf_mgr_add_bufs(codec_t *ps_codec)
879{
880 /* error status */
881 IH264E_ERROR_T error_status = IH264E_SUCCESS;
882 IH264_ERROR_T ret;
883
884 /* max dpb size in frames */
885 WORD32 max_dpb_size = 0;
886
887 /* mv bank size for the entire dpb */
888 WORD32 mv_bank_size_allocated = 0;
889
890 /* mv bank size per pic */
891 WORD32 pic_mv_bank_size = 0;
892
893 /* mv buffer ptr */
894 mv_buf_t *ps_mv_buf = NULL;
895
896 /* num of luma samples */
897 WORD32 num_luma_samples = ALIGN16(ps_codec->s_cfg.u4_wd)
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530898 * ALIGN16(ps_codec->s_cfg.u4_ht);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530899
900 /* number of mb's & frame partitions */
901 WORD32 num_pu, num_mb;
902
903 /* temp var */
904 UWORD8 *pu1_buf = NULL;
905 WORD32 i;
906
907 /* Compute the number of MB Bank buffers needed */
908 max_dpb_size = ps_codec->i4_ref_buf_cnt;
909
910 /* allocate memory for mv buffer array */
911 ps_codec->ps_mv_buf = ps_codec->pv_mv_bank_buf_base;
912 pu1_buf = ps_codec->pv_mv_bank_buf_base;
913 pu1_buf += BUF_MGR_MAX_CNT * sizeof(mv_buf_t);
914
915 /********************************************************************/
916 /* allocate memory for individual elements of mv buffer ptr */
917 /********************************************************************/
918 mv_bank_size_allocated = ps_codec->i4_total_mv_bank_size
919 - (BUF_MGR_MAX_CNT * sizeof(mv_buf_t));
920
921 /* compute MV bank size per picture */
922 pic_mv_bank_size = ih264e_get_pic_mv_bank_size(num_luma_samples);
923
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530924 num_pu = num_luma_samples / (ENC_MIN_PU_SIZE * ENC_MIN_PU_SIZE);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530925 num_mb = num_luma_samples / (MB_SIZE * MB_SIZE);
926 i = 0;
927 ps_mv_buf = ps_codec->pv_mv_bank_buf_base;
928
929 while (i < max_dpb_size)
930 {
931 mv_bank_size_allocated -= pic_mv_bank_size;
932
933 if (mv_bank_size_allocated < 0)
934 {
935 ps_codec->i4_error_code = IH264E_INSUFFICIENT_MEM_MVBANK;
936
937 error_status = IH264E_INSUFFICIENT_MEM_MVBANK;
938
939 return error_status;
940 }
941
942 ps_mv_buf->pu4_mb_pu_cnt = (UWORD32 *) pu1_buf;
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530943 pu1_buf += num_mb * sizeof(WORD32);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530944
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530945 ps_mv_buf->pu1_pic_pu_map = pu1_buf;
946 pu1_buf += ALIGN4(num_pu);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530947
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530948 ps_mv_buf->ps_pic_pu = (enc_pu_t *) (pu1_buf);
949 pu1_buf += ALIGN4(num_pu * sizeof(enc_pu_t));
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530950
951 ret = ih264_buf_mgr_add((buf_mgr_t *) ps_codec->pv_mv_buf_mgr,
952 ps_mv_buf, i);
953
954 if (IH264_SUCCESS != ret)
955 {
956 ps_codec->i4_error_code = IH264E_BUF_MGR_ERROR;
957 error_status = IH264E_BUF_MGR_ERROR;
958 return error_status;
959 }
960
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530961 ps_mv_buf++;
962 i++;
963 }
964
965 return error_status;
966}
967
968/**
969*******************************************************************************
970*
971* @brief Function to initialize quant params structure
972*
973* @par Description:
974* The forward quantization modules depends on qp/6, qp mod 6, forward scale
975* matrix, forward threshold matrix, weight list. The inverse quantization
976* modules depends on qp/6, qp mod 6, inverse scale matrix, weight list.
977* These params are initialized in this function.
978*
979* @param[in] ps_proc
980* pointer to process context
981*
982* @param[in] qp
983* quantization parameter
984*
985* @returns none
986*
987* @remarks
988*
989*******************************************************************************
990*/
991void ih264e_init_quant_params(process_ctxt_t *ps_proc, int qp)
992{
993 /* quant params */
994 quant_params_t *ps_qp_params;
995
996 /* ptr to forward quant threshold matrix */
997 const UWORD16 *pu2_thres_mat = NULL;
998
999 /* ptr to forward scale matrix */
1000 const UWORD16 *pu2_scale_mat = gu2_quant_scale_matrix_4x4;
1001
1002 /* ptr to inverse scale matrix */
1003 const UWORD16 *pu2_iscale_mat = gau2_ih264_iquant_scale_matrix_4x4;
1004
1005 /* temp var */
1006 UWORD32 u4_qp[3], u4_qp_div6, u4_qp_mod6;
1007 COMPONENT_TYPE plane;
1008 WORD32 i;
1009 UWORD32 u4_satdq_t;
1010 const UWORD16 *pu2_smat;
1011
1012 /********************************************************************/
1013 /* init quant params for all planes Y, U and V */
1014 /********************************************************************/
1015 /* luma qp */
1016 u4_qp[Y] = qp;
1017
1018 /* chroma qp
1019 * TODO_LATER : just in case if the chroma planes use different qp's this
1020 * needs to be corrected accordingly.
1021 */
1022 u4_qp[U] = gu1_qpc_fqpi[qp];
1023 u4_qp[V] = gu1_qpc_fqpi[qp];
1024
1025 plane = Y;
1026 while (plane <= V)
1027 {
1028 u4_qp_div6 = (u4_qp[plane] / 6);
1029 u4_qp_mod6 = (u4_qp[plane] % 6);
1030
1031 ps_qp_params = ps_proc->ps_qp_params[plane];
1032
1033 /* mb qp */
1034 ps_qp_params->u1_mb_qp = u4_qp[plane];
1035
1036 /* mb qp / 6 */
1037 ps_qp_params->u1_qp_div = u4_qp_div6;
1038
1039 /* mb qp % 6 */
1040 ps_qp_params->u1_qp_rem = u4_qp_mod6;
1041
1042 /* QP bits */
1043 ps_qp_params->u1_qbits = QP_BITS_h264_4x4 + u4_qp_div6;
1044
1045 /* forward scale matrix */
1046 ps_qp_params->pu2_scale_mat = pu2_scale_mat + (u4_qp_mod6 * 16);
1047
1048 /* threshold matrix & weight for quantization */
1049 pu2_thres_mat = gu2_forward_quant_threshold_4x4 + (u4_qp_mod6 * 16);
1050 for (i = 0; i < 16; i++)
1051 {
1052 ps_qp_params->pu2_thres_mat[i] = pu2_thres_mat[i]
1053 >> (8 - u4_qp_div6);
1054 ps_qp_params->pu2_weigh_mat[i] = 16;
1055 }
1056
1057 /* qp dependent rounding constant */
1058 ps_qp_params->u4_dead_zone =
1059 gu4_forward_quant_round_factor_4x4[u4_qp_div6];
1060
1061 /* slice dependent rounding constant */
1062 if (ps_proc->i4_slice_type != ISLICE
1063 && ps_proc->i4_slice_type != SISLICE)
1064 {
1065 ps_qp_params->u4_dead_zone >>= 1;
1066 }
1067
1068 /* SATQD threshold for zero block prediction */
1069 if (ps_proc->ps_codec->s_cfg.u4_enable_satqd)
1070 {
1071 pu2_smat = ps_qp_params->pu2_scale_mat;
1072
1073 u4_satdq_t = ((1 << (ps_qp_params->u1_qbits)) - ps_qp_params->u4_dead_zone);
1074
1075 ps_qp_params->pu2_sad_thrsh[0] = u4_satdq_t / MAX(pu2_smat[3], pu2_smat[11]);
1076 ps_qp_params->pu2_sad_thrsh[1] = u4_satdq_t / MAX(pu2_smat[1], pu2_smat[9]);
1077 ps_qp_params->pu2_sad_thrsh[2] = u4_satdq_t / pu2_smat[15];
1078 ps_qp_params->pu2_sad_thrsh[3] = u4_satdq_t / pu2_smat[7];
1079 ps_qp_params->pu2_sad_thrsh[4] = u4_satdq_t / MAX(pu2_smat[12], pu2_smat[14]);
1080 ps_qp_params->pu2_sad_thrsh[5] = u4_satdq_t / MAX(pu2_smat[4], pu2_smat[6]);
1081 ps_qp_params->pu2_sad_thrsh[6] = u4_satdq_t / pu2_smat[13];
1082 ps_qp_params->pu2_sad_thrsh[7] = u4_satdq_t / pu2_smat[5];
1083 ps_qp_params->pu2_sad_thrsh[8] = u4_satdq_t / MAX(MAX3(pu2_smat[0], pu2_smat[2], pu2_smat[8]), pu2_smat[10]);
1084 }
1085
1086 /* inverse scale matrix */
1087 ps_qp_params->pu2_iscale_mat = pu2_iscale_mat + (u4_qp_mod6 * 16);
1088
1089 plane += 1;
1090 }
1091 return ;
1092}
1093
1094/**
1095*******************************************************************************
1096*
1097* @brief
1098* Initialize AIR mb frame Map
1099*
1100* @par Description:
1101* Initialize AIR mb frame map
1102* MB frame map indicates which frame an Mb should be coded as intra according to AIR
1103*
1104* @param[in] ps_codec
1105* Pointer to codec context
1106*
1107* @returns error_status
1108*
1109* @remarks
1110*
1111*
1112*******************************************************************************
1113*/
1114IH264E_ERROR_T ih264e_init_air_map(codec_t *ps_codec)
1115{
1116 /* intra refresh map */
1117 UWORD16 *pu2_intr_rfrsh_map = ps_codec->pu2_intr_rfrsh_map;
1118
1119 /* air mode */
1120 IVE_AIR_MODE_T air_mode = ps_codec->s_cfg.e_air_mode;
1121
1122 /* refresh period */
1123 UWORD32 air_period = ps_codec->s_cfg.u4_air_refresh_period;
1124
1125 /* mb cnt */
1126 UWORD32 u4_mb_cnt = ps_codec->s_cfg.i4_wd_mbs * ps_codec->s_cfg.i4_ht_mbs;
1127
1128 /* temp var */
1129 UWORD32 curr_mb, seed_rand = 1;
1130
1131 switch (air_mode)
1132 {
1133 case IVE_AIR_MODE_CYCLIC:
1134
1135 for (curr_mb = 0; curr_mb < u4_mb_cnt; curr_mb++)
1136 {
1137 pu2_intr_rfrsh_map[curr_mb] = curr_mb % air_period;
1138 }
1139 break;
1140
1141 case IVE_AIR_MODE_RANDOM:
1142
1143 for (curr_mb = 0; curr_mb < u4_mb_cnt; curr_mb++)
1144 {
1145 seed_rand = (seed_rand * 32719 + 3) % 32749;
1146 pu2_intr_rfrsh_map[curr_mb] = seed_rand % air_period;
1147 }
1148 break;
1149
1150 default:
1151
1152 break;
1153 }
1154
1155 return IH264E_SUCCESS;
1156}
1157
1158/**
1159*******************************************************************************
1160*
1161* @brief
1162* Codec level initializations
1163*
1164* @par Description:
1165* Initializes the codec with parameters that needs to be set before encoding
1166* first frame
1167*
1168* @param[in] ps_codec
1169* Pointer to codec context
1170*
1171* @param[in] ps_inp_buf
1172* Pointer to input buffer context
1173*
1174* @returns error_status
1175*
1176* @remarks
1177*
1178*
1179*******************************************************************************
1180*/
1181IH264E_ERROR_T ih264e_codec_init(codec_t *ps_codec)
1182{
1183 /********************************************************************
1184 * INITIALIZE CODEC CONTEXT *
1185 ********************************************************************/
1186 /* encoder presets */
1187 if (ps_codec->s_cfg.u4_enc_speed_preset != IVE_CONFIG)
1188 {
1189 if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
1190 {/* high quality */
1191 /* enable diamond search */
1192 ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
1193 ps_codec->s_cfg.u4_enable_fast_sad = 0;
1194
1195 /* disable intra 4x4 */
1196 ps_codec->s_cfg.u4_enable_intra_4x4 = 1;
1197 ps_codec->luma_energy_compaction[1] =
1198 ih264e_code_luma_intra_macroblock_4x4_rdopt_on;
1199
1200 /* sub pel off */
1201 ps_codec->s_cfg.u4_enable_hpel = 1;
1202
1203 /* deblocking off */
1204 ps_codec->s_cfg.u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0;
1205
1206 /* disabled intra inter gating in Inter slices */
1207 ps_codec->u4_inter_gate = 0;
1208 }
1209 else if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_NORMAL)
1210 {/* normal */
1211 /* enable diamond search */
1212 ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
1213 ps_codec->s_cfg.u4_enable_fast_sad = 0;
1214
1215 /* disable intra 4x4 */
1216 ps_codec->s_cfg.u4_enable_intra_4x4 = 1;
1217
1218 /* sub pel off */
1219 ps_codec->s_cfg.u4_enable_hpel = 1;
1220
1221 /* deblocking off */
1222 ps_codec->s_cfg.u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0;
1223
1224 /* disabled intra inter gating in Inter slices */
1225 ps_codec->u4_inter_gate = 0;
1226 }
1227 else if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_FAST)
1228 {/* normal */
1229 /* enable diamond search */
1230 ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
1231 ps_codec->s_cfg.u4_enable_fast_sad = 0;
1232
1233 /* disable intra 4x4 */
1234 ps_codec->s_cfg.u4_enable_intra_4x4 = 0;
1235
1236 /* sub pel off */
1237 ps_codec->s_cfg.u4_enable_hpel = 1;
1238
1239 /* deblocking off */
1240 ps_codec->s_cfg.u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0;
1241
1242 /* disabled intra inter gating in Inter slices */
1243 ps_codec->u4_inter_gate = 1;
1244 }
1245 else if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_HIGH_SPEED)
1246 {/* fast */
1247 /* enable diamond search */
1248 ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
1249 ps_codec->s_cfg.u4_enable_fast_sad = 0;
1250
1251 /* disable intra 4x4 */
1252 ps_codec->s_cfg.u4_enable_intra_4x4 = 0;
1253
1254 /* sub pel off */
1255 ps_codec->s_cfg.u4_enable_hpel = 0;
1256
1257 /* deblocking off */
1258 ps_codec->s_cfg.u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4;
1259
1260 /* disabled intra inter gating in Inter slices */
1261 ps_codec->u4_inter_gate = 0;
1262 }
1263 else if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_FASTEST)
1264 {/* fastest */
1265 /* enable diamond search */
1266 ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
1267
1268 /* disable intra 4x4 */
1269 ps_codec->s_cfg.u4_enable_intra_4x4 = 0;
1270
1271 /* sub pel off */
1272 ps_codec->s_cfg.u4_enable_hpel = 0;
1273
1274 /* deblocking off */
1275 ps_codec->s_cfg.u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4;
1276
1277 /* disabled intra inter gating in Inter slices */
1278 ps_codec->u4_inter_gate = 1;
1279 }
1280 }
1281
1282 /*****************************************************************
1283 * Initialize AIR inside codec
1284 *****************************************************************/
1285 if (IVE_AIR_MODE_NONE != ps_codec->s_cfg.e_air_mode)
1286 {
1287 ih264e_init_air_map(ps_codec);
1288
1289 ps_codec->i4_air_pic_cnt = -1;
1290 }
1291
1292 /****************************************************/
1293 /* INITIALIZE RATE CONTROL */
1294 /****************************************************/
1295 {
1296 /* init qp */
1297 UWORD8 au1_init_qp[MAX_PIC_TYPE];
1298
1299 /* min max qp */
1300 UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE];
1301
1302 /* init i,p,b qp */
1303 au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp];
1304 au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp];
1305 au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp];
1306
1307 /* init min max qp */
1308 au1_min_max_qp[2 * I_PIC] =
1309 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_min];
1310 au1_min_max_qp[2 * I_PIC + 1] =
1311 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_max];
1312
1313 au1_min_max_qp[2 * P_PIC] =
1314 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_min];
1315 au1_min_max_qp[2 * P_PIC + 1] =
1316 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_max];
1317
1318 au1_min_max_qp[2 * B_PIC] =
1319 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_min];
1320 au1_min_max_qp[2 * B_PIC + 1] =
1321 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_max];
1322
1323 /* get rc mode */
1324 switch (ps_codec->s_cfg.e_rc_mode)
1325 {
1326 case IVE_RC_STORAGE:
1327 ps_codec->s_rate_control.e_rc_type = VBR_STORAGE;
1328 break;
1329 case IVE_RC_CBR_NON_LOW_DELAY:
1330 ps_codec->s_rate_control.e_rc_type = CBR_NLDRC;
1331 break;
1332 case IVE_RC_CBR_LOW_DELAY:
1333 ps_codec->s_rate_control.e_rc_type = CBR_LDRC;
1334 break;
1335 case IVE_RC_NONE:
1336 ps_codec->s_rate_control.e_rc_type = CONST_QP;
1337 break;
1338 default:
1339 break;
1340 }
1341
1342 /* init rate control */
1343 ih264e_rc_init(ps_codec->s_rate_control.pps_rate_control_api,
1344 ps_codec->s_rate_control.pps_frame_time,
1345 ps_codec->s_rate_control.pps_time_stamp,
1346 ps_codec->s_rate_control.pps_pd_frm_rate,
1347 ps_codec->s_cfg.u4_max_framerate,
1348 ps_codec->s_cfg.u4_src_frame_rate,
1349 ps_codec->s_cfg.u4_tgt_frame_rate,
1350 ps_codec->s_rate_control.e_rc_type,
1351 ps_codec->s_cfg.u4_target_bitrate,
1352 ps_codec->s_cfg.u4_max_bitrate,
1353 ps_codec->s_cfg.u4_vbv_buffer_delay,
Harinarayanan K K134291e2015-06-18 16:03:38 +05301354 ps_codec->s_cfg.u4_i_frm_interval,
1355 ps_codec->s_cfg.u4_num_bframes + 1, au1_init_qp,
1356 ps_codec->s_cfg.u4_num_bframes + 2 , au1_min_max_qp,
Martin Storsjocc58d3f2015-06-27 20:56:24 +03001357 MAX(ps_codec->s_cfg.u4_max_level,
1358 (UWORD32)ih264e_get_min_level(ps_codec->s_cfg.u4_max_wd, ps_codec->s_cfg.u4_max_ht)));
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301359 }
1360
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301361 /* recon stride */
1362 ps_codec->i4_rec_strd = ALIGN16(ps_codec->s_cfg.u4_max_wd) + PAD_WD;
1363
1364 /* max ref and reorder cnt */
1365 ps_codec->i4_ref_buf_cnt = ps_codec->s_cfg.u4_max_ref_cnt
1366 + ps_codec->s_cfg.u4_max_reorder_cnt;
1367 ps_codec->i4_ref_buf_cnt += MAX_CTXT_SETS;
1368
1369 DEBUG_HISTOGRAM_INIT();
1370
Harinarayanan K K134291e2015-06-18 16:03:38 +05301371
1372 /* Init dependecy vars */
1373 ps_codec->i4_last_inp_buff_received = 0;
1374
Harinarayanan K Kaad45872015-06-26 15:20:33 +05301375 /* At codec start no IDR is pending */
1376 ps_codec->i4_pending_idr_flag = 0;
Harinarayanan K K134291e2015-06-18 16:03:38 +05301377
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301378 return IH264E_SUCCESS;
1379}
1380
1381/**
1382*******************************************************************************
1383*
1384* @brief
1385* Picture level initializations
1386*
1387* @par Description:
1388* Before beginning to encode the frame, the current function initializes all
1389* the ctxts (proc, entropy, me, ...) basing on the input configured params.
1390* It locates space for storing recon in the encoder picture buffer set, fetches
1391* reference frame from encoder picture buffer set. Calls RC pre-enc to get
1392* qp and pic type for the current frame. Queues proc jobs so that
1393* the other threads can begin encoding. In brief, this function sets up the
1394* tone for the entire encoder.
1395*
1396* @param[in] ps_codec
1397* Pointer to codec context
1398*
1399* @param[in] ps_inp_buf
1400* Pointer to input buffer context
1401*
1402* @returns error_status
1403*
1404* @remarks
1405*
1406*
1407*******************************************************************************
1408*/
1409IH264E_ERROR_T ih264e_pic_init(codec_t *ps_codec, inp_buf_t *ps_inp_buf)
1410{
1411 /* error status */
1412 IH264E_ERROR_T error_status = IH264E_SUCCESS;
1413 IH264_ERROR_T ret = IH264_SUCCESS;
1414
1415 /* mv buff bank */
1416 mv_buf_t *ps_mv_buf = NULL;
1417 WORD32 cur_mv_bank_buf_id;
1418
1419 /* recon buffer set */
1420 pic_buf_t *ps_cur_pic;
1421 WORD32 cur_pic_buf_id;
1422 UWORD8 *pu1_cur_pic_luma, *pu1_cur_pic_chroma;
1423
1424 /* ref buffer set */
Harinarayanan K K134291e2015-06-18 16:03:38 +05301425 pic_buf_t *aps_ref_pic[MAX_REF_PIC_CNT] = {NULL, NULL};
1426 mv_buf_t *aps_mv_buf[MAX_REF_PIC_CNT] = {NULL, NULL};
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301427 WORD32 ref_set_id;
1428
1429 /* pic time stamp */
1430 UWORD32 u4_timestamp_high = ps_inp_buf->u4_timestamp_high;
1431 UWORD32 u4_timestamp_low = ps_inp_buf->u4_timestamp_low;
1432
1433 /* indices to access curr/prev frame info */
Harinarayanan K K6cb67722015-06-19 14:44:42 +05301434 WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301435
1436 /* curr pic type */
1437 PIC_TYPE_T *pic_type = &ps_codec->pic_type;
1438
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301439 /* Diamond search Iteration Max Cnt */
1440 UWORD32 u4_num_layers =
1441 (ps_codec->s_cfg.u4_enc_speed_preset == IVE_FASTEST) ?
1442 (NUM_LAYERS >> 2) : NUM_LAYERS;
1443
1444 /* enable fast sad */
1445 UWORD32 u4_enable_fast_sad = ps_codec->s_cfg.u4_enable_fast_sad;
1446
1447 /********************************************************************/
1448 /* INITIALIZE CODEC CONTEXT */
1449 /********************************************************************/
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301450 /* slice_type */
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301451 if ((PIC_I == *pic_type) || (PIC_IDR == *pic_type))
1452 {
1453 ps_codec->i4_slice_type = ISLICE;
1454 }
1455 else if (PIC_P == *pic_type)
1456 {
1457 ps_codec->i4_slice_type = PSLICE;
1458 }
Harinarayanan K K134291e2015-06-18 16:03:38 +05301459 else if(PIC_B == *pic_type)
1460 {
1461 ps_codec->i4_slice_type = BSLICE;
1462 }
1463
1464
1465 /***************************************************************************
1466 * Set up variables for sending frame number, poc and reference
1467 * a) Set up alt ref too
1468 **************************************************************************/
1469
Harinarayanan K K134291e2015-06-18 16:03:38 +05301470 /* Check and set if the current frame is reference or not */
1471 ps_codec->u4_is_curr_frm_ref = 0;
1472
1473 /* This frame is reference if its not a B pic, pending approval from alt ref */
1474 ps_codec->u4_is_curr_frm_ref = (*pic_type != PIC_B);
1475
1476 /* In case if its a P pic, we will decide according to alt ref also */
1477 if (ps_codec->s_cfg.u4_enable_alt_ref && (*pic_type == PIC_P)
1478 && (ps_codec->i4_pic_cnt
1479 % (ps_codec->s_cfg.u4_enable_alt_ref + 1)))
1480 {
1481 ps_codec->u4_is_curr_frm_ref = 0;
1482 }
1483
1484 /*
1485 * Override everything in case of IDR
1486 * Note that in case of IDR, at this point ps_codec->u4_is_curr_frm_ref must
1487 * be 1
1488 */
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301489
1490 /* is this an IDR pic */
1491 ps_codec->u4_is_idr = 0;
1492
1493 if (PIC_IDR == *pic_type)
1494 {
1495 /* set idr flag */
1496 ps_codec->u4_is_idr = 1;
1497
1498 /* reset frame num */
1499 ps_codec->i4_frame_num = 0;
1500
1501 /* idr_pic_id */
1502 ps_codec->i4_idr_pic_id++;
1503 }
1504
Harinarayanan K K134291e2015-06-18 16:03:38 +05301505 /***************************************************************************
1506 * Set up Deblock
1507 **************************************************************************/
1508
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301509 /* set deblock disable flags based on disable deblock level */
1510 ps_codec->i4_disable_deblk_pic = 1;
1511
1512 if (ps_codec->s_cfg.u4_disable_deblock_level == DISABLE_DEBLK_LEVEL_0)
1513 {
1514 /* enable deblocking */
1515 ps_codec->i4_disable_deblk_pic = 0;
1516 }
1517 else if (ps_codec->s_cfg.u4_disable_deblock_level == DISABLE_DEBLK_LEVEL_2)
1518 {
1519 /* enable deblocking after a period of frames */
1520 if (ps_codec->i4_disable_deblk_pic_cnt == DISABLE_DEBLOCK_INTERVAL
1521 || ps_codec->i4_slice_type == ISLICE)
1522 {
1523 ps_codec->i4_disable_deblk_pic = 0;
1524 }
1525 }
1526 else if (ps_codec->s_cfg.u4_disable_deblock_level == DISABLE_DEBLK_LEVEL_3)
1527 {
1528 if (ps_codec->i4_slice_type == ISLICE)
1529 {
1530 ps_codec->i4_disable_deblk_pic = 0;
1531 }
1532 }
1533
1534 if (ps_codec->i4_disable_deblk_pic)
1535 {
1536 ps_codec->i4_disable_deblk_pic_cnt++;
1537 }
1538 else
1539 {
1540 ps_codec->i4_disable_deblk_pic_cnt = 0;
1541 }
1542
1543 /* In slice mode - lets not deblk mb edges that lie along slice boundaries */
1544 if (ps_codec->i4_disable_deblk_pic == 0)
1545 {
1546 if (ps_codec->s_cfg.e_slice_mode != IVE_SLICE_MODE_NONE)
1547 {
1548 ps_codec->i4_disable_deblk_pic = 2;
1549 }
1550 }
1551
1552 /* error status */
1553 ps_codec->i4_error_code = IH264E_SUCCESS;
1554
1555 /* populate header */
1556 if (ps_codec->i4_gen_header)
1557 {
1558 /* sps */
1559 sps_t *ps_sps = NULL;
1560
1561 /* pps */
1562 pps_t *ps_pps = NULL;
1563
1564 /*ps_codec->i4_pps_id ++;*/
1565 ps_codec->i4_pps_id %= MAX_PPS_CNT;
1566
1567 /*ps_codec->i4_sps_id ++;*/
1568 ps_codec->i4_sps_id %= MAX_SPS_CNT;
1569
1570 /* populate sps header */
1571 ps_sps = ps_codec->ps_sps_base + ps_codec->i4_sps_id;
1572 ih264e_populate_sps(ps_codec, ps_sps);
1573
1574 /* populate pps header */
1575 ps_pps = ps_codec->ps_pps_base + ps_codec->i4_pps_id;
1576 ih264e_populate_pps(ps_codec, ps_pps);
1577 }
1578
Harinarayanan K K134291e2015-06-18 16:03:38 +05301579 /***************************************************************************
1580 * Reference and MV bank Buffer Manager
1581 * Here we will
1582 * 1) Find the correct ref pics for the current frame
1583 * 2) Free the ref pic that is not going to be used anywhere
1584 * 3) Find a free buff from the list and assign it as the recon of
1585 * current frame
1586 *
1587 * 1) Finding correct ref pic
1588 * All pics needed for future are arranged in a picture list called
1589 * ps_codec->as_ref_set. Each picture in this will have a pic buffer and
1590 * MV buffer that is marked appropriately as BUF_MGR_REF, BUF_MGR_IO or
1591 * BUF_MGR_CODEC. Also the pic_cnt and poc will also be present.
1592 * Hence to find the ref pic we will loop through the list and find
1593 * 2 pictures with maximum i4_pic_cnt .
1594 *
1595 * note that i4_pic_cnt == -1 is used to filter uninit ref pics.
1596 * Now since we only have max two ref pics, we will always find max 2
1597 * ref pics.
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301598
Harinarayanan K K134291e2015-06-18 16:03:38 +05301599 *
1600 * 2) 3) Self explanatory
1601 ***************************************************************************/
1602 {
1603 /* Search for buffs with maximum pic cnt */
1604
1605 WORD32 max_pic_cnt[] = { -1, -1 };
1606
1607 mv_buf_t *ps_mv_buf_to_free[] = { NULL, NULL };
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301608
1609 /* temp var */
Harinarayanan K K134291e2015-06-18 16:03:38 +05301610 WORD32 i, buf_status;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301611
1612 for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
1613 {
Harinarayanan K K134291e2015-06-18 16:03:38 +05301614 if (ps_codec->as_ref_set[i].i4_pic_cnt == -1)
1615 continue;
1616
1617 buf_status = ih264_buf_mgr_get_status(
1618 ps_codec->pv_ref_buf_mgr,
1619 ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
1620
1621 /* Ideally we should look for buffer status of MV BUFF also. But since
1622 * the correponding MV buffs also will be at the same state. It dosent
1623 * matter as of now. But the check will make the logic better */
1624 if ((max_pic_cnt[0] < ps_codec->as_ref_set[i].i4_pic_cnt)
1625 && (buf_status & BUF_MGR_REF))
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301626 {
Harinarayanan K K134291e2015-06-18 16:03:38 +05301627 if (max_pic_cnt[1] < ps_codec->as_ref_set[i].i4_pic_cnt)
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301628 {
Harinarayanan K K134291e2015-06-18 16:03:38 +05301629 max_pic_cnt[0] = max_pic_cnt[1];
1630 aps_ref_pic[0] = aps_ref_pic[1];
1631 aps_mv_buf[0] = aps_mv_buf[1];
1632
1633 ps_mv_buf_to_free[0] = ps_mv_buf_to_free[1];
1634
1635 max_pic_cnt[1] = ps_codec->as_ref_set[i].i4_pic_cnt;
1636 aps_ref_pic[1] = ps_codec->as_ref_set[i].ps_pic_buf;
1637 aps_mv_buf[1] = ps_codec->as_ref_set[i].ps_mv_buf;
1638 ps_mv_buf_to_free[1] = ps_codec->as_ref_set[i].ps_mv_buf;
1639
1640 }
1641 else
1642 {
1643 max_pic_cnt[0] = ps_codec->as_ref_set[i].i4_pic_cnt;
1644 aps_ref_pic[0] = ps_codec->as_ref_set[i].ps_pic_buf;
1645 aps_mv_buf[0] = ps_codec->as_ref_set[i].ps_mv_buf;
1646 ps_mv_buf_to_free[0] = ps_codec->as_ref_set[i].ps_mv_buf;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301647 }
1648 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301649 }
1650
Harinarayanan K K134291e2015-06-18 16:03:38 +05301651 /*
1652 * Now if the current picture is I or P, we discard the back ref pic and
1653 * assign forward ref as backward ref
1654 */
1655 if (*pic_type != PIC_B)
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301656 {
Harinarayanan K K134291e2015-06-18 16:03:38 +05301657 if (ps_mv_buf_to_free[0])
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301658 {
Harinarayanan K K134291e2015-06-18 16:03:38 +05301659 /* release this frame from reference list */
1660 ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr,
1661 ps_mv_buf_to_free[0]->i4_buf_id,
1662 BUF_MGR_REF);
1663
1664 ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr,
1665 aps_ref_pic[0]->i4_buf_id, BUF_MGR_REF);
1666 }
1667
1668 max_pic_cnt[0] = max_pic_cnt[1];
1669 aps_ref_pic[0] = aps_ref_pic[1];
1670 aps_mv_buf[0] = aps_mv_buf[1];
1671
1672 /* Dummy */
1673 max_pic_cnt[1] = -1;
1674 }
1675
1676 /*
1677 * Mark all reference pic with unused buffers to be free
1678 * We need this step since each one, ie ref, recon io etc only unset their
1679 * respective flags. Hence we need to combine togather and mark the ref set
1680 * accordingly
1681 */
1682 ref_set_id = -1;
1683 for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
1684 {
1685 if (ps_codec->as_ref_set[i].i4_pic_cnt == -1)
1686 {
1687 ref_set_id = i;
1688 continue;
1689 }
1690
1691 buf_status = ih264_buf_mgr_get_status(
1692 ps_codec->pv_ref_buf_mgr,
1693 ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
1694
1695 if ((buf_status & (BUF_MGR_REF | BUF_MGR_CODEC | BUF_MGR_IO)) == 0)
1696 {
1697 ps_codec->as_ref_set[i].i4_pic_cnt = -1;
1698 ps_codec->as_ref_set[i].i4_poc = 32768;
1699
1700 ref_set_id = i;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301701 }
1702 }
Harinarayanan K K134291e2015-06-18 16:03:38 +05301703 /* An asssert failure here means we donot have any free buffs */
1704 ASSERT(ref_set_id >= 0);
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301705 }
1706
1707 {
1708 /*****************************************************************/
1709 /* Get free MV Bank to hold current picture's motion vector data */
1710 /* If there are no free buffers then return with an error code. */
1711 /* If the buffer is to be freed by another thread, change the */
1712 /* following to call thread yield and wait for buffer to be freed*/
1713 /*****************************************************************/
1714 ps_mv_buf = (mv_buf_t *) ih264_buf_mgr_get_next_free(
1715 (buf_mgr_t *) ps_codec->pv_mv_buf_mgr,
1716 &cur_mv_bank_buf_id);
1717
1718 if (NULL == ps_mv_buf)
1719 {
1720 ps_codec->i4_error_code = IH264E_NO_FREE_MVBANK;
1721 return IH264E_NO_FREE_MVBANK;
1722 }
1723
1724 /* mark the buffer as needed for reference if the curr pic is available for ref */
1725 if (ps_codec->u4_is_curr_frm_ref)
1726 {
1727 ih264_buf_mgr_set_status(ps_codec->pv_mv_buf_mgr,
1728 cur_mv_bank_buf_id, BUF_MGR_REF);
1729 }
1730
1731 /* Set current ABS poc to ps_mv_buf, so that while freeing a reference buffer
1732 * corresponding mv buffer can be found by looping through ps_codec->ps_mv_buf array
1733 * and getting a buffer id to free
1734 */
1735 ps_mv_buf->i4_abs_poc = ps_codec->i4_abs_pic_order_cnt;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301736 ps_mv_buf->i4_buf_id = cur_mv_bank_buf_id;
1737 }
1738
1739 {
1740 /*****************************************************************/
1741 /* Get free pic buf to hold current picture's recon data */
1742 /* If there are no free buffers then return with an error code. */
1743 /* If the buffer is to be freed by another thread, change the */
1744 /* following to call thread yield and wait for buffer to be freed*/
1745 /*****************************************************************/
1746 ps_cur_pic = (pic_buf_t *) ih264_buf_mgr_get_next_free(
1747 (buf_mgr_t *) ps_codec->pv_ref_buf_mgr,
1748 &cur_pic_buf_id);
1749
1750 if (NULL == ps_cur_pic)
1751 {
1752 ps_codec->i4_error_code = IH264E_NO_FREE_PICBUF;
1753 return IH264E_NO_FREE_PICBUF;
1754 }
1755
1756 /* mark the buffer as needed for reference if the curr pic is available for ref */
Harinarayanan K K134291e2015-06-18 16:03:38 +05301757 if (ps_codec->u4_is_curr_frm_ref)
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301758 {
1759 ih264_buf_mgr_set_status(ps_codec->pv_ref_buf_mgr, cur_pic_buf_id,
1760 BUF_MGR_REF);
1761 }
1762
1763 /* Mark the current buffer as needed for IO if recon is enabled */
1764 if (1 == ps_codec->s_cfg.u4_enable_recon)
1765 {
1766 ih264_buf_mgr_set_status(ps_codec->pv_ref_buf_mgr, cur_pic_buf_id,
1767 BUF_MGR_IO);
1768 }
1769
1770 /* Associate input timestamp with current buffer */
1771 ps_cur_pic->u4_timestamp_high = ps_inp_buf->u4_timestamp_high;
1772 ps_cur_pic->u4_timestamp_low = ps_inp_buf->u4_timestamp_low;
1773
Harinarayanan K K134291e2015-06-18 16:03:38 +05301774 ps_cur_pic->i4_abs_poc = ps_codec->i4_poc;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301775 ps_cur_pic->i4_poc_lsb = ps_codec->i4_pic_order_cnt_lsb;
1776
1777 ps_cur_pic->i4_buf_id = cur_pic_buf_id;
1778
1779 pu1_cur_pic_luma = ps_cur_pic->pu1_luma;
1780 pu1_cur_pic_chroma = ps_cur_pic->pu1_chroma;
1781 }
1782
Harinarayanan K K134291e2015-06-18 16:03:38 +05301783 /*
1784 * Add the current picture to ref list independent of the fact that it is used
1785 * as reference or not. This is because, now recon is not in sync with output
1786 * hence we may need the current recon after some delay. By adding it to ref list
1787 * we can retrieve the recon any time we want. The information that it is used
1788 * for ref can still be found by checking the buffer status of pic buf.
1789 */
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301790 {
1791 ps_codec->as_ref_set[ref_set_id].i4_pic_cnt = ps_codec->i4_pic_cnt;
Harinarayanan K K134291e2015-06-18 16:03:38 +05301792 ps_codec->as_ref_set[ref_set_id].i4_poc = ps_codec->i4_poc;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301793 ps_codec->as_ref_set[ref_set_id].ps_mv_buf = ps_mv_buf;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301794 ps_codec->as_ref_set[ref_set_id].ps_pic_buf = ps_cur_pic;
1795 }
1796
1797 /********************************************************************/
1798 /* INITIALIZE PROCESS CONTEXT */
1799 /********************************************************************/
1800 {
1801 /* temp var */
1802 WORD32 i, j = 0;
1803
1804 /* curr proc ctxt */
1805 process_ctxt_t *ps_proc = NULL;
1806
1807 j = ctxt_sel * MAX_PROCESS_THREADS;
1808
1809 /* begin init */
1810 for (i = j; i < (j + MAX_PROCESS_THREADS); i++)
1811 {
1812 ps_proc = &ps_codec->as_process[i];
1813
1814 /* luma src buffer */
1815 if (ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_422ILE)
1816 {
1817 ps_proc->pu1_src_buf_luma_base = ps_codec->pu1_y_csc_buf_base;
1818 }
1819 else
1820 {
1821 ps_proc->pu1_src_buf_luma_base =
1822 ps_inp_buf->s_raw_buf.apv_bufs[0];
1823 }
1824
1825 /* chroma src buffer */
1826 if (ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_422ILE
1827 || ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420P)
1828 {
1829 ps_proc->pu1_src_buf_chroma_base =
1830 ps_codec->pu1_uv_csc_buf_base;
1831 }
1832 else
1833 {
1834 ps_proc->pu1_src_buf_chroma_base =
1835 ps_inp_buf->s_raw_buf.apv_bufs[1];
1836 }
1837
1838 /* luma rec buffer */
1839 ps_proc->pu1_rec_buf_luma_base = pu1_cur_pic_luma;
1840
1841 /* chroma rec buffer */
1842 ps_proc->pu1_rec_buf_chroma_base = pu1_cur_pic_chroma;
1843
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301844 /* rec stride */
1845 ps_proc->i4_rec_strd = ps_codec->i4_rec_strd;
1846
1847 /* frame num */
1848 ps_proc->i4_frame_num = ps_codec->i4_frame_num;
1849
1850 /* is idr */
1851 ps_proc->u4_is_idr = ps_codec->u4_is_idr;
1852
1853 /* idr pic id */
1854 ps_proc->u4_idr_pic_id = ps_codec->i4_idr_pic_id;
1855
1856 /* slice_type */
1857 ps_proc->i4_slice_type = ps_codec->i4_slice_type;
1858
1859 /* Input width in mbs */
1860 ps_proc->i4_wd_mbs = ps_codec->s_cfg.i4_wd_mbs;
1861
1862 /* Input height in mbs */
1863 ps_proc->i4_ht_mbs = ps_codec->s_cfg.i4_ht_mbs;
1864
1865 /* Half x plane offset from pic buf */
1866 ps_proc->u4_half_x_offset = 0;
1867
1868 /* Half y plane offset from half x plane */
1869 ps_proc->u4_half_y_offset = 0;
1870
1871 /* Half x plane offset from half y plane */
1872 ps_proc->u4_half_xy_offset = 0;
1873
1874 /* top row syntax elements */
1875 ps_proc->ps_top_row_mb_syntax_ele =
1876 ps_proc->ps_top_row_mb_syntax_ele_base;
1877
1878 ps_proc->pu1_top_mb_intra_modes =
1879 ps_proc->pu1_top_mb_intra_modes_base;
1880
1881 ps_proc->ps_top_row_pu = ps_proc->ps_top_row_pu_base;
1882
1883 /* initialize quant params */
1884 ps_proc->u4_frame_qp = ps_codec->u4_frame_qp;
1885 ps_proc->u4_mb_qp = ps_codec->u4_frame_qp;
1886 ih264e_init_quant_params(ps_proc, ps_proc->u4_frame_qp);
1887
1888 /* previous mb qp*/
1889 ps_proc->u4_mb_qp_prev = ps_proc->u4_frame_qp;
1890
1891 /* Reset frame info */
1892 memset(&ps_proc->s_frame_info, 0, sizeof(frame_info_t));
1893
1894 /* initialize proc, deblk and ME map */
1895 if (i == j)
1896 {
1897 /* row '-1' */
1898 memset(ps_proc->pu1_proc_map - ps_proc->i4_wd_mbs, 1, ps_proc->i4_wd_mbs);
1899 /* row 0 to ht in mbs */
1900 memset(ps_proc->pu1_proc_map, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
1901
1902 /* row '-1' */
1903 memset(ps_proc->pu1_deblk_map - ps_proc->i4_wd_mbs, 1, ps_proc->i4_wd_mbs);
1904 /* row 0 to ht in mbs */
1905 memset(ps_proc->pu1_deblk_map, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
1906
1907 /* row '-1' */
1908 memset(ps_proc->pu1_me_map - ps_proc->i4_wd_mbs, 1, ps_proc->i4_wd_mbs);
1909 /* row 0 to ht in mbs */
1910 memset(ps_proc->pu1_me_map, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
1911
1912 /* at the start of air refresh period, reset intra coded map */
1913 if (IVE_AIR_MODE_NONE != ps_codec->s_cfg.e_air_mode)
1914 {
1915 ps_codec->i4_air_pic_cnt = (ps_codec->i4_air_pic_cnt + 1)
1916 % ps_codec->s_cfg.u4_air_refresh_period;
1917
1918 if (!ps_codec->i4_air_pic_cnt)
1919 {
1920 memset(ps_proc->pu1_is_intra_coded, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
1921 }
1922 }
1923 }
1924
1925 /* deblock level */
1926 ps_proc->u4_disable_deblock_level = ps_codec->i4_disable_deblk_pic;
1927
1928 /* slice index map */
1929 /* no slice */
1930 if (ps_codec->s_cfg.e_slice_mode == IVE_SLICE_MODE_NONE)
1931 {
1932 memset(ps_proc->pu1_slice_idx, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
1933 }
1934 /* generate slices for every 'n' rows, 'n' is given through slice param */
1935 else if (ps_codec->s_cfg.e_slice_mode == IVE_SLICE_MODE_BLOCKS)
1936 {
1937 /* slice idx map */
1938 UWORD8 *pu1_slice_idx = ps_proc->pu1_slice_idx;
1939
1940 /* temp var */
1941 WORD32 i4_mb_y = 0, slice_idx = 0, cnt;
1942
1943 while (i4_mb_y < ps_proc->i4_ht_mbs)
1944 {
1945 if (i4_mb_y +(WORD32)ps_codec->s_cfg.u4_slice_param < ps_proc->i4_ht_mbs)
1946 {
1947 cnt = ps_codec->s_cfg.u4_slice_param * ps_proc->i4_wd_mbs;
1948 i4_mb_y += ps_codec->s_cfg.u4_slice_param;
1949 }
1950 else
1951 {
1952 cnt = (ps_proc->i4_ht_mbs - i4_mb_y) * ps_proc->i4_wd_mbs;
1953 i4_mb_y += (ps_proc->i4_ht_mbs - i4_mb_y);
1954 }
1955 memset(pu1_slice_idx, slice_idx, cnt);
1956 slice_idx++;
1957 pu1_slice_idx += cnt;
1958 }
1959 }
1960
1961 /* Current MV Bank's buffer ID */
1962 ps_proc->i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id;
1963
1964 /* Pointer to current picture buffer structure */
1965 ps_proc->ps_cur_pic = ps_cur_pic;
1966
1967 /* Pointer to current pictures mv buffers */
1968 ps_proc->ps_cur_mv_buf = ps_mv_buf;
1969
Harinarayanan K K134291e2015-06-18 16:03:38 +05301970 /*
1971 * pointer to ref picture
1972 * 0 : Temporal back reference
1973 * 1 : Temporal forward reference
1974 */
1975 ps_proc->aps_ref_pic[PRED_L0] = aps_ref_pic[PRED_L0];
1976 ps_proc->aps_ref_pic[PRED_L1] = aps_ref_pic[PRED_L1];
1977 if (ps_codec->pic_type == PIC_B)
1978 {
1979 ps_proc->aps_mv_buf[PRED_L0] = aps_mv_buf[PRED_L0];
1980 ps_proc->aps_mv_buf[PRED_L1] = aps_mv_buf[PRED_L1];
1981 }
1982 else
1983 {
1984 /*
1985 * Else is dummy since for non B pic we does not need this
1986 * But an assignment here will help in not having a segfault
1987 * when we calcualte colpic in P slices
1988 */
1989 ps_proc->aps_mv_buf[PRED_L0] = ps_mv_buf;
1990 ps_proc->aps_mv_buf[PRED_L1] = ps_mv_buf;
1991 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301992
1993 if ((*pic_type != PIC_IDR) && (*pic_type != PIC_I))
1994 {
Harinarayanan K K134291e2015-06-18 16:03:38 +05301995 /* temporal back an forward ref pointer luma and chroma */
1996 ps_proc->apu1_ref_buf_luma_base[PRED_L0] = aps_ref_pic[PRED_L0]->pu1_luma;
1997 ps_proc->apu1_ref_buf_chroma_base[PRED_L0] = aps_ref_pic[PRED_L0]->pu1_chroma;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301998
Harinarayanan K K134291e2015-06-18 16:03:38 +05301999 ps_proc->apu1_ref_buf_luma_base[PRED_L1] = aps_ref_pic[PRED_L1]->pu1_luma;
2000 ps_proc->apu1_ref_buf_chroma_base[PRED_L1] = aps_ref_pic[PRED_L1]->pu1_chroma;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302001 }
2002
2003 /* Structure for current input buffer */
2004 ps_proc->s_inp_buf = *ps_inp_buf;
2005
2006 /* Number of encode frame API calls made */
2007 ps_proc->i4_encode_api_call_cnt = ps_codec->i4_encode_api_call_cnt;
2008
2009 /* Current Picture count */
2010 ps_proc->i4_pic_cnt = ps_codec->i4_pic_cnt;
2011
2012 /* error status */
2013 ps_proc->i4_error_code = 0;
2014
2015 /********************************************************************/
2016 /* INITIALIZE ENTROPY CONTEXT */
2017 /********************************************************************/
2018 {
2019 entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
2020
2021 /* start of frame */
2022 ps_entropy->i4_sof = 0;
2023
2024 /* end of frame */
2025 ps_entropy->i4_eof = 0;
2026
2027 /* generate header */
2028 ps_entropy->i4_gen_header = ps_codec->i4_gen_header;
2029
2030 /* sps ref_set_id */
2031 ps_entropy->u4_sps_id = ps_codec->i4_sps_id;
2032
2033 /* sps base */
2034 ps_entropy->ps_sps_base = ps_codec->ps_sps_base;
2035
2036 /* sps id */
2037 ps_entropy->u4_pps_id = ps_codec->i4_pps_id;
2038
2039 /* sps base */
2040 ps_entropy->ps_pps_base = ps_codec->ps_pps_base;
2041
2042 /* slice map */
2043 ps_entropy->pu1_slice_idx = ps_proc->pu1_slice_idx;
2044
2045 /* slice hdr base */
2046 ps_entropy->ps_slice_hdr_base = ps_proc->ps_slice_hdr_base;
2047
Harinarayanan K K134291e2015-06-18 16:03:38 +05302048 /* Abs poc */
2049 ps_entropy->i4_abs_pic_order_cnt = ps_proc->ps_codec->i4_poc;
2050
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302051 /* initialize entropy map */
2052 if (i == j)
2053 {
2054 /* row '-1' */
2055 memset(ps_entropy->pu1_entropy_map - ps_proc->i4_wd_mbs, 1, ps_proc->i4_wd_mbs);
2056 /* row 0 to ht in mbs */
2057 memset(ps_entropy->pu1_entropy_map, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
Harinarayanan K K134291e2015-06-18 16:03:38 +05302058
2059 /* intialize cabac tables */
2060 ih264e_init_cabac_table(ps_entropy);
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302061 }
2062
2063 /* wd in mbs */
2064 ps_entropy->i4_wd_mbs = ps_proc->i4_wd_mbs;
2065
2066 /* ht in mbs */
2067 ps_entropy->i4_ht_mbs = ps_proc->i4_ht_mbs;
2068
2069 /* transform_8x8_mode_flag */
2070 ps_entropy->i1_transform_8x8_mode_flag = 0;
2071
2072 /* entropy_coding_mode_flag */
2073 ps_entropy->u1_entropy_coding_mode_flag =
2074 ps_codec->s_cfg.u4_entropy_coding_mode;
2075
2076 /* error code */
2077 ps_entropy->i4_error_code = IH264E_SUCCESS;
2078
2079 /* mb skip run */
2080 *(ps_proc->s_entropy.pi4_mb_skip_run) = 0;
2081
2082 /* last frame to encode */
2083 ps_proc->s_entropy.u4_is_last = ps_inp_buf->u4_is_last;
2084
2085 /* Current Picture count */
2086 ps_proc->s_entropy.i4_pic_cnt = ps_codec->i4_pic_cnt;
2087
2088 /* time stamps */
2089 ps_entropy->u4_timestamp_low = u4_timestamp_low;
2090 ps_entropy->u4_timestamp_high = u4_timestamp_high;
2091
2092 /* init frame statistics */
2093 ps_entropy->u4_header_bits[MB_TYPE_INTRA] = 0;
2094 ps_entropy->u4_header_bits[MB_TYPE_INTER] = 0;
2095 ps_entropy->u4_residue_bits[MB_TYPE_INTRA] = 0;
2096 ps_entropy->u4_residue_bits[MB_TYPE_INTER] = 0;
2097 }
2098
2099 /********************************************************************/
2100 /* INITIALIZE DEBLOCK CONTEXT */
2101 /********************************************************************/
2102 {
2103 /* deblk ctxt */
2104 deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
2105
2106 /* slice idx map */
2107 ps_deblk->pu1_slice_idx = ps_proc->pu1_slice_idx;
2108 }
2109
2110 /********************************************************************/
2111 /* INITIALIZE ME CONTEXT */
2112 /********************************************************************/
2113 {
2114 /* me ctxt */
2115 me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
2116
2117 /* srch range x */
2118 ps_me_ctxt->ai2_srch_boundaries[0] =
2119 ps_codec->s_cfg.u4_srch_rng_x;
2120
2121 /* srch range y */
2122 ps_me_ctxt->ai2_srch_boundaries[1] =
2123 ps_codec->s_cfg.u4_srch_rng_y;
2124
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302125 /* rec stride */
2126 ps_me_ctxt->i4_rec_strd = ps_codec->i4_rec_strd;
2127
2128 /* Half x plane offset from pic buf */
2129 ps_me_ctxt->u4_half_x_offset = ps_proc->u4_half_x_offset;
2130
2131 /* Half y plane offset from half x plane */
2132 ps_me_ctxt->u4_half_y_offset = ps_proc->u4_half_y_offset;
2133
2134 /* Half x plane offset from half y plane */
2135 ps_me_ctxt->u4_half_xy_offset = ps_proc->u4_half_xy_offset;
2136
2137 /* enable fast sad */
2138 ps_me_ctxt->u4_enable_fast_sad = u4_enable_fast_sad;
2139
2140 /* half pel */
2141 ps_me_ctxt->u4_enable_hpel = ps_codec->s_cfg.u4_enable_hpel;
2142
2143 /* Diamond search Iteration Max Cnt */
2144 ps_me_ctxt->u4_num_layers = u4_num_layers;
2145
2146 /* me speed preset */
2147 ps_me_ctxt->u4_me_speed_preset =
2148 ps_codec->s_cfg.u4_me_speed_preset;
2149
2150 /* qp */
2151 ps_me_ctxt->u1_mb_qp = ps_codec->u4_frame_qp;
2152
Harinarayanan K K134291e2015-06-18 16:03:38 +05302153 if ((i == j) && (0 == ps_codec->i4_poc))
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302154 {
2155 /* init mv bits tables */
2156 ih264e_init_mv_bits(ps_me_ctxt);
2157 }
2158 }
2159
2160 ps_proc->ps_ngbr_avbl = &(ps_proc->s_ngbr_avbl);
2161
2162 }
2163
2164 /* reset encoder header */
2165 ps_codec->i4_gen_header = 0;
2166 }
2167
2168 /********************************************************************/
2169 /* ADD JOBS TO THE QUEUE */
2170 /********************************************************************/
2171 {
2172 /* job structures */
2173 job_t s_job;
2174
2175 /* temp var */
2176 WORD32 i;
2177
2178 /* job class */
2179 s_job.i4_cmd = CMD_PROCESS;
2180
2181 /* number of mbs to be processed in the current job */
2182 s_job.i2_mb_cnt = ps_codec->s_cfg.i4_wd_mbs;
2183
2184 /* job start index x */
2185 s_job.i2_mb_x = 0;
2186
2187 /* proc base idx */
2188 s_job.i2_proc_base_idx = ctxt_sel ? (MAX_PROCESS_CTXT / 2) : 0;
2189
2190 for (i = 0; i < (WORD32)ps_codec->s_cfg.i4_ht_mbs; i++)
2191 {
2192 /* job start index y */
2193 s_job.i2_mb_y = i;
2194
2195 /* queue the job */
2196 ret = ih264_list_queue(ps_codec->pv_proc_jobq, &s_job, 1);
2197 if (ret != IH264_SUCCESS)
2198 {
2199 ps_codec->i4_error_code = ret;
2200 return IH264E_FAIL;
2201 }
2202 }
2203
2204 /* Once all the jobs are queued, terminate the queue */
2205 /* Since the threads are created and deleted in each call, terminating
2206 here is not an issue */
2207 ih264_list_terminate(ps_codec->pv_proc_jobq);
2208 }
2209
2210 return error_status;
2211}