[FFmpeg-devel] [PATCH] ZeroCodec Decoder
Michael Niedermayer
michaelni at gmx.at
Fri Mar 16 08:20:45 CET 2012
On Thu, Mar 15, 2012 at 03:59:54PM -0400, Derek Buitenhuis wrote:
> An obscure Japanese screen capture video codec.
[...]
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index a3d5614..4e984dc 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -247,6 +247,7 @@ enum CodecID {
> CODEC_ID_V410,
> CODEC_ID_XWD,
> CODEC_ID_CDXL,
> + CODEC_ID_ZEROCODEC,
> CODEC_ID_Y41P = MKBETAG('Y','4','1','P'),
> CODEC_ID_ESCAPE130 = MKBETAG('E','1','3','0'),
> CODEC_ID_AVRP = MKBETAG('A','V','R','P'),
I hope this wont break compatibility
[...]
> +static int zerocodec_decode_frame(AVCodecContext *avctx, void *data,
> + int *data_size, AVPacket *avpkt)
> +{
> + ZeroCodecContext *zc = avctx->priv_data;
> + AVFrame *pic = avctx->coded_frame;
> + z_stream *zstream = &zc->zstream;
> + uint8_t *src, *prev_src, *dst;
> + int i, j, zret;
> +
> + pic->reference = 0;
> +
> + if (pic->data[0])
> + avctx->release_buffer(avctx, pic);
> +
> + if (avctx->get_buffer(avctx, pic) < 0) {
> + av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
> + return AVERROR(ENOMEM);
> + }
> +
> + pic->key_frame = 1;
> + pic->pict_type = AV_PICTURE_TYPE_I;
these look wrong
> +
> + zret = inflateReset(zstream);
> +
> + if (zret != Z_OK) {
> + av_log(avctx, AV_LOG_ERROR, "Could not reset inflate: %d\n", zret);
> + return AVERROR(EINVAL);
> + }
> +
> + zstream->next_in = avpkt->data;
> + zstream->avail_in = avpkt->size;
> + zstream->next_out = zc->current_frame;
> + zstream->avail_out = zc->size;
> +
> + inflate(zstream, Z_FINISH);
> +
> + src = zc->current_frame;
> + prev_src = zc->previous_frame;
> + dst = pic->data[0];
> +
> + /**
> + * ZeroCodec has very simple interframe compression. If a value
> + * is the same as the previous frame, set it to 0.
> + */
> +
> + if (avpkt->flags & AV_PKT_FLAG_KEY) {
> + for (i = 0; i < avctx->height; i++) {
> + memcpy(dst, src, avctx->width << 1);
> + src += avctx->width << 1;
> + dst += pic->linesize[0];
> + }
> + } else {
> + for (i = 0; i < avctx->height; i++) {
> +
> + for (j = 0; j < avctx->width << 1; j++)
> + src[j] = src[j] ? src[j] : prev_src[j];
> +
> + memcpy(dst, src, avctx->width << 1);
> +
> + src += avctx->width << 1;
> + prev_src += avctx->width << 1;
> + dst += pic->linesize[0];
> + }
> + }
> +
> + /* Store the current frame for later use */
> + memcpy(zc->previous_frame, zc->current_frame, zc->size);
this can be avoided by exchanging the pointers
its also possible to get rid of the second memcpy by keeping and
using the previous frame instead of a seperate buffer
not sure if the codec is used in practice, if not optimizing it
doesnt make much sense
[...]
> +static av_cold int zerocodec_decode_init(AVCodecContext *avctx)
> +{
> + ZeroCodecContext *zc = avctx->priv_data;
> + z_stream *zstream = &zc->zstream;
> + int zret;
> +
> + avctx->pix_fmt = 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;
> +
> + zret = inflateInit(zstream);
> +
> + if (zret != Z_OK) {
> + av_log(avctx, AV_LOG_ERROR, "Could not initialize inflate: %d\n", zret);
> + 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");
> + return AVERROR(ENOMEM);
> + }
> +
> + zc->current_frame = av_malloc(zc->size * sizeof(*zc->current_frame));
> +
> + if (!zc->current_frame) {
> + av_log(avctx, AV_LOG_ERROR, "Could not allocate current frame buffer.\n");
> + return AVERROR(ENOMEM);
> + }
> +
> + zc->previous_frame = av_malloc(zc->size * sizeof(*zc->previous_frame));
> +
> + if (!zc->previous_frame) {
> + av_log(avctx, AV_LOG_ERROR, "Could not allocate previous frame buffer.\n");
> + return AVERROR(ENOMEM);
> + }
memleaks in case of malloc failures
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
I do not agree with what you have to say, but I'll defend to the death your
right to say it. -- Voltaire
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20120316/2622895c/attachment.asc>
More information about the ffmpeg-devel
mailing list