~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to ffmpeg/libavcodec/os2thread.c

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-25 15:47:12 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080225154712-qvr11ekcea4c9ry8
Tags: 1.1.6-0.1ubuntu1
* Merge from debian-multimedia (LP: #120003), Ubuntu Changes:
 - For ffmpeg-related build-deps, remove cvs from package names.
 - Standards-Version 3.7.3
 - Maintainer Spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
 
3
 *
 
4
 * This file is part of FFmpeg.
 
5
 *
 
6
 * FFmpeg is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU Lesser General Public
 
8
 * License as published by the Free Software Foundation; either
 
9
 * version 2.1 of the License, or (at your option) any later version.
 
10
 *
 
11
 * FFmpeg is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * Lesser General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public
 
17
 * License along with FFmpeg; if not, write to the Free Software
 
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
19
 *
 
20
 */
 
21
//#define DEBUG
 
22
 
 
23
// Ported by Vlad Stelmahovsky
 
24
 
 
25
#include "avcodec.h"
 
26
#include "common.h"
 
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
}