X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Flibxvidff.c;h=a11e4ac913c4ea37e60717557ddec1fb596b9e39;hb=5d42ac7ffb5471666136402a553454caf3a3c989;hp=e37b900c1da453ffda96347c11e55d6643a3b6df;hpb=a2ab5ad5f15fc65b41d653f2b8a9606d45fad919;p=ffmpeg diff --git a/libavcodec/libxvidff.c b/libavcodec/libxvidff.c index e37b900c1da..a11e4ac913c 100644 --- a/libavcodec/libxvidff.c +++ b/libavcodec/libxvidff.c @@ -2,20 +2,20 @@ * Interface to xvidcore for mpeg4 encoding * Copyright (c) 2004 Adam Thayer * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -25,13 +25,12 @@ * @author Adam Thayer (krevnik@comcast.net) */ -/* needed for mkstemp() */ -#define _XOPEN_SOURCE 600 - #include #include #include "avcodec.h" +#include "libavutil/cpu.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mathematics.h" #include "libxvid_internal.h" #if !HAVE_MKSTEMP #include @@ -44,35 +43,33 @@ #define BUFFER_REMAINING(x) (BUFFER_SIZE - strlen(x)) #define BUFFER_CAT(x) (&((x)[strlen(x)])) -/* For PPC Use */ -int has_altivec(void); - /** * Structure for the private Xvid context. * This stores all the private context for the codec. */ struct xvid_context { - void *encoder_handle; /** Handle for Xvid encoder */ - int xsize, ysize; /** Frame size */ - int vop_flags; /** VOP flags for Xvid encoder */ - int vol_flags; /** VOL flags for Xvid encoder */ - int me_flags; /** Motion Estimation flags */ - int qscale; /** Do we use constant scale? */ - int quicktime_format; /** Are we in a QT-based format? */ - AVFrame encoded_picture; /** Encoded frame information */ - char *twopassbuffer; /** Character buffer for two-pass */ - char *old_twopassbuffer; /** Old character buffer (two-pass) */ - char *twopassfile; /** second pass temp file name */ - unsigned char *intra_matrix; /** P-Frame Quant Matrix */ - unsigned char *inter_matrix; /** I-Frame Quant Matrix */ + void *encoder_handle; /**< Handle for Xvid encoder */ + int xsize; /**< Frame x size */ + int ysize; /**< Frame y size */ + int vop_flags; /**< VOP flags for Xvid encoder */ + int vol_flags; /**< VOL flags for Xvid encoder */ + int me_flags; /**< Motion Estimation flags */ + int qscale; /**< Do we use constant scale? */ + int quicktime_format; /**< Are we in a QT-based format? */ + AVFrame encoded_picture; /**< Encoded frame information */ + char *twopassbuffer; /**< Character buffer for two-pass */ + char *old_twopassbuffer; /**< Old character buffer (two-pass) */ + char *twopassfile; /**< second pass temp file name */ + unsigned char *intra_matrix; /**< P-Frame Quant Matrix */ + unsigned char *inter_matrix; /**< I-Frame Quant Matrix */ }; /** * Structure for the private first-pass plugin. */ struct xvid_ff_pass1 { - int version; /** Xvid version */ - struct xvid_context *context; /** Pointer to private context */ + int version; /**< Xvid version */ + struct xvid_context *context; /**< Pointer to private context */ }; /* Prototypes - See function implementation for details */ @@ -80,6 +77,44 @@ int xvid_strip_vol_header(AVCodecContext *avctx, unsigned char *frame, unsigned int xvid_ff_2pass(void *ref, int opt, void *p1, void *p2); void xvid_correct_framerate(AVCodecContext *avctx); +/* Wrapper to work around the lack of mkstemp() on mingw. + * Also, tries to create file in /tmp first, if possible. + * *prefix can be a character constant; *filename will be allocated internally. + * @return file descriptor of opened file (or -1 on error) + * and opened file name in **filename. */ +int ff_tempfile(const char *prefix, char **filename) { + int fd=-1; +#if !HAVE_MKSTEMP + *filename = tempnam(".", prefix); +#else + size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */ + *filename = av_malloc(len); +#endif + /* -----common section-----*/ + if (*filename == NULL) { + av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n"); + return -1; + } +#if !HAVE_MKSTEMP + fd = open(*filename, O_RDWR | O_BINARY | O_CREAT, 0444); +#else + snprintf(*filename, len, "/tmp/%sXXXXXX", prefix); + fd = mkstemp(*filename); + if (fd < 0) { + snprintf(*filename, len, "./%sXXXXXX", prefix); + fd = mkstemp(*filename); + } +#endif + /* -----common section-----*/ + if (fd < 0) { + av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename); + return -1; + } + return fd; /* success */ +} + +#if CONFIG_LIBXVID_ENCODER + /** * Create the private context for the encoder. * All buffers are allocated, settings are loaded from the user, @@ -102,7 +137,7 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { xvid_enc_create_t xvid_enc_create; xvid_enc_plugin_t plugins[7]; - /* Bring in VOP flags from ffmpeg command-line */ + /* Bring in VOP flags from avconv command-line */ x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */ if( xvid_flags & CODEC_FLAG_4MV ) x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */ @@ -156,7 +191,7 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { break; } - /* Bring in VOL flags from ffmpeg command-line */ + /* Bring in VOL flags from avconv command-line */ x->vol_flags = 0; if( xvid_flags & CODEC_FLAG_GMC ) { x->vol_flags |= XVID_VOL_GMC; @@ -176,7 +211,7 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { #if ARCH_PPC /* Xvid's PPC support is borked, use libavcodec to detect */ #if HAVE_ALTIVEC - if( has_altivec() ) { + if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) { xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ALTIVEC; } else #endif @@ -235,7 +270,7 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { rc2pass2.version = XVID_VERSION; rc2pass2.bitrate = avctx->bit_rate; - fd = ff_tempfile("xvidff.", &(x->twopassfile)); + fd = ff_tempfile("xvidff.", &x->twopassfile); if( fd == -1 ) { av_log(avctx, AV_LOG_ERROR, "Xvid: Cannot write 2-pass pipe\n"); @@ -379,7 +414,7 @@ static int xvid_encode_frame(AVCodecContext *avctx, char *tmp; struct xvid_context *x = avctx->priv_data; AVFrame *picture = data; - AVFrame *p = &(x->encoded_picture); + AVFrame *p = &x->encoded_picture; xvid_enc_frame_t xvid_enc_frame; xvid_enc_stats_t xvid_enc_stats; @@ -412,7 +447,11 @@ static int xvid_encode_frame(AVCodecContext *avctx, xvid_enc_frame.vop_flags = x->vop_flags; xvid_enc_frame.vol_flags = x->vol_flags; xvid_enc_frame.motion = x->me_flags; - xvid_enc_frame.type = XVID_TYPE_AUTO; + xvid_enc_frame.type = + picture->pict_type == AV_PICTURE_TYPE_I ? XVID_TYPE_IVOP : + picture->pict_type == AV_PICTURE_TYPE_P ? XVID_TYPE_PVOP : + picture->pict_type == AV_PICTURE_TYPE_B ? XVID_TYPE_BVOP : + XVID_TYPE_AUTO; /* Pixel aspect ratio setting */ if (avctx->sample_aspect_ratio.num < 1 || avctx->sample_aspect_ratio.num > 255 || @@ -452,13 +491,13 @@ static int xvid_encode_frame(AVCodecContext *avctx, if( 0 <= xerr ) { p->quality = xvid_enc_stats.quant * FF_QP2LAMBDA; if( xvid_enc_stats.type == XVID_TYPE_PVOP ) - p->pict_type = FF_P_TYPE; + p->pict_type = AV_PICTURE_TYPE_P; else if( xvid_enc_stats.type == XVID_TYPE_BVOP ) - p->pict_type = FF_B_TYPE; + p->pict_type = AV_PICTURE_TYPE_B; else if( xvid_enc_stats.type == XVID_TYPE_SVOP ) - p->pict_type = FF_S_TYPE; + p->pict_type = AV_PICTURE_TYPE_S; else - p->pict_type = FF_I_TYPE; + p->pict_type = AV_PICTURE_TYPE_I; if( xvid_enc_frame.out_flags & XVID_KEYFRAME ) { p->key_frame = 1; if( x->quicktime_format ) @@ -486,18 +525,14 @@ static av_cold int xvid_encode_close(AVCodecContext *avctx) { xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL); - if( avctx->extradata != NULL ) - av_freep(&avctx->extradata); + av_freep(&avctx->extradata); if( x->twopassbuffer != NULL ) { av_free(x->twopassbuffer); av_free(x->old_twopassbuffer); } - if( x->twopassfile != NULL ) - av_free(x->twopassfile); - if( x->intra_matrix != NULL ) - av_free(x->intra_matrix); - if( x->inter_matrix != NULL ) - av_free(x->inter_matrix); + av_free(x->twopassfile); + av_free(x->intra_matrix); + av_free(x->inter_matrix); return 0; } @@ -540,7 +575,7 @@ int xvid_strip_vol_header(AVCodecContext *avctx, } /* Less dangerous now, memmove properly copies the two chunks of overlapping data */ - memmove(frame, &(frame[vo_len]), frame_len - vo_len); + memmove(frame, &frame[vo_len], frame_len - vo_len); return frame_len - vo_len; } else return frame_len; @@ -634,7 +669,7 @@ static int xvid_ff_2pass_create(xvid_plg_create_t * param, /* This is because we can safely prevent a buffer overflow */ log[0] = 0; snprintf(log, BUFFER_REMAINING(log), - "# ffmpeg 2-pass log file, using xvid codec\n"); + "# avconv 2-pass log file, using xvid codec\n"); snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log), "# Do not modify. libxvidcore version: %d.%d.%d\n\n", XVID_VERSION_MAJOR(XVID_VERSION), @@ -714,7 +749,7 @@ static int xvid_ff_2pass_before(struct xvid_context *ref, static int xvid_ff_2pass_after(struct xvid_context *ref, xvid_plg_data_t *param) { char *log = ref->twopassbuffer; - char *frame_types = " ipbs"; + const char *frame_types = " ipbs"; char frame_type; /* Quick bounds check */ @@ -770,53 +805,19 @@ int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2) { } } -/* Wrapper to work around the lack of mkstemp() on mingw/cygin. - * Also, tries to create file in /tmp first, if possible. - * *prefix can be a character constant; *filename will be allocated internally. - * @return file descriptor of opened file (or -1 on error) - * and opened file name in **filename. */ -int ff_tempfile(char *prefix, char **filename) { - int fd=-1; -#if !HAVE_MKSTEMP - *filename = tempnam(".", prefix); -#else - size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */ - *filename = av_malloc(len); -#endif - /* -----common section-----*/ - if (*filename == NULL) { - av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n"); - return -1; - } -#if !HAVE_MKSTEMP - fd = open(*filename, O_RDWR | O_BINARY | O_CREAT, 0444); -#else - snprintf(*filename, len, "/tmp/%sXXXXXX", prefix); - fd = mkstemp(*filename); - if (fd < 0) { - snprintf(*filename, len, "./%sXXXXXX", prefix); - fd = mkstemp(*filename); - } -#endif - /* -----common section-----*/ - if (fd < 0) { - av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename); - return -1; - } - return fd; /* success */ -} - /** * Xvid codec definition for libavcodec. */ -AVCodec libxvid_encoder = { - "libxvid", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_MPEG4, - sizeof(struct xvid_context), - xvid_encode_init, - xvid_encode_frame, - xvid_encode_close, +AVCodec ff_libxvid_encoder = { + .name = "libxvid", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MPEG4, + .priv_data_size = sizeof(struct xvid_context), + .init = xvid_encode_init, + .encode = xvid_encode_frame, + .close = xvid_encode_close, .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, .long_name= NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"), }; + +#endif /* CONFIG_LIBXVID_ENCODER */