blob: c7e371749d15f20bd09fc564f16e04c5a1a08a4f [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
99/*****************************************************************************/
100/* Function Definitions */
101/*****************************************************************************/
102
103/**
104******************************************************************************
105*
106* @brief
107* This function joins all the spawned threads after successful completion of
108* their tasks
109*
110* @par Description
111*
112* @param[in] ps_codec
113* pointer to codec context
114*
115* @returns none
116*
117******************************************************************************
118*/
119void ih264e_join_threads(codec_t *ps_codec)
120{
121 /* temp var */
122 WORD32 i = 0;
123 WORD32 ret = 0;
124
125 /* join spawned threads */
126 while (i < ps_codec->i4_proc_thread_cnt)
127 {
128 if (ps_codec->ai4_process_thread_created[i])
129 {
130 ret = ithread_join(ps_codec->apv_proc_thread_handle[i], NULL);
131 if (ret != 0)
132 {
133 printf("pthread Join Failed");
134 assert(0);
135 }
136 ps_codec->ai4_process_thread_created[i] = 0;
137 i++;
138 }
139 }
140
141 ps_codec->i4_proc_thread_cnt = 0;
142}
143
144/**
145******************************************************************************
146*
147* @brief This function puts the current thread to sleep for a duration
148* of sleep_us
149*
150* @par Description
151* ithread_yield() method causes the calling thread to yield execution to another
152* thread that is ready to run on the current processor. The operating system
153* selects the thread to yield to. ithread_usleep blocks the current thread for
154* the specified number of milliseconds. In other words, yield just says,
155* end my timeslice prematurely, look around for other threads to run. If there
156* is nothing better than me, continue. Sleep says I don't want to run for x
157* milliseconds. Even if no other thread wants to run, don't make me run.
158*
159* @param[in] sleep_us
160* thread sleep duration
161*
162* @returns error_status
163*
164******************************************************************************
165*/
166IH264E_ERROR_T ih264e_wait_for_thread(UWORD32 sleep_us)
167{
168 /* yield thread */
169 ithread_yield();
170
171 /* put thread to sleep */
172 ithread_usleep(sleep_us);
173
174 return IH264E_SUCCESS;
175}
176
177/**
178******************************************************************************
179*
180* @brief
181* Encodes in synchronous api mode
182*
183* @par Description
184* This routine processes input yuv, encodes it and outputs bitstream and recon
185*
186* @param[in] ps_codec_obj
187* Pointer to codec object at API level
188*
189* @param[in] pv_api_ip
190* Pointer to input argument structure
191*
192* @param[out] pv_api_op
193* Pointer to output argument structure
194*
195* @returns Status
196*
197******************************************************************************
198*/
199WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
200{
201 /* error status */
202 IH264E_ERROR_T error_status = IH264E_SUCCESS;
203
204 /* codec ctxt */
205 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
206
207 /* input frame to encode */
208 ih264e_video_encode_ip_t *ps_video_encode_ip = pv_api_ip;
209
210 /* output buffer to write stream */
211 ih264e_video_encode_op_t *ps_video_encode_op = pv_api_op;
212
213 /* i/o structures */
214 inp_buf_t s_inp_buf;
215 out_buf_t s_out_buf;
216
217 /* temp var */
Harinarayanan K K134291e2015-06-18 16:03:38 +0530218 WORD32 ctxt_sel = 0, i, i4_rc_pre_enc_skip;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530219
220 /********************************************************************/
221 /* BEGIN INIT */
222 /********************************************************************/
223 /* reset output structure */
224 ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
225 ps_video_encode_op->s_ive_op.output_present = 0;
226 ps_video_encode_op->s_ive_op.dump_recon = 0;
227 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
Neelkamal Semwal65b4ce92021-03-12 10:15:49 +0530228 /* By default set the current input buffer as the buffer to be freed */
229 /* This will later be updated to the actual input that gets encoded */
230 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 +0530231
Harinarayanan K Kd2d469e2015-06-19 14:45:44 +0530232 /* Check for output memory allocation size */
233 if (ps_video_encode_ip->s_ive_ip.s_out_buf.u4_bufsize < MIN_STREAM_SIZE)
234 {
235 error_status |= IH264E_INSUFFICIENT_OUTPUT_BUFFER;
236 SET_ERROR_ON_RETURN(error_status,
237 IVE_UNSUPPORTEDPARAM,
238 ps_video_encode_op->s_ive_op.u4_error_code,
239 IV_FAIL);
240 }
241
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530242 /* copy output info. to internal structure */
243 s_out_buf.s_bits_buf = ps_video_encode_ip->s_ive_ip.s_out_buf;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530244 s_out_buf.u4_is_last = 0;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530245 s_out_buf.u4_timestamp_low = ps_video_encode_ip->s_ive_ip.u4_timestamp_low;
246 s_out_buf.u4_timestamp_high = ps_video_encode_ip->s_ive_ip.u4_timestamp_high;
247
248 /* api call cnt */
249 ps_codec->i4_encode_api_call_cnt += 1;
250
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530251 /* codec context selector */
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530252 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530253
254 /* reset status flags */
255 ps_codec->ai4_pic_cnt[ctxt_sel] = -1;
256 ps_codec->s_rate_control.post_encode_skip[ctxt_sel] = 0;
257 ps_codec->s_rate_control.pre_encode_skip[ctxt_sel] = 0;
258
259 /* pass output buffer to codec */
260 ps_codec->as_out_buf[ctxt_sel] = s_out_buf;
261
262 /* initialize codec ctxt with default params for the first encode api call */
263 if (ps_codec->i4_encode_api_call_cnt == 0)
264 {
265 ih264e_codec_init(ps_codec);
266 }
267
268 /* parse configuration params */
269 for (i = 0; i < MAX_ACTIVE_CONFIG_PARAMS; i++)
270 {
271 cfg_params_t *ps_cfg = &ps_codec->as_cfg[i];
272
273 if (1 == ps_cfg->u4_is_valid)
274 {
Harinarayanan K K134291e2015-06-18 16:03:38 +0530275 if ( ((ps_cfg->u4_timestamp_high == ps_video_encode_ip->s_ive_ip.u4_timestamp_high) &&
276 (ps_cfg->u4_timestamp_low == ps_video_encode_ip->s_ive_ip.u4_timestamp_low)) ||
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530277 ((WORD32)ps_cfg->u4_timestamp_high == -1) ||
278 ((WORD32)ps_cfg->u4_timestamp_low == -1) )
279 {
280 error_status |= ih264e_codec_update_config(ps_codec, ps_cfg);
281 SET_ERROR_ON_RETURN(error_status,
282 IVE_UNSUPPORTEDPARAM,
283 ps_video_encode_op->s_ive_op.u4_error_code,
284 IV_FAIL);
285
286 ps_cfg->u4_is_valid = 0;
287 }
288 }
289 }
290
291 /******************************************************************
292 * INSERT LOGO
293 *****************************************************************/
294#ifdef LOGO_EN
295 if (s_inp_buf.s_raw_buf.apv_bufs[0] != NULL &&
296 ps_codec->i4_header_mode != 1)
297 {
298 ih264e_insert_logo(s_inp_buf.s_raw_buf.apv_bufs[0],
299 s_inp_buf.s_raw_buf.apv_bufs[1],
300 s_inp_buf.s_raw_buf.apv_bufs[2],
301 s_inp_buf.s_raw_buf.au4_strd[0],
302 0,
303 0,
304 ps_codec->s_cfg.e_inp_color_fmt,
305 ps_codec->s_cfg.u4_disp_wd,
306 ps_codec->s_cfg.u4_disp_ht);
307 }
308#endif /*LOGO_EN*/
309
Martin Storsjo7c99adf2015-06-23 11:51:06 +0300310 /* In case of alt ref and B pics we will have non reference frame in stream */
311 if (ps_codec->s_cfg.u4_enable_alt_ref || ps_codec->s_cfg.u4_num_bframes)
312 {
313 ps_codec->i4_non_ref_frames_in_stream = 1;
314 }
315
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530316 if (ps_codec->i4_encode_api_call_cnt == 0)
317 {
318 /********************************************************************/
319 /* number of mv/ref bank buffers used by the codec, */
320 /* 1 to handle curr frame */
321 /* 1 to store information of ref frame */
322 /* 1 more additional because of the codec employs 2 ctxt sets */
323 /* to assist asynchronous API */
324 /********************************************************************/
325
326 /* initialize mv bank buffer manager */
327 error_status |= ih264e_mv_buf_mgr_add_bufs(ps_codec);
328 SET_ERROR_ON_RETURN(error_status,
329 IVE_FATALERROR,
330 ps_video_encode_op->s_ive_op.u4_error_code,
331 IV_FAIL);
332
333 /* initialize ref bank buffer manager */
334 error_status |= ih264e_pic_buf_mgr_add_bufs(ps_codec);
335 SET_ERROR_ON_RETURN(error_status,
336 IVE_FATALERROR,
337 ps_video_encode_op->s_ive_op.u4_error_code,
338 IV_FAIL);
339
340 /* for the first frame, generate header when not requested explicitly */
341 if (ps_codec->i4_header_mode == 0 &&
342 ps_codec->u4_header_generated == 0)
343 {
344 ps_codec->i4_gen_header = 1;
345 }
346 }
347
348 /* generate header and return when encoder is operated in header mode */
349 if (ps_codec->i4_header_mode == 1)
350 {
351 /* whenever the header is generated, this implies a start of sequence
352 * and a sequence needs to be started with IDR
353 */
354 ps_codec->force_curr_frame_type = IV_IDR_FRAME;
355
356 /* generate header */
357 error_status |= ih264e_generate_sps_pps(ps_codec);
358
359 /* api call cnt */
360 ps_codec->i4_encode_api_call_cnt --;
361
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530362 /* header mode tag is not sticky */
363 ps_codec->i4_header_mode = 0;
Martin Storsjoafe8d032015-06-23 11:14:45 +0300364 ps_codec->i4_gen_header = 0;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530365
366 /* send the input to app */
Martin Storsjo8e78e302015-06-29 16:33:39 +0300367 ps_video_encode_op->s_ive_op.s_inp_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf;
368 ps_video_encode_op->s_ive_op.u4_timestamp_low = ps_video_encode_ip->s_ive_ip.u4_timestamp_low;
369 ps_video_encode_op->s_ive_op.u4_timestamp_high = ps_video_encode_ip->s_ive_ip.u4_timestamp_high;
370
371 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 +0530372
373 /* send the output to app */
374 ps_video_encode_op->s_ive_op.output_present = 1;
375 ps_video_encode_op->s_ive_op.dump_recon = 0;
376 ps_video_encode_op->s_ive_op.s_out_buf = ps_codec->as_out_buf[ctxt_sel].s_bits_buf;
377
378 /* error status */
379 SET_ERROR_ON_RETURN(error_status,
380 IVE_FATALERROR,
381 ps_video_encode_op->s_ive_op.u4_error_code,
382 IV_FAIL);
383
384 /* indicates that header has been generated previously */
385 ps_codec->u4_header_generated = 1;
386
387 return IV_SUCCESS;
388 }
389
Harinarayanan K K134291e2015-06-18 16:03:38 +0530390 /* curr pic cnt */
391 ps_codec->i4_pic_cnt += 1;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530392
Harinarayanan K K134291e2015-06-18 16:03:38 +0530393 i4_rc_pre_enc_skip = 0;
394 i4_rc_pre_enc_skip = ih264e_input_queue_update(
395 ps_codec, &ps_video_encode_ip->s_ive_ip, &s_inp_buf);
396
397 s_out_buf.u4_is_last = s_inp_buf.u4_is_last;
398 ps_video_encode_op->s_ive_op.u4_is_last = s_inp_buf.u4_is_last;
399
Neelkamal Semwal65b4ce92021-03-12 10:15:49 +0530400 /* Send the input to application so that it can free it */
401 ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf;
402
Harinarayanan K K134291e2015-06-18 16:03:38 +0530403 /* Only encode if the current frame is not pre-encode skip */
404 if (!i4_rc_pre_enc_skip && s_inp_buf.s_raw_buf.apv_bufs[0])
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530405 {
Harinarayanan K K134291e2015-06-18 16:03:38 +0530406 /* proc ctxt base idx */
407 WORD32 proc_ctxt_select = ctxt_sel * MAX_PROCESS_THREADS;
408
409 /* proc ctxt */
410 process_ctxt_t *ps_proc = &ps_codec->as_process[proc_ctxt_select];
411
412 WORD32 ret = 0;
413
414 /* number of addl. threads to be created */
415 WORD32 num_thread_cnt = ps_codec->s_cfg.u4_num_cores - 1;
416
Martin Storsjo9fbffcf2015-06-27 00:19:48 +0300417 /* array giving pic cnt that is being processed in curr context set */
418 ps_codec->ai4_pic_cnt[ctxt_sel] = ps_codec->i4_pic_cnt;
419
420 /* initialize all relevant process ctxts */
421 error_status |= ih264e_pic_init(ps_codec, &s_inp_buf);
422 SET_ERROR_ON_RETURN(error_status,
423 IVE_FATALERROR,
424 ps_video_encode_op->s_ive_op.u4_error_code,
425 IV_FAIL);
426
Harinarayanan K K134291e2015-06-18 16:03:38 +0530427 for (i = 0; i < num_thread_cnt; i++)
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530428 {
Harinarayanan K K134291e2015-06-18 16:03:38 +0530429 ret = ithread_create(ps_codec->apv_proc_thread_handle[i],
430 NULL,
431 (void *)ih264e_process_thread,
432 &ps_codec->as_process[i + 1]);
433 if (ret != 0)
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530434 {
Harinarayanan K K134291e2015-06-18 16:03:38 +0530435 printf("pthread Create Failed");
436 assert(0);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530437 }
438
Harinarayanan K K134291e2015-06-18 16:03:38 +0530439 ps_codec->ai4_process_thread_created[i] = 1;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530440
Harinarayanan K K134291e2015-06-18 16:03:38 +0530441 ps_codec->i4_proc_thread_cnt++;
442 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530443
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530444
Harinarayanan K K134291e2015-06-18 16:03:38 +0530445 /* launch job */
446 ih264e_process_thread(ps_proc);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530447
Harinarayanan K K134291e2015-06-18 16:03:38 +0530448 /* Join threads at the end of encoding a frame */
449 ih264e_join_threads(ps_codec);
450
451 ih264_list_reset(ps_codec->pv_proc_jobq);
452
453 ih264_list_reset(ps_codec->pv_entropy_jobq);
454 }
455
456
457 /****************************************************************************
458 * RECON
459 * Since we have forward dependent frames, we cannot return recon in encoding
460 * order. It must be in poc order, or input pic order. To achieve this we
461 * introduce a delay of 1 to the recon wrt encode. Now since we have that
462 * delay, at any point minimum of pic_cnt in our ref buffer will be the
463 * correct frame. For ex let our GOP be IBBP [1 2 3 4] . The encode order
464 * will be [1 4 2 3] .Now since we have a delay of 1, when we are done with
465 * encoding 4, the min in the list will be 1. After encoding 2, it will be
466 * 2, 3 after 3 and 4 after 4. Hence we can return in sequence. Note
467 * that the 1 delay is critical. Hence if we have post enc skip, we must
468 * skip here too. Note that since post enc skip already frees the recon
469 * buffer we need not do any thing here
470 *
471 * We need to return a recon when ever we consume an input buffer. This
472 * comsumption include a pre or post enc skip. Thus dump recon is set for
473 * all cases except when
474 * 1) We are waiting -> ps_codec->i4_frame_num > 1
475 * 2) When the input buffer is null [ ie we are not consuming any inp]
476 * An exception need to be made for the case when we have the last buffer
477 * since we need to flush out the on remainig recon.
478 ****************************************************************************/
479
480 ps_video_encode_op->s_ive_op.dump_recon = 0;
481
Harinarayanan K Kf080d512015-06-26 15:20:54 +0530482 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 +0530483 && (s_inp_buf.s_raw_buf.apv_bufs[0] || s_inp_buf.u4_is_last))
484 {
485 /* error status */
486 IH264_ERROR_T ret = IH264_SUCCESS;
487 pic_buf_t *ps_pic_buf = NULL;
488 WORD32 i4_buf_status, i4_curr_poc = 32768;
489
490 /* In case of skips we return recon, but indicate that buffer is zero size */
491 if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel]
492 || i4_rc_pre_enc_skip)
493 {
494
495 ps_video_encode_op->s_ive_op.dump_recon = 1;
496 ps_video_encode_op->s_ive_op.s_recon_buf.au4_wd[0] = 0;
497 ps_video_encode_op->s_ive_op.s_recon_buf.au4_wd[1] = 0;
498
499 }
500 else
501 {
502 for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
503 {
504 if (ps_codec->as_ref_set[i].i4_pic_cnt == -1)
505 continue;
506
507 i4_buf_status = ih264_buf_mgr_get_status(
508 ps_codec->pv_ref_buf_mgr,
509 ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
510
511 if ((i4_buf_status & BUF_MGR_IO)
512 && (ps_codec->as_ref_set[i].i4_poc < i4_curr_poc))
513 {
514 ps_pic_buf = ps_codec->as_ref_set[i].ps_pic_buf;
515 i4_curr_poc = ps_codec->as_ref_set[i].i4_poc;
516 }
517 }
518
519 ps_video_encode_op->s_ive_op.s_recon_buf =
520 ps_video_encode_ip->s_ive_ip.s_recon_buf;
521
522 /*
523 * If we get a valid buffer. output and free recon.
524 *
525 * we may get an invalid buffer if num_b_frames is 0. This is because
526 * We assume that there will be a ref frame in ref list after encoding
527 * the last frame. With B frames this is correct since its forward ref
528 * pic will be in the ref list. But if num_b_frames is 0, we will not
529 * have a forward ref pic
530 */
531
532 if (ps_pic_buf)
533 {
534 /* copy/convert the recon buffer and return */
535 ih264e_fmt_conv(ps_codec,
536 ps_pic_buf,
537 ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[0],
538 ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[1],
539 ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[2],
540 ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[0],
541 ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[1],
542 0, ps_codec->s_cfg.u4_disp_ht);
543
544 ps_video_encode_op->s_ive_op.dump_recon = 1;
545
546 ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr,
547 ps_pic_buf->i4_buf_id, BUF_MGR_IO);
548
549 if (IH264_SUCCESS != ret)
550 {
551 SET_ERROR_ON_RETURN(
552 (IH264E_ERROR_T)ret, IVE_FATALERROR,
553 ps_video_encode_op->s_ive_op.u4_error_code,
554 IV_FAIL);
555 }
556 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530557 }
558 }
559
Harinarayanan K K134291e2015-06-18 16:03:38 +0530560
561 /***************************************************************************
562 * Free reference buffers:
563 * In case of a post enc skip, we have to ensure that those pics will not
564 * be used as reference anymore. In all other cases we will not even mark
565 * the ref buffers
566 ***************************************************************************/
567 if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel])
568 {
569 /* pic info */
570 pic_buf_t *ps_cur_pic;
571
572 /* mv info */
573 mv_buf_t *ps_cur_mv_buf;
574
575 /* error status */
576 IH264_ERROR_T ret = IH264_SUCCESS;
577
578 /* Decrement coded pic count */
579 ps_codec->i4_poc--;
580
581 /* loop through to get the min pic cnt among the list of pics stored in ref list */
582 /* since the skipped frame may not be on reference list, we may not have an MV bank
583 * hence free only if we have allocated */
584 for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
585 {
586 if (ps_codec->i4_pic_cnt == ps_codec->as_ref_set[i].i4_pic_cnt)
587 {
588
589 ps_cur_pic = ps_codec->as_ref_set[i].ps_pic_buf;
590
591 ps_cur_mv_buf = ps_codec->as_ref_set[i].ps_mv_buf;
592
593 /* release this frame from reference list and recon list */
594 ret = ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr, ps_cur_mv_buf->i4_buf_id , BUF_MGR_REF);
595 ret |= ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr, ps_cur_mv_buf->i4_buf_id , BUF_MGR_IO);
596 SET_ERROR_ON_RETURN((IH264E_ERROR_T)ret,
597 IVE_FATALERROR,
598 ps_video_encode_op->s_ive_op.u4_error_code,
599 IV_FAIL);
600
601 ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id , BUF_MGR_REF);
602 ret |= ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id , BUF_MGR_IO);
603 SET_ERROR_ON_RETURN((IH264E_ERROR_T)ret,
604 IVE_FATALERROR,
605 ps_video_encode_op->s_ive_op.u4_error_code,
606 IV_FAIL);
607 break;
608 }
609 }
610 }
611
612 /*
613 * Since recon is not in sync with output, ie there can be frame to be
614 * given back as recon even after last output. Hence we need to mark that
615 * the output is not the last.
616 * Hence search through reflist and mark appropriately
617 */
618 if (ps_codec->s_cfg.u4_enable_recon)
619 {
620 WORD32 i4_buf_status = 0;
621
622 for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
623 {
624 if (ps_codec->as_ref_set[i].i4_pic_cnt == -1)
625 continue;
626
627 i4_buf_status |= ih264_buf_mgr_get_status(
628 ps_codec->pv_ref_buf_mgr,
629 ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
630 }
631
632 if (i4_buf_status & BUF_MGR_IO)
633 {
634 s_out_buf.u4_is_last = 0;
635 ps_video_encode_op->s_ive_op.u4_is_last = 0;
636 }
637 }
638
639
640 /**************************************************************************
641 * Signaling to APP
642 * 1) If we valid a valid output mark it so
643 * 2) Set the codec output ps_video_encode_op
644 * 3) Set the error status
645 * 4) Set the return Pic type
646 * Note that we already has marked recon properly
647 * 5)Send the consumed input back to app so that it can free it if possible
648 *
649 * We will have to return the output and input buffers unconditionally
650 * so that app can release them
651 **************************************************************************/
652 if (!i4_rc_pre_enc_skip
653 && !ps_codec->s_rate_control.post_encode_skip[ctxt_sel]
654 && s_inp_buf.s_raw_buf.apv_bufs[0])
655 {
656
657 /* receive output back from codec */
658 s_out_buf = ps_codec->as_out_buf[ctxt_sel];
659
660 /* send the output to app */
661 ps_video_encode_op->s_ive_op.output_present = 1;
662 ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
663
664 /* Set the time stamps of the encodec input */
665 ps_video_encode_op->s_ive_op.u4_timestamp_low = s_inp_buf.u4_timestamp_low;
666 ps_video_encode_op->s_ive_op.u4_timestamp_high = s_inp_buf.u4_timestamp_high;
667
668
669 switch (ps_codec->pic_type)
670 {
671 case PIC_IDR:
672 ps_video_encode_op->s_ive_op.u4_encoded_frame_type =IV_IDR_FRAME;
673 break;
674
675 case PIC_I:
676 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_I_FRAME;
677 break;
678
679 case PIC_P:
680 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_P_FRAME;
681 break;
682
683 case PIC_B:
684 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_B_FRAME;
685 break;
686
687 default:
688 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
689 break;
690 }
691
692 for (i = 0; i < (WORD32)ps_codec->s_cfg.u4_num_cores; i++)
693 {
694 error_status |= ps_codec->as_process[ctxt_sel + i].i4_error_code;
695 }
696 SET_ERROR_ON_RETURN(error_status,
697 IVE_FATALERROR,
698 ps_video_encode_op->s_ive_op.u4_error_code,
699 IV_FAIL);
700 }
701 else
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530702 {
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530703 /* receive output back from codec */
704 s_out_buf = ps_codec->as_out_buf[ctxt_sel];
705
Harinarayanan K K134291e2015-06-18 16:03:38 +0530706 ps_video_encode_op->s_ive_op.output_present = 0;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530707 ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
708
Harinarayanan K K134291e2015-06-18 16:03:38 +0530709 /* Set the time stamps of the encodec input */
710 ps_video_encode_op->s_ive_op.u4_timestamp_low = 0;
711 ps_video_encode_op->s_ive_op.u4_timestamp_high = 0;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530712
Harinarayanan K K134291e2015-06-18 16:03:38 +0530713 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530714
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530715 }
716
Harinarayanan K K134291e2015-06-18 16:03:38 +0530717 ps_video_encode_op->s_ive_op.s_out_buf = s_out_buf.s_bits_buf;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530718
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530719 if (1 == s_inp_buf.u4_is_last)
720 {
721 ps_video_encode_op->s_ive_op.output_present = 0;
722 ps_video_encode_op->s_ive_op.dump_recon = 0;
723 }
724
725 return IV_SUCCESS;
726}