/src/libavc/encoder/ih264e_encode.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_encode.c |
25 | | * |
26 | | * @brief |
27 | | * This file contains functions for encoding the input yuv frame in synchronous |
28 | | * api mode |
29 | | * |
30 | | * @author |
31 | | * ittiam |
32 | | * |
33 | | * List of Functions |
34 | | * - ih264e_join_threads |
35 | | * - ih264e_wait_for_thread |
36 | | * - ih264e_encode |
37 | | * |
38 | | ****************************************************************************** |
39 | | */ |
40 | | |
41 | | /*****************************************************************************/ |
42 | | /* File Includes */ |
43 | | /*****************************************************************************/ |
44 | | |
45 | | /* System Include files */ |
46 | | #include <stdio.h> |
47 | | #include <stddef.h> |
48 | | #include <stdlib.h> |
49 | | #include <string.h> |
50 | | #include <assert.h> |
51 | | #include <limits.h> |
52 | | #include <stdbool.h> |
53 | | |
54 | | /* User Include Files */ |
55 | | #include "ih264e_config.h" |
56 | | #include "ih264_typedefs.h" |
57 | | #include "iv2.h" |
58 | | #include "ive2.h" |
59 | | #include "ithread.h" |
60 | | |
61 | | #include "ih264_debug.h" |
62 | | #include "ih264_macros.h" |
63 | | #include "ih264_error.h" |
64 | | #include "ih264_defs.h" |
65 | | #include "ih264_mem_fns.h" |
66 | | #include "ih264_padding.h" |
67 | | #include "ih264_structs.h" |
68 | | #include "ih264_trans_quant_itrans_iquant.h" |
69 | | #include "ih264_inter_pred_filters.h" |
70 | | #include "ih264_intra_pred_filters.h" |
71 | | #include "ih264_deblk_edge_filters.h" |
72 | | #include "ih264_cabac_tables.h" |
73 | | #include "ih264_buf_mgr.h" |
74 | | #include "ih264_list.h" |
75 | | #include "ih264_dpb_mgr.h" |
76 | | #include "ih264_platform_macros.h" |
77 | | |
78 | | #include "ime_defs.h" |
79 | | #include "ime_distortion_metrics.h" |
80 | | #include "ime_structs.h" |
81 | | |
82 | | #include "irc_mem_req_and_acq.h" |
83 | | #include "irc_cntrl_param.h" |
84 | | #include "irc_frame_info_collector.h" |
85 | | |
86 | | #include "ih264e.h" |
87 | | #include "ih264e_error.h" |
88 | | #include "ih264e_defs.h" |
89 | | #include "ih264e_time_stamp.h" |
90 | | #include "ih264e_rate_control.h" |
91 | | #include "ih264e_bitstream.h" |
92 | | #include "ih264e_cabac_structs.h" |
93 | | #include "ih264e_structs.h" |
94 | | #include "ih264e_utils.h" |
95 | | #include "ih264e_encode_header.h" |
96 | | #include "ih264e_master.h" |
97 | | #include "ih264e_process.h" |
98 | | #include "ih264e_fmt_conv.h" |
99 | | #include "ih264e_statistics.h" |
100 | | #include "ih264e_trace.h" |
101 | | #ifdef LOGO_EN |
102 | | #include "ih264e_ittiam_logo.h" |
103 | | #endif |
104 | | |
105 | | |
106 | | #define SEI_BASED_FORCE_IDR 1 |
107 | | |
108 | | /*****************************************************************************/ |
109 | | /* Function Definitions */ |
110 | | /*****************************************************************************/ |
111 | | |
112 | | /** |
113 | | ****************************************************************************** |
114 | | * |
115 | | * @brief |
116 | | * This function joins all the spawned threads after successful completion of |
117 | | * their tasks |
118 | | * |
119 | | * @par Description |
120 | | * |
121 | | * @param[in] ps_codec |
122 | | * pointer to codec context |
123 | | * |
124 | | * @returns none |
125 | | * |
126 | | ****************************************************************************** |
127 | | */ |
128 | | void ih264e_join_threads(codec_t *ps_codec) |
129 | 41.7k | { |
130 | | /* temp var */ |
131 | 41.7k | WORD32 i = 0; |
132 | 41.7k | WORD32 ret = 0; |
133 | | |
134 | | /* join spawned threads */ |
135 | 175k | while (i < ps_codec->i4_proc_thread_cnt) |
136 | 133k | { |
137 | 133k | if (ps_codec->ai4_process_thread_created[i]) |
138 | 133k | { |
139 | 133k | ret = ithread_join(ps_codec->apv_proc_thread_handle[i], NULL); |
140 | 133k | if (ret != 0) |
141 | 0 | { |
142 | 0 | printf("pthread Join Failed"); |
143 | 0 | assert(0); |
144 | 0 | } |
145 | 133k | ps_codec->ai4_process_thread_created[i] = 0; |
146 | 133k | i++; |
147 | 133k | } |
148 | 133k | } |
149 | | |
150 | 41.7k | ps_codec->i4_proc_thread_cnt = 0; |
151 | 41.7k | } |
152 | | |
153 | | /** |
154 | | ****************************************************************************** |
155 | | * |
156 | | * @brief This function puts the current thread to sleep for a duration |
157 | | * of sleep_us |
158 | | * |
159 | | * @par Description |
160 | | * ithread_yield() method causes the calling thread to yield execution to another |
161 | | * thread that is ready to run on the current processor. The operating system |
162 | | * selects the thread to yield to. ithread_usleep blocks the current thread for |
163 | | * the specified number of milliseconds. In other words, yield just says, |
164 | | * end my timeslice prematurely, look around for other threads to run. If there |
165 | | * is nothing better than me, continue. Sleep says I don't want to run for x |
166 | | * milliseconds. Even if no other thread wants to run, don't make me run. |
167 | | * |
168 | | * @param[in] sleep_us |
169 | | * thread sleep duration |
170 | | * |
171 | | * @returns error_status |
172 | | * |
173 | | ****************************************************************************** |
174 | | */ |
175 | | IH264E_ERROR_T ih264e_wait_for_thread(UWORD32 sleep_us) |
176 | 0 | { |
177 | | /* yield thread */ |
178 | 0 | ithread_yield(); |
179 | | |
180 | | /* put thread to sleep */ |
181 | 0 | ithread_usleep(sleep_us); |
182 | |
|
183 | 0 | return IH264E_SUCCESS; |
184 | 0 | } |
185 | | |
186 | | /** |
187 | | ******************************************************************************* |
188 | | * |
189 | | * @brief |
190 | | * Used to test validity of input dimensions |
191 | | * |
192 | | * @par Description: |
193 | | * Dimensions of the input buffer passed to encode call are validated |
194 | | * |
195 | | * @param[in] ps_codec |
196 | | * Codec context |
197 | | * |
198 | | * @param[in] ps_ip |
199 | | * Pointer to input structure |
200 | | * |
201 | | * @param[out] ps_op |
202 | | * Pointer to output structure |
203 | | * |
204 | | * @returns error status |
205 | | * |
206 | | * @remarks none |
207 | | * |
208 | | ******************************************************************************* |
209 | | */ |
210 | | static IV_STATUS_T api_check_input_dimensions(codec_t *ps_codec, |
211 | | ih264e_video_encode_ip_t *ps_ip, |
212 | | ih264e_video_encode_op_t *ps_op) |
213 | 44.1k | { |
214 | 44.1k | UWORD32 u4_wd, u4_ht; |
215 | 44.1k | cfg_params_t *ps_curr_cfg = &ps_codec->s_cfg; |
216 | 44.1k | iv_raw_buf_t *ps_inp_buf = &ps_ip->s_ive_ip.s_inp_buf; |
217 | | |
218 | 44.1k | u4_wd = ps_inp_buf->au4_wd[0]; |
219 | 44.1k | u4_ht = ps_inp_buf->au4_ht[0]; |
220 | 44.1k | switch (ps_inp_buf->e_color_fmt) |
221 | 44.1k | { |
222 | 24.4k | case IV_YUV_420P: |
223 | 24.4k | if (((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[1]) || |
224 | 24.4k | ((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[2]) || |
225 | 24.4k | (ps_inp_buf->au4_wd[1] != ps_inp_buf->au4_wd[2])) |
226 | 0 | { |
227 | 0 | ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
228 | 0 | ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED; |
229 | 0 | return (IV_FAIL); |
230 | 0 | } |
231 | 24.4k | if (((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[1]) || |
232 | 24.4k | ((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[2]) || |
233 | 24.4k | (ps_inp_buf->au4_ht[1] != ps_inp_buf->au4_ht[2])) |
234 | 0 | { |
235 | 0 | ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
236 | 0 | ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED; |
237 | 0 | return (IV_FAIL); |
238 | 0 | } |
239 | 24.4k | break; |
240 | 24.4k | case IV_YUV_420SP_UV: |
241 | 18.4k | case IV_YUV_420SP_VU: |
242 | 18.4k | if (ps_inp_buf->au4_wd[0] != ps_inp_buf->au4_wd[1]) |
243 | 0 | { |
244 | 0 | ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
245 | 0 | ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED; |
246 | 0 | return (IV_FAIL); |
247 | 0 | } |
248 | 18.4k | if ((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[1]) |
249 | 0 | { |
250 | 0 | ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
251 | 0 | ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED; |
252 | 0 | return (IV_FAIL); |
253 | 0 | } |
254 | 18.4k | break; |
255 | 18.4k | case IV_YUV_422ILE: |
256 | 1.25k | u4_wd = ps_inp_buf->au4_wd[0] / 2; |
257 | 1.25k | break; |
258 | 0 | default: |
259 | 0 | ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
260 | 0 | ps_op->s_ive_op.u4_error_code |= IH264E_INPUT_CHROMA_FORMAT_NOT_SUPPORTED; |
261 | 0 | return (IV_FAIL); |
262 | 44.1k | } |
263 | | |
264 | 44.1k | if (u4_wd != ps_curr_cfg->u4_disp_wd) |
265 | 88 | { |
266 | 88 | ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
267 | 88 | ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED; |
268 | 88 | return (IV_FAIL); |
269 | 88 | } |
270 | | |
271 | 44.0k | if (u4_ht != ps_curr_cfg->u4_disp_ht) |
272 | 7 | { |
273 | 7 | ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
274 | 7 | ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED; |
275 | 7 | return (IV_FAIL); |
276 | 7 | } |
277 | | |
278 | 44.0k | return IV_SUCCESS; |
279 | 44.0k | } |
280 | | |
281 | | /** |
282 | | ****************************************************************************** |
283 | | * |
284 | | * @brief |
285 | | * Encodes in synchronous api mode |
286 | | * |
287 | | * @par Description |
288 | | * This routine processes input yuv, encodes it and outputs bitstream and recon |
289 | | * |
290 | | * @param[in] ps_codec_obj |
291 | | * Pointer to codec object at API level |
292 | | * |
293 | | * @param[in] pv_api_ip |
294 | | * Pointer to input argument structure |
295 | | * |
296 | | * @param[out] pv_api_op |
297 | | * Pointer to output argument structure |
298 | | * |
299 | | * @returns Status |
300 | | * |
301 | | ****************************************************************************** |
302 | | */ |
303 | | WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) |
304 | 77.0k | { |
305 | | /* error status */ |
306 | 77.0k | IH264E_ERROR_T error_status = IH264E_SUCCESS; |
307 | | |
308 | | /* codec ctxt */ |
309 | 77.0k | codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; |
310 | | |
311 | | /* input frame to encode */ |
312 | 77.0k | ih264e_video_encode_ip_t *ps_video_encode_ip = pv_api_ip; |
313 | | |
314 | | /* output buffer to write stream */ |
315 | 77.0k | ih264e_video_encode_op_t *ps_video_encode_op = pv_api_op; |
316 | | |
317 | | /* i/o structures */ |
318 | 77.0k | inp_buf_t s_inp_buf = {}; |
319 | 77.0k | out_buf_t s_out_buf = {}; |
320 | | |
321 | | /* temp var */ |
322 | 77.0k | WORD32 ctxt_sel = 0, i, i4_rc_pre_enc_skip; |
323 | | |
324 | | /********************************************************************/ |
325 | | /* BEGIN INIT */ |
326 | | /********************************************************************/ |
327 | | /* reset output structure */ |
328 | 77.0k | ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS; |
329 | 77.0k | ps_video_encode_op->s_ive_op.output_present = 0; |
330 | 77.0k | ps_video_encode_op->s_ive_op.dump_recon = 0; |
331 | 77.0k | ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME; |
332 | | /* By default set the current input buffer as the buffer to be freed */ |
333 | | /* This will later be updated to the actual input that gets encoded */ |
334 | 77.0k | ps_video_encode_op->s_ive_op.s_inp_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf; |
335 | | |
336 | 77.0k | if (ps_codec->i4_error_code & (1 << IVE_FATALERROR)) |
337 | 9.91k | { |
338 | 9.91k | error_status = ps_codec->i4_error_code & 0xFF; |
339 | 9.91k | SET_ERROR_ON_RETURN(error_status, |
340 | 9.91k | IVE_FATALERROR, |
341 | 9.91k | ps_video_encode_op->s_ive_op.u4_error_code, |
342 | 9.91k | IV_FAIL); |
343 | 0 | } |
344 | | |
345 | | /* Check for output memory allocation size */ |
346 | 67.1k | if (ps_video_encode_ip->s_ive_ip.s_out_buf.u4_bufsize < MIN_STREAM_SIZE) |
347 | 48.6k | { |
348 | 48.6k | error_status = IH264E_INSUFFICIENT_OUTPUT_BUFFER; |
349 | 48.6k | SET_ERROR_ON_RETURN(error_status, |
350 | 48.6k | IVE_UNSUPPORTEDPARAM, |
351 | 48.6k | ps_video_encode_op->s_ive_op.u4_error_code, |
352 | 48.6k | IV_FAIL); |
353 | 48.6k | } |
354 | | |
355 | 67.1k | if (ps_codec->i4_init_done != 1) |
356 | 0 | { |
357 | 0 | error_status = IH264E_INIT_NOT_DONE; |
358 | 0 | SET_ERROR_ON_RETURN(error_status, |
359 | 0 | IVE_FATALERROR, |
360 | 0 | ps_video_encode_op->s_ive_op.u4_error_code, |
361 | 0 | IV_FAIL); |
362 | 0 | } |
363 | | |
364 | | /* copy output info. to internal structure */ |
365 | 67.1k | s_out_buf.s_bits_buf = ps_video_encode_ip->s_ive_ip.s_out_buf; |
366 | 67.1k | s_out_buf.u4_is_last = 0; |
367 | 67.1k | s_out_buf.u4_timestamp_low = ps_video_encode_ip->s_ive_ip.u4_timestamp_low; |
368 | 67.1k | s_out_buf.u4_timestamp_high = ps_video_encode_ip->s_ive_ip.u4_timestamp_high; |
369 | | |
370 | | /* api call cnt */ |
371 | 67.1k | ps_codec->i4_encode_api_call_cnt += 1; |
372 | | |
373 | | /* codec context selector */ |
374 | 67.1k | ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS; |
375 | | |
376 | | /* reset status flags */ |
377 | 67.1k | ps_codec->ai4_pic_cnt[ctxt_sel] = -1; |
378 | 67.1k | ps_codec->s_rate_control.post_encode_skip[ctxt_sel] = 0; |
379 | 67.1k | ps_codec->s_rate_control.pre_encode_skip[ctxt_sel] = 0; |
380 | | |
381 | | /* pass output buffer to codec */ |
382 | 67.1k | ps_codec->as_out_buf[ctxt_sel] = s_out_buf; |
383 | | |
384 | | /* initialize codec ctxt with default params for the first encode api call */ |
385 | 67.1k | if (ps_codec->i4_encode_api_call_cnt == 0) |
386 | 11.2k | { |
387 | 11.2k | ih264e_codec_init(ps_codec); |
388 | 11.2k | } |
389 | | |
390 | | /* parse configuration params */ |
391 | 2.21M | for (i = 0; i < MAX_ACTIVE_CONFIG_PARAMS; i++) |
392 | 2.14M | { |
393 | 2.14M | cfg_params_t *ps_cfg = &ps_codec->as_cfg[i]; |
394 | | |
395 | 2.14M | if (1 == ps_cfg->u4_is_valid) |
396 | 105k | { |
397 | 105k | if ( ((ps_cfg->u4_timestamp_high == ps_video_encode_ip->s_ive_ip.u4_timestamp_high) && |
398 | 105k | (ps_cfg->u4_timestamp_low == ps_video_encode_ip->s_ive_ip.u4_timestamp_low)) || |
399 | 105k | ((WORD32)ps_cfg->u4_timestamp_high == -1) || |
400 | 105k | ((WORD32)ps_cfg->u4_timestamp_low == -1) ) |
401 | 105k | { |
402 | 105k | error_status = ih264e_codec_update_config(ps_codec, ps_cfg); |
403 | 105k | SET_ERROR_ON_RETURN(error_status, |
404 | 105k | IVE_FATALERROR, |
405 | 105k | ps_video_encode_op->s_ive_op.u4_error_code, |
406 | 105k | IV_FAIL); |
407 | | |
408 | 105k | ps_cfg->u4_is_valid = 0; |
409 | 105k | } |
410 | 105k | } |
411 | 2.14M | } |
412 | | /* Force IDR based on SEI params */ |
413 | 67.1k | #if SEI_BASED_FORCE_IDR |
414 | 67.1k | { |
415 | 67.1k | int i; |
416 | 67.1k | bool au4_sub_layer_num_units_in_shutter_interval_flag = 0; |
417 | | |
418 | 67.1k | sei_mdcv_params_t *ps_sei_mdcv_params = &ps_codec->s_sei.s_sei_mdcv_params; |
419 | 67.1k | sei_mdcv_params_t *ps_cfg_sei_mdcv_params = |
420 | 67.1k | &ps_codec->s_cfg.s_sei.s_sei_mdcv_params; |
421 | 67.1k | sei_cll_params_t *ps_sei_cll_params = &ps_codec->s_sei.s_sei_cll_params; |
422 | 67.1k | sei_cll_params_t *ps_cfg_sei_cll_params = |
423 | 67.1k | &ps_codec->s_cfg.s_sei.s_sei_cll_params; |
424 | 67.1k | sei_ave_params_t *ps_sei_ave_params = &ps_codec->s_sei.s_sei_ave_params; |
425 | 67.1k | sei_ave_params_t *ps_cfg_sei_ave_params = |
426 | 67.1k | &ps_codec->s_cfg.s_sei.s_sei_ave_params; |
427 | 67.1k | sei_sii_params_t *ps_sei_sii_params = &ps_codec->s_sei.s_sei_sii_params; |
428 | 67.1k | sei_sii_params_t *ps_cfg_sei_sii_params = &ps_codec->s_cfg.s_sei.s_sei_sii_params; |
429 | | |
430 | 67.1k | if((ps_sei_mdcv_params->au2_display_primaries_x[0]!= |
431 | 67.1k | ps_cfg_sei_mdcv_params->au2_display_primaries_x[0]) || |
432 | 67.1k | (ps_sei_mdcv_params->au2_display_primaries_x[1] != |
433 | 64.4k | ps_cfg_sei_mdcv_params->au2_display_primaries_x[1]) || |
434 | 67.1k | (ps_sei_mdcv_params->au2_display_primaries_x[2] != |
435 | 64.4k | ps_cfg_sei_mdcv_params->au2_display_primaries_x[2]) || |
436 | 67.1k | (ps_sei_mdcv_params->au2_display_primaries_y[0] != |
437 | 64.4k | ps_cfg_sei_mdcv_params->au2_display_primaries_y[0]) || |
438 | 67.1k | (ps_sei_mdcv_params->au2_display_primaries_y[1] != |
439 | 64.4k | ps_cfg_sei_mdcv_params->au2_display_primaries_y[1]) || |
440 | 67.1k | (ps_sei_mdcv_params->au2_display_primaries_y[2] != |
441 | 64.4k | ps_cfg_sei_mdcv_params->au2_display_primaries_y[2]) || |
442 | 67.1k | (ps_sei_mdcv_params->u2_white_point_x != |
443 | 64.4k | ps_cfg_sei_mdcv_params->u2_white_point_x) || |
444 | 67.1k | (ps_sei_mdcv_params->u2_white_point_y != |
445 | 64.4k | ps_cfg_sei_mdcv_params->u2_white_point_y) || |
446 | 67.1k | (ps_sei_mdcv_params->u4_max_display_mastering_luminance != |
447 | 64.4k | ps_cfg_sei_mdcv_params->u4_max_display_mastering_luminance) || |
448 | 67.1k | (ps_sei_mdcv_params->u4_min_display_mastering_luminance != |
449 | 64.4k | ps_cfg_sei_mdcv_params->u4_min_display_mastering_luminance)) |
450 | 2.65k | { |
451 | 2.65k | ps_codec->s_sei.s_sei_mdcv_params = ps_codec->s_cfg.s_sei.s_sei_mdcv_params; |
452 | 2.65k | ps_codec->s_sei.u1_sei_mdcv_params_present_flag = 1; |
453 | 2.65k | } |
454 | 64.4k | else |
455 | 64.4k | { |
456 | 64.4k | ps_codec->s_sei.u1_sei_mdcv_params_present_flag = 0; |
457 | 64.4k | } |
458 | | |
459 | 67.1k | if((ps_sei_cll_params->u2_max_content_light_level != |
460 | 67.1k | ps_cfg_sei_cll_params->u2_max_content_light_level) || |
461 | 67.1k | (ps_sei_cll_params->u2_max_pic_average_light_level != |
462 | 67.1k | ps_cfg_sei_cll_params->u2_max_pic_average_light_level)) |
463 | 0 | { |
464 | 0 | ps_codec->s_sei.s_sei_cll_params = ps_codec->s_cfg.s_sei.s_sei_cll_params; |
465 | 0 | ps_codec->s_sei.u1_sei_cll_params_present_flag = 1; |
466 | 0 | } |
467 | 67.1k | else |
468 | 67.1k | { |
469 | 67.1k | ps_codec->s_sei.u1_sei_cll_params_present_flag = 0; |
470 | 67.1k | } |
471 | | |
472 | 67.1k | if((ps_sei_ave_params->u4_ambient_illuminance != |
473 | 67.1k | ps_cfg_sei_ave_params->u4_ambient_illuminance) || |
474 | 67.1k | (ps_sei_ave_params->u2_ambient_light_x != |
475 | 64.8k | ps_cfg_sei_ave_params->u2_ambient_light_x) || |
476 | 67.1k | (ps_sei_ave_params->u2_ambient_light_y != |
477 | 64.8k | ps_cfg_sei_ave_params->u2_ambient_light_y)) |
478 | 2.33k | { |
479 | 2.33k | ps_codec->s_sei.s_sei_ave_params = ps_codec->s_cfg.s_sei.s_sei_ave_params; |
480 | 2.33k | ps_codec->s_sei.u1_sei_ave_params_present_flag = 1; |
481 | 2.33k | } |
482 | 64.8k | else |
483 | 64.8k | { |
484 | 64.8k | ps_codec->s_sei.u1_sei_ave_params_present_flag = 0; |
485 | 64.8k | } |
486 | | |
487 | 301k | for(i = 0; i <= ps_cfg_sei_sii_params->u1_sii_max_sub_layers_minus1; i++) |
488 | 234k | { |
489 | 234k | au4_sub_layer_num_units_in_shutter_interval_flag = |
490 | 234k | (au4_sub_layer_num_units_in_shutter_interval_flag || |
491 | 234k | (ps_sei_sii_params->au4_sub_layer_num_units_in_shutter_interval[i] != |
492 | 219k | ps_cfg_sei_sii_params->au4_sub_layer_num_units_in_shutter_interval[i])); |
493 | 234k | } |
494 | | |
495 | 67.1k | if((ps_sei_sii_params->u4_sii_sub_layer_idx != |
496 | 67.1k | ps_cfg_sei_sii_params->u4_sii_sub_layer_idx) || |
497 | 67.1k | (ps_sei_sii_params->u1_shutter_interval_info_present_flag != |
498 | 67.1k | ps_cfg_sei_sii_params->u1_shutter_interval_info_present_flag) || |
499 | 67.1k | (ps_sei_sii_params->u4_sii_time_scale != ps_cfg_sei_sii_params->u4_sii_time_scale) || |
500 | 67.1k | (ps_sei_sii_params->u1_fixed_shutter_interval_within_cvs_flag != |
501 | 64.9k | ps_cfg_sei_sii_params->u1_fixed_shutter_interval_within_cvs_flag) || |
502 | 67.1k | (ps_sei_sii_params->u4_sii_num_units_in_shutter_interval != |
503 | 64.9k | ps_cfg_sei_sii_params->u4_sii_num_units_in_shutter_interval) || |
504 | 67.1k | (ps_sei_sii_params->u1_sii_max_sub_layers_minus1 != |
505 | 64.9k | ps_cfg_sei_sii_params->u1_sii_max_sub_layers_minus1) || |
506 | 67.1k | au4_sub_layer_num_units_in_shutter_interval_flag) |
507 | 2.20k | { |
508 | 2.20k | ps_codec->s_sei.s_sei_sii_params = ps_codec->s_cfg.s_sei.s_sei_sii_params; |
509 | 2.20k | ps_codec->s_sei.u1_sei_sii_params_present_flag = 1; |
510 | 2.20k | } |
511 | 64.9k | else |
512 | 64.9k | { |
513 | 64.9k | ps_codec->s_sei.u1_sei_sii_params_present_flag = 0; |
514 | 64.9k | } |
515 | | |
516 | 67.1k | if((1 == ps_codec->s_sei.u1_sei_mdcv_params_present_flag) || |
517 | 67.1k | (1 == ps_codec->s_sei.u1_sei_cll_params_present_flag) || |
518 | 67.1k | (1 == ps_codec->s_sei.u1_sei_ave_params_present_flag) || |
519 | 67.1k | (1 == ps_codec->s_sei.u1_sei_sii_params_present_flag)) |
520 | 4.14k | { |
521 | 4.14k | ps_codec->force_curr_frame_type = IV_IDR_FRAME; |
522 | 4.14k | } |
523 | 67.1k | } |
524 | 67.1k | #endif |
525 | | |
526 | 67.1k | if (ps_video_encode_ip->s_ive_ip.s_inp_buf.apv_bufs[0] != NULL && |
527 | 67.1k | ps_codec->i4_header_mode != 1) |
528 | 44.1k | { |
529 | 44.1k | if (IV_SUCCESS != api_check_input_dimensions(ps_codec, pv_api_ip, pv_api_op)) |
530 | 95 | { |
531 | 95 | error_status = IH264E_FAIL; |
532 | 95 | SET_ERROR_ON_RETURN(error_status, |
533 | 95 | IVE_FATALERROR, |
534 | 95 | ps_video_encode_op->s_ive_op.u4_error_code, |
535 | 95 | IV_FAIL); |
536 | 0 | } |
537 | | /****************************************************************** |
538 | | * INSERT LOGO |
539 | | *****************************************************************/ |
540 | | #ifdef LOGO_EN |
541 | | ih264e_insert_logo(ps_video_encode_ip->s_ive_ip.s_inp_buf.apv_bufs[0], |
542 | | ps_video_encode_ip->s_ive_ip.s_inp_buf.apv_bufs[1], |
543 | | ps_video_encode_ip->s_ive_ip.s_inp_buf.apv_bufs[2], |
544 | | ps_video_encode_ip->s_ive_ip.s_inp_buf.au4_strd[0], |
545 | | 0, |
546 | | 0, |
547 | | ps_codec->s_cfg.e_inp_color_fmt, |
548 | | ps_codec->s_cfg.u4_disp_wd, |
549 | | ps_codec->s_cfg.u4_disp_ht); |
550 | | #endif /*LOGO_EN*/ |
551 | 44.1k | } |
552 | | |
553 | | /* In case of alt ref and B pics we will have non reference frame in stream */ |
554 | 67.0k | if (ps_codec->s_cfg.u4_enable_alt_ref || ps_codec->s_cfg.u4_num_bframes) |
555 | 49.9k | { |
556 | 49.9k | ps_codec->i4_non_ref_frames_in_stream = 1; |
557 | 49.9k | } |
558 | | |
559 | 67.0k | if (ps_codec->i4_encode_api_call_cnt == 0) |
560 | 11.1k | { |
561 | | /********************************************************************/ |
562 | | /* number of mv/ref bank buffers used by the codec, */ |
563 | | /* 1 to handle curr frame */ |
564 | | /* 1 to store information of ref frame */ |
565 | | /* 1 more additional because of the codec employs 2 ctxt sets */ |
566 | | /* to assist asynchronous API */ |
567 | | /********************************************************************/ |
568 | | |
569 | | /* initialize mv bank buffer manager */ |
570 | 11.1k | error_status = ih264e_mv_buf_mgr_add_bufs(ps_codec); |
571 | 11.1k | SET_ERROR_ON_RETURN(error_status, |
572 | 11.1k | IVE_FATALERROR, |
573 | 11.1k | ps_video_encode_op->s_ive_op.u4_error_code, |
574 | 11.1k | IV_FAIL); |
575 | | |
576 | | /* initialize ref bank buffer manager */ |
577 | 11.1k | error_status = ih264e_pic_buf_mgr_add_bufs(ps_codec); |
578 | 11.1k | SET_ERROR_ON_RETURN(error_status, |
579 | 11.1k | IVE_FATALERROR, |
580 | 11.1k | ps_video_encode_op->s_ive_op.u4_error_code, |
581 | 11.1k | IV_FAIL); |
582 | | |
583 | | /* for the first frame, generate header when not requested explicitly */ |
584 | 11.1k | if (ps_codec->i4_header_mode == 0 && |
585 | 11.1k | ps_codec->u4_header_generated == 0) |
586 | 0 | { |
587 | 0 | ps_codec->i4_gen_header = 1; |
588 | 0 | } |
589 | 11.1k | } |
590 | | |
591 | | /* generate header and return when encoder is operated in header mode */ |
592 | 67.0k | if (ps_codec->i4_header_mode == 1) |
593 | 5.61k | { |
594 | | /* whenever the header is generated, this implies a start of sequence |
595 | | * and a sequence needs to be started with IDR |
596 | | */ |
597 | 5.61k | ps_codec->force_curr_frame_type = IV_IDR_FRAME; |
598 | | |
599 | | /* generate header */ |
600 | 5.61k | error_status = ih264e_generate_sps_pps(ps_codec); |
601 | | |
602 | | /* send the input to app */ |
603 | 5.61k | ps_video_encode_op->s_ive_op.s_inp_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf; |
604 | 5.61k | ps_video_encode_op->s_ive_op.u4_timestamp_low = ps_video_encode_ip->s_ive_ip.u4_timestamp_low; |
605 | 5.61k | ps_video_encode_op->s_ive_op.u4_timestamp_high = ps_video_encode_ip->s_ive_ip.u4_timestamp_high; |
606 | | |
607 | 5.61k | ps_video_encode_op->s_ive_op.u4_is_last = ps_video_encode_ip->s_ive_ip.u4_is_last; |
608 | | |
609 | | /* send the output to app */ |
610 | 5.61k | ps_video_encode_op->s_ive_op.output_present = 1; |
611 | 5.61k | ps_video_encode_op->s_ive_op.dump_recon = 0; |
612 | 5.61k | ps_video_encode_op->s_ive_op.s_out_buf = ps_codec->as_out_buf[ctxt_sel].s_bits_buf; |
613 | | |
614 | | /* error status */ |
615 | 5.61k | SET_ERROR_ON_RETURN(error_status, |
616 | 5.61k | IVE_UNSUPPORTEDPARAM, |
617 | 5.61k | ps_video_encode_op->s_ive_op.u4_error_code, |
618 | 5.61k | IV_FAIL); |
619 | | |
620 | | /* indicates that header has been generated previously */ |
621 | 5.61k | ps_codec->u4_header_generated = 1; |
622 | | |
623 | | /* api call cnt */ |
624 | 5.61k | ps_codec->i4_encode_api_call_cnt --; |
625 | | |
626 | | /* header mode tag is not sticky */ |
627 | 5.61k | ps_codec->i4_header_mode = 0; |
628 | 5.61k | ps_codec->i4_gen_header = 0; |
629 | | |
630 | 5.61k | return IV_SUCCESS; |
631 | 5.61k | } |
632 | | |
633 | | /* curr pic cnt */ |
634 | 61.4k | ps_codec->i4_pic_cnt += 1; |
635 | | |
636 | 61.4k | i4_rc_pre_enc_skip = 0; |
637 | 61.4k | i4_rc_pre_enc_skip = ih264e_input_queue_update( |
638 | 61.4k | ps_codec, &ps_video_encode_ip->s_ive_ip, &s_inp_buf); |
639 | | |
640 | 61.4k | s_out_buf.u4_is_last = s_inp_buf.u4_is_last; |
641 | 61.4k | ps_video_encode_op->s_ive_op.u4_is_last = s_inp_buf.u4_is_last; |
642 | | |
643 | | /* Send the input to application so that it can free it */ |
644 | 61.4k | ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf; |
645 | | |
646 | | /* Only encode if the current frame is not pre-encode skip */ |
647 | 61.4k | if (!i4_rc_pre_enc_skip && s_inp_buf.s_raw_buf.apv_bufs[0]) |
648 | 41.8k | { |
649 | | /* proc ctxt base idx */ |
650 | 41.8k | WORD32 proc_ctxt_select = ctxt_sel * MAX_PROCESS_THREADS; |
651 | | |
652 | | /* proc ctxt */ |
653 | 41.8k | process_ctxt_t *ps_proc = &ps_codec->as_process[proc_ctxt_select]; |
654 | | |
655 | 41.8k | WORD32 ret = 0; |
656 | | |
657 | | /* number of addl. threads to be created */ |
658 | 41.8k | WORD32 num_thread_cnt = ps_codec->s_cfg.u4_num_cores - 1; |
659 | | |
660 | | /* array giving pic cnt that is being processed in curr context set */ |
661 | 41.8k | ps_codec->ai4_pic_cnt[ctxt_sel] = ps_codec->i4_pic_cnt; |
662 | | |
663 | | /* initialize all relevant process ctxts */ |
664 | 41.8k | error_status = ih264e_pic_init(ps_codec, &s_inp_buf); |
665 | 41.8k | SET_ERROR_ON_RETURN(error_status, |
666 | 41.8k | IVE_FATALERROR, |
667 | 41.8k | ps_video_encode_op->s_ive_op.u4_error_code, |
668 | 41.8k | IV_FAIL); |
669 | | |
670 | 175k | for (i = 0; i < num_thread_cnt; i++) |
671 | 133k | { |
672 | 133k | ret = ithread_create(ps_codec->apv_proc_thread_handle[i], |
673 | 133k | NULL, |
674 | 133k | (void *)ih264e_process_thread, |
675 | 133k | &ps_codec->as_process[i + 1]); |
676 | 133k | if (ret != 0) |
677 | 0 | { |
678 | 0 | printf("pthread Create Failed"); |
679 | 0 | assert(0); |
680 | 0 | } |
681 | | |
682 | 133k | ps_codec->ai4_process_thread_created[i] = 1; |
683 | | |
684 | 133k | ps_codec->i4_proc_thread_cnt++; |
685 | 133k | } |
686 | | |
687 | | |
688 | | /* launch job */ |
689 | 41.7k | ih264e_process_thread(ps_proc); |
690 | | |
691 | | /* Join threads at the end of encoding a frame */ |
692 | 41.7k | ih264e_join_threads(ps_codec); |
693 | | |
694 | 41.7k | ih264_list_reset(ps_codec->pv_proc_jobq); |
695 | | |
696 | 41.7k | ih264_list_reset(ps_codec->pv_entropy_jobq); |
697 | | |
698 | 41.7k | error_status = ih264e_update_rc_post_enc(ps_codec, ctxt_sel, (ps_codec->i4_poc == 0)); |
699 | 41.7k | SET_ERROR_ON_RETURN(error_status, |
700 | 41.7k | ((error_status == IH264E_BITSTREAM_BUFFER_OVERFLOW) ? |
701 | 41.7k | IVE_UNSUPPORTEDPARAM : IVE_FATALERROR), |
702 | 41.7k | ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL); |
703 | | |
704 | 41.7k | if (ps_codec->s_cfg.u4_enable_quality_metrics & QUALITY_MASK_PSNR) |
705 | 0 | { |
706 | 0 | ih264e_compute_quality_stats(ps_proc); |
707 | 0 | } |
708 | | |
709 | 41.7k | } |
710 | | |
711 | | /**************************************************************************** |
712 | | * RECON |
713 | | * Since we have forward dependent frames, we cannot return recon in encoding |
714 | | * order. It must be in poc order, or input pic order. To achieve this we |
715 | | * introduce a delay of 1 to the recon wrt encode. Now since we have that |
716 | | * delay, at any point minimum of pic_cnt in our ref buffer will be the |
717 | | * correct frame. For ex let our GOP be IBBP [1 2 3 4] . The encode order |
718 | | * will be [1 4 2 3] .Now since we have a delay of 1, when we are done with |
719 | | * encoding 4, the min in the list will be 1. After encoding 2, it will be |
720 | | * 2, 3 after 3 and 4 after 4. Hence we can return in sequence. Note |
721 | | * that the 1 delay is critical. Hence if we have post enc skip, we must |
722 | | * skip here too. Note that since post enc skip already frees the recon |
723 | | * buffer we need not do any thing here |
724 | | * |
725 | | * We need to return a recon when ever we consume an input buffer. This |
726 | | * comsumption include a pre or post enc skip. Thus dump recon is set for |
727 | | * all cases except when |
728 | | * 1) We are waiting -> ps_codec->i4_pic_cnt > ps_codec->s_cfg.u4_num_bframe |
729 | | * An exception need to be made for the case when we have the last buffer |
730 | | * since we need to flush out the on remainig recon. |
731 | | ****************************************************************************/ |
732 | | |
733 | 61.4k | ps_video_encode_op->s_ive_op.dump_recon = 0; |
734 | | |
735 | 61.4k | if (ps_codec->s_cfg.u4_enable_recon |
736 | 61.4k | && (ps_codec->i4_pic_cnt > (WORD32)ps_codec->s_cfg.u4_num_bframes || |
737 | 0 | s_inp_buf.u4_is_last)) |
738 | 0 | { |
739 | | /* error status */ |
740 | 0 | IH264_ERROR_T ret = IH264_SUCCESS; |
741 | 0 | pic_buf_t *ps_pic_buf = NULL; |
742 | 0 | WORD32 i4_buf_status, i4_curr_poc = 32768; |
743 | 0 | WORD8 buf_idx = -1; |
744 | | |
745 | | /* In case of skips we return recon, but indicate that buffer is zero size */ |
746 | 0 | if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel] |
747 | 0 | || i4_rc_pre_enc_skip) |
748 | 0 | { |
749 | |
|
750 | 0 | ps_video_encode_op->s_ive_op.dump_recon = 1; |
751 | 0 | ps_video_encode_op->s_ive_op.s_recon_buf.au4_wd[0] = 0; |
752 | 0 | ps_video_encode_op->s_ive_op.s_recon_buf.au4_wd[1] = 0; |
753 | |
|
754 | 0 | } |
755 | 0 | else |
756 | 0 | { |
757 | 0 | for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++) |
758 | 0 | { |
759 | 0 | if (ps_codec->as_ref_set[i].i4_pic_cnt == -1) |
760 | 0 | continue; |
761 | | |
762 | 0 | i4_buf_status = ih264_buf_mgr_get_status( |
763 | 0 | ps_codec->pv_ref_buf_mgr, |
764 | 0 | ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id); |
765 | |
|
766 | 0 | if ((i4_buf_status & BUF_MGR_IO) |
767 | 0 | && (ps_codec->as_ref_set[i].i4_poc < i4_curr_poc)) |
768 | 0 | { |
769 | 0 | ps_pic_buf = ps_codec->as_ref_set[i].ps_pic_buf; |
770 | 0 | i4_curr_poc = ps_codec->as_ref_set[i].i4_poc; |
771 | 0 | buf_idx = i; |
772 | 0 | } |
773 | 0 | } |
774 | 0 | if ((ps_codec->s_cfg.u4_enable_quality_metrics & QUALITY_MASK_PSNR) |
775 | 0 | && buf_idx >= 0) |
776 | 0 | { |
777 | 0 | UWORD8 comp; |
778 | 0 | for(comp = 0; comp < 3; comp++) |
779 | 0 | { |
780 | 0 | DEBUG("PSNR[%d]: %f\n", comp, |
781 | 0 | ps_codec->as_ref_set[buf_idx].s_pic_quality_stats.total_psnr[comp]); |
782 | 0 | } |
783 | 0 | } |
784 | |
|
785 | 0 | ps_video_encode_op->s_ive_op.s_recon_buf = |
786 | 0 | ps_video_encode_ip->s_ive_ip.s_recon_buf; |
787 | | |
788 | | /* |
789 | | * If we get a valid buffer. output and free recon. |
790 | | * |
791 | | * we may get an invalid buffer if num_b_frames is 0. This is because |
792 | | * We assume that there will be a ref frame in ref list after encoding |
793 | | * the last frame. With B frames this is correct since its forward ref |
794 | | * pic will be in the ref list. But if num_b_frames is 0, we will not |
795 | | * have a forward ref pic |
796 | | */ |
797 | |
|
798 | 0 | if (ps_pic_buf) |
799 | 0 | { |
800 | | /* copy/convert the recon buffer and return */ |
801 | 0 | ih264e_fmt_conv(ps_codec, |
802 | 0 | ps_pic_buf, |
803 | 0 | ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[0], |
804 | 0 | ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[1], |
805 | 0 | ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[2], |
806 | 0 | ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[0], |
807 | 0 | ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[1], |
808 | 0 | 0, ps_codec->s_cfg.u4_disp_ht); |
809 | |
|
810 | 0 | ps_video_encode_op->s_ive_op.dump_recon = 1; |
811 | |
|
812 | 0 | ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, |
813 | 0 | ps_pic_buf->i4_buf_id, BUF_MGR_IO); |
814 | |
|
815 | 0 | if (IH264_SUCCESS != ret) |
816 | 0 | { |
817 | 0 | SET_ERROR_ON_RETURN( |
818 | 0 | (IH264E_ERROR_T)ret, IVE_FATALERROR, |
819 | 0 | ps_video_encode_op->s_ive_op.u4_error_code, |
820 | 0 | IV_FAIL); |
821 | 0 | } |
822 | 0 | } |
823 | 0 | } |
824 | 0 | } |
825 | | |
826 | | /*************************************************************************** |
827 | | * Free reference buffers: |
828 | | * In case of a post enc skip, we have to ensure that those pics will not |
829 | | * be used as reference anymore. In all other cases we will not even mark |
830 | | * the ref buffers |
831 | | ***************************************************************************/ |
832 | 61.4k | if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel]) |
833 | 0 | { |
834 | | /* pic info */ |
835 | 0 | pic_buf_t *ps_cur_pic; |
836 | | |
837 | | /* mv info */ |
838 | 0 | mv_buf_t *ps_cur_mv_buf; |
839 | | |
840 | | /* error status */ |
841 | 0 | IH264_ERROR_T ret = IH264_SUCCESS; |
842 | | |
843 | | /* Decrement coded pic count */ |
844 | 0 | ps_codec->i4_poc--; |
845 | | |
846 | | /* loop through to get the min pic cnt among the list of pics stored in ref list */ |
847 | | /* since the skipped frame may not be on reference list, we may not have an MV bank |
848 | | * hence free only if we have allocated */ |
849 | 0 | for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++) |
850 | 0 | { |
851 | 0 | if (ps_codec->i4_pic_cnt == ps_codec->as_ref_set[i].i4_pic_cnt) |
852 | 0 | { |
853 | |
|
854 | 0 | ps_cur_pic = ps_codec->as_ref_set[i].ps_pic_buf; |
855 | |
|
856 | 0 | ps_cur_mv_buf = ps_codec->as_ref_set[i].ps_mv_buf; |
857 | | |
858 | | /* release this frame from reference list and recon list */ |
859 | 0 | ret = ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr, ps_cur_mv_buf->i4_buf_id , BUF_MGR_REF); |
860 | 0 | ret |= ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr, ps_cur_mv_buf->i4_buf_id , BUF_MGR_IO); |
861 | 0 | SET_ERROR_ON_RETURN((IH264E_ERROR_T)ret, |
862 | 0 | IVE_FATALERROR, |
863 | 0 | ps_video_encode_op->s_ive_op.u4_error_code, |
864 | 0 | IV_FAIL); |
865 | |
|
866 | 0 | ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id , BUF_MGR_REF); |
867 | 0 | ret |= ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id , BUF_MGR_IO); |
868 | 0 | SET_ERROR_ON_RETURN((IH264E_ERROR_T)ret, |
869 | 0 | IVE_FATALERROR, |
870 | 0 | ps_video_encode_op->s_ive_op.u4_error_code, |
871 | 0 | IV_FAIL); |
872 | 0 | break; |
873 | 0 | } |
874 | 0 | } |
875 | 0 | } |
876 | | |
877 | | /* |
878 | | * Since recon is not in sync with output, ie there can be frame to be |
879 | | * given back as recon even after last output. Hence we need to mark that |
880 | | * the output is not the last. |
881 | | * Hence search through reflist and mark appropriately |
882 | | */ |
883 | 61.4k | if (ps_codec->s_cfg.u4_enable_recon) |
884 | 0 | { |
885 | 0 | WORD32 i4_buf_status = 0; |
886 | |
|
887 | 0 | for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++) |
888 | 0 | { |
889 | 0 | if (ps_codec->as_ref_set[i].i4_pic_cnt == -1) |
890 | 0 | continue; |
891 | | |
892 | 0 | i4_buf_status |= ih264_buf_mgr_get_status( |
893 | 0 | ps_codec->pv_ref_buf_mgr, |
894 | 0 | ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id); |
895 | 0 | } |
896 | |
|
897 | 0 | if (i4_buf_status & BUF_MGR_IO) |
898 | 0 | { |
899 | 0 | s_out_buf.u4_is_last = 0; |
900 | 0 | ps_video_encode_op->s_ive_op.u4_is_last = 0; |
901 | 0 | } |
902 | 0 | } |
903 | | |
904 | | /************************************************************************** |
905 | | * Signaling to APP |
906 | | * 1) If we valid a valid output mark it so |
907 | | * 2) Set the codec output ps_video_encode_op |
908 | | * 3) Set the error status |
909 | | * 4) Set the return Pic type |
910 | | * Note that we already has marked recon properly |
911 | | * 5)Send the consumed input back to app so that it can free it if possible |
912 | | * |
913 | | * We will have to return the output and input buffers unconditionally |
914 | | * so that app can release them |
915 | | **************************************************************************/ |
916 | 61.4k | if (!i4_rc_pre_enc_skip |
917 | 61.4k | && !ps_codec->s_rate_control.post_encode_skip[ctxt_sel] |
918 | 61.4k | && s_inp_buf.s_raw_buf.apv_bufs[0]) |
919 | 41.7k | { |
920 | | |
921 | | /* receive output back from codec */ |
922 | 41.7k | s_out_buf = ps_codec->as_out_buf[ctxt_sel]; |
923 | | |
924 | | /* send the output to app */ |
925 | 41.7k | ps_video_encode_op->s_ive_op.output_present = 1; |
926 | 41.7k | ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS; |
927 | | |
928 | | /* Set the time stamps of the encodec input */ |
929 | 41.7k | ps_video_encode_op->s_ive_op.u4_timestamp_low = s_inp_buf.u4_timestamp_low; |
930 | 41.7k | ps_video_encode_op->s_ive_op.u4_timestamp_high = s_inp_buf.u4_timestamp_high; |
931 | | |
932 | 41.7k | switch (ps_codec->pic_type) |
933 | 41.7k | { |
934 | 10.4k | case PIC_IDR: |
935 | 10.4k | ps_video_encode_op->s_ive_op.u4_encoded_frame_type =IV_IDR_FRAME; |
936 | 10.4k | break; |
937 | | |
938 | 2.07k | case PIC_I: |
939 | 2.07k | ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_I_FRAME; |
940 | 2.07k | break; |
941 | | |
942 | 13.9k | case PIC_P: |
943 | 13.9k | ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_P_FRAME; |
944 | 13.9k | break; |
945 | | |
946 | 15.3k | case PIC_B: |
947 | 15.3k | ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_B_FRAME; |
948 | 15.3k | break; |
949 | | |
950 | 0 | default: |
951 | 0 | ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME; |
952 | 0 | break; |
953 | 41.7k | } |
954 | | |
955 | 217k | for (i = 0; i < (WORD32)ps_codec->s_cfg.u4_num_cores; i++) |
956 | 175k | { |
957 | 175k | error_status |= ps_codec->as_process[ctxt_sel + i].i4_error_code; |
958 | 175k | } |
959 | 41.7k | SET_ERROR_ON_RETURN(error_status, |
960 | 41.7k | ((error_status == IH264E_BITSTREAM_BUFFER_OVERFLOW) ? |
961 | 41.7k | IVE_UNSUPPORTEDPARAM : IVE_FATALERROR), |
962 | 41.7k | ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL); |
963 | 41.7k | } |
964 | 19.6k | else |
965 | 19.6k | { |
966 | | /* receive output back from codec */ |
967 | 19.6k | s_out_buf = ps_codec->as_out_buf[ctxt_sel]; |
968 | | |
969 | 19.6k | ps_video_encode_op->s_ive_op.output_present = 0; |
970 | 19.6k | ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS; |
971 | | |
972 | | /* Set the time stamps of the encodec input */ |
973 | 19.6k | ps_video_encode_op->s_ive_op.u4_timestamp_low = 0; |
974 | 19.6k | ps_video_encode_op->s_ive_op.u4_timestamp_high = 0; |
975 | | |
976 | 19.6k | ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME; |
977 | | |
978 | 19.6k | } |
979 | | |
980 | 61.4k | ps_video_encode_op->s_ive_op.s_out_buf = s_out_buf.s_bits_buf; |
981 | | |
982 | 61.4k | return IV_SUCCESS; |
983 | 61.4k | } |