~ubuntu-branches/ubuntu/trusty/linphone/trusty

« back to all changes in this revision

Viewing changes to mediastreamer2/src/msfilerec_win.c

  • Committer: Package Import Robot
  • Author(s): Luk Claes
  • Date: 2013-09-11 19:08:43 UTC
  • mfrom: (1.1.19) (16.1.12 sid)
  • Revision ID: package-import@ubuntu.com-20130911190843-fkydjxsdvy1fmx24
Tags: 3.6.1-2.1
* Non-maintainer upload.
* Apply Sebastian Ramacher's patch to fix FTBFS (Closes: #720668).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
mediastreamer2 library - modular sound and video processing and streaming
3
 
Copyright (C) 2006  Simon MORLAT (simon.morlat@linphone.org)
4
 
 
5
 
This program is free software; you can redistribute it and/or
6
 
modify it under the terms of the GNU General Public License
7
 
as published by the Free Software Foundation; either version 2
8
 
of the License, or (at your option) any later version.
9
 
 
10
 
This program is distributed in the hope that it will be useful,
11
 
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
GNU General Public License for more details.
14
 
 
15
 
You should have received a copy of the GNU General Public License
16
 
along with this program; if not, write to the Free Software
17
 
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
 
*/
19
 
 
20
 
#define UNICODE
21
 
 
22
 
#include "mediastreamer2/msfilerec.h"
23
 
#include "mediastreamer2/waveheader.h"
24
 
 
25
 
#if !defined(_WIN32_WCE)
26
 
#include <sys/types.h>
27
 
#include <sys/stat.h>
28
 
#include <fcntl.h>
29
 
#endif
30
 
 
31
 
 
32
 
typedef enum{
33
 
        Closed,
34
 
        Stopped,
35
 
        Started
36
 
} State;
37
 
 
38
 
typedef struct RecState{
39
 
        HANDLE fd;
40
 
        int rate;
41
 
        int size;
42
 
        State state;
43
 
        char filename[256];
44
 
} RecState;
45
 
 
46
 
static void rec_init(MSFilter *f){
47
 
        RecState *s=(RecState *)ms_new(RecState,1);
48
 
        s->fd=INVALID_HANDLE_VALUE;
49
 
        s->rate=8000;
50
 
        s->size=0;
51
 
        s->state=Closed;
52
 
        f->data=s;
53
 
}
54
 
 
55
 
static void rec_process(MSFilter *f){
56
 
        RecState *s=(RecState*)f->data;
57
 
        mblk_t *m;
58
 
        int err;
59
 
        while((m=ms_queue_get(f->inputs[0]))!=NULL){
60
 
                mblk_t *it=m;
61
 
                ms_mutex_lock(&f->lock);
62
 
                if (s->state==Started){
63
 
                        while(it!=NULL){
64
 
                                int len=it->b_wptr-it->b_rptr;
65
 
                            DWORD byte_written=0;
66
 
                                if ((err=WriteFile(s->fd,it->b_rptr,len, &byte_written, NULL))!=len){
67
 
                                        if (err<0)
68
 
                                        {
69
 
#if !defined(_WIN32_WCE)
70
 
                                                ms_warning("MSFileRec: fail to write %i bytes: %s",len,strerror(errno));
71
 
#else
72
 
                                                ms_warning("MSFileRec: fail to write %i bytes: %i",len,WSAGetLastError());
73
 
#endif
74
 
                                        }
75
 
                                }
76
 
                                it=it->b_cont;
77
 
                                s->size+=len;
78
 
                        }
79
 
                }
80
 
                ms_mutex_unlock(&f->lock);
81
 
                freemsg(m);
82
 
        }
83
 
}
84
 
 
85
 
static void write_wav_header(int rate,int size, char *filename){
86
 
        wave_header_t header;
87
 
        DWORD bytes_written=0;
88
 
        HANDLE fd;
89
 
        WCHAR wUnicode[1024];
90
 
        MultiByteToWideChar(CP_UTF8, 0, filename, -1, wUnicode, 1024);
91
 
 
92
 
        memcpy(&header.riff_chunk.riff,"RIFF",4);
93
 
        header.riff_chunk.len=le_uint32(size+32);
94
 
        memcpy(&header.riff_chunk.wave,"WAVE",4);
95
 
 
96
 
        memcpy(&header.format_chunk.fmt,"fmt ",4);
97
 
        header.format_chunk.len=le_uint32(0x10);
98
 
        header.format_chunk.type=le_uint16(0x1);
99
 
        header.format_chunk.channel=le_uint16(0x1);
100
 
        header.format_chunk.rate=le_uint32(rate);
101
 
        header.format_chunk.bps=le_uint32(rate*2);
102
 
        header.format_chunk.blockalign=le_uint16(2);
103
 
        header.format_chunk.bitpspl=le_uint16(16);
104
 
 
105
 
        memcpy(&header.data_chunk.data,"data",4);
106
 
        header.data_chunk.len=le_uint32(size);
107
 
 
108
 
        /* TODO: replace with "lseek" equivalent for windows */
109
 
        fd=CreateFile(wUnicode, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
110
 
        if (fd==INVALID_HANDLE_VALUE){
111
 
#if !defined(_WIN32_WCE)
112
 
                ms_warning("Cannot open %s: %s",filename,strerror(errno));
113
 
#else
114
 
                ms_warning("Cannot open %s: %i",filename,WSAGetLastError());
115
 
#endif
116
 
                return;
117
 
        }
118
 
        WriteFile(fd,&header,sizeof(header), &bytes_written, NULL);
119
 
        if (bytes_written!=sizeof(header)){
120
 
                ms_warning("Fail to write wav header.");
121
 
        }
122
 
        CloseHandle(fd);
123
 
}
124
 
 
125
 
static int rec_open(MSFilter *f, void *arg){
126
 
        wave_header_t header;
127
 
        DWORD bytes_written=0;
128
 
 
129
 
        RecState *s=(RecState*)f->data;
130
 
        const char *filename=(const char*)arg;
131
 
        WCHAR wUnicode[1024];
132
 
        MultiByteToWideChar(CP_UTF8, 0, filename, -1, wUnicode, 1024);
133
 
 
134
 
        ms_mutex_lock(&f->lock);
135
 
        snprintf(s->filename, sizeof(s->filename), "%s", filename);
136
 
        s->fd=CreateFile(wUnicode, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
137
 
        if (s->fd==INVALID_HANDLE_VALUE){
138
 
#if !defined(_WIN32_WCE)
139
 
                ms_warning("Cannot open %s: %s",filename,strerror(errno));
140
 
#else
141
 
                ms_warning("Cannot open %s: %i",filename,WSAGetLastError());
142
 
#endif
143
 
                ms_mutex_unlock(&f->lock);
144
 
                return -1;
145
 
        }
146
 
 
147
 
        memset(&header ,0,sizeof(header));
148
 
        WriteFile(s->fd,&header,sizeof(header), &bytes_written, NULL);
149
 
        if (bytes_written!=sizeof(header)){
150
 
                ms_warning("Fail to write wav header.");
151
 
        }
152
 
 
153
 
        s->state=Stopped;
154
 
        ms_mutex_unlock(&f->lock);
155
 
        return 0;
156
 
}
157
 
 
158
 
static int rec_start(MSFilter *f, void *arg){
159
 
        RecState *s=(RecState*)f->data;
160
 
        ms_mutex_lock(&f->lock);
161
 
        s->state=Started;
162
 
        ms_mutex_unlock(&f->lock);
163
 
        return 0;
164
 
}
165
 
 
166
 
static int rec_stop(MSFilter *f, void *arg){
167
 
        RecState *s=(RecState*)f->data;
168
 
        ms_mutex_lock(&f->lock);
169
 
        s->state=Stopped;
170
 
        ms_mutex_unlock(&f->lock);
171
 
        return 0;
172
 
}
173
 
 
174
 
static int rec_close(MSFilter *f, void *arg){
175
 
        RecState *s=(RecState*)f->data;
176
 
        ms_mutex_lock(&f->lock);
177
 
        s->state=Closed;
178
 
        if (s->fd!=INVALID_HANDLE_VALUE) {
179
 
                CloseHandle(s->fd);
180
 
                write_wav_header(s->rate, s->size, s->filename);
181
 
                s->fd=INVALID_HANDLE_VALUE;
182
 
                s->size=0;
183
 
        }
184
 
        ms_mutex_unlock(&f->lock);
185
 
        return 0;
186
 
}
187
 
 
188
 
static int rec_set_sr(MSFilter *f, void *arg){
189
 
        RecState *s=(RecState*)f->data;
190
 
        ms_mutex_lock(&f->lock);
191
 
        s->rate=*((int*)arg);
192
 
        ms_mutex_unlock(&f->lock);
193
 
        return 0;
194
 
}
195
 
 
196
 
static void rec_uninit(MSFilter *f){
197
 
        RecState *s=(RecState*)f->data;
198
 
        if (s->fd!=INVALID_HANDLE_VALUE)        rec_close(f,NULL);
199
 
        ms_free(s);
200
 
}
201
 
 
202
 
static MSFilterMethod rec_methods[]={
203
 
        {       MS_FILTER_SET_SAMPLE_RATE,      rec_set_sr      },
204
 
        {       MS_FILE_REC_OPEN        ,       rec_open        },
205
 
        {       MS_FILE_REC_START       ,       rec_start       },
206
 
        {       MS_FILE_REC_STOP        ,       rec_stop        },
207
 
        {       MS_FILE_REC_CLOSE       ,       rec_close       },
208
 
        {       0                       ,       NULL            }
209
 
};
210
 
 
211
 
#ifdef WIN32
212
 
 
213
 
MSFilterDesc ms_file_rec_desc={
214
 
        MS_FILE_REC_ID,
215
 
        "MSFileRec",
216
 
        N_("Wav file recorder"),
217
 
        MS_FILTER_OTHER,
218
 
        NULL,
219
 
    1,
220
 
        0,
221
 
        rec_init,
222
 
        NULL,
223
 
    rec_process,
224
 
        NULL,
225
 
    rec_uninit,
226
 
        rec_methods
227
 
};
228
 
 
229
 
#else
230
 
 
231
 
MSFilterDesc ms_file_rec_desc={
232
 
        .id=MS_FILE_REC_ID,
233
 
        .name="MSFileRec",
234
 
        .text=N_("Wav file recorder"),
235
 
        .category=MS_FILTER_OTHER,
236
 
        .ninputs=1,
237
 
        .noutputs=0,
238
 
        .init=rec_init,
239
 
        .process=rec_process,
240
 
        .uninit=rec_uninit,
241
 
        .methods=rec_methods
242
 
};
243
 
 
244
 
#endif
245
 
 
246
 
MS_FILTER_DESC_EXPORT(ms_file_rec_desc)