Add ff_mt_delayed_release_buffer for handling reference frames.
---
 libavcodec/framethread.c |   29 +++++++++++++++++++++++++++++
 libavcodec/thread.h      |    1 +
 2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/libavcodec/framethread.c b/libavcodec/framethread.c
index 3cd83d2..8c5740d 100644
--- a/libavcodec/framethread.c
+++ b/libavcodec/framethread.c
@@ -22,6 +22,8 @@
 #include "avcodec.h"
 #include "thread.h"
 
+#define MAX_DELAYED_RELEASED_BUFFERS 2
+
 /*
 FIXME:
 There are maybe more (or less) conds/mutexes than necessary
@@ -47,6 +49,9 @@ typedef struct PerThreadContext {
     int frame_number, decoded_frame_number, decode_progress;
 
     int predecoded; // unneeded?
+
+    AVFrame released_buffers[MAX_DELAYED_RELEASED_BUFFERS];
+    int nb_released_buffers;
 } PerThreadContext;
 
 typedef struct FrameThreadContext {
@@ -99,6 +104,7 @@ static void submit_frame(PerThreadContext * volatile p, const uint8_t *buf, int
 {
     AVCodec *codec = p->context->codec;
     PerThreadContext *last_thread = p->parent->last_thread;
+    int i;
 
     if (!buf_size && !(p->context->codec->capabilities & CODEC_CAP_DELAY)) return;
 
@@ -115,6 +121,11 @@ static void submit_frame(PerThreadContext * volatile p, const uint8_t *buf, int
     p->decode_progress = -1;
     p->predecoded = 0;
 
+    for (i = 0; i < p->nb_released_buffers; i++)
+        ff_mt_release_buffer(&p->released_buffers[i]);
+
+    p->nb_released_buffers = 0;
+
     pthread_cond_signal(&p->input_cond);
     pthread_mutex_unlock(&p->mutex);
 
@@ -332,3 +343,21 @@ void ff_mt_release_buffer(AVFrame *f)
     f->avctx->release_buffer(f->avctx, f);
     pthread_mutex_unlock(&p->buffer_mutex);
 }
+
+void ff_mt_delayed_release_buffer(AVCodecContext *avctx, AVFrame *f)
+{
+    PerThreadContext *p = avctx->thread_opaque;
+
+    if (!p) {
+        f->avctx->release_buffer(f->avctx, f);
+        return;
+    }
+
+    if (p->nb_released_buffers >= MAX_DELAYED_RELEASED_BUFFERS) {
+        av_log(p->context, AV_LOG_ERROR, "too many delayed release_buffer calls!\n");
+        return;
+    }
+
+    p->released_buffers[p->nb_released_buffers++] = *f;
+    memset(f->data, 0, sizeof(f->data));
+}
\ No newline at end of file
diff --git a/libavcodec/thread.h b/libavcodec/thread.h
index 7b78e13..ebe9a73 100644
--- a/libavcodec/thread.h
+++ b/libavcodec/thread.h
@@ -40,6 +40,7 @@ void ff_await_decode_progress(AVFrame *, int progress);
 
 int ff_mt_get_buffer(AVCodecContext *, AVFrame *f);
 void ff_mt_release_buffer(AVFrame *);
+void ff_mt_delayed_release_buffer(AVCodecContext *avctx, AVFrame *f);
 #else
 static int ff_thread_init(AVCodecContext *) {return 0;}
 static void ff_thread_free(AVCodecContext *) {}
-- 
1.5.5.1

_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc

Reply via email to