]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/interplayvideo.c
avcodec: Constify AVCodecs
[ffmpeg] / libavcodec / interplayvideo.c
index b0a4953cb01740bb5083fe5bf63d46cf6db9fe86..bd1d7c74ba8380d80a235c3b65ccc1386a227eca 100644 (file)
@@ -43,6 +43,7 @@
 #define BITSTREAM_READER_LE
 #include "avcodec.h"
 #include "bytestream.h"
+#include "decode.h"
 #include "get_bits.h"
 #include "hpeldsp.h"
 #include "internal.h"
@@ -77,9 +78,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 +937,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 +1007,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);
     }
 }
@@ -1155,7 +1161,6 @@ static void ipvideo_decode_format_11_opcodes(IpvideoContext *s, AVFrame *frame)
 static av_cold int ipvideo_decode_init(AVCodecContext *avctx)
 {
     IpvideoContext *s = avctx->priv_data;
-    int ret;
 
     s->avctx = avctx;
 
@@ -1170,8 +1175,7 @@ static av_cold int ipvideo_decode_init(AVCodecContext *avctx)
     s->prev_decode_frame = av_frame_alloc();
     if (!s->last_frame || !s->second_last_frame ||
         !s->cur_decode_frame || !s->prev_decode_frame) {
-        ret = AVERROR(ENOMEM);
-        goto error;
+        return AVERROR(ENOMEM);
     }
 
     s->cur_decode_frame->width   = avctx->width;
@@ -1182,12 +1186,6 @@ static av_cold int ipvideo_decode_init(AVCodecContext *avctx)
     s->prev_decode_frame->format = avctx->pix_fmt;
 
     return 0;
-error:
-    av_frame_free(&s->last_frame);
-    av_frame_free(&s->second_last_frame);
-    av_frame_free(&s->cur_decode_frame);
-    av_frame_free(&s->prev_decode_frame);
-    return ret;
 }
 
 static int ipvideo_decode_frame(AVCodecContext *avctx,
@@ -1320,14 +1318,7 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
         return ret;
 
     if (!s->is_16bpp) {
-        int size;
-        const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size);
-        if (pal && size == AVPALETTE_SIZE) {
-            frame->palette_has_changed = 1;
-            memcpy(s->pal, pal, AVPALETTE_SIZE);
-        } else if (pal) {
-            av_log(avctx, AV_LOG_ERROR, "Palette size %d is wrong\n", size);
-        }
+        frame->palette_has_changed = ff_copy_palette(s->pal, avpkt, avctx);
     }
 
     switch (frame_format) {
@@ -1366,7 +1357,7 @@ static av_cold int ipvideo_decode_end(AVCodecContext *avctx)
     return 0;
 }
 
-AVCodec ff_interplay_video_decoder = {
+const AVCodec ff_interplay_video_decoder = {
     .name           = "interplayvideo",
     .long_name      = NULL_IF_CONFIG_SMALL("Interplay MVE video"),
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -1376,4 +1367,5 @@ AVCodec ff_interplay_video_decoder = {
     .close          = ipvideo_decode_end,
     .decode         = ipvideo_decode_frame,
     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_PARAM_CHANGE,
+    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
 };