On 2013-01-08 15:37:38 +0100, Anton Khirnov wrote:
> Additionally switch to get_bufer() and enable DR1.
get_buf*f*er, doesn't matter since it's supposed to squashed although
I'm not too happy with doing both in a single step.
> ---
> libavcodec/eatgv.c | 74
> ++++++++++++++++++++++++----------------------------
> 1 file changed, 34 insertions(+), 40 deletions(-)
>
> diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c
> index 82a12b4..8eb6137 100644
> --- a/libavcodec/eatgv.c
> +++ b/libavcodec/eatgv.c
> @@ -31,6 +31,7 @@
> #include "avcodec.h"
> #define BITSTREAM_READER_LE
> #include "get_bits.h"
> +#include "internal.h"
> #include "libavutil/imgutils.h"
> #include "libavutil/mem.h"
>
> @@ -39,8 +40,8 @@
>
> typedef struct TgvContext {
> AVCodecContext *avctx;
> - AVFrame frame;
> AVFrame last_frame;
> + uint8_t *frame_buffer;
> int width,height;
> uint32_t palette[AVPALETTE_COUNT];
>
> @@ -138,8 +139,8 @@ static int unpack(const uint8_t *src, const uint8_t
> *src_end,
> * Decode inter-frame
> * @return 0 on success, -1 on critical buffer underflow
> */
> -static int tgv_decode_inter(TgvContext * s, const uint8_t *buf,
> - const uint8_t *buf_end)
> +static int tgv_decode_inter(TgvContext * s, AVFrame *frame,
> + const uint8_t *buf, const uint8_t *buf_end)
> {
> int num_mvs;
> int num_blocks_raw;
> @@ -237,22 +238,13 @@ static int tgv_decode_inter(TgvContext * s, const
> uint8_t *buf,
>
> for (j = 0; j < 4; j++)
> for (i = 0; i < 4; i++)
> - s->frame.data[0][(y * 4 + j) * s->frame.linesize[0] + (x
> * 4 + i)] =
> + frame->data[0][(y * 4 + j) * frame->linesize[0] + (x * 4
> + i)] =
> src[j * src_stride + i];
> }
>
> return 0;
> }
>
> -/** release AVFrame buffers if allocated */
> -static void cond_release_buffer(AVFrame *pic)
> -{
> - if (pic->data[0]) {
> - av_freep(&pic->data[0]);
> - av_free(pic->data[1]);
> - }
> -}
> -
> static int tgv_decode_frame(AVCodecContext *avctx,
> void *data, int *got_frame,
> AVPacket *avpkt)
> @@ -261,6 +253,7 @@ static int tgv_decode_frame(AVCodecContext *avctx,
> int buf_size = avpkt->size;
> TgvContext *s = avctx->priv_data;
> const uint8_t *buf_end = buf + buf_size;
> + AVFrame *frame = data;
> int chunk_type, ret;
>
> chunk_type = AV_RL32(&buf[0]);
> @@ -277,8 +270,8 @@ static int tgv_decode_frame(AVCodecContext *avctx,
> s->height = AV_RL16(&buf[2]);
> if (s->avctx->width != s->width || s->avctx->height != s->height) {
> avcodec_set_dimensions(s->avctx, s->width, s->height);
> - cond_release_buffer(&s->frame);
> - cond_release_buffer(&s->last_frame);
> + av_freep(&s->frame_buffer);
> + av_frame_unref(&s->last_frame);
> }
>
> pal_count = AV_RL16(&buf[6]);
> @@ -292,46 +285,46 @@ static int tgv_decode_frame(AVCodecContext *avctx,
> if ((ret = av_image_check_size(s->width, s->height, 0, avctx)) < 0)
> return ret;
>
> - /* shuffle */
> - FFSWAP(AVFrame, s->frame, s->last_frame);
> - if (!s->frame.data[0]) {
> - s->frame.reference = 1;
> - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
> - s->frame.linesize[0] = s->width;
> + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
> + return ret;
>
> - s->frame.data[0] = av_malloc(s->width * s->height);
> - if (!s->frame.data[0])
> - return AVERROR(ENOMEM);
> - s->frame.data[1] = av_malloc(AVPALETTE_SIZE);
> - if (!s->frame.data[1]) {
> - av_freep(&s->frame.data[0]);
> - return AVERROR(ENOMEM);
> - }
> - }
> - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
> + memcpy(frame->data[1], s->palette, AVPALETTE_SIZE);
>
> if (chunk_type == kVGT_TAG) {
> - s->frame.key_frame = 1;
> - s->frame.pict_type = AV_PICTURE_TYPE_I;
> - if (unpack(buf, buf_end, s->frame.data[0], s->avctx->width,
> s->avctx->height) < 0) {
> + int y;
> + frame->key_frame = 1;
> + frame->pict_type = AV_PICTURE_TYPE_I;
> +
> + if (!s->frame_buffer &&
> + !(s->frame_buffer = av_malloc(s->width * s->height)))
> + return AVERROR(ENOMEM);
> +
> + if (unpack(buf, buf_end, s->frame_buffer, s->avctx->width,
> s->avctx->height) < 0) {
> av_log(avctx, AV_LOG_WARNING, "truncated intra frame\n");
> return AVERROR_INVALIDDATA;
> }
> + for (y = 0; y < s->height; y++)
> + memcpy(frame->data[0] + y * frame->linesize[0],
> + s->frame_buffer + y * s->width,
> + s->width);
I guess there is no way to guarantee that get_buffer2() returns a frame
without edges. Although I'm suspect we already have decoders depending
on it. The seperate buffer and memcpy is ugly and direct rendering is a
lie.
> } else {
> if (!s->last_frame.data[0]) {
> av_log(avctx, AV_LOG_WARNING, "inter frame without corresponding
> intra frame\n");
> return buf_size;
> }
> - s->frame.key_frame = 0;
> - s->frame.pict_type = AV_PICTURE_TYPE_P;
> - if (tgv_decode_inter(s, buf, buf_end) < 0) {
> + frame->key_frame = 0;
> + frame->pict_type = AV_PICTURE_TYPE_P;
> + if (tgv_decode_inter(s, frame, buf, buf_end) < 0) {
> av_log(avctx, AV_LOG_WARNING, "truncated inter frame\n");
> return AVERROR_INVALIDDATA;
> }
> }
>
> + av_frame_unref(&s->last_frame);
> + if ((ret = av_frame_ref(&s->last_frame, frame)) < 0)
> + return ret;
> +
> *got_frame = 1;
> - *(AVFrame*)data = s->frame;
>
> return buf_size;
> }
> @@ -339,8 +332,8 @@ static int tgv_decode_frame(AVCodecContext *avctx,
> static av_cold int tgv_decode_end(AVCodecContext *avctx)
> {
> TgvContext *s = avctx->priv_data;
> - cond_release_buffer(&s->frame);
> - cond_release_buffer(&s->last_frame);
> + av_frame_unref(&s->last_frame);
> + av_freep(&s->frame_buffer);
> av_free(s->mv_codebook);
> av_free(s->block_codebook);
> return 0;
> @@ -355,4 +348,5 @@ AVCodec ff_eatgv_decoder = {
> .close = tgv_decode_end,
> .decode = tgv_decode_frame,
> .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TGV video"),
> + .capabilities = CODEC_CAP_DR1,
> };
probably ok
Janne
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel