Commit | Line | Data |
---|---|---|
1ddadfa9 AT |
1 | /* |
2 | * Interface to xvidcore for mpeg4 encoding | |
3 | * Copyright (c) 2004 Adam Thayer <krevnik@comcast.net> | |
4 | * | |
b78e7197 DB |
5 | * This file is part of FFmpeg. |
6 | * | |
7 | * FFmpeg is free software; you can redistribute it and/or | |
1ddadfa9 AT |
8 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either | |
b78e7197 | 10 | * version 2.1 of the License, or (at your option) any later version. |
1ddadfa9 | 11 | * |
b78e7197 | 12 | * FFmpeg is distributed in the hope that it will be useful, |
1ddadfa9 AT |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * Lesser General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public | |
b78e7197 | 18 | * License along with FFmpeg; if not, write to the Free Software |
5509bffa | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1ddadfa9 | 20 | */ |
115329f1 | 21 | |
1ddadfa9 AT |
22 | /** |
23 | * @file xvidmpeg4.c | |
24 | * Interface to xvidcore for MPEG-4 compliant encoding. | |
25 | * @author Adam Thayer (krevnik@comcast.net) | |
26 | */ | |
115329f1 | 27 | |
1ddadfa9 AT |
28 | #include <xvid.h> |
29 | #include <unistd.h> | |
30 | #include "common.h" | |
31 | #include "avcodec.h" | |
cb690cad | 32 | #include "xvid_internal.h" |
1ddadfa9 AT |
33 | |
34 | /** | |
35 | * Buffer management macros. | |
36 | */ | |
37 | #define BUFFER_SIZE 1024 | |
38 | #define BUFFER_REMAINING(x) (BUFFER_SIZE - strlen(x)) | |
39 | #define BUFFER_CAT(x) (&((x)[strlen(x)])) | |
40 | ||
41 | /* For PPC Use */ | |
42 | #if HAVE_ALTIVEC==1 | |
43 | extern int has_altivec(void); | |
44 | #endif | |
45 | ||
46 | /** | |
47 | * Structure for the private XviD context. | |
48 | * This stores all the private context for the codec. | |
49 | */ | |
50 | typedef struct xvid_context { | |
51 | void *encoder_handle; /** Handle for XviD Encoder */ | |
52 | int xsize, ysize; /** Frame size */ | |
53 | int vop_flags; /** VOP flags for XviD Encoder */ | |
54 | int vol_flags; /** VOL flags for XviD Encoder */ | |
55 | int me_flags; /** Motion Estimation flags */ | |
56 | int qscale; /** Do we use constant scale? */ | |
57 | int quicktime_format; /** Are we in a QT-based format? */ | |
58 | AVFrame encoded_picture; /** Encoded frame information */ | |
59 | char *twopassbuffer; /** Character buffer for two-pass */ | |
60 | char *old_twopassbuffer; /** Old character buffer (two-pass) */ | |
61 | char *twopassfile; /** second pass temp file name */ | |
62 | unsigned char *intra_matrix; /** P-Frame Quant Matrix */ | |
63 | unsigned char *inter_matrix; /** I-Frame Quant Matrix */ | |
64 | } xvid_context_t; | |
115329f1 | 65 | |
1ddadfa9 AT |
66 | /** |
67 | * Structure for the private first-pass plugin. | |
68 | */ | |
69 | typedef struct xvid_ff_pass1 { | |
70 | int version; /** XviD version */ | |
71 | xvid_context_t *context; /** Pointer to private context */ | |
72 | } xvid_ff_pass1_t; | |
73 | ||
74 | /* Prototypes - See function implementation for details */ | |
75 | int xvid_strip_vol_header(AVCodecContext *avctx, unsigned char *frame, unsigned int header_len, unsigned int frame_len); | |
76 | int xvid_ff_2pass(void *ref, int opt, void *p1, void *p2); | |
115329f1 DB |
77 | void xvid_correct_framerate(AVCodecContext *avctx); |
78 | ||
79 | /** | |
1ddadfa9 AT |
80 | * Creates the private context for the encoder. |
81 | * All buffers are allocated, settings are loaded from the user, | |
82 | * and the encoder context created. | |
83 | * | |
84 | * @param avctx AVCodecContext pointer to context | |
85 | * @return Returns 0 on success, -1 on failure | |
115329f1 | 86 | */ |
1ddadfa9 AT |
87 | int ff_xvid_encode_init(AVCodecContext *avctx) { |
88 | int xerr, i; | |
89 | int xvid_flags = avctx->flags; | |
90 | xvid_context_t *x = avctx->priv_data; | |
91 | uint16_t *intra, *inter; | |
92 | int fd; | |
115329f1 | 93 | |
1ddadfa9 AT |
94 | xvid_plugin_single_t single; |
95 | xvid_ff_pass1_t rc2pass1; | |
96 | xvid_plugin_2pass2_t rc2pass2; | |
97 | xvid_gbl_init_t xvid_gbl_init; | |
98 | xvid_enc_create_t xvid_enc_create; | |
99 | xvid_enc_plugin_t plugins[7]; | |
100 | ||
101 | /* Bring in VOP flags from ffmpeg command-line */ | |
102 | x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */ | |
115329f1 | 103 | if( xvid_flags & CODEC_FLAG_4MV ) |
1ddadfa9 | 104 | x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */ |
115329f1 | 105 | if( xvid_flags & CODEC_FLAG_TRELLIS_QUANT) |
1ddadfa9 | 106 | x->vop_flags |= XVID_VOP_TRELLISQUANT; /* Level 5 */ |
115329f1 | 107 | if( xvid_flags & CODEC_FLAG_AC_PRED ) |
1ddadfa9 AT |
108 | x->vop_flags |= XVID_VOP_HQACPRED; /* Level 6 */ |
109 | if( xvid_flags & CODEC_FLAG_GRAY ) | |
110 | x->vop_flags |= XVID_VOP_GREYSCALE; | |
115329f1 | 111 | |
1ddadfa9 AT |
112 | /* Decide which ME quality setting to use */ |
113 | x->me_flags = 0; | |
114 | switch( avctx->me_method ) { | |
115 | case ME_FULL: /* Quality 6 */ | |
116 | x->me_flags |= XVID_ME_EXTSEARCH16 | |
117 | | XVID_ME_EXTSEARCH8; | |
115329f1 | 118 | |
1ddadfa9 AT |
119 | case ME_EPZS: /* Quality 4 */ |
120 | x->me_flags |= XVID_ME_ADVANCEDDIAMOND8 | |
121 | | XVID_ME_HALFPELREFINE8 | |
122 | | XVID_ME_CHROMA_PVOP | |
123 | | XVID_ME_CHROMA_BVOP; | |
115329f1 | 124 | |
1ddadfa9 AT |
125 | case ME_LOG: /* Quality 2 */ |
126 | case ME_PHODS: | |
127 | case ME_X1: | |
128 | x->me_flags |= XVID_ME_ADVANCEDDIAMOND16 | |
129 | | XVID_ME_HALFPELREFINE16; | |
115329f1 | 130 | |
1ddadfa9 AT |
131 | case ME_ZERO: /* Quality 0 */ |
132 | default: | |
133 | break; | |
134 | } | |
115329f1 | 135 | |
1ddadfa9 AT |
136 | /* Decide how we should decide blocks */ |
137 | switch( avctx->mb_decision ) { | |
138 | case 2: | |
139 | x->vop_flags |= XVID_VOP_MODEDECISION_RD; | |
140 | x->me_flags |= XVID_ME_HALFPELREFINE8_RD | |
141 | | XVID_ME_QUARTERPELREFINE8_RD | |
142 | | XVID_ME_EXTSEARCH_RD | |
115329f1 | 143 | | XVID_ME_CHECKPREDICTION_RD; |
1ddadfa9 AT |
144 | case 1: |
145 | if( !(x->vop_flags & XVID_VOP_MODEDECISION_RD) ) | |
146 | x->vop_flags |= XVID_VOP_FAST_MODEDECISION_RD; | |
147 | x->me_flags |= XVID_ME_HALFPELREFINE16_RD | |
148 | | XVID_ME_QUARTERPELREFINE16_RD; | |
115329f1 | 149 | |
1ddadfa9 AT |
150 | default: |
151 | break; | |
152 | } | |
115329f1 | 153 | |
1ddadfa9 AT |
154 | /* Bring in VOL flags from ffmpeg command-line */ |
155 | x->vol_flags = 0; | |
115329f1 DB |
156 | if( xvid_flags & CODEC_FLAG_GMC ) { |
157 | x->vol_flags |= XVID_VOL_GMC; | |
158 | x->me_flags |= XVID_ME_GME_REFINE; | |
1ddadfa9 | 159 | } |
115329f1 | 160 | if( xvid_flags & CODEC_FLAG_QPEL ) { |
1ddadfa9 AT |
161 | x->vol_flags |= XVID_VOL_QUARTERPEL; |
162 | x->me_flags |= XVID_ME_QUARTERPELREFINE16; | |
163 | if( x->vop_flags & XVID_VOP_INTER4V ) | |
164 | x->me_flags |= XVID_ME_QUARTERPELREFINE8; | |
165 | } | |
166 | ||
167 | memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init)); | |
168 | xvid_gbl_init.version = XVID_VERSION; | |
169 | xvid_gbl_init.debug = 0; | |
115329f1 | 170 | |
1ddadfa9 AT |
171 | #ifdef ARCH_POWERPC |
172 | /* XviD's PPC support is borked, use libavcodec to detect */ | |
173 | #if HAVE_ALTIVEC==1 | |
174 | if( has_altivec() ) { | |
175 | xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ALTIVEC; | |
176 | } else | |
177 | #endif | |
115329f1 | 178 | xvid_gbl_init.cpu_flags = XVID_CPU_FORCE; |
1ddadfa9 AT |
179 | #else |
180 | /* XviD can detect on x86 */ | |
181 | xvid_gbl_init.cpu_flags = 0; | |
182 | #endif | |
115329f1 | 183 | |
1ddadfa9 AT |
184 | /* Initialize */ |
185 | xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL); | |
186 | ||
187 | /* Create the encoder reference */ | |
188 | memset(&xvid_enc_create, 0, sizeof(xvid_enc_create)); | |
189 | xvid_enc_create.version = XVID_VERSION; | |
115329f1 | 190 | |
1ddadfa9 AT |
191 | /* Store the desired frame size */ |
192 | xvid_enc_create.width = x->xsize = avctx->width; | |
193 | xvid_enc_create.height = x->ysize = avctx->height; | |
194 | ||
195 | /* XviD can determine the proper profile to use */ | |
196 | /* xvid_enc_create.profile = XVID_PROFILE_S_L3; */ | |
115329f1 | 197 | |
1ddadfa9 AT |
198 | /* We don't use zones or threads */ |
199 | xvid_enc_create.zones = NULL; | |
200 | xvid_enc_create.num_zones = 0; | |
201 | xvid_enc_create.num_threads = 0; | |
115329f1 | 202 | |
1ddadfa9 AT |
203 | xvid_enc_create.plugins = plugins; |
204 | xvid_enc_create.num_plugins = 0; | |
115329f1 | 205 | |
1ddadfa9 AT |
206 | /* Initialize Buffers */ |
207 | x->twopassbuffer = NULL; | |
208 | x->old_twopassbuffer = NULL; | |
209 | x->twopassfile = NULL; | |
115329f1 | 210 | |
1ddadfa9 AT |
211 | if( xvid_flags & CODEC_FLAG_PASS1 ) { |
212 | memset(&rc2pass1, 0, sizeof(xvid_ff_pass1_t)); | |
213 | rc2pass1.version = XVID_VERSION; | |
214 | rc2pass1.context = x; | |
215 | x->twopassbuffer = av_malloc(BUFFER_SIZE); | |
216 | x->old_twopassbuffer = av_malloc(BUFFER_SIZE); | |
217 | if( x->twopassbuffer == NULL || x->old_twopassbuffer == NULL ) { | |
218 | av_log(avctx, AV_LOG_ERROR, | |
219 | "XviD: Cannot allocate 2-pass log buffers\n"); | |
220 | return -1; | |
221 | } | |
222 | x->twopassbuffer[0] = x->old_twopassbuffer[0] = 0; | |
115329f1 | 223 | |
1ddadfa9 AT |
224 | plugins[xvid_enc_create.num_plugins].func = xvid_ff_2pass; |
225 | plugins[xvid_enc_create.num_plugins].param = &rc2pass1; | |
226 | xvid_enc_create.num_plugins++; | |
227 | } else if( xvid_flags & CODEC_FLAG_PASS2 ) { | |
228 | memset(&rc2pass2, 0, sizeof(xvid_plugin_2pass2_t)); | |
229 | rc2pass2.version = XVID_VERSION; | |
230 | rc2pass2.bitrate = avctx->bit_rate; | |
115329f1 | 231 | |
1005f542 | 232 | fd = av_tempfile("xvidff.", &(x->twopassfile)); |
1ddadfa9 AT |
233 | if( fd == -1 ) { |
234 | av_log(avctx, AV_LOG_ERROR, | |
235 | "XviD: Cannot write 2-pass pipe\n"); | |
236 | return -1; | |
237 | } | |
115329f1 | 238 | |
1ddadfa9 AT |
239 | if( avctx->stats_in == NULL ) { |
240 | av_log(avctx, AV_LOG_ERROR, | |
241 | "XviD: No 2-pass information loaded for second pass\n"); | |
242 | return -1; | |
243 | } | |
115329f1 DB |
244 | |
245 | if( strlen(avctx->stats_in) > | |
1ddadfa9 AT |
246 | write(fd, avctx->stats_in, strlen(avctx->stats_in)) ) { |
247 | close(fd); | |
248 | av_log(avctx, AV_LOG_ERROR, | |
249 | "XviD: Cannot write to 2-pass pipe\n"); | |
250 | return -1; | |
251 | } | |
115329f1 | 252 | |
1ddadfa9 AT |
253 | close(fd); |
254 | rc2pass2.filename = x->twopassfile; | |
255 | plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2; | |
256 | plugins[xvid_enc_create.num_plugins].param = &rc2pass2; | |
257 | xvid_enc_create.num_plugins++; | |
258 | } else if( !(xvid_flags & CODEC_FLAG_QSCALE) ) { | |
259 | /* Single Pass Bitrate Control! */ | |
260 | memset(&single, 0, sizeof(xvid_plugin_single_t)); | |
261 | single.version = XVID_VERSION; | |
262 | single.bitrate = avctx->bit_rate; | |
115329f1 | 263 | |
1ddadfa9 AT |
264 | plugins[xvid_enc_create.num_plugins].func = xvid_plugin_single; |
265 | plugins[xvid_enc_create.num_plugins].param = &single; | |
266 | xvid_enc_create.num_plugins++; | |
267 | } | |
268 | ||
269 | /* Luminance Masking */ | |
270 | if( 0.0 != avctx->lumi_masking ) { | |
271 | plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking; | |
272 | plugins[xvid_enc_create.num_plugins].param = NULL; | |
273 | xvid_enc_create.num_plugins++; | |
274 | } | |
275 | ||
276 | /* Frame Rate and Key Frames */ | |
277 | xvid_correct_framerate(avctx); | |
c0df9d75 MN |
278 | xvid_enc_create.fincr = avctx->time_base.num; |
279 | xvid_enc_create.fbase = avctx->time_base.den; | |
1ddadfa9 AT |
280 | if( avctx->gop_size > 0 ) |
281 | xvid_enc_create.max_key_interval = avctx->gop_size; | |
282 | else | |
283 | xvid_enc_create.max_key_interval = 240; /* XviD's best default */ | |
284 | ||
285 | /* Quants */ | |
115329f1 | 286 | if( xvid_flags & CODEC_FLAG_QSCALE ) x->qscale = 1; |
1ddadfa9 | 287 | else x->qscale = 0; |
115329f1 | 288 | |
1ddadfa9 AT |
289 | xvid_enc_create.min_quant[0] = avctx->qmin; |
290 | xvid_enc_create.min_quant[1] = avctx->qmin; | |
291 | xvid_enc_create.min_quant[2] = avctx->qmin; | |
292 | xvid_enc_create.max_quant[0] = avctx->qmax; | |
293 | xvid_enc_create.max_quant[1] = avctx->qmax; | |
294 | xvid_enc_create.max_quant[2] = avctx->qmax; | |
115329f1 | 295 | |
1ddadfa9 AT |
296 | /* Quant Matrices */ |
297 | x->intra_matrix = x->inter_matrix = NULL; | |
298 | if( avctx->mpeg_quant ) | |
299 | x->vol_flags |= XVID_VOL_MPEGQUANT; | |
300 | if( (avctx->intra_matrix || avctx->inter_matrix) ) { | |
301 | x->vol_flags |= XVID_VOL_MPEGQUANT; | |
115329f1 | 302 | |
1ddadfa9 AT |
303 | if( avctx->intra_matrix ) { |
304 | intra = avctx->intra_matrix; | |
305 | x->intra_matrix = av_malloc(sizeof(unsigned char) * 64); | |
115329f1 | 306 | } else |
1ddadfa9 AT |
307 | intra = NULL; |
308 | if( avctx->inter_matrix ) { | |
309 | inter = avctx->inter_matrix; | |
310 | x->inter_matrix = av_malloc(sizeof(unsigned char) * 64); | |
115329f1 | 311 | } else |
1ddadfa9 | 312 | inter = NULL; |
115329f1 | 313 | |
1ddadfa9 AT |
314 | for( i = 0; i < 64; i++ ) { |
315 | if( intra ) | |
316 | x->intra_matrix[i] = (unsigned char)intra[i]; | |
317 | if( inter ) | |
318 | x->inter_matrix[i] = (unsigned char)inter[i]; | |
319 | } | |
320 | } | |
115329f1 | 321 | |
1ddadfa9 AT |
322 | /* Misc Settings */ |
323 | xvid_enc_create.frame_drop_ratio = 0; | |
324 | xvid_enc_create.global = 0; | |
115329f1 | 325 | if( xvid_flags & CODEC_FLAG_CLOSED_GOP ) |
1ddadfa9 AT |
326 | xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP; |
327 | ||
328 | /* Determines which codec mode we are operating in */ | |
329 | avctx->extradata = NULL; | |
330 | avctx->extradata_size = 0; | |
331 | if( xvid_flags & CODEC_FLAG_GLOBAL_HEADER ) { | |
332 | /* In this case, we are claiming to be MPEG4 */ | |
333 | x->quicktime_format = 1; | |
334 | avctx->codec_id = CODEC_ID_MPEG4; | |
335 | } else { | |
336 | /* We are claiming to be XviD */ | |
337 | x->quicktime_format = 0; | |
aa770811 RP |
338 | if(!avctx->codec_tag) |
339 | avctx->codec_tag = ff_get_fourcc("xvid"); | |
115329f1 DB |
340 | } |
341 | ||
1ddadfa9 AT |
342 | /* Bframes */ |
343 | xvid_enc_create.max_bframes = avctx->max_b_frames; | |
0adba3d8 | 344 | xvid_enc_create.bquant_offset = 100 * avctx->b_quant_offset; |
1ddadfa9 AT |
345 | xvid_enc_create.bquant_ratio = 100 * avctx->b_quant_factor; |
346 | if( avctx->max_b_frames > 0 && !x->quicktime_format ) xvid_enc_create.global |= XVID_GLOBAL_PACKED; | |
115329f1 | 347 | |
1ddadfa9 AT |
348 | /* Create encoder context */ |
349 | xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); | |
350 | if( xerr ) { | |
351 | av_log(avctx, AV_LOG_ERROR, "XviD: Could not create encoder reference\n"); | |
352 | return -1; | |
353 | } | |
115329f1 | 354 | |
1ddadfa9 AT |
355 | x->encoder_handle = xvid_enc_create.handle; |
356 | avctx->coded_frame = &x->encoded_picture; | |
357 | ||
358 | return 0; | |
359 | } | |
360 | ||
115329f1 | 361 | /** |
1ddadfa9 AT |
362 | * Encodes a single frame. |
363 | * | |
364 | * @param avctx AVCodecContext pointer to context | |
365 | * @param frame Pointer to encoded frame buffer | |
366 | * @param buf_size Size of encoded frame buffer | |
367 | * @param data Pointer to AVFrame of unencoded frame | |
368 | * @return Returns 0 on success, -1 on failure | |
369 | */ | |
370 | int ff_xvid_encode_frame(AVCodecContext *avctx, | |
371 | unsigned char *frame, int buf_size, void *data) { | |
372 | int xerr, i; | |
373 | char *tmp; | |
374 | xvid_context_t *x = avctx->priv_data; | |
375 | AVFrame *picture = data; | |
376 | AVFrame *p = &(x->encoded_picture); | |
115329f1 | 377 | |
1ddadfa9 AT |
378 | xvid_enc_frame_t xvid_enc_frame; |
379 | xvid_enc_stats_t xvid_enc_stats; | |
115329f1 | 380 | |
1ddadfa9 AT |
381 | /* Start setting up the frame */ |
382 | memset(&xvid_enc_frame, 0, sizeof(xvid_enc_frame)); | |
383 | xvid_enc_frame.version = XVID_VERSION; | |
384 | memset(&xvid_enc_stats, 0, sizeof(xvid_enc_stats)); | |
385 | xvid_enc_stats.version = XVID_VERSION; | |
115329f1 | 386 | *p = *picture; |
1ddadfa9 AT |
387 | |
388 | /* Let XviD know where to put the frame. */ | |
389 | xvid_enc_frame.bitstream = frame; | |
390 | xvid_enc_frame.length = buf_size; | |
115329f1 | 391 | |
1ddadfa9 AT |
392 | /* Initialize input image fields */ |
393 | if( avctx->pix_fmt != PIX_FMT_YUV420P ) { | |
394 | av_log(avctx, AV_LOG_ERROR, "XviD: Color spaces other than 420p not supported\n"); | |
395 | return -1; | |
396 | } | |
115329f1 | 397 | |
1ddadfa9 AT |
398 | xvid_enc_frame.input.csp = XVID_CSP_PLANAR; /* YUV420P */ |
399 | ||
400 | for( i = 0; i < 4; i++ ) { | |
401 | xvid_enc_frame.input.plane[i] = picture->data[i]; | |
402 | xvid_enc_frame.input.stride[i] = picture->linesize[i]; | |
403 | } | |
404 | ||
405 | /* Encoder Flags */ | |
406 | xvid_enc_frame.vop_flags = x->vop_flags; | |
407 | xvid_enc_frame.vol_flags = x->vol_flags; | |
408 | xvid_enc_frame.motion = x->me_flags; | |
409 | xvid_enc_frame.type = XVID_TYPE_AUTO; | |
115329f1 | 410 | |
1ddadfa9 AT |
411 | /* Quant Setting */ |
412 | if( x->qscale ) xvid_enc_frame.quant = picture->quality / FF_QP2LAMBDA; | |
413 | else xvid_enc_frame.quant = 0; | |
115329f1 | 414 | |
1ddadfa9 AT |
415 | /* Matrices */ |
416 | xvid_enc_frame.quant_intra_matrix = x->intra_matrix; | |
417 | xvid_enc_frame.quant_inter_matrix = x->inter_matrix; | |
418 | ||
419 | /* Encode */ | |
115329f1 | 420 | xerr = xvid_encore(x->encoder_handle, XVID_ENC_ENCODE, |
1ddadfa9 AT |
421 | &xvid_enc_frame, &xvid_enc_stats); |
422 | ||
423 | /* Two-pass log buffer swapping */ | |
424 | avctx->stats_out = NULL; | |
425 | if( x->twopassbuffer ) { | |
426 | tmp = x->old_twopassbuffer; | |
427 | x->old_twopassbuffer = x->twopassbuffer; | |
428 | x->twopassbuffer = tmp; | |
429 | x->twopassbuffer[0] = 0; | |
430 | if( x->old_twopassbuffer[0] != 0 ) { | |
431 | avctx->stats_out = x->old_twopassbuffer; | |
432 | } | |
115329f1 DB |
433 | } |
434 | ||
1ddadfa9 AT |
435 | if( 0 <= xerr ) { |
436 | p->quality = xvid_enc_stats.quant * FF_QP2LAMBDA; | |
437 | if( xvid_enc_stats.type == XVID_TYPE_PVOP ) | |
438 | p->pict_type = FF_P_TYPE; | |
439 | else if( xvid_enc_stats.type == XVID_TYPE_BVOP ) | |
440 | p->pict_type = FF_B_TYPE; | |
441 | else if( xvid_enc_stats.type == XVID_TYPE_SVOP ) | |
9b21f056 | 442 | p->pict_type = FF_S_TYPE; |
1ddadfa9 AT |
443 | else |
444 | p->pict_type = FF_I_TYPE; | |
445 | if( xvid_enc_frame.out_flags & XVID_KEYFRAME ) { | |
446 | p->key_frame = 1; | |
447 | if( x->quicktime_format ) | |
115329f1 | 448 | return xvid_strip_vol_header(avctx, frame, |
1ddadfa9 | 449 | xvid_enc_stats.hlength, xerr); |
115329f1 | 450 | } else |
1ddadfa9 AT |
451 | p->key_frame = 0; |
452 | ||
453 | return xerr; | |
454 | } else { | |
455 | av_log(avctx, AV_LOG_ERROR, "XviD: Encoding Error Occurred: %i\n", xerr); | |
456 | return -1; | |
457 | } | |
458 | } | |
459 | ||
115329f1 | 460 | /** |
1ddadfa9 AT |
461 | * Destroys the private context for the encoder. |
462 | * All buffers are freed, and the XviD encoder context is destroyed. | |
463 | * | |
464 | * @param avctx AVCodecContext pointer to context | |
465 | * @return Returns 0, success guaranteed | |
466 | */ | |
467 | int ff_xvid_encode_close(AVCodecContext *avctx) { | |
468 | xvid_context_t *x = avctx->priv_data; | |
115329f1 | 469 | |
1ddadfa9 AT |
470 | xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL); |
471 | ||
472 | if( avctx->extradata != NULL ) | |
473 | av_free(avctx->extradata); | |
474 | if( x->twopassbuffer != NULL ) { | |
475 | av_free(x->twopassbuffer); | |
476 | av_free(x->old_twopassbuffer); | |
477 | } | |
478 | if( x->twopassfile != NULL ) | |
479 | av_free(x->twopassfile); | |
480 | if( x->intra_matrix != NULL ) | |
481 | av_free(x->intra_matrix); | |
482 | if( x->inter_matrix != NULL ) | |
483 | av_free(x->inter_matrix); | |
484 | ||
485 | return 0; | |
486 | } | |
487 | ||
115329f1 | 488 | /** |
1ddadfa9 AT |
489 | * Routine to create a global VO/VOL header for MP4 container. |
490 | * What we do here is extract the header from the XviD bitstream | |
491 | * as it is encoded. We also strip the repeated headers from the | |
492 | * bitstream when a global header is requested for MPEG-4 ISO | |
493 | * compliance. | |
494 | * | |
495 | * @param avctx AVCodecContext pointer to context | |
496 | * @param frame Pointer to encoded frame data | |
497 | * @param header_len Length of header to search | |
498 | * @param frame_len Length of encoded frame data | |
499 | * @return Returns new length of frame data | |
500 | */ | |
115329f1 DB |
501 | int xvid_strip_vol_header(AVCodecContext *avctx, |
502 | unsigned char *frame, | |
1ddadfa9 AT |
503 | unsigned int header_len, |
504 | unsigned int frame_len) { | |
505 | int vo_len = 0, i; | |
506 | ||
507 | for( i = 0; i < header_len - 3; i++ ) { | |
115329f1 | 508 | if( frame[i] == 0x00 && |
1ddadfa9 AT |
509 | frame[i+1] == 0x00 && |
510 | frame[i+2] == 0x01 && | |
511 | frame[i+3] == 0xB6 ) { | |
512 | vo_len = i; | |
513 | break; | |
115329f1 | 514 | } |
1ddadfa9 | 515 | } |
115329f1 | 516 | |
1ddadfa9 AT |
517 | if( vo_len > 0 ) { |
518 | /* We need to store the header, so extract it */ | |
519 | if( avctx->extradata == NULL ) { | |
520 | avctx->extradata = av_malloc(vo_len); | |
521 | memcpy(avctx->extradata, frame, vo_len); | |
522 | avctx->extradata_size = vo_len; | |
523 | } | |
524 | /* Less dangerous now, memmove properly copies the two | |
525 | chunks of overlapping data */ | |
526 | memmove(frame, &(frame[vo_len]), frame_len - vo_len); | |
527 | return frame_len - vo_len; | |
528 | } else | |
529 | return frame_len; | |
530 | } | |
531 | ||
532 | /** | |
533 | * Routine to correct a possibly erroneous framerate being fed to us. | |
115329f1 | 534 | * XviD currently chokes on framerates where the ticks per frame is |
1ddadfa9 | 535 | * extremely large. This function works to correct problems in this area |
115329f1 | 536 | * by estimating a new framerate and taking the simpler fraction of |
1ddadfa9 AT |
537 | * the two presented. |
538 | * | |
539 | * @param avctx Context that contains the framerate to correct. | |
540 | */ | |
541 | void xvid_correct_framerate(AVCodecContext *avctx) { | |
542 | int frate, fbase; | |
543 | int est_frate, est_fbase; | |
544 | int gcd; | |
545 | float est_fps, fps; | |
115329f1 | 546 | |
c0df9d75 MN |
547 | frate = avctx->time_base.den; |
548 | fbase = avctx->time_base.num; | |
115329f1 | 549 | |
1ddadfa9 AT |
550 | gcd = ff_gcd(frate, fbase); |
551 | if( gcd > 1 ) { | |
552 | frate /= gcd; | |
553 | fbase /= gcd; | |
554 | } | |
115329f1 | 555 | |
1ddadfa9 | 556 | if( frate <= 65000 && fbase <= 65000 ) { |
c0df9d75 MN |
557 | avctx->time_base.den = frate; |
558 | avctx->time_base.num = fbase; | |
1ddadfa9 AT |
559 | return; |
560 | } | |
115329f1 | 561 | |
1ddadfa9 AT |
562 | fps = (float)frate / (float)fbase; |
563 | est_fps = roundf(fps * 1000.0) / 1000.0; | |
564 | ||
565 | est_frate = (int)est_fps; | |
566 | if( est_fps > (int)est_fps ) { | |
567 | est_frate = (est_frate + 1) * 1000; | |
115329f1 | 568 | est_fbase = (int)roundf((float)est_frate / est_fps); |
1ddadfa9 AT |
569 | } else |
570 | est_fbase = 1; | |
571 | ||
572 | gcd = ff_gcd(est_frate, est_fbase); | |
573 | if( gcd > 1 ) { | |
574 | est_frate /= gcd; | |
575 | est_fbase /= gcd; | |
115329f1 DB |
576 | } |
577 | ||
1ddadfa9 | 578 | if( fbase > est_fbase ) { |
c0df9d75 MN |
579 | avctx->time_base.den = est_frate; |
580 | avctx->time_base.num = est_fbase; | |
115329f1 | 581 | av_log(avctx, AV_LOG_DEBUG, |
1ddadfa9 AT |
582 | "XviD: framerate re-estimated: %.2f, %.3f%% correction\n", |
583 | est_fps, (((est_fps - fps)/fps) * 100.0)); | |
584 | } else { | |
c0df9d75 MN |
585 | avctx->time_base.den = frate; |
586 | avctx->time_base.num = fbase; | |
1ddadfa9 AT |
587 | } |
588 | } | |
589 | ||
590 | /* | |
591 | * XviD 2-Pass Kludge Section | |
592 | * | |
593 | * XviD's default 2-pass doesn't allow us to create data as we need to, so | |
594 | * this section spends time replacing the first pass plugin so we can write | |
595 | * statistic information as libavcodec requests in. We have another kludge | |
596 | * that allows us to pass data to the second pass in XviD without a custom | |
597 | * rate-control plugin. | |
598 | */ | |
599 | ||
600 | /** | |
601 | * Initializes the two-pass plugin and context. | |
602 | * | |
603 | * @param param Input construction parameter structure | |
604 | * @param handle Private context handle | |
605 | * @return Returns XVID_ERR_xxxx on failure, or 0 on success. | |
606 | */ | |
607 | static int xvid_ff_2pass_create(xvid_plg_create_t * param, | |
608 | void ** handle) { | |
609 | xvid_ff_pass1_t *x = (xvid_ff_pass1_t *)param->param; | |
610 | char *log = x->context->twopassbuffer; | |
115329f1 | 611 | |
1ddadfa9 AT |
612 | /* Do a quick bounds check */ |
613 | if( log == NULL ) | |
614 | return XVID_ERR_FAIL; | |
115329f1 | 615 | |
1ddadfa9 AT |
616 | /* We use snprintf() */ |
617 | /* This is because we can safely prevent a buffer overflow */ | |
618 | log[0] = 0; | |
619 | snprintf(log, BUFFER_REMAINING(log), | |
620 | "# ffmpeg 2-pass log file, using xvid codec\n"); | |
621 | snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log), | |
622 | "# Do not modify. libxvidcore version: %d.%d.%d\n\n", | |
623 | XVID_VERSION_MAJOR(XVID_VERSION), | |
624 | XVID_VERSION_MINOR(XVID_VERSION), | |
625 | XVID_VERSION_PATCH(XVID_VERSION)); | |
115329f1 | 626 | |
1ddadfa9 | 627 | *handle = x->context; |
115329f1 | 628 | return 0; |
1ddadfa9 AT |
629 | } |
630 | ||
631 | /** | |
632 | * Destroys the two-pass plugin context. | |
633 | * | |
634 | * @param ref Context pointer for the plugin | |
635 | * @param param Destrooy context | |
636 | * @return Returns 0, success guaranteed | |
637 | */ | |
115329f1 | 638 | static int xvid_ff_2pass_destroy(xvid_context_t *ref, |
1ddadfa9 AT |
639 | xvid_plg_destroy_t *param) { |
640 | /* Currently cannot think of anything to do on destruction */ | |
641 | /* Still, the framework should be here for reference/use */ | |
642 | if( ref->twopassbuffer != NULL ) | |
643 | ref->twopassbuffer[0] = 0; | |
644 | return 0; | |
645 | } | |
646 | ||
647 | /** | |
648 | * Enables fast encode mode during the first pass. | |
649 | * | |
650 | * @param ref Context pointer for the plugin | |
651 | * @param param Frame data | |
652 | * @return Returns 0, success guaranteed | |
653 | */ | |
654 | static int xvid_ff_2pass_before(xvid_context_t *ref, | |
655 | xvid_plg_data_t *param) { | |
656 | int motion_remove; | |
115329f1 | 657 | int motion_replacements; |
1ddadfa9 | 658 | int vop_remove; |
115329f1 DB |
659 | |
660 | /* Nothing to do here, result is changed too much */ | |
1ddadfa9 | 661 | if( param->zone && param->zone->mode == XVID_ZONE_QUANT ) |
115329f1 DB |
662 | return 0; |
663 | ||
664 | /* We can implement a 'turbo' first pass mode here */ | |
665 | param->quant = 2; | |
666 | ||
1ddadfa9 AT |
667 | /* Init values */ |
668 | motion_remove = ~XVID_ME_CHROMA_PVOP & | |
669 | ~XVID_ME_CHROMA_BVOP & | |
670 | ~XVID_ME_EXTSEARCH16 & | |
671 | ~XVID_ME_ADVANCEDDIAMOND16; | |
672 | motion_replacements = XVID_ME_FAST_MODEINTERPOLATE | | |
673 | XVID_ME_SKIP_DELTASEARCH | | |
674 | XVID_ME_FASTREFINE16 | | |
675 | XVID_ME_BFRAME_EARLYSTOP; | |
676 | vop_remove = ~XVID_VOP_MODEDECISION_RD & | |
677 | ~XVID_VOP_FAST_MODEDECISION_RD & | |
678 | ~XVID_VOP_TRELLISQUANT & | |
679 | ~XVID_VOP_INTER4V & | |
680 | ~XVID_VOP_HQACPRED; | |
115329f1 | 681 | |
1ddadfa9 AT |
682 | param->vol_flags &= ~XVID_VOL_GMC; |
683 | param->vop_flags &= vop_remove; | |
684 | param->motion_flags &= motion_remove; | |
115329f1 DB |
685 | param->motion_flags |= motion_replacements; |
686 | ||
687 | return 0; | |
1ddadfa9 AT |
688 | } |
689 | ||
690 | /** | |
691 | * Captures statistic data and writes it during first pass. | |
692 | * | |
693 | * @param ref Context pointer for the plugin | |
694 | * @param param Statistic data | |
695 | * @return Returns XVID_ERR_xxxx on failure, or 0 on success | |
696 | */ | |
697 | static int xvid_ff_2pass_after(xvid_context_t *ref, | |
698 | xvid_plg_data_t *param) { | |
699 | char *log = ref->twopassbuffer; | |
700 | char *frame_types = " ipbs"; | |
701 | char frame_type; | |
115329f1 | 702 | |
1ddadfa9 AT |
703 | /* Quick bounds check */ |
704 | if( log == NULL ) | |
705 | return XVID_ERR_FAIL; | |
115329f1 | 706 | |
1ddadfa9 AT |
707 | /* Convert the type given to us into a character */ |
708 | if( param->type < 5 && param->type > 0 ) { | |
709 | frame_type = frame_types[param->type]; | |
710 | } else { | |
711 | return XVID_ERR_FAIL; | |
712 | } | |
115329f1 | 713 | |
1ddadfa9 AT |
714 | snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log), |
715 | "%c %d %d %d %d %d %d\n", | |
115329f1 | 716 | frame_type, param->stats.quant, param->stats.kblks, param->stats.mblks, |
1ddadfa9 | 717 | param->stats.ublks, param->stats.length, param->stats.hlength); |
115329f1 | 718 | |
1ddadfa9 AT |
719 | return 0; |
720 | } | |
721 | ||
722 | /** | |
723 | * Dispatch function for our custom plugin. | |
724 | * This handles the dispatch for the XviD plugin. It passes data | |
725 | * on to other functions for actual processing. | |
726 | * | |
727 | * @param ref Context pointer for the plugin | |
728 | * @param cmd The task given for us to complete | |
729 | * @param p1 First parameter (varies) | |
730 | * @param p2 Second parameter (varies) | |
731 | * @return Returns XVID_ERR_xxxx on failure, or 0 on success | |
732 | */ | |
733 | int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2) { | |
734 | switch( cmd ) { | |
735 | case XVID_PLG_INFO: | |
736 | case XVID_PLG_FRAME: | |
737 | return 0; | |
738 | ||
739 | case XVID_PLG_BEFORE: | |
740 | return xvid_ff_2pass_before(ref, p1); | |
115329f1 | 741 | |
1ddadfa9 AT |
742 | case XVID_PLG_CREATE: |
743 | return xvid_ff_2pass_create(p1, p2); | |
115329f1 | 744 | |
1ddadfa9 AT |
745 | case XVID_PLG_AFTER: |
746 | return xvid_ff_2pass_after(ref, p1); | |
115329f1 | 747 | |
1ddadfa9 AT |
748 | case XVID_PLG_DESTROY: |
749 | return xvid_ff_2pass_destroy(ref, p1); | |
115329f1 | 750 | |
1ddadfa9 AT |
751 | default: |
752 | return XVID_ERR_FAIL; | |
753 | } | |
754 | } | |
755 | ||
756 | /** | |
757 | * XviD codec definition for libavcodec. | |
758 | */ | |
759 | AVCodec xvid_encoder = { | |
760 | "xvid", | |
761 | CODEC_TYPE_VIDEO, | |
762 | CODEC_ID_XVID, | |
763 | sizeof(xvid_context_t), | |
764 | ff_xvid_encode_init, | |
765 | ff_xvid_encode_frame, | |
1449b722 MN |
766 | ff_xvid_encode_close, |
767 | .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, | |
1ddadfa9 | 768 | }; |