summaryrefslogtreecommitdiff
path: root/libavcodec/libxvidff.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2012-02-23 08:19:13 +0100
committerAnton Khirnov <anton@khirnov.net>2012-02-23 19:55:23 +0100
commit4da6d194e5b00404f4d545adcaa8e206592ae746 (patch)
treef71f1ce160a2f2ca80d452bafc4ef7f13f3a7db7 /libavcodec/libxvidff.c
parent760b004086265bf12091698c729bd507cb9829da (diff)
libxvid: switch to encode2().
Diffstat (limited to 'libavcodec/libxvidff.c')
-rw-r--r--libavcodec/libxvidff.c60
1 files changed, 39 insertions, 21 deletions
diff --git a/libavcodec/libxvidff.c b/libavcodec/libxvidff.c
index a11e4ac913..44580d1364 100644
--- a/libavcodec/libxvidff.c
+++ b/libavcodec/libxvidff.c
@@ -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"),