The new _progress3 functions allow reporting the x,y position in decoding. ff_thread_report_progress3_raster_end allows signaling the end of a raster line and updates unconditionally the position to the start of next raster line.
ff_thread_report_progress3_increment tries to increment position if it lies on the same raster line as current position. --- libavcodec/pthread_frame.c | 68 ++++++++++++++++++++++++++++++++++++++++++++-- libavcodec/thread.h | 24 ++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 2a67f4d..9896bba 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -488,6 +488,51 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int field) pthread_mutex_unlock(&p->progress_mutex); } +void ff_thread_report_progress3_raster_end(ThreadFrame *f, int y) +{ + PerThreadContext *p; + volatile int *progress = f->progress ? (int*)f->progress->data : NULL; + + if (!progress || progress[0] > y || progress[1] > y ) + return; + + p = f->owner->internal->thread_ctx; + + if (f->owner->debug&FF_DEBUG_THREADS) + av_log(f->owner, AV_LOG_DEBUG, "%p finished line %d\n", progress, y); + + pthread_mutex_lock(&p->progress_mutex); + progress[0] = y; + progress[1] = y; + progress[2] = 0; + pthread_cond_broadcast(&p->progress_cond); + pthread_mutex_unlock(&p->progress_mutex); +} + +void ff_thread_report_progress3_increment(ThreadFrame *f, int x, int y, int step) +{ + PerThreadContext *p; + volatile int *progress = f->progress ? (int*)f->progress->data : NULL; + + if (!progress || (progress[0]!=-1 && y != progress[0])) return; + // Until a line is completed, increments on x from next line are ignored, + // therefore allow horizontal jumps in case they are on the expect line + if (progress[0] != progress[1] && progress[2]+step != x) return; + + p = f->owner->internal->thread_ctx; + + if (f->owner->debug&FF_DEBUG_THREADS) + av_log(f->owner, AV_LOG_DEBUG, "%p finished up to (%d,%d)/%d\n", + progress, x, y, step); + + pthread_mutex_lock(&p->progress_mutex); + progress[0] = y; + progress[1] = y + step; + progress[2] = x; + pthread_cond_broadcast(&p->progress_cond); + pthread_mutex_unlock(&p->progress_mutex); +} + void ff_thread_await_progress(ThreadFrame *f, int n, int field) { PerThreadContext *p; @@ -506,6 +551,25 @@ void ff_thread_await_progress(ThreadFrame *f, int n, int field) pthread_mutex_unlock(&p->progress_mutex); } +void ff_thread_await_progress3(ThreadFrame *f, int x, int y) +{ + PerThreadContext *p; + volatile int *progress = f->progress ? (int*)f->progress->data : NULL; + + if (!progress || progress[0] >= y || + (progress[2] >= x && progress[1] >= y)) return; + + p = f->owner->internal->thread_ctx; + + if (f->owner->debug&FF_DEBUG_THREADS) + av_log(f->owner, AV_LOG_DEBUG, "thread awaiting (%d,%d) point in %p\n", x, y, progress); + + pthread_mutex_lock(&p->progress_mutex); + while (progress[0] < y && (progress[2] < x || progress[1] < y)) + pthread_cond_wait(&p->progress_cond, &p->progress_mutex); + pthread_mutex_unlock(&p->progress_mutex); +} + void ff_thread_finish_setup(AVCodecContext *avctx) { PerThreadContext *p = avctx->internal->thread_ctx; @@ -766,13 +830,13 @@ static int thread_get_buffer_internal(AVCodecContext *avctx, ThreadFrame *f, int if (avctx->internal->allocate_progress) { int *progress; - f->progress = av_buffer_alloc(2 * sizeof(int)); + f->progress = av_buffer_alloc(3 * sizeof(int)); if (!f->progress) { return AVERROR(ENOMEM); } progress = (int*)f->progress->data; - progress[0] = progress[1] = -1; + progress[0] = progress[1] = progress[2] = -1; } pthread_mutex_lock(&p->parent->buffer_mutex); diff --git a/libavcodec/thread.h b/libavcodec/thread.h index c848d7a..ca1bf81 100644 --- a/libavcodec/thread.h +++ b/libavcodec/thread.h @@ -140,4 +140,28 @@ void ff_reset_entries(AVCodecContext *avctx); void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n); void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift); +/** + * Report end of a line in raster order: change current raster line and refresh + * position. + * @param f The picture being decoded. + * @param y Ordinate of the finished line. + */ +void ff_thread_report_progress3_raster_end(ThreadFrame *f, int y); +/** + * Report progress inside a raster line. If the progress does not correspond to + * an increment, it is ignored. + * @param f The picture being decoded. + * @param x Abscissa of the progress + * @param y Ordinate of the progress + * @param step Allowed increment + */ +void ff_thread_report_progress3_increment(ThreadFrame *f, int x, int y, int step); +/** + * Wait for point to be in the decoded area. + * @param f The picture being decoded. + * @param x First coordinate. + * @param y Second coordinate. + */ +void ff_thread_await_progress3(ThreadFrame *f, int x, int y); + #endif /* AVCODEC_THREAD_H */ -- 1.9.2.msysgit.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel