Statistics
| Branch: | Revision:

ffmpeg / libavcodec / os2thread.c @ 94d85eaf

History | View | Annotate | Download (4.26 KB)

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

    
21
// Ported by Vlad Stelmahovsky
22

    
23
#include "avcodec.h"
24
#include "common.h"
25

    
26
#ifdef HAVE_THREADS
27

    
28
#define INCL_DOS
29
#define INCL_DOSERRORS
30
#define INCL_DOSDEVIOCTL
31
#include <os2.h>
32

    
33
typedef struct ThreadContext{
34
    AVCodecContext *avctx;
35
    int thread;
36
    HEV work_sem;
37
    HEV done_sem;
38
    int (*func)(AVCodecContext *c, void *arg);
39
    void *arg;
40
    int ret;
41
}ThreadContext;
42

    
43

    
44
void thread_func(void *v){
45
    ThreadContext *c= v;
46

    
47
    for(;;){
48
        //printf("thread_func %X enter wait\n", (int)v); fflush(stdout);
49
        DosWaitEventSem(c->work_sem, SEM_INDEFINITE_WAIT);
50
//        WaitForSingleObject(c->work_sem, INFINITE);
51
//printf("thread_func %X after wait (func=%X)\n", (int)v, (int)c->func); fflush(stdout);
52
        if(c->func)
53
            c->ret= c->func(c->avctx, c->arg);
54
        else
55
            return;
56
        //printf("thread_func %X signal complete\n", (int)v); fflush(stdout);
57
        DosPostEventSem(c->done_sem);
58
//        ReleaseSemaphore(c->done_sem, 1, 0);
59
    }
60

    
61
    return;
62
}
63

    
64
/**
65
 * free what has been allocated by avcodec_thread_init().
66
 * must be called after decoding has finished, especially dont call while avcodec_thread_execute() is running
67
 */
68
void avcodec_thread_free(AVCodecContext *s){
69
    ThreadContext *c= s->thread_opaque;
70
    int i;
71

    
72
    for(i=0; i<s->thread_count; i++){
73

    
74
        c[i].func= NULL;
75
        DosPostEventSem(c[i].work_sem);
76
        //        ReleaseSemaphore(c[i].work_sem, 1, 0);
77
        DosWaitThread((PTID)&c[i].thread,DCWW_WAIT);
78
//        WaitForSingleObject(c[i].thread, INFINITE);
79
        if(c[i].work_sem) DosCloseEventSem(c[i].work_sem);//CloseHandle(c[i].work_sem);
80
        if(c[i].done_sem) DosCloseEventSem(c[i].done_sem);//CloseHandle(c[i].done_sem);
81
    }
82

    
83
    av_freep(&s->thread_opaque);
84
}
85

    
86
int avcodec_thread_execute(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2),void **arg, int *ret, int count){
87
    ThreadContext *c= s->thread_opaque;
88
    int i;
89

    
90
    assert(s == c->avctx);
91
    assert(count <= s->thread_count);
92

    
93
    /* note, we can be certain that this is not called with the same AVCodecContext by different threads at the same time */
94

    
95
    for(i=0; i<count; i++){
96

    
97
        c[i].arg= arg[i];
98
        c[i].func= func;
99
        c[i].ret= 12345;
100

    
101
        DosPostEventSem(c[i].work_sem);
102
//        ReleaseSemaphore(c[i].work_sem, 1, 0);
103
    }
104
    for(i=0; i<count; i++){
105
        DosWaitEventSem(c[i].done_sem,SEM_INDEFINITE_WAIT);
106
//        WaitForSingleObject(c[i].done_sem, INFINITE);
107

    
108
        c[i].func= NULL;
109
        if(ret) ret[i]= c[i].ret;
110
    }
111
    return 0;
112
}
113

    
114
int avcodec_thread_init(AVCodecContext *s, int thread_count){
115
    int i;
116
    ThreadContext *c;
117
    uint32_t threadid;
118

    
119
    s->thread_count= thread_count;
120

    
121
    assert(!s->thread_opaque);
122
    c= av_mallocz(sizeof(ThreadContext)*thread_count);
123
    s->thread_opaque= c;
124

    
125
    for(i=0; i<thread_count; i++){
126
//printf("init semaphors %d\n", i); fflush(stdout);
127
        c[i].avctx= s;
128

    
129
        if (DosCreateEventSem(NULL,&c[i].work_sem,DC_SEM_SHARED,0))
130
            goto fail;
131
        if (DosCreateEventSem(NULL,&c[i].done_sem,DC_SEM_SHARED,0))
132
            goto fail;
133

    
134
//printf("create thread %d\n", i); fflush(stdout);
135
//        c[i].thread = (HANDLE)_beginthreadex(NULL, 0, thread_func, &c[i], 0, &threadid );
136
        c[i].thread = _beginthread(thread_func, NULL, 0x10000, &c[i]);
137
        if( c[i].thread <= 0 ) goto fail;
138
    }
139
//printf("init done\n"); fflush(stdout);
140

    
141
    s->execute= avcodec_thread_execute;
142

    
143
    return 0;
144
fail:
145
    avcodec_thread_free(s);
146
    return -1;
147
}
148
#endif