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
This commit is contained in:
parent
febd1c90a6
commit
8d23a86f33
@ -30,7 +30,7 @@
|
|||||||
#include "libavutil/avutil.h"
|
#include "libavutil/avutil.h"
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_MAJOR 52
|
#define LIBAVCODEC_VERSION_MAJOR 52
|
||||||
#define LIBAVCODEC_VERSION_MINOR 36
|
#define LIBAVCODEC_VERSION_MINOR 37
|
||||||
#define LIBAVCODEC_VERSION_MICRO 0
|
#define LIBAVCODEC_VERSION_MICRO 0
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||||
@ -2526,6 +2526,26 @@ typedef struct AVCodecContext {
|
|||||||
* - decoding: Set by libavcodec
|
* - decoding: Set by libavcodec
|
||||||
*/
|
*/
|
||||||
enum AVChromaLocation chroma_sample_location;
|
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;
|
} AVCodecContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3154,6 +3174,7 @@ int avcodec_thread_init(AVCodecContext *s, int thread_count);
|
|||||||
void avcodec_thread_free(AVCodecContext *s);
|
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_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_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
|
//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->release_buffer= avcodec_default_release_buffer;
|
||||||
s->get_format= avcodec_default_get_format;
|
s->get_format= avcodec_default_get_format;
|
||||||
s->execute= avcodec_default_execute;
|
s->execute= avcodec_default_execute;
|
||||||
|
s->execute2= avcodec_default_execute2;
|
||||||
s->sample_aspect_ratio= (AVRational){0,1};
|
s->sample_aspect_ratio= (AVRational){0,1};
|
||||||
s->pix_fmt= PIX_FMT_NONE;
|
s->pix_fmt= PIX_FMT_NONE;
|
||||||
s->sample_fmt= SAMPLE_FMT_S16; // FIXME: set to NONE
|
s->sample_fmt= SAMPLE_FMT_S16; // FIXME: set to NONE
|
||||||
|
@ -26,10 +26,12 @@
|
|||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
|
|
||||||
typedef int (action_func)(AVCodecContext *c, void *arg);
|
typedef int (action_func)(AVCodecContext *c, void *arg);
|
||||||
|
typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);
|
||||||
|
|
||||||
typedef struct ThreadContext {
|
typedef struct ThreadContext {
|
||||||
pthread_t *workers;
|
pthread_t *workers;
|
||||||
action_func *func;
|
action_func *func;
|
||||||
|
action_func2 *func2;
|
||||||
void *args;
|
void *args;
|
||||||
int *rets;
|
int *rets;
|
||||||
int rets_count;
|
int rets_count;
|
||||||
@ -68,7 +70,8 @@ static void* attribute_align_arg worker(void *v)
|
|||||||
}
|
}
|
||||||
pthread_mutex_unlock(&c->current_job_lock);
|
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);
|
pthread_mutex_lock(&c->current_job_lock);
|
||||||
our_job = c->current_job++;
|
our_job = c->current_job++;
|
||||||
@ -130,6 +133,13 @@ int avcodec_thread_execute(AVCodecContext *avctx, action_func* func, void *arg,
|
|||||||
return 0;
|
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 avcodec_thread_init(AVCodecContext *avctx, int thread_count)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -167,5 +177,6 @@ int avcodec_thread_init(AVCodecContext *avctx, int thread_count)
|
|||||||
avcodec_thread_park_workers(c, thread_count);
|
avcodec_thread_park_workers(c, thread_count);
|
||||||
|
|
||||||
avctx->execute = avcodec_thread_execute;
|
avctx->execute = avcodec_thread_execute;
|
||||||
|
avctx->execute2 = avcodec_thread_execute2;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -414,6 +414,16 @@ int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, v
|
|||||||
return 0;
|
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){
|
enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat *fmt){
|
||||||
while (*fmt != PIX_FMT_NONE && ff_is_hwaccel_pix_fmt(*fmt))
|
while (*fmt != PIX_FMT_NONE && ff_is_hwaccel_pix_fmt(*fmt))
|
||||||
++fmt;
|
++fmt;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user