summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-02-08 02:59:09 +0100
committerMichael Niedermayer <michaelni@gmx.at>2012-02-08 05:53:35 +0100
commit18d0a16fc9d189b1d5593f9a42bb2316e9a66ca9 (patch)
treeaad3d9b1a07b9efebd7435bb27dde147cfa67913 /libavcodec
parent950930b461cef025152de406f816a3b2efffb540 (diff)
parentef1c785f11c168384e42d147648c8fdf5317739b (diff)
Merge remote-tracking branch 'qatar/master'
* qatar/master: swscale: make yuv2yuv1 use named registers. h264: mark h264_idct_add8_10 with number of XMM registers. swscale: fix V plane memory location in bilinear/unscaled RGB/YUYV case. vp8: always update next_framep[] before returning from decode_frame(). avconv: estimate next_dts from framerate if it is set. avconv: better next_dts usage. avconv: rename InputStream.pts to last_dts. avconv: reduce overloading for InputStream.pts. avconv: rename InputStream.next_pts to next_dts. avconv: rework -t handling for encoding. avconv: set encoder timebase for subtitles. pva-demux test: add -vn swscale: K&R formatting cosmetics for SPARC code apedec: allow the user to set the maximum number of output samples per call apedec: do not unnecessarily zero output samples for mono frames apedec: allocate a single flat buffer for decoded samples apedec: use sizeof(field) instead of sizeof(type) swscale: split C output functions into separate file. swscale: Split C input functions into separate file. bytestream: Add bytestream2 writing API. The avconv changes are due to massive regressions and bugs not merged yet. Conflicts: ffmpeg.c libavcodec/vp8.c libswscale/swscale.c libswscale/x86/swscale_template.c tests/fate/demux.mak tests/ref/lavf/asf tests/ref/lavf/avi tests/ref/lavf/mkv tests/ref/lavf/mpg tests/ref/lavf/nut tests/ref/lavf/ogg tests/ref/lavf/rm tests/ref/lavf/ts tests/ref/seek/lavf_avi tests/ref/seek/lavf_mkv tests/ref/seek/lavf_rm Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/apedec.c104
-rw-r--r--libavcodec/bytestream.h112
-rw-r--r--libavcodec/vp8.c78
-rw-r--r--libavcodec/x86/h264_idct_10bit.asm2
4 files changed, 206 insertions, 90 deletions
diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
index 35c9a23dd6..1cd7d1e66d 100644
--- a/libavcodec/apedec.c
+++ b/libavcodec/apedec.c
@@ -25,13 +25,13 @@
#include "bytestream.h"
#include "libavutil/audioconvert.h"
#include "libavutil/avassert.h"
+#include "libavutil/opt.h"
/**
* @file
* Monkey's Audio lossless audio decoder
*/
-#define BLOCKS_PER_LOOP 4608
#define MAX_CHANNELS 2
#define MAX_BYTESPERSAMPLE 3
@@ -126,6 +126,7 @@ typedef struct APEPredictor {
/** Decoder context */
typedef struct APEContext {
+ AVClass *class; ///< class for AVOptions
AVCodecContext *avctx;
AVFrame frame;
DSPContext dsp;
@@ -142,8 +143,10 @@ typedef struct APEContext {
int frameflags; ///< frame flags
APEPredictor predictor; ///< predictor used for final reconstruction
- int32_t decoded0[BLOCKS_PER_LOOP]; ///< decoded data for the first channel
- int32_t decoded1[BLOCKS_PER_LOOP]; ///< decoded data for the second channel
+ int32_t *decoded_buffer;
+ int decoded_size;
+ int32_t *decoded[MAX_CHANNELS]; ///< decoded data for each channel
+ int blocks_per_loop; ///< maximum number of samples to decode for each call
int16_t* filterbuf[APE_FILTER_LEVELS]; ///< filter memory
@@ -170,8 +173,9 @@ static av_cold int ape_decode_close(AVCodecContext *avctx)
for (i = 0; i < APE_FILTER_LEVELS; i++)
av_freep(&s->filterbuf[i]);
+ av_freep(&s->decoded_buffer);
av_freep(&s->data);
- s->data_size = 0;
+ s->decoded_size = s->data_size = 0;
return 0;
}
@@ -469,19 +473,13 @@ static inline int ape_decode_value(APEContext *ctx, APERice *rice)
static void entropy_decode(APEContext *ctx, int blockstodecode, int stereo)
{
- int32_t *decoded0 = ctx->decoded0;
- int32_t *decoded1 = ctx->decoded1;
+ int32_t *decoded0 = ctx->decoded[0];
+ int32_t *decoded1 = ctx->decoded[1];
- if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) {
- /* We are pure silence, just memset the output buffer. */
- memset(decoded0, 0, blockstodecode * sizeof(int32_t));
- memset(decoded1, 0, blockstodecode * sizeof(int32_t));
- } else {
- while (blockstodecode--) {
- *decoded0++ = ape_decode_value(ctx, &ctx->riceY);
- if (stereo)
- *decoded1++ = ape_decode_value(ctx, &ctx->riceX);
- }
+ while (blockstodecode--) {
+ *decoded0++ = ape_decode_value(ctx, &ctx->riceY);
+ if (stereo)
+ *decoded1++ = ape_decode_value(ctx, &ctx->riceX);
}
}
@@ -525,7 +523,7 @@ static void init_predictor_decoder(APEContext *ctx)
APEPredictor *p = &ctx->predictor;
/* Zero the history buffers */
- memset(p->historybuffer, 0, PREDICTOR_SIZE * sizeof(int32_t));
+ memset(p->historybuffer, 0, PREDICTOR_SIZE * sizeof(*p->historybuffer));
p->buf = p->historybuffer;
/* Initialize and zero the coefficients */
@@ -593,8 +591,8 @@ static av_always_inline int predictor_update_filter(APEPredictor *p,
static void predictor_decode_stereo(APEContext *ctx, int count)
{
APEPredictor *p = &ctx->predictor;
- int32_t *decoded0 = ctx->decoded0;
- int32_t *decoded1 = ctx->decoded1;
+ int32_t *decoded0 = ctx->decoded[0];
+ int32_t *decoded1 = ctx->decoded[1];
while (count--) {
/* Predictor Y */
@@ -610,7 +608,8 @@ static void predictor_decode_stereo(APEContext *ctx, int count)
/* Have we filled the history buffer? */
if (p->buf == p->historybuffer + HISTORY_SIZE) {
- memmove(p->historybuffer, p->buf, PREDICTOR_SIZE * sizeof(int32_t));
+ memmove(p->historybuffer, p->buf,
+ PREDICTOR_SIZE * sizeof(*p->historybuffer));
p->buf = p->historybuffer;
}
}
@@ -619,7 +618,7 @@ static void predictor_decode_stereo(APEContext *ctx, int count)
static void predictor_decode_mono(APEContext *ctx, int count)
{
APEPredictor *p = &ctx->predictor;
- int32_t *decoded0 = ctx->decoded0;
+ int32_t *decoded0 = ctx->decoded[0];
int32_t predictionA, currentA, A, sign;
currentA = p->lastA[0];
@@ -650,7 +649,8 @@ static void predictor_decode_mono(APEContext *ctx, int count)
/* Have we filled the history buffer? */
if (p->buf == p->historybuffer + HISTORY_SIZE) {
- memmove(p->historybuffer, p->buf, PREDICTOR_SIZE * sizeof(int32_t));
+ memmove(p->historybuffer, p->buf,
+ PREDICTOR_SIZE * sizeof(*p->historybuffer));
p->buf = p->historybuffer;
}
@@ -668,8 +668,8 @@ static void do_init_filter(APEFilter *f, int16_t *buf, int order)
f->delay = f->historybuffer + order * 2;
f->adaptcoeffs = f->historybuffer + order;
- memset(f->historybuffer, 0, (order * 2) * sizeof(int16_t));
- memset(f->coeffs, 0, order * sizeof(int16_t));
+ memset(f->historybuffer, 0, (order * 2) * sizeof(*f->historybuffer));
+ memset(f->coeffs, 0, order * sizeof(*f->coeffs));
f->avg = 0;
}
@@ -725,7 +725,7 @@ static void do_apply_filter(APEContext *ctx, int version, APEFilter *f,
/* Have we filled the history buffer? */
if (f->delay == f->historybuffer + HISTORY_SIZE + (order * 2)) {
memmove(f->historybuffer, f->delay - (order * 2),
- (order * 2) * sizeof(int16_t));
+ (order * 2) * sizeof(*f->historybuffer));
f->delay = f->historybuffer + order * 2;
f->adaptcoeffs = f->historybuffer + order;
}
@@ -773,33 +773,29 @@ static int init_frame_decoder(APEContext *ctx)
static void ape_unpack_mono(APEContext *ctx, int count)
{
- int32_t *decoded0 = ctx->decoded0;
- int32_t *decoded1 = ctx->decoded1;
-
if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) {
- entropy_decode(ctx, count, 0);
/* We are pure silence, so we're done. */
av_log(ctx->avctx, AV_LOG_DEBUG, "pure silence mono\n");
return;
}
entropy_decode(ctx, count, 0);
- ape_apply_filters(ctx, decoded0, NULL, count);
+ ape_apply_filters(ctx, ctx->decoded[0], NULL, count);
/* Now apply the predictor decoding */
predictor_decode_mono(ctx, count);
/* Pseudo-stereo - just copy left channel to right channel */
if (ctx->channels == 2) {
- memcpy(decoded1, decoded0, count * sizeof(*decoded1));
+ memcpy(ctx->decoded[1], ctx->decoded[0], count * sizeof(*ctx->decoded[1]));
}
}
static void ape_unpack_stereo(APEContext *ctx, int count)
{
int32_t left, right;
- int32_t *decoded0 = ctx->decoded0;
- int32_t *decoded1 = ctx->decoded1;
+ int32_t *decoded0 = ctx->decoded[0];
+ int32_t *decoded1 = ctx->decoded[1];
if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) {
/* We are pure silence, so we're done. */
@@ -883,9 +879,6 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
}
s->samples = nblocks;
- memset(s->decoded0, 0, sizeof(s->decoded0));
- memset(s->decoded1, 0, sizeof(s->decoded1));
-
/* Initialize the frame decoder */
if (init_frame_decoder(s) < 0) {
av_log(avctx, AV_LOG_ERROR, "Error reading frame header\n");
@@ -900,7 +893,16 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
return avpkt->size;
}
- blockstodecode = FFMIN(BLOCKS_PER_LOOP, s->samples);
+ blockstodecode = FFMIN(s->blocks_per_loop, s->samples);
+
+ /* reallocate decoded sample buffer if needed */
+ av_fast_malloc(&s->decoded_buffer, &s->decoded_size,
+ 2 * FFALIGN(blockstodecode, 8) * sizeof(*s->decoded_buffer));
+ if (!s->decoded_buffer)
+ return AVERROR(ENOMEM);
+ memset(s->decoded_buffer, 0, s->decoded_size);
+ s->decoded[0] = s->decoded_buffer;
+ s->decoded[1] = s->decoded_buffer + FFALIGN(blockstodecode, 8);
/* get output buffer */
s->frame.nb_samples = blockstodecode;
@@ -927,25 +929,25 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
case 8:
sample8 = (uint8_t *)s->frame.data[0];
for (i = 0; i < blockstodecode; i++) {
- *sample8++ = (s->decoded0[i] + 0x80) & 0xff;
+ *sample8++ = (s->decoded[0][i] + 0x80) & 0xff;
if (s->channels == 2)
- *sample8++ = (s->decoded1[i] + 0x80) & 0xff;
+ *sample8++ = (s->decoded[1][i] + 0x80) & 0xff;
}
break;
case 16:
sample16 = (int16_t *)s->frame.data[0];
for (i = 0; i < blockstodecode; i++) {
- *sample16++ = s->decoded0[i];
+ *sample16++ = s->decoded[0][i];
if (s->channels == 2)
- *sample16++ = s->decoded1[i];
+ *sample16++ = s->decoded[1][i];
}
break;
case 24:
sample24 = (int32_t *)s->frame.data[0];
for (i = 0; i < blockstodecode; i++) {
- *sample24++ = s->decoded0[i] << 8;
+ *sample24++ = s->decoded[0][i] << 8;
if (s->channels == 2)
- *sample24++ = s->decoded1[i] << 8;
+ *sample24++ = s->decoded[1][i] << 8;
}
break;
}
@@ -964,6 +966,21 @@ static void ape_flush(AVCodecContext *avctx)
s->samples= 0;
}
+#define OFFSET(x) offsetof(APEContext, x)
+#define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM)
+static const AVOption options[] = {
+ { "max_samples", "maximum number of samples decoded per call", OFFSET(blocks_per_loop), AV_OPT_TYPE_INT, { 4608 }, 1, INT_MAX, PAR, "max_samples" },
+ { "all", "no maximum. decode all samples for each packet at once", 0, AV_OPT_TYPE_CONST, { INT_MAX }, INT_MIN, INT_MAX, PAR, "max_samples" },
+ { NULL},
+};
+
+static const AVClass ape_decoder_class = {
+ .class_name = "APE decoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVCodec ff_ape_decoder = {
.name = "ape",
.type = AVMEDIA_TYPE_AUDIO,
@@ -975,4 +992,5 @@ AVCodec ff_ape_decoder = {
.capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DELAY | CODEC_CAP_DR1,
.flush = ape_flush,
.long_name = NULL_IF_CONFIG_SMALL("Monkey's Audio"),
+ .priv_class = &ape_decoder_class,
};
diff --git a/libavcodec/bytestream.h b/libavcodec/bytestream.h
index 71c70aac84..d315e3f818 100644
--- a/libavcodec/bytestream.h
+++ b/libavcodec/bytestream.h
@@ -1,6 +1,7 @@
/*
* Bytestream functions
* copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@free.fr>
+ * Copyright (c) 2012 Aneesh Dogra (lionaneesh) <lionaneesh@gmail.com>
*
* This file is part of FFmpeg.
*
@@ -30,6 +31,11 @@ typedef struct {
const uint8_t *buffer, *buffer_end, *buffer_start;
} GetByteContext;
+typedef struct {
+ uint8_t *buffer, *buffer_end, *buffer_start;
+ int eof;
+} PutByteContext;
+
#define DEF_T(type, name, bytes, read, write) \
static av_always_inline type bytestream_get_ ## name(const uint8_t **b){\
(*b) += bytes;\
@@ -39,6 +45,17 @@ static av_always_inline void bytestream_put_ ##name(uint8_t **b, const type valu
write(*b, value);\
(*b) += bytes;\
}\
+static av_always_inline void bytestream2_put_ ## name ## u(PutByteContext *p, const type value)\
+{\
+ bytestream_put_ ## name(&p->buffer, value);\
+}\
+static av_always_inline void bytestream2_put_ ## name(PutByteContext *p, const type value){\
+ if (!p->eof && (p->buffer_end - p->buffer >= bytes)) {\
+ write(p->buffer, value);\
+ p->buffer += bytes;\
+ } else\
+ p->eof = 1;\
+}\
static av_always_inline type bytestream2_get_ ## name ## u(GetByteContext *g)\
{\
return bytestream_get_ ## name(&g->buffer);\
@@ -119,22 +136,53 @@ static av_always_inline void bytestream2_init(GetByteContext *g,
g->buffer_end = buf + buf_size;
}
+static av_always_inline void bytestream2_init_writer(PutByteContext *p,
+ uint8_t *buf, int buf_size)
+{
+ p->buffer = buf;
+ p->buffer_start = buf;
+ p->buffer_end = buf + buf_size;
+ p->eof = 0;
+}
+
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
{
return g->buffer_end - g->buffer;
}
+static av_always_inline unsigned int bytestream2_get_bytes_left_p(PutByteContext *p)
+{
+ return p->buffer_end - p->buffer;
+}
+
static av_always_inline void bytestream2_skip(GetByteContext *g,
unsigned int size)
{
g->buffer += FFMIN(g->buffer_end - g->buffer, size);
}
+static av_always_inline void bytestream2_skip_p(PutByteContext *p,
+ unsigned int size)
+{
+ int size2;
+ if (p->eof)
+ return;
+ size2 = FFMIN(p->buffer_end - p->buffer, size);
+ if (size2 != size)
+ p->eof = 1;
+ p->buffer += size2;
+}
+
static av_always_inline int bytestream2_tell(GetByteContext *g)
{
return (int)(g->buffer - g->buffer_start);
}
+static av_always_inline int bytestream2_tell_p(PutByteContext *p)
+{
+ return (int)(p->buffer - p->buffer_start);
+}
+
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset,
int whence)
{
@@ -158,6 +206,36 @@ static av_always_inline int bytestream2_seek(GetByteContext *g, int offset,
return bytestream2_tell(g);
}
+static av_always_inline int bytestream2_seek_p(PutByteContext *p, int offset,
+ int whence)
+{
+ p->eof = 0;
+ switch (whence) {
+ case SEEK_CUR:
+ if (p->buffer_end - p->buffer < offset)
+ p->eof = 1;
+ offset = av_clip(offset, -(p->buffer - p->buffer_start),
+ p->buffer_end - p->buffer);
+ p->buffer += offset;
+ break;
+ case SEEK_END:
+ if (offset > 0)
+ p->eof = 1;
+ offset = av_clip(offset, -(p->buffer_end - p->buffer_start), 0);
+ p->buffer = p->buffer_end + offset;
+ break;
+ case SEEK_SET:
+ if (p->buffer_end - p->buffer_start < offset)
+ p->eof = 1;
+ offset = av_clip(offset, 0, p->buffer_end - p->buffer_start);
+ p->buffer = p->buffer_start + offset;
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+ return bytestream2_tell_p(p);
+}
+
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g,
uint8_t *dst,
unsigned int size)
@@ -168,6 +246,40 @@ static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g,
return size2;
}
+static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p,
+ const uint8_t *src,
+ unsigned int size)
+{
+ int size2;
+ if (p->eof)
+ return 0;
+ size2 = FFMIN(p->buffer_end - p->buffer, size);
+ if (size2 != size)
+ p->eof = 1;
+ memcpy(p->buffer, src, size2);
+ p->buffer += size2;
+ return size2;
+}
+
+static av_always_inline void bytestream2_set_buffer(PutByteContext *p,
+ const uint8_t c,
+ unsigned int size)
+{
+ int size2;
+ if (p->eof)
+ return;
+ size2 = FFMIN(p->buffer_end - p->buffer, size);
+ if (size2 != size)
+ p->eof = 1;
+ memset(p->buffer, c, size2);
+ p->buffer += size2;
+}
+
+static av_always_inline unsigned int bytestream2_get_eof(PutByteContext *p)
+{
+ return p->eof;
+}
+
static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, uint8_t *dst, unsigned int size)
{
memcpy(dst, *b, size);
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 370fb0070c..4728393d10 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -1561,18 +1561,6 @@ static void release_queued_segmaps(VP8Context *s, int is_close)
s->maps_are_invalid = 0;
}
-/**
- * Sets things up for skipping the current frame.
- * In particular, removes it from the reference buffers.
- */
-static void skipframe_clear(VP8Context *s)
-{
- s->invisible = 1;
- s->next_framep[VP56_FRAME_CURRENT] = NULL;
- if (s->update_last)
- s->next_framep[VP56_FRAME_PREVIOUS] = NULL;
-}
-
static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
AVPacket *avpkt)
{
@@ -1584,7 +1572,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
release_queued_segmaps(s, 0);
if ((ret = decode_frame_header(s, avpkt->data, avpkt->size)) < 0)
- return ret;
+ goto err;
prev_frame = s->framep[VP56_FRAME_CURRENT];
@@ -1594,6 +1582,11 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
skip_thresh = !referenced ? AVDISCARD_NONREF :
!s->keyframe ? AVDISCARD_NONKEY : AVDISCARD_ALL;
+ if (avctx->skip_frame >= skip_thresh) {
+ s->invisible = 1;
+ memcpy(&s->next_framep[0], &s->framep[0], sizeof(s->framep[0]) * 4);
+ goto skip_decode;
+ }
s->deblock_filter = s->filter.level && avctx->skip_loop_filter < skip_thresh;
// release no longer referenced frames
@@ -1618,6 +1611,27 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
av_log(avctx, AV_LOG_FATAL, "Ran out of free frames!\n");
abort();
}
+ if (curframe->data[0])
+ vp8_release_frame(s, curframe, 1, 0);
+
+ // Given that arithmetic probabilities are updated every frame, it's quite likely
+ // that the values we have on a random interframe are complete junk if we didn't
+ // start decode on a keyframe. So just don't display anything rather than junk.
+ if (!s->keyframe && (!s->framep[VP56_FRAME_PREVIOUS] ||
+ !s->framep[VP56_FRAME_GOLDEN] ||
+ !s->framep[VP56_FRAME_GOLDEN2])) {
+ av_log(avctx, AV_LOG_WARNING, "Discarding interframe without a prior keyframe!\n");
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+
+ curframe->key_frame = s->keyframe;
+ curframe->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+ curframe->reference = referenced ? 3 : 0;
+ if ((ret = vp8_alloc_frame(s, curframe))) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed!\n");
+ goto err;
+ }
// check if golden and altref are swapped
if (s->update_altref != VP56_FRAME_NONE) {
@@ -1637,36 +1651,6 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
}
s->next_framep[VP56_FRAME_CURRENT] = curframe;
- if (avctx->skip_frame >= skip_thresh) {
- skipframe_clear(s);
- ret = avpkt->size;
- goto skip_decode;
- }
-
- // Given that arithmetic probabilities are updated every frame, it's quite likely
- // that the values we have on a random interframe are complete junk if we didn't
- // start decode on a keyframe. So just don't display anything rather than junk.
- if (!s->keyframe && (!s->framep[VP56_FRAME_PREVIOUS] ||
- !s->framep[VP56_FRAME_GOLDEN] ||
- !s->framep[VP56_FRAME_GOLDEN2])) {
- av_log(avctx, AV_LOG_WARNING, "Discarding interframe without a prior keyframe!\n");
- skipframe_clear(s);
- ret = AVERROR_INVALIDDATA;
- goto skip_decode;
- }
-
- if (curframe->data[0])
- vp8_release_frame(s, curframe, 1, 0);
-
- curframe->key_frame = s->keyframe;
- curframe->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
- curframe->reference = referenced ? 3 : 0;
- if ((ret = vp8_alloc_frame(s, curframe))) {
- av_log(avctx, AV_LOG_ERROR, "get_buffer() failed!\n");
- skipframe_clear(s);
- goto skip_decode;
- }
-
ff_thread_finish_setup(avctx);
s->linesize = curframe->linesize[0];
@@ -1778,20 +1762,22 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
}
ff_thread_report_progress(curframe, INT_MAX, 0);
- ret = avpkt->size;
+ memcpy(&s->framep[0], &s->next_framep[0], sizeof(s->framep[0]) * 4);
+
skip_decode:
// if future frames don't use the updated probabilities,
// reset them to the values we saved
if (!s->update_probabilities)
s->prob[0] = s->prob[1];
- memcpy(&s->framep[0], &s->next_framep[0], sizeof(s->framep[0]) * 4);
-
if (!s->invisible) {
*(AVFrame*)data = *curframe;
*data_size = sizeof(AVFrame);
}
+ return avpkt->size;
+err:
+ memcpy(&s->next_framep[0], &s->framep[0], sizeof(s->framep[0]) * 4);
return ret;
}
diff --git a/libavcodec/x86/h264_idct_10bit.asm b/libavcodec/x86/h264_idct_10bit.asm
index f94207bb11..27a18f47da 100644
--- a/libavcodec/x86/h264_idct_10bit.asm
+++ b/libavcodec/x86/h264_idct_10bit.asm
@@ -315,7 +315,7 @@ IDCT_ADD16INTRA_10 avx
; h264_idct_add8(pixel **dst, const int *block_offset, dctcoef *block, int stride, const uint8_t nnzc[6*8])
;-----------------------------------------------------------------------------
%macro IDCT_ADD8 1
-cglobal h264_idct_add8_10_%1,5,7
+cglobal h264_idct_add8_10_%1,5,7,7
%if ARCH_X86_64
mov r10, r0
%endif