Implement avcodec_flush_buffers for multithreaded codecs.

---
 libavcodec/framethread.c |   27 +++++++++++++++++++++++++++
 libavcodec/thread.h      |    2 ++
 libavcodec/utils.c       |    4 +++-
 3 files changed, 32 insertions(+), 1 deletions(-)

diff --git a/libavcodec/framethread.c b/libavcodec/framethread.c
index 66b1aa8..0ff8605 100644
--- a/libavcodec/framethread.c
+++ b/libavcodec/framethread.c
@@ -309,6 +309,33 @@ void ff_frame_thread_free(AVCodecContext *avctx) {
     av_free(fctx);
 }
 
+void ff_frame_thread_flush(AVCodecContext *avctx)
+{
+    FrameThreadContext *fctx = ((PerThreadContext*)avctx->thread_opaque)->parent;
+    int i;
+
+    for (i = 0; i < avctx->thread_count; i++) {
+        PerThreadContext *p = &fctx->threads[i];
+
+        pthread_mutex_lock(&p->progress_mutex);
+        while (p->decoded_frame_number <= p->frame_number) pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
+        pthread_mutex_unlock(&p->progress_mutex);
+    }
+
+    for (i = 0; i < avctx->thread_count; i++) {
+        PerThreadContext *p = &fctx->threads[i];
+        int j;
+
+        for (j = 0; j < p->nb_released_buffers; j++)
+            ff_release_buffer(&p->released_buffers[j]);
+
+        p->nb_released_buffers = 0;
+    }
+
+    if (avctx->codec->flush)
+        avctx->codec->flush(fctx->last_thread->context);
+}
+
 int ff_get_buffer(AVCodecContext *avctx, AVFrame *f)
 {
     int ret, *progress;
diff --git a/libavcodec/thread.h b/libavcodec/thread.h
index ce5c5fe..4377d08 100644
--- a/libavcodec/thread.h
+++ b/libavcodec/thread.h
@@ -29,6 +29,7 @@ void ff_thread_free(AVCodecContext *avctx);
 
 int ff_frame_thread_init(AVCodecContext *avctx);
 void ff_frame_thread_free(AVCodecContext *avctx);
+void ff_frame_thread_flush(AVCodecContext *avctx);
 
 int ff_decode_frame_threaded(AVCodecContext *avctx,
                         void *data, int *data_size,
@@ -47,6 +48,7 @@ static void ff_thread_free(AVCodecContext *avctx) {}
 
 static int ff_frame_thread_init(AVCodecContext *avctx) {return 0;}
 static void ff_frame_thread_free(AVCodecContext *avctx) {}
+static void ff_frame_thread_flush(AVCodecContext *avctx) {}
 
 #define ff_report_predecode_done(avctx)  {}
 #define ff_report_decode_progress(avctx) {}
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 85f3682..fdadc05 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -1281,7 +1281,9 @@ void avcodec_init(void)
 
 void avcodec_flush_buffers(AVCodecContext *avctx)
 {
-    if(avctx->codec->flush)
+    if(USE_FRAME_THREADING(avctx))
+        ff_frame_thread_flush(avctx);
+    else if(avctx->codec->flush)
         avctx->codec->flush(avctx);
 }
 
-- 
1.5.5.1


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

Reply via email to