1 /*
2 libfame - Fast Assembly MPEG Encoder Library
3 Copyright (C) 2002 Yannick Vignon
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h> /* strlen() */
23 #include <math.h>
24 #include "fame.h"
25 #include "fame_rate_simple.h"
26 #include "fame_monitor.h"
27
28 #define power(x,y) (exp(y*log(x)))
29 #define quant_model(coeff, rate, act) (coeff*act/rate)
30 #define coeff_model(quant, rate, act) (quant*rate/act)
31
32 static void rate_init(fame_rate_t *rate,
33 int mb_width,
34 int mb_height,
35 int bitrate,
36 char *coding,
37 fame_frame_statistics_t *stats_list,
38 fame_global_statistics_t *global_stats,
39 unsigned int flags);
40 static void rate_enter(fame_rate_t *rate,
41 fame_yuv_t **ref,
42 fame_yuv_t *current,
43 unsigned char *shape,
44 char coding,
45 fame_frame_statistics_t *frame_stats);
46 static void rate_leave(fame_rate_t *rate,
47 int spent);
48
FAME_CONSTRUCTOR(fame_rate_simple_t)49 FAME_CONSTRUCTOR(fame_rate_simple_t)
50 {
51 fame_rate_t_constructor(FAME_RATE(this));
52 FAME_OBJECT(this)->name = "simple rate estimation";
53
54 this->FAME_OVERLOADED(init) = FAME_RATE(this)->init;
55 FAME_RATE(this)->init = rate_init;
56 this->FAME_OVERLOADED(enter) = FAME_RATE(this)->enter;
57 FAME_RATE(this)->enter = rate_enter;
58 this->FAME_OVERLOADED(leave) = FAME_RATE(this)->leave;
59 FAME_RATE(this)->leave = rate_leave;
60
61 FAME_RATE(this)->flags = 0xffffffff;
62 return(this);
63 }
64
65 /* rate_init */
66 /* */
67 /* Description: */
68 /* Initialise rate estimation. */
69 /* */
70 /* Arguments: */
71 /* fame_rate_t *rate: the rate estimation */
72 /* int mb_width: width in macroblocks */
73 /* int mb_height: height in macroblocks */
74 /* */
75 /* Return value: */
76 /* Rate. */
77
rate_init(fame_rate_t * rate,int mb_width,int mb_height,int bitrate,char * coding,fame_frame_statistics_t * stats_list,fame_global_statistics_t * global_stats,unsigned int flags)78 static void rate_init(fame_rate_t *rate,
79 int mb_width,
80 int mb_height,
81 int bitrate,
82 char *coding,
83 fame_frame_statistics_t *stats_list,
84 fame_global_statistics_t *global_stats,
85 unsigned int flags)
86 {
87 int ni, np;
88 int ratio;
89 int i;
90
91 #ifdef HAS_MMX
92 asm("emms");
93 #endif
94
95 FAME_RATE_SIMPLE(rate)->FAME_OVERLOADED(init)(rate,
96 mb_width,
97 mb_height,
98 bitrate,
99 coding,
100 stats_list,
101 global_stats,
102 flags);
103
104 ni = np = 0;
105 for(i = 0; i < strlen(coding); i++) {
106 switch(coding[i]) {
107 case 'I': ni++; break;
108 case 'P': np++; break;
109 case 'A': np++; break;
110 }
111 }
112
113 ratio = 1;
114 FAME_RATE_SIMPLE(rate)->P_bits = bitrate * (np + ni) / (np + ratio * ni);
115 FAME_RATE_SIMPLE(rate)->I_bits = ratio * FAME_RATE_SIMPLE(rate)->P_bits;
116
117 rate->coeff1 = 1/6.0;
118 FAME_RATE_SIMPLE(rate)->I_coeff1 = 1;
119 }
120
121
122 /* rate_enter */
123 /* */
124 /* Description: */
125 /* Prepare for a new frame. */
126 /* */
127 /* Arguments: */
128 /* fame_rate_t *rate: the rate estimation */
129 /* fame_yuv_t **ref: the reference frames (half-pel) */
130 /* fame_yuv_t *current: the current frame */
131 /* unsigned char *shape: the current shape */
132 /* */
133 /* Return value: */
134 /* Rate. */
135
rate_enter(struct _fame_rate_t_ * rate,fame_yuv_t ** ref,fame_yuv_t * current,unsigned char * shape,char coding,fame_frame_statistics_t * frame_stats)136 static void rate_enter(struct _fame_rate_t_ *rate,
137 fame_yuv_t **ref,
138 fame_yuv_t *current,
139 unsigned char *shape,
140 char coding,
141 fame_frame_statistics_t *frame_stats)
142 {
143 int old_scale;
144
145 #ifdef HAS_MMX
146 asm("emms");
147 #endif
148
149
150 /* Update number of available bits */
151 switch(coding) {
152 case 'I': rate->available += FAME_RATE_SIMPLE(rate)->I_bits; break;
153 case 'P': rate->available += FAME_RATE_SIMPLE(rate)->P_bits; break;
154 };
155
156
157 /* Common tasks */
158 FAME_RATE_SIMPLE(rate)->FAME_OVERLOADED(enter)(rate,
159 ref,
160 current,
161 shape,
162 coding,
163 frame_stats);
164
165
166 /* compute frame activity */
167 if (frame_stats)
168 FAME_RATE_SIMPLE(rate)->activity = frame_stats->spatial_activity;
169 else FAME_RATE_SIMPLE(rate)->activity = activity2(rate->ref[0],
170 rate->current,
171 rate->shape,
172 rate->mb_width,
173 rate->mb_height);
174
175
176 /* Compute quantization scale */
177 old_scale = rate->global_scale;
178 if (rate->available > 0) {
179 switch (coding) {
180 case 'I':
181 rate->global_scale = quant_model(FAME_RATE_SIMPLE(rate)->I_coeff1,
182 rate->available,
183 FAME_RATE_SIMPLE(rate)->activity);
184 break;
185 case 'P':
186 rate->global_scale = quant_model(rate->coeff1,
187 rate->available,
188 FAME_RATE_SIMPLE(rate)->activity);
189 break;
190 }
191 }
192 else
193 rate->global_scale = 31;
194
195
196 if( rate->global_scale < 2) rate->global_scale = 2;
197 if( rate->global_scale > 31) rate->global_scale = 31;
198 rate->global_scale = (rate->global_scale + old_scale)/2;
199 }
200
201 /* rate_leave */
202 /* */
203 /* Description: */
204 /* Finish estimating a frame. */
205 /* */
206 /* Arguments: */
207 /* fame_rate_t *rate: the rate estimation */
208 /* */
209 /* Return value: */
210 /* Rate. */
211
rate_leave(fame_rate_t * rate,int spent)212 static void rate_leave(fame_rate_t *rate, int spent)
213 {
214 #ifdef HAS_MMX
215 asm("emms");
216 #endif
217
218 FAME_RATE_SIMPLE(rate)->FAME_OVERLOADED(leave)(rate,
219 spent);
220
221 switch(rate->coding) {
222 case 'I' :
223 FAME_RATE_SIMPLE(rate)->I_coeff1 =
224 coeff_model(rate->global_scale,
225 spent,
226 FAME_RATE_SIMPLE(rate)->activity);
227 break;
228 case 'P':
229 rate->coeff1 =
230 coeff_model(rate->global_scale,
231 spent,
232 FAME_RATE_SIMPLE(rate)->activity);
233 break;
234 }
235 }
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251