blob: d916f117141eb1d179ba0e13e2b91535dc21ea52
1 | /* |
2 | * Interface to xvidcore for MPEG-4 encoding |
3 | * Copyright (c) 2004 Adam Thayer <krevnik@comcast.net> |
4 | * |
5 | * This file is part of FFmpeg. |
6 | * |
7 | * FFmpeg is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Lesser General Public |
9 | * License as published by the Free Software Foundation; either |
10 | * version 2.1 of the License, or (at your option) any later version. |
11 | * |
12 | * FFmpeg is distributed in the hope that it will be useful, |
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 |
18 | * License along with FFmpeg; if not, write to the Free Software |
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | */ |
21 | |
22 | /** |
23 | * @file |
24 | * Interface to xvidcore for MPEG-4 compliant encoding. |
25 | * @author Adam Thayer (krevnik@comcast.net) |
26 | */ |
27 | |
28 | #include <stdio.h> |
29 | #include <string.h> |
30 | #include <xvid.h> |
31 | |
32 | #include "libavutil/avassert.h" |
33 | #include "libavutil/cpu.h" |
34 | #include "libavutil/file.h" |
35 | #include "libavutil/internal.h" |
36 | #include "libavutil/intreadwrite.h" |
37 | #include "libavutil/mathematics.h" |
38 | #include "libavutil/mem.h" |
39 | #include "libavutil/opt.h" |
40 | |
41 | #include "avcodec.h" |
42 | #include "internal.h" |
43 | #include "libxvid.h" |
44 | #include "mpegutils.h" |
45 | |
46 | #if HAVE_UNISTD_H |
47 | #include <unistd.h> |
48 | #endif |
49 | |
50 | #if HAVE_IO_H |
51 | #include <io.h> |
52 | #endif |
53 | |
54 | /** |
55 | * Buffer management macros. |
56 | */ |
57 | #define BUFFER_SIZE 1024 |
58 | #define BUFFER_REMAINING(x) (BUFFER_SIZE - strlen(x)) |
59 | #define BUFFER_CAT(x) (&((x)[strlen(x)])) |
60 | |
61 | /** |
62 | * Structure for the private Xvid context. |
63 | * This stores all the private context for the codec. |
64 | */ |
65 | struct xvid_context { |
66 | AVClass *class; |
67 | void *encoder_handle; /**< Handle for Xvid encoder */ |
68 | int xsize; /**< Frame x size */ |
69 | int ysize; /**< Frame y size */ |
70 | int vop_flags; /**< VOP flags for Xvid encoder */ |
71 | int vol_flags; /**< VOL flags for Xvid encoder */ |
72 | int me_flags; /**< Motion Estimation flags */ |
73 | int qscale; /**< Do we use constant scale? */ |
74 | int quicktime_format; /**< Are we in a QT-based format? */ |
75 | char *twopassbuffer; /**< Character buffer for two-pass */ |
76 | char *old_twopassbuffer; /**< Old character buffer (two-pass) */ |
77 | char *twopassfile; /**< second pass temp file name */ |
78 | int twopassfd; |
79 | unsigned char *intra_matrix; /**< P-Frame Quant Matrix */ |
80 | unsigned char *inter_matrix; /**< I-Frame Quant Matrix */ |
81 | int lumi_aq; /**< Lumi masking as an aq method */ |
82 | int variance_aq; /**< Variance adaptive quantization */ |
83 | int ssim; /**< SSIM information display mode */ |
84 | int ssim_acc; /**< SSIM accuracy. 0: accurate. 4: fast. */ |
85 | int gmc; |
86 | int me_quality; /**< Motion estimation quality. 0: fast 6: best. */ |
87 | int mpeg_quant; /**< Quantization type. 0: H.263, 1: MPEG */ |
88 | }; |
89 | |
90 | /** |
91 | * Structure for the private first-pass plugin. |
92 | */ |
93 | struct xvid_ff_pass1 { |
94 | int version; /**< Xvid version */ |
95 | struct xvid_context *context; /**< Pointer to private context */ |
96 | }; |
97 | |
98 | static int xvid_encode_close(AVCodecContext *avctx); |
99 | static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt, |
100 | const AVFrame *picture, int *got_packet); |
101 | |
102 | |
103 | /* |
104 | * Xvid 2-Pass Kludge Section |
105 | * |
106 | * Xvid's default 2-pass doesn't allow us to create data as we need to, so |
107 | * this section spends time replacing the first pass plugin so we can write |
108 | * statistic information as libavcodec requests in. We have another kludge |
109 | * that allows us to pass data to the second pass in Xvid without a custom |
110 | * rate-control plugin. |
111 | */ |
112 | |
113 | /** |
114 | * Initialize the two-pass plugin and context. |
115 | * |
116 | * @param param Input construction parameter structure |
117 | * @param handle Private context handle |
118 | * @return Returns XVID_ERR_xxxx on failure, or 0 on success. |
119 | */ |
120 | static int xvid_ff_2pass_create(xvid_plg_create_t *param, void **handle) |
121 | { |
122 | struct xvid_ff_pass1 *x = (struct xvid_ff_pass1 *) param->param; |
123 | char *log = x->context->twopassbuffer; |
124 | |
125 | /* Do a quick bounds check */ |
126 | if (!log) |
127 | return XVID_ERR_FAIL; |
128 | |
129 | /* We use snprintf() */ |
130 | /* This is because we can safely prevent a buffer overflow */ |
131 | log[0] = 0; |
132 | snprintf(log, BUFFER_REMAINING(log), |
133 | "# ffmpeg 2-pass log file, using xvid codec\n"); |
134 | snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log), |
135 | "# Do not modify. libxvidcore version: %d.%d.%d\n\n", |
136 | XVID_VERSION_MAJOR(XVID_VERSION), |
137 | XVID_VERSION_MINOR(XVID_VERSION), |
138 | XVID_VERSION_PATCH(XVID_VERSION)); |
139 | |
140 | *handle = x->context; |
141 | return 0; |
142 | } |
143 | |
144 | /** |
145 | * Destroy the two-pass plugin context. |
146 | * |
147 | * @param ref Context pointer for the plugin |
148 | * @param param Destroy context |
149 | * @return Returns 0, success guaranteed |
150 | */ |
151 | static int xvid_ff_2pass_destroy(struct xvid_context *ref, |
152 | xvid_plg_destroy_t *param) |
153 | { |
154 | /* Currently cannot think of anything to do on destruction */ |
155 | /* Still, the framework should be here for reference/use */ |
156 | if (ref->twopassbuffer) |
157 | ref->twopassbuffer[0] = 0; |
158 | return 0; |
159 | } |
160 | |
161 | /** |
162 | * Enable fast encode mode during the first pass. |
163 | * |
164 | * @param ref Context pointer for the plugin |
165 | * @param param Frame data |
166 | * @return Returns 0, success guaranteed |
167 | */ |
168 | static int xvid_ff_2pass_before(struct xvid_context *ref, |
169 | xvid_plg_data_t *param) |
170 | { |
171 | int motion_remove; |
172 | int motion_replacements; |
173 | int vop_remove; |
174 | |
175 | /* Nothing to do here, result is changed too much */ |
176 | if (param->zone && param->zone->mode == XVID_ZONE_QUANT) |
177 | return 0; |
178 | |
179 | /* We can implement a 'turbo' first pass mode here */ |
180 | param->quant = 2; |
181 | |
182 | /* Init values */ |
183 | motion_remove = ~XVID_ME_CHROMA_PVOP & |
184 | ~XVID_ME_CHROMA_BVOP & |
185 | ~XVID_ME_EXTSEARCH16 & |
186 | ~XVID_ME_ADVANCEDDIAMOND16; |
187 | motion_replacements = XVID_ME_FAST_MODEINTERPOLATE | |
188 | XVID_ME_SKIP_DELTASEARCH | |
189 | XVID_ME_FASTREFINE16 | |
190 | XVID_ME_BFRAME_EARLYSTOP; |
191 | vop_remove = ~XVID_VOP_MODEDECISION_RD & |
192 | ~XVID_VOP_FAST_MODEDECISION_RD & |
193 | ~XVID_VOP_TRELLISQUANT & |
194 | ~XVID_VOP_INTER4V & |
195 | ~XVID_VOP_HQACPRED; |
196 | |
197 | param->vol_flags &= ~XVID_VOL_GMC; |
198 | param->vop_flags &= vop_remove; |
199 | param->motion_flags &= motion_remove; |
200 | param->motion_flags |= motion_replacements; |
201 | |
202 | return 0; |
203 | } |
204 | |
205 | /** |
206 | * Capture statistic data and write it during first pass. |
207 | * |
208 | * @param ref Context pointer for the plugin |
209 | * @param param Statistic data |
210 | * @return Returns XVID_ERR_xxxx on failure, or 0 on success |
211 | */ |
212 | static int xvid_ff_2pass_after(struct xvid_context *ref, |
213 | xvid_plg_data_t *param) |
214 | { |
215 | char *log = ref->twopassbuffer; |
216 | const char *frame_types = " ipbs"; |
217 | char frame_type; |
218 | |
219 | /* Quick bounds check */ |
220 | if (!log) |
221 | return XVID_ERR_FAIL; |
222 | |
223 | /* Convert the type given to us into a character */ |
224 | if (param->type < 5 && param->type > 0) |
225 | frame_type = frame_types[param->type]; |
226 | else |
227 | return XVID_ERR_FAIL; |
228 | |
229 | snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log), |
230 | "%c %d %d %d %d %d %d\n", |
231 | frame_type, param->stats.quant, param->stats.kblks, |
232 | param->stats.mblks, param->stats.ublks, |
233 | param->stats.length, param->stats.hlength); |
234 | |
235 | return 0; |
236 | } |
237 | |
238 | /** |
239 | * Dispatch function for our custom plugin. |
240 | * This handles the dispatch for the Xvid plugin. It passes data |
241 | * on to other functions for actual processing. |
242 | * |
243 | * @param ref Context pointer for the plugin |
244 | * @param cmd The task given for us to complete |
245 | * @param p1 First parameter (varies) |
246 | * @param p2 Second parameter (varies) |
247 | * @return Returns XVID_ERR_xxxx on failure, or 0 on success |
248 | */ |
249 | static int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2) |
250 | { |
251 | switch (cmd) { |
252 | case XVID_PLG_INFO: |
253 | case XVID_PLG_FRAME: |
254 | return 0; |
255 | case XVID_PLG_BEFORE: |
256 | return xvid_ff_2pass_before(ref, p1); |
257 | case XVID_PLG_CREATE: |
258 | return xvid_ff_2pass_create(p1, p2); |
259 | case XVID_PLG_AFTER: |
260 | return xvid_ff_2pass_after(ref, p1); |
261 | case XVID_PLG_DESTROY: |
262 | return xvid_ff_2pass_destroy(ref, p1); |
263 | default: |
264 | return XVID_ERR_FAIL; |
265 | } |
266 | } |
267 | |
268 | /** |
269 | * Routine to create a global VO/VOL header for MP4 container. |
270 | * What we do here is extract the header from the Xvid bitstream |
271 | * as it is encoded. We also strip the repeated headers from the |
272 | * bitstream when a global header is requested for MPEG-4 ISO |
273 | * compliance. |
274 | * |
275 | * @param avctx AVCodecContext pointer to context |
276 | * @param frame Pointer to encoded frame data |
277 | * @param header_len Length of header to search |
278 | * @param frame_len Length of encoded frame data |
279 | * @return Returns new length of frame data |
280 | */ |
281 | static int xvid_strip_vol_header(AVCodecContext *avctx, AVPacket *pkt, |
282 | unsigned int header_len, |
283 | unsigned int frame_len) |
284 | { |
285 | int vo_len = 0, i; |
286 | |
287 | for (i = 0; i < header_len - 3; i++) { |
288 | if (pkt->data[i] == 0x00 && |
289 | pkt->data[i + 1] == 0x00 && |
290 | pkt->data[i + 2] == 0x01 && |
291 | pkt->data[i + 3] == 0xB6) { |
292 | vo_len = i; |
293 | break; |
294 | } |
295 | } |
296 | |
297 | if (vo_len > 0) { |
298 | /* We need to store the header, so extract it */ |
299 | if (!avctx->extradata) { |
300 | avctx->extradata = av_malloc(vo_len); |
301 | if (!avctx->extradata) |
302 | return AVERROR(ENOMEM); |
303 | memcpy(avctx->extradata, pkt->data, vo_len); |
304 | avctx->extradata_size = vo_len; |
305 | } |
306 | /* Less dangerous now, memmove properly copies the two |
307 | * chunks of overlapping data */ |
308 | memmove(pkt->data, &pkt->data[vo_len], frame_len - vo_len); |
309 | pkt->size = frame_len - vo_len; |
310 | } |
311 | return 0; |
312 | } |
313 | |
314 | /** |
315 | * Routine to correct a possibly erroneous framerate being fed to us. |
316 | * Xvid currently chokes on framerates where the ticks per frame is |
317 | * extremely large. This function works to correct problems in this area |
318 | * by estimating a new framerate and taking the simpler fraction of |
319 | * the two presented. |
320 | * |
321 | * @param avctx Context that contains the framerate to correct. |
322 | */ |
323 | static void xvid_correct_framerate(AVCodecContext *avctx) |
324 | { |
325 | int frate, fbase; |
326 | int est_frate, est_fbase; |
327 | int gcd; |
328 | float est_fps, fps; |
329 | |
330 | frate = avctx->time_base.den; |
331 | fbase = avctx->time_base.num; |
332 | |
333 | gcd = av_gcd(frate, fbase); |
334 | if (gcd > 1) { |
335 | frate /= gcd; |
336 | fbase /= gcd; |
337 | } |
338 | |
339 | if (frate <= 65000 && fbase <= 65000) { |
340 | avctx->time_base.den = frate; |
341 | avctx->time_base.num = fbase; |
342 | return; |
343 | } |
344 | |
345 | fps = (float) frate / (float) fbase; |
346 | est_fps = roundf(fps * 1000.0) / 1000.0; |
347 | |
348 | est_frate = (int) est_fps; |
349 | if (est_fps > (int) est_fps) { |
350 | est_frate = (est_frate + 1) * 1000; |
351 | est_fbase = (int) roundf((float) est_frate / est_fps); |
352 | } else |
353 | est_fbase = 1; |
354 | |
355 | gcd = av_gcd(est_frate, est_fbase); |
356 | if (gcd > 1) { |
357 | est_frate /= gcd; |
358 | est_fbase /= gcd; |
359 | } |
360 | |
361 | if (fbase > est_fbase) { |
362 | avctx->time_base.den = est_frate; |
363 | avctx->time_base.num = est_fbase; |
364 | av_log(avctx, AV_LOG_DEBUG, |
365 | "Xvid: framerate re-estimated: %.2f, %.3f%% correction\n", |
366 | est_fps, (((est_fps - fps) / fps) * 100.0)); |
367 | } else { |
368 | avctx->time_base.den = frate; |
369 | avctx->time_base.num = fbase; |
370 | } |
371 | } |
372 | |
373 | static av_cold int xvid_encode_init(AVCodecContext *avctx) |
374 | { |
375 | int xerr, i, ret = -1; |
376 | int xvid_flags = avctx->flags; |
377 | struct xvid_context *x = avctx->priv_data; |
378 | uint16_t *intra, *inter; |
379 | int fd; |
380 | |
381 | xvid_plugin_single_t single = { 0 }; |
382 | struct xvid_ff_pass1 rc2pass1 = { 0 }; |
383 | xvid_plugin_2pass2_t rc2pass2 = { 0 }; |
384 | xvid_plugin_lumimasking_t masking_l = { 0 }; /* For lumi masking */ |
385 | xvid_plugin_lumimasking_t masking_v = { 0 }; /* For variance AQ */ |
386 | xvid_plugin_ssim_t ssim = { 0 }; |
387 | xvid_gbl_init_t xvid_gbl_init = { 0 }; |
388 | xvid_enc_create_t xvid_enc_create = { 0 }; |
389 | xvid_enc_plugin_t plugins[4]; |
390 | |
391 | x->twopassfd = -1; |
392 | |
393 | /* Bring in VOP flags from ffmpeg command-line */ |
394 | x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */ |
395 | if (xvid_flags & AV_CODEC_FLAG_4MV) |
396 | x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */ |
397 | if (avctx->trellis) |
398 | x->vop_flags |= XVID_VOP_TRELLISQUANT; /* Level 5 */ |
399 | if (xvid_flags & AV_CODEC_FLAG_AC_PRED) |
400 | x->vop_flags |= XVID_VOP_HQACPRED; /* Level 6 */ |
401 | if (xvid_flags & AV_CODEC_FLAG_GRAY) |
402 | x->vop_flags |= XVID_VOP_GREYSCALE; |
403 | |
404 | /* Decide which ME quality setting to use */ |
405 | x->me_flags = 0; |
406 | switch (x->me_quality) { |
407 | case 6: |
408 | case 5: |
409 | x->me_flags |= XVID_ME_EXTSEARCH16 | |
410 | XVID_ME_EXTSEARCH8; |
411 | case 4: |
412 | case 3: |
413 | x->me_flags |= XVID_ME_ADVANCEDDIAMOND8 | |
414 | XVID_ME_HALFPELREFINE8 | |
415 | XVID_ME_CHROMA_PVOP | |
416 | XVID_ME_CHROMA_BVOP; |
417 | case 2: |
418 | case 1: |
419 | x->me_flags |= XVID_ME_ADVANCEDDIAMOND16 | |
420 | XVID_ME_HALFPELREFINE16; |
421 | #if FF_API_MOTION_EST |
422 | FF_DISABLE_DEPRECATION_WARNINGS |
423 | break; |
424 | default: |
425 | switch (avctx->me_method) { |
426 | case ME_FULL: /* Quality 6 */ |
427 | x->me_flags |= XVID_ME_EXTSEARCH16 | |
428 | XVID_ME_EXTSEARCH8; |
429 | case ME_EPZS: /* Quality 4 */ |
430 | x->me_flags |= XVID_ME_ADVANCEDDIAMOND8 | |
431 | XVID_ME_HALFPELREFINE8 | |
432 | XVID_ME_CHROMA_PVOP | |
433 | XVID_ME_CHROMA_BVOP; |
434 | case ME_LOG: /* Quality 2 */ |
435 | case ME_PHODS: |
436 | case ME_X1: |
437 | x->me_flags |= XVID_ME_ADVANCEDDIAMOND16 | |
438 | XVID_ME_HALFPELREFINE16; |
439 | case ME_ZERO: /* Quality 0 */ |
440 | default: |
441 | break; |
442 | } |
443 | FF_ENABLE_DEPRECATION_WARNINGS |
444 | #endif |
445 | } |
446 | |
447 | /* Decide how we should decide blocks */ |
448 | switch (avctx->mb_decision) { |
449 | case 2: |
450 | x->vop_flags |= XVID_VOP_MODEDECISION_RD; |
451 | x->me_flags |= XVID_ME_HALFPELREFINE8_RD | |
452 | XVID_ME_QUARTERPELREFINE8_RD | |
453 | XVID_ME_EXTSEARCH_RD | |
454 | XVID_ME_CHECKPREDICTION_RD; |
455 | case 1: |
456 | if (!(x->vop_flags & XVID_VOP_MODEDECISION_RD)) |
457 | x->vop_flags |= XVID_VOP_FAST_MODEDECISION_RD; |
458 | x->me_flags |= XVID_ME_HALFPELREFINE16_RD | |
459 | XVID_ME_QUARTERPELREFINE16_RD; |
460 | default: |
461 | break; |
462 | } |
463 | |
464 | /* Bring in VOL flags from ffmpeg command-line */ |
465 | #if FF_API_GMC |
466 | if (avctx->flags & CODEC_FLAG_GMC) |
467 | x->gmc = 1; |
468 | #endif |
469 | |
470 | x->vol_flags = 0; |
471 | if (x->gmc) { |
472 | x->vol_flags |= XVID_VOL_GMC; |
473 | x->me_flags |= XVID_ME_GME_REFINE; |
474 | } |
475 | if (xvid_flags & AV_CODEC_FLAG_QPEL) { |
476 | x->vol_flags |= XVID_VOL_QUARTERPEL; |
477 | x->me_flags |= XVID_ME_QUARTERPELREFINE16; |
478 | if (x->vop_flags & XVID_VOP_INTER4V) |
479 | x->me_flags |= XVID_ME_QUARTERPELREFINE8; |
480 | } |
481 | |
482 | xvid_gbl_init.version = XVID_VERSION; |
483 | xvid_gbl_init.debug = 0; |
484 | xvid_gbl_init.cpu_flags = 0; |
485 | |
486 | /* Initialize */ |
487 | xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL); |
488 | |
489 | /* Create the encoder reference */ |
490 | xvid_enc_create.version = XVID_VERSION; |
491 | |
492 | /* Store the desired frame size */ |
493 | xvid_enc_create.width = |
494 | x->xsize = avctx->width; |
495 | xvid_enc_create.height = |
496 | x->ysize = avctx->height; |
497 | |
498 | /* Xvid can determine the proper profile to use */ |
499 | /* xvid_enc_create.profile = XVID_PROFILE_S_L3; */ |
500 | |
501 | /* We don't use zones */ |
502 | xvid_enc_create.zones = NULL; |
503 | xvid_enc_create.num_zones = 0; |
504 | |
505 | xvid_enc_create.num_threads = avctx->thread_count; |
506 | #if (XVID_VERSION <= 0x010303) && (XVID_VERSION >= 0x010300) |
507 | /* workaround for a bug in libxvidcore */ |
508 | if (avctx->height <= 16) { |
509 | if (avctx->thread_count < 2) { |
510 | xvid_enc_create.num_threads = 0; |
511 | } else { |
512 | av_log(avctx, AV_LOG_ERROR, |
513 | "Too small height for threads > 1."); |
514 | return AVERROR(EINVAL); |
515 | } |
516 | } |
517 | #endif |
518 | |
519 | xvid_enc_create.plugins = plugins; |
520 | xvid_enc_create.num_plugins = 0; |
521 | |
522 | /* Initialize Buffers */ |
523 | x->twopassbuffer = NULL; |
524 | x->old_twopassbuffer = NULL; |
525 | x->twopassfile = NULL; |
526 | |
527 | if (xvid_flags & AV_CODEC_FLAG_PASS1) { |
528 | rc2pass1.version = XVID_VERSION; |
529 | rc2pass1.context = x; |
530 | x->twopassbuffer = av_malloc(BUFFER_SIZE); |
531 | x->old_twopassbuffer = av_malloc(BUFFER_SIZE); |
532 | if (!x->twopassbuffer || !x->old_twopassbuffer) { |
533 | av_log(avctx, AV_LOG_ERROR, |
534 | "Xvid: Cannot allocate 2-pass log buffers\n"); |
535 | return AVERROR(ENOMEM); |
536 | } |
537 | x->twopassbuffer[0] = |
538 | x->old_twopassbuffer[0] = 0; |
539 | |
540 | plugins[xvid_enc_create.num_plugins].func = xvid_ff_2pass; |
541 | plugins[xvid_enc_create.num_plugins].param = &rc2pass1; |
542 | xvid_enc_create.num_plugins++; |
543 | } else if (xvid_flags & AV_CODEC_FLAG_PASS2) { |
544 | rc2pass2.version = XVID_VERSION; |
545 | rc2pass2.bitrate = avctx->bit_rate; |
546 | |
547 | fd = avpriv_tempfile("xvidff.", &x->twopassfile, 0, avctx); |
548 | if (fd < 0) { |
549 | av_log(avctx, AV_LOG_ERROR, "Xvid: Cannot write 2-pass pipe\n"); |
550 | return fd; |
551 | } |
552 | x->twopassfd = fd; |
553 | |
554 | if (!avctx->stats_in) { |
555 | av_log(avctx, AV_LOG_ERROR, |
556 | "Xvid: No 2-pass information loaded for second pass\n"); |
557 | return AVERROR(EINVAL); |
558 | } |
559 | |
560 | ret = write(fd, avctx->stats_in, strlen(avctx->stats_in)); |
561 | if (ret == -1) |
562 | ret = AVERROR(errno); |
563 | else if (strlen(avctx->stats_in) > ret) { |
564 | av_log(avctx, AV_LOG_ERROR, "Xvid: Cannot write to 2-pass pipe\n"); |
565 | ret = AVERROR(EIO); |
566 | } |
567 | if (ret < 0) |
568 | return ret; |
569 | |
570 | rc2pass2.filename = x->twopassfile; |
571 | plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2; |
572 | plugins[xvid_enc_create.num_plugins].param = &rc2pass2; |
573 | xvid_enc_create.num_plugins++; |
574 | } else if (!(xvid_flags & AV_CODEC_FLAG_QSCALE)) { |
575 | /* Single Pass Bitrate Control! */ |
576 | single.version = XVID_VERSION; |
577 | single.bitrate = avctx->bit_rate; |
578 | |
579 | plugins[xvid_enc_create.num_plugins].func = xvid_plugin_single; |
580 | plugins[xvid_enc_create.num_plugins].param = &single; |
581 | xvid_enc_create.num_plugins++; |
582 | } |
583 | |
584 | if (avctx->lumi_masking != 0.0) |
585 | x->lumi_aq = 1; |
586 | |
587 | /* Luminance Masking */ |
588 | if (x->lumi_aq) { |
589 | masking_l.method = 0; |
590 | plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking; |
591 | |
592 | /* The old behavior is that when avctx->lumi_masking is specified, |
593 | * plugins[...].param = NULL. Trying to keep the old behavior here. */ |
594 | plugins[xvid_enc_create.num_plugins].param = |
595 | avctx->lumi_masking ? NULL : &masking_l; |
596 | xvid_enc_create.num_plugins++; |
597 | } |
598 | |
599 | /* Variance AQ */ |
600 | if (x->variance_aq) { |
601 | masking_v.method = 1; |
602 | plugins[xvid_enc_create.num_plugins].func = xvid_plugin_lumimasking; |
603 | plugins[xvid_enc_create.num_plugins].param = &masking_v; |
604 | xvid_enc_create.num_plugins++; |
605 | } |
606 | |
607 | if (x->lumi_aq && x->variance_aq ) |
608 | av_log(avctx, AV_LOG_INFO, |
609 | "Both lumi_aq and variance_aq are enabled. The resulting quality" |
610 | "will be the worse one of the two effects made by the AQ.\n"); |
611 | |
612 | /* SSIM */ |
613 | if (x->ssim) { |
614 | plugins[xvid_enc_create.num_plugins].func = xvid_plugin_ssim; |
615 | ssim.b_printstat = x->ssim == 2; |
616 | ssim.acc = x->ssim_acc; |
617 | ssim.cpu_flags = xvid_gbl_init.cpu_flags; |
618 | ssim.b_visualize = 0; |
619 | plugins[xvid_enc_create.num_plugins].param = &ssim; |
620 | xvid_enc_create.num_plugins++; |
621 | } |
622 | |
623 | /* Frame Rate and Key Frames */ |
624 | xvid_correct_framerate(avctx); |
625 | xvid_enc_create.fincr = avctx->time_base.num; |
626 | xvid_enc_create.fbase = avctx->time_base.den; |
627 | if (avctx->gop_size > 0) |
628 | xvid_enc_create.max_key_interval = avctx->gop_size; |
629 | else |
630 | xvid_enc_create.max_key_interval = 240; /* Xvid's best default */ |
631 | |
632 | /* Quants */ |
633 | if (xvid_flags & AV_CODEC_FLAG_QSCALE) |
634 | x->qscale = 1; |
635 | else |
636 | x->qscale = 0; |
637 | |
638 | xvid_enc_create.min_quant[0] = avctx->qmin; |
639 | xvid_enc_create.min_quant[1] = avctx->qmin; |
640 | xvid_enc_create.min_quant[2] = avctx->qmin; |
641 | xvid_enc_create.max_quant[0] = avctx->qmax; |
642 | xvid_enc_create.max_quant[1] = avctx->qmax; |
643 | xvid_enc_create.max_quant[2] = avctx->qmax; |
644 | |
645 | /* Quant Matrices */ |
646 | x->intra_matrix = |
647 | x->inter_matrix = NULL; |
648 | |
649 | #if FF_API_PRIVATE_OPT |
650 | FF_DISABLE_DEPRECATION_WARNINGS |
651 | if (avctx->mpeg_quant) |
652 | x->mpeg_quant = avctx->mpeg_quant; |
653 | FF_ENABLE_DEPRECATION_WARNINGS |
654 | #endif |
655 | |
656 | if (x->mpeg_quant) |
657 | x->vol_flags |= XVID_VOL_MPEGQUANT; |
658 | if ((avctx->intra_matrix || avctx->inter_matrix)) { |
659 | x->vol_flags |= XVID_VOL_MPEGQUANT; |
660 | |
661 | if (avctx->intra_matrix) { |
662 | intra = avctx->intra_matrix; |
663 | x->intra_matrix = av_malloc(sizeof(unsigned char) * 64); |
664 | if (!x->intra_matrix) |
665 | return AVERROR(ENOMEM); |
666 | } else |
667 | intra = NULL; |
668 | if (avctx->inter_matrix) { |
669 | inter = avctx->inter_matrix; |
670 | x->inter_matrix = av_malloc(sizeof(unsigned char) * 64); |
671 | if (!x->inter_matrix) |
672 | return AVERROR(ENOMEM); |
673 | } else |
674 | inter = NULL; |
675 | |
676 | for (i = 0; i < 64; i++) { |
677 | if (intra) |
678 | x->intra_matrix[i] = (unsigned char) intra[i]; |
679 | if (inter) |
680 | x->inter_matrix[i] = (unsigned char) inter[i]; |
681 | } |
682 | } |
683 | |
684 | /* Misc Settings */ |
685 | xvid_enc_create.frame_drop_ratio = 0; |
686 | xvid_enc_create.global = 0; |
687 | if (xvid_flags & AV_CODEC_FLAG_CLOSED_GOP) |
688 | xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP; |
689 | |
690 | /* Determines which codec mode we are operating in */ |
691 | avctx->extradata = NULL; |
692 | avctx->extradata_size = 0; |
693 | if (xvid_flags & AV_CODEC_FLAG_GLOBAL_HEADER) { |
694 | /* In this case, we are claiming to be MPEG-4 */ |
695 | x->quicktime_format = 1; |
696 | avctx->codec_id = AV_CODEC_ID_MPEG4; |
697 | } else { |
698 | /* We are claiming to be Xvid */ |
699 | x->quicktime_format = 0; |
700 | if (!avctx->codec_tag) |
701 | avctx->codec_tag = AV_RL32("xvid"); |
702 | } |
703 | |
704 | /* Bframes */ |
705 | xvid_enc_create.max_bframes = avctx->max_b_frames; |
706 | xvid_enc_create.bquant_offset = 100 * avctx->b_quant_offset; |
707 | xvid_enc_create.bquant_ratio = 100 * avctx->b_quant_factor; |
708 | if (avctx->max_b_frames > 0 && !x->quicktime_format) |
709 | xvid_enc_create.global |= XVID_GLOBAL_PACKED; |
710 | |
711 | av_assert0(xvid_enc_create.num_plugins + (!!x->ssim) + (!!x->variance_aq) + (!!x->lumi_aq) <= FF_ARRAY_ELEMS(plugins)); |
712 | |
713 | /* Encode a dummy frame to get the extradata immediately */ |
714 | if (x->quicktime_format) { |
715 | AVFrame *picture; |
716 | AVPacket packet = {0}; |
717 | int size, got_packet, ret; |
718 | |
719 | av_init_packet(&packet); |
720 | |
721 | picture = av_frame_alloc(); |
722 | if (!picture) |
723 | return AVERROR(ENOMEM); |
724 | |
725 | xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); |
726 | if( xerr ) { |
727 | av_frame_free(&picture); |
728 | av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n"); |
729 | return AVERROR_EXTERNAL; |
730 | } |
731 | x->encoder_handle = xvid_enc_create.handle; |
732 | size = ((avctx->width + 1) & ~1) * ((avctx->height + 1) & ~1); |
733 | picture->data[0] = av_malloc(size + size / 2); |
734 | if (!picture->data[0]) { |
735 | av_frame_free(&picture); |
736 | return AVERROR(ENOMEM); |
737 | } |
738 | picture->data[1] = picture->data[0] + size; |
739 | picture->data[2] = picture->data[1] + size / 4; |
740 | memset(picture->data[0], 0, size); |
741 | memset(picture->data[1], 128, size / 2); |
742 | ret = xvid_encode_frame(avctx, &packet, picture, &got_packet); |
743 | if (!ret && got_packet) |
744 | av_packet_unref(&packet); |
745 | av_free(picture->data[0]); |
746 | av_frame_free(&picture); |
747 | xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL); |
748 | } |
749 | |
750 | /* Create encoder context */ |
751 | xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); |
752 | if (xerr) { |
753 | av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n"); |
754 | return AVERROR_EXTERNAL; |
755 | } |
756 | |
757 | x->encoder_handle = xvid_enc_create.handle; |
758 | |
759 | return 0; |
760 | } |
761 | |
762 | static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt, |
763 | const AVFrame *picture, int *got_packet) |
764 | { |
765 | int xerr, i, ret, user_packet = !!pkt->data; |
766 | struct xvid_context *x = avctx->priv_data; |
767 | int mb_width = (avctx->width + 15) / 16; |
768 | int mb_height = (avctx->height + 15) / 16; |
769 | char *tmp; |
770 | |
771 | xvid_enc_frame_t xvid_enc_frame = { 0 }; |
772 | xvid_enc_stats_t xvid_enc_stats = { 0 }; |
773 | |
774 | if ((ret = ff_alloc_packet2(avctx, pkt, mb_width*(int64_t)mb_height*MAX_MB_BYTES + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0) |
775 | return ret; |
776 | |
777 | /* Start setting up the frame */ |
778 | xvid_enc_frame.version = XVID_VERSION; |
779 | xvid_enc_stats.version = XVID_VERSION; |
780 | |
781 | /* Let Xvid know where to put the frame. */ |
782 | xvid_enc_frame.bitstream = pkt->data; |
783 | xvid_enc_frame.length = pkt->size; |
784 | |
785 | /* Initialize input image fields */ |
786 | if (avctx->pix_fmt != AV_PIX_FMT_YUV420P) { |
787 | av_log(avctx, AV_LOG_ERROR, |
788 | "Xvid: Color spaces other than 420P not supported\n"); |
789 | return AVERROR(EINVAL); |
790 | } |
791 | |
792 | xvid_enc_frame.input.csp = XVID_CSP_PLANAR; /* YUV420P */ |
793 | |
794 | for (i = 0; i < 4; i++) { |
795 | xvid_enc_frame.input.plane[i] = picture->data[i]; |
796 | xvid_enc_frame.input.stride[i] = picture->linesize[i]; |
797 | } |
798 | |
799 | /* Encoder Flags */ |
800 | xvid_enc_frame.vop_flags = x->vop_flags; |
801 | xvid_enc_frame.vol_flags = x->vol_flags; |
802 | xvid_enc_frame.motion = x->me_flags; |
803 | xvid_enc_frame.type = |
804 | picture->pict_type == AV_PICTURE_TYPE_I ? XVID_TYPE_IVOP : |
805 | picture->pict_type == AV_PICTURE_TYPE_P ? XVID_TYPE_PVOP : |
806 | picture->pict_type == AV_PICTURE_TYPE_B ? XVID_TYPE_BVOP : |
807 | XVID_TYPE_AUTO; |
808 | |
809 | /* Pixel aspect ratio setting */ |
810 | if (avctx->sample_aspect_ratio.num < 0 || avctx->sample_aspect_ratio.num > 255 || |
811 | avctx->sample_aspect_ratio.den < 0 || avctx->sample_aspect_ratio.den > 255) { |
812 | av_log(avctx, AV_LOG_WARNING, |
813 | "Invalid pixel aspect ratio %i/%i, limit is 255/255 reducing\n", |
814 | avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den); |
815 | av_reduce(&avctx->sample_aspect_ratio.num, &avctx->sample_aspect_ratio.den, |
816 | avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den, 255); |
817 | } |
818 | xvid_enc_frame.par = XVID_PAR_EXT; |
819 | xvid_enc_frame.par_width = avctx->sample_aspect_ratio.num; |
820 | xvid_enc_frame.par_height = avctx->sample_aspect_ratio.den; |
821 | |
822 | /* Quant Setting */ |
823 | if (x->qscale) |
824 | xvid_enc_frame.quant = picture->quality / FF_QP2LAMBDA; |
825 | else |
826 | xvid_enc_frame.quant = 0; |
827 | |
828 | /* Matrices */ |
829 | xvid_enc_frame.quant_intra_matrix = x->intra_matrix; |
830 | xvid_enc_frame.quant_inter_matrix = x->inter_matrix; |
831 | |
832 | /* Encode */ |
833 | xerr = xvid_encore(x->encoder_handle, XVID_ENC_ENCODE, |
834 | &xvid_enc_frame, &xvid_enc_stats); |
835 | |
836 | /* Two-pass log buffer swapping */ |
837 | avctx->stats_out = NULL; |
838 | if (x->twopassbuffer) { |
839 | tmp = x->old_twopassbuffer; |
840 | x->old_twopassbuffer = x->twopassbuffer; |
841 | x->twopassbuffer = tmp; |
842 | x->twopassbuffer[0] = 0; |
843 | if (x->old_twopassbuffer[0] != 0) { |
844 | avctx->stats_out = x->old_twopassbuffer; |
845 | } |
846 | } |
847 | |
848 | if (xerr > 0) { |
849 | int pict_type; |
850 | |
851 | *got_packet = 1; |
852 | |
853 | if (xvid_enc_stats.type == XVID_TYPE_PVOP) |
854 | pict_type = AV_PICTURE_TYPE_P; |
855 | else if (xvid_enc_stats.type == XVID_TYPE_BVOP) |
856 | pict_type = AV_PICTURE_TYPE_B; |
857 | else if (xvid_enc_stats.type == XVID_TYPE_SVOP) |
858 | pict_type = AV_PICTURE_TYPE_S; |
859 | else |
860 | pict_type = AV_PICTURE_TYPE_I; |
861 | |
862 | #if FF_API_CODED_FRAME |
863 | FF_DISABLE_DEPRECATION_WARNINGS |
864 | avctx->coded_frame->pict_type = pict_type; |
865 | avctx->coded_frame->quality = xvid_enc_stats.quant * FF_QP2LAMBDA; |
866 | FF_ENABLE_DEPRECATION_WARNINGS |
867 | #endif |
868 | |
869 | ff_side_data_set_encoder_stats(pkt, xvid_enc_stats.quant * FF_QP2LAMBDA, NULL, 0, pict_type); |
870 | |
871 | if (xvid_enc_frame.out_flags & XVID_KEYFRAME) { |
872 | #if FF_API_CODED_FRAME |
873 | FF_DISABLE_DEPRECATION_WARNINGS |
874 | avctx->coded_frame->key_frame = 1; |
875 | FF_ENABLE_DEPRECATION_WARNINGS |
876 | #endif |
877 | pkt->flags |= AV_PKT_FLAG_KEY; |
878 | if (x->quicktime_format) |
879 | return xvid_strip_vol_header(avctx, pkt, |
880 | xvid_enc_stats.hlength, xerr); |
881 | } else { |
882 | #if FF_API_CODED_FRAME |
883 | FF_DISABLE_DEPRECATION_WARNINGS |
884 | avctx->coded_frame->key_frame = 0; |
885 | FF_ENABLE_DEPRECATION_WARNINGS |
886 | #endif |
887 | } |
888 | |
889 | pkt->size = xerr; |
890 | |
891 | return 0; |
892 | } else { |
893 | if (!user_packet) |
894 | av_packet_unref(pkt); |
895 | if (!xerr) |
896 | return 0; |
897 | av_log(avctx, AV_LOG_ERROR, |
898 | "Xvid: Encoding Error Occurred: %i\n", xerr); |
899 | return AVERROR_EXTERNAL; |
900 | } |
901 | } |
902 | |
903 | static av_cold int xvid_encode_close(AVCodecContext *avctx) |
904 | { |
905 | struct xvid_context *x = avctx->priv_data; |
906 | |
907 | if (x->encoder_handle) { |
908 | xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL); |
909 | x->encoder_handle = NULL; |
910 | } |
911 | |
912 | av_freep(&avctx->extradata); |
913 | if (x->twopassbuffer) { |
914 | av_freep(&x->twopassbuffer); |
915 | av_freep(&x->old_twopassbuffer); |
916 | avctx->stats_out = NULL; |
917 | } |
918 | if (x->twopassfd>=0) { |
919 | unlink(x->twopassfile); |
920 | close(x->twopassfd); |
921 | x->twopassfd = -1; |
922 | } |
923 | av_freep(&x->twopassfile); |
924 | av_freep(&x->intra_matrix); |
925 | av_freep(&x->inter_matrix); |
926 | |
927 | return 0; |
928 | } |
929 | |
930 | #define OFFSET(x) offsetof(struct xvid_context, x) |
931 | #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM |
932 | static const AVOption options[] = { |
933 | { "lumi_aq", "Luminance masking AQ", OFFSET(lumi_aq), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, |
934 | { "variance_aq", "Variance AQ", OFFSET(variance_aq), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, |
935 | { "ssim", "Show SSIM information to stdout", OFFSET(ssim), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, VE, "ssim" }, |
936 | { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "ssim" }, |
937 | { "avg", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "ssim" }, |
938 | { "frame", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "ssim" }, |
939 | { "ssim_acc", "SSIM accuracy", OFFSET(ssim_acc), AV_OPT_TYPE_INT, { .i64 = 2 }, 0, 4, VE }, |
940 | { "gmc", "use GMC", OFFSET(gmc), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, |
941 | { "me_quality", "Motion estimation quality", OFFSET(me_quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 6, VE }, |
942 | { "mpeg_quant", "Use MPEG quantizers instead of H.263", OFFSET(mpeg_quant), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, |
943 | { NULL }, |
944 | }; |
945 | |
946 | static const AVClass xvid_class = { |
947 | .class_name = "libxvid", |
948 | .item_name = av_default_item_name, |
949 | .option = options, |
950 | .version = LIBAVUTIL_VERSION_INT, |
951 | }; |
952 | |
953 | AVCodec ff_libxvid_encoder = { |
954 | .name = "libxvid", |
955 | .long_name = NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"), |
956 | .type = AVMEDIA_TYPE_VIDEO, |
957 | .id = AV_CODEC_ID_MPEG4, |
958 | .priv_data_size = sizeof(struct xvid_context), |
959 | .init = xvid_encode_init, |
960 | .encode2 = xvid_encode_frame, |
961 | .close = xvid_encode_close, |
962 | .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, |
963 | .priv_class = &xvid_class, |
964 | .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | |
965 | FF_CODEC_CAP_INIT_CLEANUP, |
966 | }; |
967 |