X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=inline;f=libavcodec%2Finterplayvideo.c;h=274641c3d1a90f77b46ebb7a1223f5b7e74659d2;hb=e8344f21e16b7043411830cea99304169127dacf;hp=deaa09cba60ff4e9319bb121c794b1ab8717be20;hpb=768b07e3bca7e81d2f9c60badb3973d3d88481dc;p=ffmpeg diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c index deaa09cba60..274641c3d1a 100644 --- a/libavcodec/interplayvideo.c +++ b/libavcodec/interplayvideo.c @@ -77,9 +77,14 @@ typedef struct IpvideoContext { static int copy_from(IpvideoContext *s, AVFrame *src, AVFrame *dst, int delta_x, int delta_y) { + int width = dst->width; int current_offset = s->pixel_ptr - dst->data[0]; - int motion_offset = current_offset + delta_y * dst->linesize[0] - + delta_x * (1 + s->is_16bpp); + int x = (current_offset % dst->linesize[0]) / (1 + s->is_16bpp); + int y = current_offset / dst->linesize[0]; + int dx = delta_x + x - ((delta_x + x >= width) - (delta_x + x < 0)) * width; + int dy = delta_y + y + (delta_x + x >= width) - (delta_x + x < 0); + int motion_offset = dy * src->linesize[0] + dx * (1 + s->is_16bpp); + if (motion_offset < 0) { av_log(s->avctx, AV_LOG_ERROR, "motion offset < 0 (%d)\n", motion_offset); return AVERROR_INVALIDDATA; @@ -931,12 +936,12 @@ static void ipvideo_format_06_secondpass(IpvideoContext *s, AVFrame *frame, int1 int off_x, off_y; if (opcode < 0) { - off_x = ((uint16_t)opcode - 0xC000) % frame->linesize[0]; - off_y = ((uint16_t)opcode - 0xC000) / frame->linesize[0]; + off_x = ((uint16_t)opcode - 0xC000) % frame->width; + off_y = ((uint16_t)opcode - 0xC000) / frame->width; copy_from(s, s->last_frame, frame, off_x, off_y); } else if (opcode > 0) { - off_x = ((uint16_t)opcode - 0x4000) % frame->linesize[0]; - off_y = ((uint16_t)opcode - 0x4000) / frame->linesize[0]; + off_x = ((uint16_t)opcode - 0x4000) % frame->width; + off_y = ((uint16_t)opcode - 0x4000) / frame->width; copy_from(s, frame, frame, off_x, off_y); } } @@ -1001,12 +1006,12 @@ static void ipvideo_format_10_secondpass(IpvideoContext *s, AVFrame *frame, int1 int off_x, off_y; if (opcode < 0) { - off_x = ((uint16_t)opcode - 0xC000) % s->cur_decode_frame->linesize[0]; - off_y = ((uint16_t)opcode - 0xC000) / s->cur_decode_frame->linesize[0]; + off_x = ((uint16_t)opcode - 0xC000) % s->cur_decode_frame->width; + off_y = ((uint16_t)opcode - 0xC000) / s->cur_decode_frame->width; copy_from(s, s->prev_decode_frame, s->cur_decode_frame, off_x, off_y); } else if (opcode > 0) { - off_x = ((uint16_t)opcode - 0x4000) % s->cur_decode_frame->linesize[0]; - off_y = ((uint16_t)opcode - 0x4000) / s->cur_decode_frame->linesize[0]; + off_x = ((uint16_t)opcode - 0x4000) % s->cur_decode_frame->width; + off_y = ((uint16_t)opcode - 0x4000) / s->cur_decode_frame->width; copy_from(s, s->cur_decode_frame, s->cur_decode_frame, off_x, off_y); } } @@ -1181,14 +1186,6 @@ static av_cold int ipvideo_decode_init(AVCodecContext *avctx) s->cur_decode_frame->format = avctx->pix_fmt; s->prev_decode_frame->format = avctx->pix_fmt; - ret = ff_get_buffer(avctx, s->cur_decode_frame, 0); - if (ret < 0) - goto error; - - ret = ff_get_buffer(avctx, s->prev_decode_frame, 0); - if (ret < 0) - goto error; - return 0; error: av_frame_free(&s->last_frame); @@ -1239,83 +1236,83 @@ static int ipvideo_decode_frame(AVCodecContext *avctx, s->decoding_map_size = AV_RL16(buf + 4); s->skip_map_size = AV_RL16(buf + 6); - switch(frame_format) { - case 0x06: - if (s->decoding_map_size) { - av_log(avctx, AV_LOG_ERROR, "Decoding map for format 0x06\n"); - return AVERROR_INVALIDDATA; - } + switch (frame_format) { + case 0x06: + if (s->decoding_map_size) { + av_log(avctx, AV_LOG_ERROR, "Decoding map for format 0x06\n"); + return AVERROR_INVALIDDATA; + } - if (s->skip_map_size) { - av_log(avctx, AV_LOG_ERROR, "Skip map for format 0x06\n"); - return AVERROR_INVALIDDATA; - } + if (s->skip_map_size) { + av_log(avctx, AV_LOG_ERROR, "Skip map for format 0x06\n"); + return AVERROR_INVALIDDATA; + } - if (s->is_16bpp) { - av_log(avctx, AV_LOG_ERROR, "Video format 0x06 does not support 16bpp movies\n"); - return AVERROR_INVALIDDATA; - } + if (s->is_16bpp) { + av_log(avctx, AV_LOG_ERROR, "Video format 0x06 does not support 16bpp movies\n"); + return AVERROR_INVALIDDATA; + } - /* Decoding map for 0x06 frame format is at the top of pixeldata */ - s->decoding_map_size = ((s->avctx->width / 8) * (s->avctx->height / 8)) * 2; - s->decoding_map = buf + 8 + 14; /* 14 bits of op data */ - video_data_size -= s->decoding_map_size + 14; - if (video_data_size <= 0) - return AVERROR_INVALIDDATA; + /* Decoding map for 0x06 frame format is at the top of pixeldata */ + s->decoding_map_size = ((s->avctx->width / 8) * (s->avctx->height / 8)) * 2; + s->decoding_map = buf + 8 + 14; /* 14 bits of op data */ + video_data_size -= s->decoding_map_size + 14; + if (video_data_size <= 0 || s->decoding_map_size == 0) + return AVERROR_INVALIDDATA; - if (buf_size < 8 + s->decoding_map_size + 14 + video_data_size) - return AVERROR_INVALIDDATA; + if (buf_size < 8 + s->decoding_map_size + 14 + video_data_size) + return AVERROR_INVALIDDATA; - bytestream2_init(&s->stream_ptr, buf + 8 + s->decoding_map_size + 14, video_data_size); + bytestream2_init(&s->stream_ptr, buf + 8 + s->decoding_map_size + 14, video_data_size); - break; + break; - case 0x10: - if (! s->decoding_map_size) { - av_log(avctx, AV_LOG_ERROR, "Empty decoding map for format 0x10\n"); - return AVERROR_INVALIDDATA; - } + case 0x10: + if (! s->decoding_map_size) { + av_log(avctx, AV_LOG_ERROR, "Empty decoding map for format 0x10\n"); + return AVERROR_INVALIDDATA; + } - if (! s->skip_map_size) { - av_log(avctx, AV_LOG_ERROR, "Empty skip map for format 0x10\n"); - return AVERROR_INVALIDDATA; - } + if (! s->skip_map_size) { + av_log(avctx, AV_LOG_ERROR, "Empty skip map for format 0x10\n"); + return AVERROR_INVALIDDATA; + } - if (s->is_16bpp) { - av_log(avctx, AV_LOG_ERROR, "Video format 0x10 does not support 16bpp movies\n"); - return AVERROR_INVALIDDATA; - } + if (s->is_16bpp) { + av_log(avctx, AV_LOG_ERROR, "Video format 0x10 does not support 16bpp movies\n"); + return AVERROR_INVALIDDATA; + } - if (buf_size < 8 + video_data_size + s->decoding_map_size + s->skip_map_size) - return AVERROR_INVALIDDATA; + if (buf_size < 8 + video_data_size + s->decoding_map_size + s->skip_map_size) + return AVERROR_INVALIDDATA; - bytestream2_init(&s->stream_ptr, buf + 8, video_data_size); - s->decoding_map = buf + 8 + video_data_size; - s->skip_map = buf + 8 + video_data_size + s->decoding_map_size; + bytestream2_init(&s->stream_ptr, buf + 8, video_data_size); + s->decoding_map = buf + 8 + video_data_size; + s->skip_map = buf + 8 + video_data_size + s->decoding_map_size; - break; + break; - case 0x11: - if (! s->decoding_map_size) { - av_log(avctx, AV_LOG_ERROR, "Empty decoding map for format 0x11\n"); - return AVERROR_INVALIDDATA; - } + case 0x11: + if (! s->decoding_map_size) { + av_log(avctx, AV_LOG_ERROR, "Empty decoding map for format 0x11\n"); + return AVERROR_INVALIDDATA; + } - if (s->skip_map_size) { - av_log(avctx, AV_LOG_ERROR, "Skip map for format 0x11\n"); - return AVERROR_INVALIDDATA; - } + if (s->skip_map_size) { + av_log(avctx, AV_LOG_ERROR, "Skip map for format 0x11\n"); + return AVERROR_INVALIDDATA; + } - if (buf_size < 8 + video_data_size + s->decoding_map_size) - return AVERROR_INVALIDDATA; + if (buf_size < 8 + video_data_size + s->decoding_map_size) + return AVERROR_INVALIDDATA; - bytestream2_init(&s->stream_ptr, buf + 8, video_data_size); - s->decoding_map = buf + 8 + video_data_size; + bytestream2_init(&s->stream_ptr, buf + 8, video_data_size); + s->decoding_map = buf + 8 + video_data_size; - break; + break; - default: - av_log(avctx, AV_LOG_ERROR, "Frame type 0x%02X unsupported\n", frame_format); + default: + av_log(avctx, AV_LOG_ERROR, "Frame type 0x%02X unsupported\n", frame_format); } /* ensure we can't overread the packet */ @@ -1338,16 +1335,16 @@ static int ipvideo_decode_frame(AVCodecContext *avctx, } } - switch(frame_format) { - case 0x06: - ipvideo_decode_format_06_opcodes(s, frame); - break; - case 0x10: - ipvideo_decode_format_10_opcodes(s, frame); - break; - case 0x11: - ipvideo_decode_format_11_opcodes(s, frame); - break; + switch (frame_format) { + case 0x06: + ipvideo_decode_format_06_opcodes(s, frame); + break; + case 0x10: + ipvideo_decode_format_10_opcodes(s, frame); + break; + case 0x11: + ipvideo_decode_format_11_opcodes(s, frame); + break; } *got_frame = send_buffer;