Skip to content
Snippets Groups Projects
Commit 8d23a86f authored by Reimar Döffinger's avatar Reimar Döffinger
Browse files

Add an execute2 function that is more flexible and allows to use parallel

processing with jobs > threads without wasting too much memory.
It also avoids needing a separate int array when the only additional data
the jobs needs is a single int running from 0 to count-1.

Originally committed as revision 20210 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent febd1c90
No related branches found
No related tags found
No related merge requests found
......@@ -30,7 +30,7 @@
#include "libavutil/avutil.h"
#define LIBAVCODEC_VERSION_MAJOR 52
#define LIBAVCODEC_VERSION_MINOR 36
#define LIBAVCODEC_VERSION_MINOR 37
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
......@@ -2526,6 +2526,26 @@ typedef struct AVCodecContext {
* - decoding: Set by libavcodec
*/
enum AVChromaLocation chroma_sample_location;
/**
* The codec may call this to execute several independent things.
* It will return only after finishing all tasks.
* The user may replace this with some multithreaded implementation,
* the default implementation will execute the parts serially.
* Also see avcodec_thread_init and e.g. the --enable-pthread configure option.
* @param c context passed also to func
* @param count the number of things to execute
* @param arg2 argument passed unchanged to func
* @param ret return values of executed functions, must have space for "count" values. May be NULL.
* @param func function that will be called count times, with jobnr from 0 to count-1.
* threadnr will be in the range 0 to c->thread_count-1 < MAX_THREADS and so that no
* two instances of func executing at the same time will have the same threadnr.
* @return always 0 currently, but code should handle a future improvement where when any call to func
* returns < 0 no further calls to func may be done and < 0 is returned.
* - encoding: Set by libavcodec, user can override.
* - decoding: Set by libavcodec, user can override.
*/
int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count);
} AVCodecContext;
/**
......@@ -3154,6 +3174,7 @@ int avcodec_thread_init(AVCodecContext *s, int thread_count);
void avcodec_thread_free(AVCodecContext *s);
int avcodec_thread_execute(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size);
int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size);
int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count);
//FIXME func typedef
/**
......
......@@ -433,6 +433,7 @@ void avcodec_get_context_defaults2(AVCodecContext *s, enum CodecType codec_type)
s->release_buffer= avcodec_default_release_buffer;
s->get_format= avcodec_default_get_format;
s->execute= avcodec_default_execute;
s->execute2= avcodec_default_execute2;
s->sample_aspect_ratio= (AVRational){0,1};
s->pix_fmt= PIX_FMT_NONE;
s->sample_fmt= SAMPLE_FMT_S16; // FIXME: set to NONE
......
......@@ -26,10 +26,12 @@
#include "avcodec.h"
typedef int (action_func)(AVCodecContext *c, void *arg);
typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);
typedef struct ThreadContext {
pthread_t *workers;
action_func *func;
action_func2 *func2;
void *args;
int *rets;
int rets_count;
......@@ -68,7 +70,8 @@ static void* attribute_align_arg worker(void *v)
}
pthread_mutex_unlock(&c->current_job_lock);
c->rets[our_job%c->rets_count] = c->func(avctx, (char*)c->args + our_job*c->job_size);
c->rets[our_job%c->rets_count] = c->func ? c->func(avctx, (char*)c->args + our_job*c->job_size):
c->func2(avctx, c->args, our_job, self_id);
pthread_mutex_lock(&c->current_job_lock);
our_job = c->current_job++;
......@@ -130,6 +133,13 @@ int avcodec_thread_execute(AVCodecContext *avctx, action_func* func, void *arg,
return 0;
}
int avcodec_thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg, int *ret, int job_count)
{
ThreadContext *c= avctx->thread_opaque;
c->func2 = func2;
return avcodec_thread_execute(avctx, NULL, arg, ret, job_count, 0);
}
int avcodec_thread_init(AVCodecContext *avctx, int thread_count)
{
int i;
......@@ -167,5 +177,6 @@ int avcodec_thread_init(AVCodecContext *avctx, int thread_count)
avcodec_thread_park_workers(c, thread_count);
avctx->execute = avcodec_thread_execute;
avctx->execute2 = avcodec_thread_execute2;
return 0;
}
......@@ -414,6 +414,16 @@ int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, v
return 0;
}
int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int jobnr, int threadnr),void *arg, int *ret, int count){
int i;
for(i=0; i<count; i++){
int r= func(c, arg, i, 0);
if(ret) ret[i]= r;
}
return 0;
}
enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat *fmt){
while (*fmt != PIX_FMT_NONE && ff_is_hwaccel_pix_fmt(*fmt))
++fmt;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment