---
 libavcodec/pthread.c |   27 ++++++++++++++++++++-------
 libavcodec/thread.h  |   20 +++++++++++++++++++-
 mt-work/todo.txt     |    1 -
 3 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c
index 577329f..f142796 100644
--- a/libavcodec/pthread.c
+++ b/libavcodec/pthread.c
@@ -255,7 +255,10 @@ static attribute_align_arg void *decode_frame_thread(void *arg)
         p->result = codec->decode(avctx, &p->picture, &p->got_picture, p->buf, p->buf_size);
 
         if (p->state == STATE_PREDECODING) ff_report_frame_setup_done(avctx);
-        if (p->got_picture) ff_report_frame_progress(&p->picture, INT_MAX);
+        if (p->got_picture) {
+            ff_report_field_progress(&p->picture, INT_MAX, 0);
+            ff_report_field_progress(&p->picture, INT_MAX, 1);
+        }
 
         p->buf_size = 0;
         p->state = STATE_INPUT_READY;
@@ -487,32 +490,42 @@ int ff_decode_frame_threaded(AVCodecContext *avctx,
     return p->result;
 }
 
-void ff_report_frame_progress(AVFrame *f, int n)
+void ff_report_field_progress(AVFrame *f, int n, int field)
 {
     PerThreadContext *p = f->owner->thread_opaque;
     int *progress = f->thread_opaque;
 
-    if (*progress >= n) return;
+    if (progress[field] >= n) return;
 
     pthread_mutex_lock(&p->progress_mutex);
-    *progress = n;
+    progress[field] = n;
     pthread_cond_broadcast(&p->progress_cond);
     pthread_mutex_unlock(&p->progress_mutex);
 }
 
-void ff_await_frame_progress(AVFrame *f, int n)
+void ff_await_field_progress(AVFrame *f, int n, int field)
 {
     PerThreadContext *p = f->owner->thread_opaque;
     int * volatile progress = f->thread_opaque;
 
-    if (*progress >= n) return;
+    if (progress[field] >= n) return;
 
     pthread_mutex_lock(&p->progress_mutex);
-    while (*progress < n)
+    while (progress[field] < n)
         pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
     pthread_mutex_unlock(&p->progress_mutex);
 }
 
+void ff_report_frame_progress(AVFrame *f, int n)
+{
+    ff_report_field_progress(f, n, 0);
+}
+
+void ff_await_frame_progress(AVFrame *f, int n)
+{
+    ff_await_field_progress(f, n, 0);
+}
+
 void ff_report_frame_setup_done(AVCodecContext *avctx) {
     PerThreadContext *p = avctx->thread_opaque;
 
diff --git a/libavcodec/thread.h b/libavcodec/thread.h
index a5d390f..6f4ae2a 100644
--- a/libavcodec/thread.h
+++ b/libavcodec/thread.h
@@ -61,7 +61,7 @@ void ff_report_frame_setup_done(AVCodecContext *avctx);
  * Subsequent calls with lower values for \p progress will be ignored.
  *
  * @param f The frame being decoded
- * @param progress The highest-numbered part decoded so far
+ * @param progress The highest-numbered part finished so far
  */
 void ff_report_frame_progress(AVFrame *f, int progress);
 
@@ -72,6 +72,22 @@ void ff_report_frame_progress(AVFrame *f, int progress);
 void ff_await_frame_progress(AVFrame *f, int progress);
 
 /**
+ * Equivalent of ff_report_frame_progress() for pictures whose fields
+ * are stored in seperate frames.
+ *
+ * @param f The frame containing the current field
+ * @param progress The highest-numbered part finished so far
+ * @param field The current field. 0 for top field/frame, 1 for bottom.
+ */
+void ff_report_field_progress(AVFrame *f, int progress, int field);
+
+/**
+ * Equivaent of ff_await_frame_progress() for pictures whose fields
+ * are stored in seperate frames.
+ */
+void ff_await_field_progress(AVFrame *f, int progress, int field);
+
+/**
  * Allocate a frame with avctx->get_buffer() and set
  * values needed for multithreading. Codecs must call
  * this instead of using get_buffer() directly if
@@ -97,7 +113,9 @@ void ff_release_buffer(AVCodecContext *avctx, AVFrame *f);
 //Stub out these functions for systems without pthreads
 static inline void ff_report_frame_setup_done(AVCodecContext *avctx) {}
 static inline void ff_report_frame_progress(AVFrame *f, int progress) {}
+static inline void ff_report_field_progress(AVFrame *f, int progress, int field) {}
 static inline void ff_await_frame_progress(AVFrame *f, int progress) {}
+static inline void ff_await_field_progress(AVFrame *f, int progress, int field) {}
 
 static inline int ff_get_buffer(AVCodecContext *avctx, AVFrame *f)
 {
diff --git a/mt-work/todo.txt b/mt-work/todo.txt
index 5806140..cb593b6 100644
--- a/mt-work/todo.txt
+++ b/mt-work/todo.txt
@@ -9,7 +9,6 @@ There is a branch with a guess at the right code.
 probably can't handle A/V sync with it properly. ffplay and mplayer should be fine.
 - PAFF is not parallelized
 - The last frame/some B-frames in H.264 has a wrong crc with a large number of threads.
-- Allocate two progress counters for each buffer and use them to track individual fields
 - Support slice+frame threading, which is a bit hard because streams can have varying slices
 per frame.
 - Frame num gaps cause indeterminism (easy to fix)
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc

Reply via email to