## ffmpeg / libavcodec / ratecontrol.c @ 57514323

History | View | Annotate | Download (14.1 KB)

1 | 8b4c7dbc | Michael Niedermayer | ```
/*
``` |
---|---|---|---|

2 | ```
Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at>
``` |
||

3 | |||

4 | ```
This program is free software; you can redistribute it and/or modify
``` |
||

5 | ```
it under the terms of the GNU General Public License as published by
``` |
||

6 | ```
the Free Software Foundation; either version 2 of the License, or
``` |
||

7 | ```
(at your option) any later version.
``` |
||

8 | |||

9 | ```
This program is distributed in the hope that it will be useful,
``` |
||

10 | ```
but WITHOUT ANY WARRANTY; without even the implied warranty of
``` |
||

11 | ```
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
``` |
||

12 | ```
GNU General Public License for more details.
``` |
||

13 | |||

14 | ```
You should have received a copy of the GNU General Public License
``` |
||

15 | ```
along with this program; if not, write to the Free Software
``` |
||

16 | ```
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
``` |
||

17 | ```
*/
``` |
||

18 | |||

19 | #include <inttypes.h> |
||

20 | #include <stdio.h> |
||

21 | |||

22 | #include "common.h" //needed for mpegvideo.h to compile |
||

23 | #include "dsputil.h" //needed for mpegvideo.h to compile |
||

24 | #include "avcodec.h" |
||

25 | #include "mpegvideo.h" |
||

26 | |||

27 | #define STATS_FILE "lavc_stats.txt" |
||

28 | |||

29 | static int init_pass2(MpegEncContext *s); |
||

30 | |||

31 | ```
void ff_write_pass1_stats(MpegEncContext *s){
``` |
||

32 | RateControlContext *rcc= &s->rc_context; |
||

33 | ```
// fprintf(c->stats_file, "type:%d q:%d icount:%d pcount:%d scount:%d itex:%d ptex%d mv:%d misc:%d fcode:%d bcode:%d\")
``` |
||

34 | ```
fprintf(rcc->stats_file, "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d\n",
``` |
||

35 | s->picture_number, s->input_picture_number - s->max_b_frames, s->pict_type, |
||

36 | s->qscale, s->i_tex_bits, s->p_tex_bits, s->mv_bits, s->misc_bits, s->f_code, s->b_code); |
||

37 | } |
||

38 | |||

39 | ```
int ff_rate_control_init(MpegEncContext *s)
``` |
||

40 | { |
||

41 | RateControlContext *rcc= &s->rc_context; |
||

42 | emms_c(); |
||

43 | |||

44 | ```
if(s->flags&CODEC_FLAG_PASS1){
``` |
||

45 | ```
rcc->stats_file= fopen(STATS_FILE, "w");
``` |
||

46 | ```
if(!rcc->stats_file){
``` |
||

47 | fprintf(stderr, "failed to open " STATS_FILE "\n"); |
||

48 | return -1; |
||

49 | } |
||

50 | } else if(s->flags&CODEC_FLAG_PASS2){ |
||

51 | ```
int size;
``` |
||

52 | ```
int i;
``` |
||

53 | |||

54 | ```
rcc->stats_file= fopen(STATS_FILE, "r");
``` |
||

55 | ```
if(!rcc->stats_file){
``` |
||

56 | fprintf(stderr, "failed to open " STATS_FILE "\n"); |
||

57 | return -1; |
||

58 | } |
||

59 | |||

60 | ```
/* find number of pics without reading the file twice :) */
``` |
||

61 | ```
fseek(rcc->stats_file, 0, SEEK_END);
``` |
||

62 | size= ftell(rcc->stats_file); |
||

63 | ```
fseek(rcc->stats_file, 0, SEEK_SET);
``` |
||

64 | |||

65 | size/= 64; // we need at least 64 byte to store a line ... |
||

66 | ```
rcc->entry = (RateControlEntry*)av_mallocz(size*sizeof(RateControlEntry));
``` |
||

67 | |||

68 | for(i=0; !feof(rcc->stats_file); i++){ |
||

69 | RateControlEntry *rce; |
||

70 | ```
int picture_number;
``` |
||

71 | ```
int e;
``` |
||

72 | |||

73 | ```
e= fscanf(rcc->stats_file, "in:%d ", &picture_number);
``` |
||

74 | rce= &rcc->entry[picture_number]; |
||

75 | ```
e+=fscanf(rcc->stats_file, "out:%*d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d fcode:%*d bcode:%*d\n",
``` |
||

76 | &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits, &rce->mv_bits, &rce->misc_bits); |
||

77 | if(e!=7){ |
||

78 | ```
fprintf(stderr, STATS_FILE " is damaged\n");
``` |
||

79 | return -1; |
||

80 | } |
||

81 | } |
||

82 | rcc->num_entries= i; |
||

83 | |||

84 | if(init_pass2(s) < 0) return -1; |
||

85 | } |
||

86 | |||

87 | ```
/* no 2pass stuff, just normal 1-pass */
``` |
||

88 | ```
//initial values, they dont really matter as they will be totally different within a few frames
``` |
||

89 | s->i_pred.coeff= s->p_pred.coeff= 7.0; |
||

90 | s->i_pred.count= s->p_pred.count= 1.0; |
||

91 | |||

92 | s->i_pred.decay= s->p_pred.decay= 0.4; |
||

93 | |||

94 | ```
// use more bits at the beginning, otherwise high motion at the begin will look like shit
``` |
||

95 | ```
s->qsum=100 * s->qmin;
``` |
||

96 | ```
s->qcount=100;
``` |
||

97 | |||

98 | s->short_term_qsum=0.001; |
||

99 | s->short_term_qcount=0.001; |
||

100 | |||

101 | return 0; |
||

102 | } |
||

103 | |||

104 | ```
void ff_rate_control_uninit(MpegEncContext *s)
``` |
||

105 | { |
||

106 | RateControlContext *rcc= &s->rc_context; |
||

107 | emms_c(); |
||

108 | |||

109 | ```
if(rcc->stats_file) fclose(rcc->stats_file);
``` |
||

110 | ```
if(rcc->entry) free(rcc->entry);
``` |
||

111 | ```
rcc->stats_file= NULL;
``` |
||

112 | ```
rcc->entry= NULL;
``` |
||

113 | } |
||

114 | |||

115 | ```
//----------------------------------
``` |
||

116 | ```
// 1 Pass Code
``` |
||

117 | |||

118 | static double predict(Predictor *p, double q, double var) |
||

119 | { |
||

120 | ```
return p->coeff*var / (q*p->count);
``` |
||

121 | } |
||

122 | |||

123 | static void update_predictor(Predictor *p, double q, double var, double size) |
||

124 | { |
||

125 | double new_coeff= size*q / (var + 1); |
||

126 | if(var<1000) return; |
||

127 | |||

128 | p->count*= p->decay; |
||

129 | p->coeff*= p->decay; |
||

130 | p->count++; |
||

131 | p->coeff+= new_coeff; |
||

132 | } |
||

133 | |||

134 | ```
int ff_rate_estimate_qscale(MpegEncContext *s)
``` |
||

135 | { |
||

136 | ```
int qmin= s->qmin;
``` |
||

137 | ```
int qmax= s->qmax;
``` |
||

138 | int rate_q=5; |
||

139 | ```
float q;
``` |
||

140 | ```
int qscale;
``` |
||

141 | ```
float br_compensation;
``` |
||

142 | ```
double diff;
``` |
||

143 | ```
double short_term_q;
``` |
||

144 | ```
double long_term_q;
``` |
||

145 | ```
double fps;
``` |
||

146 | ```
int picture_number= s->input_picture_number - s->max_b_frames;
``` |
||

147 | int64_t wanted_bits; |
||

148 | emms_c(); |
||

149 | |||

150 | ```
fps= (double)s->frame_rate / FRAME_RATE_BASE;
``` |
||

151 | ```
wanted_bits= (uint64_t)(s->bit_rate*(double)picture_number/fps);
``` |
||

152 | ```
// printf("%d %d %d\n", picture_number, (int)wanted_bits, (int)s->total_bits);
``` |
||

153 | |||

154 | ```
if(s->pict_type==B_TYPE){
``` |
||

155 | qmin= (int)(qmin*s->b_quant_factor+0.5); |
||

156 | qmax= (int)(qmax*s->b_quant_factor+0.5); |
||

157 | } |
||

158 | if(qmin<2) qmin=2; |
||

159 | if(qmax>31) qmax=31; |
||

160 | ```
if(qmax<=qmin) qmax= qmin;
``` |
||

161 | |||

162 | ```
/* update predictors */
``` |
||

163 | if(picture_number>2){ |
||

164 | ```
if(s->pict_type!=B_TYPE && s->last_non_b_pict_type == P_TYPE){
``` |
||

165 | ```
//printf("%d %d %d %f\n", s->qscale, s->last_mc_mb_var, s->frame_bits, s->p_pred.coeff);
``` |
||

166 | update_predictor(&s->p_pred, s->last_non_b_qscale, s->last_non_b_mc_mb_var, s->pb_frame_bits); |
||

167 | } |
||

168 | } |
||

169 | |||

170 | ```
if(s->pict_type == I_TYPE){
``` |
||

171 | short_term_q= s->short_term_qsum/s->short_term_qcount; |
||

172 | |||

173 | long_term_q= s->qsum/s->qcount*(s->total_bits+1)/(wanted_bits+1); //+1 to avoid nan & 0 |
||

174 | |||

175 | q= 1/((1/long_term_q - 1/short_term_q)*s->qcompress + 1/short_term_q); |
||

176 | }else if(s->pict_type==B_TYPE){ |
||

177 | q= (int)(s->last_non_b_qscale*s->b_quant_factor+0.5); |
||

178 | }else{ //P Frame |
||

179 | ```
int i;
``` |
||

180 | int diff, best_diff=1000000000; |
||

181 | for(i=1; i<=31; i++){ |
||

182 | ```
diff= predict(&s->p_pred, i, s->mc_mb_var) - (double)s->bit_rate/fps;
``` |
||

183 | if(diff<0) diff= -diff; |
||

184 | ```
if(diff<best_diff){
``` |
||

185 | best_diff= diff; |
||

186 | rate_q= i; |
||

187 | } |
||

188 | } |
||

189 | s->short_term_qsum*=s->qblur; |
||

190 | s->short_term_qcount*=s->qblur; |
||

191 | |||

192 | s->short_term_qsum+= rate_q; |
||

193 | s->short_term_qcount++; |
||

194 | short_term_q= s->short_term_qsum/s->short_term_qcount; |
||

195 | |||

196 | long_term_q= s->qsum/s->qcount*(s->total_bits+1)/(wanted_bits+1); //+1 to avoid nan & 0 |
||

197 | |||

198 | ```
// q= (long_term_q - short_term_q)*s->qcompress + short_term_q;
``` |
||

199 | q= 1/((1/long_term_q - 1/short_term_q)*s->qcompress + 1/short_term_q); |
||

200 | } |
||

201 | |||

202 | diff= s->total_bits - wanted_bits; |
||

203 | br_compensation= (s->bit_rate_tolerance - diff)/s->bit_rate_tolerance; |
||

204 | if(br_compensation<=0.0) br_compensation=0.001; |
||

205 | q/=br_compensation; |
||

206 | ```
//printf("%f %f %f\n", q, br_compensation, short_term_q);
``` |
||

207 | qscale= (int)(q + 0.5); |
||

208 | ```
if (qscale<qmin) qscale=qmin;
``` |
||

209 | else if(qscale>qmax) qscale=qmax; |
||

210 | |||

211 | ```
if(s->pict_type!=B_TYPE){
``` |
||

212 | s->qsum+= qscale; |
||

213 | s->qcount++; |
||

214 | ```
if (qscale<s->last_non_b_qscale-s->max_qdiff) qscale=s->last_non_b_qscale-s->max_qdiff;
``` |
||

215 | else if(qscale>s->last_non_b_qscale+s->max_qdiff) qscale=s->last_non_b_qscale+s->max_qdiff; |
||

216 | } |
||

217 | ```
//printf("q:%d diff:%d comp:%f rate_q:%d st_q:%f fvar:%d last_size:%d\n", qscale, (int)diff, br_compensation,
``` |
||

218 | ```
// rate_q, short_term_q, s->mc_mb_var, s->frame_bits);
``` |
||

219 | ```
//printf("%d %d\n", s->bit_rate, (int)fps);
``` |
||

220 | ```
return qscale;
``` |
||

221 | } |
||

222 | |||

223 | ```
//----------------------------------------------
``` |
||

224 | ```
// 2-Pass code
``` |
||

225 | |||

226 | static int init_pass2(MpegEncContext *s) |
||

227 | { |
||

228 | RateControlContext *rcc= &s->rc_context; |
||

229 | ```
int i;
``` |
||

230 | double fps= (double)s->frame_rate / FRAME_RATE_BASE; |
||

231 | double complexity[5]={0,0,0,0,0}; // aproximate bits at quant=1 |
||

232 | double avg_quantizer[5]; |
||

233 | uint64_t const_bits[5]={0,0,0,0,0}; // quantizer idependant bits |
||

234 | ```
uint64_t available_bits[5];
``` |
||

235 | uint64_t all_const_bits; |
||

236 | ```
uint64_t all_available_bits= (uint64_t)(s->bit_rate*(double)rcc->num_entries/fps);
``` |
||

237 | int num_frames[5]={0,0,0,0,0}; |
||

238 | double rate_factor=0; |
||

239 | ```
double step;
``` |
||

240 | int last_i_frame=-10000000; |
||

241 | |||

242 | ```
/* find complexity & const_bits & decide the pict_types */
``` |
||

243 | for(i=0; i<rcc->num_entries; i++){ |
||

244 | RateControlEntry *rce= &rcc->entry[i]; |
||

245 | |||

246 | if(s->b_frame_strategy==0 || s->max_b_frames==0){ |
||

247 | rce->new_pict_type= rce->pict_type; |
||

248 | ```
}else{
``` |
||

249 | ```
int j;
``` |
||

250 | ```
int next_non_b_type=P_TYPE;
``` |
||

251 | |||

252 | ```
switch(rce->pict_type){
``` |
||

253 | ```
case I_TYPE:
``` |
||

254 | if(i-last_i_frame>s->gop_size/2){ //FIXME this is not optimal |
||

255 | rce->new_pict_type= I_TYPE; |
||

256 | last_i_frame= i; |
||

257 | ```
}else{
``` |
||

258 | ```
rce->new_pict_type= P_TYPE; // will be caught by the scene detection anyway
``` |
||

259 | } |
||

260 | ```
break;
``` |
||

261 | ```
case P_TYPE:
``` |
||

262 | rce->new_pict_type= P_TYPE; |
||

263 | ```
break;
``` |
||

264 | ```
case B_TYPE:
``` |
||

265 | for(j=i+1; j<i+s->max_b_frames+2 && j<rcc->num_entries; j++){ |
||

266 | ```
if(rcc->entry[j].pict_type != B_TYPE){
``` |
||

267 | next_non_b_type= rcc->entry[j].pict_type; |
||

268 | ```
break;
``` |
||

269 | } |
||

270 | } |
||

271 | ```
if(next_non_b_type==I_TYPE)
``` |
||

272 | rce->new_pict_type= P_TYPE; |
||

273 | ```
else
``` |
||

274 | rce->new_pict_type= B_TYPE; |
||

275 | ```
break;
``` |
||

276 | } |
||

277 | } |
||

278 | |||

279 | ```
complexity[rce->new_pict_type]+= (rce->i_tex_bits+ rce->p_tex_bits)*(double)rce->qscale;
``` |
||

280 | const_bits[rce->new_pict_type]+= rce->mv_bits + rce->misc_bits; |
||

281 | num_frames[rce->new_pict_type]++; |
||

282 | } |
||

283 | all_const_bits= const_bits[I_TYPE] + const_bits[P_TYPE] + const_bits[B_TYPE]; |
||

284 | |||

285 | ```
if(all_available_bits < all_const_bits){
``` |
||

286 | ```
fprintf(stderr, "requested bitrate is to low\n");
``` |
||

287 | return -1; |
||

288 | } |
||

289 | |||

290 | ```
// avg_complexity= complexity/rcc->num_entries;
``` |
||

291 | avg_quantizer[P_TYPE]= |
||

292 | avg_quantizer[I_TYPE]= (complexity[I_TYPE]+complexity[P_TYPE] + complexity[B_TYPE]/s->b_quant_factor) |
||

293 | / (all_available_bits - all_const_bits); |
||

294 | avg_quantizer[B_TYPE]= avg_quantizer[P_TYPE]*s->b_quant_factor; |
||

295 | ```
//printf("avg quantizer: %f %f\n", avg_quantizer[P_TYPE], avg_quantizer[B_TYPE]);
``` |
||

296 | |||

297 | for(i=0; i<5; i++){ |
||

298 | available_bits[i]= const_bits[i] + complexity[i]/avg_quantizer[i]; |
||

299 | } |
||

300 | ```
//printf("%lld %lld %lld %lld\n", available_bits[I_TYPE], available_bits[P_TYPE], available_bits[B_TYPE], all_available_bits);
``` |
||

301 | |||

302 | for(step=256*256; step>0.0000001; step*=0.5){ |
||

303 | ```
uint64_t expected_bits=0;
``` |
||

304 | rate_factor+= step; |
||

305 | ```
/* find qscale */
``` |
||

306 | for(i=0; i<rcc->num_entries; i++){ |
||

307 | RateControlEntry *rce= &rcc->entry[i]; |
||

308 | ```
double short_term_q, q, bits_left;
``` |
||

309 | const int pict_type= rce->new_pict_type; |
||

310 | ```
int qmin= s->qmin;
``` |
||

311 | ```
int qmax= s->qmax;
``` |
||

312 | |||

313 | ```
if(pict_type==B_TYPE){
``` |
||

314 | qmin= (int)(qmin*s->b_quant_factor+0.5); |
||

315 | qmax= (int)(qmax*s->b_quant_factor+0.5); |
||

316 | } |
||

317 | if(qmin<2) qmin=2; |
||

318 | if(qmax>31) qmax=31; |
||

319 | ```
if(qmax<=qmin) qmax= qmin;
``` |
||

320 | |||

321 | ```
switch(s->rc_strategy){
``` |
||

322 | case 0: |
||

323 | bits_left= available_bits[pict_type]/num_frames[pict_type]*rate_factor - rce->misc_bits - rce->mv_bits; |
||

324 | if(bits_left<1.0) bits_left=1.0; |
||

325 | short_term_q= rce->qscale*(rce->i_tex_bits + rce->p_tex_bits)/bits_left; |
||

326 | ```
break;
``` |
||

327 | case 1: |
||

328 | bits_left= (available_bits[pict_type] - const_bits[pict_type])/num_frames[pict_type]*rate_factor; |
||

329 | if(bits_left<1.0) bits_left=1.0; |
||

330 | short_term_q= rce->qscale*(rce->i_tex_bits + rce->p_tex_bits)/bits_left; |
||

331 | ```
break;
``` |
||

332 | case 2: |
||

333 | bits_left= available_bits[pict_type]/num_frames[pict_type]*rate_factor; |
||

334 | if(bits_left<1.0) bits_left=1.0; |
||

335 | short_term_q= rce->qscale*(rce->i_tex_bits + rce->p_tex_bits + rce->misc_bits + rce->mv_bits)/bits_left; |
||

336 | ```
break;
``` |
||

337 | ```
default:
``` |
||

338 | ```
fprintf(stderr, "unknown strategy\n");
``` |
||

339 | short_term_q=3; //gcc warning fix |
||

340 | } |
||

341 | |||

342 | if(short_term_q>31.0) short_term_q=31.0; |
||

343 | else if (short_term_q<1.0) short_term_q=1.0; |
||

344 | |||

345 | q= 1/((1/avg_quantizer[pict_type] - 1/short_term_q)*s->qcompress + 1/short_term_q); |
||

346 | ```
if (q<qmin) q=qmin;
``` |
||

347 | else if(q>qmax) q=qmax; |
||

348 | ```
//printf("lq:%f, sq:%f t:%f q:%f\n", avg_quantizer[rce->pict_type], short_term_q, bits_left, q);
``` |
||

349 | rce->new_qscale= q; |
||

350 | } |
||

351 | |||

352 | ```
/* smooth curve */
``` |
||

353 | |||

354 | ```
/* find expected bits */
``` |
||

355 | for(i=0; i<rcc->num_entries; i++){ |
||

356 | RateControlEntry *rce= &rcc->entry[i]; |
||

357 | ```
double factor= rce->qscale / rce->new_qscale;
``` |
||

358 | |||

359 | rce->expected_bits= expected_bits; |
||

360 | expected_bits += (int)(rce->misc_bits + rce->mv_bits + (rce->i_tex_bits + rce->p_tex_bits)*factor + 0.5); |
||

361 | } |
||

362 | |||

363 | ```
// printf("%d %d %f\n", (int)expected_bits, (int)all_available_bits, rate_factor);
``` |
||

364 | ```
if(expected_bits > all_available_bits) rate_factor-= step;
``` |
||

365 | } |
||

366 | |||

367 | return 0; |
||

368 | } |
||

369 | |||

370 | ```
int ff_rate_estimate_qscale_pass2(MpegEncContext *s)
``` |
||

371 | { |
||

372 | ```
int qmin= s->qmin;
``` |
||

373 | ```
int qmax= s->qmax;
``` |
||

374 | ```
float q;
``` |
||

375 | ```
int qscale;
``` |
||

376 | ```
float br_compensation;
``` |
||

377 | ```
double diff;
``` |
||

378 | ```
int picture_number= s->picture_number;
``` |
||

379 | RateControlEntry *rce= &s->rc_context.entry[picture_number]; |
||

380 | int64_t wanted_bits= rce->expected_bits; |
||

381 | emms_c(); |
||

382 | |||

383 | ```
// printf("%d %d %d\n", picture_number, (int)wanted_bits, (int)s->total_bits);
``` |
||

384 | |||

385 | ```
if(s->pict_type==B_TYPE){
``` |
||

386 | qmin= (int)(qmin*s->b_quant_factor+0.5); |
||

387 | qmax= (int)(qmax*s->b_quant_factor+0.5); |
||

388 | } |
||

389 | if(qmin<2) qmin=2; |
||

390 | if(qmax>31) qmax=31; |
||

391 | ```
if(qmax<=qmin) qmax= qmin;
``` |
||

392 | |||

393 | q= rce->new_qscale; |
||

394 | |||

395 | diff= s->total_bits - wanted_bits; |
||

396 | br_compensation= (s->bit_rate_tolerance - diff)/s->bit_rate_tolerance; |
||

397 | if(br_compensation<=0.0) br_compensation=0.001; |
||

398 | q/=br_compensation; |
||

399 | |||

400 | qscale= (int)(q + 0.5); |
||

401 | ```
if (qscale<qmin) qscale=qmin;
``` |
||

402 | else if(qscale>qmax) qscale=qmax; |
||

403 | ```
// printf("%d %d %d %d type:%d\n", qmin, qscale, qmax, picture_number, s->pict_type); fflush(stdout);
``` |
||

404 | ```
return qscale;
``` |
||

405 | } |