diff options
Diffstat (limited to 'libavcodec/libxvid.c')
-rw-r--r-- | libavcodec/libxvid.c | 68 |
1 files changed, 41 insertions, 27 deletions
diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c index dd1e3e3e8b..05a12db58b 100644 --- a/libavcodec/libxvid.c +++ b/libavcodec/libxvid.c @@ -2,20 +2,20 @@ * Interface to xvidcore for mpeg4 encoding * Copyright (c) 2004 Adam Thayer <krevnik@comcast.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg 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. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -28,6 +28,8 @@ #include <xvid.h> #include <unistd.h> #include "avcodec.h" +#include "internal.h" +#include "libavutil/file.h" #include "libavutil/cpu.h" #include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" @@ -58,6 +60,7 @@ struct xvid_context { char *twopassbuffer; /**< Character buffer for two-pass */ char *old_twopassbuffer; /**< Old character buffer (two-pass) */ char *twopassfile; /**< second pass temp file name */ + int twopassfd; unsigned char *intra_matrix; /**< P-Frame Quant Matrix */ unsigned char *inter_matrix; /**< I-Frame Quant Matrix */ }; @@ -70,6 +73,8 @@ struct xvid_ff_pass1 { struct xvid_context *context; /**< Pointer to private context */ }; +static int xvid_encode_close(AVCodecContext *avctx); + /* * Xvid 2-Pass Kludge Section * @@ -100,7 +105,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), - "# avconv 2-pass log file, using xvid codec\n"); + "# ffmpeg 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), @@ -354,7 +359,9 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { xvid_enc_create_t xvid_enc_create = { 0 }; xvid_enc_plugin_t plugins[7]; - /* Bring in VOP flags from avconv command-line */ + x->twopassfd = -1; + + /* Bring in VOP flags from ffmpeg 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 */ @@ -408,7 +415,7 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { break; } - /* Bring in VOL flags from avconv command-line */ + /* Bring in VOL flags from ffmpeg command-line */ x->vol_flags = 0; if( xvid_flags & CODEC_FLAG_GMC ) { x->vol_flags |= XVID_VOL_GMC; @@ -472,7 +479,7 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { if( x->twopassbuffer == NULL || x->old_twopassbuffer == NULL ) { av_log(avctx, AV_LOG_ERROR, "Xvid: Cannot allocate 2-pass log buffers\n"); - return -1; + goto fail; } x->twopassbuffer[0] = x->old_twopassbuffer[0] = 0; @@ -483,28 +490,27 @@ 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 = av_tempfile("xvidff.", &x->twopassfile, 0, avctx); if( fd == -1 ) { av_log(avctx, AV_LOG_ERROR, "Xvid: Cannot write 2-pass pipe\n"); - return -1; + goto fail; } + x->twopassfd = fd; if( avctx->stats_in == NULL ) { av_log(avctx, AV_LOG_ERROR, "Xvid: No 2-pass information loaded for second pass\n"); - return -1; + goto fail; } if( strlen(avctx->stats_in) > write(fd, avctx->stats_in, strlen(avctx->stats_in)) ) { - close(fd); av_log(avctx, AV_LOG_ERROR, "Xvid: Cannot write to 2-pass pipe\n"); - return -1; + goto fail; } - close(fd); rc2pass2.filename = x->twopassfile; plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2; plugins[xvid_enc_create.num_plugins].param = &rc2pass2; @@ -602,13 +608,16 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); if( xerr ) { av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n"); - return -1; + goto fail; } x->encoder_handle = xvid_enc_create.handle; avctx->coded_frame = &x->encoded_picture; return 0; +fail: + xvid_encode_close(avctx); + return -1; } static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt, @@ -624,11 +633,8 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt, xvid_enc_frame_t xvid_enc_frame = { 0 }; xvid_enc_stats_t xvid_enc_stats = { 0 }; - if (!user_packet && - (ret = av_new_packet(pkt, mb_width*mb_height*MAX_MB_BYTES + FF_MIN_BUFFER_SIZE)) < 0) { - av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n"); + if ((ret = ff_alloc_packet2(avctx, pkt, mb_width*mb_height*MAX_MB_BYTES + FF_MIN_BUFFER_SIZE)) < 0) return ret; - } /* Start setting up the frame */ xvid_enc_frame.version = XVID_VERSION; @@ -663,8 +669,8 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt, XVID_TYPE_AUTO; /* Pixel aspect ratio setting */ - if (avctx->sample_aspect_ratio.num < 1 || avctx->sample_aspect_ratio.num > 255 || - avctx->sample_aspect_ratio.den < 1 || avctx->sample_aspect_ratio.den > 255) { + if (avctx->sample_aspect_ratio.num < 0 || avctx->sample_aspect_ratio.num > 255 || + avctx->sample_aspect_ratio.den < 0 || avctx->sample_aspect_ratio.den > 255) { av_log(avctx, AV_LOG_ERROR, "Invalid pixel aspect ratio %i/%i\n", avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den); return -1; @@ -734,16 +740,24 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt, static av_cold int xvid_encode_close(AVCodecContext *avctx) { struct xvid_context *x = avctx->priv_data; - xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL); + if(x->encoder_handle) + xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL); + x->encoder_handle = NULL; av_freep(&avctx->extradata); if( x->twopassbuffer != NULL ) { - av_free(x->twopassbuffer); - av_free(x->old_twopassbuffer); + av_freep(&x->twopassbuffer); + av_freep(&x->old_twopassbuffer); + avctx->stats_out = NULL; + } + if (x->twopassfd>=0) { + unlink(x->twopassfile); + close(x->twopassfd); + x->twopassfd = -1; } - av_free(x->twopassfile); - av_free(x->intra_matrix); - av_free(x->inter_matrix); + av_freep(&x->twopassfile); + av_freep(&x->intra_matrix); + av_freep(&x->inter_matrix); return 0; } |