mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-08 13:22:53 +02:00
libxvid: switch to encode2().
This commit is contained in:
parent
760b004086
commit
4da6d194e5
@ -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"),
|
||||
|
Loading…
Reference in New Issue
Block a user