[FFmpeg-devel] [PATCH v2 3/3] lavc/libdavs2.c: use decoder data directly instead of memcpy

hwrenx hwrenx at 126.com
Fri Jul 12 15:47:40 EEST 2019


Signed-off-by: hwrenx <hwrenx at 126.com>
---
 libavcodec/libdavs2.c | 55 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 32 insertions(+), 23 deletions(-)

diff --git a/libavcodec/libdavs2.c b/libavcodec/libdavs2.c
index df538af..f88dfa0 100644
--- a/libavcodec/libdavs2.c
+++ b/libavcodec/libdavs2.c
@@ -58,13 +58,25 @@ static av_cold int davs2_init(AVCodecContext *avctx)
     return 0;
 }
 
+static void davs2_frame_unref(void *opaque, uint8_t *data) {
+    DAVS2Context    *cad = (DAVS2Context *)opaque;
+    davs2_picture_t *pic = (davs2_picture_t *)data;
+
+    /* set release pointer to itself */
+    pic->magic = pic;
+
+    if (cad->decoder) {
+        davs2_decoder_frame_unref(cad->decoder, pic);
+    } else {
+        av_log(NULL, AV_LOG_WARNING, "Decoder not found, frame unreference failed.\n");
+    }
+}
+
 static int davs2_dump_frames(AVCodecContext *avctx, davs2_picture_t *pic, int *got_frame,
                              davs2_seq_info_t *headerset, int ret_type, AVFrame *frame)
 {
     DAVS2Context *cad    = avctx->priv_data;
-    int bytes_per_sample = pic->bytes_per_sample;
-    int plane = 0;
-    int line  = 0;
+    int plane;
 
     if (!headerset) {
         *got_frame = 0;
@@ -102,29 +114,28 @@ static int davs2_dump_frames(AVCodecContext *avctx, davs2_picture_t *pic, int *g
         return AVERROR_EXTERNAL;
     }
 
-    for (plane = 0; plane < 3; ++plane) {
-        int size_line = pic->widths[plane] * bytes_per_sample;
-        frame->buf[plane]  = av_buffer_alloc(size_line * pic->lines[plane]);
-
-        if (!frame->buf[plane]){
-            av_log(avctx, AV_LOG_ERROR, "Decoder error: allocation failure, can't dump frames.\n");
-            return AVERROR(ENOMEM);
-        }
-
-        frame->data[plane]     = frame->buf[plane]->data;
-        frame->linesize[plane] = size_line;
-
-        for (line = 0; line < pic->lines[plane]; ++line)
-            memcpy(frame->data[plane] + line * size_line,
-                   pic->planes[plane] + line * pic->strides[plane],
-                   pic->widths[plane] * bytes_per_sample);
-    }
-
     frame->width     = cad->headerset.width;
     frame->height    = cad->headerset.height;
     frame->pts       = cad->out_frame.pts;
     frame->format    = avctx->pix_fmt;
 
+    /* handle the actual picture in magic */
+    frame->buf[0]    = av_buffer_create((uint8_t *)pic->magic,
+                                        sizeof(davs2_picture_t *),
+                                        davs2_frame_unref,
+                                        (void *)cad,
+                                        AV_BUFFER_FLAG_READONLY);
+    if (!frame->buf[0]) {
+        av_log(avctx, AV_LOG_ERROR,
+            "Decoder error: allocation failure, can't dump frames.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    for (plane = 0; plane < 3; ++plane) {
+        frame->linesize[plane] = pic->strides[plane];
+        frame->data[plane] = pic->planes[plane];
+    }
+
     *got_frame = 1;
     return 0;
 }
@@ -156,7 +167,6 @@ static int send_delayed_frame(AVCodecContext *avctx, AVFrame *frame, int *got_fr
     }
     if (ret == DAVS2_GOT_FRAME) {
         ret = davs2_dump_frames(avctx, &cad->out_frame, got_frame, &cad->headerset, ret, frame);
-        davs2_decoder_frame_unref(cad->decoder, &cad->out_frame);
     }
     return ret;
 }
@@ -205,7 +215,6 @@ static int davs2_decode_frame(AVCodecContext *avctx, void *data,
 
     if (ret != DAVS2_DEFAULT) {
         ret = davs2_dump_frames(avctx, &cad->out_frame, got_frame, &cad->headerset, ret, frame);
-        davs2_decoder_frame_unref(cad->decoder, &cad->out_frame);
     }
 
     return ret == 0 ? buf_size : ret;
-- 
2.7.4



More information about the ffmpeg-devel mailing list