summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorDerek Buitenhuis <derek.buitenhuis@gmail.com>2016-04-05 11:21:35 -0400
committerLuca Barbato <lu_zero@gentoo.org>2016-04-19 19:00:41 +0200
commiteae2ebded3b801ed55d32746b98db88ffe196f4f (patch)
tree4035cbebecb4775dbd6276e01da067a079cc01d2 /libavcodec
parent785bfb1d7bb8de567c3aac1d9cc369b55ac9fb7b (diff)
libxvid: Create extradata in init using a dummy frame
Modifying global header extradata in encode_frame is an API violation and only happens to work currently because mov writes its header at the end of the file. Heavily based off of a patch from 2012 by Nicolas George. Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com> Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/libxvid.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c
index b352849b96..49952f57ca 100644
--- a/libavcodec/libxvid.c
+++ b/libavcodec/libxvid.c
@@ -85,6 +85,10 @@ struct xvid_ff_pass1 {
struct xvid_context *context; /**< Pointer to private context */
};
+static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+ const AVFrame *picture, int *got_packet);
+
+
/*
* Xvid 2-Pass Kludge Section
*
@@ -677,6 +681,43 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (avctx->max_b_frames > 0 && !x->quicktime_format)
xvid_enc_create.global |= XVID_GLOBAL_PACKED;
+ /* Encode a dummy frame to get the extradata immediately */
+ if (x->quicktime_format) {
+ AVFrame *picture;
+ AVPacket packet;
+ int got_packet, ret;
+
+ av_init_packet(&packet);
+
+ picture = av_frame_alloc();
+ if (!picture)
+ return AVERROR(ENOMEM);
+
+ xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL);
+ if (xerr) {
+ av_frame_free(&picture);
+ av_log(avctx, AV_LOG_ERROR, "Xvid: Could not create encoder reference\n");
+ return AVERROR_UNKNOWN;
+ }
+ x->encoder_handle = xvid_enc_create.handle;
+
+ picture->width = avctx->width;
+ picture->height = avctx->height;
+ picture->format = avctx->pix_fmt;
+
+ if ((ret = av_frame_get_buffer(picture, 32)) < 0) {
+ xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL);
+ av_frame_free(&picture);
+ return ret;
+ }
+
+ ret = xvid_encode_frame(avctx, &packet, picture, &got_packet);
+ if (!ret && got_packet)
+ av_packet_unref(&packet);
+ av_frame_free(&picture);
+ xvid_encore(x->encoder_handle, XVID_ENC_DESTROY, NULL, NULL);
+ }
+
/* Create encoder context */
xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL);
if (xerr) {