[FFmpeg-devel] [PATCH 1/4] libavcodec: new API for frame threading by step

Michael Niedermayer michaelni at gmx.at
Mon Jul 28 23:15:30 CEST 2014


On Mon, Jul 28, 2014 at 07:21:37PM +0200, Christophe Gisquet wrote:
> 2014-07-23 21:20 GMT+02:00 Christophe Gisquet <christophe.gisquet at gmail.com>:
> > Didn't refresh the patch with update documentation. Here it is.
> 
> It didn't contain dummy functions in libavcodec/utils.c.
> 
> The attached patch should fix failures to build with pthread disabled.
> 
> -- 
> Christophe

>  doc/multithreading.txt     |   23 ++++++++++++++-
>  libavcodec/pthread_frame.c |   68 +++++++++++++++++++++++++++++++++++++++++++--
>  libavcodec/thread.h        |   24 +++++++++++++++
>  libavcodec/utils.c         |   12 +++++++
>  4 files changed, 124 insertions(+), 3 deletions(-)
> 7f84dee144197c510c7fa872df36e08b04f85987  0004-libavcodec-new-API-for-frame-threading-by-step.patch
> From 4a144438e5dcd66be173b2d23f310bb4eacec24d Mon Sep 17 00:00:00 2001
> From: Christophe Gisquet <christophe.gisquet at gmail.com>
> Date: Fri, 18 Jul 2014 19:19:06 +0200
> Subject: [PATCH 04/15] libavcodec: new API for frame threading by step
> 
> 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.
> ---
>  doc/multithreading.txt     |   23 ++++++++++++++-
>  libavcodec/pthread_frame.c |   68 ++++++++++++++++++++++++++++++++++++++++++-
>  libavcodec/thread.h        |   24 +++++++++++++++
>  libavcodec/utils.c         |   12 ++++++++
>  4 files changed, 124 insertions(+), 3 deletions(-)
> 
> diff --git a/doc/multithreading.txt b/doc/multithreading.txt
> index 2b992fc..30e7219 100644
> --- a/doc/multithreading.txt
> +++ b/doc/multithreading.txt
> @@ -1,7 +1,7 @@
>  FFmpeg multithreading methods
>  ==============================================
>  
> -FFmpeg provides two methods for multithreading codecs.
> +FFmpeg provides three methods for multithreading codecs.
>  
>  Slice threading decodes multiple parts of a frame at the same time, using
>  AVCodecContext execute() and execute2().
> @@ -11,6 +11,9 @@ It accepts N future frames and delays decoded pictures by N-1 frames.
>  The later frames are decoded in separate threads while the user is
>  displaying the current one.
>  
> +Frame step threading is similar to frame threading except the progress is
> +measured in a finer way.
> +
>  Restrictions on clients
>  ==============================================
>  
> @@ -26,6 +29,9 @@ Frame threading -
>    Clients must be able to handle this; the pkt_dts and pkt_pts fields in
>    AVFrame will work as usual.
>  
> +Frame step threading -
> +* Same as frame threading
> +
>  Restrictions on codec implementations
>  ==============================================
>  
> @@ -42,6 +48,10 @@ Frame threading -
>  * The contents of buffers must not be written to after ff_thread_report_progress()
>    has been called on them. This includes draw_edges().
>  
> +Frame step threadin -
> +* The progress must be in raster scan.
> +* Raster lines must be reported in order.
> +
>  Porting codecs to frame threading
>  ==============================================
>  
> @@ -68,3 +78,14 @@ called anywhere, as it's useful too and the implementation is trivial when you'r
>  doing this. Note that draw_edges() needs to be called before reporting progress.
>  
>  Before accessing a reference frame or its MVs, call ff_thread_await_progress().
> +
> +Porting codecs to frame step threading
> +==============================================
> +
> +Instead of using {report,await}_progress() with the ordinate:
> +- You can signal a raster line end by passing the line ordinate to
> +  ff_thread_report_progress3_raster_end;
> +- You should signal intermediate progress by passing the x,y progress
> +  as well as the expected step since last progress to
> +  ff_thread_report_progress3_increment;
> +- ff_thread_await_progress3 now takes x,y parameters.

> 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;

maybe i misunderstand but the "progress[1] > y" check looks odd,
shouldnt progress[0] be updated to a larger value even if
progress[1] > y
?


> +
> +    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;

from ff_thread_await_progress3()
    > +    if (!progress || progress[0] >= y ||
    > +        (progress[2] >= x && progress[1] >= y)) return;


i would have expected report to do:

if (progress[1] <= y + step &&  progress[2] <= x)
    update progress[1..2]

but again, maybe iam missing something


> +
> +    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;

if progress[0] starts with 0 then this should be unneeded


also if the x and y step size is constant then one could use a
single variable based progress with
x_in_steps + y_in_steps * width_in_steps


[...]

> +void ff_thread_report_progress3_increment(ThreadFrame *f, int x, int y, int step);
> +{
> +}

typo ";"


[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

The greatest way to live with honor in this world is to be what we pretend
to be. -- Socrates
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140728/a6cf8cfb/attachment.asc>


More information about the ffmpeg-devel mailing list