blob: 239271e011760daa715b46a2f4b946e6d35717c2 [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
Thomala Srinivas5c3b9922019-04-17 18:20:04 +0530448 /* The buffer in the queue is set to NULL to specify that encoding is done for that frame */
449 for(i = 0; i < 3; i++)
450 {
451 ps_inp_buf->s_raw_buf.apv_bufs[i] = NULL;
452 }
453
Harinarayanan K K134291e2015-06-18 16:03:38 +0530454 /* Return the buffer status */
455 return (0);
456}
457
458/**
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530459*******************************************************************************
460*
461* @brief
462* Used to get minimum level index for a given picture size
463*
464* @par Description:
465* Gets the minimum level index and then gets corresponding level.
466* Also used to ignore invalid levels like 2.3, 3.3 etc
467*
468* @param[in] level
469* Level of the stream
470*
471* @returns Level index for a given level
472*
473* @remarks
474*
475*******************************************************************************
476*/
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530477WORD32 ih264e_get_min_level(WORD32 wd, WORD32 ht)
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530478{
479 WORD32 lvl_idx = MAX_LEVEL, i;
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530480 WORD32 pic_size = wd * ht;
481 WORD32 max = MAX(wd, ht);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530482 for (i = 0; i < MAX_LEVEL; i++)
483 {
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530484 if ((pic_size <= gai4_ih264_max_luma_pic_size[i]) &&
485 (max <= gai4_ih264_max_wd_ht[i]))
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530486 {
487 lvl_idx = i;
488 break;
489 }
490 }
491
492 return gai4_ih264_levels[lvl_idx];
493}
494
495/**
496*******************************************************************************
497*
498* @brief
499* Used to get level index for a given level
500*
501* @par Description:
502* Converts from level_idc (which is multiplied by 30) to an index that can be
503* used as a lookup. Also used to ignore invalid levels like 2.2 , 3.2 etc
504*
505* @param[in] level
506* Level of the stream
507*
508* @returns Level index for a given level
509*
510* @remarks
511*
512*******************************************************************************
513*/
514WORD32 ih264e_get_lvl_idx(WORD32 level)
515{
516 WORD32 lvl_idx = 0;
517
518 if (level < IH264_LEVEL_11)
519 {
520 lvl_idx = 0;
521 }
522 else if (level < IH264_LEVEL_12)
523 {
524 lvl_idx = 1;
525 }
526 else if (level < IH264_LEVEL_13)
527 {
528 lvl_idx = 2;
529 }
530 else if (level < IH264_LEVEL_20)
531 {
532 lvl_idx = 3;
533 }
534 else if (level < IH264_LEVEL_21)
535 {
536 lvl_idx = 4;
537 }
538 else if (level < IH264_LEVEL_22)
539 {
540 lvl_idx = 5;
541 }
542 else if (level < IH264_LEVEL_30)
543 {
544 lvl_idx = 6;
545 }
546 else if (level < IH264_LEVEL_31)
547 {
548 lvl_idx = 7;
549 }
550 else if (level < IH264_LEVEL_32)
551 {
552 lvl_idx = 8;
553 }
554 else if (level < IH264_LEVEL_40)
555 {
556 lvl_idx = 9;
557 }
558 else if (level < IH264_LEVEL_41)
559 {
560 lvl_idx = 10;
561 }
562 else if (level < IH264_LEVEL_42)
563 {
564 lvl_idx = 11;
565 }
566 else if (level < IH264_LEVEL_50)
567 {
568 lvl_idx = 12;
569 }
Martin Storsjobf9cd172015-05-15 14:23:46 +0300570 else if (level < IH264_LEVEL_51)
571 {
572 lvl_idx = 13;
573 }
574 else
575 {
576 lvl_idx = 14;
577 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530578
579 return (lvl_idx);
580}
581
582/**
583*******************************************************************************
584*
585* @brief returns maximum number of pictures allowed in dpb for a given level
586*
587* @par Description:
588* For given width, height and level, number of pictures allowed in decoder
589* picture buffer is computed as per Annex A.3.1
590*
591* @param[in] level
592* level of the bit-stream
593*
594* @param[in] pic_size
595* width * height
596*
597* @returns Number of buffers in DPB
598*
599* @remarks
600* From annexure A.3.1 of H264 specification,
601* max_dec_frame_buffering <= MaxDpbSize, where MaxDpbSize is equal to
602* Min( 1024 * MaxDPB / ( PicWidthInMbs * FrameHeightInMbs * 384 ), 16 ) and
603* MaxDPB is given in Table A-1 in units of 1024 bytes. However the MaxDPB size
604* presented in the look up table gas_ih264_lvl_tbl is in units of 512
605* bytes. Hence the expression is modified accordingly.
606*
607*******************************************************************************
608*/
609WORD32 ih264e_get_dpb_size(WORD32 level, WORD32 pic_size)
610{
611 /* dpb size */
612 WORD32 max_dpb_size_bytes = 0;
613
614 /* dec frame buffering */
615 WORD32 max_dpb_size_frames = 0;
616
617 /* temp var */
618 WORD32 i;
619
620 /* determine max luma samples */
621 for (i = 0; i < 16; i++)
622 if (level == (WORD32)gas_ih264_lvl_tbl[i].u4_level_idc)
623 max_dpb_size_bytes = gas_ih264_lvl_tbl[i].u4_max_dpb_size;
624
625 /* from Annexure A.3.1 h264 specification */
626 max_dpb_size_frames =
627 MIN( 1024 * max_dpb_size_bytes / ( pic_size * 3 ), MAX_DPB_SIZE );
628
629 return max_dpb_size_frames;
630}
631
632/**
633*******************************************************************************
634*
635* @brief
636* Used to get reference picture buffer size for a given level and
637* and padding used
638*
639* @par Description:
640* Used to get reference picture buffer size for a given level and padding used
641* Each picture is padded on all four sides
642*
643* @param[in] pic_size
644* Number of luma samples (Width * Height)
645*
646* @param[in] level
647* Level
648*
649* @param[in] horz_pad
650* Total padding used in horizontal direction
651*
652* @param[in] vert_pad
653* Total padding used in vertical direction
654*
655* @returns Total picture buffer size
656*
657* @remarks
658*
659*
660*******************************************************************************
661*/
662WORD32 ih264e_get_total_pic_buf_size(WORD32 pic_size,
663 WORD32 level,
664 WORD32 horz_pad,
665 WORD32 vert_pad,
666 WORD32 num_ref_frames,
667 WORD32 num_reorder_frames)
668{
669 WORD32 size;
670 WORD32 num_luma_samples;
671 WORD32 lvl_idx;
672 WORD32 max_wd, min_ht;
673 WORD32 num_samples;
674 WORD32 max_num_bufs;
675 WORD32 pad = MAX(horz_pad, vert_pad);
Harinarayanan K K134291e2015-06-18 16:03:38 +0530676
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530677 /*
678 * If num_ref_frames and num_reorder_frmaes is specified
679 * Use minimum value
680 */
681 max_num_bufs = (num_ref_frames + num_reorder_frames + MAX_CTXT_SETS);
682
683 /* Get level index */
684 lvl_idx = ih264e_get_lvl_idx(level);
685
686 /* Maximum number of luma samples in a picture at given level */
687 num_luma_samples = gai4_ih264_max_luma_pic_size[lvl_idx];
Harinarayanan K K134291e2015-06-18 16:03:38 +0530688 num_luma_samples = MAX(num_luma_samples, pic_size);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530689
690 /* Account for chroma */
691 num_samples = num_luma_samples * 3 / 2;
692
693 /* Maximum width of luma samples in a picture at given level */
694 max_wd = gai4_ih264_max_wd_ht[lvl_idx];
695
696 /* Minimum height of luma samples in a picture at given level */
697 min_ht = gai4_ih264_min_wd_ht[lvl_idx];
698
699 /* Allocation is required for
700 * (Wd + horz_pad) * (Ht + vert_pad) * (2 * max_dpb_size + 1)
701 *
702 * Above expanded as
703 * ((Wd * Ht) + (horz_pad * vert_pad) + Wd * vert_pad + Ht * horz_pad) * (2 * max_dpb_size + 1)
704 * (Wd * Ht) * (2 * max_dpb_size + 1) + ((horz_pad * vert_pad) + Wd * vert_pad + Ht * horz_pad) * (2 * max_dpb_size + 1)
705 * 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
706 *
707 * In the above equation (Wd * Ht) * (2 * max_dpb_size + 1) is accounted by using num_samples * (2 * max_dpb_size + 1) below
708 *
709 * For the padded area use MAX(horz_pad, vert_pad) as pad
710 * ((pad * pad) + pad * (Wd + Ht)) * (2 * max_dpb_size + 1) has to accounted from the above for padding
711 *
712 * Since Width and Height can change worst Wd + Ht is when One of the dimensions is max and other is min
713 * So use max_wd and min_ht
714 */
715
716 /* Number of bytes in reference pictures */
717 size = num_samples * max_num_bufs;
718
719 /* Account for padding area */
Martin Storsjobc7164d2015-05-25 14:42:53 +0300720 size += ((pad * pad) + pad * (max_wd + min_ht)) * 3 / 2 * max_num_bufs;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530721
722 return size;
723}
724
725/**
726*******************************************************************************
727*
728* @brief Returns MV bank buffer size for a given number of luma samples
729*
730* @par Description:
731* For given number of luma samples one MV bank size is computed.
732* Each MV bank includes pu_map and enc_pu_t for all the min PUs(4x4) in a picture
733*
734* @param[in] num_luma_samples
735* Max number of luma pixels in the frame
736*
737* @returns Total MV Bank size
738*
739* @remarks
740*
741*******************************************************************************
742*/
743WORD32 ih264e_get_pic_mv_bank_size(WORD32 num_luma_samples)
744{
745 /* mv bank buffer size */
746 WORD32 mv_bank_size = 0;
747
748 /* number of sub mb partitions possible */
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530749 WORD32 num_pu = num_luma_samples / (ENC_MIN_PU_SIZE * ENC_MIN_PU_SIZE);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530750
751 /* number of mbs */
752 WORD32 num_mb = num_luma_samples / (MB_SIZE * MB_SIZE);
753
754 /* Size for storing enc_pu_t start index each MB */
755 /* One extra entry is needed to compute number of PUs in the last MB */
756 mv_bank_size += num_mb * sizeof(WORD32);
757
758 /* Size for pu_map */
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530759 mv_bank_size += ALIGN4(num_pu);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530760
761 /* Size for storing enc_pu_t for each PU */
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530762 mv_bank_size += ALIGN4(num_pu * sizeof(enc_pu_t));
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530763
764 return mv_bank_size;
765}
766
767/**
768*******************************************************************************
769*
770* @brief
771* Function to initialize ps_pic_buf structs add pic buffers to
772* buffer manager in case of non-shared mode
773*
774* @par Description:
775* Function to initialize ps_pic_buf structs add pic buffers to
776* buffer manager in case of non-shared mode
777* To be called once per stream or for every reset
778*
779* @param[in] ps_codec
780* Pointer to codec context
781*
782* @returns error status
783*
784* @remarks
785*
786*******************************************************************************
787*/
788IH264E_ERROR_T ih264e_pic_buf_mgr_add_bufs(codec_t *ps_codec)
789{
790 /* error status */
791 IH264E_ERROR_T ret = IH264E_SUCCESS;
792
793 /* max ref buffer cnt */
794 WORD32 max_num_bufs = ps_codec->i4_ref_buf_cnt;
795
796 /* total size for pic buffers */
797 WORD32 pic_buf_size_allocated = ps_codec->i4_total_pic_buf_size
798 - BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
799
800 /* temp var */
801 UWORD8 *pu1_buf = (UWORD8 *) ps_codec->ps_pic_buf;
802 pic_buf_t *ps_pic_buf = (pic_buf_t *) ps_codec->ps_pic_buf;
803 WORD32 i;
804
805 pu1_buf += BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
806
807 /* In case of non-shared mode, add picture buffers to buffer manager
808 * In case of shared mode, buffers are added in the run-time
809 */
810 {
811 WORD32 buf_ret;
812
813 WORD32 luma_samples = (ps_codec->i4_rec_strd)
814 * (ps_codec->s_cfg.u4_ht + PAD_HT);
815
816 WORD32 chroma_samples = luma_samples >> 1;
817
818 /* Try and add as many buffers as possible for the memory that is allocated */
819 /* If the number of buffers that can be added is less than max_num_bufs
820 * return with an error */
821 for (i = 0; i < max_num_bufs; i++)
822 {
823 pic_buf_size_allocated -= (luma_samples + chroma_samples);
824
825 if (pic_buf_size_allocated < 0)
826 {
827 ps_codec->i4_error_code = IH264E_INSUFFICIENT_MEM_PICBUF;
828 return IH264E_INSUFFICIENT_MEM_PICBUF;
829 }
830
831 ps_pic_buf->pu1_luma = pu1_buf + ps_codec->i4_rec_strd * PAD_TOP
832 + PAD_LEFT;
833 pu1_buf += luma_samples;
834
835 ps_pic_buf->pu1_chroma = pu1_buf
836 + ps_codec->i4_rec_strd * (PAD_TOP / 2)+ PAD_LEFT;
837 pu1_buf += chroma_samples;
838
839 buf_ret = ih264_buf_mgr_add((buf_mgr_t *) ps_codec->pv_ref_buf_mgr,
840 ps_pic_buf, i);
841
842 if (0 != buf_ret)
843 {
844 ps_codec->i4_error_code = IH264E_BUF_MGR_ERROR;
845 return IH264E_BUF_MGR_ERROR;
846 }
847 pu1_buf += (HPEL_PLANES_CNT - 1) * (chroma_samples + luma_samples);
848 ps_pic_buf++;
849 }
850 }
851
852 return ret;
853}
854
855/**
856*******************************************************************************
857*
858* @brief Function to add buffers to MV Bank buffer manager
859*
860* @par Description:
861* Function to add buffers to MV Bank buffer manager. To be called once per
862* stream or for every reset
863*
864* @param[in] ps_codec
865* Pointer to codec context
866*
867* @returns error status
868*
869* @remarks
870*
871*******************************************************************************
872*/
873IH264E_ERROR_T ih264e_mv_buf_mgr_add_bufs(codec_t *ps_codec)
874{
875 /* error status */
876 IH264E_ERROR_T error_status = IH264E_SUCCESS;
877 IH264_ERROR_T ret;
878
879 /* max dpb size in frames */
880 WORD32 max_dpb_size = 0;
881
882 /* mv bank size for the entire dpb */
883 WORD32 mv_bank_size_allocated = 0;
884
885 /* mv bank size per pic */
886 WORD32 pic_mv_bank_size = 0;
887
888 /* mv buffer ptr */
889 mv_buf_t *ps_mv_buf = NULL;
890
891 /* num of luma samples */
892 WORD32 num_luma_samples = ALIGN16(ps_codec->s_cfg.u4_wd)
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530893 * ALIGN16(ps_codec->s_cfg.u4_ht);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530894
895 /* number of mb's & frame partitions */
896 WORD32 num_pu, num_mb;
897
898 /* temp var */
899 UWORD8 *pu1_buf = NULL;
900 WORD32 i;
901
902 /* Compute the number of MB Bank buffers needed */
903 max_dpb_size = ps_codec->i4_ref_buf_cnt;
904
905 /* allocate memory for mv buffer array */
906 ps_codec->ps_mv_buf = ps_codec->pv_mv_bank_buf_base;
907 pu1_buf = ps_codec->pv_mv_bank_buf_base;
908 pu1_buf += BUF_MGR_MAX_CNT * sizeof(mv_buf_t);
909
910 /********************************************************************/
911 /* allocate memory for individual elements of mv buffer ptr */
912 /********************************************************************/
913 mv_bank_size_allocated = ps_codec->i4_total_mv_bank_size
914 - (BUF_MGR_MAX_CNT * sizeof(mv_buf_t));
915
916 /* compute MV bank size per picture */
917 pic_mv_bank_size = ih264e_get_pic_mv_bank_size(num_luma_samples);
918
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530919 num_pu = num_luma_samples / (ENC_MIN_PU_SIZE * ENC_MIN_PU_SIZE);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530920 num_mb = num_luma_samples / (MB_SIZE * MB_SIZE);
921 i = 0;
922 ps_mv_buf = ps_codec->pv_mv_bank_buf_base;
923
924 while (i < max_dpb_size)
925 {
926 mv_bank_size_allocated -= pic_mv_bank_size;
927
928 if (mv_bank_size_allocated < 0)
929 {
930 ps_codec->i4_error_code = IH264E_INSUFFICIENT_MEM_MVBANK;
931
932 error_status = IH264E_INSUFFICIENT_MEM_MVBANK;
933
934 return error_status;
935 }
936
937 ps_mv_buf->pu4_mb_pu_cnt = (UWORD32 *) pu1_buf;
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530938 pu1_buf += num_mb * sizeof(WORD32);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530939
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530940 ps_mv_buf->pu1_pic_pu_map = pu1_buf;
941 pu1_buf += ALIGN4(num_pu);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530942
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530943 ps_mv_buf->ps_pic_pu = (enc_pu_t *) (pu1_buf);
944 pu1_buf += ALIGN4(num_pu * sizeof(enc_pu_t));
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530945
946 ret = ih264_buf_mgr_add((buf_mgr_t *) ps_codec->pv_mv_buf_mgr,
947 ps_mv_buf, i);
948
949 if (IH264_SUCCESS != ret)
950 {
951 ps_codec->i4_error_code = IH264E_BUF_MGR_ERROR;
952 error_status = IH264E_BUF_MGR_ERROR;
953 return error_status;
954 }
955
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530956 ps_mv_buf++;
957 i++;
958 }
959
960 return error_status;
961}
962
963/**
964*******************************************************************************
965*
966* @brief Function to initialize quant params structure
967*
968* @par Description:
969* The forward quantization modules depends on qp/6, qp mod 6, forward scale
970* matrix, forward threshold matrix, weight list. The inverse quantization
971* modules depends on qp/6, qp mod 6, inverse scale matrix, weight list.
972* These params are initialized in this function.
973*
974* @param[in] ps_proc
975* pointer to process context
976*
977* @param[in] qp
978* quantization parameter
979*
980* @returns none
981*
982* @remarks
983*
984*******************************************************************************
985*/
986void ih264e_init_quant_params(process_ctxt_t *ps_proc, int qp)
987{
988 /* quant params */
989 quant_params_t *ps_qp_params;
990
991 /* ptr to forward quant threshold matrix */
992 const UWORD16 *pu2_thres_mat = NULL;
993
994 /* ptr to forward scale matrix */
995 const UWORD16 *pu2_scale_mat = gu2_quant_scale_matrix_4x4;
996
997 /* ptr to inverse scale matrix */
998 const UWORD16 *pu2_iscale_mat = gau2_ih264_iquant_scale_matrix_4x4;
999
1000 /* temp var */
1001 UWORD32 u4_qp[3], u4_qp_div6, u4_qp_mod6;
1002 COMPONENT_TYPE plane;
1003 WORD32 i;
1004 UWORD32 u4_satdq_t;
1005 const UWORD16 *pu2_smat;
1006
1007 /********************************************************************/
1008 /* init quant params for all planes Y, U and V */
1009 /********************************************************************/
1010 /* luma qp */
1011 u4_qp[Y] = qp;
1012
1013 /* chroma qp
1014 * TODO_LATER : just in case if the chroma planes use different qp's this
1015 * needs to be corrected accordingly.
1016 */
1017 u4_qp[U] = gu1_qpc_fqpi[qp];
1018 u4_qp[V] = gu1_qpc_fqpi[qp];
1019
1020 plane = Y;
1021 while (plane <= V)
1022 {
1023 u4_qp_div6 = (u4_qp[plane] / 6);
1024 u4_qp_mod6 = (u4_qp[plane] % 6);
1025
1026 ps_qp_params = ps_proc->ps_qp_params[plane];
1027
1028 /* mb qp */
1029 ps_qp_params->u1_mb_qp = u4_qp[plane];
1030
1031 /* mb qp / 6 */
1032 ps_qp_params->u1_qp_div = u4_qp_div6;
1033
1034 /* mb qp % 6 */
1035 ps_qp_params->u1_qp_rem = u4_qp_mod6;
1036
1037 /* QP bits */
1038 ps_qp_params->u1_qbits = QP_BITS_h264_4x4 + u4_qp_div6;
1039
1040 /* forward scale matrix */
1041 ps_qp_params->pu2_scale_mat = pu2_scale_mat + (u4_qp_mod6 * 16);
1042
1043 /* threshold matrix & weight for quantization */
1044 pu2_thres_mat = gu2_forward_quant_threshold_4x4 + (u4_qp_mod6 * 16);
1045 for (i = 0; i < 16; i++)
1046 {
1047 ps_qp_params->pu2_thres_mat[i] = pu2_thres_mat[i]
1048 >> (8 - u4_qp_div6);
1049 ps_qp_params->pu2_weigh_mat[i] = 16;
1050 }
1051
1052 /* qp dependent rounding constant */
1053 ps_qp_params->u4_dead_zone =
1054 gu4_forward_quant_round_factor_4x4[u4_qp_div6];
1055
1056 /* slice dependent rounding constant */
1057 if (ps_proc->i4_slice_type != ISLICE
1058 && ps_proc->i4_slice_type != SISLICE)
1059 {
1060 ps_qp_params->u4_dead_zone >>= 1;
1061 }
1062
1063 /* SATQD threshold for zero block prediction */
1064 if (ps_proc->ps_codec->s_cfg.u4_enable_satqd)
1065 {
1066 pu2_smat = ps_qp_params->pu2_scale_mat;
1067
1068 u4_satdq_t = ((1 << (ps_qp_params->u1_qbits)) - ps_qp_params->u4_dead_zone);
1069
1070 ps_qp_params->pu2_sad_thrsh[0] = u4_satdq_t / MAX(pu2_smat[3], pu2_smat[11]);
1071 ps_qp_params->pu2_sad_thrsh[1] = u4_satdq_t / MAX(pu2_smat[1], pu2_smat[9]);
1072 ps_qp_params->pu2_sad_thrsh[2] = u4_satdq_t / pu2_smat[15];
1073 ps_qp_params->pu2_sad_thrsh[3] = u4_satdq_t / pu2_smat[7];
1074 ps_qp_params->pu2_sad_thrsh[4] = u4_satdq_t / MAX(pu2_smat[12], pu2_smat[14]);
1075 ps_qp_params->pu2_sad_thrsh[5] = u4_satdq_t / MAX(pu2_smat[4], pu2_smat[6]);
1076 ps_qp_params->pu2_sad_thrsh[6] = u4_satdq_t / pu2_smat[13];
1077 ps_qp_params->pu2_sad_thrsh[7] = u4_satdq_t / pu2_smat[5];
1078 ps_qp_params->pu2_sad_thrsh[8] = u4_satdq_t / MAX(MAX3(pu2_smat[0], pu2_smat[2], pu2_smat[8]), pu2_smat[10]);
1079 }
1080
1081 /* inverse scale matrix */
1082 ps_qp_params->pu2_iscale_mat = pu2_iscale_mat + (u4_qp_mod6 * 16);
1083
1084 plane += 1;
1085 }
1086 return ;
1087}
1088
1089/**
1090*******************************************************************************
1091*
1092* @brief
1093* Initialize AIR mb frame Map
1094*
1095* @par Description:
1096* Initialize AIR mb frame map
1097* MB frame map indicates which frame an Mb should be coded as intra according to AIR
1098*
1099* @param[in] ps_codec
1100* Pointer to codec context
1101*
1102* @returns error_status
1103*
1104* @remarks
1105*
1106*
1107*******************************************************************************
1108*/
1109IH264E_ERROR_T ih264e_init_air_map(codec_t *ps_codec)
1110{
1111 /* intra refresh map */
1112 UWORD16 *pu2_intr_rfrsh_map = ps_codec->pu2_intr_rfrsh_map;
1113
1114 /* air mode */
1115 IVE_AIR_MODE_T air_mode = ps_codec->s_cfg.e_air_mode;
1116
1117 /* refresh period */
1118 UWORD32 air_period = ps_codec->s_cfg.u4_air_refresh_period;
1119
1120 /* mb cnt */
1121 UWORD32 u4_mb_cnt = ps_codec->s_cfg.i4_wd_mbs * ps_codec->s_cfg.i4_ht_mbs;
1122
1123 /* temp var */
1124 UWORD32 curr_mb, seed_rand = 1;
1125
1126 switch (air_mode)
1127 {
1128 case IVE_AIR_MODE_CYCLIC:
1129
1130 for (curr_mb = 0; curr_mb < u4_mb_cnt; curr_mb++)
1131 {
1132 pu2_intr_rfrsh_map[curr_mb] = curr_mb % air_period;
1133 }
1134 break;
1135
1136 case IVE_AIR_MODE_RANDOM:
1137
1138 for (curr_mb = 0; curr_mb < u4_mb_cnt; curr_mb++)
1139 {
1140 seed_rand = (seed_rand * 32719 + 3) % 32749;
1141 pu2_intr_rfrsh_map[curr_mb] = seed_rand % air_period;
1142 }
1143 break;
1144
1145 default:
1146
1147 break;
1148 }
1149
1150 return IH264E_SUCCESS;
1151}
1152
1153/**
1154*******************************************************************************
1155*
1156* @brief
1157* Codec level initializations
1158*
1159* @par Description:
1160* Initializes the codec with parameters that needs to be set before encoding
1161* first frame
1162*
1163* @param[in] ps_codec
1164* Pointer to codec context
1165*
1166* @param[in] ps_inp_buf
1167* Pointer to input buffer context
1168*
1169* @returns error_status
1170*
1171* @remarks
1172*
1173*
1174*******************************************************************************
1175*/
1176IH264E_ERROR_T ih264e_codec_init(codec_t *ps_codec)
1177{
1178 /********************************************************************
1179 * INITIALIZE CODEC CONTEXT *
1180 ********************************************************************/
1181 /* encoder presets */
1182 if (ps_codec->s_cfg.u4_enc_speed_preset != IVE_CONFIG)
1183 {
1184 if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
1185 {/* high quality */
1186 /* enable diamond search */
1187 ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
1188 ps_codec->s_cfg.u4_enable_fast_sad = 0;
1189
1190 /* disable intra 4x4 */
1191 ps_codec->s_cfg.u4_enable_intra_4x4 = 1;
1192 ps_codec->luma_energy_compaction[1] =
1193 ih264e_code_luma_intra_macroblock_4x4_rdopt_on;
1194
1195 /* sub pel off */
1196 ps_codec->s_cfg.u4_enable_hpel = 1;
1197
1198 /* deblocking off */
1199 ps_codec->s_cfg.u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0;
1200
1201 /* disabled intra inter gating in Inter slices */
1202 ps_codec->u4_inter_gate = 0;
1203 }
1204 else if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_NORMAL)
1205 {/* normal */
1206 /* enable diamond search */
1207 ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
1208 ps_codec->s_cfg.u4_enable_fast_sad = 0;
1209
1210 /* disable intra 4x4 */
1211 ps_codec->s_cfg.u4_enable_intra_4x4 = 1;
1212
1213 /* sub pel off */
1214 ps_codec->s_cfg.u4_enable_hpel = 1;
1215
1216 /* deblocking off */
1217 ps_codec->s_cfg.u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0;
1218
1219 /* disabled intra inter gating in Inter slices */
1220 ps_codec->u4_inter_gate = 0;
1221 }
1222 else if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_FAST)
1223 {/* normal */
1224 /* enable diamond search */
1225 ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
1226 ps_codec->s_cfg.u4_enable_fast_sad = 0;
1227
1228 /* disable intra 4x4 */
1229 ps_codec->s_cfg.u4_enable_intra_4x4 = 0;
1230
1231 /* sub pel off */
1232 ps_codec->s_cfg.u4_enable_hpel = 1;
1233
1234 /* deblocking off */
1235 ps_codec->s_cfg.u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0;
1236
1237 /* disabled intra inter gating in Inter slices */
1238 ps_codec->u4_inter_gate = 1;
1239 }
1240 else if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_HIGH_SPEED)
1241 {/* fast */
1242 /* enable diamond search */
1243 ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
1244 ps_codec->s_cfg.u4_enable_fast_sad = 0;
1245
1246 /* disable intra 4x4 */
1247 ps_codec->s_cfg.u4_enable_intra_4x4 = 0;
1248
1249 /* sub pel off */
1250 ps_codec->s_cfg.u4_enable_hpel = 0;
1251
1252 /* deblocking off */
1253 ps_codec->s_cfg.u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4;
1254
1255 /* disabled intra inter gating in Inter slices */
1256 ps_codec->u4_inter_gate = 0;
1257 }
1258 else if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_FASTEST)
1259 {/* fastest */
1260 /* enable diamond search */
1261 ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
1262
1263 /* disable intra 4x4 */
1264 ps_codec->s_cfg.u4_enable_intra_4x4 = 0;
1265
1266 /* sub pel off */
1267 ps_codec->s_cfg.u4_enable_hpel = 0;
1268
1269 /* deblocking off */
1270 ps_codec->s_cfg.u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4;
1271
1272 /* disabled intra inter gating in Inter slices */
1273 ps_codec->u4_inter_gate = 1;
1274 }
1275 }
1276
1277 /*****************************************************************
1278 * Initialize AIR inside codec
1279 *****************************************************************/
1280 if (IVE_AIR_MODE_NONE != ps_codec->s_cfg.e_air_mode)
1281 {
1282 ih264e_init_air_map(ps_codec);
1283
1284 ps_codec->i4_air_pic_cnt = -1;
1285 }
1286
1287 /****************************************************/
1288 /* INITIALIZE RATE CONTROL */
1289 /****************************************************/
1290 {
1291 /* init qp */
1292 UWORD8 au1_init_qp[MAX_PIC_TYPE];
1293
1294 /* min max qp */
1295 UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE];
1296
1297 /* init i,p,b qp */
1298 au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp];
1299 au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp];
1300 au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp];
1301
1302 /* init min max qp */
1303 au1_min_max_qp[2 * I_PIC] =
1304 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_min];
1305 au1_min_max_qp[2 * I_PIC + 1] =
1306 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_max];
1307
1308 au1_min_max_qp[2 * P_PIC] =
1309 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_min];
1310 au1_min_max_qp[2 * P_PIC + 1] =
1311 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_max];
1312
1313 au1_min_max_qp[2 * B_PIC] =
1314 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_min];
1315 au1_min_max_qp[2 * B_PIC + 1] =
1316 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_max];
1317
1318 /* get rc mode */
1319 switch (ps_codec->s_cfg.e_rc_mode)
1320 {
1321 case IVE_RC_STORAGE:
1322 ps_codec->s_rate_control.e_rc_type = VBR_STORAGE;
1323 break;
1324 case IVE_RC_CBR_NON_LOW_DELAY:
1325 ps_codec->s_rate_control.e_rc_type = CBR_NLDRC;
1326 break;
1327 case IVE_RC_CBR_LOW_DELAY:
1328 ps_codec->s_rate_control.e_rc_type = CBR_LDRC;
1329 break;
1330 case IVE_RC_NONE:
1331 ps_codec->s_rate_control.e_rc_type = CONST_QP;
1332 break;
1333 default:
1334 break;
1335 }
1336
1337 /* init rate control */
1338 ih264e_rc_init(ps_codec->s_rate_control.pps_rate_control_api,
1339 ps_codec->s_rate_control.pps_frame_time,
1340 ps_codec->s_rate_control.pps_time_stamp,
1341 ps_codec->s_rate_control.pps_pd_frm_rate,
1342 ps_codec->s_cfg.u4_max_framerate,
1343 ps_codec->s_cfg.u4_src_frame_rate,
1344 ps_codec->s_cfg.u4_tgt_frame_rate,
1345 ps_codec->s_rate_control.e_rc_type,
1346 ps_codec->s_cfg.u4_target_bitrate,
1347 ps_codec->s_cfg.u4_max_bitrate,
1348 ps_codec->s_cfg.u4_vbv_buffer_delay,
Harinarayanan K K134291e2015-06-18 16:03:38 +05301349 ps_codec->s_cfg.u4_i_frm_interval,
1350 ps_codec->s_cfg.u4_num_bframes + 1, au1_init_qp,
1351 ps_codec->s_cfg.u4_num_bframes + 2 , au1_min_max_qp,
Martin Storsjocc58d3f2015-06-27 20:56:24 +03001352 MAX(ps_codec->s_cfg.u4_max_level,
1353 (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 +05301354 }
1355
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301356 /* recon stride */
1357 ps_codec->i4_rec_strd = ALIGN16(ps_codec->s_cfg.u4_max_wd) + PAD_WD;
1358
1359 /* max ref and reorder cnt */
1360 ps_codec->i4_ref_buf_cnt = ps_codec->s_cfg.u4_max_ref_cnt
1361 + ps_codec->s_cfg.u4_max_reorder_cnt;
1362 ps_codec->i4_ref_buf_cnt += MAX_CTXT_SETS;
1363
1364 DEBUG_HISTOGRAM_INIT();
1365
Harinarayanan K K134291e2015-06-18 16:03:38 +05301366
1367 /* Init dependecy vars */
1368 ps_codec->i4_last_inp_buff_received = 0;
1369
Harinarayanan K Kaad45872015-06-26 15:20:33 +05301370 /* At codec start no IDR is pending */
1371 ps_codec->i4_pending_idr_flag = 0;
Harinarayanan K K134291e2015-06-18 16:03:38 +05301372
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301373 return IH264E_SUCCESS;
1374}
1375
1376/**
1377*******************************************************************************
1378*
1379* @brief
1380* Picture level initializations
1381*
1382* @par Description:
1383* Before beginning to encode the frame, the current function initializes all
1384* the ctxts (proc, entropy, me, ...) basing on the input configured params.
1385* It locates space for storing recon in the encoder picture buffer set, fetches
1386* reference frame from encoder picture buffer set. Calls RC pre-enc to get
1387* qp and pic type for the current frame. Queues proc jobs so that
1388* the other threads can begin encoding. In brief, this function sets up the
1389* tone for the entire encoder.
1390*
1391* @param[in] ps_codec
1392* Pointer to codec context
1393*
1394* @param[in] ps_inp_buf
1395* Pointer to input buffer context
1396*
1397* @returns error_status
1398*
1399* @remarks
1400*
1401*
1402*******************************************************************************
1403*/
1404IH264E_ERROR_T ih264e_pic_init(codec_t *ps_codec, inp_buf_t *ps_inp_buf)
1405{
1406 /* error status */
1407 IH264E_ERROR_T error_status = IH264E_SUCCESS;
1408 IH264_ERROR_T ret = IH264_SUCCESS;
1409
1410 /* mv buff bank */
1411 mv_buf_t *ps_mv_buf = NULL;
1412 WORD32 cur_mv_bank_buf_id;
1413
1414 /* recon buffer set */
1415 pic_buf_t *ps_cur_pic;
1416 WORD32 cur_pic_buf_id;
1417 UWORD8 *pu1_cur_pic_luma, *pu1_cur_pic_chroma;
1418
1419 /* ref buffer set */
Harinarayanan K K134291e2015-06-18 16:03:38 +05301420 pic_buf_t *aps_ref_pic[MAX_REF_PIC_CNT] = {NULL, NULL};
1421 mv_buf_t *aps_mv_buf[MAX_REF_PIC_CNT] = {NULL, NULL};
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301422 WORD32 ref_set_id;
1423
1424 /* pic time stamp */
1425 UWORD32 u4_timestamp_high = ps_inp_buf->u4_timestamp_high;
1426 UWORD32 u4_timestamp_low = ps_inp_buf->u4_timestamp_low;
1427
1428 /* indices to access curr/prev frame info */
Harinarayanan K K6cb67722015-06-19 14:44:42 +05301429 WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301430
1431 /* curr pic type */
1432 PIC_TYPE_T *pic_type = &ps_codec->pic_type;
1433
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301434 /* Diamond search Iteration Max Cnt */
1435 UWORD32 u4_num_layers =
1436 (ps_codec->s_cfg.u4_enc_speed_preset == IVE_FASTEST) ?
1437 (NUM_LAYERS >> 2) : NUM_LAYERS;
1438
1439 /* enable fast sad */
1440 UWORD32 u4_enable_fast_sad = ps_codec->s_cfg.u4_enable_fast_sad;
1441
1442 /********************************************************************/
1443 /* INITIALIZE CODEC CONTEXT */
1444 /********************************************************************/
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301445 /* slice_type */
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301446 if ((PIC_I == *pic_type) || (PIC_IDR == *pic_type))
1447 {
1448 ps_codec->i4_slice_type = ISLICE;
1449 }
1450 else if (PIC_P == *pic_type)
1451 {
1452 ps_codec->i4_slice_type = PSLICE;
1453 }
Harinarayanan K K134291e2015-06-18 16:03:38 +05301454 else if(PIC_B == *pic_type)
1455 {
1456 ps_codec->i4_slice_type = BSLICE;
1457 }
1458
1459
1460 /***************************************************************************
1461 * Set up variables for sending frame number, poc and reference
1462 * a) Set up alt ref too
1463 **************************************************************************/
1464
Harinarayanan K K134291e2015-06-18 16:03:38 +05301465 /* Check and set if the current frame is reference or not */
1466 ps_codec->u4_is_curr_frm_ref = 0;
1467
1468 /* This frame is reference if its not a B pic, pending approval from alt ref */
1469 ps_codec->u4_is_curr_frm_ref = (*pic_type != PIC_B);
1470
1471 /* In case if its a P pic, we will decide according to alt ref also */
1472 if (ps_codec->s_cfg.u4_enable_alt_ref && (*pic_type == PIC_P)
1473 && (ps_codec->i4_pic_cnt
1474 % (ps_codec->s_cfg.u4_enable_alt_ref + 1)))
1475 {
1476 ps_codec->u4_is_curr_frm_ref = 0;
1477 }
1478
1479 /*
1480 * Override everything in case of IDR
1481 * Note that in case of IDR, at this point ps_codec->u4_is_curr_frm_ref must
1482 * be 1
1483 */
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301484
1485 /* is this an IDR pic */
1486 ps_codec->u4_is_idr = 0;
1487
1488 if (PIC_IDR == *pic_type)
1489 {
1490 /* set idr flag */
1491 ps_codec->u4_is_idr = 1;
1492
1493 /* reset frame num */
1494 ps_codec->i4_frame_num = 0;
1495
1496 /* idr_pic_id */
1497 ps_codec->i4_idr_pic_id++;
1498 }
1499
Harinarayanan K K134291e2015-06-18 16:03:38 +05301500 /***************************************************************************
1501 * Set up Deblock
1502 **************************************************************************/
1503
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301504 /* set deblock disable flags based on disable deblock level */
1505 ps_codec->i4_disable_deblk_pic = 1;
1506
1507 if (ps_codec->s_cfg.u4_disable_deblock_level == DISABLE_DEBLK_LEVEL_0)
1508 {
1509 /* enable deblocking */
1510 ps_codec->i4_disable_deblk_pic = 0;
1511 }
1512 else if (ps_codec->s_cfg.u4_disable_deblock_level == DISABLE_DEBLK_LEVEL_2)
1513 {
1514 /* enable deblocking after a period of frames */
1515 if (ps_codec->i4_disable_deblk_pic_cnt == DISABLE_DEBLOCK_INTERVAL
1516 || ps_codec->i4_slice_type == ISLICE)
1517 {
1518 ps_codec->i4_disable_deblk_pic = 0;
1519 }
1520 }
1521 else if (ps_codec->s_cfg.u4_disable_deblock_level == DISABLE_DEBLK_LEVEL_3)
1522 {
1523 if (ps_codec->i4_slice_type == ISLICE)
1524 {
1525 ps_codec->i4_disable_deblk_pic = 0;
1526 }
1527 }
1528
1529 if (ps_codec->i4_disable_deblk_pic)
1530 {
1531 ps_codec->i4_disable_deblk_pic_cnt++;
1532 }
1533 else
1534 {
1535 ps_codec->i4_disable_deblk_pic_cnt = 0;
1536 }
1537
1538 /* In slice mode - lets not deblk mb edges that lie along slice boundaries */
1539 if (ps_codec->i4_disable_deblk_pic == 0)
1540 {
1541 if (ps_codec->s_cfg.e_slice_mode != IVE_SLICE_MODE_NONE)
1542 {
1543 ps_codec->i4_disable_deblk_pic = 2;
1544 }
1545 }
1546
1547 /* error status */
1548 ps_codec->i4_error_code = IH264E_SUCCESS;
1549
1550 /* populate header */
1551 if (ps_codec->i4_gen_header)
1552 {
1553 /* sps */
1554 sps_t *ps_sps = NULL;
1555
1556 /* pps */
1557 pps_t *ps_pps = NULL;
1558
1559 /*ps_codec->i4_pps_id ++;*/
1560 ps_codec->i4_pps_id %= MAX_PPS_CNT;
1561
1562 /*ps_codec->i4_sps_id ++;*/
1563 ps_codec->i4_sps_id %= MAX_SPS_CNT;
1564
1565 /* populate sps header */
1566 ps_sps = ps_codec->ps_sps_base + ps_codec->i4_sps_id;
1567 ih264e_populate_sps(ps_codec, ps_sps);
1568
1569 /* populate pps header */
1570 ps_pps = ps_codec->ps_pps_base + ps_codec->i4_pps_id;
1571 ih264e_populate_pps(ps_codec, ps_pps);
1572 }
1573
Harinarayanan K K134291e2015-06-18 16:03:38 +05301574 /***************************************************************************
1575 * Reference and MV bank Buffer Manager
1576 * Here we will
1577 * 1) Find the correct ref pics for the current frame
1578 * 2) Free the ref pic that is not going to be used anywhere
1579 * 3) Find a free buff from the list and assign it as the recon of
1580 * current frame
1581 *
1582 * 1) Finding correct ref pic
1583 * All pics needed for future are arranged in a picture list called
1584 * ps_codec->as_ref_set. Each picture in this will have a pic buffer and
1585 * MV buffer that is marked appropriately as BUF_MGR_REF, BUF_MGR_IO or
1586 * BUF_MGR_CODEC. Also the pic_cnt and poc will also be present.
1587 * Hence to find the ref pic we will loop through the list and find
1588 * 2 pictures with maximum i4_pic_cnt .
1589 *
1590 * note that i4_pic_cnt == -1 is used to filter uninit ref pics.
1591 * Now since we only have max two ref pics, we will always find max 2
1592 * ref pics.
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301593
Harinarayanan K K134291e2015-06-18 16:03:38 +05301594 *
1595 * 2) 3) Self explanatory
1596 ***************************************************************************/
1597 {
1598 /* Search for buffs with maximum pic cnt */
1599
1600 WORD32 max_pic_cnt[] = { -1, -1 };
1601
1602 mv_buf_t *ps_mv_buf_to_free[] = { NULL, NULL };
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301603
1604 /* temp var */
Harinarayanan K K134291e2015-06-18 16:03:38 +05301605 WORD32 i, buf_status;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301606
1607 for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
1608 {
Harinarayanan K K134291e2015-06-18 16:03:38 +05301609 if (ps_codec->as_ref_set[i].i4_pic_cnt == -1)
1610 continue;
1611
1612 buf_status = ih264_buf_mgr_get_status(
1613 ps_codec->pv_ref_buf_mgr,
1614 ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
1615
1616 /* Ideally we should look for buffer status of MV BUFF also. But since
1617 * the correponding MV buffs also will be at the same state. It dosent
1618 * matter as of now. But the check will make the logic better */
1619 if ((max_pic_cnt[0] < ps_codec->as_ref_set[i].i4_pic_cnt)
1620 && (buf_status & BUF_MGR_REF))
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301621 {
Harinarayanan K K134291e2015-06-18 16:03:38 +05301622 if (max_pic_cnt[1] < ps_codec->as_ref_set[i].i4_pic_cnt)
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301623 {
Harinarayanan K K134291e2015-06-18 16:03:38 +05301624 max_pic_cnt[0] = max_pic_cnt[1];
1625 aps_ref_pic[0] = aps_ref_pic[1];
1626 aps_mv_buf[0] = aps_mv_buf[1];
1627
1628 ps_mv_buf_to_free[0] = ps_mv_buf_to_free[1];
1629
1630 max_pic_cnt[1] = ps_codec->as_ref_set[i].i4_pic_cnt;
1631 aps_ref_pic[1] = ps_codec->as_ref_set[i].ps_pic_buf;
1632 aps_mv_buf[1] = ps_codec->as_ref_set[i].ps_mv_buf;
1633 ps_mv_buf_to_free[1] = ps_codec->as_ref_set[i].ps_mv_buf;
1634
1635 }
1636 else
1637 {
1638 max_pic_cnt[0] = ps_codec->as_ref_set[i].i4_pic_cnt;
1639 aps_ref_pic[0] = ps_codec->as_ref_set[i].ps_pic_buf;
1640 aps_mv_buf[0] = ps_codec->as_ref_set[i].ps_mv_buf;
1641 ps_mv_buf_to_free[0] = ps_codec->as_ref_set[i].ps_mv_buf;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301642 }
1643 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301644 }
1645
Harinarayanan K K134291e2015-06-18 16:03:38 +05301646 /*
1647 * Now if the current picture is I or P, we discard the back ref pic and
1648 * assign forward ref as backward ref
1649 */
1650 if (*pic_type != PIC_B)
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301651 {
Harinarayanan K K134291e2015-06-18 16:03:38 +05301652 if (ps_mv_buf_to_free[0])
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301653 {
Harinarayanan K K134291e2015-06-18 16:03:38 +05301654 /* release this frame from reference list */
1655 ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr,
1656 ps_mv_buf_to_free[0]->i4_buf_id,
1657 BUF_MGR_REF);
1658
1659 ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr,
1660 aps_ref_pic[0]->i4_buf_id, BUF_MGR_REF);
1661 }
1662
1663 max_pic_cnt[0] = max_pic_cnt[1];
1664 aps_ref_pic[0] = aps_ref_pic[1];
1665 aps_mv_buf[0] = aps_mv_buf[1];
1666
1667 /* Dummy */
1668 max_pic_cnt[1] = -1;
1669 }
1670
1671 /*
1672 * Mark all reference pic with unused buffers to be free
1673 * We need this step since each one, ie ref, recon io etc only unset their
1674 * respective flags. Hence we need to combine togather and mark the ref set
1675 * accordingly
1676 */
1677 ref_set_id = -1;
1678 for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
1679 {
1680 if (ps_codec->as_ref_set[i].i4_pic_cnt == -1)
1681 {
1682 ref_set_id = i;
1683 continue;
1684 }
1685
1686 buf_status = ih264_buf_mgr_get_status(
1687 ps_codec->pv_ref_buf_mgr,
1688 ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
1689
1690 if ((buf_status & (BUF_MGR_REF | BUF_MGR_CODEC | BUF_MGR_IO)) == 0)
1691 {
1692 ps_codec->as_ref_set[i].i4_pic_cnt = -1;
1693 ps_codec->as_ref_set[i].i4_poc = 32768;
1694
1695 ref_set_id = i;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301696 }
1697 }
Harinarayanan K K134291e2015-06-18 16:03:38 +05301698 /* An asssert failure here means we donot have any free buffs */
1699 ASSERT(ref_set_id >= 0);
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301700 }
1701
1702 {
1703 /*****************************************************************/
1704 /* Get free MV Bank to hold current picture's motion vector data */
1705 /* If there are no free buffers then return with an error code. */
1706 /* If the buffer is to be freed by another thread, change the */
1707 /* following to call thread yield and wait for buffer to be freed*/
1708 /*****************************************************************/
1709 ps_mv_buf = (mv_buf_t *) ih264_buf_mgr_get_next_free(
1710 (buf_mgr_t *) ps_codec->pv_mv_buf_mgr,
1711 &cur_mv_bank_buf_id);
1712
1713 if (NULL == ps_mv_buf)
1714 {
1715 ps_codec->i4_error_code = IH264E_NO_FREE_MVBANK;
1716 return IH264E_NO_FREE_MVBANK;
1717 }
1718
1719 /* mark the buffer as needed for reference if the curr pic is available for ref */
1720 if (ps_codec->u4_is_curr_frm_ref)
1721 {
1722 ih264_buf_mgr_set_status(ps_codec->pv_mv_buf_mgr,
1723 cur_mv_bank_buf_id, BUF_MGR_REF);
1724 }
1725
1726 /* Set current ABS poc to ps_mv_buf, so that while freeing a reference buffer
1727 * corresponding mv buffer can be found by looping through ps_codec->ps_mv_buf array
1728 * and getting a buffer id to free
1729 */
1730 ps_mv_buf->i4_abs_poc = ps_codec->i4_abs_pic_order_cnt;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301731 ps_mv_buf->i4_buf_id = cur_mv_bank_buf_id;
1732 }
1733
1734 {
1735 /*****************************************************************/
1736 /* Get free pic buf to hold current picture's recon data */
1737 /* If there are no free buffers then return with an error code. */
1738 /* If the buffer is to be freed by another thread, change the */
1739 /* following to call thread yield and wait for buffer to be freed*/
1740 /*****************************************************************/
1741 ps_cur_pic = (pic_buf_t *) ih264_buf_mgr_get_next_free(
1742 (buf_mgr_t *) ps_codec->pv_ref_buf_mgr,
1743 &cur_pic_buf_id);
1744
1745 if (NULL == ps_cur_pic)
1746 {
1747 ps_codec->i4_error_code = IH264E_NO_FREE_PICBUF;
1748 return IH264E_NO_FREE_PICBUF;
1749 }
1750
1751 /* mark the buffer as needed for reference if the curr pic is available for ref */
Harinarayanan K K134291e2015-06-18 16:03:38 +05301752 if (ps_codec->u4_is_curr_frm_ref)
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301753 {
1754 ih264_buf_mgr_set_status(ps_codec->pv_ref_buf_mgr, cur_pic_buf_id,
1755 BUF_MGR_REF);
1756 }
1757
1758 /* Mark the current buffer as needed for IO if recon is enabled */
1759 if (1 == ps_codec->s_cfg.u4_enable_recon)
1760 {
1761 ih264_buf_mgr_set_status(ps_codec->pv_ref_buf_mgr, cur_pic_buf_id,
1762 BUF_MGR_IO);
1763 }
1764
1765 /* Associate input timestamp with current buffer */
1766 ps_cur_pic->u4_timestamp_high = ps_inp_buf->u4_timestamp_high;
1767 ps_cur_pic->u4_timestamp_low = ps_inp_buf->u4_timestamp_low;
1768
Harinarayanan K K134291e2015-06-18 16:03:38 +05301769 ps_cur_pic->i4_abs_poc = ps_codec->i4_poc;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301770 ps_cur_pic->i4_poc_lsb = ps_codec->i4_pic_order_cnt_lsb;
1771
1772 ps_cur_pic->i4_buf_id = cur_pic_buf_id;
1773
1774 pu1_cur_pic_luma = ps_cur_pic->pu1_luma;
1775 pu1_cur_pic_chroma = ps_cur_pic->pu1_chroma;
1776 }
1777
Harinarayanan K K134291e2015-06-18 16:03:38 +05301778 /*
1779 * Add the current picture to ref list independent of the fact that it is used
1780 * as reference or not. This is because, now recon is not in sync with output
1781 * hence we may need the current recon after some delay. By adding it to ref list
1782 * we can retrieve the recon any time we want. The information that it is used
1783 * for ref can still be found by checking the buffer status of pic buf.
1784 */
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301785 {
1786 ps_codec->as_ref_set[ref_set_id].i4_pic_cnt = ps_codec->i4_pic_cnt;
Harinarayanan K K134291e2015-06-18 16:03:38 +05301787 ps_codec->as_ref_set[ref_set_id].i4_poc = ps_codec->i4_poc;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301788 ps_codec->as_ref_set[ref_set_id].ps_mv_buf = ps_mv_buf;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301789 ps_codec->as_ref_set[ref_set_id].ps_pic_buf = ps_cur_pic;
1790 }
1791
1792 /********************************************************************/
1793 /* INITIALIZE PROCESS CONTEXT */
1794 /********************************************************************/
1795 {
1796 /* temp var */
1797 WORD32 i, j = 0;
1798
1799 /* curr proc ctxt */
1800 process_ctxt_t *ps_proc = NULL;
1801
1802 j = ctxt_sel * MAX_PROCESS_THREADS;
1803
1804 /* begin init */
1805 for (i = j; i < (j + MAX_PROCESS_THREADS); i++)
1806 {
1807 ps_proc = &ps_codec->as_process[i];
1808
1809 /* luma src buffer */
1810 if (ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_422ILE)
1811 {
1812 ps_proc->pu1_src_buf_luma_base = ps_codec->pu1_y_csc_buf_base;
1813 }
1814 else
1815 {
1816 ps_proc->pu1_src_buf_luma_base =
1817 ps_inp_buf->s_raw_buf.apv_bufs[0];
1818 }
1819
1820 /* chroma src buffer */
1821 if (ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_422ILE
1822 || ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420P)
1823 {
1824 ps_proc->pu1_src_buf_chroma_base =
1825 ps_codec->pu1_uv_csc_buf_base;
1826 }
1827 else
1828 {
1829 ps_proc->pu1_src_buf_chroma_base =
1830 ps_inp_buf->s_raw_buf.apv_bufs[1];
1831 }
1832
1833 /* luma rec buffer */
1834 ps_proc->pu1_rec_buf_luma_base = pu1_cur_pic_luma;
1835
1836 /* chroma rec buffer */
1837 ps_proc->pu1_rec_buf_chroma_base = pu1_cur_pic_chroma;
1838
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301839 /* rec stride */
1840 ps_proc->i4_rec_strd = ps_codec->i4_rec_strd;
1841
1842 /* frame num */
1843 ps_proc->i4_frame_num = ps_codec->i4_frame_num;
1844
1845 /* is idr */
1846 ps_proc->u4_is_idr = ps_codec->u4_is_idr;
1847
1848 /* idr pic id */
1849 ps_proc->u4_idr_pic_id = ps_codec->i4_idr_pic_id;
1850
1851 /* slice_type */
1852 ps_proc->i4_slice_type = ps_codec->i4_slice_type;
1853
1854 /* Input width in mbs */
1855 ps_proc->i4_wd_mbs = ps_codec->s_cfg.i4_wd_mbs;
1856
1857 /* Input height in mbs */
1858 ps_proc->i4_ht_mbs = ps_codec->s_cfg.i4_ht_mbs;
1859
1860 /* Half x plane offset from pic buf */
1861 ps_proc->u4_half_x_offset = 0;
1862
1863 /* Half y plane offset from half x plane */
1864 ps_proc->u4_half_y_offset = 0;
1865
1866 /* Half x plane offset from half y plane */
1867 ps_proc->u4_half_xy_offset = 0;
1868
1869 /* top row syntax elements */
1870 ps_proc->ps_top_row_mb_syntax_ele =
1871 ps_proc->ps_top_row_mb_syntax_ele_base;
1872
1873 ps_proc->pu1_top_mb_intra_modes =
1874 ps_proc->pu1_top_mb_intra_modes_base;
1875
1876 ps_proc->ps_top_row_pu = ps_proc->ps_top_row_pu_base;
1877
1878 /* initialize quant params */
1879 ps_proc->u4_frame_qp = ps_codec->u4_frame_qp;
1880 ps_proc->u4_mb_qp = ps_codec->u4_frame_qp;
1881 ih264e_init_quant_params(ps_proc, ps_proc->u4_frame_qp);
1882
1883 /* previous mb qp*/
1884 ps_proc->u4_mb_qp_prev = ps_proc->u4_frame_qp;
1885
1886 /* Reset frame info */
1887 memset(&ps_proc->s_frame_info, 0, sizeof(frame_info_t));
1888
1889 /* initialize proc, deblk and ME map */
1890 if (i == j)
1891 {
1892 /* row '-1' */
1893 memset(ps_proc->pu1_proc_map - ps_proc->i4_wd_mbs, 1, ps_proc->i4_wd_mbs);
1894 /* row 0 to ht in mbs */
1895 memset(ps_proc->pu1_proc_map, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
1896
1897 /* row '-1' */
1898 memset(ps_proc->pu1_deblk_map - ps_proc->i4_wd_mbs, 1, ps_proc->i4_wd_mbs);
1899 /* row 0 to ht in mbs */
1900 memset(ps_proc->pu1_deblk_map, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
1901
1902 /* row '-1' */
1903 memset(ps_proc->pu1_me_map - ps_proc->i4_wd_mbs, 1, ps_proc->i4_wd_mbs);
1904 /* row 0 to ht in mbs */
1905 memset(ps_proc->pu1_me_map, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
1906
1907 /* at the start of air refresh period, reset intra coded map */
1908 if (IVE_AIR_MODE_NONE != ps_codec->s_cfg.e_air_mode)
1909 {
1910 ps_codec->i4_air_pic_cnt = (ps_codec->i4_air_pic_cnt + 1)
1911 % ps_codec->s_cfg.u4_air_refresh_period;
1912
1913 if (!ps_codec->i4_air_pic_cnt)
1914 {
1915 memset(ps_proc->pu1_is_intra_coded, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
1916 }
1917 }
1918 }
1919
1920 /* deblock level */
1921 ps_proc->u4_disable_deblock_level = ps_codec->i4_disable_deblk_pic;
1922
1923 /* slice index map */
1924 /* no slice */
1925 if (ps_codec->s_cfg.e_slice_mode == IVE_SLICE_MODE_NONE)
1926 {
1927 memset(ps_proc->pu1_slice_idx, 0, ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs);
1928 }
1929 /* generate slices for every 'n' rows, 'n' is given through slice param */
1930 else if (ps_codec->s_cfg.e_slice_mode == IVE_SLICE_MODE_BLOCKS)
1931 {
1932 /* slice idx map */
1933 UWORD8 *pu1_slice_idx = ps_proc->pu1_slice_idx;
1934
1935 /* temp var */
1936 WORD32 i4_mb_y = 0, slice_idx = 0, cnt;
1937
1938 while (i4_mb_y < ps_proc->i4_ht_mbs)
1939 {
1940 if (i4_mb_y +(WORD32)ps_codec->s_cfg.u4_slice_param < ps_proc->i4_ht_mbs)
1941 {
1942 cnt = ps_codec->s_cfg.u4_slice_param * ps_proc->i4_wd_mbs;
1943 i4_mb_y += ps_codec->s_cfg.u4_slice_param;
1944 }
1945 else
1946 {
1947 cnt = (ps_proc->i4_ht_mbs - i4_mb_y) * ps_proc->i4_wd_mbs;
1948 i4_mb_y += (ps_proc->i4_ht_mbs - i4_mb_y);
1949 }
1950 memset(pu1_slice_idx, slice_idx, cnt);
1951 slice_idx++;
1952 pu1_slice_idx += cnt;
1953 }
1954 }
1955
1956 /* Current MV Bank's buffer ID */
1957 ps_proc->i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id;
1958
1959 /* Pointer to current picture buffer structure */
1960 ps_proc->ps_cur_pic = ps_cur_pic;
1961
1962 /* Pointer to current pictures mv buffers */
1963 ps_proc->ps_cur_mv_buf = ps_mv_buf;
1964
Harinarayanan K K134291e2015-06-18 16:03:38 +05301965 /*
1966 * pointer to ref picture
1967 * 0 : Temporal back reference
1968 * 1 : Temporal forward reference
1969 */
1970 ps_proc->aps_ref_pic[PRED_L0] = aps_ref_pic[PRED_L0];
1971 ps_proc->aps_ref_pic[PRED_L1] = aps_ref_pic[PRED_L1];
1972 if (ps_codec->pic_type == PIC_B)
1973 {
1974 ps_proc->aps_mv_buf[PRED_L0] = aps_mv_buf[PRED_L0];
1975 ps_proc->aps_mv_buf[PRED_L1] = aps_mv_buf[PRED_L1];
1976 }
1977 else
1978 {
1979 /*
1980 * Else is dummy since for non B pic we does not need this
1981 * But an assignment here will help in not having a segfault
1982 * when we calcualte colpic in P slices
1983 */
1984 ps_proc->aps_mv_buf[PRED_L0] = ps_mv_buf;
1985 ps_proc->aps_mv_buf[PRED_L1] = ps_mv_buf;
1986 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301987
1988 if ((*pic_type != PIC_IDR) && (*pic_type != PIC_I))
1989 {
Harinarayanan K K134291e2015-06-18 16:03:38 +05301990 /* temporal back an forward ref pointer luma and chroma */
1991 ps_proc->apu1_ref_buf_luma_base[PRED_L0] = aps_ref_pic[PRED_L0]->pu1_luma;
1992 ps_proc->apu1_ref_buf_chroma_base[PRED_L0] = aps_ref_pic[PRED_L0]->pu1_chroma;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301993
Harinarayanan K K134291e2015-06-18 16:03:38 +05301994 ps_proc->apu1_ref_buf_luma_base[PRED_L1] = aps_ref_pic[PRED_L1]->pu1_luma;
1995 ps_proc->apu1_ref_buf_chroma_base[PRED_L1] = aps_ref_pic[PRED_L1]->pu1_chroma;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301996 }
1997
1998 /* Structure for current input buffer */
1999 ps_proc->s_inp_buf = *ps_inp_buf;
2000
2001 /* Number of encode frame API calls made */
2002 ps_proc->i4_encode_api_call_cnt = ps_codec->i4_encode_api_call_cnt;
2003
2004 /* Current Picture count */
2005 ps_proc->i4_pic_cnt = ps_codec->i4_pic_cnt;
2006
2007 /* error status */
2008 ps_proc->i4_error_code = 0;
2009
2010 /********************************************************************/
2011 /* INITIALIZE ENTROPY CONTEXT */
2012 /********************************************************************/
2013 {
2014 entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
2015
2016 /* start of frame */
2017 ps_entropy->i4_sof = 0;
2018
2019 /* end of frame */
2020 ps_entropy->i4_eof = 0;
2021
2022 /* generate header */
2023 ps_entropy->i4_gen_header = ps_codec->i4_gen_header;
2024
2025 /* sps ref_set_id */
2026 ps_entropy->u4_sps_id = ps_codec->i4_sps_id;
2027
2028 /* sps base */
2029 ps_entropy->ps_sps_base = ps_codec->ps_sps_base;
2030
2031 /* sps id */
2032 ps_entropy->u4_pps_id = ps_codec->i4_pps_id;
2033
2034 /* sps base */
2035 ps_entropy->ps_pps_base = ps_codec->ps_pps_base;
2036
2037 /* slice map */
2038 ps_entropy->pu1_slice_idx = ps_proc->pu1_slice_idx;
2039
2040 /* slice hdr base */
2041 ps_entropy->ps_slice_hdr_base = ps_proc->ps_slice_hdr_base;
2042
Harinarayanan K K134291e2015-06-18 16:03:38 +05302043 /* Abs poc */
2044 ps_entropy->i4_abs_pic_order_cnt = ps_proc->ps_codec->i4_poc;
2045
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302046 /* initialize entropy map */
2047 if (i == j)
2048 {
2049 /* row '-1' */
2050 memset(ps_entropy->pu1_entropy_map - ps_proc->i4_wd_mbs, 1, ps_proc->i4_wd_mbs);
2051 /* row 0 to ht in mbs */
2052 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 +05302053
2054 /* intialize cabac tables */
2055 ih264e_init_cabac_table(ps_entropy);
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302056 }
2057
2058 /* wd in mbs */
2059 ps_entropy->i4_wd_mbs = ps_proc->i4_wd_mbs;
2060
2061 /* ht in mbs */
2062 ps_entropy->i4_ht_mbs = ps_proc->i4_ht_mbs;
2063
2064 /* transform_8x8_mode_flag */
2065 ps_entropy->i1_transform_8x8_mode_flag = 0;
2066
2067 /* entropy_coding_mode_flag */
2068 ps_entropy->u1_entropy_coding_mode_flag =
2069 ps_codec->s_cfg.u4_entropy_coding_mode;
2070
2071 /* error code */
2072 ps_entropy->i4_error_code = IH264E_SUCCESS;
2073
2074 /* mb skip run */
2075 *(ps_proc->s_entropy.pi4_mb_skip_run) = 0;
2076
2077 /* last frame to encode */
2078 ps_proc->s_entropy.u4_is_last = ps_inp_buf->u4_is_last;
2079
2080 /* Current Picture count */
2081 ps_proc->s_entropy.i4_pic_cnt = ps_codec->i4_pic_cnt;
2082
2083 /* time stamps */
2084 ps_entropy->u4_timestamp_low = u4_timestamp_low;
2085 ps_entropy->u4_timestamp_high = u4_timestamp_high;
2086
2087 /* init frame statistics */
2088 ps_entropy->u4_header_bits[MB_TYPE_INTRA] = 0;
2089 ps_entropy->u4_header_bits[MB_TYPE_INTER] = 0;
2090 ps_entropy->u4_residue_bits[MB_TYPE_INTRA] = 0;
2091 ps_entropy->u4_residue_bits[MB_TYPE_INTER] = 0;
2092 }
2093
2094 /********************************************************************/
2095 /* INITIALIZE DEBLOCK CONTEXT */
2096 /********************************************************************/
2097 {
2098 /* deblk ctxt */
2099 deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
2100
2101 /* slice idx map */
2102 ps_deblk->pu1_slice_idx = ps_proc->pu1_slice_idx;
2103 }
2104
2105 /********************************************************************/
2106 /* INITIALIZE ME CONTEXT */
2107 /********************************************************************/
2108 {
2109 /* me ctxt */
2110 me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
2111
2112 /* srch range x */
2113 ps_me_ctxt->ai2_srch_boundaries[0] =
2114 ps_codec->s_cfg.u4_srch_rng_x;
2115
2116 /* srch range y */
2117 ps_me_ctxt->ai2_srch_boundaries[1] =
2118 ps_codec->s_cfg.u4_srch_rng_y;
2119
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302120 /* rec stride */
2121 ps_me_ctxt->i4_rec_strd = ps_codec->i4_rec_strd;
2122
2123 /* Half x plane offset from pic buf */
2124 ps_me_ctxt->u4_half_x_offset = ps_proc->u4_half_x_offset;
2125
2126 /* Half y plane offset from half x plane */
2127 ps_me_ctxt->u4_half_y_offset = ps_proc->u4_half_y_offset;
2128
2129 /* Half x plane offset from half y plane */
2130 ps_me_ctxt->u4_half_xy_offset = ps_proc->u4_half_xy_offset;
2131
2132 /* enable fast sad */
2133 ps_me_ctxt->u4_enable_fast_sad = u4_enable_fast_sad;
2134
2135 /* half pel */
2136 ps_me_ctxt->u4_enable_hpel = ps_codec->s_cfg.u4_enable_hpel;
2137
2138 /* Diamond search Iteration Max Cnt */
2139 ps_me_ctxt->u4_num_layers = u4_num_layers;
2140
2141 /* me speed preset */
2142 ps_me_ctxt->u4_me_speed_preset =
2143 ps_codec->s_cfg.u4_me_speed_preset;
2144
2145 /* qp */
2146 ps_me_ctxt->u1_mb_qp = ps_codec->u4_frame_qp;
2147
Harinarayanan K K134291e2015-06-18 16:03:38 +05302148 if ((i == j) && (0 == ps_codec->i4_poc))
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302149 {
2150 /* init mv bits tables */
2151 ih264e_init_mv_bits(ps_me_ctxt);
2152 }
2153 }
2154
2155 ps_proc->ps_ngbr_avbl = &(ps_proc->s_ngbr_avbl);
2156
2157 }
2158
2159 /* reset encoder header */
2160 ps_codec->i4_gen_header = 0;
2161 }
2162
2163 /********************************************************************/
2164 /* ADD JOBS TO THE QUEUE */
2165 /********************************************************************/
2166 {
2167 /* job structures */
2168 job_t s_job;
2169
2170 /* temp var */
2171 WORD32 i;
2172
2173 /* job class */
2174 s_job.i4_cmd = CMD_PROCESS;
2175
2176 /* number of mbs to be processed in the current job */
2177 s_job.i2_mb_cnt = ps_codec->s_cfg.i4_wd_mbs;
2178
2179 /* job start index x */
2180 s_job.i2_mb_x = 0;
2181
2182 /* proc base idx */
2183 s_job.i2_proc_base_idx = ctxt_sel ? (MAX_PROCESS_CTXT / 2) : 0;
2184
2185 for (i = 0; i < (WORD32)ps_codec->s_cfg.i4_ht_mbs; i++)
2186 {
2187 /* job start index y */
2188 s_job.i2_mb_y = i;
2189
2190 /* queue the job */
2191 ret = ih264_list_queue(ps_codec->pv_proc_jobq, &s_job, 1);
2192 if (ret != IH264_SUCCESS)
2193 {
2194 ps_codec->i4_error_code = ret;
2195 return IH264E_FAIL;
2196 }
2197 }
2198
2199 /* Once all the jobs are queued, terminate the queue */
2200 /* Since the threads are created and deleted in each call, terminating
2201 here is not an issue */
2202 ih264_list_terminate(ps_codec->pv_proc_jobq);
2203 }
2204
2205 return error_status;
2206}