]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/bmv.c
dict: add av_dict_parse_string()
[ffmpeg] / libavcodec / bmv.c
index 49346a41a8d5dde1777d5ab4a01b184bb0de869c..a082d3ced7c5ff2dcc4844fef51e019c856b11c9 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/channel_layout.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 enum BMVFlags{
     BMV_NOP = 0,
@@ -52,7 +54,7 @@ typedef struct BMVDecContext {
 
 static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, int frame_off)
 {
-    int val, saved_val = 0;
+    unsigned val, saved_val = 0;
     int tmplen = src_len;
     const uint8_t *src, *source_end = source + src_len;
     uint8_t *frame_end = frame + SCREEN_WIDE * SCREEN_HIGH;
@@ -65,7 +67,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
     int i;
 
     if (src_len <= 0)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     if (forward) {
         src = source;
@@ -89,7 +91,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
          */
         if (!mode || (tmplen == 4)) {
             if (src < source || src >= source_end)
-                return -1;
+                return AVERROR_INVALIDDATA;
             val = *src;
             read_two_nibbles = 1;
         } else {
@@ -100,7 +102,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
             for (;;) {
                 if (!read_two_nibbles) {
                     if (src < source || src >= source_end)
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     shift += 2;
                     val |= *src << shift;
                     if (*src & 0xC)
@@ -135,21 +137,25 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
         if (mode >= 4)
             mode -= 3;
         if (FFABS(dst_end - dst) < len)
-            return -1;
+            return AVERROR_INVALIDDATA;
         switch (mode) {
         case 1:
             if (forward) {
                 if (dst - frame + SCREEN_WIDE < frame_off ||
-                        frame_end - dst < frame_off + len)
-                    return -1;
+                        dst - frame + SCREEN_WIDE + frame_off < 0 ||
+                        frame_end - dst < frame_off + len ||
+                        frame_end - dst < len)
+                    return AVERROR_INVALIDDATA;
                 for (i = 0; i < len; i++)
                     dst[i] = dst[frame_off + i];
                 dst += len;
             } else {
                 dst -= len;
                 if (dst - frame + SCREEN_WIDE < frame_off ||
-                        frame_end - dst < frame_off + len)
-                    return -1;
+                        dst - frame + SCREEN_WIDE + frame_off < 0 ||
+                        frame_end - dst < frame_off + len ||
+                        frame_end - dst < len)
+                    return AVERROR_INVALIDDATA;
                 for (i = len - 1; i >= 0; i--)
                     dst[i] = dst[frame_off + i];
             }
@@ -157,13 +163,13 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
         case 2:
             if (forward) {
                 if (source + src_len - src < len)
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 memcpy(dst, src, len);
                 dst += len;
                 src += len;
             } else {
                 if (src - source < len)
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 dst -= len;
                 src -= len;
                 memcpy(dst, src, len);
@@ -188,11 +194,12 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt)
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                        AVPacket *pkt)
 {
     BMVDecContext * const c = avctx->priv_data;
     int type, scr_off;
-    int i;
+    int i, ret;
     uint8_t *srcptr, *outptr;
 
     c->stream = pkt->data;
@@ -233,6 +240,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
         scr_off = 0;
     }
 
+    if (c->pic.data[0])
+        avctx->release_buffer(avctx, &c->pic);
+
+    c->pic.reference = 3;
+    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
+    }
+
     if (decode_bmv_frame(c->stream, pkt->size - (c->stream - pkt->data), c->frame, scr_off)) {
         av_log(avctx, AV_LOG_ERROR, "Error decoding frame data\n");
         return AVERROR_INVALIDDATA;
@@ -250,7 +266,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
         outptr += c->pic.linesize[0];
     }
 
-    *data_size = sizeof(AVFrame);
+    *got_frame = 1;
     *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
@@ -262,13 +278,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
     BMVDecContext * const c = avctx->priv_data;
 
     c->avctx = avctx;
-    avctx->pix_fmt = PIX_FMT_PAL8;
-
-    c->pic.reference = 1;
-    if (avctx->get_buffer(avctx, &c->pic) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
-    }
+    avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
     c->frame = c->frame_base + 640;
 
@@ -297,12 +307,9 @@ static av_cold int bmv_aud_decode_init(AVCodecContext *avctx)
 {
     BMVAudioDecContext *c = avctx->priv_data;
 
-    if (avctx->channels != 2) {
-        av_log(avctx, AV_LOG_INFO, "invalid number of channels\n");
-        return AVERROR(EINVAL);
-    }
-
-    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+    avctx->channels       = 2;
+    avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+    avctx->sample_fmt     = AV_SAMPLE_FMT_S16;
 
     avcodec_get_frame_defaults(&c->frame);
     avctx->coded_frame = &c->frame;
@@ -330,7 +337,7 @@ static int bmv_aud_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     c->frame.nb_samples = total_blocks * 32;
-    if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -356,18 +363,19 @@ static int bmv_aud_decode_frame(AVCodecContext *avctx, void *data,
 AVCodec ff_bmv_video_decoder = {
     .name           = "bmv_video",
     .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = CODEC_ID_BMV_VIDEO,
+    .id             = AV_CODEC_ID_BMV_VIDEO,
     .priv_data_size = sizeof(BMVDecContext),
     .init           = decode_init,
     .close          = decode_end,
     .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Discworld II BMV video"),
 };
 
 AVCodec ff_bmv_audio_decoder = {
     .name           = "bmv_audio",
     .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = CODEC_ID_BMV_AUDIO,
+    .id             = AV_CODEC_ID_BMV_AUDIO,
     .priv_data_size = sizeof(BMVAudioDecContext),
     .init           = bmv_aud_decode_init,
     .decode         = bmv_aud_decode_frame,