On 2013-01-08 15:37:40 +0100, Anton Khirnov wrote:
> ---
> libavcodec/eacmv.c | 87
> ++++++++++++++++++++++++++++------------------------
> 1 file changed, 47 insertions(+), 40 deletions(-)
>
> diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c
> index 0dce066..5971815 100644
> --- a/libavcodec/eacmv.c
> +++ b/libavcodec/eacmv.c
> @@ -36,9 +36,8 @@
>
> typedef struct CmvContext {
> AVCodecContext *avctx;
> - AVFrame frame; ///< current
> - AVFrame last_frame; ///< last
> - AVFrame last2_frame; ///< second-last
> + AVFrame *last_frame; ///< last
> + AVFrame *last2_frame; ///< second-last
> int width, height;
> unsigned int palette[AVPALETTE_COUNT];
> } CmvContext;
> @@ -47,16 +46,27 @@ static av_cold int cmv_decode_init(AVCodecContext *avctx){
> CmvContext *s = avctx->priv_data;
> s->avctx = avctx;
> avctx->pix_fmt = AV_PIX_FMT_PAL8;
> +
> + s->last_frame = av_frame_alloc();
> + s->last2_frame = av_frame_alloc();
> + if (!s->last_frame || !s->last2_frame) {
> + av_frame_free(&s->last_frame);
> + av_frame_free(&s->last2_frame);
> + return AVERROR(ENOMEM);
> + }
> +
> return 0;
> }
>
> -static void cmv_decode_intra(CmvContext * s, const uint8_t *buf, const
> uint8_t *buf_end){
> - unsigned char *dst = s->frame.data[0];
> +static void cmv_decode_intra(CmvContext * s, AVFrame *frame,
> + const uint8_t *buf, const uint8_t *buf_end)
> +{
> + unsigned char *dst = frame->data[0];
> int i;
>
> for (i=0; i < s->avctx->height && buf_end - buf >= s->avctx->width; i++)
> {
> memcpy(dst, buf, s->avctx->width);
> - dst += s->frame.linesize[0];
> + dst += frame->linesize[0];
> buf += s->avctx->width;
> }
> }
> @@ -80,7 +90,9 @@ static void cmv_motcomp(unsigned char *dst, int dst_stride,
> }
> }
>
> -static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const
> uint8_t *buf_end){
> +static void cmv_decode_inter(CmvContext *s, AVFrame *frame, const uint8_t
> *buf,
> + const uint8_t *buf_end)
> +{
> const uint8_t *raw = buf + (s->avctx->width*s->avctx->height/16);
> int x,y,i;
>
> @@ -88,28 +100,28 @@ static void cmv_decode_inter(CmvContext * s, const
> uint8_t *buf, const uint8_t *
> for(y=0; y<s->avctx->height/4; y++)
> for(x=0; x<s->avctx->width/4 && buf_end - buf > i; x++) {
> if (buf[i]==0xFF) {
> - unsigned char *dst = s->frame.data[0] +
> (y*4)*s->frame.linesize[0] + x*4;
> + unsigned char *dst = frame->data[0] + (y*4)*frame->linesize[0] +
> x*4;
> if (raw+16<buf_end && *raw==0xFF) { /* intra */
> raw++;
> memcpy(dst, raw, 4);
> - memcpy(dst+s->frame.linesize[0], raw+4, 4);
> - memcpy(dst+2*s->frame.linesize[0], raw+8, 4);
> - memcpy(dst+3*s->frame.linesize[0], raw+12, 4);
> + memcpy(dst + frame->linesize[0], raw+4, 4);
> + memcpy(dst + 2 * frame->linesize[0], raw+8, 4);
> + memcpy(dst + 3 * frame->linesize[0], raw+12, 4);
> raw+=16;
> }else if(raw<buf_end) { /* inter using second-last frame as
> reference */
> int xoffset = (*raw & 0xF) - 7;
> int yoffset = ((*raw >> 4)) - 7;
> - if (s->last2_frame.data[0])
> - cmv_motcomp(s->frame.data[0], s->frame.linesize[0],
> - s->last2_frame.data[0],
> s->last2_frame.linesize[0],
> + if (s->last2_frame->data[0])
> + cmv_motcomp(frame->data[0], frame->linesize[0],
> + s->last2_frame->data[0],
> s->last2_frame->linesize[0],
> x*4, y*4, xoffset, yoffset, s->avctx->width,
> s->avctx->height);
> raw++;
> }
> }else{ /* inter using last frame as reference */
> int xoffset = (buf[i] & 0xF) - 7;
> int yoffset = ((buf[i] >> 4)) - 7;
> - cmv_motcomp(s->frame.data[0], s->frame.linesize[0],
> - s->last_frame.data[0], s->last_frame.linesize[0],
> + cmv_motcomp(frame->data[0], frame->linesize[0],
> + s->last_frame->data[0], s->last_frame->linesize[0],
> x*4, y*4, xoffset, yoffset, s->avctx->width,
> s->avctx->height);
> }
> i++;
> @@ -154,6 +166,8 @@ static int cmv_decode_frame(AVCodecContext *avctx,
> int buf_size = avpkt->size;
> CmvContext *s = avctx->priv_data;
> const uint8_t *buf_end = buf + buf_size;
> + AVFrame *frame = data;
> + int ret;
>
> if (buf_end - buf < EA_PREAMBLE_SIZE)
> return AVERROR_INVALIDDATA;
> @@ -166,46 +180,39 @@ static int cmv_decode_frame(AVCodecContext *avctx,
> if (av_image_check_size(s->width, s->height, 0, s->avctx))
> return -1;
>
> - /* shuffle */
> - if (s->last2_frame.data[0])
> - avctx->release_buffer(avctx, &s->last2_frame);
> - FFSWAP(AVFrame, s->last_frame, s->last2_frame);
> - FFSWAP(AVFrame, s->frame, s->last_frame);
> -
> - s->frame.reference = 1;
> - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
> - if (ff_get_buffer(avctx, &s->frame)<0) {
> + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
> av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
> - return -1;
> + return ret;
> }
>
> - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
> + memcpy(frame->data[1], s->palette, AVPALETTE_SIZE);
>
> buf += EA_PREAMBLE_SIZE;
> if ((buf[0]&1)) { // subtype
> - cmv_decode_inter(s, buf+2, buf_end);
> - s->frame.key_frame = 0;
> - s->frame.pict_type = AV_PICTURE_TYPE_P;
> + cmv_decode_inter(s, frame, buf+2, buf_end);
> + frame->key_frame = 0;
> + frame->pict_type = AV_PICTURE_TYPE_P;
> }else{
> - s->frame.key_frame = 1;
> - s->frame.pict_type = AV_PICTURE_TYPE_I;
> - cmv_decode_intra(s, buf+2, buf_end);
> + frame->key_frame = 1;
> + frame->pict_type = AV_PICTURE_TYPE_I;
> + cmv_decode_intra(s, frame, buf+2, buf_end);
> }
>
> + FFSWAP(AVFrame*, s->last2_frame, s->last_frame);
> + av_frame_unref(s->last_frame);
av_frame_unref(s->last2_frame);
*s->last2_frame = *s->last_frame;
would be less confusing and simpler
> + if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
> + return ret;
> +
> *got_frame = 1;
> - *(AVFrame*)data = s->frame;
>
> return buf_size;
> }
>
> static av_cold int cmv_decode_end(AVCodecContext *avctx){
> CmvContext *s = avctx->priv_data;
> - if (s->frame.data[0])
> - s->avctx->release_buffer(avctx, &s->frame);
> - if (s->last_frame.data[0])
> - s->avctx->release_buffer(avctx, &s->last_frame);
> - if (s->last2_frame.data[0])
> - s->avctx->release_buffer(avctx, &s->last2_frame);
> +
> + av_frame_free(&s->last_frame);
> + av_frame_free(&s->last2_frame);
>
> return 0;
> }
otherwise ok
Janne
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel