On Sun, 1 Nov 2015 17:07:07 +0100 Paul B Mahol <one...@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 <one...@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. _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel