Line | Count | Source (jump to first uncovered line) |
1 | | /******************************************************************** |
2 | | * * |
3 | | * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * |
4 | | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
5 | | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
6 | | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
7 | | * * |
8 | | * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * |
9 | | * by the Xiph.Org Foundation http://www.xiph.org/ * |
10 | | * * |
11 | | ******************************************************************** |
12 | | |
13 | | function: |
14 | | last mod: $Id$ |
15 | | |
16 | | ********************************************************************/ |
17 | | #include <stdlib.h> |
18 | | #include <string.h> |
19 | | #include "encint.h" |
20 | | |
21 | | /*A rough lookup table for tan(x), 0<=x<pi/2. |
22 | | The values are Q12 fixed-point and spaced at 5 degree intervals. |
23 | | These decisions are somewhat arbitrary, but sufficient for the 2nd order |
24 | | Bessel follower below. |
25 | | Values of x larger than 85 degrees are extrapolated from the last inteval, |
26 | | which is way off, but "good enough".*/ |
27 | | static unsigned short OC_ROUGH_TAN_LOOKUP[18]={ |
28 | | 0, 358, 722, 1098, 1491, 1910, |
29 | | 2365, 2868, 3437, 4096, 4881, 5850, |
30 | | 7094, 8784,11254,15286,23230,46817 |
31 | | }; |
32 | | |
33 | | /*_alpha is Q24 in the range [0,0.5). |
34 | | The return values is 5.12.*/ |
35 | 33.8k | static int oc_warp_alpha(int _alpha){ |
36 | 33.8k | int i; |
37 | 33.8k | int d; |
38 | 33.8k | int t0; |
39 | 33.8k | int t1; |
40 | 33.8k | i=_alpha*36>>24; |
41 | 33.8k | if(i>=17)i=16; |
42 | 33.8k | t0=OC_ROUGH_TAN_LOOKUP[i]; |
43 | 33.8k | t1=OC_ROUGH_TAN_LOOKUP[i+1]; |
44 | 33.8k | d=_alpha*36-(i<<24); |
45 | 33.8k | return (int)(((ogg_int64_t)t0<<32)+(t1-t0<<8)*(ogg_int64_t)d>>32); |
46 | 33.8k | } |
47 | | |
48 | | /*Re-initialize the Bessel filter coefficients with the specified delay. |
49 | | This does not alter the x/y state, but changes the reaction time of the |
50 | | filter. |
51 | | Altering the time constant of a reactive filter without alterning internal |
52 | | state is something that has to be done carefuly, but our design operates at |
53 | | high enough delays and with small enough time constant changes to make it |
54 | | safe.*/ |
55 | 11.2k | static void oc_iir_filter_reinit(oc_iir_filter *_f,int _delay){ |
56 | 11.2k | int alpha; |
57 | 11.2k | ogg_int64_t one48; |
58 | 11.2k | ogg_int64_t warp; |
59 | 11.2k | ogg_int64_t k1; |
60 | 11.2k | ogg_int64_t k2; |
61 | 11.2k | ogg_int64_t d; |
62 | 11.2k | ogg_int64_t a; |
63 | 11.2k | ogg_int64_t ik2; |
64 | 11.2k | ogg_int64_t b1; |
65 | 11.2k | ogg_int64_t b2; |
66 | | /*This borrows some code from an unreleased version of Postfish. |
67 | | See the recipe at http://unicorn.us.com/alex/2polefilters.html for details |
68 | | on deriving the filter coefficients.*/ |
69 | | /*alpha is Q24*/ |
70 | 11.2k | alpha=(1<<24)/_delay; |
71 | 11.2k | one48=(ogg_int64_t)1<<48; |
72 | | /*warp is 7.12*/ |
73 | 11.2k | warp=OC_MAXI(oc_warp_alpha(alpha),1); |
74 | | /*k1 is 9.12*/ |
75 | 11.2k | k1=3*warp; |
76 | | /*k2 is 16.24.*/ |
77 | 11.2k | k2=k1*warp; |
78 | | /*d is 16.15.*/ |
79 | 11.2k | d=((1<<12)+k1<<12)+k2+256>>9; |
80 | | /*a is 0.32, since d is larger than both 1.0 and k2.*/ |
81 | 11.2k | a=(k2<<23)/d; |
82 | | /*ik2 is 25.24.*/ |
83 | 11.2k | ik2=one48/k2; |
84 | | /*b1 is Q56; in practice, the integer ranges between -2 and 2.*/ |
85 | 11.2k | b1=2*a*(ik2-(1<<24)); |
86 | | /*b2 is Q56; in practice, the integer ranges between -2 and 2.*/ |
87 | 11.2k | b2=(one48<<8)-(4*a<<24)-b1; |
88 | | /*All of the filter parameters are Q24.*/ |
89 | 11.2k | _f->c[0]=(ogg_int32_t)(b1+((ogg_int64_t)1<<31)>>32); |
90 | 11.2k | _f->c[1]=(ogg_int32_t)(b2+((ogg_int64_t)1<<31)>>32); |
91 | 11.2k | _f->g=(ogg_int32_t)(a+128>>8); |
92 | 11.2k | } |
93 | | |
94 | | /*Initialize a 2nd order low-pass Bessel filter with the corresponding delay |
95 | | and initial value. |
96 | | _value is Q24.*/ |
97 | 8.32k | static void oc_iir_filter_init(oc_iir_filter *_f,int _delay,ogg_int32_t _value){ |
98 | 8.32k | oc_iir_filter_reinit(_f,_delay); |
99 | 8.32k | _f->y[1]=_f->y[0]=_f->x[1]=_f->x[0]=_value; |
100 | 8.32k | } |
101 | | |
102 | 49.8k | static ogg_int64_t oc_iir_filter_update(oc_iir_filter *_f,ogg_int32_t _x){ |
103 | 49.8k | ogg_int64_t c0; |
104 | 49.8k | ogg_int64_t c1; |
105 | 49.8k | ogg_int64_t g; |
106 | 49.8k | ogg_int64_t x0; |
107 | 49.8k | ogg_int64_t x1; |
108 | 49.8k | ogg_int64_t y0; |
109 | 49.8k | ogg_int64_t y1; |
110 | 49.8k | ogg_int64_t ya; |
111 | 49.8k | c0=_f->c[0]; |
112 | 49.8k | c1=_f->c[1]; |
113 | 49.8k | g=_f->g; |
114 | 49.8k | x0=_f->x[0]; |
115 | 49.8k | x1=_f->x[1]; |
116 | 49.8k | y0=_f->y[0]; |
117 | 49.8k | y1=_f->y[1]; |
118 | 49.8k | ya=(_x+x0*2+x1)*g+y0*c0+y1*c1+(1<<23)>>24; |
119 | 49.8k | _f->x[1]=(ogg_int32_t)x0; |
120 | 49.8k | _f->x[0]=_x; |
121 | 49.8k | _f->y[1]=(ogg_int32_t)y0; |
122 | 49.8k | _f->y[0]=(ogg_int32_t)ya; |
123 | 49.8k | return ya; |
124 | 49.8k | } |
125 | | |
126 | | |
127 | | |
128 | | /*Search for the quantizer that matches the target most closely. |
129 | | We don't assume a linear ordering, but when there are ties we pick the |
130 | | quantizer closest to the old one.*/ |
131 | | static int oc_enc_find_qi_for_target(oc_enc_ctx *_enc,int _qti,int _qi_old, |
132 | 119k | int _qi_min,ogg_int64_t _log_qtarget){ |
133 | 119k | ogg_int64_t best_qdiff; |
134 | 119k | int best_qi; |
135 | 119k | int qi; |
136 | 119k | best_qi=_qi_min; |
137 | 119k | best_qdiff=_enc->log_qavg[_qti][best_qi]-_log_qtarget; |
138 | 119k | best_qdiff=best_qdiff+OC_SIGNMASK(best_qdiff)^OC_SIGNMASK(best_qdiff); |
139 | 7.63M | for(qi=_qi_min+1;qi<64;qi++){ |
140 | 7.51M | ogg_int64_t qdiff; |
141 | 7.51M | qdiff=_enc->log_qavg[_qti][qi]-_log_qtarget; |
142 | 7.51M | qdiff=qdiff+OC_SIGNMASK(qdiff)^OC_SIGNMASK(qdiff); |
143 | 7.51M | if(qdiff<best_qdiff|| |
144 | 7.51M | qdiff==best_qdiff&&abs(qi-_qi_old)<abs(best_qi-_qi_old)){ |
145 | 5.68M | best_qi=qi; |
146 | 5.68M | best_qdiff=qdiff; |
147 | 5.68M | } |
148 | 7.51M | } |
149 | 119k | return best_qi; |
150 | 119k | } |
151 | | |
152 | 62.0k | void oc_enc_calc_lambda(oc_enc_ctx *_enc,int _qti){ |
153 | 62.0k | ogg_int64_t lq; |
154 | 62.0k | int qi; |
155 | 62.0k | int qi1; |
156 | 62.0k | int nqis; |
157 | | /*For now, lambda is fixed depending on the qi value and frame type: |
158 | | lambda=qscale*(qavg[qti][qi]**2), |
159 | | where qscale=0.2125. |
160 | | This was derived by exhaustively searching for the optimal quantizer for |
161 | | the AC coefficients in each block from a number of test sequences for a |
162 | | number of fixed lambda values and fitting the peaks of the resulting |
163 | | histograms (on the log(qavg) scale). |
164 | | The same model applies to both inter and intra frames. |
165 | | A more adaptive scheme might perform better.*/ |
166 | 62.0k | qi=_enc->state.qis[0]; |
167 | | /*If rate control is active, use the lambda for the _target_ quantizer. |
168 | | This allows us to scale to rates slightly lower than we'd normally be able |
169 | | to reach, and give the rate control a semblance of "fractional qi" |
170 | | precision. |
171 | | TODO: Add API for changing QI, and allow extra precision.*/ |
172 | 62.0k | if(_enc->state.info.target_bitrate>0)lq=_enc->rc.log_qtarget; |
173 | 12.3k | else lq=_enc->log_qavg[_qti][qi]; |
174 | | /*The resulting lambda value is less than 0x500000.*/ |
175 | 62.0k | _enc->lambda=(int)oc_bexp64(2*lq-0x4780BD468D6B62BLL); |
176 | | /*Select additional quantizers. |
177 | | The R-D optimal block AC quantizer statistics suggest that the distribution |
178 | | is roughly Gaussian-like with a slight positive skew. |
179 | | K-means clustering on log_qavg to select 3 quantizers produces cluster |
180 | | centers of {log_qavg-0.6,log_qavg,log_qavg+0.7}. |
181 | | Experiments confirm these are relatively good choices. |
182 | | |
183 | | Although we do greedy R-D optimization of the qii flags to avoid switching |
184 | | too frequently, this becomes ineffective at low rates, either because we |
185 | | do a poor job of predicting the actual R-D cost, or the greedy |
186 | | optimization is not sufficient. |
187 | | Therefore adaptive quantization is disabled above an (experimentally |
188 | | suggested) threshold of log_qavg=7.00 (e.g., below INTRA qi=12 or |
189 | | INTER qi=20 with current matrices). |
190 | | This may need to be revised if the R-D cost estimation or qii flag |
191 | | optimization strategies change.*/ |
192 | 62.0k | nqis=1; |
193 | 62.0k | if(lq<(OC_Q57(56)>>3)&&!_enc->vp3_compatible&& |
194 | 62.0k | _enc->sp_level<OC_SP_LEVEL_FAST_ANALYSIS){ |
195 | 34.7k | qi1=oc_enc_find_qi_for_target(_enc,_qti,OC_MAXI(qi-1,0),0, |
196 | 34.7k | lq+(OC_Q57(7)+5)/10); |
197 | 34.7k | if(qi1!=qi)_enc->state.qis[nqis++]=qi1; |
198 | 34.7k | qi1=oc_enc_find_qi_for_target(_enc,_qti,OC_MINI(qi+1,63),0, |
199 | 34.7k | lq-(OC_Q57(6)+5)/10); |
200 | 34.7k | if(qi1!=qi&&qi1!=_enc->state.qis[nqis-1])_enc->state.qis[nqis++]=qi1; |
201 | 34.7k | } |
202 | 62.0k | _enc->state.nqis=nqis; |
203 | 62.0k | } |
204 | | |
205 | | /*Binary exponential of _log_scale with 24-bit fractional precision and |
206 | | saturation. |
207 | | _log_scale: A binary logarithm in Q24 format. |
208 | | Return: The binary exponential in Q24 format, saturated to 2**47-1 if |
209 | | _log_scale was too large.*/ |
210 | 0 | static ogg_int64_t oc_bexp_q24(ogg_int32_t _log_scale){ |
211 | 0 | if(_log_scale<(ogg_int32_t)23<<24){ |
212 | 0 | ogg_int64_t ret; |
213 | 0 | ret=oc_bexp64(((ogg_int64_t)_log_scale<<33)+OC_Q57(24)); |
214 | 0 | return ret<0x7FFFFFFFFFFFLL?ret:0x7FFFFFFFFFFFLL; |
215 | 0 | } |
216 | 0 | return 0x7FFFFFFFFFFFLL; |
217 | 0 | } |
218 | | |
219 | | /*Convenience function converts Q57 value to a clamped 32-bit Q24 value |
220 | | _in: input in Q57 format. |
221 | | Return: same number in Q24 */ |
222 | 36.0k | static ogg_int32_t oc_q57_to_q24(ogg_int64_t _in){ |
223 | 36.0k | ogg_int64_t ret; |
224 | 36.0k | ret=_in+((ogg_int64_t)1<<32)>>33; |
225 | | /*0x80000000 is automatically converted to unsigned on 32-bit systems. |
226 | | -0x7FFFFFFF-1 is needed to avoid "promoting" the whole expression to |
227 | | unsigned.*/ |
228 | 36.0k | return (ogg_int32_t)OC_CLAMPI(-0x7FFFFFFF-1,ret,0x7FFFFFFF); |
229 | 36.0k | } |
230 | | |
231 | | /*Binary exponential of _log_scale with 24-bit fractional precision and |
232 | | saturation. |
233 | | _log_scale: A binary logarithm in Q57 format. |
234 | | Return: The binary exponential in Q24 format, saturated to 2**31-1 if |
235 | | _log_scale was too large.*/ |
236 | 2.77k | static ogg_int32_t oc_bexp64_q24(ogg_int64_t _log_scale){ |
237 | 2.77k | if(_log_scale<OC_Q57(8)){ |
238 | 2.77k | ogg_int64_t ret; |
239 | 2.77k | ret=oc_bexp64(_log_scale+OC_Q57(24)); |
240 | 2.77k | return ret<0x7FFFFFFF?(ogg_int32_t)ret:0x7FFFFFFF; |
241 | 2.77k | } |
242 | 0 | return 0x7FFFFFFF; |
243 | 2.77k | } |
244 | | |
245 | | |
246 | 2.77k | static void oc_enc_rc_reset(oc_enc_ctx *_enc){ |
247 | 2.77k | ogg_int64_t npixels; |
248 | 2.77k | ogg_int64_t ibpp; |
249 | 2.77k | int inter_delay; |
250 | | /*TODO: These parameters should be exposed in a th_encode_ctl() API.*/ |
251 | 2.77k | _enc->rc.bits_per_frame=(_enc->state.info.target_bitrate* |
252 | 2.77k | (ogg_int64_t)_enc->state.info.fps_denominator)/ |
253 | 2.77k | _enc->state.info.fps_numerator; |
254 | | /*Insane framerates or frame sizes mean insane bitrates. |
255 | | Let's not get carried away.*/ |
256 | 2.77k | if(_enc->rc.bits_per_frame>0x400000000000LL){ |
257 | 135 | _enc->rc.bits_per_frame=(ogg_int64_t)0x400000000000LL; |
258 | 135 | } |
259 | 2.64k | else if(_enc->rc.bits_per_frame<32)_enc->rc.bits_per_frame=32; |
260 | 2.77k | _enc->rc.buf_delay=OC_MAXI(_enc->rc.buf_delay,12); |
261 | 2.77k | _enc->rc.max=_enc->rc.bits_per_frame*_enc->rc.buf_delay; |
262 | | /*Start with a buffer fullness of 50% plus 25% of the amount we plan to spend |
263 | | on a single keyframe interval. |
264 | | We can require fully half the bits in an interval for a keyframe, so this |
265 | | initial level gives us maximum flexibility for over/under-shooting in |
266 | | subsequent frames.*/ |
267 | 2.77k | _enc->rc.target=(_enc->rc.max+1>>1)+(_enc->rc.bits_per_frame+2>>2)* |
268 | 2.77k | OC_MINI(_enc->keyframe_frequency_force,_enc->rc.buf_delay); |
269 | 2.77k | _enc->rc.fullness=_enc->rc.target; |
270 | | /*Pick exponents and initial scales for quantizer selection.*/ |
271 | 2.77k | npixels=_enc->state.info.frame_width* |
272 | 2.77k | (ogg_int64_t)_enc->state.info.frame_height; |
273 | 2.77k | _enc->rc.log_npixels=oc_blog64(npixels); |
274 | 2.77k | ibpp=npixels/_enc->rc.bits_per_frame; |
275 | 2.77k | if(ibpp<1){ |
276 | 1.38k | _enc->rc.exp[0]=59; |
277 | 1.38k | _enc->rc.log_scale[0]=oc_blog64(1997)-OC_Q57(8); |
278 | 1.38k | } |
279 | 1.38k | else if(ibpp<2){ |
280 | 87 | _enc->rc.exp[0]=55; |
281 | 87 | _enc->rc.log_scale[0]=oc_blog64(1604)-OC_Q57(8); |
282 | 87 | } |
283 | 1.30k | else{ |
284 | 1.30k | _enc->rc.exp[0]=48; |
285 | 1.30k | _enc->rc.log_scale[0]=oc_blog64(834)-OC_Q57(8); |
286 | 1.30k | } |
287 | 2.77k | if(ibpp<4){ |
288 | 1.54k | _enc->rc.exp[1]=100; |
289 | 1.54k | _enc->rc.log_scale[1]=oc_blog64(2249)-OC_Q57(8); |
290 | 1.54k | } |
291 | 1.23k | else if(ibpp<8){ |
292 | 75 | _enc->rc.exp[1]=95; |
293 | 75 | _enc->rc.log_scale[1]=oc_blog64(1751)-OC_Q57(8); |
294 | 75 | } |
295 | 1.15k | else{ |
296 | 1.15k | _enc->rc.exp[1]=73; |
297 | 1.15k | _enc->rc.log_scale[1]=oc_blog64(1260)-OC_Q57(8); |
298 | 1.15k | } |
299 | 2.77k | _enc->rc.prev_drop_count=0; |
300 | 2.77k | _enc->rc.log_drop_scale=OC_Q57(0); |
301 | | /*Set up second order followers, initialized according to corresponding |
302 | | time constants.*/ |
303 | 2.77k | oc_iir_filter_init(&_enc->rc.scalefilter[0],4, |
304 | 2.77k | oc_q57_to_q24(_enc->rc.log_scale[0])); |
305 | 2.77k | inter_delay=(_enc->rc.twopass? |
306 | 2.77k | OC_MAXI(_enc->keyframe_frequency_force,12):_enc->rc.buf_delay)>>1; |
307 | 2.77k | _enc->rc.inter_count=0; |
308 | | /*We clamp the actual inter_delay to a minimum of 10 to work within the range |
309 | | of values where later incrementing the delay works as designed. |
310 | | 10 is not an exact choice, but rather a good working trade-off.*/ |
311 | 2.77k | _enc->rc.inter_delay=10; |
312 | 2.77k | _enc->rc.inter_delay_target=inter_delay; |
313 | 2.77k | oc_iir_filter_init(&_enc->rc.scalefilter[1],_enc->rc.inter_delay, |
314 | 2.77k | oc_q57_to_q24(_enc->rc.log_scale[1])); |
315 | 2.77k | oc_iir_filter_init(&_enc->rc.vfrfilter,4, |
316 | 2.77k | oc_bexp64_q24(_enc->rc.log_drop_scale)); |
317 | 2.77k | } |
318 | | |
319 | 3.44k | void oc_rc_state_init(oc_rc_state *_rc,oc_enc_ctx *_enc){ |
320 | 3.44k | _rc->twopass=0; |
321 | 3.44k | _rc->twopass_buffer_bytes=0; |
322 | 3.44k | _rc->twopass_force_kf=0; |
323 | 3.44k | _rc->frame_metrics=NULL; |
324 | 3.44k | _rc->rate_bias=0; |
325 | 3.44k | if(_enc->state.info.target_bitrate>0){ |
326 | | /*The buffer size is set equal to the keyframe interval, clamped to the |
327 | | range [12,256] frames. |
328 | | The 12 frame minimum gives us some chance to distribute bit estimation |
329 | | errors. |
330 | | The 256 frame maximum means we'll require 8-10 seconds of pre-buffering |
331 | | at 24-30 fps, which is not unreasonable.*/ |
332 | 2.77k | _rc->buf_delay=_enc->keyframe_frequency_force>256? |
333 | 2.77k | 256:_enc->keyframe_frequency_force; |
334 | | /*By default, enforce all buffer constraints.*/ |
335 | 2.77k | _rc->drop_frames=1; |
336 | 2.77k | _rc->cap_overflow=1; |
337 | 2.77k | _rc->cap_underflow=0; |
338 | 2.77k | oc_enc_rc_reset(_enc); |
339 | 2.77k | } |
340 | 3.44k | } |
341 | | |
342 | 3.44k | void oc_rc_state_clear(oc_rc_state *_rc){ |
343 | 3.44k | _ogg_free(_rc->frame_metrics); |
344 | 3.44k | } |
345 | | |
346 | 0 | void oc_enc_rc_resize(oc_enc_ctx *_enc){ |
347 | | /*If encoding has not yet begun, reset the buffer state.*/ |
348 | 0 | if(_enc->state.curframe_num<0)oc_enc_rc_reset(_enc); |
349 | 0 | else{ |
350 | 0 | int idt; |
351 | | /*Otherwise, update the bounds on the buffer, but not the current |
352 | | fullness.*/ |
353 | 0 | _enc->rc.bits_per_frame=(_enc->state.info.target_bitrate* |
354 | 0 | (ogg_int64_t)_enc->state.info.fps_denominator)/ |
355 | 0 | _enc->state.info.fps_numerator; |
356 | | /*Insane framerates or frame sizes mean insane bitrates. |
357 | | Let's not get carried away.*/ |
358 | 0 | if(_enc->rc.bits_per_frame>0x400000000000LL){ |
359 | 0 | _enc->rc.bits_per_frame=(ogg_int64_t)0x400000000000LL; |
360 | 0 | } |
361 | 0 | else if(_enc->rc.bits_per_frame<32)_enc->rc.bits_per_frame=32; |
362 | 0 | _enc->rc.buf_delay=OC_MAXI(_enc->rc.buf_delay,12); |
363 | 0 | _enc->rc.max=_enc->rc.bits_per_frame*_enc->rc.buf_delay; |
364 | 0 | _enc->rc.target=(_enc->rc.max+1>>1)+(_enc->rc.bits_per_frame+2>>2)* |
365 | 0 | OC_MINI(_enc->keyframe_frequency_force,_enc->rc.buf_delay); |
366 | | /*Update the INTER-frame scale filter delay. |
367 | | We jump to it immediately if we've already seen enough frames; otherwise |
368 | | it is simply set as the new target.*/ |
369 | 0 | _enc->rc.inter_delay_target=idt=OC_MAXI(_enc->rc.buf_delay>>1,10); |
370 | 0 | if(idt<OC_MINI(_enc->rc.inter_delay,_enc->rc.inter_count)){ |
371 | 0 | oc_iir_filter_init(&_enc->rc.scalefilter[1],idt, |
372 | 0 | _enc->rc.scalefilter[1].y[0]); |
373 | 0 | _enc->rc.inter_delay=idt; |
374 | 0 | } |
375 | 0 | } |
376 | | /*If we're in pass-2 mode, make sure the frame metrics array is big enough |
377 | | to hold frame statistics for the full buffer.*/ |
378 | 0 | if(_enc->rc.twopass==2){ |
379 | 0 | int cfm; |
380 | 0 | int buf_delay; |
381 | 0 | int reset_window; |
382 | 0 | buf_delay=_enc->rc.buf_delay; |
383 | 0 | reset_window=_enc->rc.frame_metrics==NULL&&(_enc->rc.frames_total[0]==0|| |
384 | 0 | buf_delay<_enc->rc.frames_total[0]+_enc->rc.frames_total[1] |
385 | 0 | +_enc->rc.frames_total[2]); |
386 | 0 | cfm=_enc->rc.cframe_metrics; |
387 | | /*Only try to resize the frame metrics buffer if a) it's too small and |
388 | | b) we were using a finite buffer, or are about to start.*/ |
389 | 0 | if(cfm<buf_delay&&(_enc->rc.frame_metrics!=NULL||reset_window)){ |
390 | 0 | oc_frame_metrics *fm; |
391 | 0 | int nfm; |
392 | 0 | int fmh; |
393 | 0 | fm=(oc_frame_metrics *)_ogg_realloc(_enc->rc.frame_metrics, |
394 | 0 | buf_delay*sizeof(*_enc->rc.frame_metrics)); |
395 | 0 | if(fm==NULL){ |
396 | | /*We failed to allocate a finite buffer.*/ |
397 | | /*If we don't have a valid 2-pass header yet, just return; we'll reset |
398 | | the buffer size when we read the header.*/ |
399 | 0 | if(_enc->rc.frames_total[0]==0)return; |
400 | | /*Otherwise revert to the largest finite buffer previously set, or to |
401 | | whole-file buffering if we were still using that.*/ |
402 | 0 | _enc->rc.buf_delay=_enc->rc.frame_metrics!=NULL? |
403 | 0 | cfm:_enc->rc.frames_total[0]+_enc->rc.frames_total[1] |
404 | 0 | +_enc->rc.frames_total[2]; |
405 | 0 | oc_enc_rc_resize(_enc); |
406 | 0 | return; |
407 | 0 | } |
408 | 0 | _enc->rc.frame_metrics=fm; |
409 | 0 | _enc->rc.cframe_metrics=buf_delay; |
410 | | /*Re-organize the circular buffer.*/ |
411 | 0 | fmh=_enc->rc.frame_metrics_head; |
412 | 0 | nfm=_enc->rc.nframe_metrics; |
413 | 0 | if(fmh+nfm>cfm){ |
414 | 0 | int shift; |
415 | 0 | shift=OC_MINI(fmh+nfm-cfm,buf_delay-cfm); |
416 | 0 | memcpy(fm+cfm,fm,OC_MINI(fmh+nfm-cfm,buf_delay-cfm)*sizeof(*fm)); |
417 | 0 | if(fmh+nfm>buf_delay)memmove(fm,fm+shift,fmh+nfm-buf_delay); |
418 | 0 | } |
419 | 0 | } |
420 | | /*We were using whole-file buffering; now we're not.*/ |
421 | 0 | if(reset_window){ |
422 | 0 | _enc->rc.nframes[0]=_enc->rc.nframes[1]=_enc->rc.nframes[2]=0; |
423 | 0 | _enc->rc.scale_sum[0]=_enc->rc.scale_sum[1]=0; |
424 | 0 | _enc->rc.scale_window_end=_enc->rc.scale_window0= |
425 | 0 | _enc->state.curframe_num+_enc->prev_dup_count+1; |
426 | 0 | if(_enc->rc.twopass_buffer_bytes){ |
427 | 0 | int qti; |
428 | | /*We already read the metrics for the first frame in the window.*/ |
429 | 0 | *(_enc->rc.frame_metrics)=*&_enc->rc.cur_metrics; |
430 | 0 | _enc->rc.nframe_metrics++; |
431 | 0 | qti=_enc->rc.cur_metrics.frame_type; |
432 | 0 | _enc->rc.nframes[qti]++; |
433 | 0 | _enc->rc.nframes[2]+=_enc->rc.cur_metrics.dup_count; |
434 | 0 | _enc->rc.scale_sum[qti]+=oc_bexp_q24(_enc->rc.cur_metrics.log_scale); |
435 | 0 | _enc->rc.scale_window_end+=_enc->rc.cur_metrics.dup_count+1; |
436 | 0 | if(_enc->rc.scale_window_end-_enc->rc.scale_window0<buf_delay){ |
437 | | /*We need more frame data.*/ |
438 | 0 | _enc->rc.twopass_buffer_bytes=0; |
439 | 0 | } |
440 | 0 | } |
441 | 0 | } |
442 | | /*Otherwise, we could shrink the size of the current window, if necessary, |
443 | | but leaving it like it is lets us adapt to the new buffer size more |
444 | | gracefully.*/ |
445 | 0 | } |
446 | 0 | } |
447 | | |
448 | | /*Scale the number of frames by the number of expected drops/duplicates.*/ |
449 | 49.7k | static int oc_rc_scale_drop(oc_rc_state *_rc,int _nframes){ |
450 | 49.7k | if(_rc->prev_drop_count>0||_rc->log_drop_scale>OC_Q57(0)){ |
451 | 14.4k | ogg_int64_t dup_scale; |
452 | 14.4k | dup_scale=oc_bexp64((_rc->log_drop_scale |
453 | 14.4k | +oc_blog64(_rc->prev_drop_count+1)>>1)+OC_Q57(8)); |
454 | 14.4k | if(dup_scale<_nframes<<8){ |
455 | 14.3k | int dup_scalei; |
456 | 14.3k | dup_scalei=(int)dup_scale; |
457 | 14.3k | if(dup_scalei>0)_nframes=((_nframes<<8)+dup_scalei-1)/dup_scalei; |
458 | 14.3k | } |
459 | 127 | else _nframes=!!_nframes; |
460 | 14.4k | } |
461 | 49.7k | return _nframes; |
462 | 49.7k | } |
463 | | |
464 | 49.7k | int oc_enc_select_qi(oc_enc_ctx *_enc,int _qti,int _clamp){ |
465 | 49.7k | ogg_int64_t rate_total; |
466 | 49.7k | ogg_int64_t rate_bias; |
467 | 49.7k | int nframes[2]; |
468 | 49.7k | int buf_delay; |
469 | 49.7k | int buf_pad; |
470 | 49.7k | ogg_int64_t log_qtarget; |
471 | 49.7k | ogg_int64_t log_scale0; |
472 | 49.7k | ogg_int64_t log_cur_scale; |
473 | 49.7k | ogg_int64_t log_qexp; |
474 | 49.7k | int exp0; |
475 | 49.7k | int old_qi; |
476 | 49.7k | int qi; |
477 | | /*Figure out how to re-distribute bits so that we hit our fullness target |
478 | | before the last keyframe in our current buffer window (after the current |
479 | | frame), or the end of the buffer window, whichever comes first.*/ |
480 | 49.7k | log_cur_scale=(ogg_int64_t)_enc->rc.scalefilter[_qti].y[0]<<33; |
481 | 49.7k | buf_pad=0; |
482 | 49.7k | switch(_enc->rc.twopass){ |
483 | 49.7k | default:{ |
484 | 49.7k | ogg_uint32_t next_key_frame; |
485 | | /*Single pass mode: assume only forced keyframes and attempt to estimate |
486 | | the drop count for VFR content.*/ |
487 | 49.7k | next_key_frame=_qti?_enc->keyframe_frequency_force |
488 | 29.7k | -(_enc->state.curframe_num-_enc->state.keyframe_num):0; |
489 | 49.7k | nframes[0]=(_enc->rc.buf_delay-OC_MINI(next_key_frame,_enc->rc.buf_delay) |
490 | 49.7k | +_enc->keyframe_frequency_force-1)/_enc->keyframe_frequency_force; |
491 | 49.7k | if(nframes[0]+_qti>1){ |
492 | 8.79k | nframes[0]--; |
493 | 8.79k | buf_delay=next_key_frame+nframes[0]*_enc->keyframe_frequency_force; |
494 | 8.79k | } |
495 | 40.9k | else buf_delay=_enc->rc.buf_delay; |
496 | 49.7k | nframes[1]=buf_delay-nframes[0]; |
497 | | /*Downgrade the delta frame rate to correspond to the recent drop count |
498 | | history.*/ |
499 | 49.7k | nframes[1]=oc_rc_scale_drop(&_enc->rc,nframes[1]); |
500 | 49.7k | }break; |
501 | 0 | case 1:{ |
502 | | /*Pass 1 mode: use a fixed qi value.*/ |
503 | 0 | qi=_enc->state.qis[0]; |
504 | 0 | _enc->rc.log_qtarget=_enc->log_qavg[_qti][qi]; |
505 | 0 | return qi; |
506 | 0 | }break; |
507 | 0 | case 2:{ |
508 | 0 | ogg_int64_t scale_sum[2]; |
509 | 0 | int qti; |
510 | | /*Pass 2 mode: we know exactly how much of each frame type there is in |
511 | | the current buffer window, and have estimates for the scales.*/ |
512 | 0 | nframes[0]=_enc->rc.nframes[0]; |
513 | 0 | nframes[1]=_enc->rc.nframes[1]; |
514 | 0 | scale_sum[0]=_enc->rc.scale_sum[0]; |
515 | 0 | scale_sum[1]=_enc->rc.scale_sum[1]; |
516 | | /*The window size can be slightly larger than the buffer window for VFR |
517 | | content; clamp it down, if appropriate (the excess will all be dup |
518 | | frames).*/ |
519 | 0 | buf_delay=OC_MINI(_enc->rc.scale_window_end-_enc->rc.scale_window0, |
520 | 0 | _enc->rc.buf_delay); |
521 | | /*If we're approaching the end of the file, add some slack to keep us |
522 | | from slamming into a rail. |
523 | | Our rate accuracy goes down, but it keeps the result sensible. |
524 | | We position the target where the first forced keyframe beyond the end |
525 | | of the file would be (for consistency with 1-pass mode).*/ |
526 | 0 | buf_pad=OC_MINI(_enc->rc.buf_delay,_enc->state.keyframe_num |
527 | 0 | +_enc->keyframe_frequency_force-_enc->rc.scale_window0); |
528 | 0 | if(buf_delay<buf_pad)buf_pad-=buf_delay; |
529 | 0 | else{ |
530 | | /*Otherwise, search for the last keyframe in the buffer window and |
531 | | target that.*/ |
532 | 0 | buf_pad=0; |
533 | | /*TODO: Currently we only do this when using a finite buffer; we could |
534 | | save the position of the last keyframe in the summary data and do it |
535 | | with a whole-file buffer as well, but it isn't likely to make a |
536 | | difference.*/ |
537 | 0 | if(_enc->rc.frame_metrics!=NULL){ |
538 | 0 | int fmi; |
539 | 0 | int fm_tail; |
540 | 0 | fm_tail=_enc->rc.frame_metrics_head+_enc->rc.nframe_metrics; |
541 | 0 | if(fm_tail>=_enc->rc.cframe_metrics)fm_tail-=_enc->rc.cframe_metrics; |
542 | 0 | for(fmi=fm_tail;;){ |
543 | 0 | oc_frame_metrics *m; |
544 | 0 | fmi--; |
545 | 0 | if(fmi<0)fmi+=_enc->rc.cframe_metrics; |
546 | | /*Stop before we remove the first frame.*/ |
547 | 0 | if(fmi==_enc->rc.frame_metrics_head)break; |
548 | 0 | m=_enc->rc.frame_metrics+fmi; |
549 | | /*If we find a keyframe, remove it and everything past it.*/ |
550 | 0 | if(m->frame_type==OC_INTRA_FRAME){ |
551 | 0 | do{ |
552 | 0 | qti=m->frame_type; |
553 | 0 | nframes[qti]--; |
554 | 0 | scale_sum[qti]-=oc_bexp_q24(m->log_scale); |
555 | 0 | buf_delay-=m->dup_count+1; |
556 | 0 | fmi++; |
557 | 0 | if(fmi>=_enc->rc.cframe_metrics)fmi=0; |
558 | 0 | m=_enc->rc.frame_metrics+fmi; |
559 | 0 | } |
560 | 0 | while(fmi!=fm_tail); |
561 | | /*And stop scanning backwards.*/ |
562 | 0 | break; |
563 | 0 | } |
564 | 0 | } |
565 | 0 | } |
566 | 0 | } |
567 | | /*If we're not using the same frame type as in pass 1 (because someone |
568 | | changed the keyframe interval), remove that scale estimate. |
569 | | We'll add in a replacement for the correct frame type below.*/ |
570 | 0 | qti=_enc->rc.cur_metrics.frame_type; |
571 | 0 | if(qti!=_qti){ |
572 | 0 | nframes[qti]--; |
573 | 0 | scale_sum[qti]-=oc_bexp_q24(_enc->rc.cur_metrics.log_scale); |
574 | 0 | } |
575 | | /*Compute log_scale estimates for each frame type from the pass-1 scales |
576 | | we measured in the current window.*/ |
577 | 0 | for(qti=0;qti<2;qti++){ |
578 | 0 | _enc->rc.log_scale[qti]=nframes[qti]>0? |
579 | 0 | oc_blog64(scale_sum[qti])-oc_blog64(nframes[qti])-OC_Q57(24): |
580 | 0 | -_enc->rc.log_npixels; |
581 | 0 | } |
582 | | /*If we're not using the same frame type as in pass 1, add a scale |
583 | | estimate for the corresponding frame using the current low-pass |
584 | | filter value. |
585 | | This is mostly to ensure we have a valid estimate even when pass 1 had |
586 | | no frames of this type in the buffer window. |
587 | | TODO: We could also plan ahead and figure out how many keyframes we'll |
588 | | be forced to add in the current buffer window.*/ |
589 | 0 | qti=_enc->rc.cur_metrics.frame_type; |
590 | 0 | if(qti!=_qti){ |
591 | 0 | ogg_int64_t scale; |
592 | 0 | scale=_enc->rc.log_scale[_qti]<OC_Q57(23)? |
593 | 0 | oc_bexp64(_enc->rc.log_scale[_qti]+OC_Q57(24)):0x7FFFFFFFFFFFLL; |
594 | 0 | scale*=nframes[_qti]; |
595 | 0 | nframes[_qti]++; |
596 | 0 | scale+=oc_bexp_q24(log_cur_scale>>33); |
597 | 0 | _enc->rc.log_scale[_qti]=oc_blog64(scale) |
598 | 0 | -oc_blog64(nframes[qti])-OC_Q57(24); |
599 | 0 | } |
600 | 0 | else log_cur_scale=(ogg_int64_t)_enc->rc.cur_metrics.log_scale<<33; |
601 | | /*Add the padding from above. |
602 | | This basically reverts to 1-pass estimations in the last keyframe |
603 | | interval.*/ |
604 | 0 | if(buf_pad>0){ |
605 | 0 | ogg_int64_t scale; |
606 | 0 | int nextra_frames; |
607 | | /*Extend the buffer.*/ |
608 | 0 | buf_delay+=buf_pad; |
609 | | /*Add virtual delta frames according to the estimated drop count.*/ |
610 | 0 | nextra_frames=oc_rc_scale_drop(&_enc->rc,buf_pad); |
611 | | /*And blend in the low-pass filtered scale according to how many frames |
612 | | we added.*/ |
613 | 0 | scale= |
614 | 0 | oc_bexp64(_enc->rc.log_scale[1]+OC_Q57(24))*(ogg_int64_t)nframes[1] |
615 | 0 | +oc_bexp_q24(_enc->rc.scalefilter[1].y[0])*(ogg_int64_t)nextra_frames; |
616 | 0 | nframes[1]+=nextra_frames; |
617 | 0 | _enc->rc.log_scale[1]=oc_blog64(scale)-oc_blog64(nframes[1])-OC_Q57(24); |
618 | 0 | } |
619 | 0 | }break; |
620 | 49.7k | } |
621 | | /*If we've been missing our target, add a penalty term.*/ |
622 | 49.7k | rate_bias=(_enc->rc.rate_bias/(_enc->state.curframe_num+1000))* |
623 | 49.7k | (buf_delay-buf_pad); |
624 | | /*rate_total is the total bits available over the next buf_delay frames.*/ |
625 | 49.7k | rate_total=_enc->rc.fullness-_enc->rc.target+rate_bias |
626 | 49.7k | +buf_delay*_enc->rc.bits_per_frame; |
627 | 49.7k | log_scale0=_enc->rc.log_scale[_qti]+_enc->rc.log_npixels; |
628 | | /*If there aren't enough bits to achieve our desired fullness level, use the |
629 | | minimum quality permitted.*/ |
630 | 49.7k | if(rate_total<=buf_delay)log_qtarget=OC_QUANT_MAX_LOG; |
631 | 46.5k | else{ |
632 | 46.5k | static const ogg_int64_t LOG_KEY_RATIO=0x0137222BB70747BALL; |
633 | 46.5k | ogg_int64_t log_scale1; |
634 | 46.5k | ogg_int64_t rlo; |
635 | 46.5k | ogg_int64_t rhi; |
636 | 46.5k | log_scale1=_enc->rc.log_scale[1-_qti]+_enc->rc.log_npixels; |
637 | 46.5k | rlo=0; |
638 | 46.5k | rhi=(rate_total+nframes[_qti]-1)/nframes[_qti]; |
639 | 871k | while(rlo<rhi){ |
640 | 825k | ogg_int64_t curr; |
641 | 825k | ogg_int64_t rdiff; |
642 | 825k | ogg_int64_t log_rpow; |
643 | 825k | ogg_int64_t rscale; |
644 | 825k | curr=rlo+rhi>>1; |
645 | 825k | log_rpow=oc_blog64(curr)-log_scale0; |
646 | 825k | log_rpow=(log_rpow+(_enc->rc.exp[_qti]>>1))/_enc->rc.exp[_qti]; |
647 | 825k | if(_qti)log_rpow+=LOG_KEY_RATIO>>6; |
648 | 431k | else log_rpow-=LOG_KEY_RATIO>>6; |
649 | 825k | log_rpow*=_enc->rc.exp[1-_qti]; |
650 | 825k | rscale=nframes[1-_qti]*oc_bexp64(log_scale1+log_rpow); |
651 | 825k | rdiff=nframes[_qti]*curr+rscale-rate_total; |
652 | 825k | if(rdiff<0)rlo=curr+1; |
653 | 224k | else if(rdiff>0)rhi=curr-1; |
654 | 681 | else break; |
655 | 825k | } |
656 | 46.5k | log_qtarget=OC_Q57(2)-((oc_blog64(rlo)-log_scale0+(_enc->rc.exp[_qti]>>1))/ |
657 | 46.5k | _enc->rc.exp[_qti]<<6); |
658 | 46.5k | log_qtarget=OC_MINI(log_qtarget,OC_QUANT_MAX_LOG); |
659 | 46.5k | } |
660 | | /*The above allocation looks only at the total rate we'll accumulate in the |
661 | | next buf_delay frames. |
662 | | However, we could overflow the buffer on the very next frame, so check for |
663 | | that here, if we're not using a soft target.*/ |
664 | 49.7k | exp0=_enc->rc.exp[_qti]; |
665 | 49.7k | if(_enc->rc.cap_overflow){ |
666 | 49.7k | ogg_int64_t margin; |
667 | 49.7k | ogg_int64_t soft_limit; |
668 | 49.7k | ogg_int64_t log_soft_limit; |
669 | | /*Allow 3% of the buffer for prediction error. |
670 | | This should be plenty, and we don't mind if we go a bit over; we only |
671 | | want to keep these bits from being completely wasted.*/ |
672 | 49.7k | margin=_enc->rc.max+31>>5; |
673 | | /*We want to use at least this many bits next frame.*/ |
674 | 49.7k | soft_limit=_enc->rc.fullness+_enc->rc.bits_per_frame-(_enc->rc.max-margin); |
675 | 49.7k | log_soft_limit=oc_blog64(soft_limit); |
676 | | /*If we're predicting we won't use that many...*/ |
677 | 49.7k | log_qexp=(log_qtarget-OC_Q57(2)>>6)*exp0; |
678 | 49.7k | if(log_scale0-log_qexp<log_soft_limit){ |
679 | | /*Scale the adjustment based on how far into the margin we are.*/ |
680 | 12.3k | log_qexp+=(log_scale0-log_soft_limit-log_qexp>>32)* |
681 | 12.3k | ((OC_MINI(margin,soft_limit)<<32)/margin); |
682 | 12.3k | log_qtarget=((log_qexp+(exp0>>1))/exp0<<6)+OC_Q57(2); |
683 | 12.3k | } |
684 | 49.7k | } |
685 | | /*If this was not one of the initial frames, limit the change in quality.*/ |
686 | 49.7k | old_qi=_enc->state.qis[0]; |
687 | 49.7k | if(_clamp){ |
688 | 44.2k | ogg_int64_t log_qmin; |
689 | 44.2k | ogg_int64_t log_qmax; |
690 | | /*Clamp the target quantizer to within [0.8*Q,1.2*Q], where Q is the |
691 | | current quantizer. |
692 | | TODO: With user-specified quant matrices, we need to enlarge these limits |
693 | | if they don't actually let us change qi values.*/ |
694 | 44.2k | log_qmin=_enc->log_qavg[_qti][old_qi]-0x00A4D3C25E68DC58LL; |
695 | 44.2k | log_qmax=_enc->log_qavg[_qti][old_qi]+0x00A4D3C25E68DC58LL; |
696 | 44.2k | log_qtarget=OC_CLAMPI(log_qmin,log_qtarget,log_qmax); |
697 | 44.2k | } |
698 | | /*The above allocation looks only at the total rate we'll accumulate in the |
699 | | next buf_delay frames. |
700 | | However, we could bust the budget on the very next frame, so check for that |
701 | | here, if we're not using a soft target.*/ |
702 | | /* Disabled when our minimum qi > 0; if we saturate log_qtarget to |
703 | | to the maximum possible size when we have a minimum qi, the |
704 | | resulting lambda will interact very strangely with SKIP. The |
705 | | resulting artifacts look like waterfalls. */ |
706 | 49.7k | if(_enc->state.info.quality==0){ |
707 | 49.7k | ogg_int64_t log_hard_limit; |
708 | | /*Compute the maximum number of bits we can use in the next frame. |
709 | | Allow 50% of the rate for a single frame for prediction error. |
710 | | This may not be enough for keyframes or sudden changes in complexity.*/ |
711 | 49.7k | log_hard_limit=oc_blog64(_enc->rc.fullness+(_enc->rc.bits_per_frame>>1)); |
712 | | /*If we're predicting we'll use more than this...*/ |
713 | 49.7k | log_qexp=(log_qtarget-OC_Q57(2)>>6)*exp0; |
714 | 49.7k | if(log_scale0-log_qexp>log_hard_limit){ |
715 | | /*Force the target to hit our limit exactly.*/ |
716 | 9.09k | log_qexp=log_scale0-log_hard_limit; |
717 | 9.09k | log_qtarget=((log_qexp+(exp0>>1))/exp0<<6)+OC_Q57(2); |
718 | | /*If that target is unreasonable, oh well; we'll have to drop.*/ |
719 | 9.09k | log_qtarget=OC_MINI(log_qtarget,OC_QUANT_MAX_LOG); |
720 | 9.09k | } |
721 | 49.7k | } |
722 | | /*Compute a final estimate of the number of bits we plan to use.*/ |
723 | 49.7k | log_qexp=(log_qtarget-OC_Q57(2)>>6)*_enc->rc.exp[_qti]; |
724 | 49.7k | _enc->rc.rate_bias+=oc_bexp64(log_cur_scale+_enc->rc.log_npixels-log_qexp); |
725 | 49.7k | qi=oc_enc_find_qi_for_target(_enc,_qti,old_qi, |
726 | 49.7k | _enc->state.info.quality,log_qtarget); |
727 | | /*Save the quantizer target for lambda calculations.*/ |
728 | 49.7k | _enc->rc.log_qtarget=log_qtarget; |
729 | 49.7k | return qi; |
730 | 49.7k | } |
731 | | |
732 | | int oc_enc_update_rc_state(oc_enc_ctx *_enc, |
733 | 35.8k | long _bits,int _qti,int _qi,int _trial,int _droppable){ |
734 | 35.8k | ogg_int64_t buf_delta; |
735 | 35.8k | ogg_int64_t log_scale; |
736 | 35.8k | int dropped; |
737 | 35.8k | dropped=0; |
738 | | /* Drop frames also disabled for now in the case of infinite-buffer |
739 | | two-pass mode */ |
740 | 35.8k | if(!_enc->rc.drop_frames||_enc->rc.twopass&&_enc->rc.frame_metrics==NULL){ |
741 | 0 | _droppable=0; |
742 | 0 | } |
743 | 35.8k | buf_delta=_enc->rc.bits_per_frame*(1+_enc->dup_count); |
744 | 35.8k | if(_bits<=0){ |
745 | | /*We didn't code any blocks in this frame.*/ |
746 | 5.36k | log_scale=OC_Q57(-64); |
747 | 5.36k | _bits=0; |
748 | 5.36k | } |
749 | 30.5k | else{ |
750 | 30.5k | ogg_int64_t log_bits; |
751 | 30.5k | ogg_int64_t log_qexp; |
752 | | /*Compute the estimated scale factor for this frame type.*/ |
753 | 30.5k | log_bits=oc_blog64(_bits); |
754 | 30.5k | log_qexp=_enc->rc.log_qtarget-OC_Q57(2); |
755 | 30.5k | log_qexp=(log_qexp>>6)*(_enc->rc.exp[_qti]); |
756 | 30.5k | log_scale=OC_MINI(log_bits-_enc->rc.log_npixels+log_qexp,OC_Q57(16)); |
757 | 30.5k | } |
758 | | /*Special two-pass processing.*/ |
759 | 35.8k | switch(_enc->rc.twopass){ |
760 | 0 | case 1:{ |
761 | | /*Pass 1 mode: save the metrics for this frame.*/ |
762 | 0 | _enc->rc.cur_metrics.log_scale=oc_q57_to_q24(log_scale); |
763 | 0 | _enc->rc.cur_metrics.dup_count=_enc->dup_count; |
764 | 0 | _enc->rc.cur_metrics.frame_type=_enc->state.frame_type; |
765 | 0 | _enc->rc.cur_metrics.activity_avg=_enc->activity_avg; |
766 | 0 | _enc->rc.twopass_buffer_bytes=0; |
767 | 0 | }break; |
768 | 0 | case 2:{ |
769 | | /*Pass 2 mode:*/ |
770 | 0 | if(!_trial){ |
771 | 0 | ogg_int64_t next_frame_num; |
772 | 0 | int qti; |
773 | | /*Move the current metrics back one frame.*/ |
774 | 0 | *&_enc->rc.prev_metrics=*&_enc->rc.cur_metrics; |
775 | 0 | next_frame_num=_enc->state.curframe_num+_enc->dup_count+1; |
776 | | /*Back out the last frame's statistics from the sliding window.*/ |
777 | 0 | qti=_enc->rc.prev_metrics.frame_type; |
778 | 0 | _enc->rc.frames_left[qti]--; |
779 | 0 | _enc->rc.frames_left[2]-=_enc->rc.prev_metrics.dup_count; |
780 | 0 | _enc->rc.nframes[qti]--; |
781 | 0 | _enc->rc.nframes[2]-=_enc->rc.prev_metrics.dup_count; |
782 | 0 | _enc->rc.scale_sum[qti]-=oc_bexp_q24(_enc->rc.prev_metrics.log_scale); |
783 | 0 | _enc->rc.scale_window0=(int)next_frame_num; |
784 | | /*Free the corresponding entry in the circular buffer.*/ |
785 | 0 | if(_enc->rc.frame_metrics!=NULL){ |
786 | 0 | _enc->rc.nframe_metrics--; |
787 | 0 | _enc->rc.frame_metrics_head++; |
788 | 0 | if(_enc->rc.frame_metrics_head>=_enc->rc.cframe_metrics){ |
789 | 0 | _enc->rc.frame_metrics_head=0; |
790 | 0 | } |
791 | 0 | } |
792 | | /*Mark us ready for the next 2-pass packet.*/ |
793 | 0 | _enc->rc.twopass_buffer_bytes=0; |
794 | | /*Update state, so the user doesn't have to keep calling 2pass_in after |
795 | | they've fed in all the data when we're using a finite buffer.*/ |
796 | 0 | _enc->prev_dup_count=_enc->dup_count; |
797 | 0 | oc_enc_rc_2pass_in(_enc,NULL,0); |
798 | 0 | } |
799 | 0 | }break; |
800 | 35.8k | } |
801 | | /*Common to all passes:*/ |
802 | 35.8k | if(_bits>0){ |
803 | 30.5k | if(_trial){ |
804 | 3.94k | oc_iir_filter *f; |
805 | | /*Use the estimated scale factor directly if this was a trial.*/ |
806 | 3.94k | f=_enc->rc.scalefilter+_qti; |
807 | 3.94k | f->y[1]=f->y[0]=f->x[1]=f->x[0]=oc_q57_to_q24(log_scale); |
808 | 3.94k | _enc->rc.log_scale[_qti]=log_scale; |
809 | 3.94k | } |
810 | 26.5k | else{ |
811 | | /*Lengthen the time constant for the INTER filter as we collect more |
812 | | frame statistics, until we reach our target.*/ |
813 | 26.5k | if(_enc->rc.inter_delay<_enc->rc.inter_delay_target&& |
814 | 26.5k | _enc->rc.inter_count>=_enc->rc.inter_delay&&_qti==OC_INTER_FRAME){ |
815 | 2.96k | oc_iir_filter_reinit(&_enc->rc.scalefilter[1],++_enc->rc.inter_delay); |
816 | 2.96k | } |
817 | | /*Otherwise update the low-pass scale filter for this frame type, |
818 | | regardless of whether or not we dropped this frame.*/ |
819 | 26.5k | _enc->rc.log_scale[_qti]=oc_iir_filter_update( |
820 | 26.5k | _enc->rc.scalefilter+_qti,oc_q57_to_q24(log_scale))<<33; |
821 | | /*If this frame busts our budget, it must be dropped.*/ |
822 | 26.5k | if(_droppable&&_enc->rc.fullness+buf_delta<_bits){ |
823 | 3.27k | _enc->rc.prev_drop_count+=1+_enc->dup_count; |
824 | 3.27k | _bits=0; |
825 | 3.27k | dropped=1; |
826 | 3.27k | } |
827 | 23.3k | else{ |
828 | 23.3k | ogg_uint32_t drop_count; |
829 | | /*Update a low-pass filter to estimate the "real" frame rate taking |
830 | | drops and duplicates into account. |
831 | | This is only done if the frame is coded, as it needs the final |
832 | | count of dropped frames.*/ |
833 | 23.3k | drop_count=_enc->rc.prev_drop_count+1; |
834 | 23.3k | if(drop_count>0x7F)drop_count=0x7FFFFFFF; |
835 | 23.2k | else drop_count<<=24; |
836 | 23.3k | _enc->rc.log_drop_scale=oc_blog64(oc_iir_filter_update( |
837 | 23.3k | &_enc->rc.vfrfilter,drop_count))-OC_Q57(24); |
838 | | /*Initialize the drop count for this frame to the user-requested dup |
839 | | count. |
840 | | It will be increased if we drop more frames.*/ |
841 | 23.3k | _enc->rc.prev_drop_count=_enc->dup_count; |
842 | 23.3k | } |
843 | 26.5k | } |
844 | | /*Increment the INTER frame count, for filter adaptation purposes.*/ |
845 | 30.5k | if(_enc->rc.inter_count<INT_MAX)_enc->rc.inter_count+=_qti; |
846 | 30.5k | } |
847 | | /*Increase the drop count.*/ |
848 | 5.36k | else _enc->rc.prev_drop_count+=1+_enc->dup_count; |
849 | | /*And update the buffer fullness level.*/ |
850 | 35.8k | if(!_trial){ |
851 | 31.7k | _enc->rc.fullness+=buf_delta-_bits; |
852 | | /*If we're too quick filling the buffer and overflow is capped, |
853 | | that rate is lost forever.*/ |
854 | 31.7k | if(_enc->rc.cap_overflow&&_enc->rc.fullness>_enc->rc.max){ |
855 | 8.87k | _enc->rc.fullness=_enc->rc.max; |
856 | 8.87k | } |
857 | | /*If we're too quick draining the buffer and underflow is capped, |
858 | | don't try to make up that rate later.*/ |
859 | 31.7k | if(_enc->rc.cap_underflow&&_enc->rc.fullness<0){ |
860 | 0 | _enc->rc.fullness=0; |
861 | 0 | } |
862 | | /*Adjust the bias for the real bits we've used.*/ |
863 | 31.7k | _enc->rc.rate_bias-=_bits; |
864 | 31.7k | } |
865 | 35.8k | return dropped; |
866 | 35.8k | } |
867 | | |
868 | 0 | #define OC_RC_2PASS_VERSION (2) |
869 | 0 | #define OC_RC_2PASS_HDR_SZ (38) |
870 | 0 | #define OC_RC_2PASS_PACKET_SZ (12) |
871 | | |
872 | 0 | static void oc_rc_buffer_val(oc_rc_state *_rc,ogg_int64_t _val,int _bytes){ |
873 | 0 | while(_bytes-->0){ |
874 | 0 | _rc->twopass_buffer[_rc->twopass_buffer_bytes++]=(unsigned char)(_val&0xFF); |
875 | 0 | _val>>=8; |
876 | 0 | } |
877 | 0 | } |
878 | | |
879 | 0 | int oc_enc_rc_2pass_out(oc_enc_ctx *_enc,unsigned char **_buf){ |
880 | 0 | if(_enc->rc.twopass_buffer_bytes==0){ |
881 | 0 | if(_enc->rc.twopass==0){ |
882 | 0 | int qi; |
883 | | /*Pick first-pass qi for scale calculations.*/ |
884 | 0 | qi=oc_enc_select_qi(_enc,0,0); |
885 | 0 | _enc->state.nqis=1; |
886 | 0 | _enc->state.qis[0]=qi; |
887 | 0 | _enc->rc.twopass=1; |
888 | 0 | _enc->rc.frames_total[0]=_enc->rc.frames_total[1]= |
889 | 0 | _enc->rc.frames_total[2]=0; |
890 | 0 | _enc->rc.scale_sum[0]=_enc->rc.scale_sum[1]=0; |
891 | | /*Fill in dummy summary values.*/ |
892 | 0 | oc_rc_buffer_val(&_enc->rc,0x5032544F,4); |
893 | 0 | oc_rc_buffer_val(&_enc->rc,OC_RC_2PASS_VERSION,4); |
894 | 0 | oc_rc_buffer_val(&_enc->rc,0,OC_RC_2PASS_HDR_SZ-8); |
895 | 0 | } |
896 | 0 | else{ |
897 | 0 | int qti; |
898 | 0 | qti=_enc->rc.cur_metrics.frame_type; |
899 | 0 | _enc->rc.scale_sum[qti]+=oc_bexp_q24(_enc->rc.cur_metrics.log_scale); |
900 | 0 | _enc->rc.frames_total[qti]++; |
901 | 0 | _enc->rc.frames_total[2]+=_enc->rc.cur_metrics.dup_count; |
902 | 0 | oc_rc_buffer_val(&_enc->rc, |
903 | 0 | _enc->rc.cur_metrics.dup_count|_enc->rc.cur_metrics.frame_type<<31,4); |
904 | 0 | oc_rc_buffer_val(&_enc->rc,_enc->rc.cur_metrics.log_scale,4); |
905 | 0 | oc_rc_buffer_val(&_enc->rc,_enc->rc.cur_metrics.activity_avg,4); |
906 | 0 | } |
907 | 0 | } |
908 | 0 | else if(_enc->packet_state==OC_PACKET_DONE&& |
909 | 0 | _enc->rc.twopass_buffer_bytes!=OC_RC_2PASS_HDR_SZ){ |
910 | 0 | _enc->rc.twopass_buffer_bytes=0; |
911 | 0 | oc_rc_buffer_val(&_enc->rc,0x5032544F,4); |
912 | 0 | oc_rc_buffer_val(&_enc->rc,OC_RC_2PASS_VERSION,4); |
913 | 0 | oc_rc_buffer_val(&_enc->rc,_enc->rc.frames_total[0],4); |
914 | 0 | oc_rc_buffer_val(&_enc->rc,_enc->rc.frames_total[1],4); |
915 | 0 | oc_rc_buffer_val(&_enc->rc,_enc->rc.frames_total[2],4); |
916 | 0 | oc_rc_buffer_val(&_enc->rc,_enc->rc.exp[0],1); |
917 | 0 | oc_rc_buffer_val(&_enc->rc,_enc->rc.exp[1],1); |
918 | 0 | oc_rc_buffer_val(&_enc->rc,_enc->rc.scale_sum[0],8); |
919 | 0 | oc_rc_buffer_val(&_enc->rc,_enc->rc.scale_sum[1],8); |
920 | 0 | } |
921 | 0 | else{ |
922 | | /*The data for this frame has already been retrieved.*/ |
923 | 0 | *_buf=NULL; |
924 | 0 | return 0; |
925 | 0 | } |
926 | 0 | *_buf=_enc->rc.twopass_buffer; |
927 | 0 | return _enc->rc.twopass_buffer_bytes; |
928 | 0 | } |
929 | | |
930 | | static size_t oc_rc_buffer_fill(oc_rc_state *_rc, |
931 | 0 | unsigned char *_buf,size_t _bytes,size_t _consumed,size_t _goal){ |
932 | 0 | while(_rc->twopass_buffer_fill<_goal&&_consumed<_bytes){ |
933 | 0 | _rc->twopass_buffer[_rc->twopass_buffer_fill++]=_buf[_consumed++]; |
934 | 0 | } |
935 | 0 | return _consumed; |
936 | 0 | } |
937 | | |
938 | 0 | static ogg_int64_t oc_rc_unbuffer_val(oc_rc_state *_rc,int _bytes){ |
939 | 0 | ogg_int64_t ret; |
940 | 0 | int shift; |
941 | 0 | ret=0; |
942 | 0 | shift=0; |
943 | 0 | while(_bytes-->0){ |
944 | 0 | ret|=((ogg_int64_t)_rc->twopass_buffer[_rc->twopass_buffer_bytes++])<<shift; |
945 | 0 | shift+=8; |
946 | 0 | } |
947 | 0 | return ret; |
948 | 0 | } |
949 | | |
950 | 0 | int oc_enc_rc_2pass_in(oc_enc_ctx *_enc,unsigned char *_buf,size_t _bytes){ |
951 | 0 | size_t consumed; |
952 | 0 | consumed=0; |
953 | | /*Enable pass 2 mode if this is the first call.*/ |
954 | 0 | if(_enc->rc.twopass==0){ |
955 | 0 | _enc->rc.twopass=2; |
956 | 0 | _enc->rc.twopass_buffer_fill=0; |
957 | 0 | _enc->rc.frames_total[0]=0; |
958 | 0 | _enc->rc.nframe_metrics=0; |
959 | 0 | _enc->rc.cframe_metrics=0; |
960 | 0 | _enc->rc.frame_metrics_head=0; |
961 | 0 | _enc->rc.scale_window0=0; |
962 | 0 | _enc->rc.scale_window_end=0; |
963 | 0 | } |
964 | | /*If we haven't got a valid summary header yet, try to parse one.*/ |
965 | 0 | if(_enc->rc.frames_total[0]==0){ |
966 | 0 | if(!_buf){ |
967 | 0 | int frames_needed; |
968 | | /*If we're using a whole-file buffer, we just need the first frame. |
969 | | Otherwise, we may need as many as one per buffer slot.*/ |
970 | 0 | frames_needed=_enc->rc.frame_metrics==NULL?1:_enc->rc.buf_delay; |
971 | 0 | return OC_RC_2PASS_HDR_SZ+frames_needed*OC_RC_2PASS_PACKET_SZ |
972 | 0 | -_enc->rc.twopass_buffer_fill; |
973 | 0 | } |
974 | 0 | consumed=oc_rc_buffer_fill(&_enc->rc, |
975 | 0 | _buf,_bytes,consumed,OC_RC_2PASS_HDR_SZ); |
976 | 0 | if(_enc->rc.twopass_buffer_fill>=OC_RC_2PASS_HDR_SZ){ |
977 | 0 | ogg_int64_t scale_sum[2]; |
978 | 0 | int exp[2]; |
979 | 0 | int buf_delay; |
980 | | /*Read the summary header data.*/ |
981 | | /*Check the magic value and version number.*/ |
982 | 0 | if(oc_rc_unbuffer_val(&_enc->rc,4)!=0x5032544F|| |
983 | 0 | oc_rc_unbuffer_val(&_enc->rc,4)!=OC_RC_2PASS_VERSION){ |
984 | 0 | _enc->rc.twopass_buffer_bytes=0; |
985 | 0 | return TH_ENOTFORMAT; |
986 | 0 | } |
987 | 0 | _enc->rc.frames_total[0]=(ogg_uint32_t)oc_rc_unbuffer_val(&_enc->rc,4); |
988 | 0 | _enc->rc.frames_total[1]=(ogg_uint32_t)oc_rc_unbuffer_val(&_enc->rc,4); |
989 | 0 | _enc->rc.frames_total[2]=(ogg_uint32_t)oc_rc_unbuffer_val(&_enc->rc,4); |
990 | 0 | exp[0]=(int)oc_rc_unbuffer_val(&_enc->rc,1); |
991 | 0 | exp[1]=(int)oc_rc_unbuffer_val(&_enc->rc,1); |
992 | 0 | scale_sum[0]=oc_rc_unbuffer_val(&_enc->rc,8); |
993 | 0 | scale_sum[1]=oc_rc_unbuffer_val(&_enc->rc,8); |
994 | | /*Make sure the file claims to have at least one frame. |
995 | | Otherwise we probably got the placeholder data from an aborted pass 1. |
996 | | Also make sure the total frame count doesn't overflow an integer.*/ |
997 | 0 | buf_delay=_enc->rc.frames_total[0]+_enc->rc.frames_total[1] |
998 | 0 | +_enc->rc.frames_total[2]; |
999 | 0 | if(_enc->rc.frames_total[0]==0||buf_delay<0|| |
1000 | 0 | (ogg_uint32_t)buf_delay<_enc->rc.frames_total[0]|| |
1001 | 0 | (ogg_uint32_t)buf_delay<_enc->rc.frames_total[1]){ |
1002 | 0 | _enc->rc.frames_total[0]=0; |
1003 | 0 | _enc->rc.twopass_buffer_bytes=0; |
1004 | 0 | return TH_EBADHEADER; |
1005 | 0 | } |
1006 | | /*Got a valid header; set up pass 2.*/ |
1007 | 0 | _enc->rc.frames_left[0]=_enc->rc.frames_total[0]; |
1008 | 0 | _enc->rc.frames_left[1]=_enc->rc.frames_total[1]; |
1009 | 0 | _enc->rc.frames_left[2]=_enc->rc.frames_total[2]; |
1010 | | /*If the user hasn't specified a buffer size, use the whole file.*/ |
1011 | 0 | if(_enc->rc.frame_metrics==NULL){ |
1012 | 0 | _enc->rc.buf_delay=buf_delay; |
1013 | 0 | _enc->rc.nframes[0]=_enc->rc.frames_total[0]; |
1014 | 0 | _enc->rc.nframes[1]=_enc->rc.frames_total[1]; |
1015 | 0 | _enc->rc.nframes[2]=_enc->rc.frames_total[2]; |
1016 | 0 | _enc->rc.scale_sum[0]=scale_sum[0]; |
1017 | 0 | _enc->rc.scale_sum[1]=scale_sum[1]; |
1018 | 0 | _enc->rc.scale_window_end=buf_delay; |
1019 | 0 | oc_enc_rc_reset(_enc); |
1020 | 0 | } |
1021 | 0 | _enc->rc.exp[0]=exp[0]; |
1022 | 0 | _enc->rc.exp[1]=exp[1]; |
1023 | | /*Clear the header data from the buffer to make room for packet data.*/ |
1024 | 0 | _enc->rc.twopass_buffer_fill=0; |
1025 | 0 | _enc->rc.twopass_buffer_bytes=0; |
1026 | 0 | } |
1027 | 0 | } |
1028 | 0 | if(_enc->rc.frames_total[0]!=0){ |
1029 | 0 | ogg_int64_t curframe_num; |
1030 | 0 | int nframes_total; |
1031 | 0 | curframe_num=_enc->state.curframe_num; |
1032 | 0 | if(curframe_num>=0){ |
1033 | | /*We just encoded a frame; make sure things matched.*/ |
1034 | 0 | if(_enc->rc.prev_metrics.dup_count!=_enc->prev_dup_count){ |
1035 | 0 | _enc->rc.twopass_buffer_bytes=0; |
1036 | 0 | return TH_EINVAL; |
1037 | 0 | } |
1038 | 0 | } |
1039 | 0 | curframe_num+=_enc->prev_dup_count+1; |
1040 | 0 | nframes_total=_enc->rc.frames_total[0]+_enc->rc.frames_total[1] |
1041 | 0 | +_enc->rc.frames_total[2]; |
1042 | 0 | if(curframe_num>=nframes_total){ |
1043 | | /*We don't want any more data after the last frame, and we don't want to |
1044 | | allow any more frames to be encoded.*/ |
1045 | 0 | _enc->rc.twopass_buffer_bytes=0; |
1046 | 0 | } |
1047 | 0 | else if(_enc->rc.twopass_buffer_bytes==0){ |
1048 | 0 | if(_enc->rc.frame_metrics==NULL){ |
1049 | | /*We're using a whole-file buffer:*/ |
1050 | 0 | if(!_buf)return OC_RC_2PASS_PACKET_SZ-_enc->rc.twopass_buffer_fill; |
1051 | 0 | consumed=oc_rc_buffer_fill(&_enc->rc, |
1052 | 0 | _buf,_bytes,consumed,OC_RC_2PASS_PACKET_SZ); |
1053 | 0 | if(_enc->rc.twopass_buffer_fill>=OC_RC_2PASS_PACKET_SZ){ |
1054 | 0 | ogg_uint32_t dup_count; |
1055 | 0 | ogg_int32_t log_scale; |
1056 | 0 | unsigned activity; |
1057 | 0 | int qti; |
1058 | 0 | int arg; |
1059 | | /*Read the metrics for the next frame.*/ |
1060 | 0 | dup_count=oc_rc_unbuffer_val(&_enc->rc,4); |
1061 | 0 | log_scale=oc_rc_unbuffer_val(&_enc->rc,4); |
1062 | 0 | activity=oc_rc_unbuffer_val(&_enc->rc,4); |
1063 | 0 | _enc->rc.cur_metrics.log_scale=log_scale; |
1064 | 0 | qti=(dup_count&0x80000000)>>31; |
1065 | 0 | _enc->rc.cur_metrics.dup_count=dup_count&0x7FFFFFFF; |
1066 | 0 | _enc->rc.cur_metrics.frame_type=qti; |
1067 | 0 | _enc->rc.twopass_force_kf=qti==OC_INTRA_FRAME; |
1068 | 0 | _enc->activity_avg=_enc->rc.cur_metrics.activity_avg=activity; |
1069 | | /*"Helpfully" set the dup count back to what it was in pass 1.*/ |
1070 | 0 | arg=_enc->rc.cur_metrics.dup_count; |
1071 | 0 | th_encode_ctl(_enc,TH_ENCCTL_SET_DUP_COUNT,&arg,sizeof(arg)); |
1072 | | /*Clear the buffer for the next frame.*/ |
1073 | 0 | _enc->rc.twopass_buffer_fill=0; |
1074 | 0 | } |
1075 | 0 | } |
1076 | 0 | else{ |
1077 | 0 | int frames_needed; |
1078 | | /*We're using a finite buffer:*/ |
1079 | 0 | frames_needed=OC_MINI(_enc->rc.buf_delay-OC_MINI(_enc->rc.buf_delay, |
1080 | 0 | _enc->rc.scale_window_end-_enc->rc.scale_window0), |
1081 | 0 | _enc->rc.frames_left[0]+_enc->rc.frames_left[1] |
1082 | 0 | -_enc->rc.nframes[0]-_enc->rc.nframes[1]); |
1083 | 0 | while(frames_needed>0){ |
1084 | 0 | if(!_buf){ |
1085 | 0 | return OC_RC_2PASS_PACKET_SZ*frames_needed |
1086 | 0 | -_enc->rc.twopass_buffer_fill; |
1087 | 0 | } |
1088 | 0 | consumed=oc_rc_buffer_fill(&_enc->rc, |
1089 | 0 | _buf,_bytes,consumed,OC_RC_2PASS_PACKET_SZ); |
1090 | 0 | if(_enc->rc.twopass_buffer_fill>=OC_RC_2PASS_PACKET_SZ){ |
1091 | 0 | oc_frame_metrics *m; |
1092 | 0 | int fmi; |
1093 | 0 | ogg_uint32_t dup_count; |
1094 | 0 | ogg_int32_t log_scale; |
1095 | 0 | int qti; |
1096 | 0 | unsigned activity; |
1097 | | /*Read the metrics for the next frame.*/ |
1098 | 0 | dup_count=oc_rc_unbuffer_val(&_enc->rc,4); |
1099 | 0 | log_scale=oc_rc_unbuffer_val(&_enc->rc,4); |
1100 | 0 | activity=oc_rc_unbuffer_val(&_enc->rc,4); |
1101 | | /*Add the to the circular buffer.*/ |
1102 | 0 | fmi=_enc->rc.frame_metrics_head+_enc->rc.nframe_metrics++; |
1103 | 0 | if(fmi>=_enc->rc.cframe_metrics)fmi-=_enc->rc.cframe_metrics; |
1104 | 0 | m=_enc->rc.frame_metrics+fmi; |
1105 | 0 | m->log_scale=log_scale; |
1106 | 0 | qti=(dup_count&0x80000000)>>31; |
1107 | 0 | m->dup_count=dup_count&0x7FFFFFFF; |
1108 | 0 | m->frame_type=qti; |
1109 | 0 | m->activity_avg=activity; |
1110 | | /*And accumulate the statistics over the window.*/ |
1111 | 0 | _enc->rc.nframes[qti]++; |
1112 | 0 | _enc->rc.nframes[2]+=m->dup_count; |
1113 | 0 | _enc->rc.scale_sum[qti]+=oc_bexp_q24(m->log_scale); |
1114 | 0 | _enc->rc.scale_window_end+=m->dup_count+1; |
1115 | | /*Compute an upper bound on the number of remaining packets needed |
1116 | | for the current window.*/ |
1117 | 0 | frames_needed=OC_MINI(_enc->rc.buf_delay-OC_MINI(_enc->rc.buf_delay, |
1118 | 0 | _enc->rc.scale_window_end-_enc->rc.scale_window0), |
1119 | 0 | _enc->rc.frames_left[0]+_enc->rc.frames_left[1] |
1120 | 0 | -_enc->rc.nframes[0]-_enc->rc.nframes[1]); |
1121 | | /*Clear the buffer for the next frame.*/ |
1122 | 0 | _enc->rc.twopass_buffer_fill=0; |
1123 | 0 | _enc->rc.twopass_buffer_bytes=0; |
1124 | 0 | } |
1125 | | /*Go back for more data.*/ |
1126 | 0 | else break; |
1127 | 0 | } |
1128 | | /*If we've got all the frames we need, fill in the current metrics. |
1129 | | We're ready to go.*/ |
1130 | 0 | if(frames_needed<=0){ |
1131 | 0 | int arg; |
1132 | 0 | *&_enc->rc.cur_metrics= |
1133 | 0 | *(_enc->rc.frame_metrics+_enc->rc.frame_metrics_head); |
1134 | 0 | _enc->rc.twopass_force_kf= |
1135 | 0 | _enc->rc.cur_metrics.frame_type==OC_INTRA_FRAME; |
1136 | 0 | _enc->activity_avg=_enc->rc.cur_metrics.activity_avg; |
1137 | | /*"Helpfully" set the dup count back to what it was in pass 1.*/ |
1138 | 0 | arg=_enc->rc.cur_metrics.dup_count; |
1139 | 0 | th_encode_ctl(_enc,TH_ENCCTL_SET_DUP_COUNT,&arg,sizeof(arg)); |
1140 | | /*Mark us ready for the next frame.*/ |
1141 | 0 | _enc->rc.twopass_buffer_bytes=1; |
1142 | 0 | } |
1143 | 0 | } |
1144 | 0 | } |
1145 | 0 | } |
1146 | 0 | return (int)consumed; |
1147 | 0 | } |