1 
2 /*!
3  ***************************************************************************
4  * \file ratectl.c
5  *
6  * \brief
7  *    Rate Control algorithm
8  *
9  * \author
10  *    Main contributors (see contributors.h for copyright, address and affiliation details)
11  *     - Siwei Ma <swma@jdl.ac.cn>
12  *     - Zhengguo LI<ezgli@lit.a-star.edu.sg>
13  *
14  * \date
15  *   16 Jan. 2003
16  **************************************************************************
17  */
18 
19 #include <math.h>
20 #include <limits.h>
21 
22 #include "global.h"
23 #include "ratectl.h"
24 
25 
26 /*!
27  *************************************************************************************
28  * \brief
29  *    Update Rate Control Parameters
30  *************************************************************************************
31  */
rc_store_mad(Macroblock * currMB)32 void rc_store_mad(Macroblock *currMB)
33 {
34   VideoParameters *p_Vid = currMB->p_Vid;
35   InputParameters *p_Inp = currMB->p_Inp;
36   RCGeneric *p_gen = p_Vid->p_rc_gen;
37 
38   p_gen->MADofMB[currMB->mbAddrX] = ComputeMBMAD(currMB->p_Slice->diffy);
39 
40   if(p_Inp->basicunit < p_Vid->FrameSizeInMbs)
41   {
42     p_gen->TotalMADBasicUnit += p_gen->MADofMB[currMB->mbAddrX];
43   }
44 }
45 
46 /*!
47  *************************************************************************************
48  * \brief
49  *    map QP to Qstep
50  *
51  *************************************************************************************
52 */
QP2Qstep(int QP)53 double QP2Qstep( int QP )
54 {
55   int i;
56   double Qstep;
57   static const double QP2QSTEP[6] = { 0.625, 0.6875, 0.8125, 0.875, 1.0, 1.125 };
58 
59   Qstep = QP2QSTEP[QP % 6];
60   for( i=0; i<(QP/6); i++)
61     Qstep *= 2;
62 
63   return Qstep;
64 }
65 
66 
67 /*!
68  *************************************************************************************
69  * \brief
70  *    map Qstep to QP
71  *
72  *************************************************************************************
73 */
Qstep2QP(double Qstep,int qp_offset)74 int Qstep2QP( double Qstep, int qp_offset )
75 {
76   int q_per = 0, q_rem = 0;
77 
78   if( Qstep < QP2Qstep(MIN_QP))
79     return MIN_QP;
80   else if (Qstep > QP2Qstep(MAX_QP + qp_offset) )
81     return (MAX_QP + qp_offset);
82 
83   while( Qstep > QP2Qstep(5) )
84   {
85     Qstep /= 2.0;
86     q_per++;
87   }
88 
89   if (Qstep <= 0.65625)
90   {
91     //Qstep = 0.625;
92     q_rem = 0;
93   }
94   else if (Qstep <= 0.75)
95   {
96     //Qstep = 0.6875;
97     q_rem = 1;
98   }
99   else if (Qstep <= 0.84375)
100   {
101     //Qstep = 0.8125;
102     q_rem = 2;
103   }
104   else if (Qstep <= 0.9375)
105   {
106     //Qstep = 0.875;
107     q_rem = 3;
108   }
109   else if (Qstep <= 1.0625)
110   {
111     //Qstep = 1.0;
112     q_rem = 4;
113   }
114   else
115   {
116     //Qstep = 1.125;
117     q_rem = 5;
118   }
119 
120   return (q_per * 6 + q_rem);
121 }
122 
123 /*!
124  ************************************************************************************
125  * \brief
126  *    calculate MAD for the current macroblock
127  *
128  * \return
129  *    calculated MAD
130  *
131  *************************************************************************************
132 */
ComputeMBMAD(int diffy[16][16])133 int ComputeMBMAD(int diffy[16][16])
134 {
135   int k, l, sum = 0;
136 
137   for (k = 0; k < 16; k++)
138     for (l = 0; l < 16; l++)
139       sum += iabs(diffy[k][l]);
140 
141   return sum;
142 }
143 
144 /*!
145  *************************************************************************************
146  * \brief
147  *    Compute Frame MAD
148  *
149  *************************************************************************************
150 */
ComputeFrameMAD(VideoParameters * p_Vid)151 double ComputeFrameMAD(VideoParameters *p_Vid)
152 {
153   int64 TotalMAD = 0;
154   unsigned int i;
155   for(i = 0; i < p_Vid->FrameSizeInMbs; i++)
156     TotalMAD += p_Vid->p_rc_gen->MADofMB[i];
157   return (double)TotalMAD / (256.0 * (double)p_Vid->FrameSizeInMbs);
158 }
159 
160 
161 /*!
162  *************************************************************************************
163  * \brief
164  *    Copy JVT rate control objects
165  *
166  *************************************************************************************
167 */
rc_copy_generic(VideoParameters * p_Vid,RCGeneric * dst,RCGeneric * src)168 void rc_copy_generic( VideoParameters *p_Vid, RCGeneric *dst, RCGeneric *src )
169 {
170   /* buffer original addresses for which memory has been allocated */
171   int *tmpMADofMB = dst->MADofMB;
172 
173   /* copy object */
174 
175   // This could be written as: *dst = *src;
176   memcpy( (void *)dst, (void *)src, sizeof(RCGeneric) );
177 
178   /* restore original addresses */
179   dst->MADofMB = tmpMADofMB;
180 
181   /* copy MADs */
182   memcpy( (void *)dst->MADofMB, (void *)src->MADofMB, p_Vid->FrameSizeInMbs * sizeof (int) );
183 }
184 
185 /*!
186  *************************************************************************************
187  * \brief
188  *    Dynamically allocate memory needed for generic rate control
189  *
190  *************************************************************************************
191  */
rc_alloc_generic(VideoParameters * p_Vid,RCGeneric ** p_quad)192 void rc_alloc_generic( VideoParameters *p_Vid, RCGeneric **p_quad )
193 {
194   *p_quad = (RCGeneric *) malloc ( sizeof( RCGeneric ) );
195   if (NULL == *p_quad)
196   {
197     no_mem_exit("rc_alloc_generic: rc_alloc_generic");
198   }
199   (*p_quad)->MADofMB = (int *) calloc (p_Vid->FrameSizeInMbs, sizeof (int));
200   if (NULL == (*p_quad)->MADofMB)
201   {
202     no_mem_exit("rc_alloc_generic: (*p_quad)->MADofMB");
203   }
204   (*p_quad)->FieldFrame = 1;
205 }
206 
207 
208 /*!
209  *************************************************************************************
210  * \brief
211  *    Free memory needed for generic rate control
212  *
213  *************************************************************************************
214  */
rc_free_generic(RCGeneric ** p_quad)215 void rc_free_generic(RCGeneric **p_quad)
216 {
217   if (NULL!=(*p_quad)->MADofMB)
218   {
219     free ((*p_quad)->MADofMB);
220     (*p_quad)->MADofMB = NULL;
221   }
222   if (NULL!=(*p_quad))
223   {
224     free ((*p_quad));
225     (*p_quad) = NULL;
226   }
227 }
228 
229 /*!
230  *************************************************************************************
231  * \brief
232  *    Initialize GOP Level Rate Control parameters
233  *
234  *************************************************************************************
235  */
rc_init_gop_params(VideoParameters * p_Vid,InputParameters * p_Inp)236 void rc_init_gop_params(VideoParameters *p_Vid, InputParameters *p_Inp)
237 {
238   int np, nb;
239   RCQuadratic *p_quad = p_Vid->p_rc_quad;
240   RCGeneric *p_gen = p_Vid->p_rc_gen;
241 
242   switch( p_Inp->RCUpdateMode )
243   {
244   case RC_MODE_1:
245   case RC_MODE_3:
246     if ( !(p_Vid->curr_frm_idx) )
247     {
248       /* number of P frames */
249       np = (int) (p_Inp->no_frames + p_Inp->NumberBFrames) / (1 + p_Inp->NumberBFrames) - 1 + 1; // approximate but good enough (hack...)
250       /* number of B frames */
251       nb = np * p_Inp->NumberBFrames;
252 
253       rc_init_GOP(p_Vid, p_Inp, p_quad, p_gen, np, nb);
254     }
255     break;
256   case RC_MODE_0:
257   case RC_MODE_2:
258     if (p_Inp->idr_period == 0)
259     {
260       if ( !(p_Vid->curr_frm_idx) )
261       {
262         /* number of P frames */
263         np = (int) (p_Inp->no_frames + p_Inp->NumberBFrames) / (1 + p_Inp->NumberBFrames) - 1 + 1; // approximate but good enough (hack...)
264         /* number of B frames */
265         nb = np * p_Inp->NumberBFrames;
266         rc_init_GOP(p_Vid, p_Inp, p_quad, p_gen, np, nb);
267       }
268     }
269     else if ( p_Vid->p_curr_frm_struct->idr_flag )
270     {
271       int M = p_Inp->NumberBFrames + 1;
272       int n = p_Inp->idr_period;
273 
274       /* last GOP may contain less frames */
275       if ((p_Vid->curr_frm_idx / p_Inp->idr_period) >= (p_Inp->no_frames / p_Inp->idr_period))
276       {
277         n = p_Inp->no_frames - p_Vid->curr_frm_idx;
278       }
279 
280       /* number of P frames */
281       np = (p_Vid->curr_frm_idx == 0) ? 1 + ((n - 2) / M) : (n - 1) / M;
282       /* number of B frames */
283       nb = n - np - 1;
284       rc_init_GOP(p_Vid, p_Inp, p_quad, p_gen, np, nb);
285     }
286     break;
287   default:
288     break;
289   }
290 }
291 
292 /*!
293  *************************************************************************************
294  * \brief
295  *    Initialize Frame Level Rate Control parameters
296  *
297  *************************************************************************************
298  */
299 
rc_init_frame(VideoParameters * p_Vid,InputParameters * p_Inp)300 void rc_init_frame(VideoParameters *p_Vid, InputParameters *p_Inp)
301 {
302   switch( p_Inp->RCUpdateMode )
303   {
304   case RC_MODE_0:  case RC_MODE_1:  case RC_MODE_2:  case RC_MODE_3:
305 
306   // update the number of MBs in the basic unit for MBAFF coding
307   if( (p_Inp->MbInterlace) && (p_Inp->basicunit < p_Vid->FrameSizeInMbs) && (p_Vid->type == P_SLICE || (p_Inp->RCUpdateMode == RC_MODE_1 && p_Vid->number) ) )
308     p_Vid->BasicUnit = p_Inp->basicunit << 1;
309   else
310     p_Vid->BasicUnit = p_Inp->basicunit;
311 
312     if ( p_Inp->RDPictureDecision )
313     {
314       rc_copy_quadratic( p_Vid, p_Inp, p_Vid->p_rc_quad_init, p_Vid->p_rc_quad ); // store rate allocation quadratic...
315       rc_copy_generic( p_Vid, p_Vid->p_rc_gen_init, p_Vid->p_rc_gen ); // ...and generic model
316     }
317     p_Vid->rc_init_pict_ptr(p_Vid, p_Inp, p_Vid->p_rc_quad, p_Vid->p_rc_gen, 1,0,1, 1.0F);
318 
319     if( p_Vid->active_sps->frame_mbs_only_flag)
320       p_Vid->p_rc_gen->TopFieldFlag=0;
321 
322     p_Vid->p_curr_frm_struct->qp = p_Vid->qp = p_Vid->updateQP(p_Vid, p_Inp, p_Vid->p_rc_quad, p_Vid->p_rc_gen, 0) - p_Vid->p_rc_quad->bitdepth_qp_scale;
323     break;
324   default:
325     break;
326   }
327 }
328 
329 /*!
330  *************************************************************************************
331  * \brief
332  *    Initialize Sequence Level Rate Control parameters
333  *
334  *************************************************************************************
335  */
336 
rc_init_sequence(VideoParameters * p_Vid,InputParameters * p_Inp)337 void rc_init_sequence(VideoParameters *p_Vid, InputParameters *p_Inp)
338 {
339   switch( p_Inp->RCUpdateMode )
340   {
341   case RC_MODE_0:  case RC_MODE_1:  case RC_MODE_2:  case RC_MODE_3:
342     rc_init_seq(p_Vid, p_Inp, p_Vid->p_rc_quad, p_Vid->p_rc_gen);
343     break;
344   default:
345     break;
346   }
347 }
348 
rc_store_slice_header_bits(VideoParameters * p_Vid,InputParameters * p_Inp,int len)349 void rc_store_slice_header_bits( VideoParameters *p_Vid, InputParameters *p_Inp, int len )
350 {
351   switch (p_Inp->RCUpdateMode)
352   {
353   case RC_MODE_0:  case RC_MODE_1:  case RC_MODE_2:  case RC_MODE_3:
354     p_Vid->p_rc_gen->NumberofHeaderBits +=len;
355 
356     // basic unit layer rate control
357     if(p_Vid->BasicUnit < p_Vid->FrameSizeInMbs)
358       p_Vid->p_rc_gen->NumberofBasicUnitHeaderBits +=len;
359     break;
360   default:
361     break;
362   }
363 }
364 
365 
366 /*!
367 *************************************************************************************
368 * \brief
369 *    Update Rate Control Difference
370 *************************************************************************************
371 */
rc_store_diff(int diffy[16][16],imgpel ** p_curImg,int cpix_x,imgpel ** prediction)372 void rc_store_diff(int diffy[16][16], imgpel **p_curImg, int cpix_x,imgpel **prediction)
373 {
374   int i, j;
375   int *iDst;
376   imgpel *Src1, *Src2;
377 
378   for(j = 0; j < MB_BLOCK_SIZE; j++)
379   {
380     iDst = diffy[j];
381     Src1 = &p_curImg[j][cpix_x];
382     Src2 = prediction[j];
383     for (i = 0; i < MB_BLOCK_SIZE; i++)
384     {
385       iDst[i] = Src1[i] - Src2[i];
386     }
387   }
388 }
389 
rc_store_diff_16b(int diffy[16][16],imgpel ** p_curImg,int cpix_x,imgpel ** prediction)390 void rc_store_diff_16b(int diffy[16][16], imgpel **p_curImg, int cpix_x,imgpel **prediction)
391 {
392   int i, j;
393   int *iDst;
394   uint16 *Src1, *Src2;
395 
396   for(j = 0; j < MB_BLOCK_SIZE; j++)
397   {
398     iDst = diffy[j];
399     Src1 = (uint16*)(p_curImg[j]) +cpix_x;
400     Src2 = (uint16*)(prediction[j]);
401     for (i = 0; i < MB_BLOCK_SIZE; i++)
402     {
403       iDst[i] = Src1[i] - Src2[i];
404     }
405   }
406 }
407