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