]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/interplayvideo.c
vqf/twinvq: pass vqf COMM chunk info in extradata
[ffmpeg] / libavcodec / interplayvideo.c
index e56b9243603a892876aa949702c95aab86782ad0..d0e8f4cdc6d58303ef3e9d5e51226c218ab252c8 100644 (file)
@@ -2,25 +2,25 @@
  * Interplay MVE Video Decoder
  * Copyright (C) 2003 the ffmpeg project
  *
- * This file is part of FFmpeg.
+ * This file is part of Libav.
  *
- * FFmpeg is free software; you can redistribute it and/or
+ * Libav is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * FFmpeg is distributed in the hope that it will be useful,
+ * Libav is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
+ * License along with Libav; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
- * @file libavcodec/interplayvideo.c
+ * @file
  * Interplay MVE Video Decoder by Mike Melanson (melanson@pcisys.net)
  * For more information about the Interplay MVE format, visit:
  *   http://www.pcisys.net/~melanson/codecs/interplay-mve.txt
 
 #define PALETTE_COUNT 256
 
-/* debugging support */
-#define DEBUG_INTERPLAY 0
-#if DEBUG_INTERPLAY
-#define debug_interplay(x,...) av_log(NULL, AV_LOG_DEBUG, x, __VA_ARGS__)
-#else
-static inline void debug_interplay(const char *format, ...) { }
-#endif
-
 typedef struct IpvideoContext {
 
     AVCodecContext *avctx;
@@ -77,6 +69,7 @@ typedef struct IpvideoContext {
     int stride;
     int upper_motion_limit_offset;
 
+    uint32_t pal[256];
 } IpvideoContext;
 
 #define CHECK_STREAM_PTR(stream_ptr, stream_end, n) \
@@ -99,6 +92,10 @@ static int copy_from(IpvideoContext *s, AVFrame *src, int delta_x, int delta_y)
             motion_offset, s->upper_motion_limit_offset);
         return -1;
     }
+    if (src->data[0] == NULL) {
+        av_log(s->avctx, AV_LOG_ERROR, "Invalid decode type, corrupted header?\n");
+        return AVERROR(EINVAL);
+    }
     s->dsp.put_pixels_tab[!s->is_16bpp][0](s->pixel_ptr, src->data[0] + motion_offset,
                                            s->current_frame.linesize[0], 8);
     return 0;
@@ -136,7 +133,7 @@ static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s)
         y =   8 + ((B - 56) / 29);
     }
 
-    debug_interplay ("    motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
+    av_dlog(NULL, "    motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
     return copy_from(s, &s->second_last_frame, x, y);
 }
 
@@ -164,7 +161,7 @@ static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s)
         y = -(  8 + ((B - 56) / 29));
     }
 
-    debug_interplay ("    motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
+    av_dlog(NULL, "    motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
     return copy_from(s, &s->current_frame, x, y);
 }
 
@@ -187,7 +184,7 @@ static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s)
     x = -8 + BL;
     y = -8 + BH;
 
-    debug_interplay ("    motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
+    av_dlog(NULL, "    motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
     return copy_from(s, &s->last_frame, x, y);
 }
 
@@ -202,7 +199,7 @@ static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s)
     x = *s->stream_ptr++;
     y = *s->stream_ptr++;
 
-    debug_interplay ("    motion bytes = %d, %d\n", x, y);
+    av_dlog(NULL, "    motion bytes = %d, %d\n", x, y);
     return copy_from(s, &s->last_frame, x, y);
 }
 
@@ -583,7 +580,7 @@ static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s)
     x = *s->stream_ptr++;
     y = *s->stream_ptr++;
 
-    debug_interplay ("    motion bytes = %d, %d\n", x, y);
+    av_dlog(NULL, "    motion bytes = %d, %d\n", x, y);
     return copy_from(s, &s->second_last_frame, x, y);
 }
 
@@ -960,12 +957,12 @@ static void ipvideo_decode_opcodes(IpvideoContext *s)
     static int frame = 0;
     GetBitContext gb;
 
-    debug_interplay("------------------ frame %d\n", frame);
+    av_dlog(NULL, "------------------ frame %d\n", frame);
     frame++;
 
     if (!s->is_16bpp) {
         /* this is PAL8, so make the palette available */
-        memcpy(s->current_frame.data[1], s->avctx->palctrl->palette, PALETTE_COUNT * 4);
+        memcpy(s->current_frame.data[1], s->pal, AVPALETTE_SIZE);
 
         s->stride = s->current_frame.linesize[0];
         s->stream_ptr = s->buf + 14;  /* data starts 14 bytes in */
@@ -986,8 +983,8 @@ static void ipvideo_decode_opcodes(IpvideoContext *s)
         for (x = 0; x < s->avctx->width; x += 8) {
             opcode = get_bits(&gb, 4);
 
-            debug_interplay("  block @ (%3d, %3d): encoding 0x%X, data ptr @ %p\n",
-                            x, y, opcode, s->stream_ptr);
+            av_dlog(NULL, "  block @ (%3d, %3d): encoding 0x%X, data ptr @ %p\n",
+                    x, y, opcode, s->stream_ptr);
 
             if (!s->is_16bpp) {
                 s->pixel_ptr = s->current_frame.data[0] + x
@@ -1017,13 +1014,9 @@ static av_cold int ipvideo_decode_init(AVCodecContext *avctx)
 
     s->avctx = avctx;
 
-    if (s->avctx->palctrl == NULL) {
-        av_log(avctx, AV_LOG_ERROR, " Interplay video: palette expected.\n");
-        return -1;
-    }
-
     s->is_16bpp = avctx->bits_per_coded_sample == 16;
     avctx->pix_fmt = s->is_16bpp ? PIX_FMT_RGB555 : PIX_FMT_PAL8;
+
     dsputil_init(&s->dsp, avctx);
 
     /* decoding map contains 4 bits of information per 8x8 block */
@@ -1042,7 +1035,6 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     IpvideoContext *s = avctx->priv_data;
-    AVPaletteControl *palette_control = avctx->palctrl;
 
     /* compressed buffer needs to be large enough to at least hold an entire
      * decoding map */
@@ -1059,13 +1051,16 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
         return -1;
     }
 
-    ipvideo_decode_opcodes(s);
-
-    if (!s->is_16bpp && palette_control->palette_changed) {
-        palette_control->palette_changed = 0;
-        s->current_frame.palette_has_changed = 1;
+    if (!s->is_16bpp) {
+        const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
+        if (pal) {
+            s->current_frame.palette_has_changed = 1;
+            memcpy(s->pal, pal, AVPALETTE_SIZE);
+        }
     }
 
+    ipvideo_decode_opcodes(s);
+
     *data_size = sizeof(AVFrame);
     *(AVFrame*)data = s->current_frame;
 
@@ -1093,15 +1088,14 @@ static av_cold int ipvideo_decode_end(AVCodecContext *avctx)
     return 0;
 }
 
-AVCodec interplay_video_decoder = {
-    "interplayvideo",
-    CODEC_TYPE_VIDEO,
-    CODEC_ID_INTERPLAY_VIDEO,
-    sizeof(IpvideoContext),
-    ipvideo_decode_init,
-    NULL,
-    ipvideo_decode_end,
-    ipvideo_decode_frame,
-    CODEC_CAP_DR1,
+AVCodec ff_interplay_video_decoder = {
+    .name           = "interplayvideo",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = CODEC_ID_INTERPLAY_VIDEO,
+    .priv_data_size = sizeof(IpvideoContext),
+    .init           = ipvideo_decode_init,
+    .close          = ipvideo_decode_end,
+    .decode         = ipvideo_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
     .long_name = NULL_IF_CONFIG_SMALL("Interplay MVE video"),
 };