printf -> mp_msg
[mplayer/glamo.git] / divx4_vbr.c
blobf1a87c4906a7f41cc4a456e4e7170aef2845f37c
1 /*
2 * divx4_vbr.c
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file COPYING in the main directory of the Linux
6 * distribution for more details.
8 * 2-pass code OpenDivX port:
9 * Copyright (C) 2001 Christoph Lampert <gruel@gmx.de>
11 * Large parts of this code were taken from VbrControl() from the OpenDivX
12 * project, (C) divxnetworks, written by Eugene Kuznetsov <ekuznetsov@divxnetworks.com>
13 * with the permission of Darrius "Junto" Thompson, Director DivX
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include <math.h>
22 #include <inttypes.h>
24 #include "divx4_vbr.h"
26 //#include "transcode.h"
28 #define FALSE 0
29 #define TRUE 1
31 /* Absolute maximum and minimum quantizers used in VBR modes */
32 static const int min_quantizer=1;
33 static const int max_quantizer=31;
35 /* Limits on frame-level deviation of quantizer ( higher values
36 correspond to frames with more changes and vice versa ) */
37 static const float min_quant_delta=-10.f;
38 static const float max_quant_delta=5.f;
39 /* Limits on stream-level deviation of quantizer ( used to make
40 overall bitrate of stream close to requested value ) */
41 static const float min_rc_quant_delta=.6f;
42 static const float max_rc_quant_delta=1.5f;
44 /* Crispness parameter controls threshold for decision whether
45 to skip the frame or to code it. */
46 //static const float max_crispness=100.f;
47 /* Maximum allowed number of skipped frames in a line. */
48 //static const int max_drops_line=0; // CHL We don't drop frames at the moment!
51 typedef struct entry_s
52 /* max 28 bytes/frame or 5 Mb for 2-hour movie */
54 int quant;
55 int text_bits;
56 int motion_bits;
57 int total_bits;
58 float mult;
59 short is_key_frame;
60 short drop;
61 } entry;
63 static int m_iCount;
64 static int m_iQuant;
65 /*static int m_iCrispness;*/
66 static short m_bDrop;
67 static float m_fQuant;
69 static int64_t m_lEncodedBits;
70 static int64_t m_lExpectedBits;
72 static FILE *m_pFile;
74 static entry vFrame;
75 static entry *m_vFrames;
76 static long lFrameStart;
78 static int iNumFrames;
79 static int dummy;
82 void VbrControl_init_1pass_vbr(int quality, int crispness)
84 m_fQuant=min_quantizer+((max_quantizer-min_quantizer)/6.)*(6-quality);
85 m_iCount=0;
86 m_bDrop=FALSE;
87 VbrControl_update_1pass_vbr();
90 int VbrControl_init_2pass_vbr_analysis(const char *filename, int quality)
92 m_pFile=fopen(filename, "wb");
93 if(m_pFile==0)
94 return -1;
95 m_iCount=0;
96 m_bDrop=FALSE;
97 fprintf(m_pFile, "##version 1\n");
98 fprintf(m_pFile, "quality %d\n", quality);
99 return 0;
102 int VbrControl_init_2pass_vbr_encoding(const char *filename, int bitrate, double framerate, int crispness, int quality)
104 int i;
106 int64_t text_bits=0;
107 int64_t total_bits=0;
108 int64_t complexity=0;
109 int64_t new_complexity=0;
110 int64_t motion_bits=0;
111 int64_t denominator=0;
112 float qual_multiplier=1.;
113 char head[20];
115 int64_t desired_bits;
116 int64_t non_text_bits;
118 float average_complexity;
120 m_pFile=fopen(filename, "rb");
121 if(m_pFile==0)
122 return -1;
123 m_bDrop=FALSE;
124 m_iCount=0;
126 fread(head, 10, 1, m_pFile);
127 if(!strncmp("##version ", head, 10))
129 int version;
130 int iOldQual;
131 float old_qual, new_qual;
132 fscanf(m_pFile, "%d\n", &version);
133 fscanf(m_pFile, "quality %d\n", &iOldQual);
134 switch(iOldQual)
136 case 5:
137 old_qual=1.f;
138 break;
139 case 4:
140 old_qual=1.1f;
141 break;
142 case 3:
143 old_qual=1.25f;
144 break;
145 case 2:
146 old_qual=1.4f;
147 break;
148 case 1:
149 old_qual=2.f;
150 break;
152 switch(quality)
154 case 5:
155 new_qual=1.f;
156 break;
157 case 4:
158 new_qual=1.1f;
159 break;
160 case 3:
161 new_qual=1.25f;
162 break;
163 case 2:
164 new_qual=1.4f;
165 break;
166 case 1:
167 new_qual=2.f;
168 break;
170 qual_multiplier=new_qual/old_qual;
172 else
173 fseek(m_pFile, 0, SEEK_SET);
175 lFrameStart=ftell(m_pFile); // save current position
177 /* removed C++ dependencies, now read file twice :-( */
180 while(!feof(m_pFile))
181 { fscanf(m_pFile, "Frame %d: intra %hd, quant %d, texture %d, motion %d, total %d\n",
182 &iNumFrames, &(vFrame.is_key_frame), &(vFrame.quant), &(vFrame.text_bits), &(vFrame.motion_bits), &(vFrame.total_bits));
184 vFrame.total_bits+=vFrame.text_bits*(qual_multiplier-1);
185 vFrame.text_bits*=qual_multiplier;
186 text_bits +=(int64_t)vFrame.text_bits;
187 motion_bits += (int64_t)vFrame.motion_bits;
188 total_bits +=(int64_t)vFrame.total_bits;
189 complexity +=(int64_t)vFrame.text_bits*vFrame.quant;
191 // printf("Frames %d, texture %d, motion %d, quant %d total %d ",
192 // iNumFrames, vFrame.text_bits, vFrame.motion_bits, vFrame.quant, vFrame.total_bits);
193 // printf("texture %d, total %d, complexity %lld \n",vFrame.text_bits,vFrame.total_bits, complexity);
195 iNumFrames++;
196 average_complexity=complexity/iNumFrames;
198 // if (verbose & TC_DEBUG) {
199 // fprintf(stderr, "(%s) frames %d, texture %lld, motion %lld, total %lld, complexity %lld\n", __FILE__, iNumFrames, text_bits, motion_bits, total_bits, complexity);
200 // }
202 m_vFrames = (entry*)malloc(iNumFrames*sizeof(entry));
203 if (!m_vFrames)
204 { printf("out of memory");
205 return -2; //TC_EXPORT_ERROR;
208 fseek(m_pFile, lFrameStart, SEEK_SET); // start again
210 for (i=0;i<iNumFrames;i++)
211 { fscanf(m_pFile, "Frame %d: intra %hd, quant %d, texture %d, motion %d, total %d\n",
212 &dummy, &(m_vFrames[i].is_key_frame), &(m_vFrames[i].quant),
213 &(m_vFrames[i].text_bits), &(m_vFrames[i].motion_bits),
214 &(m_vFrames[i].total_bits));
216 m_vFrames[i].total_bits += m_vFrames[i].text_bits*(qual_multiplier-1);
217 m_vFrames[i].text_bits *= qual_multiplier;
220 if (m_pFile)
221 { fclose(m_pFile);
222 m_pFile=NULL;
225 desired_bits=(int64_t)bitrate*(int64_t)iNumFrames/framerate;
226 non_text_bits=total_bits-text_bits;
228 if(desired_bits<=non_text_bits)
230 /* char s[200];*/
231 printf("Specified bitrate is too low for this clip.\n"
232 "Minimum possible bitrate for the clip is %.0f kbps. Overriding\n"
233 "user-specified value.\n",
234 (float)(non_text_bits*framerate/(int64_t)iNumFrames));
236 desired_bits=non_text_bits*3/2;
238 m_fQuant=max_quantizer;
239 for(int i=0; i<iNumFrames; i++)
241 m_vFrames[i].drop=0;
242 m_vFrames[i].mult=1;
244 VbrControl_set_quant(m_fQuant);
245 return 0;
249 desired_bits -= non_text_bits;
251 BRIEF EXPLANATION OF WHAT'S GOING ON HERE.
252 We assume that
253 text_bits=complexity / quantizer
254 total_bits-text_bits = const(complexity)
255 where 'complexity' is a characteristic of the frame
256 and does not depend much on quantizer dynamics.
257 Using this equation, we calculate 'average' quantizer
258 to be used for encoding ( 1st order effect ).
259 Having constant quantizer for the entire stream is not
260 very convenient - reconstruction errors are
261 more noticeable in low-motion scenes. To compensate
262 this effect, we multiply quantizer for each frame by
263 (complexity/average_complexity)^k,
264 ( k - parameter of adjustment ). k=0 means 'no compensation'
265 and k=1 is 'constant bitrate mode'. We choose something in
266 between, like 0.5 ( 2nd order effect ).
269 average_complexity=complexity/iNumFrames;
271 for(i=0; i<iNumFrames; i++)
273 float mult;
274 if(m_vFrames[i].is_key_frame)
276 if((i+1<iNumFrames) && (m_vFrames[i+1].is_key_frame))
277 mult=1.25;
278 else
279 mult=.75;
281 else
283 mult=m_vFrames[i].text_bits*m_vFrames[i].quant;
284 mult=(float)sqrt(mult/average_complexity);
286 // if(i && m_vFrames[i-1].is_key_frame)
287 // mult *= 0.75;
288 if(mult<0.5)
289 mult=0.5;
290 if(mult>1.5)
291 mult=1.5;
294 m_vFrames[i].mult=mult;
295 m_vFrames[i].drop=FALSE;
296 new_complexity+=m_vFrames[i].text_bits*m_vFrames[i].quant;
298 denominator+=desired_bits*m_vFrames[i].mult/iNumFrames;
301 m_fQuant=((double)new_complexity)/(double)denominator;
303 if(m_fQuant<min_quantizer) m_fQuant=min_quantizer;
304 if(m_fQuant>max_quantizer) m_fQuant=max_quantizer;
305 m_pFile=fopen("analyse.log", "wb");
306 if(m_pFile)
308 fprintf(m_pFile, "Total frames: %d Avg quantizer: %f\n",
309 iNumFrames, m_fQuant);
310 fprintf(m_pFile, "Expecting %12lld bits\n", desired_bits+non_text_bits);
311 fflush(m_pFile);
313 VbrControl_set_quant(m_fQuant*m_vFrames[0].mult);
314 m_lEncodedBits=m_lExpectedBits=0;
315 return 0;
318 int VbrControl_get_intra()
320 return m_vFrames[m_iCount].is_key_frame;
323 short VbrControl_get_drop()
325 return m_bDrop;
328 int VbrControl_get_quant()
330 return m_iQuant;
333 void VbrControl_set_quant(float quant)
335 m_iQuant=quant;
336 if((rand() % 10)<((quant-m_iQuant) * 10))
337 m_iQuant++;
338 if(m_iQuant<min_quantizer) m_iQuant=min_quantizer;
339 if(m_iQuant>max_quantizer) m_iQuant=max_quantizer;
342 void VbrControl_update_1pass_vbr()
344 VbrControl_set_quant(m_fQuant);
345 m_iCount++;
348 void VbrControl_update_2pass_vbr_analysis(int is_key_frame, int motion_bits, int texture_bits, int total_bits, int quant)
350 if(!m_pFile)
351 return;
352 fprintf(m_pFile, "Frame %d: intra %d, quant %d, texture %d, motion %d, total %d\n",
353 m_iCount, is_key_frame, quant, texture_bits, motion_bits, total_bits);
354 m_iCount++;
357 void VbrControl_update_2pass_vbr_encoding(int motion_bits, int texture_bits, int total_bits)
359 double q;
360 double dq;
362 if(m_iCount>=iNumFrames)
363 return;
365 m_lExpectedBits+=(m_vFrames[m_iCount].total_bits-m_vFrames[m_iCount].text_bits)
366 + m_vFrames[m_iCount].text_bits*m_vFrames[m_iCount].quant/m_fQuant;
367 m_lEncodedBits+=(int64_t)total_bits;
369 if(m_pFile)
370 fprintf(m_pFile, "Frame %d: PRESENT, complexity %d, quant multiplier %f, texture %d, total %d ",
371 m_iCount, m_vFrames[m_iCount].text_bits*m_vFrames[m_iCount].quant,
372 m_vFrames[m_iCount].mult, texture_bits, total_bits);
374 m_iCount++;
376 q = m_fQuant * m_vFrames[m_iCount].mult;
377 if(q<m_fQuant+min_quant_delta) q=m_fQuant+min_quant_delta;
378 if(q>m_fQuant+max_quant_delta) q=m_fQuant+max_quant_delta;
380 dq = (double)m_lEncodedBits/(double)m_lExpectedBits;
381 dq*=dq;
382 if(dq<min_rc_quant_delta)
383 dq=min_rc_quant_delta;
384 if(dq>max_rc_quant_delta)
385 dq=max_rc_quant_delta;
386 if(m_iCount<20) // no framerate corrections in first frames
387 dq=1;
388 if(m_pFile)
389 fprintf(m_pFile, "Progress: expected %12lld, achieved %12lld, dq %f",
390 m_lExpectedBits, m_lEncodedBits, dq);
391 q *= dq;
392 VbrControl_set_quant(q);
393 if(m_pFile)
394 fprintf(m_pFile, ", new quant %d\n", m_iQuant);
397 void VbrControl_close()
399 if(m_pFile)
401 fclose(m_pFile);
402 m_pFile=NULL;
404 free(m_vFrames);