2 * Interface to xvidcore for mpeg4 encoding
3 * Copyright (c) 2004 Adam Thayer <krevnik@comcast.net>
5 * This file is part of FFmpeg.
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.
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.
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
24 * Interface to xvidcore for MPEG-4 compliant encoding.
25 * @author Adam Thayer (krevnik@comcast.net)
30 #include "libavutil/cpu.h"
31 #include "libavutil/file.h"
32 #include "libavutil/intreadwrite.h"
33 #include "libavutil/mathematics.h"
38 #include "mpegvideo.h"
49 * Buffer management macros.
51 #define BUFFER_SIZE 1024
52 #define BUFFER_REMAINING(x) (BUFFER_SIZE - strlen(x))
53 #define BUFFER_CAT(x) (&((x)[strlen(x)]))
56 * Structure for the private Xvid context.
57 * This stores all the private context for the codec.
61 void *encoder_handle
; /**< Handle for Xvid encoder */
62 int xsize
; /**< Frame x size */
63 int ysize
; /**< Frame y size */
64 int vop_flags
; /**< VOP flags for Xvid encoder */
65 int vol_flags
; /**< VOL flags for Xvid encoder */
66 int me_flags
; /**< Motion Estimation flags */
67 int qscale
; /**< Do we use constant scale? */
68 int quicktime_format
; /**< Are we in a QT-based format? */
69 char *twopassbuffer
; /**< Character buffer for two-pass */
70 char *old_twopassbuffer
; /**< Old character buffer (two-pass) */
71 char *twopassfile
; /**< second pass temp file name */
73 unsigned char *intra_matrix
; /**< P-Frame Quant Matrix */
74 unsigned char *inter_matrix
; /**< I-Frame Quant Matrix */
75 int lumi_aq
; /**< Lumi masking as an aq method */
76 int variance_aq
; /**< Variance adaptive quantization */
77 int ssim
; /**< SSIM information display mode */
78 int ssim_acc
; /**< SSIM accuracy. 0: accurate. 4: fast. */
83 * Structure for the private first-pass plugin.
85 struct xvid_ff_pass1
{
86 int version
; /**< Xvid version */
87 struct xvid_context
*context
; /**< Pointer to private context */
90 static int xvid_encode_close(AVCodecContext
*avctx
);
93 * Xvid 2-Pass Kludge Section
95 * Xvid's default 2-pass doesn't allow us to create data as we need to, so
96 * this section spends time replacing the first pass plugin so we can write
97 * statistic information as libavcodec requests in. We have another kludge
98 * that allows us to pass data to the second pass in Xvid without a custom
99 * rate-control plugin.
103 * Initialize the two-pass plugin and context.
105 * @param param Input construction parameter structure
106 * @param handle Private context handle
107 * @return Returns XVID_ERR_xxxx on failure, or 0 on success.
109 static int xvid_ff_2pass_create(xvid_plg_create_t
*param
, void **handle
)
111 struct xvid_ff_pass1
*x
= (struct xvid_ff_pass1
*) param
->param
;
112 char *log
= x
->context
->twopassbuffer
;
114 /* Do a quick bounds check */
116 return XVID_ERR_FAIL
;
118 /* We use snprintf() */
119 /* This is because we can safely prevent a buffer overflow */
121 snprintf(log
, BUFFER_REMAINING(log
),
122 "# ffmpeg 2-pass log file, using xvid codec\n");
123 snprintf(BUFFER_CAT(log
), BUFFER_REMAINING(log
),
124 "# Do not modify. libxvidcore version: %d.%d.%d\n\n",
125 XVID_VERSION_MAJOR(XVID_VERSION
),
126 XVID_VERSION_MINOR(XVID_VERSION
),
127 XVID_VERSION_PATCH(XVID_VERSION
));
129 *handle
= x
->context
;
134 * Destroy the two-pass plugin context.
136 * @param ref Context pointer for the plugin
137 * @param param Destrooy context
138 * @return Returns 0, success guaranteed
140 static int xvid_ff_2pass_destroy(struct xvid_context
*ref
,
141 xvid_plg_destroy_t
*param
)
143 /* Currently cannot think of anything to do on destruction */
144 /* Still, the framework should be here for reference/use */
145 if (ref
->twopassbuffer
)
146 ref
->twopassbuffer
[0] = 0;
151 * Enable fast encode mode during the first pass.
153 * @param ref Context pointer for the plugin
154 * @param param Frame data
155 * @return Returns 0, success guaranteed
157 static int xvid_ff_2pass_before(struct xvid_context
*ref
,
158 xvid_plg_data_t
*param
)
161 int motion_replacements
;
164 /* Nothing to do here, result is changed too much */
165 if (param
->zone
&& param
->zone
->mode
== XVID_ZONE_QUANT
)
168 /* We can implement a 'turbo' first pass mode here */
172 motion_remove
= ~XVID_ME_CHROMA_PVOP
&
173 ~XVID_ME_CHROMA_BVOP
&
174 ~XVID_ME_EXTSEARCH16
&
175 ~XVID_ME_ADVANCEDDIAMOND16
;
176 motion_replacements
= XVID_ME_FAST_MODEINTERPOLATE
|
177 XVID_ME_SKIP_DELTASEARCH
|
178 XVID_ME_FASTREFINE16
|
179 XVID_ME_BFRAME_EARLYSTOP
;
180 vop_remove
= ~XVID_VOP_MODEDECISION_RD
&
181 ~XVID_VOP_FAST_MODEDECISION_RD
&
182 ~XVID_VOP_TRELLISQUANT
&
186 param
->vol_flags
&= ~XVID_VOL_GMC
;
187 param
->vop_flags
&= vop_remove
;
188 param
->motion_flags
&= motion_remove
;
189 param
->motion_flags
|= motion_replacements
;
195 * Capture statistic data and write it during first pass.
197 * @param ref Context pointer for the plugin
198 * @param param Statistic data
199 * @return Returns XVID_ERR_xxxx on failure, or 0 on success
201 static int xvid_ff_2pass_after(struct xvid_context
*ref
,
202 xvid_plg_data_t
*param
)
204 char *log
= ref
->twopassbuffer
;
205 const char *frame_types
= " ipbs";
208 /* Quick bounds check */
210 return XVID_ERR_FAIL
;
212 /* Convert the type given to us into a character */
213 if (param
->type
< 5 && param
->type
> 0)
214 frame_type
= frame_types
[param
->type
];
216 return XVID_ERR_FAIL
;
218 snprintf(BUFFER_CAT(log
), BUFFER_REMAINING(log
),
219 "%c %d %d %d %d %d %d\n",
220 frame_type
, param
->stats
.quant
, param
->stats
.kblks
,
221 param
->stats
.mblks
, param
->stats
.ublks
,
222 param
->stats
.length
, param
->stats
.hlength
);
228 * Dispatch function for our custom plugin.
229 * This handles the dispatch for the Xvid plugin. It passes data
230 * on to other functions for actual processing.
232 * @param ref Context pointer for the plugin
233 * @param cmd The task given for us to complete
234 * @param p1 First parameter (varies)
235 * @param p2 Second parameter (varies)
236 * @return Returns XVID_ERR_xxxx on failure, or 0 on success
238 static int xvid_ff_2pass(void *ref
, int cmd
, void *p1
, void *p2
)
244 case XVID_PLG_BEFORE
:
245 return xvid_ff_2pass_before(ref
, p1
);
246 case XVID_PLG_CREATE
:
247 return xvid_ff_2pass_create(p1
, p2
);
249 return xvid_ff_2pass_after(ref
, p1
);
250 case XVID_PLG_DESTROY
:
251 return xvid_ff_2pass_destroy(ref
, p1
);
253 return XVID_ERR_FAIL
;
258 * Routine to create a global VO/VOL header for MP4 container.
259 * What we do here is extract the header from the Xvid bitstream
260 * as it is encoded. We also strip the repeated headers from the
261 * bitstream when a global header is requested for MPEG-4 ISO
264 * @param avctx AVCodecContext pointer to context
265 * @param frame Pointer to encoded frame data
266 * @param header_len Length of header to search
267 * @param frame_len Length of encoded frame data
268 * @return Returns new length of frame data
270 static int xvid_strip_vol_header(AVCodecContext
*avctx
, AVPacket
*pkt
,
271 unsigned int header_len
,
272 unsigned int frame_len
)
276 for (i
= 0; i
< header_len
- 3; i
++) {
277 if (pkt
->data
[i
] == 0x00 &&
278 pkt
->data
[i
+ 1] == 0x00 &&
279 pkt
->data
[i
+ 2] == 0x01 &&
280 pkt
->data
[i
+ 3] == 0xB6) {
287 /* We need to store the header, so extract it */
288 if (!avctx
->extradata
) {
289 avctx
->extradata
= av_malloc(vo_len
);
290 memcpy(avctx
->extradata
, pkt
->data
, vo_len
);
291 avctx
->extradata_size
= vo_len
;
293 /* Less dangerous now, memmove properly copies the two
294 * chunks of overlapping data */
295 memmove(pkt
->data
, &pkt
->data
[vo_len
], frame_len
- vo_len
);
296 pkt
->size
= frame_len
- vo_len
;
302 * Routine to correct a possibly erroneous framerate being fed to us.
303 * Xvid currently chokes on framerates where the ticks per frame is
304 * extremely large. This function works to correct problems in this area
305 * by estimating a new framerate and taking the simpler fraction of
308 * @param avctx Context that contains the framerate to correct.
310 static void xvid_correct_framerate(AVCodecContext
*avctx
)
313 int est_frate
, est_fbase
;
317 frate
= avctx
->time_base
.den
;
318 fbase
= avctx
->time_base
.num
;
320 gcd
= av_gcd(frate
, fbase
);
326 if (frate
<= 65000 && fbase
<= 65000) {
327 avctx
->time_base
.den
= frate
;
328 avctx
->time_base
.num
= fbase
;
332 fps
= (float) frate
/ (float) fbase
;
333 est_fps
= roundf(fps
* 1000.0) / 1000.0;
335 est_frate
= (int) est_fps
;
336 if (est_fps
> (int) est_fps
) {
337 est_frate
= (est_frate
+ 1) * 1000;
338 est_fbase
= (int) roundf((float) est_frate
/ est_fps
);
342 gcd
= av_gcd(est_frate
, est_fbase
);
348 if (fbase
> est_fbase
) {
349 avctx
->time_base
.den
= est_frate
;
350 avctx
->time_base
.num
= est_fbase
;
351 av_log(avctx
, AV_LOG_DEBUG
,
352 "Xvid: framerate re-estimated: %.2f, %.3f%% correction\n",
353 est_fps
, (((est_fps
- fps
) / fps
) * 100.0));
355 avctx
->time_base
.den
= frate
;
356 avctx
->time_base
.num
= fbase
;
360 static av_cold
int xvid_encode_init(AVCodecContext
*avctx
)
362 int xerr
, i
, ret
= -1;
363 int xvid_flags
= avctx
->flags
;
364 struct xvid_context
*x
= avctx
->priv_data
;
365 uint16_t *intra
, *inter
;
368 xvid_plugin_single_t single
= { 0 };
369 struct xvid_ff_pass1 rc2pass1
= { 0 };
370 xvid_plugin_2pass2_t rc2pass2
= { 0 };
371 xvid_plugin_lumimasking_t masking_l
= { 0 }; /* For lumi masking */
372 xvid_plugin_lumimasking_t masking_v
= { 0 }; /* For variance AQ */
373 xvid_plugin_ssim_t ssim
= { 0 };
374 xvid_gbl_init_t xvid_gbl_init
= { 0 };
375 xvid_enc_create_t xvid_enc_create
= { 0 };
376 xvid_enc_plugin_t plugins
[4];
380 /* Bring in VOP flags from ffmpeg command-line */
381 x
->vop_flags
= XVID_VOP_HALFPEL
; /* Bare minimum quality */
382 if (xvid_flags
& CODEC_FLAG_4MV
)
383 x
->vop_flags
|= XVID_VOP_INTER4V
; /* Level 3 */
385 x
->vop_flags
|= XVID_VOP_TRELLISQUANT
; /* Level 5 */
386 if (xvid_flags
& CODEC_FLAG_AC_PRED
)
387 x
->vop_flags
|= XVID_VOP_HQACPRED
; /* Level 6 */
388 if (xvid_flags
& CODEC_FLAG_GRAY
)
389 x
->vop_flags
|= XVID_VOP_GREYSCALE
;
391 /* Decide which ME quality setting to use */
393 switch (avctx
->me_method
) {
394 case ME_FULL
: /* Quality 6 */
395 x
->me_flags
|= XVID_ME_EXTSEARCH16
|
398 case ME_EPZS
: /* Quality 4 */
399 x
->me_flags
|= XVID_ME_ADVANCEDDIAMOND8
|
400 XVID_ME_HALFPELREFINE8
|
401 XVID_ME_CHROMA_PVOP
|
404 case ME_LOG
: /* Quality 2 */
407 x
->me_flags
|= XVID_ME_ADVANCEDDIAMOND16
|
408 XVID_ME_HALFPELREFINE16
;
410 case ME_ZERO
: /* Quality 0 */
415 /* Decide how we should decide blocks */
416 switch (avctx
->mb_decision
) {
418 x
->vop_flags
|= XVID_VOP_MODEDECISION_RD
;
419 x
->me_flags
|= XVID_ME_HALFPELREFINE8_RD
|
420 XVID_ME_QUARTERPELREFINE8_RD
|
421 XVID_ME_EXTSEARCH_RD
|
422 XVID_ME_CHECKPREDICTION_RD
;
424 if (!(x
->vop_flags
& XVID_VOP_MODEDECISION_RD
))
425 x
->vop_flags
|= XVID_VOP_FAST_MODEDECISION_RD
;
426 x
->me_flags
|= XVID_ME_HALFPELREFINE16_RD
|
427 XVID_ME_QUARTERPELREFINE16_RD
;
432 /* Bring in VOL flags from ffmpeg command-line */
434 if (avctx
->flags
& CODEC_FLAG_GMC
)
440 x
->vol_flags
|= XVID_VOL_GMC
;
441 x
->me_flags
|= XVID_ME_GME_REFINE
;
443 if (xvid_flags
& CODEC_FLAG_QPEL
) {
444 x
->vol_flags
|= XVID_VOL_QUARTERPEL
;
445 x
->me_flags
|= XVID_ME_QUARTERPELREFINE16
;
446 if (x
->vop_flags
& XVID_VOP_INTER4V
)
447 x
->me_flags
|= XVID_ME_QUARTERPELREFINE8
;
450 xvid_gbl_init
.version
= XVID_VERSION
;
451 xvid_gbl_init
.debug
= 0;
452 xvid_gbl_init
.cpu_flags
= 0;
455 xvid_global(NULL
, XVID_GBL_INIT
, &xvid_gbl_init
, NULL
);
457 /* Create the encoder reference */
458 xvid_enc_create
.version
= XVID_VERSION
;
460 /* Store the desired frame size */
461 xvid_enc_create
.width
=
462 x
->xsize
= avctx
->width
;
463 xvid_enc_create
.height
=
464 x
->ysize
= avctx
->height
;
466 /* Xvid can determine the proper profile to use */
467 /* xvid_enc_create.profile = XVID_PROFILE_S_L3; */
469 /* We don't use zones */
470 xvid_enc_create
.zones
= NULL
;
471 xvid_enc_create
.num_zones
= 0;
473 xvid_enc_create
.num_threads
= avctx
->thread_count
;
475 xvid_enc_create
.plugins
= plugins
;
476 xvid_enc_create
.num_plugins
= 0;
478 /* Initialize Buffers */
479 x
->twopassbuffer
= NULL
;
480 x
->old_twopassbuffer
= NULL
;
481 x
->twopassfile
= NULL
;
483 if (xvid_flags
& CODEC_FLAG_PASS1
) {
484 rc2pass1
.version
= XVID_VERSION
;
485 rc2pass1
.context
= x
;
486 x
->twopassbuffer
= av_malloc(BUFFER_SIZE
);
487 x
->old_twopassbuffer
= av_malloc(BUFFER_SIZE
);
488 if (!x
->twopassbuffer
|| !x
->old_twopassbuffer
) {
489 av_log(avctx
, AV_LOG_ERROR
,
490 "Xvid: Cannot allocate 2-pass log buffers\n");
491 ret
= AVERROR(ENOMEM
);
494 x
->twopassbuffer
[0] =
495 x
->old_twopassbuffer
[0] = 0;
497 plugins
[xvid_enc_create
.num_plugins
].func
= xvid_ff_2pass
;
498 plugins
[xvid_enc_create
.num_plugins
].param
= &rc2pass1
;
499 xvid_enc_create
.num_plugins
++;
500 } else if (xvid_flags
& CODEC_FLAG_PASS2
) {
501 rc2pass2
.version
= XVID_VERSION
;
502 rc2pass2
.bitrate
= avctx
->bit_rate
;
504 fd
= av_tempfile("xvidff.", &x
->twopassfile
, 0, avctx
);
506 av_log(avctx
, AV_LOG_ERROR
, "Xvid: Cannot write 2-pass pipe\n");
512 if (!avctx
->stats_in
) {
513 av_log(avctx
, AV_LOG_ERROR
,
514 "Xvid: No 2-pass information loaded for second pass\n");
515 ret
= AVERROR(EINVAL
);
519 ret
= write(fd
, avctx
->stats_in
, strlen(avctx
->stats_in
));
521 ret
= AVERROR(errno
);
522 else if (strlen(avctx
->stats_in
) > ret
) {
523 av_log(avctx
, AV_LOG_ERROR
, "Xvid: Cannot write to 2-pass pipe\n");
529 rc2pass2
.filename
= x
->twopassfile
;
530 plugins
[xvid_enc_create
.num_plugins
].func
= xvid_plugin_2pass2
;
531 plugins
[xvid_enc_create
.num_plugins
].param
= &rc2pass2
;
532 xvid_enc_create
.num_plugins
++;
533 } else if (!(xvid_flags
& CODEC_FLAG_QSCALE
)) {
534 /* Single Pass Bitrate Control! */
535 single
.version
= XVID_VERSION
;
536 single
.bitrate
= avctx
->bit_rate
;
538 plugins
[xvid_enc_create
.num_plugins
].func
= xvid_plugin_single
;
539 plugins
[xvid_enc_create
.num_plugins
].param
= &single
;
540 xvid_enc_create
.num_plugins
++;
543 if (avctx
->lumi_masking
!= 0.0)
546 /* Luminance Masking */
548 masking_l
.method
= 0;
549 plugins
[xvid_enc_create
.num_plugins
].func
= xvid_plugin_lumimasking
;
551 /* The old behavior is that when avctx->lumi_masking is specified,
552 * plugins[...].param = NULL. Trying to keep the old behavior here. */
553 plugins
[xvid_enc_create
.num_plugins
].param
=
554 avctx
->lumi_masking
? NULL
: &masking_l
;
555 xvid_enc_create
.num_plugins
++;
559 if (x
->variance_aq
) {
560 masking_v
.method
= 1;
561 plugins
[xvid_enc_create
.num_plugins
].func
= xvid_plugin_lumimasking
;
562 plugins
[xvid_enc_create
.num_plugins
].param
= &masking_v
;
563 xvid_enc_create
.num_plugins
++;
566 if (x
->lumi_aq
&& x
->variance_aq
)
567 av_log(avctx
, AV_LOG_INFO
,
568 "Both lumi_aq and variance_aq are enabled. The resulting quality"
569 "will be the worse one of the two effects made by the AQ.\n");
573 plugins
[xvid_enc_create
.num_plugins
].func
= xvid_plugin_ssim
;
574 ssim
.b_printstat
= x
->ssim
== 2;
575 ssim
.acc
= x
->ssim_acc
;
576 ssim
.cpu_flags
= xvid_gbl_init
.cpu_flags
;
577 ssim
.b_visualize
= 0;
578 plugins
[xvid_enc_create
.num_plugins
].param
= &ssim
;
579 xvid_enc_create
.num_plugins
++;
582 /* Frame Rate and Key Frames */
583 xvid_correct_framerate(avctx
);
584 xvid_enc_create
.fincr
= avctx
->time_base
.num
;
585 xvid_enc_create
.fbase
= avctx
->time_base
.den
;
586 if (avctx
->gop_size
> 0)
587 xvid_enc_create
.max_key_interval
= avctx
->gop_size
;
589 xvid_enc_create
.max_key_interval
= 240; /* Xvid's best default */
592 if (xvid_flags
& CODEC_FLAG_QSCALE
)
597 xvid_enc_create
.min_quant
[0] = avctx
->qmin
;
598 xvid_enc_create
.min_quant
[1] = avctx
->qmin
;
599 xvid_enc_create
.min_quant
[2] = avctx
->qmin
;
600 xvid_enc_create
.max_quant
[0] = avctx
->qmax
;
601 xvid_enc_create
.max_quant
[1] = avctx
->qmax
;
602 xvid_enc_create
.max_quant
[2] = avctx
->qmax
;
606 x
->inter_matrix
= NULL
;
607 if (avctx
->mpeg_quant
)
608 x
->vol_flags
|= XVID_VOL_MPEGQUANT
;
609 if ((avctx
->intra_matrix
|| avctx
->inter_matrix
)) {
610 x
->vol_flags
|= XVID_VOL_MPEGQUANT
;
612 if (avctx
->intra_matrix
) {
613 intra
= avctx
->intra_matrix
;
614 x
->intra_matrix
= av_malloc(sizeof(unsigned char) * 64);
617 if (avctx
->inter_matrix
) {
618 inter
= avctx
->inter_matrix
;
619 x
->inter_matrix
= av_malloc(sizeof(unsigned char) * 64);
623 for (i
= 0; i
< 64; i
++) {
625 x
->intra_matrix
[i
] = (unsigned char) intra
[i
];
627 x
->inter_matrix
[i
] = (unsigned char) inter
[i
];
632 xvid_enc_create
.frame_drop_ratio
= 0;
633 xvid_enc_create
.global
= 0;
634 if (xvid_flags
& CODEC_FLAG_CLOSED_GOP
)
635 xvid_enc_create
.global
|= XVID_GLOBAL_CLOSED_GOP
;
637 /* Determines which codec mode we are operating in */
638 avctx
->extradata
= NULL
;
639 avctx
->extradata_size
= 0;
640 if (xvid_flags
& CODEC_FLAG_GLOBAL_HEADER
) {
641 /* In this case, we are claiming to be MPEG4 */
642 x
->quicktime_format
= 1;
643 avctx
->codec_id
= AV_CODEC_ID_MPEG4
;
645 /* We are claiming to be Xvid */
646 x
->quicktime_format
= 0;
647 if (!avctx
->codec_tag
)
648 avctx
->codec_tag
= AV_RL32("xvid");
652 xvid_enc_create
.max_bframes
= avctx
->max_b_frames
;
653 xvid_enc_create
.bquant_offset
= 100 * avctx
->b_quant_offset
;
654 xvid_enc_create
.bquant_ratio
= 100 * avctx
->b_quant_factor
;
655 if (avctx
->max_b_frames
> 0 && !x
->quicktime_format
)
656 xvid_enc_create
.global
|= XVID_GLOBAL_PACKED
;
658 av_assert0(xvid_enc_create
.num_plugins
+ (!!x
->ssim
) + (!!x
->variance_aq
) + (!!x
->lumi_aq
) <= FF_ARRAY_ELEMS(plugins
));
660 /* Create encoder context */
661 xerr
= xvid_encore(NULL
, XVID_ENC_CREATE
, &xvid_enc_create
, NULL
);
663 av_log(avctx
, AV_LOG_ERROR
, "Xvid: Could not create encoder reference\n");
667 x
->encoder_handle
= xvid_enc_create
.handle
;
668 avctx
->coded_frame
= av_frame_alloc();
669 if (!avctx
->coded_frame
) {
670 ret
= AVERROR(ENOMEM
);
676 xvid_encode_close(avctx
);
680 static int xvid_encode_frame(AVCodecContext
*avctx
, AVPacket
*pkt
,
681 const AVFrame
*picture
, int *got_packet
)
683 int xerr
, i
, ret
, user_packet
= !!pkt
->data
;
684 struct xvid_context
*x
= avctx
->priv_data
;
685 AVFrame
*p
= avctx
->coded_frame
;
686 int mb_width
= (avctx
->width
+ 15) / 16;
687 int mb_height
= (avctx
->height
+ 15) / 16;
690 xvid_enc_frame_t xvid_enc_frame
= { 0 };
691 xvid_enc_stats_t xvid_enc_stats
= { 0 };
693 if ((ret
= ff_alloc_packet2(avctx
, pkt
, mb_width
*mb_height
*MAX_MB_BYTES
+ FF_MIN_BUFFER_SIZE
)) < 0)
696 /* Start setting up the frame */
697 xvid_enc_frame
.version
= XVID_VERSION
;
698 xvid_enc_stats
.version
= XVID_VERSION
;
700 /* Let Xvid know where to put the frame. */
701 xvid_enc_frame
.bitstream
= pkt
->data
;
702 xvid_enc_frame
.length
= pkt
->size
;
704 /* Initialize input image fields */
705 if (avctx
->pix_fmt
!= AV_PIX_FMT_YUV420P
) {
706 av_log(avctx
, AV_LOG_ERROR
,
707 "Xvid: Color spaces other than 420P not supported\n");
708 return AVERROR(EINVAL
);
711 xvid_enc_frame
.input
.csp
= XVID_CSP_PLANAR
; /* YUV420P */
713 for (i
= 0; i
< 4; i
++) {
714 xvid_enc_frame
.input
.plane
[i
] = picture
->data
[i
];
715 xvid_enc_frame
.input
.stride
[i
] = picture
->linesize
[i
];
719 xvid_enc_frame
.vop_flags
= x
->vop_flags
;
720 xvid_enc_frame
.vol_flags
= x
->vol_flags
;
721 xvid_enc_frame
.motion
= x
->me_flags
;
722 xvid_enc_frame
.type
=
723 picture
->pict_type
== AV_PICTURE_TYPE_I
? XVID_TYPE_IVOP
:
724 picture
->pict_type
== AV_PICTURE_TYPE_P
? XVID_TYPE_PVOP
:
725 picture
->pict_type
== AV_PICTURE_TYPE_B
? XVID_TYPE_BVOP
:
728 /* Pixel aspect ratio setting */
729 if (avctx
->sample_aspect_ratio
.num
< 0 || avctx
->sample_aspect_ratio
.num
> 255 ||
730 avctx
->sample_aspect_ratio
.den
< 0 || avctx
->sample_aspect_ratio
.den
> 255) {
731 av_log(avctx
, AV_LOG_WARNING
,
732 "Invalid pixel aspect ratio %i/%i, limit is 255/255 reducing\n",
733 avctx
->sample_aspect_ratio
.num
, avctx
->sample_aspect_ratio
.den
);
734 av_reduce(&avctx
->sample_aspect_ratio
.num
, &avctx
->sample_aspect_ratio
.den
,
735 avctx
->sample_aspect_ratio
.num
, avctx
->sample_aspect_ratio
.den
, 255);
737 xvid_enc_frame
.par
= XVID_PAR_EXT
;
738 xvid_enc_frame
.par_width
= avctx
->sample_aspect_ratio
.num
;
739 xvid_enc_frame
.par_height
= avctx
->sample_aspect_ratio
.den
;
743 xvid_enc_frame
.quant
= picture
->quality
/ FF_QP2LAMBDA
;
745 xvid_enc_frame
.quant
= 0;
748 xvid_enc_frame
.quant_intra_matrix
= x
->intra_matrix
;
749 xvid_enc_frame
.quant_inter_matrix
= x
->inter_matrix
;
752 xerr
= xvid_encore(x
->encoder_handle
, XVID_ENC_ENCODE
,
753 &xvid_enc_frame
, &xvid_enc_stats
);
755 /* Two-pass log buffer swapping */
756 avctx
->stats_out
= NULL
;
757 if (x
->twopassbuffer
) {
758 tmp
= x
->old_twopassbuffer
;
759 x
->old_twopassbuffer
= x
->twopassbuffer
;
760 x
->twopassbuffer
= tmp
;
761 x
->twopassbuffer
[0] = 0;
762 if (x
->old_twopassbuffer
[0] != 0) {
763 avctx
->stats_out
= x
->old_twopassbuffer
;
770 p
->quality
= xvid_enc_stats
.quant
* FF_QP2LAMBDA
;
771 if (xvid_enc_stats
.type
== XVID_TYPE_PVOP
)
772 p
->pict_type
= AV_PICTURE_TYPE_P
;
773 else if (xvid_enc_stats
.type
== XVID_TYPE_BVOP
)
774 p
->pict_type
= AV_PICTURE_TYPE_B
;
775 else if (xvid_enc_stats
.type
== XVID_TYPE_SVOP
)
776 p
->pict_type
= AV_PICTURE_TYPE_S
;
778 p
->pict_type
= AV_PICTURE_TYPE_I
;
779 if (xvid_enc_frame
.out_flags
& XVID_KEYFRAME
) {
781 pkt
->flags
|= AV_PKT_FLAG_KEY
;
782 if (x
->quicktime_format
)
783 return xvid_strip_vol_header(avctx
, pkt
,
784 xvid_enc_stats
.hlength
, xerr
);
796 av_log(avctx
, AV_LOG_ERROR
,
797 "Xvid: Encoding Error Occurred: %i\n", xerr
);
798 return AVERROR_EXTERNAL
;
802 static av_cold
int xvid_encode_close(AVCodecContext
*avctx
)
804 struct xvid_context
*x
= avctx
->priv_data
;
806 if(x
->encoder_handle
)
807 xvid_encore(x
->encoder_handle
, XVID_ENC_DESTROY
, NULL
, NULL
);
808 x
->encoder_handle
= NULL
;
810 av_freep(&avctx
->extradata
);
811 if (x
->twopassbuffer
) {
812 av_freep(&x
->twopassbuffer
);
813 av_freep(&x
->old_twopassbuffer
);
814 avctx
->stats_out
= NULL
;
816 if (x
->twopassfd
>=0) {
817 unlink(x
->twopassfile
);
821 av_freep(&x
->twopassfile
);
822 av_freep(&x
->intra_matrix
);
823 av_freep(&x
->inter_matrix
);
824 av_frame_free(&avctx
->coded_frame
);
829 #define OFFSET(x) offsetof(struct xvid_context, x)
830 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
831 static const AVOption options
[] = {
832 { "lumi_aq", "Luminance masking AQ", OFFSET(lumi_aq
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 1, VE
},
833 { "variance_aq", "Variance AQ", OFFSET(variance_aq
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 1, VE
},
834 { "ssim", "Show SSIM information to stdout", OFFSET(ssim
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 2, VE
, "ssim" },
835 { "off", NULL
, 0, AV_OPT_TYPE_CONST
, { .i64
= 0 }, INT_MIN
, INT_MAX
, VE
, "ssim" },
836 { "avg", NULL
, 0, AV_OPT_TYPE_CONST
, { .i64
= 1 }, INT_MIN
, INT_MAX
, VE
, "ssim" },
837 { "frame", NULL
, 0, AV_OPT_TYPE_CONST
, { .i64
= 2 }, INT_MIN
, INT_MAX
, VE
, "ssim" },
838 { "ssim_acc", "SSIM accuracy", OFFSET(ssim_acc
), AV_OPT_TYPE_INT
, { .i64
= 2 }, 0, 4, VE
},
839 { "gmc", "use GMC", OFFSET(gmc
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 1, VE
},
843 static const AVClass xvid_class
= {
844 .class_name
= "libxvid",
845 .item_name
= av_default_item_name
,
847 .version
= LIBAVUTIL_VERSION_INT
,
850 AVCodec ff_libxvid_encoder
= {
852 .long_name
= NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"),
853 .type
= AVMEDIA_TYPE_VIDEO
,
854 .id
= AV_CODEC_ID_MPEG4
,
855 .priv_data_size
= sizeof(struct xvid_context
),
856 .init
= xvid_encode_init
,
857 .encode2
= xvid_encode_frame
,
858 .close
= xvid_encode_close
,
859 .pix_fmts
= (const enum AVPixelFormat
[]) { AV_PIX_FMT_YUV420P
, AV_PIX_FMT_NONE
},
860 .priv_class
= &xvid_class
,