libxvid: switch to encode2().

This commit is contained in:
Anton Khirnov 2012-02-23 08:19:13 +01:00
parent 760b004086
commit 4da6d194e5

View File

@ -32,6 +32,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "libxvid_internal.h"
#include "mpegvideo.h"
#if !HAVE_MKSTEMP
#include <fcntl.h>
#endif
@ -73,7 +74,7 @@ struct xvid_ff_pass1 {
};
/* Prototypes - See function implementation for details */
int xvid_strip_vol_header(AVCodecContext *avctx, unsigned char *frame, unsigned int header_len, unsigned int frame_len);
int xvid_strip_vol_header(AVCodecContext *avctx, AVPacket *pkt, unsigned int header_len, unsigned int frame_len);
int xvid_ff_2pass(void *ref, int opt, void *p1, void *p2);
void xvid_correct_framerate(AVCodecContext *avctx);
@ -408,17 +409,25 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) {
* @param data Pointer to AVFrame of unencoded frame
* @return Returns 0 on success, -1 on failure
*/
static int xvid_encode_frame(AVCodecContext *avctx,
unsigned char *frame, int buf_size, void *data) {
int xerr, i;
static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *picture, int *got_packet)
{
int xerr, i, ret, user_packet = !!pkt->data;
char *tmp;
struct xvid_context *x = avctx->priv_data;
AVFrame *picture = data;
AVFrame *p = &x->encoded_picture;
int mb_width = (avctx->width + 15) / 16;
int mb_height = (avctx->height + 15) / 16;
xvid_enc_frame_t xvid_enc_frame;
xvid_enc_stats_t xvid_enc_stats;
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");
return ret;
}
/* Start setting up the frame */
memset(&xvid_enc_frame, 0, sizeof(xvid_enc_frame));
xvid_enc_frame.version = XVID_VERSION;
@ -427,8 +436,8 @@ static int xvid_encode_frame(AVCodecContext *avctx,
*p = *picture;
/* Let Xvid know where to put the frame. */
xvid_enc_frame.bitstream = frame;
xvid_enc_frame.length = buf_size;
xvid_enc_frame.bitstream = pkt->data;
xvid_enc_frame.length = pkt->size;
/* Initialize input image fields */
if( avctx->pix_fmt != PIX_FMT_YUV420P ) {
@ -488,7 +497,9 @@ static int xvid_encode_frame(AVCodecContext *avctx,
}
}
if( 0 <= xerr ) {
if (xerr > 0) {
*got_packet = 1;
p->quality = xvid_enc_stats.quant * FF_QP2LAMBDA;
if( xvid_enc_stats.type == XVID_TYPE_PVOP )
p->pict_type = AV_PICTURE_TYPE_P;
@ -500,14 +511,21 @@ static int xvid_encode_frame(AVCodecContext *avctx,
p->pict_type = AV_PICTURE_TYPE_I;
if( xvid_enc_frame.out_flags & XVID_KEYFRAME ) {
p->key_frame = 1;
pkt->flags |= AV_PKT_FLAG_KEY;
if( x->quicktime_format )
return xvid_strip_vol_header(avctx, frame,
return xvid_strip_vol_header(avctx, pkt,
xvid_enc_stats.hlength, xerr);
} else
p->key_frame = 0;
return xerr;
pkt->size = xerr;
return 0;
} else {
if (!user_packet)
av_free_packet(pkt);
if (!xerr)
return 0;
av_log(avctx, AV_LOG_ERROR, "Xvid: Encoding Error Occurred: %i\n", xerr);
return -1;
}
@ -551,16 +569,16 @@ static av_cold int xvid_encode_close(AVCodecContext *avctx) {
* @return Returns new length of frame data
*/
int xvid_strip_vol_header(AVCodecContext *avctx,
unsigned char *frame,
AVPacket *pkt,
unsigned int header_len,
unsigned int frame_len) {
int vo_len = 0, i;
for( i = 0; i < header_len - 3; i++ ) {
if( frame[i] == 0x00 &&
frame[i+1] == 0x00 &&
frame[i+2] == 0x01 &&
frame[i+3] == 0xB6 ) {
if( pkt->data[i] == 0x00 &&
pkt->data[i+1] == 0x00 &&
pkt->data[i+2] == 0x01 &&
pkt->data[i+3] == 0xB6 ) {
vo_len = i;
break;
}
@ -570,15 +588,15 @@ int xvid_strip_vol_header(AVCodecContext *avctx,
/* We need to store the header, so extract it */
if( avctx->extradata == NULL ) {
avctx->extradata = av_malloc(vo_len);
memcpy(avctx->extradata, frame, vo_len);
memcpy(avctx->extradata, pkt->data, vo_len);
avctx->extradata_size = vo_len;
}
/* Less dangerous now, memmove properly copies the two
chunks of overlapping data */
memmove(frame, &frame[vo_len], frame_len - vo_len);
return frame_len - vo_len;
} else
return frame_len;
memmove(pkt->data, &pkt->data[vo_len], frame_len - vo_len);
pkt->size = frame_len - vo_len;
}
return 0;
}
/**
@ -814,7 +832,7 @@ AVCodec ff_libxvid_encoder = {
.id = CODEC_ID_MPEG4,
.priv_data_size = sizeof(struct xvid_context),
.init = xvid_encode_init,
.encode = xvid_encode_frame,
.encode2 = 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"),