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