typedef struct {
AVFrame previous_frame;
z_stream zstream;
- int size;
} ZeroCodecContext;
static int zerocodec_decode_frame(AVCodecContext *avctx, void *data,
int *got_frame, AVPacket *avpkt)
{
ZeroCodecContext *zc = avctx->priv_data;
- AVFrame *pic = avctx->coded_frame;
+ AVFrame *pic = data;
AVFrame *prev_pic = &zc->previous_frame;
z_stream *zstream = &zc->zstream;
uint8_t *prev = prev_pic->data[0];
uint8_t *dst;
- int i, j, zret;
-
- pic->reference = 3;
+ int i, j, zret, ret;
if (avpkt->flags & AV_PKT_FLAG_KEY) {
pic->key_frame = 1;
av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
return AVERROR_INVALIDDATA;
}
+
+ prev += (avctx->height - 1) * prev_pic->linesize[0];
+
pic->key_frame = 0;
pic->pict_type = AV_PICTURE_TYPE_P;
}
return AVERROR_INVALIDDATA;
}
- if (ff_get_buffer(avctx, pic) < 0) {
+ if (ff_get_buffer(avctx, pic, AV_GET_BUFFER_FLAG_REF) < 0) {
av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
return AVERROR(ENOMEM);
}
zstream->next_in = avpkt->data;
zstream->avail_in = avpkt->size;
- dst = pic->data[0];
+ dst = pic->data[0] + (avctx->height - 1) * pic->linesize[0];
/**
* ZeroCodec has very simple interframe compression. If a value
zret = inflate(zstream, Z_SYNC_FLUSH);
if (zret != Z_OK && zret != Z_STREAM_END) {
- avctx->release_buffer(avctx, pic);
av_log(avctx, AV_LOG_ERROR,
"Inflate failed with return code: %d.\n", zret);
return AVERROR_INVALIDDATA;
for (j = 0; j < avctx->width << 1; j++)
dst[j] += prev[j] & -!dst[j];
- prev += prev_pic->linesize[0];
- dst += pic->linesize[0];
+ prev -= prev_pic->linesize[0];
+ dst -= pic->linesize[0];
}
- /* Release the previous buffer if need be */
- if (prev_pic->data[0])
- avctx->release_buffer(avctx, prev_pic);
+ av_frame_unref(&zc->previous_frame);
+ if ((ret = av_frame_ref(&zc->previous_frame, pic)) < 0)
+ return ret;
*got_frame = 1;
- *(AVFrame *)data = *pic;
-
- /* Store the previous frame for use later.
- * FFSWAP ensures that e.g. pic->data is NULLed. */
- FFSWAP(AVFrame, *pic, *prev_pic);
return avpkt->size;
}
static av_cold int zerocodec_decode_close(AVCodecContext *avctx)
{
ZeroCodecContext *zc = avctx->priv_data;
- AVFrame *prev_pic = &zc->previous_frame;
-
- inflateEnd(&zc->zstream);
- /* Release last frame */
- if (prev_pic->data[0])
- avctx->release_buffer(avctx, prev_pic);
+ av_frame_unref(&zc->previous_frame);
- av_freep(&avctx->coded_frame);
+ inflateEnd(&zc->zstream);
return 0;
}
avctx->pix_fmt = AV_PIX_FMT_UYVY422;
avctx->bits_per_raw_sample = 8;
- zc->size = avpicture_get_size(avctx->pix_fmt,
- avctx->width, avctx->height);
-
zstream->zalloc = Z_NULL;
zstream->zfree = Z_NULL;
zstream->opaque = Z_NULL;
return AVERROR(ENOMEM);
}
- avctx->coded_frame = avcodec_alloc_frame();
- if (!avctx->coded_frame) {
- av_log(avctx, AV_LOG_ERROR, "Could not allocate frame buffer.\n");
- zerocodec_decode_close(avctx);
- return AVERROR(ENOMEM);
- }
-
return 0;
}