summaryrefslogtreecommitdiffstats
path: root/encoder/ih264e_encode.c
diff options
context:
space:
mode:
Diffstat (limited to 'encoder/ih264e_encode.c')
-rw-r--r--encoder/ih264e_encode.c436
1 files changed, 284 insertions, 152 deletions
diff --git a/encoder/ih264e_encode.c b/encoder/ih264e_encode.c
index ffc6fb7..f131eb2 100644
--- a/encoder/ih264e_encode.c
+++ b/encoder/ih264e_encode.c
@@ -48,7 +48,7 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
-
+#include <limits.h>
/* User Include files */
#include "ih264e_config.h"
#include "ih264_typedefs.h"
@@ -63,26 +63,25 @@
#include "ih264_platform_macros.h"
#include "ih264_error.h"
#include "ime_distortion_metrics.h"
+#include "ime_defs.h"
#include "ime_structs.h"
-#include "ih264_defs.h"
-#include "ih264_error.h"
-#include "ih264_structs.h"
#include "ih264_trans_quant_itrans_iquant.h"
#include "ih264_inter_pred_filters.h"
#include "ih264_mem_fns.h"
#include "ih264_padding.h"
#include "ih264_intra_pred_filters.h"
#include "ih264_deblk_edge_filters.h"
+#include "ih264_cabac_tables.h"
#include "ih264_list.h"
#include "ih264e_error.h"
#include "ih264e_defs.h"
-#include "ih264_padding.h"
#include "ih264e_bitstream.h"
#include "irc_mem_req_and_acq.h"
#include "irc_cntrl_param.h"
#include "irc_frame_info_collector.h"
#include "ih264e_rate_control.h"
#include "ih264e_time_stamp.h"
+#include "ih264e_cabac_structs.h"
#include "ih264e_structs.h"
#include "ih264e_master.h"
#include "ih264e_process.h"
@@ -90,7 +89,6 @@
#include "ih264_dpb_mgr.h"
#include "ih264e_utils.h"
#include "ih264e_fmt_conv.h"
-#include "ih264e_config.h"
#include "ih264e_statistics.h"
#include "ih264e_trace.h"
#include "ih264e_debug.h"
@@ -217,7 +215,7 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
out_buf_t s_out_buf;
/* temp var */
- WORD32 ctxt_sel = 0, i;
+ WORD32 ctxt_sel = 0, i, i4_rc_pre_enc_skip;
/********************************************************************/
/* BEGIN INIT */
@@ -228,28 +226,15 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
ps_video_encode_op->s_ive_op.dump_recon = 0;
ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
- /* copy input info. to internal structure */
- s_inp_buf.s_raw_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf;
- s_inp_buf.u4_timestamp_low = ps_video_encode_ip->s_ive_ip.u4_timestamp_low;
- s_inp_buf.u4_timestamp_high = ps_video_encode_ip->s_ive_ip.u4_timestamp_high;
- s_inp_buf.u4_is_last = ps_video_encode_ip->s_ive_ip.u4_is_last;
- s_inp_buf.pv_mb_info = ps_video_encode_ip->s_ive_ip.pv_mb_info;
- s_inp_buf.u4_mb_info_type = ps_video_encode_ip->s_ive_ip.u4_mb_info_type;
- s_inp_buf.pv_pic_info = ps_video_encode_ip->s_ive_ip.pv_pic_info;
- s_inp_buf.u4_pic_info_type = ps_video_encode_ip->s_ive_ip.u4_pic_info_type;
-
/* copy output info. to internal structure */
s_out_buf.s_bits_buf = ps_video_encode_ip->s_ive_ip.s_out_buf;
- s_out_buf.u4_is_last = ps_video_encode_ip->s_ive_ip.u4_is_last;
+ s_out_buf.u4_is_last = 0;
s_out_buf.u4_timestamp_low = ps_video_encode_ip->s_ive_ip.u4_timestamp_low;
s_out_buf.u4_timestamp_high = ps_video_encode_ip->s_ive_ip.u4_timestamp_high;
/* api call cnt */
ps_codec->i4_encode_api_call_cnt += 1;
- /* curr pic cnt */
- ps_codec->i4_pic_cnt += 1;
-
/* codec context selector */
ctxt_sel = ps_codec->i4_encode_api_call_cnt & 1;
@@ -274,8 +259,8 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
if (1 == ps_cfg->u4_is_valid)
{
- if ( ((ps_cfg->u4_timestamp_high == s_inp_buf.u4_timestamp_high) &&
- (ps_cfg->u4_timestamp_low == s_inp_buf.u4_timestamp_low)) ||
+ if ( ((ps_cfg->u4_timestamp_high == ps_video_encode_ip->s_ive_ip.u4_timestamp_high) &&
+ (ps_cfg->u4_timestamp_low == ps_video_encode_ip->s_ive_ip.u4_timestamp_low)) ||
((WORD32)ps_cfg->u4_timestamp_high == -1) ||
((WORD32)ps_cfg->u4_timestamp_low == -1) )
{
@@ -355,9 +340,6 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
/* api call cnt */
ps_codec->i4_encode_api_call_cnt --;
- /* curr pic cnt */
- ps_codec->i4_pic_cnt --;
-
/* header mode tag is not sticky */
ps_codec->i4_header_mode = 0;
@@ -381,8 +363,18 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
return IV_SUCCESS;
}
+ /* curr pic cnt */
+ ps_codec->i4_pic_cnt += 1;
+
+ i4_rc_pre_enc_skip = 0;
+ i4_rc_pre_enc_skip = ih264e_input_queue_update(
+ ps_codec, &ps_video_encode_ip->s_ive_ip, &s_inp_buf);
+
+ s_out_buf.u4_is_last = s_inp_buf.u4_is_last;
+ ps_video_encode_op->s_ive_op.u4_is_last = s_inp_buf.u4_is_last;
- if (s_inp_buf.s_raw_buf.apv_bufs[0] != NULL)
+ /* Only encode if the current frame is not pre-encode skip */
+ if (!i4_rc_pre_enc_skip && s_inp_buf.s_raw_buf.apv_bufs[0])
{
/* array giving pic cnt that is being processed in curr context set */
ps_codec->ai4_pic_cnt[ctxt_sel] = ps_codec->i4_pic_cnt;
@@ -394,172 +386,282 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
ps_video_encode_op->s_ive_op.u4_error_code,
IV_FAIL);
- if (ps_codec->s_rate_control.pre_encode_skip[ctxt_sel] == 0)
- {
- /* proc ctxt base idx */
- WORD32 proc_ctxt_select = ctxt_sel * MAX_PROCESS_THREADS;
+ /* proc ctxt base idx */
+ WORD32 proc_ctxt_select = ctxt_sel * MAX_PROCESS_THREADS;
- /* proc ctxt */
- process_ctxt_t *ps_proc = &ps_codec->as_process[proc_ctxt_select];
+ /* proc ctxt */
+ process_ctxt_t *ps_proc = &ps_codec->as_process[proc_ctxt_select];
- WORD32 ret = 0;
+ WORD32 ret = 0;
- /* number of addl. threads to be created */
- WORD32 num_thread_cnt = ps_codec->s_cfg.u4_num_cores - 1;
+ /* number of addl. threads to be created */
+ WORD32 num_thread_cnt = ps_codec->s_cfg.u4_num_cores - 1;
- for (i = 0; i < num_thread_cnt; i++)
+ for (i = 0; i < num_thread_cnt; i++)
+ {
+ ret = ithread_create(ps_codec->apv_proc_thread_handle[i],
+ NULL,
+ (void *)ih264e_process_thread,
+ &ps_codec->as_process[i + 1]);
+ if (ret != 0)
{
- ret = ithread_create(ps_codec->apv_proc_thread_handle[i],
- NULL,
- (void*)ih264e_process_thread,
- &ps_codec->as_process[i + 1]);
- if (ret != 0)
- {
- printf("pthread Create Failed");
- assert(0);
- }
+ printf("pthread Create Failed");
+ assert(0);
+ }
- ps_codec->ai4_process_thread_created[i] = 1;
+ ps_codec->ai4_process_thread_created[i] = 1;
- ps_codec->i4_proc_thread_cnt++;
- }
+ ps_codec->i4_proc_thread_cnt++;
+ }
- /* launch job */
- ih264e_process_thread(ps_proc);
+ /* launch job */
+ ih264e_process_thread(ps_proc);
- /* Join threads at the end of encoding a frame */
- ih264e_join_threads(ps_codec);
+ /* Join threads at the end of encoding a frame */
+ ih264e_join_threads(ps_codec);
- ih264_list_reset(ps_codec->pv_proc_jobq);
+ ih264_list_reset(ps_codec->pv_proc_jobq);
- ih264_list_reset(ps_codec->pv_entropy_jobq);
- }
+ ih264_list_reset(ps_codec->pv_entropy_jobq);
}
- if (-1 != ps_codec->ai4_pic_cnt[ctxt_sel])
- {
- /* proc ctxt base idx */
- WORD32 proc_ctxt_select = ctxt_sel * MAX_PROCESS_THREADS;
- /* proc ctxt */
- process_ctxt_t *ps_proc = &ps_codec->as_process[proc_ctxt_select];
+ /****************************************************************************
+ * RECON
+ * Since we have forward dependent frames, we cannot return recon in encoding
+ * order. It must be in poc order, or input pic order. To achieve this we
+ * introduce a delay of 1 to the recon wrt encode. Now since we have that
+ * delay, at any point minimum of pic_cnt in our ref buffer will be the
+ * correct frame. For ex let our GOP be IBBP [1 2 3 4] . The encode order
+ * will be [1 4 2 3] .Now since we have a delay of 1, when we are done with
+ * encoding 4, the min in the list will be 1. After encoding 2, it will be
+ * 2, 3 after 3 and 4 after 4. Hence we can return in sequence. Note
+ * that the 1 delay is critical. Hence if we have post enc skip, we must
+ * skip here too. Note that since post enc skip already frees the recon
+ * buffer we need not do any thing here
+ *
+ * We need to return a recon when ever we consume an input buffer. This
+ * comsumption include a pre or post enc skip. Thus dump recon is set for
+ * all cases except when
+ * 1) We are waiting -> ps_codec->i4_frame_num > 1
+ * 2) When the input buffer is null [ ie we are not consuming any inp]
+ * An exception need to be made for the case when we have the last buffer
+ * since we need to flush out the on remainig recon.
+ ****************************************************************************/
- /* receive output back from codec */
- s_out_buf = ps_codec->as_out_buf[ctxt_sel];
+ ps_video_encode_op->s_ive_op.dump_recon = 0;
- /* send the output to app */
- ps_video_encode_op->s_ive_op.output_present = 1;
- ps_video_encode_op->s_ive_op.dump_recon = 1;
- ps_video_encode_op->s_ive_op.s_out_buf = s_out_buf.s_bits_buf;
- ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
+ if (ps_codec->s_cfg.u4_enable_recon && (ps_codec->i4_frame_num > 1)
+ && (s_inp_buf.s_raw_buf.apv_bufs[0] || s_inp_buf.u4_is_last))
+ {
+ /* error status */
+ IH264_ERROR_T ret = IH264_SUCCESS;
+ pic_buf_t *ps_pic_buf = NULL;
+ WORD32 i4_buf_status, i4_curr_poc = 32768;
- /* receive input back from codec */
- s_inp_buf = ps_proc->s_inp_buf;
+ /* In case of skips we return recon, but indicate that buffer is zero size */
+ if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel]
+ || i4_rc_pre_enc_skip)
+ {
- /* send the input to app */
- ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf;
+ ps_video_encode_op->s_ive_op.dump_recon = 1;
+ ps_video_encode_op->s_ive_op.s_recon_buf.au4_wd[0] = 0;
+ ps_video_encode_op->s_ive_op.s_recon_buf.au4_wd[1] = 0;
- if (ps_codec->s_cfg.u4_enable_recon &&
- ps_codec->s_rate_control.pre_encode_skip[ctxt_sel] == 0)
+ }
+ else
{
- /* error status */
- IH264_ERROR_T ret = IH264_SUCCESS;
-
- /* recon buffer */
- rec_buf_t *ps_rec_buf = &ps_codec->as_rec_buf[ctxt_sel];
-
- ps_video_encode_op->s_ive_op.s_recon_buf = ps_video_encode_ip->s_ive_ip.s_recon_buf;
-
- /* copy/convert the recon buffer and return */
- ih264e_fmt_conv(ps_codec, &ps_rec_buf->s_pic_buf,
- ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[0],
- ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[1],
- ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[2],
- ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[0],
- ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[1],
- 0,
- ps_codec->s_cfg.u4_disp_ht);
-
- ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_rec_buf->s_pic_buf.i4_buf_id, BUF_MGR_IO);
- if (IH264_SUCCESS != ret)
+ for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
{
- SET_ERROR_ON_RETURN((IH264E_ERROR_T)ret,
- IVE_FATALERROR,
+ if (ps_codec->as_ref_set[i].i4_pic_cnt == -1)
+ continue;
+
+ i4_buf_status = ih264_buf_mgr_get_status(
+ ps_codec->pv_ref_buf_mgr,
+ ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
+
+ if ((i4_buf_status & BUF_MGR_IO)
+ && (ps_codec->as_ref_set[i].i4_poc < i4_curr_poc))
+ {
+ ps_pic_buf = ps_codec->as_ref_set[i].ps_pic_buf;
+ i4_curr_poc = ps_codec->as_ref_set[i].i4_poc;
+ }
+ }
+
+ ps_video_encode_op->s_ive_op.s_recon_buf =
+ ps_video_encode_ip->s_ive_ip.s_recon_buf;
+
+ /*
+ * If we get a valid buffer. output and free recon.
+ *
+ * we may get an invalid buffer if num_b_frames is 0. This is because
+ * We assume that there will be a ref frame in ref list after encoding
+ * the last frame. With B frames this is correct since its forward ref
+ * pic will be in the ref list. But if num_b_frames is 0, we will not
+ * have a forward ref pic
+ */
+
+ if (ps_pic_buf)
+ {
+ /* copy/convert the recon buffer and return */
+ ih264e_fmt_conv(ps_codec,
+ ps_pic_buf,
+ ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[0],
+ ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[1],
+ ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[2],
+ ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[0],
+ ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[1],
+ 0, ps_codec->s_cfg.u4_disp_ht);
+
+ ps_video_encode_op->s_ive_op.dump_recon = 1;
+
+ ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr,
+ ps_pic_buf->i4_buf_id, BUF_MGR_IO);
+
+ if (IH264_SUCCESS != ret)
+ {
+ SET_ERROR_ON_RETURN(
+ (IH264E_ERROR_T)ret, IVE_FATALERROR,
ps_video_encode_op->s_ive_op.u4_error_code,
IV_FAIL);
+ }
}
}
+ }
- /* release buffers from ref list */
- if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel] == 1)
- {
- /* pic info */
- pic_buf_t *ps_cur_pic;
- /* mv info */
- mv_buf_t *ps_cur_mv_buf;
+ /***************************************************************************
+ * Free reference buffers:
+ * In case of a post enc skip, we have to ensure that those pics will not
+ * be used as reference anymore. In all other cases we will not even mark
+ * the ref buffers
+ ***************************************************************************/
+ if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel])
+ {
+ /* pic info */
+ pic_buf_t *ps_cur_pic;
- /* error status */
- IH264_ERROR_T ret = IH264_SUCCESS;
+ /* mv info */
+ mv_buf_t *ps_cur_mv_buf;
- /* Decrement coded pic count */
- ps_codec->i4_coded_pic_cnt--;
+ /* error status */
+ IH264_ERROR_T ret = IH264_SUCCESS;
- /* loop through to get the min pic cnt among the list of pics stored in ref list */
- /* since the skipped frame may not be on reference list, we may not have an MV bank
- * hence free only if we have allocated */
- for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
+ /* Decrement coded pic count */
+ ps_codec->i4_poc--;
+
+ /* loop through to get the min pic cnt among the list of pics stored in ref list */
+ /* since the skipped frame may not be on reference list, we may not have an MV bank
+ * hence free only if we have allocated */
+ for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
+ {
+ if (ps_codec->i4_pic_cnt == ps_codec->as_ref_set[i].i4_pic_cnt)
{
- if (ps_codec->i4_pic_cnt == ps_codec->as_ref_set[i].i4_pic_cnt)
- {
- ps_codec->as_ref_set[i].i4_pic_cnt = -1;
- ps_codec->as_ref_set[i].i4_poc = -1;
-
- ps_cur_pic = ps_codec->as_ref_set[i].ps_pic_buf;
-
- ps_cur_mv_buf = ps_codec->as_ref_set[i].ps_mv_buf;
-
- /* release this frame from reference list */
- ret = ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr, ps_cur_mv_buf->i4_buf_id , BUF_MGR_REF);
- SET_ERROR_ON_RETURN((IH264E_ERROR_T)ret,
- IVE_FATALERROR,
- ps_video_encode_op->s_ive_op.u4_error_code,
- IV_FAIL);
-
- ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id , BUF_MGR_REF);
- SET_ERROR_ON_RETURN((IH264E_ERROR_T)ret,
- IVE_FATALERROR,
- ps_video_encode_op->s_ive_op.u4_error_code,
- IV_FAIL);
- break;
- }
+
+ ps_cur_pic = ps_codec->as_ref_set[i].ps_pic_buf;
+
+ ps_cur_mv_buf = ps_codec->as_ref_set[i].ps_mv_buf;
+
+ /* release this frame from reference list and recon list */
+ ret = ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr, ps_cur_mv_buf->i4_buf_id , BUF_MGR_REF);
+ ret |= ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr, ps_cur_mv_buf->i4_buf_id , BUF_MGR_IO);
+ SET_ERROR_ON_RETURN((IH264E_ERROR_T)ret,
+ IVE_FATALERROR,
+ ps_video_encode_op->s_ive_op.u4_error_code,
+ IV_FAIL);
+
+ ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id , BUF_MGR_REF);
+ ret |= ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id , BUF_MGR_IO);
+ SET_ERROR_ON_RETURN((IH264E_ERROR_T)ret,
+ IVE_FATALERROR,
+ ps_video_encode_op->s_ive_op.u4_error_code,
+ IV_FAIL);
+ break;
}
}
+ }
- if ((ps_codec->s_rate_control.post_encode_skip[ctxt_sel] == 1) ||
- (ps_codec->s_rate_control.pre_encode_skip[ctxt_sel] == 1))
+ /*
+ * Since recon is not in sync with output, ie there can be frame to be
+ * given back as recon even after last output. Hence we need to mark that
+ * the output is not the last.
+ * Hence search through reflist and mark appropriately
+ */
+ if (ps_codec->s_cfg.u4_enable_recon)
+ {
+ WORD32 i4_buf_status = 0;
+
+ for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
{
- ps_video_encode_op->s_ive_op.dump_recon = 0;
+ if (ps_codec->as_ref_set[i].i4_pic_cnt == -1)
+ continue;
+
+ i4_buf_status |= ih264_buf_mgr_get_status(
+ ps_codec->pv_ref_buf_mgr,
+ ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
}
- else
+
+ if (i4_buf_status & BUF_MGR_IO)
{
- /* set output pic type */
- if (ps_codec->i4_slice_type == PSLICE)
- {
- ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_P_FRAME;
- }
- else if (ps_codec->i4_slice_type == ISLICE && ps_codec->u4_is_idr != 1)
- {
+ s_out_buf.u4_is_last = 0;
+ ps_video_encode_op->s_ive_op.u4_is_last = 0;
+ }
+ }
+
+
+ /**************************************************************************
+ * Signaling to APP
+ * 1) If we valid a valid output mark it so
+ * 2) Set the codec output ps_video_encode_op
+ * 3) Set the error status
+ * 4) Set the return Pic type
+ * Note that we already has marked recon properly
+ * 5)Send the consumed input back to app so that it can free it if possible
+ *
+ * We will have to return the output and input buffers unconditionally
+ * so that app can release them
+ **************************************************************************/
+ if (!i4_rc_pre_enc_skip
+ && !ps_codec->s_rate_control.post_encode_skip[ctxt_sel]
+ && s_inp_buf.s_raw_buf.apv_bufs[0])
+ {
+
+ /* receive output back from codec */
+ s_out_buf = ps_codec->as_out_buf[ctxt_sel];
+
+ /* send the output to app */
+ ps_video_encode_op->s_ive_op.output_present = 1;
+ ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
+
+ /* Set the time stamps of the encodec input */
+ ps_video_encode_op->s_ive_op.u4_timestamp_low = s_inp_buf.u4_timestamp_low;
+ ps_video_encode_op->s_ive_op.u4_timestamp_high = s_inp_buf.u4_timestamp_high;
+
+
+ switch (ps_codec->pic_type)
+ {
+ case PIC_IDR:
+ ps_video_encode_op->s_ive_op.u4_encoded_frame_type =IV_IDR_FRAME;
+ break;
+
+ case PIC_I:
ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_I_FRAME;
- }
- else
- {
- ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_IDR_FRAME;
- }
+ break;
+
+ case PIC_P:
+ ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_P_FRAME;
+ break;
+
+ case PIC_B:
+ ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_B_FRAME;
+ break;
+
+ default:
+ ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
+ break;
}
- /* loop through to get the error status */
for (i = 0; i < (WORD32)ps_codec->s_cfg.u4_num_cores; i++)
{
error_status |= ps_codec->as_process[ctxt_sel + i].i4_error_code;
@@ -569,6 +671,36 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
ps_video_encode_op->s_ive_op.u4_error_code,
IV_FAIL);
}
+ else
+ {
+ /* proc ctxt base idx */
+ WORD32 proc_ctxt_select = ctxt_sel * MAX_PROCESS_THREADS;
+
+ /* proc ctxt */
+ process_ctxt_t *ps_proc = &ps_codec->as_process[proc_ctxt_select];
+
+ /* receive output back from codec */
+ s_out_buf = ps_codec->as_out_buf[ctxt_sel];
+
+ ps_video_encode_op->s_ive_op.output_present = 0;
+ ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
+
+ /* Set the time stamps of the encodec input */
+ ps_video_encode_op->s_ive_op.u4_timestamp_low = 0;
+ ps_video_encode_op->s_ive_op.u4_timestamp_high = 0;
+
+ /* receive input back from codec and send it to app */
+ s_inp_buf = ps_proc->s_inp_buf;
+ ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf;
+
+ ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
+
+ }
+
+ /* Send the input to encoder so that it can free it if possible */
+ ps_video_encode_op->s_ive_op.s_out_buf = s_out_buf.s_bits_buf;
+ ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf;
+
if (1 == s_inp_buf.u4_is_last)
{