[FFmpeg-devel] [PATCH 2/2] avcodec/scpr: rework frame handling

Paul B Mahol onemda at gmail.com
Sun Mar 12 13:40:40 EET 2017


Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
 libavcodec/scpr.c | 49 +++++++++++++++++++------------------------------
 1 file changed, 19 insertions(+), 30 deletions(-)

diff --git a/libavcodec/scpr.c b/libavcodec/scpr.c
index a37e99a..2d190db 100644
--- a/libavcodec/scpr.c
+++ b/libavcodec/scpr.c
@@ -45,7 +45,6 @@ typedef struct PixelModel {
 
 typedef struct SCPRContext {
     AVFrame        *last_frame;
-    AVFrame        *current_frame;
     GetByteContext  gb;
     RangeCoder      rc;
     PixelModel      pixel_model[3][4096];
@@ -751,12 +750,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     AVFrame *frame = data;
     int ret, type;
 
-    if (avctx->bits_per_coded_sample == 16) {
-        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
-            return ret;
-    }
-
-    if ((ret = ff_reget_buffer(avctx, s->current_frame)) < 0)
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
     bytestream2_init(gb, avpkt->data, avpkt->size);
@@ -767,16 +761,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         s->get_freq = get_freq0;
         s->decode = decode0;
         frame->key_frame = 1;
-        ret = decompress_i(avctx, (uint32_t *)s->current_frame->data[0],
-                           s->current_frame->linesize[0] / 4);
+        ret = decompress_i(avctx, (uint32_t *)frame->data[0],
+                           frame->linesize[0] / 4);
     } else if (type == 18) {
         s->get_freq = get_freq;
         s->decode = decode;
         frame->key_frame = 1;
-        ret = decompress_i(avctx, (uint32_t *)s->current_frame->data[0],
-                           s->current_frame->linesize[0] / 4);
+        ret = decompress_i(avctx, (uint32_t *)frame->data[0],
+                           frame->linesize[0] / 4);
     } else if (type == 17) {
-        uint32_t clr, *dst = (uint32_t *)s->current_frame->data[0];
+        uint32_t clr, *dst = (uint32_t *)frame->data[0];
         int x, y;
 
         frame->key_frame = 1;
@@ -796,17 +790,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             for (x = 0; x < avctx->width; x++) {
                 dst[x] = clr;
             }
-            dst += s->current_frame->linesize[0] / 4;
+            dst += frame->linesize[0] / 4;
         }
     } else if (type == 0 || type == 1) {
         frame->key_frame = 0;
 
-        ret = av_frame_copy(s->current_frame, s->last_frame);
+        ret = av_frame_copy(frame, s->last_frame);
         if (ret < 0)
             return ret;
+        av_frame_make_writable(frame);
 
-        ret = decompress_p(avctx, (uint32_t *)s->current_frame->data[0],
-                           s->current_frame->linesize[0] / 4,
+        ret = decompress_p(avctx, (uint32_t *)frame->data[0],
+                           frame->linesize[0] / 4,
                            (uint32_t *)s->last_frame->data[0],
                            s->last_frame->linesize[0] / 4);
     } else {
@@ -816,18 +811,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     if (ret < 0)
         return ret;
 
-    if (avctx->bits_per_coded_sample != 16) {
-        ret = av_frame_ref(data, s->current_frame);
-        if (ret < 0)
-            return ret;
-    } else {
+    av_frame_unref(s->last_frame);
+    s->last_frame = av_frame_clone(frame);
+    if (!s->last_frame)
+        return AVERROR(ENOMEM);
+
+    if (avctx->bits_per_coded_sample == 16) {
         uint8_t *dst = frame->data[0];
         int x, y;
 
-        ret = av_frame_copy(frame, s->current_frame);
-        if (ret < 0)
-            return ret;
-
+        av_frame_make_writable(s->last_frame);
         for (y = 0; y < avctx->height; y++) {
             for (x = 0; x < avctx->width * 4; x++) {
                 dst[x] = dst[x] << 3;
@@ -838,8 +831,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     frame->pict_type = frame->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
 
-    FFSWAP(AVFrame *, s->current_frame, s->last_frame);
-
     *got_frame = 1;
 
     return avpkt->size;
@@ -871,8 +862,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
 
     s->last_frame = av_frame_alloc();
-    s->current_frame = av_frame_alloc();
-    if (!s->last_frame || !s->current_frame)
+    if (!s->last_frame)
         return AVERROR(ENOMEM);
 
     return 0;
@@ -884,7 +874,6 @@ static av_cold int decode_close(AVCodecContext *avctx)
 
     av_freep(&s->blocks);
     av_frame_free(&s->last_frame);
-    av_frame_free(&s->current_frame);
 
     return 0;
 }
-- 
2.9.3



More information about the ffmpeg-devel mailing list