w32thread.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:4k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
  3.  *
  4.  * This library is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU Lesser General Public
  6.  * License as published by the Free Software Foundation; either
  7.  * version 2 of the License, or (at your option) any later version.
  8.  *
  9.  * This library is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.  * Lesser General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU Lesser General Public
  15.  * License along with this library; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17.  *
  18.  */
  19. //#define DEBUG
  20. #include "avcodec.h"
  21. #include "common.h"
  22. #define WIN32_LEAN_AND_MEAN
  23. #include <windows.h>
  24. #include <process.h>
  25. typedef struct ThreadContext{
  26.     AVCodecContext *avctx;
  27.     HANDLE thread;
  28.     HANDLE work_sem;
  29.     HANDLE done_sem;
  30.     int (*func)(AVCodecContext *c, void *arg);
  31.     void *arg;
  32.     int ret;
  33. }ThreadContext;
  34. static unsigned __stdcall thread_func(void *v){
  35.     ThreadContext *c= v;
  36.     for(;;){
  37. //printf("thread_func %X enter waitn", (int)v); fflush(stdout);
  38.         WaitForSingleObject(c->work_sem, INFINITE);
  39. //printf("thread_func %X after wait (func=%X)n", (int)v, (int)c->func); fflush(stdout);
  40.         if(c->func)
  41.             c->ret= c->func(c->avctx, c->arg);
  42.         else
  43.             return 0;
  44. //printf("thread_func %X signal completen", (int)v); fflush(stdout);
  45.         ReleaseSemaphore(c->done_sem, 1, 0);
  46.     }
  47.     
  48.     return 0;
  49. }
  50. /**
  51.  * free what has been allocated by avcodec_thread_init().
  52.  * must be called after decoding has finished, especially dont call while avcodec_thread_execute() is running
  53.  */
  54. void avcodec_thread_free(AVCodecContext *s){
  55.     ThreadContext *c= s->thread_opaque;
  56.     int i;
  57.     for(i=0; i<s->thread_count; i++){
  58.         
  59.         c[i].func= NULL;
  60.         ReleaseSemaphore(c[i].work_sem, 1, 0);
  61.         WaitForSingleObject(c[i].thread, INFINITE);
  62.         if(c[i].work_sem) CloseHandle(c[i].work_sem);
  63.         if(c[i].done_sem) CloseHandle(c[i].done_sem);
  64.     }
  65.     av_freep(&s->thread_opaque);
  66. }
  67. int avcodec_thread_execute(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2),void **arg, int *ret, int count){
  68.     ThreadContext *c= s->thread_opaque;
  69.     int i;
  70.     
  71.     assert(s == c->avctx);
  72.     assert(count <= s->thread_count);
  73.     
  74.     /* note, we can be certain that this is not called with the same AVCodecContext by different threads at the same time */
  75.     for(i=0; i<count; i++){
  76.         c[i].arg= arg[i];
  77.         c[i].func= func;
  78.         c[i].ret= 12345;
  79.         ReleaseSemaphore(c[i].work_sem, 1, 0);
  80.     }
  81.     for(i=0; i<count; i++){
  82.         WaitForSingleObject(c[i].done_sem, INFINITE);
  83.         
  84.         c[i].func= NULL;
  85.         if(ret) ret[i]= c[i].ret;
  86.     }
  87.     return 0;
  88. }
  89. int avcodec_thread_init(AVCodecContext *s, int thread_count){
  90.     int i;
  91.     ThreadContext *c;
  92.     uint32_t threadid;
  93.     s->thread_count= thread_count;
  94.     assert(!s->thread_opaque);
  95.     c= av_mallocz(sizeof(ThreadContext)*thread_count);
  96.     s->thread_opaque= c;
  97.     
  98.     for(i=0; i<thread_count; i++){
  99. //printf("init semaphors %dn", i); fflush(stdout);
  100.         c[i].avctx= s;
  101.         if(!(c[i].work_sem = CreateSemaphore(NULL, 0, s->thread_count, NULL)))
  102.             goto fail;
  103.         if(!(c[i].done_sem = CreateSemaphore(NULL, 0, s->thread_count, NULL)))
  104.             goto fail;
  105. //printf("create thread %dn", i); fflush(stdout);
  106.         c[i].thread = (HANDLE)_beginthreadex(NULL, 0, thread_func, &c[i], 0, &threadid );
  107.         if( !c[i].thread ) goto fail;
  108.     }
  109. //printf("init donen"); fflush(stdout);
  110.     
  111.     s->execute= avcodec_thread_execute;
  112.     return 0;
  113. fail:
  114.     avcodec_thread_free(s);
  115.     return -1;
  116. }