1 #include "config.h"
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <unistd.h>
8 #include <fcntl.h>
9 #include <pthread.h>
10
11 #include <libdv/dv.h>
12
13 #include "grab-ng.h"
14 #include "list.h"
15
16 /* ----------------------------------------------------------------------- */
17
18 struct dv_frame {
19 struct list_head list;
20 int seq;
21 int video,audio;
22 unsigned char obuf[0];
23 };
24
25 struct dv_handle {
26 /* handles */
27 int fd;
28 dv_encoder_t *enc;
29
30 /* format */
31 struct ng_video_fmt video;
32 struct ng_audio_fmt audio;
33
34 /* misc */
35 int framesize, fvideo, faudio;
36 struct list_head frames;
37 };
38
39 /* ----------------------------------------------------------------------- */
40
41 static struct dv_frame*
42 dv_get_frame(struct dv_handle *h, int nr)
43 {
44 struct dv_frame *frame = NULL;
45 struct list_head *item;
46
47 list_for_each(item,&h->frames) {
48 frame = list_entry(item,struct dv_frame,list);
49 if (frame->seq == nr)
50 break;
51 }
52 if (NULL == frame || frame->seq != nr) {
53 frame = malloc(sizeof(*frame) + h->framesize);
54 memset(frame,0,sizeof(*frame) + h->framesize);
55 frame->seq = nr;
56 list_add_tail(&frame->list,&h->frames);
57 }
58 return frame;
59 }
60
61 static int dv_put_frame(struct dv_handle *h, struct dv_frame *frame)
62 {
63 int rc;
64
65 if (h->video.fmtid && !frame->video)
66 return 0;
67 if (h->audio.fmtid && !frame->audio)
68 return 0;
69
70 if (ng_debug)
71 fprintf(stderr,"dv: write frame #%d\n",frame->seq);
72 rc = write(h->fd, frame->obuf, h->framesize);
73 list_del(&frame->list);
74 free(frame);
75 return (rc == h->framesize) ? 0 : -1;
76 }
77
78 /* ----------------------------------------------------------------------- */
79
80 static void*
81 dv_open(char *filename, char *dummy,
82 struct ng_video_fmt *video, const void *priv_video, int fps,
83 struct ng_audio_fmt *audio, const void *priv_audio)
84 {
85 struct dv_handle *h;
86
87 if (NULL == (h = malloc(sizeof(*h))))
88 return NULL;
89
90 memset(h,0,sizeof(*h));
91 h->video = *video;
92 h->audio = *audio;
93
94 if (-1 == (h->fd = open(filename,O_CREAT | O_RDWR | O_TRUNC, 0666))) {
95 fprintf(stderr,"open %s: %s\n",filename,strerror(errno));
96 goto fail;
97 }
98 h->enc = dv_encoder_new(0,0,0);
99 if (NULL == h->enc) {
100 fprintf(stderr,"dv: dv_encoder_new failed\n");
101 goto fail;
102 }
103
104 if (h->audio.fmtid != AUDIO_NONE) {
105 }
106 if (h->video.fmtid != VIDEO_NONE) {
107 if (720 == h->video.width &&
108 480 == h->video.height &&
109 30000 == fps) {
110 /* NTSC */
111 h->enc->isPAL = 0;
112 h->framesize = 120000;
113 } else if (720 == h->video.width &&
114 576 == h->video.height &&
115 25000 == fps) {
116 /* PAL */
117 h->enc->isPAL = 1;
118 h->framesize = 144000;
119 } else {
120 fprintf(stderr,
121 "dv: %dx%d @ %d fps is not allowed for digital video\n"
122 "dv: use 720x480/30 (NTSC) or 720x576/25 (PAL)\n",
123 h->video.width, h->video.height, fps/1000);
124 goto fail;
125 }
126 }
127 INIT_LIST_HEAD(&h->frames);
128 return h;
129
130 fail:
131 if (h->enc)
132 dv_encoder_free(h->enc);
133 if (-1 != h->fd)
134 close(h->fd);
135 free(h);
136 return NULL;
137 }
138
139 static int
140 dv_video(void *handle, struct ng_video_buf *buf)
141 {
142 struct dv_handle *h = handle;
143 struct dv_frame *frame;
144 unsigned char *pixels[3];
145
146 frame = dv_get_frame(h,h->fvideo);
147 pixels[0] = buf->data;
148 switch (buf->fmt.fmtid) {
149 case VIDEO_YUYV:
150 dv_encode_full_frame(h->enc,pixels,e_dv_color_yuv,frame->obuf);
151 break;
152 case VIDEO_RGB24:
153 dv_encode_full_frame(h->enc,pixels,e_dv_color_rgb,frame->obuf);
154 break;
155 case VIDEO_BGR32:
156 dv_encode_full_frame(h->enc,pixels,e_dv_color_bgr0,frame->obuf);
157 break;
158 default:
159 BUG_ON(1,"unknown fmtid");
160 }
161 frame->video = 1;
162 dv_put_frame(h,frame);
163 h->fvideo++;
164 return 0;
165 }
166
167 static int
168 dv_audio(void *handle, struct ng_audio_buf *buf)
169 {
170 //struct dv_handle *h = handle;
171 //struct dv_frame *frame;
172
173 return -1;
174 }
175
176 static int
177 dv_close(void *handle)
178 {
179 struct dv_handle *h = handle;
180
181 dv_encoder_free(h->enc);
182 close(h->fd);
183 free(h);
184 return 0;
185 }
186
187 /* ----------------------------------------------------------------------- */
188
189 static const struct ng_format_list dv_vformats[] = {
190 {
191 name: "dv",
192 ext: "dv",
193 desc: "digital video",
194 fmtid: VIDEO_YUYV,
195 },{
196 /* EOF */
197 }
198 };
199
200 static const struct ng_format_list dv_aformats[] = {
201 {
202 name: "stereo16",
203 ext: "dv",
204 fmtid: AUDIO_S16_NATIVE_STEREO,
205 },{
206 /* EOF */
207 }
208 };
209
210 struct ng_writer dv_writer = {
211 name: "dv",
212 desc: "Digital Video",
213 //combined: 1,
214 video: dv_vformats,
215 //audio: dv_aformats,
216 wr_open: dv_open,
217 wr_video: dv_video,
218 wr_audio: dv_audio,
219 wr_close: dv_close,
220 };
221
222 extern void ng_plugin_init(void);
223 void ng_plugin_init(void)
224 {
225 //ng_writer_register(NG_PLUGIN_MAGIC,__FILE__,&dv_writer);
226 }
227
|
This page was automatically generated by the
LXR engine.
|