## ffmpeg / libavcodec / mpeg4videoenc.c @ 2912e87a

History | View | Annotate | Download (46.2 KB)

1 | ca334dd1 | Michael Niedermayer | ```
/*
``` |
---|---|---|---|

2 | ```
* MPEG4 encoder.
``` |
||

3 | ```
* Copyright (c) 2000,2001 Fabrice Bellard
``` |
||

4 | ```
* Copyright (c) 2002-2010 Michael Niedermayer <michaelni@gmx.at>
``` |
||

5 | ```
*
``` |
||

6 | 2912e87a | Mans Rullgard | ```
* This file is part of Libav.
``` |

7 | ca334dd1 | Michael Niedermayer | ```
*
``` |

8 | 2912e87a | Mans Rullgard | ```
* Libav is free software; you can redistribute it and/or
``` |

9 | ca334dd1 | Michael Niedermayer | ```
* modify it under the terms of the GNU Lesser General Public
``` |

10 | ```
* License as published by the Free Software Foundation; either
``` |
||

11 | ```
* version 2.1 of the License, or (at your option) any later version.
``` |
||

12 | ```
*
``` |
||

13 | 2912e87a | Mans Rullgard | ```
* Libav is distributed in the hope that it will be useful,
``` |

14 | ca334dd1 | Michael Niedermayer | ```
* but WITHOUT ANY WARRANTY; without even the implied warranty of
``` |

15 | ```
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
``` |
||

16 | ```
* Lesser General Public License for more details.
``` |
||

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

18 | ```
* You should have received a copy of the GNU Lesser General Public
``` |
||

19 | 2912e87a | Mans Rullgard | ```
* License along with Libav; if not, write to the Free Software
``` |

20 | ca334dd1 | Michael Niedermayer | ```
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
``` |

21 | ```
*/
``` |
||

22 | |||

23 | #include "mpegvideo.h" |
||

24 | #include "h263.h" |
||

25 | #include "mpeg4video.h" |
||

26 | |||

27 | ```
//The uni_DCtab_* tables below contain unified bits+length tables to encode DC
``` |
||

28 | ```
//differences in mpeg4. Unified in the sense that the specification specifies
``` |
||

29 | ```
//this encoding in several steps.
``` |
||

30 | static uint8_t uni_DCtab_lum_len[512]; |
||

31 | static uint8_t uni_DCtab_chrom_len[512]; |
||

32 | static uint16_t uni_DCtab_lum_bits[512]; |
||

33 | static uint16_t uni_DCtab_chrom_bits[512]; |
||

34 | |||

35 | ```
//unified encoding tables for run length encoding of coefficients
``` |
||

36 | ```
//unified in the sense that the specification specifies the encoding in several steps.
``` |
||

37 | static uint32_t uni_mpeg4_intra_rl_bits[64*64*2*2]; |
||

38 | static uint8_t uni_mpeg4_intra_rl_len [64*64*2*2]; |
||

39 | static uint32_t uni_mpeg4_inter_rl_bits[64*64*2*2]; |
||

40 | static uint8_t uni_mpeg4_inter_rl_len [64*64*2*2]; |
||

41 | ```
//#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128 + (run)*256 + (level))
``` |
||

42 | ```
//#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run) + (level)*64)
``` |
||

43 | #define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run)*128 + (level)) |
||

44 | |||

45 | ```
/* mpeg4
``` |
||

46 | ```
inter
``` |
||

47 | ```
max level: 24/6
``` |
||

48 | ```
max run: 53/63
``` |
||

49 | |||

50 | ```
intra
``` |
||

51 | ```
max level: 53/16
``` |
||

52 | ```
max run: 29/41
``` |
||

53 | ```
*/
``` |
||

54 | |||

55 | |||

56 | ```
/**
``` |
||

57 | 49bd8e4b | Måns Rullgård | ```
* Return the number of bits that encoding the 8x8 block in block would need.
``` |

58 | ca334dd1 | Michael Niedermayer | ```
* @param[in] block_last_index last index in scantable order that refers to a non zero element in block.
``` |

59 | ```
*/
``` |
||

60 | static inline int get_block_rate(MpegEncContext * s, DCTELEM block[64], int block_last_index, uint8_t scantable[64]){ |
||

61 | int last=0; |
||

62 | ```
int j;
``` |
||

63 | int rate=0; |
||

64 | |||

65 | for(j=1; j<=block_last_index; j++){ |
||

66 | const int index= scantable[j]; |
||

67 | ```
int level= block[index];
``` |
||

68 | ```
if(level){
``` |
||

69 | ```
level+= 64;
``` |
||

70 | if((level&(~127)) == 0){ |
||

71 | if(j<block_last_index) rate+= s->intra_ac_vlc_length [UNI_AC_ENC_INDEX(j-last-1, level)]; |
||

72 | else rate+= s->intra_ac_vlc_last_length[UNI_AC_ENC_INDEX(j-last-1, level)]; |
||

73 | ```
}else
``` |
||

74 | rate += s->ac_esc_length; |
||

75 | |||

76 | last= j; |
||

77 | } |
||

78 | } |
||

79 | |||

80 | ```
return rate;
``` |
||

81 | } |
||

82 | |||

83 | |||

84 | ```
/**
``` |
||

85 | 49bd8e4b | Måns Rullgård | ```
* Restore the ac coefficients in block that have been changed by decide_ac_pred().
``` |

86 | ca334dd1 | Michael Niedermayer | ```
* This function also restores s->block_last_index.
``` |

87 | ```
* @param[in,out] block MB coefficients, these will be restored
``` |
||

88 | ```
* @param[in] dir ac prediction direction for each 8x8 block
``` |
||

89 | ```
* @param[out] st scantable for each 8x8 block
``` |
||

90 | ```
* @param[in] zigzag_last_index index refering to the last non zero coefficient in zigzag order
``` |
||

91 | ```
*/
``` |
||

92 | static inline void restore_ac_coeffs(MpegEncContext * s, DCTELEM block[6][64], const int dir[6], uint8_t *st[6], const int zigzag_last_index[6]) |
||

93 | { |
||

94 | ```
int i, n;
``` |
||

95 | memcpy(s->block_last_index, zigzag_last_index, sizeof(int)*6); |
||

96 | |||

97 | for(n=0; n<6; n++){ |
||

98 | int16_t *ac_val = s->ac_val[0][0] + s->block_index[n] * 16; |
||

99 | |||

100 | st[n]= s->intra_scantable.permutated; |
||

101 | ```
if(dir[n]){
``` |
||

102 | ```
/* top prediction */
``` |
||

103 | for(i=1; i<8; i++){ |
||

104 | ```
block[n][s->dsp.idct_permutation[i ]] = ac_val[i+8];
``` |
||

105 | } |
||

106 | ```
}else{
``` |
||

107 | ```
/* left prediction */
``` |
||

108 | for(i=1; i<8; i++){ |
||

109 | ```
block[n][s->dsp.idct_permutation[i<<3]]= ac_val[i ];
``` |
||

110 | } |
||

111 | } |
||

112 | } |
||

113 | } |
||

114 | |||

115 | ```
/**
``` |
||

116 | 49bd8e4b | Måns Rullgård | ```
* Return the optimal value (0 or 1) for the ac_pred element for the given MB in mpeg4.
``` |

117 | ca334dd1 | Michael Niedermayer | ```
* This function will also update s->block_last_index and s->ac_val.
``` |

118 | ```
* @param[in,out] block MB coefficients, these will be updated if 1 is returned
``` |
||

119 | ```
* @param[in] dir ac prediction direction for each 8x8 block
``` |
||

120 | ```
* @param[out] st scantable for each 8x8 block
``` |
||

121 | ```
* @param[out] zigzag_last_index index refering to the last non zero coefficient in zigzag order
``` |
||

122 | ```
*/
``` |
||

123 | static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], const int dir[6], uint8_t *st[6], int zigzag_last_index[6]) |
||

124 | { |
||

125 | int score= 0; |
||

126 | ```
int i, n;
``` |
||

127 | ```
int8_t * const qscale_table= s->current_picture.qscale_table;
``` |
||

128 | |||

129 | memcpy(zigzag_last_index, s->block_last_index, sizeof(int)*6); |
||

130 | |||

131 | for(n=0; n<6; n++){ |
||

132 | int16_t *ac_val, *ac_val1; |
||

133 | |||

134 | score -= get_block_rate(s, block[n], s->block_last_index[n], s->intra_scantable.permutated); |
||

135 | |||

136 | ac_val = s->ac_val[0][0] + s->block_index[n] * 16; |
||

137 | ac_val1= ac_val; |
||

138 | ```
if(dir[n]){
``` |
||

139 | const int xy= s->mb_x + s->mb_y*s->mb_stride - s->mb_stride; |
||

140 | ```
/* top prediction */
``` |
||

141 | ```
ac_val-= s->block_wrap[n]*16;
``` |
||

142 | if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){ |
||

143 | ```
/* same qscale */
``` |
||

144 | for(i=1; i<8; i++){ |
||

145 | const int level= block[n][s->dsp.idct_permutation[i ]]; |
||

146 | ```
block[n][s->dsp.idct_permutation[i ]] = level - ac_val[i+8];
``` |
||

147 | ```
ac_val1[i ]= block[n][s->dsp.idct_permutation[i<<3]];
``` |
||

148 | ```
ac_val1[i+8]= level;
``` |
||

149 | } |
||

150 | ```
}else{
``` |
||

151 | ```
/* different qscale, we must rescale */
``` |
||

152 | for(i=1; i<8; i++){ |
||

153 | const int level= block[n][s->dsp.idct_permutation[i ]]; |
||

154 | ```
block[n][s->dsp.idct_permutation[i ]] = level - ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale);
``` |
||

155 | ```
ac_val1[i ]= block[n][s->dsp.idct_permutation[i<<3]];
``` |
||

156 | ```
ac_val1[i+8]= level;
``` |
||

157 | } |
||

158 | } |
||

159 | st[n]= s->intra_h_scantable.permutated; |
||

160 | ```
}else{
``` |
||

161 | const int xy= s->mb_x-1 + s->mb_y*s->mb_stride; |
||

162 | ```
/* left prediction */
``` |
||

163 | ```
ac_val-= 16;
``` |
||

164 | if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){ |
||

165 | ```
/* same qscale */
``` |
||

166 | for(i=1; i<8; i++){ |
||

167 | const int level= block[n][s->dsp.idct_permutation[i<<3]]; |
||

168 | ```
block[n][s->dsp.idct_permutation[i<<3]]= level - ac_val[i];
``` |
||

169 | ac_val1[i ]= level; |
||

170 | ```
ac_val1[i+8]= block[n][s->dsp.idct_permutation[i ]];
``` |
||

171 | } |
||

172 | ```
}else{
``` |
||

173 | ```
/* different qscale, we must rescale */
``` |
||

174 | for(i=1; i<8; i++){ |
||

175 | const int level= block[n][s->dsp.idct_permutation[i<<3]]; |
||

176 | ```
block[n][s->dsp.idct_permutation[i<<3]]= level - ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale);
``` |
||

177 | ac_val1[i ]= level; |
||

178 | ```
ac_val1[i+8]= block[n][s->dsp.idct_permutation[i ]];
``` |
||

179 | } |
||

180 | } |
||

181 | st[n]= s->intra_v_scantable.permutated; |
||

182 | } |
||

183 | |||

184 | for(i=63; i>0; i--) //FIXME optimize |
||

185 | if(block[n][ st[n][i] ]) break; |
||

186 | s->block_last_index[n]= i; |
||

187 | |||

188 | score += get_block_rate(s, block[n], s->block_last_index[n], st[n]); |
||

189 | } |
||

190 | |||

191 | if(score < 0){ |
||

192 | return 1; |
||

193 | ```
}else{
``` |
||

194 | restore_ac_coeffs(s, block, dir, st, zigzag_last_index); |
||

195 | return 0; |
||

196 | } |
||

197 | } |
||

198 | |||

199 | ```
/**
``` |
||

200 | ```
* modify mb_type & qscale so that encoding is acually possible in mpeg4
``` |
||

201 | ```
*/
``` |
||

202 | ```
void ff_clean_mpeg4_qscales(MpegEncContext *s){
``` |
||

203 | ```
int i;
``` |
||

204 | ```
int8_t * const qscale_table= s->current_picture.qscale_table;
``` |
||

205 | |||

206 | ff_clean_h263_qscales(s); |
||

207 | |||

208 | ```
if(s->pict_type== FF_B_TYPE){
``` |
||

209 | int odd=0; |
||

210 | ```
/* ok, come on, this isn't funny anymore, there's more code for handling this mpeg4 mess than for the actual adaptive quantization */
``` |
||

211 | |||

212 | for(i=0; i<s->mb_num; i++){ |
||

213 | ```
int mb_xy= s->mb_index2xy[i];
``` |
||

214 | ```
odd += qscale_table[mb_xy]&1;
``` |
||

215 | } |
||

216 | |||

217 | if(2*odd > s->mb_num) odd=1; |
||

218 | else odd=0; |
||

219 | |||

220 | for(i=0; i<s->mb_num; i++){ |
||

221 | ```
int mb_xy= s->mb_index2xy[i];
``` |
||

222 | if((qscale_table[mb_xy]&1) != odd) |
||

223 | qscale_table[mb_xy]++; |
||

224 | if(qscale_table[mb_xy] > 31) |
||

225 | ```
qscale_table[mb_xy]= 31;
``` |
||

226 | } |
||

227 | |||

228 | for(i=1; i<s->mb_num; i++){ |
||

229 | ```
int mb_xy= s->mb_index2xy[i];
``` |
||

230 | if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_DIRECT)){ |
||

231 | s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_BIDIR; |
||

232 | } |
||

233 | } |
||

234 | } |
||

235 | } |
||

236 | |||

237 | |||

238 | ```
/**
``` |
||

239 | ```
* encodes the dc value.
``` |
||

240 | ```
* @param n block index (0-3 are luma, 4-5 are chroma)
``` |
||

241 | ```
*/
``` |
||

242 | static inline void mpeg4_encode_dc(PutBitContext * s, int level, int n) |
||

243 | { |
||

244 | #if 1 |
||

245 | 49d2d1c3 | Diego Biurrun | ```
/* DC will overflow if level is outside the [-255,255] range. */
``` |

246 | ca334dd1 | Michael Niedermayer | ```
level+=256;
``` |

247 | if (n < 4) { |
||

248 | ```
/* luminance */
``` |
||

249 | put_bits(s, uni_DCtab_lum_len[level], uni_DCtab_lum_bits[level]); |
||

250 | ```
} else {
``` |
||

251 | ```
/* chrominance */
``` |
||

252 | put_bits(s, uni_DCtab_chrom_len[level], uni_DCtab_chrom_bits[level]); |
||

253 | } |
||

254 | ```
#else
``` |
||

255 | ```
int size, v;
``` |
||

256 | ```
/* find number of bits */
``` |
||

257 | ```
size = 0;
``` |
||

258 | v = abs(level); |
||

259 | ```
while (v) {
``` |
||

260 | ```
v >>= 1;
``` |
||

261 | size++; |
||

262 | } |
||

263 | |||

264 | if (n < 4) { |
||

265 | ```
/* luminance */
``` |
||

266 | 05b858b0 | Michael Niedermayer | put_bits(&s->pb, ff_mpeg4_DCtab_lum[size][1], ff_mpeg4_DCtab_lum[size][0]); |

267 | ca334dd1 | Michael Niedermayer | ```
} else {
``` |

268 | ```
/* chrominance */
``` |
||

269 | 05b858b0 | Michael Niedermayer | put_bits(&s->pb, ff_mpeg4_DCtab_chrom[size][1], ff_mpeg4_DCtab_chrom[size][0]); |

270 | ca334dd1 | Michael Niedermayer | } |

271 | |||

272 | ```
/* encode remaining bits */
``` |
||

273 | if (size > 0) { |
||

274 | if (level < 0) |
||

275 | level = (-level) ^ ((1 << size) - 1); |
||

276 | put_bits(&s->pb, size, level); |
||

277 | if (size > 8) |
||

278 | put_bits(&s->pb, 1, 1); |
||

279 | } |
||

280 | ```
#endif
``` |
||

281 | } |
||

282 | |||

283 | static inline int mpeg4_get_dc_length(int level, int n){ |
||

284 | if (n < 4) { |
||

285 | return uni_DCtab_lum_len[level + 256]; |
||

286 | ```
} else {
``` |
||

287 | return uni_DCtab_chrom_len[level + 256]; |
||

288 | } |
||

289 | } |
||

290 | |||

291 | ```
/**
``` |
||

292 | ```
* encodes a 8x8 block
``` |
||

293 | ```
* @param n block index (0-3 are luma, 4-5 are chroma)
``` |
||

294 | ```
*/
``` |
||

295 | static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, |
||

296 | uint8_t *scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb) |
||

297 | { |
||

298 | ```
int i, last_non_zero;
``` |
||

299 | ```
#if 0 //variables for the outcommented version
``` |
||

300 | ```
int code, sign, last;
``` |
||

301 | ```
#endif
``` |
||

302 | ```
const RLTable *rl;
``` |
||

303 | uint32_t *bits_tab; |
||

304 | uint8_t *len_tab; |
||

305 | const int last_index = s->block_last_index[n]; |
||

306 | |||

307 | if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away |
||

308 | ```
/* mpeg4 based DC predictor */
``` |
||

309 | mpeg4_encode_dc(dc_pb, intra_dc, n); |
||

310 | if(last_index<1) return; |
||

311 | ```
i = 1;
``` |
||

312 | fef59a5b | Michael Niedermayer | rl = &ff_mpeg4_rl_intra; |

313 | ca334dd1 | Michael Niedermayer | bits_tab= uni_mpeg4_intra_rl_bits; |

314 | len_tab = uni_mpeg4_intra_rl_len; |
||

315 | ```
} else {
``` |
||

316 | if(last_index<0) return; |
||

317 | ```
i = 0;
``` |
||

318 | 101ada9a | Michael Niedermayer | rl = &ff_h263_rl_inter; |

319 | ca334dd1 | Michael Niedermayer | bits_tab= uni_mpeg4_inter_rl_bits; |

320 | len_tab = uni_mpeg4_inter_rl_len; |
||

321 | } |
||

322 | |||

323 | ```
/* AC coefs */
``` |
||

324 | ```
last_non_zero = i - 1;
``` |
||

325 | #if 1 |
||

326 | ```
for (; i < last_index; i++) {
``` |
||

327 | ```
int level = block[ scan_table[i] ];
``` |
||

328 | ```
if (level) {
``` |
||

329 | int run = i - last_non_zero - 1; |
||

330 | ```
level+=64;
``` |
||

331 | if((level&(~127)) == 0){ |
||

332 | const int index= UNI_MPEG4_ENC_INDEX(0, run, level); |
||

333 | put_bits(ac_pb, len_tab[index], bits_tab[index]); |
||

334 | }else{ //ESC3 |
||

335 | put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(0<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1); |
||

336 | } |
||

337 | last_non_zero = i; |
||

338 | } |
||

339 | } |
||

340 | ```
/*if(i<=last_index)*/{
``` |
||

341 | ```
int level = block[ scan_table[i] ];
``` |
||

342 | int run = i - last_non_zero - 1; |
||

343 | ```
level+=64;
``` |
||

344 | if((level&(~127)) == 0){ |
||

345 | const int index= UNI_MPEG4_ENC_INDEX(1, run, level); |
||

346 | put_bits(ac_pb, len_tab[index], bits_tab[index]); |
||

347 | }else{ //ESC3 |
||

348 | put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(1<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1); |
||

349 | } |
||

350 | } |
||

351 | ```
#else
``` |
||

352 | ```
for (; i <= last_index; i++) {
``` |
||

353 | const int slevel = block[ scan_table[i] ]; |
||

354 | ```
if (slevel) {
``` |
||

355 | ```
int level;
``` |
||

356 | int run = i - last_non_zero - 1; |
||

357 | last = (i == last_index); |
||

358 | ```
sign = 0;
``` |
||

359 | level = slevel; |
||

360 | if (level < 0) { |
||

361 | ```
sign = 1;
``` |
||

362 | level = -level; |
||

363 | } |
||

364 | code = get_rl_index(rl, last, run, level); |
||

365 | put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); |
||

366 | ```
if (code == rl->n) {
``` |
||

367 | ```
int level1, run1;
``` |
||

368 | level1 = level - rl->max_level[last][run]; |
||

369 | if (level1 < 1) |
||

370 | ```
goto esc2;
``` |
||

371 | code = get_rl_index(rl, last, run, level1); |
||

372 | ```
if (code == rl->n) {
``` |
||

373 | ```
esc2:
``` |
||

374 | put_bits(ac_pb, 1, 1); |
||

375 | ```
if (level > MAX_LEVEL)
``` |
||

376 | ```
goto esc3;
``` |
||

377 | ```
run1 = run - rl->max_run[last][level] - 1;
``` |
||

378 | if (run1 < 0) |
||

379 | ```
goto esc3;
``` |
||

380 | code = get_rl_index(rl, last, run1, level); |
||

381 | ```
if (code == rl->n) {
``` |
||

382 | ```
esc3:
``` |
||

383 | ```
/* third escape */
``` |
||

384 | put_bits(ac_pb, 1, 1); |
||

385 | ```
put_bits(ac_pb, 1, last);
``` |
||

386 | ```
put_bits(ac_pb, 6, run);
``` |
||

387 | put_bits(ac_pb, 1, 1); |
||

388 | ```
put_sbits(ac_pb, 12, slevel);
``` |
||

389 | put_bits(ac_pb, 1, 1); |
||

390 | ```
} else {
``` |
||

391 | ```
/* second escape */
``` |
||

392 | put_bits(ac_pb, 1, 0); |
||

393 | put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); |
||

394 | ```
put_bits(ac_pb, 1, sign);
``` |
||

395 | } |
||

396 | ```
} else {
``` |
||

397 | ```
/* first escape */
``` |
||

398 | put_bits(ac_pb, 1, 0); |
||

399 | put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); |
||

400 | ```
put_bits(ac_pb, 1, sign);
``` |
||

401 | } |
||

402 | ```
} else {
``` |
||

403 | ```
put_bits(ac_pb, 1, sign);
``` |
||

404 | } |
||

405 | last_non_zero = i; |
||

406 | } |
||

407 | } |
||

408 | ```
#endif
``` |
||

409 | } |
||

410 | |||

411 | static int mpeg4_get_block_length(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, |
||

412 | uint8_t *scan_table) |
||

413 | { |
||

414 | ```
int i, last_non_zero;
``` |
||

415 | uint8_t *len_tab; |
||

416 | const int last_index = s->block_last_index[n]; |
||

417 | int len=0; |
||

418 | |||

419 | if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away |
||

420 | ```
/* mpeg4 based DC predictor */
``` |
||

421 | len += mpeg4_get_dc_length(intra_dc, n); |
||

422 | if(last_index<1) return len; |
||

423 | ```
i = 1;
``` |
||

424 | len_tab = uni_mpeg4_intra_rl_len; |
||

425 | ```
} else {
``` |
||

426 | if(last_index<0) return 0; |
||

427 | ```
i = 0;
``` |
||

428 | len_tab = uni_mpeg4_inter_rl_len; |
||

429 | } |
||

430 | |||

431 | ```
/* AC coefs */
``` |
||

432 | ```
last_non_zero = i - 1;
``` |
||

433 | ```
for (; i < last_index; i++) {
``` |
||

434 | ```
int level = block[ scan_table[i] ];
``` |
||

435 | ```
if (level) {
``` |
||

436 | int run = i - last_non_zero - 1; |
||

437 | ```
level+=64;
``` |
||

438 | if((level&(~127)) == 0){ |
||

439 | const int index= UNI_MPEG4_ENC_INDEX(0, run, level); |
||

440 | len += len_tab[index]; |
||

441 | }else{ //ESC3 |
||

442 | len += 7+2+1+6+1+12+1; |
||

443 | } |
||

444 | last_non_zero = i; |
||

445 | } |
||

446 | } |
||

447 | ```
/*if(i<=last_index)*/{
``` |
||

448 | ```
int level = block[ scan_table[i] ];
``` |
||

449 | int run = i - last_non_zero - 1; |
||

450 | ```
level+=64;
``` |
||

451 | if((level&(~127)) == 0){ |
||

452 | const int index= UNI_MPEG4_ENC_INDEX(1, run, level); |
||

453 | len += len_tab[index]; |
||

454 | }else{ //ESC3 |
||

455 | len += 7+2+1+6+1+12+1; |
||

456 | } |
||

457 | } |
||

458 | |||

459 | ```
return len;
``` |
||

460 | } |
||

461 | |||

462 | static inline void mpeg4_encode_blocks(MpegEncContext * s, DCTELEM block[6][64], int intra_dc[6], |
||

463 | uint8_t **scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb){ |
||

464 | ```
int i;
``` |
||

465 | |||

466 | ```
if(scan_table){
``` |
||

467 | ```
if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){
``` |
||

468 | for (i = 0; i < 6; i++) { |
||

469 | skip_put_bits(&s->pb, mpeg4_get_block_length(s, block[i], i, intra_dc[i], scan_table[i])); |
||

470 | } |
||

471 | ```
}else{
``` |
||

472 | ```
/* encode each block */
``` |
||

473 | for (i = 0; i < 6; i++) { |
||

474 | mpeg4_encode_block(s, block[i], i, intra_dc[i], scan_table[i], dc_pb, ac_pb); |
||

475 | } |
||

476 | } |
||

477 | ```
}else{
``` |
||

478 | ```
if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){
``` |
||

479 | for (i = 0; i < 6; i++) { |
||

480 | ```
skip_put_bits(&s->pb, mpeg4_get_block_length(s, block[i], i, 0, s->intra_scantable.permutated));
``` |
||

481 | } |
||

482 | ```
}else{
``` |
||

483 | ```
/* encode each block */
``` |
||

484 | for (i = 0; i < 6; i++) { |
||

485 | ```
mpeg4_encode_block(s, block[i], i, 0, s->intra_scantable.permutated, dc_pb, ac_pb);
``` |
||

486 | } |
||

487 | } |
||

488 | } |
||

489 | } |
||

490 | |||

491 | ```
//FIXME this is duplicated to h263.c
``` |
||

492 | static const int dquant_code[5]= {1,0,9,2,3}; |
||

493 | |||

494 | ```
void mpeg4_encode_mb(MpegEncContext * s,
``` |
||

495 | DCTELEM block[6][64], |
||

496 | int motion_x, int motion_y) |
||

497 | { |
||

498 | ```
int cbpc, cbpy, pred_x, pred_y;
``` |
||

499 | ```
PutBitContext * const pb2 = s->data_partitioning ? &s->pb2 : &s->pb;
``` |
||

500 | ```
PutBitContext * const tex_pb = s->data_partitioning && s->pict_type!=FF_B_TYPE ? &s->tex_pb : &s->pb;
``` |
||

501 | ```
PutBitContext * const dc_pb = s->data_partitioning && s->pict_type!=FF_I_TYPE ? &s->pb2 : &s->pb;
``` |
||

502 | const int interleaved_stats= (s->flags&CODEC_FLAG_PASS1) && !s->data_partitioning ? 1 : 0; |
||

503 | |||

504 | ```
if (!s->mb_intra) {
``` |
||

505 | ```
int i, cbp;
``` |
||

506 | |||

507 | ```
if(s->pict_type==FF_B_TYPE){
``` |
||

508 | static const int mb_type_table[8]= {-1, 3, 2, 1,-1,-1,-1, 0}; /* convert from mv_dir to type */ |
||

509 | ```
int mb_type= mb_type_table[s->mv_dir];
``` |
||

510 | |||

511 | if(s->mb_x==0){ |
||

512 | for(i=0; i<2; i++){ |
||

513 | s->last_mv[i][0][0]= |
||

514 | s->last_mv[i][0][1]= |
||

515 | s->last_mv[i][1][0]= |
||

516 | s->last_mv[i][1][1]= 0; |
||

517 | } |
||

518 | } |
||

519 | |||

520 | assert(s->dquant>=-2 && s->dquant<=2); |
||

521 | assert((s->dquant&1)==0); |
||

522 | ```
assert(mb_type>=0);
``` |
||

523 | |||

524 | ```
/* nothing to do if this MB was skipped in the next P Frame */
``` |
||

525 | if(s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]){ //FIXME avoid DCT & ... |
||

526 | s->skip_count++; |
||

527 | s->mv[0][0][0]= |
||

528 | s->mv[0][0][1]= |
||

529 | s->mv[1][0][0]= |
||

530 | s->mv[1][0][1]= 0; |
||

531 | ```
s->mv_dir= MV_DIR_FORWARD; //doesn't matter
``` |
||

532 | s->qscale -= s->dquant; |
||

533 | ```
// s->mb_skipped=1;
``` |
||

534 | |||

535 | ```
return;
``` |
||

536 | } |
||

537 | |||

538 | cbp= get_b_cbp(s, block, motion_x, motion_y, mb_type); |
||

539 | |||

540 | if ((cbp | motion_x | motion_y | mb_type) ==0) { |
||

541 | ```
/* direct MB with MV={0,0} */
``` |
||

542 | ```
assert(s->dquant==0);
``` |
||

543 | |||

544 | put_bits(&s->pb, 1, 1); /* mb not coded modb1=1 */ |
||

545 | |||

546 | ```
if(interleaved_stats){
``` |
||

547 | s->misc_bits++; |
||

548 | s->last_bits++; |
||

549 | } |
||

550 | s->skip_count++; |
||

551 | ```
return;
``` |
||

552 | } |
||

553 | |||

554 | put_bits(&s->pb, 1, 0); /* mb coded modb1=0 */ |
||

555 | put_bits(&s->pb, 1, cbp ? 0 : 1); /* modb2 */ //FIXME merge |
||

556 | put_bits(&s->pb, mb_type+1, 1); // this table is so simple that we don't need it :) |
||

557 | if(cbp) put_bits(&s->pb, 6, cbp); |
||

558 | |||

559 | ```
if(cbp && mb_type){
``` |
||

560 | ```
if(s->dquant)
``` |
||

561 | put_bits(&s->pb, 2, (s->dquant>>2)+3); |
||

562 | ```
else
``` |
||

563 | put_bits(&s->pb, 1, 0); |
||

564 | ```
}else
``` |
||

565 | s->qscale -= s->dquant; |
||

566 | |||

567 | ```
if(!s->progressive_sequence){
``` |
||

568 | ```
if(cbp)
``` |
||

569 | ```
put_bits(&s->pb, 1, s->interlaced_dct);
``` |
||

570 | if(mb_type) // not direct mode |
||

571 | ```
put_bits(&s->pb, 1, s->mv_type == MV_TYPE_FIELD);
``` |
||

572 | } |
||

573 | |||

574 | ```
if(interleaved_stats){
``` |
||

575 | s->misc_bits+= get_bits_diff(s); |
||

576 | } |
||

577 | |||

578 | if(mb_type == 0){ |
||

579 | assert(s->mv_dir & MV_DIRECT); |
||

580 | ```
ff_h263_encode_motion_vector(s, motion_x, motion_y, 1);
``` |
||

581 | s->b_count++; |
||

582 | s->f_count++; |
||

583 | ```
}else{
``` |
||

584 | assert(mb_type > 0 && mb_type < 4); |
||

585 | ```
if(s->mv_type != MV_TYPE_FIELD){
``` |
||

586 | ```
if(s->mv_dir & MV_DIR_FORWARD){
``` |
||

587 | ff_h263_encode_motion_vector(s, s->mv[0][0][0] - s->last_mv[0][0][0], |
||

588 | s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); |
||

589 | s->last_mv[0][0][0]= s->last_mv[0][1][0]= s->mv[0][0][0]; |
||

590 | s->last_mv[0][0][1]= s->last_mv[0][1][1]= s->mv[0][0][1]; |
||

591 | s->f_count++; |
||

592 | } |
||

593 | ```
if(s->mv_dir & MV_DIR_BACKWARD){
``` |
||

594 | ff_h263_encode_motion_vector(s, s->mv[1][0][0] - s->last_mv[1][0][0], |
||

595 | s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); |
||

596 | s->last_mv[1][0][0]= s->last_mv[1][1][0]= s->mv[1][0][0]; |
||

597 | s->last_mv[1][0][1]= s->last_mv[1][1][1]= s->mv[1][0][1]; |
||

598 | s->b_count++; |
||

599 | } |
||

600 | ```
}else{
``` |
||

601 | ```
if(s->mv_dir & MV_DIR_FORWARD){
``` |
||

602 | put_bits(&s->pb, 1, s->field_select[0][0]); |
||

603 | put_bits(&s->pb, 1, s->field_select[0][1]); |
||

604 | } |
||

605 | ```
if(s->mv_dir & MV_DIR_BACKWARD){
``` |
||

606 | put_bits(&s->pb, 1, s->field_select[1][0]); |
||

607 | put_bits(&s->pb, 1, s->field_select[1][1]); |
||

608 | } |
||

609 | ```
if(s->mv_dir & MV_DIR_FORWARD){
``` |
||

610 | for(i=0; i<2; i++){ |
||

611 | ff_h263_encode_motion_vector(s, s->mv[0][i][0] - s->last_mv[0][i][0] , |
||

612 | s->mv[0][i][1] - s->last_mv[0][i][1]/2, s->f_code); |
||

613 | s->last_mv[0][i][0]= s->mv[0][i][0]; |
||

614 | s->last_mv[0][i][1]= s->mv[0][i][1]*2; |
||

615 | } |
||

616 | s->f_count++; |
||

617 | } |
||

618 | ```
if(s->mv_dir & MV_DIR_BACKWARD){
``` |
||

619 | for(i=0; i<2; i++){ |
||

620 | ff_h263_encode_motion_vector(s, s->mv[1][i][0] - s->last_mv[1][i][0] , |
||

621 | s->mv[1][i][1] - s->last_mv[1][i][1]/2, s->b_code); |
||

622 | s->last_mv[1][i][0]= s->mv[1][i][0]; |
||

623 | s->last_mv[1][i][1]= s->mv[1][i][1]*2; |
||

624 | } |
||

625 | s->b_count++; |
||

626 | } |
||

627 | } |
||

628 | } |
||

629 | |||

630 | ```
if(interleaved_stats){
``` |
||

631 | s->mv_bits+= get_bits_diff(s); |
||

632 | } |
||

633 | |||

634 | mpeg4_encode_blocks(s, block, NULL, NULL, NULL, &s->pb); |
||

635 | |||

636 | ```
if(interleaved_stats){
``` |
||

637 | s->p_tex_bits+= get_bits_diff(s); |
||

638 | } |
||

639 | |||

640 | }else{ /* s->pict_type==FF_B_TYPE */ |
||

641 | cbp= get_p_cbp(s, block, motion_x, motion_y); |
||

642 | |||

643 | if ((cbp | motion_x | motion_y | s->dquant) == 0 && s->mv_type==MV_TYPE_16X16) { |
||

644 | ```
/* check if the B frames can skip it too, as we must skip it if we skip here
``` |
||

645 | ```
why didn't they just compress the skip-mb bits instead of reusing them ?! */
``` |
||

646 | if(s->max_b_frames>0){ |
||

647 | ```
int i;
``` |
||

648 | ```
int x,y, offset;
``` |
||

649 | uint8_t *p_pic; |
||

650 | |||

651 | ```
x= s->mb_x*16;
``` |
||

652 | ```
y= s->mb_y*16;
``` |
||

653 | if(x+16 > s->width) x= s->width-16; |
||

654 | if(y+16 > s->height) y= s->height-16; |
||

655 | |||

656 | offset= x + y*s->linesize; |
||

657 | ```
p_pic= s->new_picture.data[0] + offset;
``` |
||

658 | |||

659 | ```
s->mb_skipped=1;
``` |
||

660 | for(i=0; i<s->max_b_frames; i++){ |
||

661 | uint8_t *b_pic; |
||

662 | ```
int diff;
``` |
||

663 | ```
Picture *pic= s->reordered_input_picture[i+1];
``` |
||

664 | |||

665 | if(pic==NULL || pic->pict_type!=FF_B_TYPE) break; |
||

666 | |||

667 | ```
b_pic= pic->data[0] + offset;
``` |
||

668 | ```
if(pic->type != FF_BUFFER_TYPE_SHARED)
``` |
||

669 | b_pic+= INPLACE_OFFSET; |
||

670 | diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16); |
||

671 | if(diff>s->qscale*70){ //FIXME check that 70 is optimal |
||

672 | ```
s->mb_skipped=0;
``` |
||

673 | ```
break;
``` |
||

674 | } |
||

675 | } |
||

676 | ```
}else
``` |
||

677 | ```
s->mb_skipped=1;
``` |
||

678 | |||

679 | if(s->mb_skipped==1){ |
||

680 | ```
/* skip macroblock */
``` |
||

681 | put_bits(&s->pb, 1, 1); |
||

682 | |||

683 | ```
if(interleaved_stats){
``` |
||

684 | s->misc_bits++; |
||

685 | s->last_bits++; |
||

686 | } |
||

687 | s->skip_count++; |
||

688 | |||

689 | ```
return;
``` |
||

690 | } |
||

691 | } |
||

692 | |||

693 | put_bits(&s->pb, 1, 0); /* mb coded */ |
||

694 | ```
cbpc = cbp & 3;
``` |
||

695 | ```
cbpy = cbp >> 2;
``` |
||

696 | ```
cbpy ^= 0xf;
``` |
||

697 | ```
if(s->mv_type==MV_TYPE_16X16){
``` |
||

698 | if(s->dquant) cbpc+= 8; |
||

699 | put_bits(&s->pb, |
||

700 | 101ada9a | Michael Niedermayer | ff_h263_inter_MCBPC_bits[cbpc], |

701 | ff_h263_inter_MCBPC_code[cbpc]); |
||

702 | ca334dd1 | Michael Niedermayer | |

703 | 101ada9a | Michael Niedermayer | put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]); |

704 | ca334dd1 | Michael Niedermayer | ```
if(s->dquant)
``` |

705 | put_bits(pb2, 2, dquant_code[s->dquant+2]); |
||

706 | |||

707 | ```
if(!s->progressive_sequence){
``` |
||

708 | ```
if(cbp)
``` |
||

709 | ```
put_bits(pb2, 1, s->interlaced_dct);
``` |
||

710 | put_bits(pb2, 1, 0); |
||

711 | } |
||

712 | |||

713 | ```
if(interleaved_stats){
``` |
||

714 | s->misc_bits+= get_bits_diff(s); |
||

715 | } |
||

716 | |||

717 | ```
/* motion vectors: 16x16 mode */
``` |
||

718 | h263_pred_motion(s, 0, 0, &pred_x, &pred_y); |
||

719 | |||

720 | ff_h263_encode_motion_vector(s, motion_x - pred_x, |
||

721 | motion_y - pred_y, s->f_code); |
||

722 | }else if(s->mv_type==MV_TYPE_FIELD){ |
||

723 | if(s->dquant) cbpc+= 8; |
||

724 | put_bits(&s->pb, |
||

725 | 101ada9a | Michael Niedermayer | ff_h263_inter_MCBPC_bits[cbpc], |

726 | ff_h263_inter_MCBPC_code[cbpc]); |
||

727 | ca334dd1 | Michael Niedermayer | |

728 | 101ada9a | Michael Niedermayer | put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]); |

729 | ca334dd1 | Michael Niedermayer | ```
if(s->dquant)
``` |

730 | put_bits(pb2, 2, dquant_code[s->dquant+2]); |
||

731 | |||

732 | assert(!s->progressive_sequence); |
||

733 | ```
if(cbp)
``` |
||

734 | ```
put_bits(pb2, 1, s->interlaced_dct);
``` |
||

735 | put_bits(pb2, 1, 1); |
||

736 | |||

737 | ```
if(interleaved_stats){
``` |
||

738 | s->misc_bits+= get_bits_diff(s); |
||

739 | } |
||

740 | |||

741 | ```
/* motion vectors: 16x8 interlaced mode */
``` |
||

742 | h263_pred_motion(s, 0, 0, &pred_x, &pred_y); |
||

743 | ```
pred_y /=2;
``` |
||

744 | |||

745 | put_bits(&s->pb, 1, s->field_select[0][0]); |
||

746 | put_bits(&s->pb, 1, s->field_select[0][1]); |
||

747 | |||

748 | ff_h263_encode_motion_vector(s, s->mv[0][0][0] - pred_x, |
||

749 | s->mv[0][0][1] - pred_y, s->f_code); |
||

750 | ff_h263_encode_motion_vector(s, s->mv[0][1][0] - pred_x, |
||

751 | s->mv[0][1][1] - pred_y, s->f_code); |
||

752 | ```
}else{
``` |
||

753 | assert(s->mv_type==MV_TYPE_8X8); |
||

754 | put_bits(&s->pb, |
||

755 | 101ada9a | Michael Niedermayer | ```
ff_h263_inter_MCBPC_bits[cbpc+16],
``` |

756 | ```
ff_h263_inter_MCBPC_code[cbpc+16]);
``` |
||

757 | put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]); |
||

758 | ca334dd1 | Michael Niedermayer | |

759 | ```
if(!s->progressive_sequence){
``` |
||

760 | ```
if(cbp)
``` |
||

761 | ```
put_bits(pb2, 1, s->interlaced_dct);
``` |
||

762 | } |
||

763 | |||

764 | ```
if(interleaved_stats){
``` |
||

765 | s->misc_bits+= get_bits_diff(s); |
||

766 | } |
||

767 | |||

768 | for(i=0; i<4; i++){ |
||

769 | ```
/* motion vectors: 8x8 mode*/
``` |
||

770 | ```
h263_pred_motion(s, i, 0, &pred_x, &pred_y);
``` |
||

771 | |||

772 | ff_h263_encode_motion_vector(s, s->current_picture.motion_val[0][ s->block_index[i] ][0] - pred_x, |
||

773 | s->current_picture.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code); |
||

774 | } |
||

775 | } |
||

776 | |||

777 | ```
if(interleaved_stats){
``` |
||

778 | s->mv_bits+= get_bits_diff(s); |
||

779 | } |
||

780 | |||

781 | mpeg4_encode_blocks(s, block, NULL, NULL, NULL, tex_pb); |
||

782 | |||

783 | ```
if(interleaved_stats){
``` |
||

784 | s->p_tex_bits+= get_bits_diff(s); |
||

785 | } |
||

786 | s->f_count++; |
||

787 | } |
||

788 | ```
} else {
``` |
||

789 | ```
int cbp;
``` |
||

790 | int dc_diff[6]; //dc values with the dc prediction subtracted |
||

791 | int dir[6]; //prediction direction |
||

792 | int zigzag_last_index[6]; |
||

793 | ```
uint8_t *scan_table[6];
``` |
||

794 | ```
int i;
``` |
||

795 | |||

796 | for(i=0; i<6; i++){ |
||

797 | dc_diff[i]= ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i], 1); |
||

798 | } |
||

799 | |||

800 | ```
if(s->flags & CODEC_FLAG_AC_PRED){
``` |
||

801 | s->ac_pred= decide_ac_pred(s, block, dir, scan_table, zigzag_last_index); |
||

802 | ```
}else{
``` |
||

803 | for(i=0; i<6; i++) |
||

804 | scan_table[i]= s->intra_scantable.permutated; |
||

805 | } |
||

806 | |||

807 | ```
/* compute cbp */
``` |
||

808 | ```
cbp = 0;
``` |
||

809 | for (i = 0; i < 6; i++) { |
||

810 | if (s->block_last_index[i] >= 1) |
||

811 | cbp |= 1 << (5 - i); |
||

812 | } |
||

813 | |||

814 | ```
cbpc = cbp & 3;
``` |
||

815 | ```
if (s->pict_type == FF_I_TYPE) {
``` |
||

816 | if(s->dquant) cbpc+=4; |
||

817 | put_bits(&s->pb, |
||

818 | 101ada9a | Michael Niedermayer | ff_h263_intra_MCBPC_bits[cbpc], |

819 | ff_h263_intra_MCBPC_code[cbpc]); |
||

820 | ca334dd1 | Michael Niedermayer | ```
} else {
``` |

821 | if(s->dquant) cbpc+=8; |
||

822 | put_bits(&s->pb, 1, 0); /* mb coded */ |
||

823 | put_bits(&s->pb, |
||

824 | 101ada9a | Michael Niedermayer | ```
ff_h263_inter_MCBPC_bits[cbpc + 4],
``` |

825 | ```
ff_h263_inter_MCBPC_code[cbpc + 4]);
``` |
||

826 | ca334dd1 | Michael Niedermayer | } |

827 | ```
put_bits(pb2, 1, s->ac_pred);
``` |
||

828 | ```
cbpy = cbp >> 2;
``` |
||

829 | 101ada9a | Michael Niedermayer | put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]); |

830 | ca334dd1 | Michael Niedermayer | ```
if(s->dquant)
``` |

831 | put_bits(dc_pb, 2, dquant_code[s->dquant+2]); |
||

832 | |||

833 | ```
if(!s->progressive_sequence){
``` |
||

834 | ```
put_bits(dc_pb, 1, s->interlaced_dct);
``` |
||

835 | } |
||

836 | |||

837 | ```
if(interleaved_stats){
``` |
||

838 | s->misc_bits+= get_bits_diff(s); |
||

839 | } |
||

840 | |||

841 | mpeg4_encode_blocks(s, block, dc_diff, scan_table, dc_pb, tex_pb); |
||

842 | |||

843 | ```
if(interleaved_stats){
``` |
||

844 | s->i_tex_bits+= get_bits_diff(s); |
||

845 | } |
||

846 | s->i_count++; |
||

847 | |||

848 | ```
/* restore ac coeffs & last_index stuff if we messed them up with the prediction */
``` |
||

849 | ```
if(s->ac_pred)
``` |
||

850 | restore_ac_coeffs(s, block, dir, scan_table, zigzag_last_index); |
||

851 | } |
||

852 | } |
||

853 | |||

854 | ```
/**
``` |
||

855 | ```
* add mpeg4 stuffing bits (01...1)
``` |
||

856 | ```
*/
``` |
||

857 | ```
void ff_mpeg4_stuffing(PutBitContext * pbc)
``` |
||

858 | { |
||

859 | ```
int length;
``` |
||

860 | put_bits(pbc, 1, 0); |
||

861 | ```
length= (-put_bits_count(pbc))&7;
``` |
||

862 | if(length) put_bits(pbc, length, (1<<length)-1); |
||

863 | } |
||

864 | |||

865 | ```
/* must be called before writing the header */
``` |
||

866 | ```
void ff_set_mpeg4_time(MpegEncContext * s){
``` |
||

867 | ```
if(s->pict_type==FF_B_TYPE){
``` |
||

868 | ff_mpeg4_init_direct_mv(s); |
||

869 | ```
}else{
``` |
||

870 | s->last_time_base= s->time_base; |
||

871 | s->time_base= s->time/s->avctx->time_base.den; |
||

872 | } |
||

873 | } |
||

874 | |||

875 | static void mpeg4_encode_gop_header(MpegEncContext * s){ |
||

876 | ```
int hours, minutes, seconds;
``` |
||

877 | int64_t time; |
||

878 | |||

879 | put_bits(&s->pb, 16, 0); |
||

880 | ```
put_bits(&s->pb, 16, GOP_STARTCODE);
``` |
||

881 | |||

882 | time= s->current_picture_ptr->pts; |
||

883 | if(s->reordered_input_picture[1]) |
||

884 | ```
time= FFMIN(time, s->reordered_input_picture[1]->pts);
``` |
||

885 | time= time*s->avctx->time_base.num; |
||

886 | |||

887 | seconds= time/s->avctx->time_base.den; |
||

888 | minutes= seconds/60; seconds %= 60; |
||

889 | hours= minutes/60; minutes %= 60; |
||

890 | ```
hours%=24;
``` |
||

891 | |||

892 | ```
put_bits(&s->pb, 5, hours);
``` |
||

893 | ```
put_bits(&s->pb, 6, minutes);
``` |
||

894 | put_bits(&s->pb, 1, 1); |
||

895 | ```
put_bits(&s->pb, 6, seconds);
``` |
||

896 | |||

897 | ```
put_bits(&s->pb, 1, !!(s->flags&CODEC_FLAG_CLOSED_GOP));
``` |
||

898 | put_bits(&s->pb, 1, 0); //broken link == NO |
||

899 | |||

900 | s->last_time_base= time / s->avctx->time_base.den; |
||

901 | |||

902 | ff_mpeg4_stuffing(&s->pb); |
||

903 | } |
||

904 | |||

905 | static void mpeg4_encode_visual_object_header(MpegEncContext * s){ |
||

906 | ```
int profile_and_level_indication;
``` |
||

907 | ```
int vo_ver_id;
``` |
||

908 | |||

909 | ```
if(s->avctx->profile != FF_PROFILE_UNKNOWN){
``` |
||

910 | ```
profile_and_level_indication = s->avctx->profile << 4;
``` |
||

911 | }else if(s->max_b_frames || s->quarter_sample){ |
||

912 | profile_and_level_indication= 0xF0; // adv simple |
||

913 | ```
}else{
``` |
||

914 | profile_and_level_indication= 0x00; // simple |
||

915 | } |
||

916 | |||

917 | ```
if(s->avctx->level != FF_LEVEL_UNKNOWN){
``` |
||

918 | profile_and_level_indication |= s->avctx->level; |
||

919 | ```
}else{
``` |
||

920 | profile_and_level_indication |= 1; //level 1 |
||

921 | } |
||

922 | |||

923 | if(profile_and_level_indication>>4 == 0xF){ |
||

924 | ```
vo_ver_id= 5;
``` |
||

925 | ```
}else{
``` |
||

926 | ```
vo_ver_id= 1;
``` |
||

927 | } |
||

928 | |||

929 | ```
//FIXME levels
``` |
||

930 | |||

931 | put_bits(&s->pb, 16, 0); |
||

932 | ```
put_bits(&s->pb, 16, VOS_STARTCODE);
``` |
||

933 | |||

934 | ```
put_bits(&s->pb, 8, profile_and_level_indication);
``` |
||

935 | |||

936 | put_bits(&s->pb, 16, 0); |
||

937 | ```
put_bits(&s->pb, 16, VISUAL_OBJ_STARTCODE);
``` |
||

938 | |||

939 | put_bits(&s->pb, 1, 1); |
||

940 | ```
put_bits(&s->pb, 4, vo_ver_id);
``` |
||

941 | put_bits(&s->pb, 3, 1); //priority |
||

942 | |||

943 | put_bits(&s->pb, 4, 1); //visual obj type== video obj |
||

944 | |||

945 | put_bits(&s->pb, 1, 0); //video signal type == no clue //FIXME |
||

946 | |||

947 | ff_mpeg4_stuffing(&s->pb); |
||

948 | } |
||

949 | |||

950 | static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_number) |
||

951 | { |
||

952 | ```
int vo_ver_id;
``` |
||

953 | |||

954 | if (!CONFIG_MPEG4_ENCODER) return; |
||

955 | |||

956 | ```
if(s->max_b_frames || s->quarter_sample){
``` |
||

957 | ```
vo_ver_id= 5;
``` |
||

958 | s->vo_type= ADV_SIMPLE_VO_TYPE; |
||

959 | ```
}else{
``` |
||

960 | ```
vo_ver_id= 1;
``` |
||

961 | s->vo_type= SIMPLE_VO_TYPE; |
||

962 | } |
||

963 | |||

964 | put_bits(&s->pb, 16, 0); |
||

965 | put_bits(&s->pb, 16, 0x100 + vo_number); /* video obj */ |
||

966 | put_bits(&s->pb, 16, 0); |
||

967 | put_bits(&s->pb, 16, 0x120 + vol_number); /* video obj layer */ |
||

968 | |||

969 | put_bits(&s->pb, 1, 0); /* random access vol */ |
||

970 | put_bits(&s->pb, 8, s->vo_type); /* video obj type indication */ |
||

971 | ```
if(s->workaround_bugs & FF_BUG_MS) {
``` |
||

972 | put_bits(&s->pb, 1, 0); /* is obj layer id= no */ |
||

973 | ```
} else {
``` |
||

974 | put_bits(&s->pb, 1, 1); /* is obj layer id= yes */ |
||

975 | put_bits(&s->pb, 4, vo_ver_id); /* is obj layer ver id */ |
||

976 | put_bits(&s->pb, 3, 1); /* is obj layer priority */ |
||

977 | } |
||

978 | |||

979 | s->aspect_ratio_info= ff_h263_aspect_to_info(s->avctx->sample_aspect_ratio); |
||

980 | |||

981 | put_bits(&s->pb, 4, s->aspect_ratio_info);/* aspect ratio info */ |
||

982 | ```
if (s->aspect_ratio_info == FF_ASPECT_EXTENDED){
``` |
||

983 | ```
put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.num);
``` |
||

984 | ```
put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.den);
``` |
||

985 | } |
||

986 | |||

987 | if(s->workaround_bugs & FF_BUG_MS) { // |
||

988 | put_bits(&s->pb, 1, 0); /* vol control parameters= no @@@ */ |
||

989 | ```
} else {
``` |
||

990 | put_bits(&s->pb, 1, 1); /* vol control parameters= yes */ |
||

991 | put_bits(&s->pb, 2, 1); /* chroma format YUV 420/YV12 */ |
||

992 | ```
put_bits(&s->pb, 1, s->low_delay);
``` |
||

993 | put_bits(&s->pb, 1, 0); /* vbv parameters= no */ |
||

994 | } |
||

995 | |||

996 | put_bits(&s->pb, 2, RECT_SHAPE); /* vol shape= rectangle */ |
||

997 | put_bits(&s->pb, 1, 1); /* marker bit */ |
||

998 | |||

999 | ```
put_bits(&s->pb, 16, s->avctx->time_base.den);
``` |
||

1000 | if (s->time_increment_bits < 1) |
||

1001 | ```
s->time_increment_bits = 1;
``` |
||

1002 | put_bits(&s->pb, 1, 1); /* marker bit */ |
||

1003 | put_bits(&s->pb, 1, 0); /* fixed vop rate=no */ |
||

1004 | put_bits(&s->pb, 1, 1); /* marker bit */ |
||

1005 | put_bits(&s->pb, 13, s->width); /* vol width */ |
||

1006 | put_bits(&s->pb, 1, 1); /* marker bit */ |
||

1007 | put_bits(&s->pb, 13, s->height); /* vol height */ |
||

1008 | put_bits(&s->pb, 1, 1); /* marker bit */ |
||

1009 | put_bits(&s->pb, 1, s->progressive_sequence ? 0 : 1); |
||

1010 | put_bits(&s->pb, 1, 1); /* obmc disable */ |
||

1011 | if (vo_ver_id == 1) { |
||

1012 | put_bits(&s->pb, 1, s->vol_sprite_usage); /* sprite enable */ |
||

1013 | ```
}else{
``` |
||

1014 | put_bits(&s->pb, 2, s->vol_sprite_usage); /* sprite enable */ |
||

1015 | } |
||

1016 | |||

1017 | put_bits(&s->pb, 1, 0); /* not 8 bit == false */ |
||

1018 | put_bits(&s->pb, 1, s->mpeg_quant); /* quant type= (0=h263 style)*/ |
||

1019 | |||

1020 | ```
if(s->mpeg_quant){
``` |
||

1021 | ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix); |
||

1022 | ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix); |
||

1023 | } |
||

1024 | |||

1025 | if (vo_ver_id != 1) |
||

1026 | ```
put_bits(&s->pb, 1, s->quarter_sample);
``` |
||

1027 | put_bits(&s->pb, 1, 1); /* complexity estimation disable */ |
||

1028 | s->resync_marker= s->rtp_mode; |
||

1029 | put_bits(&s->pb, 1, s->resync_marker ? 0 : 1);/* resync marker disable */ |
||

1030 | put_bits(&s->pb, 1, s->data_partitioning ? 1 : 0); |
||

1031 | ```
if(s->data_partitioning){
``` |
||

1032 | put_bits(&s->pb, 1, 0); /* no rvlc */ |
||

1033 | } |
||

1034 | |||

1035 | if (vo_ver_id != 1){ |
||

1036 | put_bits(&s->pb, 1, 0); /* newpred */ |
||

1037 | put_bits(&s->pb, 1, 0); /* reduced res vop */ |
||

1038 | } |
||

1039 | put_bits(&s->pb, 1, 0); /* scalability */ |
||

1040 | |||

1041 | ff_mpeg4_stuffing(&s->pb); |
||

1042 | |||

1043 | ```
/* user data */
``` |
||

1044 | ```
if(!(s->flags & CODEC_FLAG_BITEXACT)){
``` |
||

1045 | put_bits(&s->pb, 16, 0); |
||

1046 | put_bits(&s->pb, 16, 0x1B2); /* user_data */ |
||

1047 | ```
ff_put_string(&s->pb, LIBAVCODEC_IDENT, 0);
``` |
||

1048 | } |
||

1049 | } |
||

1050 | |||

1051 | ```
/* write mpeg4 VOP header */
``` |
||

1052 | void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) |
||

1053 | { |
||

1054 | ```
int time_incr;
``` |
||

1055 | ```
int time_div, time_mod;
``` |
||

1056 | |||

1057 | ```
if(s->pict_type==FF_I_TYPE){
``` |
||

1058 | ```
if(!(s->flags&CODEC_FLAG_GLOBAL_HEADER)){
``` |
||

1059 | if(s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT) //HACK, the reference sw is buggy |
||

1060 | mpeg4_encode_visual_object_header(s); |
||

1061 | if(s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || picture_number==0) //HACK, the reference sw is buggy |
||

1062 | mpeg4_encode_vol_header(s, 0, 0); |
||

1063 | } |
||

1064 | ```
if(!(s->workaround_bugs & FF_BUG_MS))
``` |
||

1065 | mpeg4_encode_gop_header(s); |
||

1066 | } |
||

1067 | |||

1068 | s->partitioned_frame= s->data_partitioning && s->pict_type!=FF_B_TYPE; |
||

1069 | |||

1070 | put_bits(&s->pb, 16, 0); /* vop header */ |
||

1071 | put_bits(&s->pb, 16, VOP_STARTCODE); /* vop header */ |
||

1072 | put_bits(&s->pb, 2, s->pict_type - 1); /* pict type: I = 0 , P = 1 */ |
||

1073 | |||

1074 | ```
assert(s->time>=0);
``` |
||

1075 | time_div= s->time/s->avctx->time_base.den; |
||

1076 | time_mod= s->time%s->avctx->time_base.den; |
||

1077 | time_incr= time_div - s->last_time_base; |
||

1078 | ```
assert(time_incr >= 0);
``` |
||

1079 | ```
while(time_incr--)
``` |
||

1080 | put_bits(&s->pb, 1, 1); |
||

1081 | |||

1082 | put_bits(&s->pb, 1, 0); |
||

1083 | |||

1084 | put_bits(&s->pb, 1, 1); /* marker */ |
||

1085 | ```
put_bits(&s->pb, s->time_increment_bits, time_mod); /* time increment */
``` |
||

1086 | put_bits(&s->pb, 1, 1); /* marker */ |
||

1087 | put_bits(&s->pb, 1, 1); /* vop coded */ |
||

1088 | ```
if ( s->pict_type == FF_P_TYPE
``` |
||

1089 | || (s->pict_type == FF_S_TYPE && s->vol_sprite_usage==GMC_SPRITE)) { |
||

1090 | put_bits(&s->pb, 1, s->no_rounding); /* rounding type */ |
||

1091 | } |
||

1092 | put_bits(&s->pb, 3, 0); /* intra dc VLC threshold */ |
||

1093 | ```
if(!s->progressive_sequence){
``` |
||

1094 | ```
put_bits(&s->pb, 1, s->current_picture_ptr->top_field_first);
``` |
||

1095 | ```
put_bits(&s->pb, 1, s->alternate_scan);
``` |
||

1096 | } |
||

1097 | ```
//FIXME sprite stuff
``` |
||

1098 | |||

1099 | ```
put_bits(&s->pb, 5, s->qscale);
``` |
||

1100 | |||

1101 | ```
if (s->pict_type != FF_I_TYPE)
``` |
||

1102 | put_bits(&s->pb, 3, s->f_code); /* fcode_for */ |
||

1103 | ```
if (s->pict_type == FF_B_TYPE)
``` |
||

1104 | put_bits(&s->pb, 3, s->b_code); /* fcode_back */ |
||

1105 | } |
||

1106 | |||

1107 | |||

1108 | static void init_uni_dc_tab(void) |
||

1109 | { |
||

1110 | ```
int level, uni_code, uni_len;
``` |
||

1111 | |||

1112 | for(level=-256; level<256; level++){ |
||

1113 | ```
int size, v, l;
``` |
||

1114 | ```
/* find number of bits */
``` |
||

1115 | ```
size = 0;
``` |
||

1116 | v = abs(level); |
||

1117 | ```
while (v) {
``` |
||

1118 | ```
v >>= 1;
``` |
||

1119 | size++; |
||

1120 | } |
||

1121 | |||

1122 | if (level < 0) |
||

1123 | l= (-level) ^ ((1 << size) - 1); |
||

1124 | ```
else
``` |
||

1125 | l= level; |
||

1126 | |||

1127 | ```
/* luminance */
``` |
||

1128 | 05b858b0 | Michael Niedermayer | ```
uni_code= ff_mpeg4_DCtab_lum[size][0];
``` |

1129 | ```
uni_len = ff_mpeg4_DCtab_lum[size][1];
``` |
||

1130 | ca334dd1 | Michael Niedermayer | |

1131 | if (size > 0) { |
||

1132 | uni_code<<=size; uni_code|=l; |
||

1133 | uni_len+=size; |
||

1134 | if (size > 8){ |
||

1135 | uni_code<<=1; uni_code|=1; |
||

1136 | uni_len++; |
||

1137 | } |
||

1138 | } |
||

1139 | ```
uni_DCtab_lum_bits[level+256]= uni_code;
``` |
||

1140 | ```
uni_DCtab_lum_len [level+256]= uni_len;
``` |
||

1141 | |||

1142 | ```
/* chrominance */
``` |
||

1143 | 05b858b0 | Michael Niedermayer | ```
uni_code= ff_mpeg4_DCtab_chrom[size][0];
``` |

1144 | ```
uni_len = ff_mpeg4_DCtab_chrom[size][1];
``` |
||

1145 | ca334dd1 | Michael Niedermayer | |

1146 | if (size > 0) { |
||

1147 | uni_code<<=size; uni_code|=l; |
||

1148 | uni_len+=size; |
||

1149 | if (size > 8){ |
||

1150 | uni_code<<=1; uni_code|=1; |
||

1151 | uni_len++; |
||

1152 | } |
||

1153 | } |
||

1154 | ```
uni_DCtab_chrom_bits[level+256]= uni_code;
``` |
||

1155 | ```
uni_DCtab_chrom_len [level+256]= uni_len;
``` |
||

1156 | |||

1157 | } |
||

1158 | } |
||

1159 | |||

1160 | static void init_uni_mpeg4_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_tab){ |
||

1161 | ```
int slevel, run, last;
``` |
||

1162 | |||

1163 | ```
assert(MAX_LEVEL >= 64);
``` |
||

1164 | ```
assert(MAX_RUN >= 63);
``` |
||

1165 | |||

1166 | for(slevel=-64; slevel<64; slevel++){ |
||

1167 | if(slevel==0) continue; |
||

1168 | for(run=0; run<64; run++){ |
||

1169 | for(last=0; last<=1; last++){ |
||

1170 | const int index= UNI_MPEG4_ENC_INDEX(last, run, slevel+64); |
||

1171 | int level= slevel < 0 ? -slevel : slevel; |
||

1172 | int sign= slevel < 0 ? 1 : 0; |
||

1173 | ```
int bits, len, code;
``` |
||

1174 | ```
int level1, run1;
``` |
||

1175 | |||

1176 | ```
len_tab[index]= 100;
``` |
||

1177 | |||

1178 | ```
/* ESC0 */
``` |
||

1179 | code= get_rl_index(rl, last, run, level); |
||

1180 | ```
bits= rl->table_vlc[code][0];
``` |
||

1181 | ```
len= rl->table_vlc[code][1];
``` |
||

1182 | ```
bits=bits*2+sign; len++;
``` |
||

1183 | |||

1184 | ```
if(code!=rl->n && len < len_tab[index]){
``` |
||

1185 | bits_tab[index]= bits; |
||

1186 | len_tab [index]= len; |
||

1187 | } |
||

1188 | ```
/* ESC1 */
``` |
||

1189 | ```
bits= rl->table_vlc[rl->n][0];
``` |
||

1190 | ```
len= rl->table_vlc[rl->n][1];
``` |
||

1191 | bits=bits*2; len++; //esc1 |
||

1192 | level1= level - rl->max_level[last][run]; |
||

1193 | if(level1>0){ |
||

1194 | code= get_rl_index(rl, last, run, level1); |
||

1195 | ```
bits<<= rl->table_vlc[code][1];
``` |
||

1196 | ```
len += rl->table_vlc[code][1];
``` |
||

1197 | ```
bits += rl->table_vlc[code][0];
``` |
||

1198 | ```
bits=bits*2+sign; len++;
``` |
||

1199 | |||

1200 | ```
if(code!=rl->n && len < len_tab[index]){
``` |
||

1201 | bits_tab[index]= bits; |
||

1202 | len_tab [index]= len; |
||

1203 | } |
||

1204 | } |
||

1205 | ```
/* ESC2 */
``` |
||

1206 | ```
bits= rl->table_vlc[rl->n][0];
``` |
||

1207 | ```
len= rl->table_vlc[rl->n][1];
``` |
||

1208 | bits=bits*4+2; len+=2; //esc2 |
||

1209 | ```
run1 = run - rl->max_run[last][level] - 1;
``` |
||

1210 | if(run1>=0){ |
||

1211 | code= get_rl_index(rl, last, run1, level); |
||

1212 | ```
bits<<= rl->table_vlc[code][1];
``` |
||

1213 | ```
len += rl->table_vlc[code][1];
``` |
||

1214 | ```
bits += rl->table_vlc[code][0];
``` |
||

1215 | ```
bits=bits*2+sign; len++;
``` |
||

1216 | |||

1217 | ```
if(code!=rl->n && len < len_tab[index]){
``` |
||

1218 | bits_tab[index]= bits; |
||

1219 | len_tab [index]= len; |
||

1220 | } |
||

1221 | } |
||

1222 | ```
/* ESC3 */
``` |
||

1223 | ```
bits= rl->table_vlc[rl->n][0];
``` |
||

1224 | ```
len = rl->table_vlc[rl->n][1];
``` |
||

1225 | bits=bits*4+3; len+=2; //esc3 |
||

1226 | ```
bits=bits*2+last; len++;
``` |
||

1227 | bits=bits*64+run; len+=6; |
||

1228 | bits=bits*2+1; len++; //marker |
||

1229 | bits=bits*4096+(slevel&0xfff); len+=12; |
||

1230 | bits=bits*2+1; len++; //marker |
||

1231 | |||

1232 | ```
if(len < len_tab[index]){
``` |
||

1233 | bits_tab[index]= bits; |
||

1234 | len_tab [index]= len; |
||

1235 | } |
||

1236 | } |
||

1237 | } |
||

1238 | } |
||

1239 | } |
||

1240 | |||

1241 | static av_cold int encode_init(AVCodecContext *avctx) |
||

1242 | { |
||

1243 | MpegEncContext *s = avctx->priv_data; |
||

1244 | ```
int ret;
``` |
||

1245 | static int done = 0; |
||

1246 | |||

1247 | if((ret=MPV_encode_init(avctx)) < 0) |
||

1248 | ```
return ret;
``` |
||

1249 | |||

1250 | ```
if (!done) {
``` |
||

1251 | ```
done = 1;
``` |
||

1252 | |||

1253 | init_uni_dc_tab(); |
||

1254 | |||

1255 | fef59a5b | Michael Niedermayer | ```
init_rl(&ff_mpeg4_rl_intra, ff_mpeg4_static_rl_table_store[0]);
``` |

1256 | ca334dd1 | Michael Niedermayer | |

1257 | fef59a5b | Michael Niedermayer | init_uni_mpeg4_rl_tab(&ff_mpeg4_rl_intra, uni_mpeg4_intra_rl_bits, uni_mpeg4_intra_rl_len); |

1258 | 101ada9a | Michael Niedermayer | init_uni_mpeg4_rl_tab(&ff_h263_rl_inter, uni_mpeg4_inter_rl_bits, uni_mpeg4_inter_rl_len); |

1259 | ca334dd1 | Michael Niedermayer | } |

1260 | |||

1261 | ```
s->min_qcoeff= -2048;
``` |
||

1262 | ```
s->max_qcoeff= 2047;
``` |
||

1263 | s->intra_ac_vlc_length = uni_mpeg4_intra_rl_len; |
||

1264 | s->intra_ac_vlc_last_length= uni_mpeg4_intra_rl_len + 128*64; |
||

1265 | s->inter_ac_vlc_length = uni_mpeg4_inter_rl_len; |
||

1266 | s->inter_ac_vlc_last_length= uni_mpeg4_inter_rl_len + 128*64; |
||

1267 | s->luma_dc_vlc_length= uni_DCtab_lum_len; |
||

1268 | s->chroma_dc_vlc_length= uni_DCtab_chrom_len; |
||

1269 | s->ac_esc_length= 7+2+1+6+1+12+1; |
||

1270 | s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; |
||

1271 | s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; |
||

1272 | |||

1273 | ```
if(s->flags & CODEC_FLAG_GLOBAL_HEADER){
``` |
||

1274 | |||

1275 | ```
s->avctx->extradata= av_malloc(1024);
``` |
||

1276 | ```
init_put_bits(&s->pb, s->avctx->extradata, 1024);
``` |
||

1277 | |||

1278 | ```
if(!(s->workaround_bugs & FF_BUG_MS))
``` |
||

1279 | mpeg4_encode_visual_object_header(s); |
||

1280 | mpeg4_encode_vol_header(s, 0, 0); |
||

1281 | |||

1282 | ```
// ff_mpeg4_stuffing(&s->pb); ?
``` |
||

1283 | flush_put_bits(&s->pb); |
||

1284 | s->avctx->extradata_size= (put_bits_count(&s->pb)+7)>>3; |
||

1285 | } |
||

1286 | return 0; |
||

1287 | } |
||

1288 | |||

1289 | ```
void ff_mpeg4_init_partitions(MpegEncContext *s)
``` |
||

1290 | { |
||

1291 | uint8_t *start= put_bits_ptr(&s->pb); |
||

1292 | uint8_t *end= s->pb.buf_end; |
||

1293 | ```
int size= end - start;
``` |
||

1294 | int pb_size = (((intptr_t)start + size/3)&(~3)) - (intptr_t)start; |
||

1295 | int tex_size= (size - 2*pb_size)&(~3); |
||

1296 | |||

1297 | set_put_bits_buffer_size(&s->pb, pb_size); |
||

1298 | init_put_bits(&s->tex_pb, start + pb_size , tex_size); |
||

1299 | init_put_bits(&s->pb2 , start + pb_size + tex_size, pb_size); |
||

1300 | } |
||

1301 | |||

1302 | ```
void ff_mpeg4_merge_partitions(MpegEncContext *s)
``` |
||

1303 | { |
||

1304 | const int pb2_len = put_bits_count(&s->pb2 ); |
||

1305 | const int tex_pb_len= put_bits_count(&s->tex_pb); |
||

1306 | const int bits= put_bits_count(&s->pb); |
||

1307 | |||

1308 | ```
if(s->pict_type==FF_I_TYPE){
``` |
||

1309 | ```
put_bits(&s->pb, 19, DC_MARKER);
``` |
||

1310 | ```
s->misc_bits+=19 + pb2_len + bits - s->last_bits;
``` |
||

1311 | s->i_tex_bits+= tex_pb_len; |
||

1312 | ```
}else{
``` |
||

1313 | ```
put_bits(&s->pb, 17, MOTION_MARKER);
``` |
||

1314 | ```
s->misc_bits+=17 + pb2_len;
``` |
||

1315 | s->mv_bits+= bits - s->last_bits; |
||

1316 | s->p_tex_bits+= tex_pb_len; |
||

1317 | } |
||

1318 | |||

1319 | flush_put_bits(&s->pb2); |
||

1320 | flush_put_bits(&s->tex_pb); |
||

1321 | |||

1322 | set_put_bits_buffer_size(&s->pb, s->pb2.buf_end - s->pb.buf); |
||

1323 | ff_copy_bits(&s->pb, s->pb2.buf , pb2_len); |
||

1324 | ff_copy_bits(&s->pb, s->tex_pb.buf, tex_pb_len); |
||

1325 | s->last_bits= put_bits_count(&s->pb); |
||

1326 | } |
||

1327 | |||

1328 | |||

1329 | ```
void ff_mpeg4_encode_video_packet_header(MpegEncContext *s)
``` |
||

1330 | { |
||

1331 | int mb_num_bits= av_log2(s->mb_num - 1) + 1; |
||

1332 | |||

1333 | ```
put_bits(&s->pb, ff_mpeg4_get_video_packet_prefix_length(s), 0);
``` |
||

1334 | put_bits(&s->pb, 1, 1); |
||

1335 | |||

1336 | put_bits(&s->pb, mb_num_bits, s->mb_x + s->mb_y*s->mb_width); |
||

1337 | put_bits(&s->pb, s->quant_precision, s->qscale); |
||

1338 | put_bits(&s->pb, 1, 0); /* no HEC */ |
||

1339 | } |
||

1340 | |||

1341 | d36beb3f | Diego Elio Pettenò | AVCodec ff_mpeg4_encoder = { |

1342 | ca334dd1 | Michael Niedermayer | ```
"mpeg4",
``` |

1343 | 72415b2a | Stefano Sabatini | AVMEDIA_TYPE_VIDEO, |

1344 | ca334dd1 | Michael Niedermayer | CODEC_ID_MPEG4, |

1345 | ```
sizeof(MpegEncContext),
``` |
||

1346 | encode_init, |
||

1347 | MPV_encode_picture, |
||

1348 | MPV_encode_end, |
||

1349 | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, |
||

1350 | .capabilities= CODEC_CAP_DELAY, |
||

1351 | ```
.long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
``` |
||

1352 | }; |