Commit 4da6d194 authored by Anton Khirnov's avatar Anton Khirnov

libxvid: switch to encode2().

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