blob: fe2384114d62b7ec1c4c4c01d82d83c7bf4c8071 [file] [log] [blame]
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301/******************************************************************************
2 *
3 * Copyright (C) 2015 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*/
20
21/**
22******************************************************************************
23* @file
24* ih264e_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>
Harinarayanan K K134291e2015-06-18 16:03:38 +053051#include <limits.h>
Hamsalekha S8d3d3032015-03-13 21:24:58 +053052/* User Include files */
53#include "ih264e_config.h"
54#include "ih264_typedefs.h"
55#include "iv2.h"
56#include "ive2.h"
57#include "ih264e.h"
58#include "ithread.h"
59#include "ih264_defs.h"
60#include "ih264_macros.h"
61#include "ih264_debug.h"
62#include "ih264_structs.h"
63#include "ih264_platform_macros.h"
64#include "ih264_error.h"
65#include "ime_distortion_metrics.h"
Harinarayanan K K134291e2015-06-18 16:03:38 +053066#include "ime_defs.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053067#include "ime_structs.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053068#include "ih264_trans_quant_itrans_iquant.h"
69#include "ih264_inter_pred_filters.h"
70#include "ih264_mem_fns.h"
71#include "ih264_padding.h"
72#include "ih264_intra_pred_filters.h"
73#include "ih264_deblk_edge_filters.h"
Harinarayanan K K134291e2015-06-18 16:03:38 +053074#include "ih264_cabac_tables.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053075#include "ih264_list.h"
76#include "ih264e_error.h"
77#include "ih264e_defs.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053078#include "ih264e_bitstream.h"
79#include "irc_mem_req_and_acq.h"
80#include "irc_cntrl_param.h"
81#include "irc_frame_info_collector.h"
82#include "ih264e_rate_control.h"
83#include "ih264e_time_stamp.h"
Harinarayanan K K134291e2015-06-18 16:03:38 +053084#include "ih264e_cabac_structs.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053085#include "ih264e_structs.h"
86#include "ih264e_master.h"
87#include "ih264e_process.h"
88#include "ih264_buf_mgr.h"
89#include "ih264_dpb_mgr.h"
90#include "ih264e_utils.h"
91#include "ih264e_fmt_conv.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053092#include "ih264e_statistics.h"
93#include "ih264e_trace.h"
94#include "ih264e_debug.h"
95#ifdef LOGO_EN
96#include "ih264e_ittiam_logo.h"
97#endif
98
Chamarthi Kishoread2eaf82019-10-01 11:59:43 +053099
100#define SEI_BASED_FORCE_IDR 1
101
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530102/*****************************************************************************/
103/* Function Definitions */
104/*****************************************************************************/
105
106/**
107******************************************************************************
108*
109* @brief
110* This function joins all the spawned threads after successful completion of
111* their tasks
112*
113* @par Description
114*
115* @param[in] ps_codec
116* pointer to codec context
117*
118* @returns none
119*
120******************************************************************************
121*/
122void ih264e_join_threads(codec_t *ps_codec)
123{
124 /* temp var */
125 WORD32 i = 0;
126 WORD32 ret = 0;
127
128 /* join spawned threads */
129 while (i < ps_codec->i4_proc_thread_cnt)
130 {
131 if (ps_codec->ai4_process_thread_created[i])
132 {
133 ret = ithread_join(ps_codec->apv_proc_thread_handle[i], NULL);
134 if (ret != 0)
135 {
136 printf("pthread Join Failed");
137 assert(0);
138 }
139 ps_codec->ai4_process_thread_created[i] = 0;
140 i++;
141 }
142 }
143
144 ps_codec->i4_proc_thread_cnt = 0;
145}
146
147/**
148******************************************************************************
149*
150* @brief This function puts the current thread to sleep for a duration
151* of sleep_us
152*
153* @par Description
154* ithread_yield() method causes the calling thread to yield execution to another
155* thread that is ready to run on the current processor. The operating system
156* selects the thread to yield to. ithread_usleep blocks the current thread for
157* the specified number of milliseconds. In other words, yield just says,
158* end my timeslice prematurely, look around for other threads to run. If there
159* is nothing better than me, continue. Sleep says I don't want to run for x
160* milliseconds. Even if no other thread wants to run, don't make me run.
161*
162* @param[in] sleep_us
163* thread sleep duration
164*
165* @returns error_status
166*
167******************************************************************************
168*/
169IH264E_ERROR_T ih264e_wait_for_thread(UWORD32 sleep_us)
170{
171 /* yield thread */
172 ithread_yield();
173
174 /* put thread to sleep */
175 ithread_usleep(sleep_us);
176
177 return IH264E_SUCCESS;
178}
179
180/**
181******************************************************************************
182*
183* @brief
184* Encodes in synchronous api mode
185*
186* @par Description
187* This routine processes input yuv, encodes it and outputs bitstream and recon
188*
189* @param[in] ps_codec_obj
190* Pointer to codec object at API level
191*
192* @param[in] pv_api_ip
193* Pointer to input argument structure
194*
195* @param[out] pv_api_op
196* Pointer to output argument structure
197*
198* @returns Status
199*
200******************************************************************************
201*/
202WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
203{
204 /* error status */
205 IH264E_ERROR_T error_status = IH264E_SUCCESS;
206
207 /* codec ctxt */
208 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
209
210 /* input frame to encode */
211 ih264e_video_encode_ip_t *ps_video_encode_ip = pv_api_ip;
212
213 /* output buffer to write stream */
214 ih264e_video_encode_op_t *ps_video_encode_op = pv_api_op;
215
216 /* i/o structures */
217 inp_buf_t s_inp_buf;
218 out_buf_t s_out_buf;
219
220 /* temp var */
Harinarayanan K K134291e2015-06-18 16:03:38 +0530221 WORD32 ctxt_sel = 0, i, i4_rc_pre_enc_skip;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530222
223 /********************************************************************/
224 /* BEGIN INIT */
225 /********************************************************************/
226 /* reset output structure */
227 ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
228 ps_video_encode_op->s_ive_op.output_present = 0;
229 ps_video_encode_op->s_ive_op.dump_recon = 0;
230 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
Neelkamal Semwal986b1ff2021-03-12 10:15:49 +0530231 /* By default set the current input buffer as the buffer to be freed */
232 /* This will later be updated to the actual input that gets encoded */
233 ps_video_encode_op->s_ive_op.s_inp_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530234
Harinarayanan K Kd2d469e2015-06-19 14:45:44 +0530235 /* Check for output memory allocation size */
236 if (ps_video_encode_ip->s_ive_ip.s_out_buf.u4_bufsize < MIN_STREAM_SIZE)
237 {
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530238 error_status = IH264E_INSUFFICIENT_OUTPUT_BUFFER;
Harinarayanan K Kd2d469e2015-06-19 14:45:44 +0530239 SET_ERROR_ON_RETURN(error_status,
240 IVE_UNSUPPORTEDPARAM,
241 ps_video_encode_op->s_ive_op.u4_error_code,
242 IV_FAIL);
243 }
244
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530245 /* copy output info. to internal structure */
246 s_out_buf.s_bits_buf = ps_video_encode_ip->s_ive_ip.s_out_buf;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530247 s_out_buf.u4_is_last = 0;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530248 s_out_buf.u4_timestamp_low = ps_video_encode_ip->s_ive_ip.u4_timestamp_low;
249 s_out_buf.u4_timestamp_high = ps_video_encode_ip->s_ive_ip.u4_timestamp_high;
250
251 /* api call cnt */
252 ps_codec->i4_encode_api_call_cnt += 1;
253
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530254 /* codec context selector */
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530255 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530256
257 /* reset status flags */
258 ps_codec->ai4_pic_cnt[ctxt_sel] = -1;
259 ps_codec->s_rate_control.post_encode_skip[ctxt_sel] = 0;
260 ps_codec->s_rate_control.pre_encode_skip[ctxt_sel] = 0;
261
262 /* pass output buffer to codec */
263 ps_codec->as_out_buf[ctxt_sel] = s_out_buf;
264
265 /* initialize codec ctxt with default params for the first encode api call */
266 if (ps_codec->i4_encode_api_call_cnt == 0)
267 {
268 ih264e_codec_init(ps_codec);
269 }
270
271 /* parse configuration params */
272 for (i = 0; i < MAX_ACTIVE_CONFIG_PARAMS; i++)
273 {
274 cfg_params_t *ps_cfg = &ps_codec->as_cfg[i];
275
276 if (1 == ps_cfg->u4_is_valid)
277 {
Harinarayanan K K134291e2015-06-18 16:03:38 +0530278 if ( ((ps_cfg->u4_timestamp_high == ps_video_encode_ip->s_ive_ip.u4_timestamp_high) &&
279 (ps_cfg->u4_timestamp_low == ps_video_encode_ip->s_ive_ip.u4_timestamp_low)) ||
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530280 ((WORD32)ps_cfg->u4_timestamp_high == -1) ||
281 ((WORD32)ps_cfg->u4_timestamp_low == -1) )
282 {
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530283 error_status = ih264e_codec_update_config(ps_codec, ps_cfg);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530284 SET_ERROR_ON_RETURN(error_status,
285 IVE_UNSUPPORTEDPARAM,
286 ps_video_encode_op->s_ive_op.u4_error_code,
287 IV_FAIL);
288
289 ps_cfg->u4_is_valid = 0;
290 }
291 }
292 }
Chamarthi Kishoread2eaf82019-10-01 11:59:43 +0530293 /* Force IDR based on SEI params */
294#if SEI_BASED_FORCE_IDR
295 {
296 sei_mdcv_params_t *ps_sei_mdcv_params = &ps_codec->s_sei.s_sei_mdcv_params;
297 sei_mdcv_params_t *ps_cfg_sei_mdcv_params =
298 &ps_codec->s_cfg.s_sei.s_sei_mdcv_params;
299 sei_cll_params_t *ps_sei_cll_params = &ps_codec->s_sei.s_sei_cll_params;
300 sei_cll_params_t *ps_cfg_sei_cll_params =
301 &ps_codec->s_cfg.s_sei.s_sei_cll_params;
302 sei_ave_params_t *ps_sei_ave_params = &ps_codec->s_sei.s_sei_ave_params;
303 sei_ave_params_t *ps_cfg_sei_ave_params =
304 &ps_codec->s_cfg.s_sei.s_sei_ave_params;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530305
Chamarthi Kishoread2eaf82019-10-01 11:59:43 +0530306 if((ps_sei_mdcv_params->au2_display_primaries_x[0]!=
307 ps_cfg_sei_mdcv_params->au2_display_primaries_x[0]) ||
308 (ps_sei_mdcv_params->au2_display_primaries_x[1] !=
309 ps_cfg_sei_mdcv_params->au2_display_primaries_x[1]) ||
310 (ps_sei_mdcv_params->au2_display_primaries_x[2] !=
311 ps_cfg_sei_mdcv_params->au2_display_primaries_x[2]) ||
312 (ps_sei_mdcv_params->au2_display_primaries_y[0] !=
313 ps_cfg_sei_mdcv_params->au2_display_primaries_y[0]) ||
314 (ps_sei_mdcv_params->au2_display_primaries_y[1] !=
315 ps_cfg_sei_mdcv_params->au2_display_primaries_y[1]) ||
316 (ps_sei_mdcv_params->au2_display_primaries_y[2] !=
317 ps_cfg_sei_mdcv_params->au2_display_primaries_y[2]) ||
318 (ps_sei_mdcv_params->u2_white_point_x !=
319 ps_cfg_sei_mdcv_params->u2_white_point_x) ||
320 (ps_sei_mdcv_params->u2_white_point_y !=
321 ps_cfg_sei_mdcv_params->u2_white_point_y) ||
322 (ps_sei_mdcv_params->u4_max_display_mastering_luminance !=
323 ps_cfg_sei_mdcv_params->u4_max_display_mastering_luminance) ||
324 (ps_sei_mdcv_params->u4_min_display_mastering_luminance !=
325 ps_cfg_sei_mdcv_params->u4_min_display_mastering_luminance))
326 {
327 ps_codec->s_sei.s_sei_mdcv_params = ps_codec->s_cfg.s_sei.s_sei_mdcv_params;
328 ps_codec->s_sei.u1_sei_mdcv_params_present_flag = 1;
329 }
330 else
331 {
332 ps_codec->s_sei.u1_sei_mdcv_params_present_flag = 0;
333 }
334
335 if((ps_sei_cll_params->u2_max_content_light_level !=
336 ps_cfg_sei_cll_params->u2_max_content_light_level) ||
337 (ps_sei_cll_params->u2_max_pic_average_light_level !=
338 ps_cfg_sei_cll_params->u2_max_pic_average_light_level))
339 {
340 ps_codec->s_sei.s_sei_cll_params = ps_codec->s_cfg.s_sei.s_sei_cll_params;
341 ps_codec->s_sei.u1_sei_cll_params_present_flag = 1;
342 }
343 else
344 {
345 ps_codec->s_sei.u1_sei_cll_params_present_flag = 0;
346 }
347
348 if((ps_sei_ave_params->u4_ambient_illuminance !=
349 ps_cfg_sei_ave_params->u4_ambient_illuminance) ||
350 (ps_sei_ave_params->u2_ambient_light_x !=
351 ps_cfg_sei_ave_params->u2_ambient_light_x) ||
352 (ps_sei_ave_params->u2_ambient_light_y !=
353 ps_cfg_sei_ave_params->u2_ambient_light_y))
354 {
355 ps_codec->s_sei.s_sei_ave_params = ps_codec->s_cfg.s_sei.s_sei_ave_params;
356 ps_codec->s_sei.u1_sei_ave_params_present_flag = 1;
357 }
358 else
359 {
360 ps_codec->s_sei.u1_sei_ave_params_present_flag = 0;
361 }
362
363 if((1 == ps_codec->s_sei.u1_sei_mdcv_params_present_flag) ||
364 (1 == ps_codec->s_sei.u1_sei_cll_params_present_flag) ||
365 (1 == ps_codec->s_sei.u1_sei_ave_params_present_flag))
366 {
367 ps_codec->force_curr_frame_type = IV_IDR_FRAME;
368 }
369 }
370#endif
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530371 /******************************************************************
372 * INSERT LOGO
373 *****************************************************************/
374#ifdef LOGO_EN
375 if (s_inp_buf.s_raw_buf.apv_bufs[0] != NULL &&
376 ps_codec->i4_header_mode != 1)
377 {
378 ih264e_insert_logo(s_inp_buf.s_raw_buf.apv_bufs[0],
379 s_inp_buf.s_raw_buf.apv_bufs[1],
380 s_inp_buf.s_raw_buf.apv_bufs[2],
381 s_inp_buf.s_raw_buf.au4_strd[0],
382 0,
383 0,
384 ps_codec->s_cfg.e_inp_color_fmt,
385 ps_codec->s_cfg.u4_disp_wd,
386 ps_codec->s_cfg.u4_disp_ht);
387 }
388#endif /*LOGO_EN*/
389
Martin Storsjo7c99adf2015-06-23 11:51:06 +0300390 /* In case of alt ref and B pics we will have non reference frame in stream */
391 if (ps_codec->s_cfg.u4_enable_alt_ref || ps_codec->s_cfg.u4_num_bframes)
392 {
393 ps_codec->i4_non_ref_frames_in_stream = 1;
394 }
395
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530396 if (ps_codec->i4_encode_api_call_cnt == 0)
397 {
398 /********************************************************************/
399 /* number of mv/ref bank buffers used by the codec, */
400 /* 1 to handle curr frame */
401 /* 1 to store information of ref frame */
402 /* 1 more additional because of the codec employs 2 ctxt sets */
403 /* to assist asynchronous API */
404 /********************************************************************/
405
406 /* initialize mv bank buffer manager */
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530407 error_status = ih264e_mv_buf_mgr_add_bufs(ps_codec);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530408 SET_ERROR_ON_RETURN(error_status,
409 IVE_FATALERROR,
410 ps_video_encode_op->s_ive_op.u4_error_code,
411 IV_FAIL);
412
413 /* initialize ref bank buffer manager */
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530414 error_status = ih264e_pic_buf_mgr_add_bufs(ps_codec);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530415 SET_ERROR_ON_RETURN(error_status,
416 IVE_FATALERROR,
417 ps_video_encode_op->s_ive_op.u4_error_code,
418 IV_FAIL);
419
420 /* for the first frame, generate header when not requested explicitly */
421 if (ps_codec->i4_header_mode == 0 &&
422 ps_codec->u4_header_generated == 0)
423 {
424 ps_codec->i4_gen_header = 1;
425 }
426 }
427
428 /* generate header and return when encoder is operated in header mode */
429 if (ps_codec->i4_header_mode == 1)
430 {
431 /* whenever the header is generated, this implies a start of sequence
432 * and a sequence needs to be started with IDR
433 */
434 ps_codec->force_curr_frame_type = IV_IDR_FRAME;
435
436 /* generate header */
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530437 error_status = ih264e_generate_sps_pps(ps_codec);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530438
439 /* send the input to app */
Martin Storsjo8e78e302015-06-29 16:33:39 +0300440 ps_video_encode_op->s_ive_op.s_inp_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf;
441 ps_video_encode_op->s_ive_op.u4_timestamp_low = ps_video_encode_ip->s_ive_ip.u4_timestamp_low;
442 ps_video_encode_op->s_ive_op.u4_timestamp_high = ps_video_encode_ip->s_ive_ip.u4_timestamp_high;
443
444 ps_video_encode_op->s_ive_op.u4_is_last = ps_video_encode_ip->s_ive_ip.u4_is_last;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530445
446 /* send the output to app */
447 ps_video_encode_op->s_ive_op.output_present = 1;
448 ps_video_encode_op->s_ive_op.dump_recon = 0;
449 ps_video_encode_op->s_ive_op.s_out_buf = ps_codec->as_out_buf[ctxt_sel].s_bits_buf;
450
451 /* error status */
452 SET_ERROR_ON_RETURN(error_status,
453 IVE_FATALERROR,
454 ps_video_encode_op->s_ive_op.u4_error_code,
455 IV_FAIL);
456
457 /* indicates that header has been generated previously */
458 ps_codec->u4_header_generated = 1;
459
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530460 /* api call cnt */
461 ps_codec->i4_encode_api_call_cnt --;
462
463 /* header mode tag is not sticky */
464 ps_codec->i4_header_mode = 0;
465 ps_codec->i4_gen_header = 0;
466
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530467 return IV_SUCCESS;
468 }
469
Harinarayanan K K134291e2015-06-18 16:03:38 +0530470 /* curr pic cnt */
471 ps_codec->i4_pic_cnt += 1;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530472
Harinarayanan K K134291e2015-06-18 16:03:38 +0530473 i4_rc_pre_enc_skip = 0;
474 i4_rc_pre_enc_skip = ih264e_input_queue_update(
475 ps_codec, &ps_video_encode_ip->s_ive_ip, &s_inp_buf);
476
477 s_out_buf.u4_is_last = s_inp_buf.u4_is_last;
478 ps_video_encode_op->s_ive_op.u4_is_last = s_inp_buf.u4_is_last;
479
Neelkamal Semwal986b1ff2021-03-12 10:15:49 +0530480 /* Send the input to application so that it can free it */
481 ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf;
482
Harinarayanan K K134291e2015-06-18 16:03:38 +0530483 /* Only encode if the current frame is not pre-encode skip */
484 if (!i4_rc_pre_enc_skip && s_inp_buf.s_raw_buf.apv_bufs[0])
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530485 {
Harinarayanan K K134291e2015-06-18 16:03:38 +0530486 /* proc ctxt base idx */
487 WORD32 proc_ctxt_select = ctxt_sel * MAX_PROCESS_THREADS;
488
489 /* proc ctxt */
490 process_ctxt_t *ps_proc = &ps_codec->as_process[proc_ctxt_select];
491
492 WORD32 ret = 0;
493
494 /* number of addl. threads to be created */
495 WORD32 num_thread_cnt = ps_codec->s_cfg.u4_num_cores - 1;
496
Martin Storsjo9fbffcf2015-06-27 00:19:48 +0300497 /* array giving pic cnt that is being processed in curr context set */
498 ps_codec->ai4_pic_cnt[ctxt_sel] = ps_codec->i4_pic_cnt;
499
500 /* initialize all relevant process ctxts */
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530501 error_status = ih264e_pic_init(ps_codec, &s_inp_buf);
Martin Storsjo9fbffcf2015-06-27 00:19:48 +0300502 SET_ERROR_ON_RETURN(error_status,
503 IVE_FATALERROR,
504 ps_video_encode_op->s_ive_op.u4_error_code,
505 IV_FAIL);
506
Harinarayanan K K134291e2015-06-18 16:03:38 +0530507 for (i = 0; i < num_thread_cnt; i++)
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530508 {
Harinarayanan K K134291e2015-06-18 16:03:38 +0530509 ret = ithread_create(ps_codec->apv_proc_thread_handle[i],
510 NULL,
511 (void *)ih264e_process_thread,
512 &ps_codec->as_process[i + 1]);
513 if (ret != 0)
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530514 {
Harinarayanan K K134291e2015-06-18 16:03:38 +0530515 printf("pthread Create Failed");
516 assert(0);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530517 }
518
Harinarayanan K K134291e2015-06-18 16:03:38 +0530519 ps_codec->ai4_process_thread_created[i] = 1;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530520
Harinarayanan K K134291e2015-06-18 16:03:38 +0530521 ps_codec->i4_proc_thread_cnt++;
522 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530523
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530524
Harinarayanan K K134291e2015-06-18 16:03:38 +0530525 /* launch job */
526 ih264e_process_thread(ps_proc);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530527
Harinarayanan K K134291e2015-06-18 16:03:38 +0530528 /* Join threads at the end of encoding a frame */
529 ih264e_join_threads(ps_codec);
530
531 ih264_list_reset(ps_codec->pv_proc_jobq);
532
533 ih264_list_reset(ps_codec->pv_entropy_jobq);
534 }
535
536
537 /****************************************************************************
538 * RECON
539 * Since we have forward dependent frames, we cannot return recon in encoding
540 * order. It must be in poc order, or input pic order. To achieve this we
541 * introduce a delay of 1 to the recon wrt encode. Now since we have that
542 * delay, at any point minimum of pic_cnt in our ref buffer will be the
543 * correct frame. For ex let our GOP be IBBP [1 2 3 4] . The encode order
544 * will be [1 4 2 3] .Now since we have a delay of 1, when we are done with
545 * encoding 4, the min in the list will be 1. After encoding 2, it will be
546 * 2, 3 after 3 and 4 after 4. Hence we can return in sequence. Note
547 * that the 1 delay is critical. Hence if we have post enc skip, we must
548 * skip here too. Note that since post enc skip already frees the recon
549 * buffer we need not do any thing here
550 *
551 * We need to return a recon when ever we consume an input buffer. This
552 * comsumption include a pre or post enc skip. Thus dump recon is set for
553 * all cases except when
554 * 1) We are waiting -> ps_codec->i4_frame_num > 1
555 * 2) When the input buffer is null [ ie we are not consuming any inp]
556 * An exception need to be made for the case when we have the last buffer
557 * since we need to flush out the on remainig recon.
558 ****************************************************************************/
559
560 ps_video_encode_op->s_ive_op.dump_recon = 0;
561
Harinarayanan K Kf080d512015-06-26 15:20:54 +0530562 if (ps_codec->s_cfg.u4_enable_recon && (ps_codec->i4_frame_num > 1 || s_inp_buf.u4_is_last)
Harinarayanan K K134291e2015-06-18 16:03:38 +0530563 && (s_inp_buf.s_raw_buf.apv_bufs[0] || s_inp_buf.u4_is_last))
564 {
565 /* error status */
566 IH264_ERROR_T ret = IH264_SUCCESS;
567 pic_buf_t *ps_pic_buf = NULL;
568 WORD32 i4_buf_status, i4_curr_poc = 32768;
569
570 /* In case of skips we return recon, but indicate that buffer is zero size */
571 if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel]
572 || i4_rc_pre_enc_skip)
573 {
574
575 ps_video_encode_op->s_ive_op.dump_recon = 1;
576 ps_video_encode_op->s_ive_op.s_recon_buf.au4_wd[0] = 0;
577 ps_video_encode_op->s_ive_op.s_recon_buf.au4_wd[1] = 0;
578
579 }
580 else
581 {
582 for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
583 {
584 if (ps_codec->as_ref_set[i].i4_pic_cnt == -1)
585 continue;
586
587 i4_buf_status = ih264_buf_mgr_get_status(
588 ps_codec->pv_ref_buf_mgr,
589 ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
590
591 if ((i4_buf_status & BUF_MGR_IO)
592 && (ps_codec->as_ref_set[i].i4_poc < i4_curr_poc))
593 {
594 ps_pic_buf = ps_codec->as_ref_set[i].ps_pic_buf;
595 i4_curr_poc = ps_codec->as_ref_set[i].i4_poc;
596 }
597 }
598
599 ps_video_encode_op->s_ive_op.s_recon_buf =
600 ps_video_encode_ip->s_ive_ip.s_recon_buf;
601
602 /*
603 * If we get a valid buffer. output and free recon.
604 *
605 * we may get an invalid buffer if num_b_frames is 0. This is because
606 * We assume that there will be a ref frame in ref list after encoding
607 * the last frame. With B frames this is correct since its forward ref
608 * pic will be in the ref list. But if num_b_frames is 0, we will not
609 * have a forward ref pic
610 */
611
612 if (ps_pic_buf)
613 {
614 /* copy/convert the recon buffer and return */
615 ih264e_fmt_conv(ps_codec,
616 ps_pic_buf,
617 ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[0],
618 ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[1],
619 ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[2],
620 ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[0],
621 ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[1],
622 0, ps_codec->s_cfg.u4_disp_ht);
623
624 ps_video_encode_op->s_ive_op.dump_recon = 1;
625
626 ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr,
627 ps_pic_buf->i4_buf_id, BUF_MGR_IO);
628
629 if (IH264_SUCCESS != ret)
630 {
631 SET_ERROR_ON_RETURN(
632 (IH264E_ERROR_T)ret, IVE_FATALERROR,
633 ps_video_encode_op->s_ive_op.u4_error_code,
634 IV_FAIL);
635 }
636 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530637 }
638 }
639
Harinarayanan K K134291e2015-06-18 16:03:38 +0530640
641 /***************************************************************************
642 * Free reference buffers:
643 * In case of a post enc skip, we have to ensure that those pics will not
644 * be used as reference anymore. In all other cases we will not even mark
645 * the ref buffers
646 ***************************************************************************/
647 if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel])
648 {
649 /* pic info */
650 pic_buf_t *ps_cur_pic;
651
652 /* mv info */
653 mv_buf_t *ps_cur_mv_buf;
654
655 /* error status */
656 IH264_ERROR_T ret = IH264_SUCCESS;
657
658 /* Decrement coded pic count */
659 ps_codec->i4_poc--;
660
661 /* loop through to get the min pic cnt among the list of pics stored in ref list */
662 /* since the skipped frame may not be on reference list, we may not have an MV bank
663 * hence free only if we have allocated */
664 for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
665 {
666 if (ps_codec->i4_pic_cnt == ps_codec->as_ref_set[i].i4_pic_cnt)
667 {
668
669 ps_cur_pic = ps_codec->as_ref_set[i].ps_pic_buf;
670
671 ps_cur_mv_buf = ps_codec->as_ref_set[i].ps_mv_buf;
672
673 /* release this frame from reference list and recon list */
674 ret = ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr, ps_cur_mv_buf->i4_buf_id , BUF_MGR_REF);
675 ret |= ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr, ps_cur_mv_buf->i4_buf_id , BUF_MGR_IO);
676 SET_ERROR_ON_RETURN((IH264E_ERROR_T)ret,
677 IVE_FATALERROR,
678 ps_video_encode_op->s_ive_op.u4_error_code,
679 IV_FAIL);
680
681 ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id , BUF_MGR_REF);
682 ret |= ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id , BUF_MGR_IO);
683 SET_ERROR_ON_RETURN((IH264E_ERROR_T)ret,
684 IVE_FATALERROR,
685 ps_video_encode_op->s_ive_op.u4_error_code,
686 IV_FAIL);
687 break;
688 }
689 }
690 }
691
692 /*
693 * Since recon is not in sync with output, ie there can be frame to be
694 * given back as recon even after last output. Hence we need to mark that
695 * the output is not the last.
696 * Hence search through reflist and mark appropriately
697 */
698 if (ps_codec->s_cfg.u4_enable_recon)
699 {
700 WORD32 i4_buf_status = 0;
701
702 for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
703 {
704 if (ps_codec->as_ref_set[i].i4_pic_cnt == -1)
705 continue;
706
707 i4_buf_status |= ih264_buf_mgr_get_status(
708 ps_codec->pv_ref_buf_mgr,
709 ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
710 }
711
712 if (i4_buf_status & BUF_MGR_IO)
713 {
714 s_out_buf.u4_is_last = 0;
715 ps_video_encode_op->s_ive_op.u4_is_last = 0;
716 }
717 }
718
719
720 /**************************************************************************
721 * Signaling to APP
722 * 1) If we valid a valid output mark it so
723 * 2) Set the codec output ps_video_encode_op
724 * 3) Set the error status
725 * 4) Set the return Pic type
726 * Note that we already has marked recon properly
727 * 5)Send the consumed input back to app so that it can free it if possible
728 *
729 * We will have to return the output and input buffers unconditionally
730 * so that app can release them
731 **************************************************************************/
732 if (!i4_rc_pre_enc_skip
733 && !ps_codec->s_rate_control.post_encode_skip[ctxt_sel]
734 && s_inp_buf.s_raw_buf.apv_bufs[0])
735 {
736
737 /* receive output back from codec */
738 s_out_buf = ps_codec->as_out_buf[ctxt_sel];
739
740 /* send the output to app */
741 ps_video_encode_op->s_ive_op.output_present = 1;
742 ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
743
744 /* Set the time stamps of the encodec input */
745 ps_video_encode_op->s_ive_op.u4_timestamp_low = s_inp_buf.u4_timestamp_low;
746 ps_video_encode_op->s_ive_op.u4_timestamp_high = s_inp_buf.u4_timestamp_high;
747
748
749 switch (ps_codec->pic_type)
750 {
751 case PIC_IDR:
752 ps_video_encode_op->s_ive_op.u4_encoded_frame_type =IV_IDR_FRAME;
753 break;
754
755 case PIC_I:
756 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_I_FRAME;
757 break;
758
759 case PIC_P:
760 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_P_FRAME;
761 break;
762
763 case PIC_B:
764 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_B_FRAME;
765 break;
766
767 default:
768 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
769 break;
770 }
771
772 for (i = 0; i < (WORD32)ps_codec->s_cfg.u4_num_cores; i++)
773 {
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530774 error_status = ps_codec->as_process[ctxt_sel + i].i4_error_code;
775 SET_ERROR_ON_RETURN(error_status,
776 IVE_FATALERROR,
777 ps_video_encode_op->s_ive_op.u4_error_code,
778 IV_FAIL);
Harinarayanan K K134291e2015-06-18 16:03:38 +0530779 }
Harinarayanan K K134291e2015-06-18 16:03:38 +0530780 }
781 else
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530782 {
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530783 /* receive output back from codec */
784 s_out_buf = ps_codec->as_out_buf[ctxt_sel];
785
Harinarayanan K K134291e2015-06-18 16:03:38 +0530786 ps_video_encode_op->s_ive_op.output_present = 0;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530787 ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
788
Harinarayanan K K134291e2015-06-18 16:03:38 +0530789 /* Set the time stamps of the encodec input */
790 ps_video_encode_op->s_ive_op.u4_timestamp_low = 0;
791 ps_video_encode_op->s_ive_op.u4_timestamp_high = 0;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530792
Harinarayanan K K134291e2015-06-18 16:03:38 +0530793 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530794
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530795 }
796
Harinarayanan K K134291e2015-06-18 16:03:38 +0530797 ps_video_encode_op->s_ive_op.s_out_buf = s_out_buf.s_bits_buf;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530798
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530799 if (1 == s_inp_buf.u4_is_last)
800 {
801 ps_video_encode_op->s_ive_op.output_present = 0;
802 ps_video_encode_op->s_ive_op.dump_recon = 0;
803 }
804
805 return IV_SUCCESS;
806}