aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2015-11-01 17:02:26 +0100
committerAndreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>2016-01-27 23:28:49 +0100
commit7b0fb4fdf796619d33d10e83ae119996f562a0b1 (patch)
tree5eb030b1091517d7fad4418404f0b119e2528d76
parent40ebeee3fc3516ede3709427e3b23c13a8a045fa (diff)
downloadffmpeg-7b0fb4fdf796619d33d10e83ae119996f562a0b1.tar.gz
avformat/ipmovie: put video decoding_map_size into packet and use it in decoder
The size of decoding map can differ from one calculated internally, producing artifacts while decoding video. Signed-off-by: Paul B Mahol <onemda@gmail.com> (cherry picked from commit c293ef258cbb2c058e23651a26edf46e3bc05050) Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
-rw-r--r--libavcodec/interplayvideo.c14
-rw-r--r--libavformat/ipmovie.c7
2 files changed, 13 insertions, 8 deletions
diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c
index a29b5fe8da..1460741a53 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 51aed323a2..ea5e5eeda5 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_free_packet(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_free_packet(pkt);
return CHUNK_EOF;