[FFmpeg-devel] [PATCH] avformat/ipmovie: put video decoding_map_size into packet and use it in decoder

wm4 nfxjfg at googlemail.com
Sun Nov 1 17:14:44 CET 2015


On Sun,  1 Nov 2015 17:07:07 +0100
Paul B Mahol <onemda at gmail.com> wrote:

> The size of decoding map can differ from one calculated
> internally, producing artifacts while decoding video.
> 
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> ---
>  libavcodec/interplayvideo.c | 14 +++++++++-----
>  libavformat/ipmovie.c       |  7 ++++---
>  2 files changed, 13 insertions(+), 8 deletions(-)
> 
> diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c
> index a29b5fe..1460741 100644
> --- a/libavcodec/interplayvideo.c
> +++ b/libavcodec/interplayvideo.c
> @@ -38,6 +38,7 @@
>  #include <stdlib.h>
>  #include <string.h>
>  
> +#include "libavutil/intreadwrite.h"
>  #include "avcodec.h"
>  #include "bytestream.h"
>  #include "hpeldsp.h"
> @@ -949,7 +950,7 @@ static void ipvideo_decode_opcodes(IpvideoContext *s, AVFrame *frame)
>          }
>      }
>      if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
> -        av_log(s->avctx, AV_LOG_ERROR,
> +        av_log(s->avctx, AV_LOG_DEBUG,
>                 "decode finished with %d bytes left over\n",
>                 bytestream2_get_bytes_left(&s->stream_ptr));
>      }
> @@ -987,12 +988,15 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
>      AVFrame *frame = data;
>      int ret;
>  
> +    if (buf_size < 2)
> +        return AVERROR_INVALIDDATA;
> +
>      /* decoding map contains 4 bits of information per 8x8 block */
> -    s->decoding_map_size = avctx->width * avctx->height / (8 * 8 * 2);
> +    s->decoding_map_size = AV_RL16(avpkt->data);
>  
>      /* compressed buffer needs to be large enough to at least hold an entire
>       * decoding map */
> -    if (buf_size < s->decoding_map_size)
> +    if (buf_size < s->decoding_map_size + 2)
>          return buf_size;
>  
>      if (av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, NULL)) {
> @@ -1000,8 +1004,8 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
>          av_frame_unref(s->second_last_frame);
>      }
>  
> -    s->decoding_map = buf;
> -    bytestream2_init(&s->stream_ptr, buf + s->decoding_map_size,
> +    s->decoding_map = buf + 2;
> +    bytestream2_init(&s->stream_ptr, buf + 2 + s->decoding_map_size,
>                       buf_size - s->decoding_map_size);
>  
>      if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
> diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c
> index 99b193d..df9b8f0 100644
> --- a/libavformat/ipmovie.c
> +++ b/libavformat/ipmovie.c
> @@ -156,7 +156,7 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb,
>  
>          /* send both the decode map and the video data together */
>  
> -        if (av_new_packet(pkt, s->decode_map_chunk_size + s->video_chunk_size))
> +        if (av_new_packet(pkt, 2 + s->decode_map_chunk_size + s->video_chunk_size))
>              return CHUNK_NOMEM;
>  
>          if (s->has_palette) {
> @@ -178,7 +178,8 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb,
>          avio_seek(pb, s->decode_map_chunk_offset, SEEK_SET);
>          s->decode_map_chunk_offset = 0;
>  
> -        if (avio_read(pb, pkt->data, s->decode_map_chunk_size) !=
> +        AV_WL16(pkt->data, s->decode_map_chunk_size);
> +        if (avio_read(pb, pkt->data + 2, s->decode_map_chunk_size) !=
>              s->decode_map_chunk_size) {
>              av_packet_unref(pkt);
>              return CHUNK_EOF;
> @@ -187,7 +188,7 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb,
>          avio_seek(pb, s->video_chunk_offset, SEEK_SET);
>          s->video_chunk_offset = 0;
>  
> -        if (avio_read(pb, pkt->data + s->decode_map_chunk_size,
> +        if (avio_read(pb, pkt->data + 2 + s->decode_map_chunk_size,
>              s->video_chunk_size) != s->video_chunk_size) {
>              av_packet_unref(pkt);
>              return CHUNK_EOF;

I can confirm this fixes it.


More information about the ffmpeg-devel mailing list