| Linux kernel & device driver programming |
| [ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] |
1 /* gcc 2.95.x doesn't compile some c99 constru 1
2 #if __GNUC__ >= 3
3
4 #include "config.h"
5
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <pthread.h>
10 #include <fcntl.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <inttypes.h>
14 #include <sys/mman.h>
15
16 #include <libdv/dv.h>
17
18 #include "grab-ng.h"
19
20 /* -------------------------------------------
21
22 struct dv_handle {
23 /* handles */
24 int fd;
25 dv_decoder_t *dec;
26
27 /* mmap()ed data */
28 unsigned char *map_start;
29 unsigned char *map_ptr;
30 off_t map_size;
31 int map_frame;
32
33 /* format */
34 struct ng_video_fmt vfmt;
35 struct ng_audio_fmt afmt;
36
37 /* misc video */
38 int rate,vframe,frames;
39
40 /* misc audio */
41 int aframe,samples;
42 int16_t *audiobuf[4];
43 };
44
45 /* -------------------------------------------
46
47 static enum color_space_e fmtid_to_colorspace[
48 [ 0 ... VIDEO_FMT_COUNT-1 ] = UNSET,
49 [ VIDEO_YUYV ] = e_dv_color_yuv,
50 [ VIDEO_RGB24 ] = e_dv_color_rgb,
51 [ VIDEO_BGR32 ] = e_dv_color_bgr0,
52 };
53
54 /* -------------------------------------------
55
56 static void dv_unmap(struct dv_handle *h)
57 {
58 if (!h->map_ptr)
59 return;
60 munmap(h->map_start,h->map_size);
61 h->map_ptr = NULL;
62 }
63
64 static void dv_map(struct dv_handle *h, int fr
65 {
66 off_t map_offset;
67 off_t pgsize, size, offset;
68
69 size = h->dec->frame_size;
70 if (0 == size)
71 size = 120000; /* NTSC frame size */
72 offset = frame * size;
73
74 pgsize = getpagesize();
75 map_offset = offset & ~(pgsize-1);
76 h->map_size = offset - map_offset + size;
77 h->map_start = mmap(0, h->map_size, PROT_R
78 h->fd, map_offset);
79 if (MAP_FAILED == h->map_start) {
80 perror("mmap");
81 exit(1);
82 }
83 h->map_ptr = h->map_start + (offset - map_
84 }
85
86 static void dv_fmt(struct dv_handle *h, int *v
87 {
88 off_t len;
89 int i;
90
91 /* video format */
92 for (i = 0; i < vn; i++) {
93 if (ng_debug)
94 fprintf(stderr,"dv: trying: %d [%s
95 vfmt[i],ng_vfmt_to_desc[vf
96 if (UNSET == fmtid_to_colorspace[vfmt[
97 continue;
98 h->vfmt.fmtid = vfmt[i];
99 break;
100 }
101 h->vfmt.width = h->dec->width;
102 h->vfmt.height = h->dec->height;
103 h->vfmt.bytesperline = (h->vfmt.width*ng_v
104 h->rate = (e_dv_system_625_50
105
106 /* audio fmt */
107 if (1 == h->dec->audio->num_channels ||
108 2 == h->dec->audio->num_channels) {
109 h->afmt.fmtid = (16 == h->dec->audio->
110 AUDIO_S16_NATIVE_MONO : AUDIO_U8_M
111 if (2 == h->dec->audio->num_channels)
112 h->afmt.fmtid++;
113 }
114 h->afmt.rate = h->dec->audio->frequency;
115
116 /* movie length (# of frames) */
117 len = lseek(h->fd,0,SEEK_END);
118 h->frames = len / h->dec->frame_size;
119
120 if (ng_debug) {
121 fprintf(stderr,"dv: len=%lld => %d fra
122 len - (off_t)h->frames * h->de
123 fprintf(stderr,
124 "dv: quality=%d system=%d std=
125 "dv: height=%d width=%d frame_
126 h->dec->quality, h->dec->syste
127 h->dec->sampling, h->dec->num_
128 h->dec->width, h->dec->frame_s
129 fprintf(stderr, "dv: audio: %d Hz, %d
130 " emphasis %s\n",
131 h->dec->audio->frequency,
132 h->dec->audio->quantization,
133 h->dec->audio->num_channels,
134 (h->dec->audio->emphasis ? "on
135 }
136 }
137
138 /* -------------------------------------------
139
140 static void* dv_open(char *moviename)
141 {
142 struct dv_handle *h;
143
144 if (NULL == (h = malloc(sizeof(*h))))
145 goto oops;
146 memset(h,0,sizeof(*h));
147 h->map_frame = -1;
148
149 if (-1 == (h->fd = open(moviename,O_RDONLY
150 fprintf(stderr,"dv: open %s: %s\n",mov
151 goto oops;
152 }
153 if (NULL == (h->dec = dv_decoder_new(0,0,0
154 fprintf(stderr,"dv: dv_decoder_new fai
155 goto oops;
156 }
157 h->dec->quality = 3;
158
159 dv_map(h, 0);
160 if (dv_parse_header(h->dec, h->map_ptr) <
161 fprintf(stderr,"dv: dv_parse_header fa
162 goto oops;
163 }
164 dv_fmt(h,NULL,0);
165
166 return h;
167
168 oops:
169 if (h->dec)
170 dv_decoder_free(h->dec);
171 if (-1 != h->fd)
172 close(h->fd);
173 if (h)
174 free(h);
175 return NULL;
176 }
177
178 static struct ng_video_fmt* dv_vfmt(void *hand
179 {
180 struct dv_handle *h = handle;
181
182 dv_fmt(h,vfmt,vn);
183 return &h->vfmt;
184 }
185
186 static struct ng_audio_fmt* dv_afmt(void *hand
187 {
188 struct dv_handle *h = handle;
189
190 return h->afmt.fmtid ? &h->afmt : NULL;
191 }
192
193 static struct ng_video_buf* dv_vdata(void *han
194 {
195 struct dv_handle *h = handle;
196 struct ng_video_buf *buf;
197 unsigned char *pixels[3];
198 int pitches[3];
199
200 h->vframe += drop;
201 if (h->vframe >= h->frames)
202 return NULL;
203 if (ng_debug > 1)
204 fprintf(stderr,"dv: frame %d [drop=%d]
205
206 dv_unmap(h); dv_map(h, h->vframe);
207 if (dv_parse_header(h->dec, h->map_ptr) <
208 fprintf(stderr,"dv: dv_parse_header fa
209 return NULL;
210 }
211
212 buf = ng_malloc_video_buf(&h->vfmt,h->vfmt
213 switch (h->vfmt.fmtid) {
214 case VIDEO_YUYV:
215 pixels[0] = buf->data;
216 pitches[0] = buf->fmt.width*2;
217 break;
218 case VIDEO_RGB24:
219 pixels[0] = buf->data;
220 pitches[0] = buf->fmt.width*3;
221 break;
222 case VIDEO_BGR32:
223 pixels[0] = buf->data;
224 pitches[0] = buf->fmt.width*4;
225 break;
226 default:
227 BUG_ON(1,"unknown fmtid");
228 }
229
230 dv_parse_packs(h->dec, h->map_ptr);
231 dv_decode_full_frame(h->dec, h->map_ptr,
232 fmtid_to_colorspace[h
233 pixels, pitches);
234 buf->info.seq = h->vframe;
235 buf->info.ts = (long long) buf->info.seq
236 h->vframe++;
237 return buf;
238 }
239
240 static struct ng_audio_buf* dv_adata(void *han
241 {
242 struct dv_handle *h = handle;
243 struct ng_audio_buf *buf;
244 int16_t *dest;
245 int asize, i;
246
247 if (h->aframe >= h->frames)
248 return NULL;
249
250 dv_unmap(h); dv_map(h, h->aframe);
251 if (dv_parse_header(h->dec, h->map_ptr) <
252 fprintf(stderr,"dv: dv_parse_header fa
253 return NULL;
254 }
255
256 asize = h->dec->audio->samples_this_frame
257 h->dec->audio->num_channels *
258 h->dec->audio->quantization >> 3;
259 if (ng_debug > 1)
260 fprintf(stderr,"dv: audio %d [samples=
261 h->dec->audio->samples_this_fr
262
263 buf = ng_malloc_audio_buf(&h->afmt, asize
264 dest = (int16_t*)buf->data;
265 if (2 == h->dec->audio->num_channels) {
266 if (NULL == h->audiobuf[0])
267 for (i = 0; i < 4; i++)
268 h->audiobuf[i] = malloc(DV_AUD
269 dv_decode_full_audio(h->dec, h->map_pt
270 for (i = 0; i < h->dec->audio->samples
271 dest[2*i+0] = h->audiobuf[0][i];
272 dest[2*i+1] = h->audiobuf[1][i];
273 }
274 }
275 if (1 == h->dec->audio->num_channels)
276 dv_decode_full_audio(h->dec, h->map_pt
277
278 buf->info.ts = (long long) h->samples * 10
279 h->samples += h->dec->audio->samples_this_
280 h->aframe++;
281 return buf;
282 }
283
284 static int64_t dv_frame_time(void *handle)
285 {
286 struct dv_handle *h = handle;
287
288 return 1000000000 / h->rate;
289 }
290
291 static int dv_close(void *handle)
292 {
293 struct dv_handle *h = handle;
294 int i;
295
296 for (i = 0; i < 4; i++)
297 if (h->audiobuf[i])
298 free(h->audiobuf[i]);
299 dv_unmap(h);
300 dv_decoder_free(h->dec);
301 close(h->fd);
302 free(h);
303 return 0;
304 }
305
306 /* -------------------------------------------
307
308 struct ng_reader dv_reader = {
309 name: "dv",
310 desc: "Digital Video",
311
312 magic: { "\x1f\x07\x00", "\x3f\x07\x
313 moff: { 0, 0x50
314 mlen: { 3, 3
315
316 rd_open: dv_open,
317 rd_vfmt: dv_vfmt,
318 rd_afmt: dv_afmt,
319 rd_vdata: dv_vdata,
320 rd_adata: dv_adata,
321 frame_time: dv_frame_time,
322 rd_close: dv_close,
323 };
324
325 extern void ng_plugin_init(void);
326 void ng_plugin_init(void)
327 {
328 ng_reader_register(NG_PLUGIN_MAGIC,__FILE_
329 }
330
331 #else /* gcc3 */
332 extern void ng_plugin_init(void);
333 void ng_plugin_init(void) {}
334 #endif /* gcc3 */
335
| This page was automatically generated by the LXR engine. |