00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "avcodec.h"
00023
00024 #define WIN32_LEAN_AND_MEAN
00025 #include <windows.h>
00026 #include <process.h>
00027
00028 typedef struct ThreadContext{
00029 AVCodecContext *avctx;
00030 HANDLE thread;
00031 HANDLE work_sem;
00032 HANDLE done_sem;
00033 int (*func)(AVCodecContext *c, void *arg);
00034 void *arg;
00035 int ret;
00036 }ThreadContext;
00037
00038
00039 static unsigned WINAPI attribute_align_arg thread_func(void *v){
00040 ThreadContext *c= v;
00041
00042 for(;;){
00043
00044 WaitForSingleObject(c->work_sem, INFINITE);
00045
00046 if(c->func)
00047 c->ret= c->func(c->avctx, c->arg);
00048 else
00049 return 0;
00050
00051 ReleaseSemaphore(c->done_sem, 1, 0);
00052 }
00053
00054 return 0;
00055 }
00056
00061 void avcodec_thread_free(AVCodecContext *s){
00062 ThreadContext *c= s->thread_opaque;
00063 int i;
00064
00065 for(i=0; i<s->thread_count; i++){
00066
00067 c[i].func= NULL;
00068 ReleaseSemaphore(c[i].work_sem, 1, 0);
00069 WaitForSingleObject(c[i].thread, INFINITE);
00070 if(c[i].work_sem) CloseHandle(c[i].work_sem);
00071 if(c[i].done_sem) CloseHandle(c[i].done_sem);
00072 }
00073
00074 av_freep(&s->thread_opaque);
00075 }
00076
00077 int avcodec_thread_execute(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size){
00078 ThreadContext *c= s->thread_opaque;
00079 int i;
00080
00081 assert(s == c->avctx);
00082 assert(count <= s->thread_count);
00083
00084
00085
00086 for(i=0; i<count; i++){
00087 c[i].arg= (char*)arg + i*size;
00088 c[i].func= func;
00089 c[i].ret= 12345;
00090
00091 ReleaseSemaphore(c[i].work_sem, 1, 0);
00092 }
00093 for(i=0; i<count; i++){
00094 WaitForSingleObject(c[i].done_sem, INFINITE);
00095
00096 c[i].func= NULL;
00097 if(ret) ret[i]= c[i].ret;
00098 }
00099 return 0;
00100 }
00101
00102 int avcodec_thread_init(AVCodecContext *s, int thread_count){
00103 int i;
00104 ThreadContext *c;
00105 uint32_t threadid;
00106
00107 s->thread_count= thread_count;
00108
00109 assert(!s->thread_opaque);
00110 c= av_mallocz(sizeof(ThreadContext)*thread_count);
00111 s->thread_opaque= c;
00112
00113 for(i=0; i<thread_count; i++){
00114
00115 c[i].avctx= s;
00116
00117 if(!(c[i].work_sem = CreateSemaphore(NULL, 0, s->thread_count, NULL)))
00118 goto fail;
00119 if(!(c[i].done_sem = CreateSemaphore(NULL, 0, s->thread_count, NULL)))
00120 goto fail;
00121
00122
00123 c[i].thread = (HANDLE)_beginthreadex(NULL, 0, thread_func, &c[i], 0, &threadid );
00124 if( !c[i].thread ) goto fail;
00125 }
00126
00127
00128 s->execute= avcodec_thread_execute;
00129
00130 return 0;
00131 fail:
00132 avcodec_thread_free(s);
00133 return -1;
00134 }