]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/smvjpegdec.c
Merge commit 'b8b809908ec547b2609dbac24194f4fd2df61aea'
[ffmpeg] / libavcodec / smvjpegdec.c
index 57116c2900b57ff1b0a131087da4f9f777ad554e..919b9a577185bf9bdaea777e57d9ae30ca5adae0 100644 (file)
@@ -36,6 +36,7 @@ typedef struct SMVJpegDecodeContext {
     AVFrame *picture[2]; /* pictures array */
     AVCodecContext* avctx;
     int frames_per_jpeg;
+    int mjpeg_data_size;
 } SMVJpegDecodeContext;
 
 static inline void smv_img_pnt_plane(uint8_t      **dst, uint8_t *src,
@@ -69,6 +70,9 @@ static inline void smv_img_pnt(uint8_t *dst_data[4], uint8_t *src_data[4],
         smv_img_pnt_plane(&dst_data[i], src_data[i],
             src_linesizes[i], h, nlines);
     }
+    if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
+        desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
+        dst_data[1] = src_data[1];
 }
 
 static av_cold int smvjpeg_decode_init(AVCodecContext *avctx)
@@ -123,6 +127,7 @@ static av_cold int smvjpeg_decode_init(AVCodecContext *avctx)
 static int smvjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
                             AVPacket *avpkt)
 {
+    const AVPixFmtDescriptor *desc;
     SMVJpegDecodeContext *s = avctx->priv_data;
     AVFrame* mjpeg_data = s->picture[0];
     int i, cur_frame = 0, ret = 0;
@@ -131,9 +136,18 @@ static int smvjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_siz
 
     /* Are we at the start of a block? */
     if (!cur_frame)
-        ret = avcodec_decode_video2(s->avctx, mjpeg_data, data_size, avpkt);
-    else /*use the last lot... */
-        *data_size = sizeof(AVPicture);
+        ret = avcodec_decode_video2(s->avctx, mjpeg_data, &s->mjpeg_data_size, avpkt);
+    else if (!s->mjpeg_data_size)
+        return AVERROR(EINVAL);
+
+    desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
+    if (desc && mjpeg_data->height % (s->frames_per_jpeg << desc->log2_chroma_h)) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid height\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    /*use the last lot... */
+    *data_size = s->mjpeg_data_size;
 
     avctx->pix_fmt = s->avctx->pix_fmt;
 
@@ -142,17 +156,19 @@ static int smvjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_siz
     avcodec_set_dimensions(avctx, mjpeg_data->width,
         mjpeg_data->height / s->frames_per_jpeg);
 
-    s->picture[1]->extended_data = NULL;
-    s->picture[1]->width         = avctx->width;
-    s->picture[1]->height        = avctx->height;
-    s->picture[1]->format        = avctx->pix_fmt;
-    /* ff_init_buffer_info(avctx, &s->picture[1]); */
-    smv_img_pnt(s->picture[1]->data, mjpeg_data->data, mjpeg_data->linesize,
-                avctx->pix_fmt, avctx->width, avctx->height, cur_frame);
-    for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
-        s->picture[1]->linesize[i] = mjpeg_data->linesize[i];
-
-    ret = av_frame_ref(data, s->picture[1]);
+    if (*data_size) {
+        s->picture[1]->extended_data = NULL;
+        s->picture[1]->width         = avctx->width;
+        s->picture[1]->height        = avctx->height;
+        s->picture[1]->format        = avctx->pix_fmt;
+        /* ff_init_buffer_info(avctx, &s->picture[1]); */
+        smv_img_pnt(s->picture[1]->data, mjpeg_data->data, mjpeg_data->linesize,
+                    avctx->pix_fmt, avctx->width, avctx->height, cur_frame);
+        for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
+            s->picture[1]->linesize[i] = mjpeg_data->linesize[i];
+
+        ret = av_frame_ref(data, s->picture[1]);
+    }
 
     return ret;
 }
@@ -183,7 +199,6 @@ AVCodec ff_smvjpeg_decoder = {
     .init           = smvjpeg_decode_init,
     .close          = smvjpeg_decode_end,
     .decode         = smvjpeg_decode_frame,
-    .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("SMV JPEG"),
     .priv_class     = &smvjpegdec_class,
 };