• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /* File Includes                                                             */
23 /*****************************************************************************/
24 
25 /* System include files */
26 #include "stdio.h"
27 #include "string.h"
28 
29 /* User include files */
30 #include "irc_datatypes.h"
31 #include "irc_cntrl_param.h"
32 #include "irc_mem_req_and_acq.h"
33 #include "irc_picture_type.h"
34 #include "irc_trace_support.h"
35 
36 #define MAX_INTER_FRM_INT   10
37 
38 /******************************Pic_details ************************************/
39 typedef struct
40 {
41     /* The id sent by the codec */
42     WORD32 i4_pic_id;
43 
44     /* The pics come in, in this order  */
45     WORD32 i4_pic_disp_order_no;
46 
47     /* I,P,B */
48     picture_type_e e_pic_type;
49 
50 } pic_details_t;
51 
52 /**************************Pic_handling structure *****************************/
53 typedef struct pic_handling_t
54 {
55     /***************************************************************************
56      * Inputs from the codec
57      **************************************************************************/
58 
59     /* Number of frames after which an I frame will repeat in display order */
60     WORD32 i4_intra_frm_int;
61 
62     /* (num_b_pics_in_subgop + 1) */
63     WORD32 i4_inter_frm_int;
64 
65     /* After these many buffered frames, the pics are encoded */
66     WORD32 i4_max_inter_frm_int;
67 
68     /* OPEN or CLOSED */
69     WORD32 i4_is_gop_closed;
70 
71     /* The pic stack */
72     /* Stack used to store the input pics in encode order */
73     pic_details_t as_pic_stack[MAX_INTER_FRM_INT + 2];
74 
75     /***************************************************************************
76      * Counters
77      **************************************************************************/
78 
79     /* Decides whether a B or ref pic */
80     WORD32 i4_buf_pic_no;
81 
82     /* Current pic's number in displayed, and gets reset after an I-frm */
83     WORD32 i4_pic_disp_order_no;
84 
85     /* Number of P frms that have come, in the current gop, so far */
86     WORD32 i4_p_count_in_gop;
87 
88     /* Number of B frms that have come, in the current gop, so far */
89     WORD32 i4_b_count_in_gop;
90 
91     /* Number of B frms that have come, in the current subgop, so far */
92     WORD32 i4_b_count_in_subgop;
93 
94     /***************************************************************************
95      * Indices to the pic stack (Since we store the pics in the encode order,
96      * these vars are modified to meet that)
97      **************************************************************************/
98 
99     /* B_PIC index */
100     WORD32 i4_b_pic_idx;
101 
102     /* I,P PIC index */
103     WORD32 i4_ref_pic_idx;
104 
105     /***************************************************************************
106      * Variables operating on the input pics
107      **************************************************************************/
108 
109     /* Flag denoting whether it's the first gop or not */
110     WORD32 i4_is_first_gop;
111 
112     /* Number of B_PICs in an incomplete subgop */
113     WORD32 i4_b_in_incomp_subgop;
114 
115     /* In CLOSED_GOPs, even if inter_frm_int > 1, there can be 2 continous
116      * P_PICs at the GOP end. This takes values of 0 or 1 */
117     WORD32 i4_extra_p;
118 
119     /***************************************************************************
120      * Arrays storing the number of frms in the gop
121      **************************************************************************/
122 
123     /* In the steady state, what's the pic distribution in display order */
124     WORD32 i4_frms_in_gop[MAX_PIC_TYPE];
125 
126     /*
127      * In case of a change in inter frm int call, the pic distribution in
128      * that gop in display order
129      */
130     WORD32 i4_frms_in_cur_gop[MAX_PIC_TYPE];
131 
132     /*
133      * This is used to denote the number of frms remaining to be encoded in the
134      * current gop
135      */
136     WORD32 i4_rem_frms_in_gop[MAX_PIC_TYPE];
137 
138     /***************************************************************************
139      * Variables operating on the output pics
140      **************************************************************************/
141 
142     /* Counts the frms encoded in a gop */
143     WORD32 i4_coded_pic_no;
144 
145     /* Counts from the start of stack to the end repeatedly */
146     WORD32 i4_stack_count;
147 
148     /***************************************************************************
149      * Tracking a change in the inputs from the codec
150      **************************************************************************/
151 
152     /* A flag that is set when the codec calls for a change in inter_frm_int */
153     WORD32 i4_change_in_inter_frm_int;
154 
155     /*
156      * When a change_in_inter_frm_int is called, this stores the new
157      * inter_frm_int
158      */
159     WORD32 i4_new_inter_frm_int;
160 
161     /*
162      * When a change_in_inter_frm_int is called in the middle of a gop,this
163      * stores the B_PICs in the incomplete subgop of the mixed gop
164      */
165     WORD32 i4_b_in_incomp_subgop_mix_gop;
166 
167     /*
168      * For a CLOSED GOP, when a change_in_inter_frm_int is called in the middle
169      * of a gop,this is a flag denoting if there is an extra P_PIC in the mixed
170      * gop
171      */
172     WORD32 i4_extra_p_mix_gop;
173 
174     /* A flag that is set when the codec calls for a change in intra_frm_int */
175     WORD32 i4_change_in_intra_frm_int;
176 
177     /*
178      * When a change_in_intra_frm_int is called, this stores the new
179      * intra_frm_int
180      */
181     WORD32 i4_new_intra_frm_int;
182 
183     /***************************************************************************
184      * Previous pic_stack_indices & details
185      **************************************************************************/
186     pic_details_t s_prev_pic_details;
187 
188     WORD32 i4_prev_b_pic_idx;
189 
190     WORD32 i4_last_frm_in_gop;
191 
192     WORD32 i4_first_gop_encoded;
193 
194     /* NITT TBR */
195     picture_type_e e_previous_pic_type;
196 
197     WORD32 i4_force_I_frame;
198 
199     WORD32 i4_forced_I_frame_cur_frame;
200 
201     WORD32 i4_sum_remaining_frm_in_gop;
202 
203     WORD32 i4_mod_temp_ref_cnt;
204 
205     WORD32 i4_frames_in_fif_gop;
206 
207     WORD32 i4_prev_intra_frame_interval;
208 
209 } pic_handling_t;
210 
211 static void irc_update_pic_distbn(pic_handling_t *ps_pic_handling,
212                                   WORD32 i4_intra_frm_int,
213                                   WORD32 i4_inter_frm_int,
214                                   WORD32 i4_gop_boundary);
215 
216 static void find_pic_distbn_in_gop(WORD32 i4_frms_in_gop[MAX_PIC_TYPE],
217                                    WORD32 i4_intra_frm_int,
218                                    WORD32 i4_inter_frm_int,
219                                    WORD32 i4_is_gop_closed,
220                                    WORD32 *pi4_b_in_incomp_subgop,
221                                    WORD32 *pi4_extra_p);
222 
irc_pic_handling_num_fill_use_free_memtab(pic_handling_t ** pps_pic_handling,itt_memtab_t * ps_memtab,ITT_FUNC_TYPE_E e_func_type)223 WORD32 irc_pic_handling_num_fill_use_free_memtab(pic_handling_t **pps_pic_handling,
224                                                  itt_memtab_t *ps_memtab,
225                                                  ITT_FUNC_TYPE_E e_func_type)
226 {
227     WORD32 i4_mem_tab_idx = 0;
228     pic_handling_t s_pic_handling_temp;
229 
230     /*
231      * Hack for al alloc, during which we dont have any state memory.
232      * Dereferencing can cause issues
233      */
234     if(e_func_type == GET_NUM_MEMTAB || e_func_type == FILL_MEMTAB)
235     {
236         (*pps_pic_handling) = &s_pic_handling_temp;
237     }
238 
239     /*for src rate control state structure*/
240     if(e_func_type != GET_NUM_MEMTAB)
241     {
242         fill_memtab(&ps_memtab[i4_mem_tab_idx], sizeof(pic_handling_t),
243                     ALIGN_128_BYTE, PERSISTENT, DDR);
244         use_or_fill_base(&ps_memtab[0], (void**)pps_pic_handling, e_func_type);
245     }
246     i4_mem_tab_idx++;
247 
248     return (i4_mem_tab_idx);
249 }
250 
251 /******************************************************************************
252  Description     : initializes the pic handling state struct
253  *****************************************************************************/
irc_init_pic_handling(pic_handling_t * ps_pic_handling,WORD32 i4_intra_frm_int,WORD32 i4_inter_frm_int,WORD32 i4_max_inter_frm_int,WORD32 i4_is_gop_closed)254 void irc_init_pic_handling(pic_handling_t *ps_pic_handling,
255                            WORD32 i4_intra_frm_int,
256                            WORD32 i4_inter_frm_int,
257                            WORD32 i4_max_inter_frm_int,
258                            WORD32 i4_is_gop_closed)
259 {
260     /* Declarations */
261     WORD32 i;
262 
263     /* Checks */
264     /* Codec Parameters */
265     ps_pic_handling->i4_intra_frm_int = i4_intra_frm_int;
266     ps_pic_handling->i4_inter_frm_int = i4_inter_frm_int;
267     ps_pic_handling->i4_max_inter_frm_int = i4_max_inter_frm_int;
268     ps_pic_handling->i4_is_gop_closed = i4_is_gop_closed;
269 
270     /* Pic_stack */
271     memset(ps_pic_handling->as_pic_stack, 0,
272            sizeof(ps_pic_handling->as_pic_stack));
273     memset(&ps_pic_handling->s_prev_pic_details, 0,
274            sizeof(ps_pic_handling->s_prev_pic_details));
275 
276     /* Counters */
277     ps_pic_handling->i4_buf_pic_no = 0;
278     ps_pic_handling->i4_pic_disp_order_no = 0;
279 
280     /* Indices to the pic_stack */
281     ps_pic_handling->i4_ref_pic_idx = 0;
282     /*
283      * B frame index should be ref_frame_num,
284      * which is 2 in out case
285      */
286     ps_pic_handling->i4_b_pic_idx = 2;
287     ps_pic_handling->i4_prev_b_pic_idx = 2;
288 
289     /* Variables working on the input frames */
290     ps_pic_handling->i4_is_first_gop = 1;
291     ps_pic_handling->i4_p_count_in_gop = 0;
292     ps_pic_handling->i4_b_count_in_gop = 0;
293     ps_pic_handling->i4_b_count_in_subgop = 0;
294 
295     /* Variables working on the output frames */
296     ps_pic_handling->i4_coded_pic_no = -1;
297     ps_pic_handling->i4_stack_count = -1;
298 
299     /* Tracks the changes in the Codec Parameters */
300     ps_pic_handling->i4_change_in_inter_frm_int = 0;
301     ps_pic_handling->i4_new_inter_frm_int = i4_max_inter_frm_int;
302 
303     /* Tracks the changes in the Codec Parameters */
304     ps_pic_handling->i4_change_in_intra_frm_int = 0;
305     ps_pic_handling->i4_new_intra_frm_int = i4_intra_frm_int;
306 
307     /* Variables on which the bit allocation is dependent  */
308     /* Get the pic distribution in the gop */
309     find_pic_distbn_in_gop(ps_pic_handling->i4_frms_in_gop, i4_intra_frm_int,
310                            i4_inter_frm_int, i4_is_gop_closed,
311                            &ps_pic_handling->i4_b_in_incomp_subgop,
312                            &ps_pic_handling->i4_extra_p);
313 
314     for(i = 0; i < MAX_PIC_TYPE; i++)
315     {
316         ps_pic_handling->i4_frms_in_cur_gop[i] =
317                         ps_pic_handling->i4_frms_in_gop[i];
318         ps_pic_handling->i4_rem_frms_in_gop[i] =
319                         ps_pic_handling->i4_frms_in_gop[i];
320     }
321 
322     ps_pic_handling->e_previous_pic_type = I_PIC;
323     ps_pic_handling->i4_prev_intra_frame_interval = i4_intra_frm_int;
324     ps_pic_handling->i4_force_I_frame = 0;
325     ps_pic_handling->i4_forced_I_frame_cur_frame = 0;
326     ps_pic_handling->i4_sum_remaining_frm_in_gop = 0;
327     ps_pic_handling->i4_mod_temp_ref_cnt = 0;
328 
329     ps_pic_handling->i4_b_in_incomp_subgop_mix_gop =
330                     ps_pic_handling->i4_b_in_incomp_subgop;
331     ps_pic_handling->i4_extra_p_mix_gop = ps_pic_handling->i4_extra_p;
332 
333     ps_pic_handling->i4_last_frm_in_gop = 0;
334     ps_pic_handling->i4_first_gop_encoded = 0;
335     ps_pic_handling->i4_frames_in_fif_gop = 0;
336 
337 }
338 
339 /*******************************************************************************
340  * @brief registers the new intra frame interval value
341  ******************************************************************************/
irc_pic_handling_register_new_int_frm_interval(pic_handling_t * ps_pic_handling,WORD32 i4_intra_frm_int)342 void irc_pic_handling_register_new_int_frm_interval(pic_handling_t *ps_pic_handling,
343                                                     WORD32 i4_intra_frm_int)
344 {
345     ps_pic_handling->i4_change_in_intra_frm_int = 1;
346     ps_pic_handling->i4_new_intra_frm_int = i4_intra_frm_int;
347 }
348 
irc_pic_handling_register_new_inter_frm_interval(pic_handling_t * ps_pic_handling,WORD32 i4_inter_frm_int)349 void irc_pic_handling_register_new_inter_frm_interval(pic_handling_t *ps_pic_handling,
350                                                       WORD32 i4_inter_frm_int)
351 {
352     /* Update the state structure with the latest values */
353     ps_pic_handling->i4_change_in_inter_frm_int = 1;
354     ps_pic_handling->i4_new_inter_frm_int = i4_inter_frm_int;
355 }
356 
start_new_gop(pic_handling_t * ps_pic_handling)357 static void start_new_gop(pic_handling_t *ps_pic_handling)
358 {
359     WORD32 i;
360     WORD32 i4_sum_remaining_frm_in_gop = 0;
361 
362     /* Now, the end of gop updates */
363     ps_pic_handling->i4_pic_disp_order_no = 0;
364     ps_pic_handling->i4_buf_pic_no = 0;
365     ps_pic_handling->i4_is_first_gop = 0;
366     ps_pic_handling->i4_extra_p_mix_gop = ps_pic_handling->i4_extra_p;
367 
368     if(ps_pic_handling->i4_is_gop_closed)
369     {
370         ps_pic_handling->i4_b_in_incomp_subgop_mix_gop =
371                         ps_pic_handling->i4_b_in_incomp_subgop;
372     }
373     /*
374      * Store the number of frames in the gop that is encoded till now
375      * just before Force I frame call is made
376      */
377     ps_pic_handling->i4_frames_in_fif_gop = ps_pic_handling->i4_b_count_in_gop
378                     + ps_pic_handling->i4_p_count_in_gop + 1;
379     for(i = 0; i < MAX_PIC_TYPE; i++)
380     {
381         i4_sum_remaining_frm_in_gop += ps_pic_handling->i4_rem_frms_in_gop[i];
382     }
383     ps_pic_handling->i4_sum_remaining_frm_in_gop = i4_sum_remaining_frm_in_gop;
384     for(i = 0; i < MAX_PIC_TYPE; i++)
385     {
386         ps_pic_handling->i4_frms_in_cur_gop[i] =
387                         ps_pic_handling->i4_frms_in_gop[i];
388         ps_pic_handling->i4_rem_frms_in_gop[i] =
389                         ps_pic_handling->i4_frms_in_cur_gop[i];
390     }
391 }
392 
393 /*******************************************************************************
394  * @brief Fills the pic_stack with the incoming pics in encode order
395  ******************************************************************************/
irc_add_pic_to_stack(pic_handling_t * ps_pic_handling,WORD32 i4_enc_pic_id)396 void irc_add_pic_to_stack(pic_handling_t *ps_pic_handling, WORD32 i4_enc_pic_id)
397 {
398     /* Declarations */
399     WORD32 i4_inter_frm_int, i4_max_inter_frm_int,
400            i4_intra_frm_int, i4_new_inter_frm_int;
401     WORD32 i4_is_gop_closed;
402     WORD32 i4_buf_pic_no, i4_pic_disp_order_no;
403     WORD32 i4_b_pic_idx, i4_ref_pic_idx;
404     WORD32 i4_is_first_gop, i4_b_in_incomp_subgop, i4_p_count_in_gop,
405            i4_b_count_in_gop, i4_b_count_in_subgop;
406     WORD32 i, i4_p_frms_in_prd, i4_b_frms_in_prd,
407            i4_num_b_in_subgop, i4_extra_p;
408     WORD32 i4_condn_for_change_in_inter_frm_int;
409     picture_type_e e_previous_pic_type, e_cur_pic_type;
410     WORD32 i4_force_I_frame;
411 
412     /*
413      * Initialize the local vars with the state struct values needed by the
414      * change calls
415      */
416     i4_intra_frm_int = ps_pic_handling->i4_intra_frm_int;
417     i4_inter_frm_int = ps_pic_handling->i4_inter_frm_int;
418     i4_max_inter_frm_int = ps_pic_handling->i4_max_inter_frm_int;
419     i4_is_gop_closed = ps_pic_handling->i4_is_gop_closed;
420 
421     i4_buf_pic_no = ps_pic_handling->i4_buf_pic_no;
422     i4_pic_disp_order_no = ps_pic_handling->i4_pic_disp_order_no;
423     i4_b_count_in_gop = ps_pic_handling->i4_b_count_in_gop;
424     i4_b_frms_in_prd = ps_pic_handling->i4_frms_in_cur_gop[B_PIC];
425     i4_is_first_gop = ps_pic_handling->i4_is_first_gop;
426     i4_new_inter_frm_int = ps_pic_handling->i4_new_inter_frm_int;
427     e_previous_pic_type = ps_pic_handling->e_previous_pic_type;
428     i4_force_I_frame = ps_pic_handling->i4_force_I_frame;
429 
430     /*  Force I frame :
431      *  Two different cases
432      *  1)OPEN_GOP: New GOP is started after number of B pictures in the last
433      *              sub gop of a gop to mimic the GOP structure.
434      *  2)Closed GOP:Wait till P frame at input and The frame after a P frame
435      *               a new GOP is started to mimic the GOP structure.
436      */
437     if(i4_force_I_frame)
438     {
439         WORD32 i4_temp_is_gop_closed;
440         WORD32 i4_codn = 0;
441         /* A special case of Open GOP where the it behaves like Closed GOP*/
442         if((i4_intra_frm_int % i4_inter_frm_int) == 1)
443         {
444             i4_temp_is_gop_closed = 1;
445         }
446         else
447         {
448             i4_temp_is_gop_closed = i4_is_gop_closed;
449         }
450         /* Get the current picture type to aid decision to force an I frame*/
451         if((i4_buf_pic_no % i4_inter_frm_int)
452            && !(i4_is_gop_closed&& (i4_b_count_in_gop == i4_b_frms_in_prd)))
453         {
454             e_cur_pic_type = B_PIC;
455         }
456         else
457         {
458             if(i4_pic_disp_order_no == 0)
459             {
460                 e_cur_pic_type = I_PIC;
461             }
462             else
463             {
464                 e_cur_pic_type = P_PIC;
465             }
466         }
467         if((i4_intra_frm_int % i4_inter_frm_int) == 0)
468         {
469             i4_codn = (e_cur_pic_type == P_PIC);
470         }
471         else
472         {
473             i4_codn = (ps_pic_handling->i4_b_count_in_subgop
474                             == ps_pic_handling->i4_b_in_incomp_subgop);
475         }
476         if(e_cur_pic_type == I_PIC)
477         {
478             /*
479              * Don't do anything. Resetting the force I frame flag
480              * since the current picture type is already a I frame
481              */
482             i4_force_I_frame = 0;
483         }
484         else if(i4_inter_frm_int == 1)
485         {
486             /*IPP case , Force I frame immediately*/
487             start_new_gop(ps_pic_handling);
488         }
489         else if((!i4_temp_is_gop_closed) && i4_codn)
490         {
491             start_new_gop(ps_pic_handling);
492             if(ps_pic_handling->i4_b_count_in_subgop)
493             {
494                 ps_pic_handling->i4_b_pic_idx += 1;
495                 ps_pic_handling->i4_b_pic_idx %= (i4_max_inter_frm_int + 1);
496             }
497         }
498         else if(i4_temp_is_gop_closed && (e_previous_pic_type == P_PIC)
499                         && (e_cur_pic_type != P_PIC))
500         {
501             start_new_gop(ps_pic_handling);
502             ps_pic_handling->i4_b_pic_idx++;
503             ps_pic_handling->i4_b_pic_idx %= (i4_max_inter_frm_int + 1);
504         }
505         i4_is_first_gop = ps_pic_handling->i4_is_first_gop;
506     }
507 
508 
509      /***********************CHANGE_INTRA_FRM_INTERVAL**************************
510      *
511      * Call the irc_update_pic_distbn if
512      *      1)Change in intra frm interval flag is set
513      *      2)It's the first B_PIC of a gop
514      */
515     if((ps_pic_handling->i4_change_in_intra_frm_int == 1)
516                     && ((i4_pic_disp_order_no == 1)))
517     {
518         irc_update_pic_distbn(ps_pic_handling,
519                               ps_pic_handling->i4_new_intra_frm_int,
520                               ps_pic_handling->i4_inter_frm_int, 1);
521 
522         ps_pic_handling->i4_change_in_intra_frm_int = 0;
523 
524         if(ps_pic_handling->i4_new_intra_frm_int == 1)
525         {
526             ps_pic_handling->i4_pic_disp_order_no = 0;
527         }
528     }
529     /*********************CHANGE_INTER_FRM_INTERVAL****************************/
530     /* Call irc_update_pic_distbn if
531      *      1)Change in inter frm interval flag is set
532      *      2)It's the first B_PIC after gop/subgop start, and
533      *      3)The new inter-frm-interval won't cross the intra_frm_interval
534      */
535     if((ps_pic_handling->i4_change_in_inter_frm_int == 1)
536        && ((i4_buf_pic_no % i4_inter_frm_int == 1)|| (i4_pic_disp_order_no == 1) || (i4_inter_frm_int == 1)))
537     {
538         /*
539          * Condition which checks if the new inter_frm_int will cross the
540          * intra_frm_int
541          */
542         i4_condn_for_change_in_inter_frm_int = ((i4_pic_disp_order_no
543                         + i4_new_inter_frm_int - 1) < i4_intra_frm_int);
544 
545         if(i4_condn_for_change_in_inter_frm_int)
546         {
547             /*
548              * If there is a change in inter frame interval. We should set the b
549              * frame IDX to the (num ref frame - num ref frame in buf)+ i4_ref_pic_idx
550              * Since our case we have a structure of I B P or I B...B P only
551              * we have three cases
552              * 1) current incoming frame is I. Then we have to leave space for
553              *    current I and next P hence write b idx as to ref idx + 2
554              * 2) Current incoming frame is B. In that case, we have I in buffer.
555              *    Only one P needs space hence write b idx as ref idx +1
556              * 3) Current incoming frame is P. In that case we are at the end of
557              *    gop [sub gop?] and we have to leave space for next gops I and P.
558              *    Thus b idx = ref idx + 2
559              *
560              *  In case of an closed Gop. The last frame has to be forced to be a P.
561              *  Hence we may have problems in that case.
562              *
563              *  Also this has the implicit assumption of only 2 ref frames
564              */
565             WORD32 i4_is_curr_frm_b =  (i4_buf_pic_no % i4_new_inter_frm_int)&&
566                             !(i4_is_gop_closed && (i4_b_count_in_gop == i4_b_frms_in_prd));
567 
568             /*If the inter_frm_int = 1, then the b_pic_idx needs to be modified */
569             if(i4_inter_frm_int == 1)
570             {
571                 ps_pic_handling->i4_b_pic_idx = ((i4_is_curr_frm_b ? 1 : 2)
572                                 + ps_pic_handling->i4_ref_pic_idx)
573                                 % (i4_max_inter_frm_int + 1);
574             }
575 
576             /*
577              * Depending on the gop/subgop boundary, call the change_inter_frm_int
578              *
579              * TO DO: make a single call, change the name of the fxn to
580              * update_state,
581              * where state = frms_in_gop + b_incomp_subgop + extra_p
582              */
583 
584             /* GOP boundary */
585             if(i4_pic_disp_order_no == 1)
586             {
587                 irc_update_pic_distbn(ps_pic_handling,
588                                       ps_pic_handling->i4_intra_frm_int,
589                                       ps_pic_handling->i4_new_inter_frm_int, 1);
590             }
591             /* Subgop boundary */
592             else
593             {
594                 irc_update_pic_distbn(ps_pic_handling,
595                                       ps_pic_handling->i4_intra_frm_int,
596                                       ps_pic_handling->i4_new_inter_frm_int, 0);
597             }
598 
599             ps_pic_handling->i4_change_in_inter_frm_int = 0;
600             ps_pic_handling->i4_new_inter_frm_int =
601                             ps_pic_handling->i4_inter_frm_int;
602         }
603 
604     }
605 
606     /* Initialize the local vars with the state struct values */
607     i4_buf_pic_no = ps_pic_handling->i4_buf_pic_no;
608     i4_pic_disp_order_no = ps_pic_handling->i4_pic_disp_order_no;
609     i4_b_pic_idx = ps_pic_handling->i4_b_pic_idx;
610     i4_ref_pic_idx = ps_pic_handling->i4_ref_pic_idx;
611     i4_b_in_incomp_subgop = ps_pic_handling->i4_b_in_incomp_subgop_mix_gop;
612     i4_p_count_in_gop = ps_pic_handling->i4_p_count_in_gop;
613     i4_b_count_in_gop = ps_pic_handling->i4_b_count_in_gop;
614     i4_b_count_in_subgop = ps_pic_handling->i4_b_count_in_subgop;
615     i4_p_frms_in_prd = ps_pic_handling->i4_frms_in_cur_gop[P_PIC];
616     i4_b_frms_in_prd = ps_pic_handling->i4_frms_in_cur_gop[B_PIC];
617     i4_extra_p = ps_pic_handling->i4_extra_p_mix_gop;
618     i4_inter_frm_int = ps_pic_handling->i4_inter_frm_int;
619     i4_intra_frm_int = ps_pic_handling->i4_intra_frm_int;
620 
621     /* Initializing the prev_state vars */
622     ps_pic_handling->i4_prev_b_pic_idx = ps_pic_handling->i4_b_pic_idx;
623 
624     i4_num_b_in_subgop = (i4_inter_frm_int - 1);
625 
626     /*********************** Fill the stack ***********************************/
627     /* The next part of the code is organized as
628      *
629      * if(B_PIC conditions satisfied)
630      * {
631      *  Fill the pic_stack using the b_pic_index
632      *  Update the b_pic_index and the other b_pic related vars for the
633      *      next B_PIC
634      * }
635      *  else
636      * {
637      *  if(I_PIC conditions are satisfied)
638      * {
639      *  Fill the pic_stack using the ref_pic_index
640      *  Update the ref_pic_index and the other ref_pic related vars for the next
641      *      I_PIC/P_PIC
642      * }
643      *  else
644      * {
645      *  Fill the pic_stack using the ref_pic_index
646      *  Update the ref_pic_index and the other ref_pic related vars for the next
647      *      I_PIC/P_PIC
648      * }
649      * }
650      */
651     /*
652      * Condition for a B_PIC -
653      * 1) Other than the first I_PIC and the periodically appearing P_PICs, after
654      *    every inter_frm_int, rest all pics are B_PICs
655      * 2) In case of CLOSED_GOP, the last frame of the gop has to be a P_PIC
656      */
657 
658     if((i4_buf_pic_no % i4_inter_frm_int)&& !(i4_is_gop_closed
659        && (i4_b_count_in_gop == i4_b_frms_in_prd))) /**** B_PIC ****/
660     {
661         /* Fill the pic_stack */
662         ps_pic_handling->as_pic_stack[i4_b_pic_idx].i4_pic_id = i4_enc_pic_id;
663         ps_pic_handling->as_pic_stack[i4_b_pic_idx].e_pic_type = B_PIC;
664         ps_pic_handling->as_pic_stack[i4_b_pic_idx].i4_pic_disp_order_no =
665                         i4_pic_disp_order_no;
666 
667         /* Store Pic type*/
668         e_previous_pic_type = B_PIC;
669 
670         /* Update the prev_pic_details */
671         memcpy(&ps_pic_handling->s_prev_pic_details,
672                &ps_pic_handling->as_pic_stack[i4_b_pic_idx],
673                sizeof(pic_details_t));
674 
675         i4_b_count_in_gop++;
676         i4_b_count_in_subgop++;
677 
678         /* Update the i4_b_pic_idx */
679         if(!i4_is_gop_closed)
680         {
681             /* If this B_PIC features in one of the complete subgops */
682             if((i4_b_count_in_subgop < i4_num_b_in_subgop)
683                             && !(i4_b_count_in_gop == i4_b_frms_in_prd))
684             {
685                 i4_b_pic_idx++;
686             }
687             else /* Else if this B_PIC is the last one in a subgop or gop  */
688             {
689                 /*
690                  * If this is the last B_PIC of a GOP, depending on the number
691                  * of incomp B_pics in the subgop, there can be either only I
692                  * or I,P pics between this and the next B_PIC
693                  */
694                 if(i4_b_count_in_gop == i4_b_frms_in_prd)
695                 {
696                     i4_b_pic_idx += (2 + (!i4_b_in_incomp_subgop)); /*Prev*/
697                     i4_b_count_in_gop = 0;
698                 }
699                 /*
700                  * For the last B_PIC of a subgop, there's always a P b/w
701                  * this & the next B_PIC
702                  */
703                 else
704                 {
705                     i4_b_pic_idx += 2;
706                 }
707                 i4_b_count_in_subgop = 0;
708             }
709         }
710         else
711         {
712             /* For the last B_PIC of a gop
713              * Normally,there will be 3 pics (P,I,P) between this and the next
714              * B_PIC for a CLOSED gop, except when
715              *  1)Number of P_pics in the gop = 1
716              *  2)There is an extra P at the end of the gop
717              */
718             if(i4_b_count_in_gop == i4_b_frms_in_prd)
719             {
720                 i4_b_pic_idx += (3 + ((i4_b_in_incomp_subgop == 0)
721                                  && (i4_p_frms_in_prd> 1)
722                                  && (i4_pic_disp_order_no
723                                  != (i4_p_frms_in_prd+ i4_b_frms_in_prd- 1))));
724 
725                 i4_b_count_in_subgop = 0;
726             }
727             /* For a B_PIC which is not the last one in a subgop */
728             else if(i4_b_count_in_subgop < i4_num_b_in_subgop)
729             {
730                 i4_b_pic_idx++;
731             }
732             else /* For the last B_PIC of a subgop */
733             {
734                 i4_b_pic_idx += 2;
735                 i4_b_count_in_subgop = 0;
736             }
737         }
738         i4_b_pic_idx %= (i4_max_inter_frm_int + 1);
739     }
740     /*********** I or P pic *********/
741     else
742     {
743         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_id = i4_enc_pic_id;
744         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_disp_order_no =
745                         i4_pic_disp_order_no;
746         /* Store Pic type*/
747         e_previous_pic_type = I_PIC;
748 
749         /**** I_PIC ****/
750         if(i4_pic_disp_order_no == 0)
751         {
752             ps_pic_handling->as_pic_stack[i4_ref_pic_idx].e_pic_type = I_PIC;
753 
754             /* Update the prev_pic_details */
755             memcpy(&ps_pic_handling->s_prev_pic_details,
756                    &ps_pic_handling->as_pic_stack[i4_ref_pic_idx],
757                    sizeof(pic_details_t));
758             /*
759              * In case of an I-frame depending on OPEN or CLOSED gop,
760              * the ref_pic_idx changes
761              */
762             if((!i4_is_gop_closed) && (i4_is_first_gop == 0))
763             {
764                 if((i4_p_frms_in_prd <= 1) && (i4_b_in_incomp_subgop == 0))
765                 {
766                     i4_ref_pic_idx++;
767                 }
768                 /*
769                  * From the 2nd gop onwards, the I and first P frame are
770                  * separated by the num_b_in_incomp_subgop
771                  */
772                 else
773                 {
774                     i4_ref_pic_idx += (i4_b_in_incomp_subgop + 1);
775                 }
776 
777                 ps_pic_handling->i4_b_in_incomp_subgop_mix_gop =
778                                 ps_pic_handling->i4_b_in_incomp_subgop;
779             }
780             else
781             {
782                 i4_ref_pic_idx++;
783             }
784 
785             i4_b_count_in_gop = 0;
786             i4_p_count_in_gop = 0;
787             i4_b_count_in_subgop = 0;
788 
789         }
790         /**** P_PIC ****/
791         else
792         {
793             ps_pic_handling->as_pic_stack[i4_ref_pic_idx].e_pic_type = P_PIC;
794             /* Store Pic type*/
795             e_previous_pic_type = P_PIC;
796 
797             /* Update the prev_pic_details */
798             memcpy(&ps_pic_handling->s_prev_pic_details,
799                    &ps_pic_handling->as_pic_stack[i4_ref_pic_idx],
800                    sizeof(pic_details_t));
801 
802             i4_p_count_in_gop++;
803             ps_pic_handling->i4_prev_intra_frame_interval = i4_intra_frm_int;
804 
805             /*
806              * In case of an P-frame depending on OPEN or CLOSED gop, the
807              * ref_pic_idx changes
808              */
809             if(i4_is_gop_closed && (i4_p_count_in_gop == i4_p_frms_in_prd))
810             {
811                 /*
812                  * For the last P_PIC in a gop, if extra_p or incomp_b are
813                  * present, the number of such pics between this and the next
814                  * ref_pic is (i4_b_in_incomp_subgop + 1)
815                  */
816                 if((i4_p_count_in_gop > 1)
817                                 && (i4_b_in_incomp_subgop || i4_extra_p))
818                 {
819                     i4_ref_pic_idx += (i4_b_in_incomp_subgop + 1);
820                 }
821                 else
822                 {
823                     i4_ref_pic_idx += i4_inter_frm_int;
824                 }
825             }
826             else
827             {
828                 i4_ref_pic_idx += i4_inter_frm_int;
829             }
830         }
831 
832         i4_ref_pic_idx %= (i4_max_inter_frm_int + 1);
833     }
834 
835     /* Update those variables working on the input frames  */
836     i4_pic_disp_order_no++;
837     i4_buf_pic_no++;
838 
839 #if 0
840     /* For any gop */
841      /* BUG FIX
842       *  This piece of code resets the gop upon I frame(?)
843       *  This introduces a problem of GOP getting reset not at I frames as it should be
844       *  The reason AFAIK is that
845       *  1) This code uses i4_pic_disp_order_no to reset GOP. I assume it computes
846       *      if are at GOP boundary and does it, but not sure
847       *  2) The frames rmainign in GOP is done in post enc as it should be.
848       *
849       *  Also ps_pic_handling->i4_pic_disp_order_no is incremented when a pic is added
850       *  to stack becuase the additon is in disp order while poping is in encode order
851       *
852       *  SUppose there is a deay od 1 frame between queue and encode.
853       *  then he timing will be. Assume a GOP of IPPIPP
854       *
855       *      Input buff    Input to qu     Output buf/encode buff      remaining pic in gop
856       *    1  I             I                 NA                          rest to 1 2
857       *    2  P             P                 I                           0 2
858       *    3  P             P                 P                           0 1
859       *    4  I             I                 P                           reset to 1 2
860       *    5  P             P                 I                           1 1
861       *    6  P             P                 P                           1 0
862       *    7  NA            NA                P
863       *
864       *  Hence our gop gets reset at I(1)  and I(4) in the RC.thus the reaming pic in gop
865       *  count will be as shown. We can clearly see that the GOP gets reset at I(4) .Hence
866       *  for the correpondinng QP for output buf p(4) will be that of an I frame.
867       *
868       *  By hiding this I hope to fix this problem. But Iam not sure exaclty.
869       *  This needs to be investigated further
870       *
871       *  By hiding this most likely we are in effect disabling the dynanic
872       *  update of gop params.
873       */
874 
875     if(ps_pic_handling->i4_pic_disp_order_no
876                     == (i4_max_inter_frm_int - 1- ((!i4_is_gop_closed)
877                         * ps_pic_handling->i4_b_in_incomp_subgop_mix_gop)))
878     {
879         for(i = 0; i < MAX_PIC_TYPE; i++)
880         {
881             ps_pic_handling->i4_rem_frms_in_gop[i] =
882                             ps_pic_handling->i4_frms_in_cur_gop[i];
883         }
884 
885         if((!i4_is_gop_closed) && (i4_is_first_gop)
886                         && (ps_pic_handling->i4_rem_frms_in_gop[B_PIC]
887                                         > ps_pic_handling->i4_b_in_incomp_subgop_mix_gop))
888         {
889             ps_pic_handling->i4_rem_frms_in_gop[B_PIC] =
890                             ps_pic_handling->i4_frms_in_cur_gop[B_PIC]
891                                             - ps_pic_handling->i4_b_in_incomp_subgop_mix_gop;
892         }
893     }
894 #endif
895 
896     /* End of GOP updates */
897     if(i4_pic_disp_order_no == (i4_p_frms_in_prd + i4_b_frms_in_prd + 1))
898     {
899         /* Now, the end of gop updates */
900         i4_pic_disp_order_no = 0;
901         i4_buf_pic_no = 0;
902         i4_is_first_gop = 0;
903         ps_pic_handling->i4_extra_p_mix_gop = ps_pic_handling->i4_extra_p;
904 
905         if(i4_is_gop_closed)
906         {
907             ps_pic_handling->i4_b_in_incomp_subgop_mix_gop =
908                             ps_pic_handling->i4_b_in_incomp_subgop;
909         }
910 
911         for(i = 0; i < MAX_PIC_TYPE; i++)
912         {
913             ps_pic_handling->i4_frms_in_cur_gop[i] =
914                             ps_pic_handling->i4_frms_in_gop[i];
915         }
916     }
917 
918     /* Updating the vars which work on the encoded pics */
919     /* For the first gop */
920     if ((ps_pic_handling->i4_is_first_gop)
921                     && (ps_pic_handling->i4_pic_disp_order_no == 0))
922     {
923         ps_pic_handling->i4_coded_pic_no = 0;
924         ps_pic_handling->i4_stack_count = 0;
925     }
926 
927     /* Update the state struct with the modifiable local vars */
928     ps_pic_handling->i4_buf_pic_no = i4_buf_pic_no;
929     ps_pic_handling->i4_pic_disp_order_no = i4_pic_disp_order_no;
930     ps_pic_handling->i4_b_pic_idx = i4_b_pic_idx;
931     ps_pic_handling->i4_ref_pic_idx = i4_ref_pic_idx;
932     ps_pic_handling->i4_is_first_gop = i4_is_first_gop;
933     ps_pic_handling->i4_p_count_in_gop = i4_p_count_in_gop;
934     ps_pic_handling->i4_b_count_in_gop = i4_b_count_in_gop;
935     ps_pic_handling->i4_b_count_in_subgop = i4_b_count_in_subgop;
936     ps_pic_handling->e_previous_pic_type = e_previous_pic_type;
937     ps_pic_handling->i4_force_I_frame = i4_force_I_frame;
938 }
939 
940 /*******************************************************************************
941  * @brief Returns the picture type, ip and display order number for the frame to
942  *        be encoded
943  ******************************************************************************/
irc_get_pic_from_stack(pic_handling_t * ps_pic_handling,WORD32 * pi4_pic_id,WORD32 * pi4_pic_disp_order_no,picture_type_e * pe_pic_type)944 void irc_get_pic_from_stack(pic_handling_t *ps_pic_handling,
945                             WORD32 *pi4_pic_id,
946                             WORD32 *pi4_pic_disp_order_no,
947                             picture_type_e *pe_pic_type)
948 {
949     pic_details_t s_pic_details;
950     pic_details_t *ps_pic_details = &s_pic_details;
951 
952     if(ps_pic_handling->i4_stack_count < 0)
953     {
954         ps_pic_details->e_pic_type = BUF_PIC;
955         ps_pic_details->i4_pic_disp_order_no = -1;
956         ps_pic_details->i4_pic_id = -1;
957     }
958     else
959     {
960         memcpy(ps_pic_details,
961                &ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count],
962                sizeof(pic_details_t));
963 
964         /* Force I frame updations */
965         if((ps_pic_handling->i4_force_I_frame == 1)
966                         && (ps_pic_details->e_pic_type == I_PIC))
967         {
968             /* Flag to signal change in remaining bits*/
969             ps_pic_handling->i4_forced_I_frame_cur_frame = 1;
970             ps_pic_handling->i4_force_I_frame = 0;
971             /*
972              * Indicates count for no. of Pictures whose temporal reference
973              * has to be modified
974              * in the new GOP
975              */
976             ps_pic_handling->i4_mod_temp_ref_cnt =
977                             ps_pic_handling->i4_b_in_incomp_subgop + 1;
978             ps_pic_handling->i4_first_gop_encoded = 1;
979         }
980 
981         /*
982          * In MPEG2, the temporal reference of the first displayed frame in a
983          * gop is 0.In case of an OPEN_GOP, the B_PICs of the last subgop in a
984          * gop, maybe coded as a part of the next gop. Hence, in such conditions
985          * the pic_disp_order needs to be modified so that it gives an
986          * indication of the temporal reference
987          */
988         if((!ps_pic_handling->i4_is_gop_closed)
989                         && (ps_pic_handling->i4_first_gop_encoded))
990         {
991             if(!ps_pic_handling->i4_mod_temp_ref_cnt)
992             {
993                 ps_pic_details->i4_pic_disp_order_no =
994                                 (ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count].i4_pic_disp_order_no
995                                                 + ps_pic_handling->i4_b_in_incomp_subgop)
996                                                 % (ps_pic_handling->i4_prev_intra_frame_interval);
997 
998             }
999             else
1000             {
1001                 /*
1002                  * due to force I frame First frame will have only
1003                  * ps_pic_handling->i4_frames_in_fif_gop number of frames
1004                  */
1005                 ps_pic_details->i4_pic_disp_order_no =
1006                                 (ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count].i4_pic_disp_order_no
1007                                                 + ps_pic_handling->i4_b_in_incomp_subgop)
1008                                                 % (ps_pic_handling->i4_frames_in_fif_gop);
1009                 ps_pic_handling->i4_mod_temp_ref_cnt--;
1010             }
1011         }
1012     }
1013 
1014     /* Giving this to the Codec */
1015     *pi4_pic_id = s_pic_details.i4_pic_id;
1016     *pi4_pic_disp_order_no = s_pic_details.i4_pic_disp_order_no;
1017     *pe_pic_type = s_pic_details.e_pic_type;
1018 }
1019 
1020 /*******************************************************************************
1021  * @brief Updates the picture handling state whenever there is changes in input
1022  *        parameter
1023  *
1024  ******************************************************************************/
irc_update_pic_distbn(pic_handling_t * ps_pic_handling,WORD32 i4_intra_frm_int,WORD32 i4_inter_frm_int,WORD32 i4_gop_boundary)1025 static void irc_update_pic_distbn(pic_handling_t *ps_pic_handling,
1026                                   WORD32 i4_intra_frm_int,
1027                                   WORD32 i4_inter_frm_int,
1028                                   WORD32 i4_gop_boundary)
1029 {
1030     /* Declarations */
1031     WORD32 i4_is_gop_closed;
1032     WORD32 i, i4_prev_inter_frm_int, i4_max_inter_frm_int, i4_pic_disp_order_no;
1033     WORD32 i4_b_in_incomp_subgop, i4_extra_p,
1034            i4_b_in_incomp_subgop_mix_gop,i4_extra_p_mix_gop;
1035     WORD32 i4_pb_frms_till_prev_p;
1036     WORD32 ai4_diff_in_frms[MAX_PIC_TYPE];
1037 
1038     /* Initialize the local vars from the state struct */
1039     i4_is_gop_closed = ps_pic_handling->i4_is_gop_closed;
1040     i4_prev_inter_frm_int = ps_pic_handling->i4_inter_frm_int;
1041     i4_max_inter_frm_int = ps_pic_handling->i4_max_inter_frm_int;
1042     i4_b_in_incomp_subgop = ps_pic_handling->i4_b_in_incomp_subgop;
1043     i4_extra_p = ps_pic_handling->i4_extra_p;
1044     i4_b_in_incomp_subgop_mix_gop =
1045                     ps_pic_handling->i4_b_in_incomp_subgop_mix_gop;
1046     i4_extra_p_mix_gop = ps_pic_handling->i4_extra_p_mix_gop;
1047     i4_pic_disp_order_no = ps_pic_handling->i4_pic_disp_order_no;
1048 
1049     i4_pb_frms_till_prev_p = (ps_pic_handling->i4_p_count_in_gop
1050                               * i4_prev_inter_frm_int);
1051 
1052     /* Check for the validity of the intra_frm_int */
1053     if(i4_intra_frm_int <= 0)
1054     {
1055         i4_intra_frm_int = ps_pic_handling->i4_intra_frm_int;
1056     }
1057     /* Check for the validity of the inter_frm_int */
1058     if((i4_inter_frm_int > i4_max_inter_frm_int) || (i4_inter_frm_int < 0))
1059     {
1060         i4_inter_frm_int = ps_pic_handling->i4_inter_frm_int;
1061     }
1062 
1063     /* Keep a copy of the older frms_in_gop */
1064     for(i = 0; i < MAX_PIC_TYPE; i++)
1065     {
1066         ai4_diff_in_frms[i] = ps_pic_handling->i4_frms_in_cur_gop[i];
1067     }
1068 
1069     /* Update all the variables which are calculated from the inter_frm_int */
1070 
1071     /* Get the new pic distribution in the gop */
1072     find_pic_distbn_in_gop(ps_pic_handling->i4_frms_in_gop, i4_intra_frm_int,
1073                            i4_inter_frm_int, i4_is_gop_closed,
1074                            &i4_b_in_incomp_subgop, &i4_extra_p);
1075 
1076     /* Find the other related variables */
1077     if(i4_gop_boundary == 0)
1078     {
1079         /*
1080          * Since, the inter frame interval has changed between a gop the
1081          * current gop will be a mixed gop. So, we need to find the values of
1082          * the related variables
1083          */
1084         find_pic_distbn_in_gop(ps_pic_handling->i4_frms_in_cur_gop,
1085                                (i4_intra_frm_int - i4_pb_frms_till_prev_p),
1086                                i4_inter_frm_int, i4_is_gop_closed,
1087                                &i4_b_in_incomp_subgop_mix_gop,
1088                                &i4_extra_p_mix_gop);
1089 
1090         ps_pic_handling->i4_frms_in_cur_gop[P_PIC] +=
1091                         ps_pic_handling->i4_p_count_in_gop;
1092         ps_pic_handling->i4_frms_in_cur_gop[B_PIC] +=
1093                         ps_pic_handling->i4_b_count_in_gop;
1094     }
1095     else
1096     {
1097         /*
1098          * Since, the inter_frm_interval has changed at a gop boundary, the
1099          * new gop will have all the subgops with the new inter_frm_interval
1100          */
1101         for(i = 0; i < MAX_PIC_TYPE; i++)
1102         {
1103             ps_pic_handling->i4_frms_in_cur_gop[i] =
1104                             ps_pic_handling->i4_frms_in_gop[i];
1105         }
1106 
1107         i4_b_in_incomp_subgop_mix_gop = i4_b_in_incomp_subgop;
1108         i4_extra_p_mix_gop = i4_extra_p;
1109     }
1110 
1111     /* For bit-allocation the rem_frms_in_gop need to be updated */
1112     /* Checks needed:
1113      1) If the encoding is happening on the same gop as that of the buffering */
1114     if(ps_pic_handling->i4_pic_disp_order_no
1115                     >= (i4_max_inter_frm_int - 1- ((!i4_is_gop_closed)
1116                        * ps_pic_handling->i4_b_in_incomp_subgop_mix_gop)))
1117     {
1118         for(i = 0; i < MAX_PIC_TYPE; i++)
1119         {
1120             ps_pic_handling->i4_rem_frms_in_gop[i] +=
1121                             (ps_pic_handling->i4_frms_in_cur_gop[i]
1122                                             - ai4_diff_in_frms[i]);
1123         }
1124     }
1125 
1126     /* Update the vars which will affect the proper filling of the pic_stack */
1127     if(i4_pic_disp_order_no == 0) /*Check if redundant*/
1128     {
1129         ps_pic_handling->i4_buf_pic_no = 0;
1130     }
1131     else
1132     {
1133         ps_pic_handling->i4_buf_pic_no = 1;
1134     }
1135 
1136     ps_pic_handling->i4_b_count_in_subgop = 0;
1137 
1138     /* Update the state struct with the new inter_frm_int */
1139     ps_pic_handling->i4_inter_frm_int = i4_inter_frm_int;
1140     ps_pic_handling->i4_intra_frm_int = i4_intra_frm_int;
1141     ps_pic_handling->i4_b_in_incomp_subgop = i4_b_in_incomp_subgop;
1142     ps_pic_handling->i4_extra_p = i4_extra_p;
1143     ps_pic_handling->i4_b_in_incomp_subgop_mix_gop =
1144                     i4_b_in_incomp_subgop_mix_gop;
1145     ps_pic_handling->i4_extra_p_mix_gop = i4_extra_p_mix_gop;
1146 
1147 }
1148 
1149 /* *****************************************************************************
1150  * @brief Distributes the frames as I, P and B based on intra/inter frame interval.
1151  *  Along with it it fills the number of frames in sub-gop and extra p frame
1152  *
1153  ******************************************************************************/
find_pic_distbn_in_gop(WORD32 i4_frms_in_gop[MAX_PIC_TYPE],WORD32 i4_intra_frm_int,WORD32 i4_inter_frm_int,WORD32 i4_is_gop_closed,WORD32 * pi4_b_in_incomp_subgop,WORD32 * pi4_extra_p)1154 static void find_pic_distbn_in_gop(WORD32 i4_frms_in_gop[MAX_PIC_TYPE],
1155                                    WORD32 i4_intra_frm_int,
1156                                    WORD32 i4_inter_frm_int,
1157                                    WORD32 i4_is_gop_closed,
1158                                    WORD32 *pi4_b_in_incomp_subgop,
1159                                    WORD32 *pi4_extra_p)
1160 {
1161     /*
1162      * Find the pic distribution in the gop depending on the inter and intra
1163      * frm intervals
1164      */
1165     i4_frms_in_gop[I_PIC] = 1;
1166 
1167     /* All I frames */
1168     if(i4_intra_frm_int == 1)
1169     {
1170         i4_frms_in_gop[P_PIC] = 0;
1171         i4_frms_in_gop[B_PIC] = 0;
1172         *pi4_b_in_incomp_subgop = 0;
1173         *pi4_extra_p = 0;
1174     }
1175     else
1176     {
1177         if(i4_is_gop_closed)
1178         {
1179             i4_frms_in_gop[P_PIC] = ((i4_intra_frm_int - 2) / i4_inter_frm_int)
1180                             + 1;
1181 
1182             if((((i4_intra_frm_int - 2) / i4_inter_frm_int) * i4_inter_frm_int)
1183                             == (i4_intra_frm_int - 2))
1184             {
1185                 *pi4_extra_p = 1;
1186             }
1187             else
1188             {
1189                 *pi4_extra_p = 0;
1190             }
1191         }
1192         else
1193         {
1194             i4_frms_in_gop[P_PIC] = ((i4_intra_frm_int - 1) / i4_inter_frm_int);
1195 
1196             *pi4_extra_p = 0;
1197         }
1198 
1199         i4_frms_in_gop[B_PIC] = (i4_intra_frm_int - 1 - i4_frms_in_gop[P_PIC]);
1200 
1201         *pi4_b_in_incomp_subgop = (i4_frms_in_gop[B_PIC] - (i4_inter_frm_int - 1)
1202                                    * ((i4_intra_frm_int - 1)/ i4_inter_frm_int));
1203     }
1204 }
1205 
irc_pic_type_get_intra_frame_interval(pic_handling_t * ps_pic_handling)1206 WORD32 irc_pic_type_get_intra_frame_interval(pic_handling_t *ps_pic_handling)
1207 {
1208 
1209     return (ps_pic_handling->i4_intra_frm_int);
1210 }
1211 
irc_pic_type_get_inter_frame_interval(pic_handling_t * ps_pic_handling)1212 WORD32 irc_pic_type_get_inter_frame_interval(pic_handling_t *ps_pic_handling)
1213 {
1214     return (ps_pic_handling->i4_inter_frm_int);
1215 }
1216 
irc_pic_type_get_rem_frms_in_gop(pic_handling_t * ps_pic_handling,WORD32 ai4_rem_frms_in_gop[MAX_PIC_TYPE])1217 void irc_pic_type_get_rem_frms_in_gop(pic_handling_t *ps_pic_handling,
1218                                       WORD32 ai4_rem_frms_in_gop[MAX_PIC_TYPE])
1219 {
1220     memcpy(ai4_rem_frms_in_gop, ps_pic_handling->i4_rem_frms_in_gop,
1221            sizeof(ps_pic_handling->i4_rem_frms_in_gop));
1222 }
1223 
irc_pic_type_get_frms_in_gop_force_I_frm(pic_handling_t * ps_pic_handling)1224 WORD32 irc_pic_type_get_frms_in_gop_force_I_frm(pic_handling_t *ps_pic_handling)
1225 {
1226     return (ps_pic_handling->i4_frames_in_fif_gop);
1227 }
1228 
irc_pic_type_get_frms_in_gop(pic_handling_t * ps_pic_handling,WORD32 ai4_frms_in_gop[MAX_PIC_TYPE])1229 void irc_pic_type_get_frms_in_gop(pic_handling_t *ps_pic_handling,
1230                                   WORD32 ai4_frms_in_gop[MAX_PIC_TYPE])
1231 {
1232     memcpy(ai4_frms_in_gop, ps_pic_handling->i4_frms_in_cur_gop,
1233            sizeof(ps_pic_handling->i4_frms_in_cur_gop));
1234 }
1235 
irc_pic_type_get_disp_order_no(pic_handling_t * ps_pic_handling)1236 WORD32 irc_pic_type_get_disp_order_no(pic_handling_t *ps_pic_handling)
1237 {
1238     return (ps_pic_handling->i4_pic_disp_order_no);
1239 }
1240 
irc_set_force_I_frame_flag(pic_handling_t * ps_pic_handling)1241 void irc_set_force_I_frame_flag(pic_handling_t *ps_pic_handling)
1242 {
1243     ps_pic_handling->i4_force_I_frame = 1;
1244 }
irc_get_forced_I_frame_cur_frm_flag(pic_handling_t * ps_pic_handling)1245 WORD32 irc_get_forced_I_frame_cur_frm_flag(pic_handling_t *ps_pic_handling)
1246 {
1247     return (ps_pic_handling->i4_forced_I_frame_cur_frame);
1248 }
irc_reset_forced_I_frame_cur_frm_flag(pic_handling_t * ps_pic_handling)1249 void irc_reset_forced_I_frame_cur_frm_flag(pic_handling_t *ps_pic_handling)
1250 {
1251     ps_pic_handling->i4_forced_I_frame_cur_frame = 0;
1252 }
1253 
1254 /******************************************************************************/
1255 /* Functions that work on the encoded frames */
1256 /******************************************************************************/
1257 
1258 /******************************************************************************
1259  Function Name   : irc_update_pic_handling
1260  Description     : Will be called only for the frames to be encoded
1261  *****************************************************************************/
irc_update_pic_handling(pic_handling_t * ps_pic_handling,picture_type_e e_pic_type)1262 void irc_update_pic_handling(pic_handling_t *ps_pic_handling,
1263                              picture_type_e e_pic_type)
1264 {
1265 
1266     WORD32 i4_max_inter_frm_int;
1267     WORD32 i;
1268 
1269     /* Initializing the local vars with that of the state struct */
1270     i4_max_inter_frm_int = ps_pic_handling->i4_max_inter_frm_int;
1271 
1272     /* Update the variables working on the output frames */
1273     /* Update the stack count */
1274     ps_pic_handling->i4_stack_count++;
1275 
1276     if(ps_pic_handling->i4_stack_count == (i4_max_inter_frm_int + 1))
1277     {
1278         ps_pic_handling->i4_stack_count = 0;
1279     }
1280 
1281     /* Update the rem_frms_in_gop */
1282     ps_pic_handling->i4_rem_frms_in_gop[e_pic_type]--;
1283 
1284     /* Assumption : Rem_frms_in_gop needs to be taken care of, for every change in frms */
1285     ps_pic_handling->i4_last_frm_in_gop = 0;
1286     if((ps_pic_handling->i4_rem_frms_in_gop[I_PIC] <= 0)
1287                     && (ps_pic_handling->i4_rem_frms_in_gop[P_PIC] <= 0)
1288                     && (ps_pic_handling->i4_rem_frms_in_gop[B_PIC] <= 0))
1289     {
1290         /* Copy the cur_frms_in_gop to the rem_frm_in_gop */
1291         for(i = 0; i < MAX_PIC_TYPE; i++)
1292         {
1293             ps_pic_handling->i4_rem_frms_in_gop[i] =
1294                             ps_pic_handling->i4_frms_in_cur_gop[i];
1295         }
1296 
1297         ps_pic_handling->i4_last_frm_in_gop = 1;
1298         ps_pic_handling->i4_first_gop_encoded = 1;
1299     }
1300 }
1301 
irc_is_last_frame_in_gop(pic_handling_handle ps_pic_handling)1302 WORD32 irc_is_last_frame_in_gop(pic_handling_handle ps_pic_handling)
1303 {
1304     return (ps_pic_handling->i4_last_frm_in_gop);
1305 }
1306 
1307 /******************************************************************************
1308  Function Name   : irc_skip_encoded_frame
1309  Description     : Needs to go to the current pic in the pic_stack.
1310                    If it's B_PIC don't do anything
1311                    If it's a reference picture, push all but the last B_PICs
1312                    in the current subgop one place down (i.e. just copy their
1313                    pic_details) and move the last B_PIC in that subgop to the
1314                    next slot of the skipped picture and convert it's pic_type
1315                    to that of the reference picture
1316  *****************************************************************************/
irc_skip_encoded_frame(pic_handling_t * ps_pic_handling,picture_type_e e_pic_type)1317 void irc_skip_encoded_frame(pic_handling_t *ps_pic_handling,
1318                             picture_type_e e_pic_type)
1319 {
1320     pic_details_t s_pic_details;
1321     WORD32 i4_stack_count, i4_next_ref_pic_idx, i4_pic_idx;
1322     WORD32 i4_max_inter_frm_int, i4_last_b_pic_idx, i4_first_b_pic_idx;
1323     WORD32 i4_next_pic_idx;
1324 
1325     /* State variables used to initialize the local vars (Not to be changed) */
1326     i4_stack_count = ps_pic_handling->i4_stack_count;
1327     i4_next_ref_pic_idx = ps_pic_handling->i4_ref_pic_idx;
1328     i4_max_inter_frm_int = ps_pic_handling->i4_max_inter_frm_int;
1329 
1330     i4_next_pic_idx = ((i4_stack_count + 1) % (i4_max_inter_frm_int + 1));
1331 
1332     /*
1333      * Check what is the encoded frm_type
1334      * Changing a B_PIC to a ref_pic is not reqd if
1335      * there are no B_PICs referring from the skipped ref_pic
1336      */
1337     if(((e_pic_type == P_PIC) || (e_pic_type == I_PIC))
1338                     && (i4_next_pic_idx != i4_next_ref_pic_idx))
1339     {
1340         /* Go to the last B_PIC before the next_ref_pic */
1341         if(i4_next_ref_pic_idx == 0)
1342         {
1343             i4_last_b_pic_idx = i4_max_inter_frm_int;
1344         }
1345         else
1346         {
1347             i4_last_b_pic_idx = (i4_next_ref_pic_idx - 1);
1348         }
1349 
1350         /* Keep a copy of the last B_PIC pic_details */
1351         memcpy(&s_pic_details,
1352                &ps_pic_handling->as_pic_stack[i4_last_b_pic_idx],
1353                sizeof(pic_details_t));
1354 
1355         i4_pic_idx = i4_last_b_pic_idx;
1356         i4_first_b_pic_idx = (i4_stack_count + 1) % (i4_max_inter_frm_int + 1);
1357 
1358         /*
1359          * All the B_PICs other than the last one, need to be shifted one place
1360          * in the stack
1361          */
1362         while((i4_pic_idx != i4_stack_count)
1363                         && (i4_first_b_pic_idx != i4_last_b_pic_idx))
1364         {
1365             if(i4_pic_idx == 0)
1366             {
1367                 i4_pic_idx = i4_max_inter_frm_int;
1368             }
1369             else
1370             {
1371                 i4_pic_idx--;
1372             }
1373 
1374             memcpy(&ps_pic_handling->as_pic_stack[(i4_pic_idx + 1)
1375                                    % (i4_max_inter_frm_int + 1)],
1376                    &ps_pic_handling->as_pic_stack[i4_pic_idx],
1377                    sizeof(pic_details_t));
1378 
1379         }
1380 
1381         /*
1382          * Copy the last B_PIC pic_details to the first B_PIC place and change
1383          * it's pic type to the ref_PIC
1384          */
1385         /*e_ref_pic_type*/
1386         ps_pic_handling->as_pic_stack[i4_first_b_pic_idx].e_pic_type = P_PIC;
1387 
1388         ps_pic_handling->as_pic_stack[i4_first_b_pic_idx].i4_pic_disp_order_no =
1389                         s_pic_details.i4_pic_disp_order_no;
1390         ps_pic_handling->as_pic_stack[i4_first_b_pic_idx].i4_pic_id =
1391                         s_pic_details.i4_pic_id;
1392 
1393         /* Change the rem_frms_in_prd so that the update works properly */
1394         if(ps_pic_handling->i4_rem_frms_in_gop[B_PIC] > 0)
1395         {
1396             ps_pic_handling->i4_rem_frms_in_gop[B_PIC]--;
1397             ps_pic_handling->i4_rem_frms_in_gop[P_PIC]++;
1398         }
1399     }
1400 
1401 }
1402 
1403 /******************************************************************************
1404  Function Name   : flush_frame
1405  Description     : Since when a flush frame is called, there will be no valid
1406                    frames after it, the last frame cannot be a B_PIC, as there
1407                    will be no reference frame for it (Input in display order)
1408 
1409                    So,this fxn needs to go to the last added pic in the pic_stack.
1410                    If it's reference pic don't do anything
1411                    If it's a B_PIC, copy it's pic_details and put it in the
1412                    place of the next reference pic, changing the pic_type to
1413                    P_PIC
1414  *****************************************************************************/
irc_flush_frame_from_pic_stack(pic_handling_t * ps_pic_handling)1415 void irc_flush_frame_from_pic_stack(pic_handling_t *ps_pic_handling)
1416 {
1417 
1418     pic_details_t s_prev_pic_details;
1419 
1420     /* Get the last entered pic_details (not to be modified here) */
1421     WORD32 i4_prev_b_pic_idx = ps_pic_handling->i4_prev_b_pic_idx;
1422     WORD32 i4_ref_pic_idx = ps_pic_handling->i4_ref_pic_idx;
1423     WORD32 i4_b_pic_idx = ps_pic_handling->i4_b_pic_idx;
1424 
1425     memcpy(&s_prev_pic_details, &ps_pic_handling->s_prev_pic_details,
1426            sizeof(pic_details_t));
1427 
1428     if(s_prev_pic_details.e_pic_type == B_PIC)
1429     {
1430         /* Copy the last B_PIC details to the next reference pic in display order */
1431         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_disp_order_no =
1432                         s_prev_pic_details.i4_pic_disp_order_no;
1433         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_id =
1434                         s_prev_pic_details.i4_pic_id;
1435         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].e_pic_type = P_PIC;
1436 
1437         /*
1438          * Modify the last B_PIC pic_type, so that codec gets to know when
1439          * all the buffered frames
1440          * are flushed
1441          */
1442         ps_pic_handling->as_pic_stack[i4_prev_b_pic_idx].e_pic_type =
1443                         MAX_PIC_TYPE;
1444         ps_pic_handling->as_pic_stack[i4_prev_b_pic_idx].i4_pic_id = -1;
1445         ps_pic_handling->as_pic_stack[i4_prev_b_pic_idx].i4_pic_disp_order_no =
1446                         -1;
1447     }
1448     else
1449     {
1450         /*
1451          * Modify the next pic_type details in the stack, so that codec gets to
1452          * know when all the
1453          * buffered frames are flushed
1454          */
1455         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].e_pic_type = MAX_PIC_TYPE;
1456         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_id = -1;
1457         ps_pic_handling->as_pic_stack[i4_ref_pic_idx].i4_pic_disp_order_no = -1;
1458 
1459         if(ps_pic_handling->i4_inter_frm_int != 1)
1460         {
1461             ps_pic_handling->as_pic_stack[i4_b_pic_idx].e_pic_type =
1462                             MAX_PIC_TYPE;
1463             ps_pic_handling->as_pic_stack[i4_b_pic_idx].i4_pic_id = -1;
1464             ps_pic_handling->as_pic_stack[i4_b_pic_idx].i4_pic_disp_order_no =
1465                             -1;
1466         }
1467     }
1468 }
1469 
1470 /******************************************************************************
1471  Function Name   : irc_add_pic_to_stack_re_enc
1472  Description     : In case of a re-enc, we can assume the pictures to be coming
1473                    in the encode order.
1474                    In case of re-encoder basically, there are 2 problematic cases.
1475                    1)Inter_frm_int is not known to start with
1476                    2)Inter_frm_int can keep changing
1477                    3)Intra_frm_int set by the application and that actually in the
1478                     decoded bitstream may be different
1479  *****************************************************************************/
irc_add_pic_to_stack_re_enc(pic_handling_t * ps_pic_handling,WORD32 i4_enc_pic_id,picture_type_e e_pic_type)1480 WORD32 irc_add_pic_to_stack_re_enc(pic_handling_t *ps_pic_handling,
1481                                    WORD32 i4_enc_pic_id,
1482                                    picture_type_e e_pic_type)
1483 {
1484     WORD32 i4_b_count_in_subgop;
1485     WORD32 i4_max_inter_frm_int, i4_inter_frm_int, i4_intra_frm_int;
1486     WORD32 i4_pic_disp_order_no;
1487     WORD32 i4_is_gop_closed;
1488     picture_type_e e_out_pic_type;
1489     WORD32 i4_b_in_incomp_subgop;
1490 
1491     /* Check if a change in intra_frm_int call has been made */
1492     if(ps_pic_handling->i4_change_in_intra_frm_int == 1)
1493     {
1494         irc_update_pic_distbn(ps_pic_handling,
1495                               ps_pic_handling->i4_new_intra_frm_int,
1496                               ps_pic_handling->i4_inter_frm_int, 1);
1497         ps_pic_handling->i4_change_in_intra_frm_int = 0;
1498     }
1499 
1500     /* Check if a change in inter_frm_int call has been made */
1501     if(ps_pic_handling->i4_change_in_inter_frm_int == 1)
1502     {
1503         irc_update_pic_distbn(ps_pic_handling,
1504                               ps_pic_handling->i4_intra_frm_int,
1505                               ps_pic_handling->i4_new_inter_frm_int, 1);
1506 
1507         ps_pic_handling->i4_change_in_inter_frm_int = 0;
1508     }
1509 
1510     /* Initialize the local vars with the state vars */
1511     i4_b_count_in_subgop = ps_pic_handling->i4_b_count_in_subgop;
1512     i4_max_inter_frm_int = ps_pic_handling->i4_max_inter_frm_int;
1513     i4_inter_frm_int = ps_pic_handling->i4_inter_frm_int;
1514     i4_intra_frm_int = ps_pic_handling->i4_intra_frm_int;
1515     i4_pic_disp_order_no = ps_pic_handling->i4_pic_disp_order_no;
1516     i4_is_gop_closed = ps_pic_handling->i4_is_gop_closed;
1517     i4_b_in_incomp_subgop = ps_pic_handling->i4_b_in_incomp_subgop;
1518 
1519     e_out_pic_type = e_pic_type;
1520 
1521     /* Initially the rate_control assumes an IPP sequence */
1522     if(e_pic_type == B_PIC)
1523     {
1524         /* Update the number of B_PICs in a subgop */
1525         i4_b_count_in_subgop++;
1526 
1527         if(i4_b_count_in_subgop > i4_max_inter_frm_int)
1528         {
1529             return (-1);
1530         }
1531 
1532         /* If the number of B_PICs exceed the set inter_frm_int then
1533          change the inter_frm_int */
1534         if(i4_b_count_in_subgop > (i4_inter_frm_int - 1))
1535         {
1536             i4_inter_frm_int = (i4_b_count_in_subgop + 1);
1537 
1538             irc_update_pic_distbn(ps_pic_handling, i4_intra_frm_int,
1539                                   i4_inter_frm_int, 0);
1540         }
1541     }
1542     else if((e_pic_type == I_PIC) || (e_pic_type == P_PIC))
1543     {
1544         /* If the B_PICs in the prev subgop were fewer than the current
1545          * (inter_frm_int-1) and none of these conditions occur, it'll mean the
1546          *  decrease in the inter_frm_int
1547          *    1)End of a GOP
1548          *    2)Beginning of an OPEN_GOP
1549          */
1550         if((i4_b_count_in_subgop < (i4_inter_frm_int - 1))
1551                         && !((!i4_is_gop_closed)
1552                                         && (i4_b_count_in_subgop
1553                                                         >= i4_b_in_incomp_subgop))
1554                         && !((i4_pic_disp_order_no
1555                                         + (i4_inter_frm_int - 1
1556                                                         - i4_b_count_in_subgop))
1557                                         > i4_intra_frm_int))
1558         {
1559             i4_inter_frm_int = (i4_b_count_in_subgop + 1);
1560 
1561             irc_update_pic_distbn(ps_pic_handling, i4_intra_frm_int,
1562                                   i4_inter_frm_int, 0);
1563         }
1564 
1565         /* Reset the number of B_PICs in a subgop */
1566         i4_b_count_in_subgop = 0;
1567     }
1568 
1569     /* Updation of the frame level vars */
1570     i4_pic_disp_order_no++;
1571 
1572     /* End of gop condition
1573      *Two cases can arise :
1574      *1) The intra_frm_int set by the application is greater than the actual
1575      *   bitstream intra_frm_int (i.e. we will get an I frame before
1576      *   pic_disp_order_no goes to intra_frm_int)
1577      *2) The intra_frm_int set by the application is smaller than the actual bitstream intra_frm_int
1578      *   (i.e. we won't get an I_PIC even if pic_disp_order_no goes to
1579      *   intra_frm_int) Constraints :
1580      *    1) I_PIC cannot be changed to B_PIC
1581      *    2) B_PIC cannot be changed to I_PIC
1582      */
1583     if(i4_pic_disp_order_no >= i4_intra_frm_int)
1584     {
1585         if(e_pic_type != B_PIC)
1586         {
1587             e_out_pic_type = I_PIC;
1588         }
1589         else
1590         {
1591             e_out_pic_type = B_PIC;
1592             ps_pic_handling->i4_rem_frms_in_gop[B_PIC]++;
1593             ps_pic_handling->i4_frms_in_cur_gop[B_PIC]++;
1594             ps_pic_handling->i4_frms_in_gop[B_PIC]++;
1595         }
1596     }
1597     else
1598     {
1599         if((e_pic_type == I_PIC) && (!ps_pic_handling->i4_is_first_gop))
1600         {
1601             e_out_pic_type = P_PIC;
1602             ps_pic_handling->i4_rem_frms_in_gop[P_PIC]++;
1603             ps_pic_handling->i4_frms_in_cur_gop[P_PIC]++;
1604             ps_pic_handling->i4_frms_in_gop[P_PIC]++;
1605         }
1606         else
1607         {
1608             e_out_pic_type = e_pic_type;
1609         }
1610     }
1611 
1612     /* Update the frm_vars at the end of the gop */
1613     if(i4_pic_disp_order_no
1614                     == (ps_pic_handling->i4_frms_in_cur_gop[P_PIC]
1615                                     + ps_pic_handling->i4_frms_in_cur_gop[B_PIC]
1616                                     + 1))
1617     {
1618         i4_pic_disp_order_no = 0;
1619         ps_pic_handling->i4_is_first_gop = 0;
1620     }
1621 
1622     /* Update the vars working on the encoded pics */
1623     if((ps_pic_handling->i4_is_first_gop)
1624                     && (ps_pic_handling->i4_stack_count == -1))
1625     {
1626         ps_pic_handling->i4_coded_pic_no = 0;
1627         ps_pic_handling->i4_stack_count = 0;
1628     }
1629 
1630     /* Add the pic_details to the pic_stack */
1631     ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count].e_pic_type =
1632                     e_out_pic_type;
1633     ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count].i4_pic_disp_order_no =
1634                     ps_pic_handling->i4_pic_disp_order_no;
1635     ps_pic_handling->as_pic_stack[ps_pic_handling->i4_stack_count].i4_pic_id =
1636                     i4_enc_pic_id;
1637 
1638     /* Writing back those values which need to be updated */
1639     ps_pic_handling->i4_inter_frm_int = i4_inter_frm_int;
1640     ps_pic_handling->i4_pic_disp_order_no = i4_pic_disp_order_no;
1641     ps_pic_handling->i4_b_count_in_subgop = i4_b_count_in_subgop;
1642 
1643     return (0);
1644 }
1645