Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 #include "config.h"
  2 
  3 #include <stdlib.h>
  4 #include <stdio.h>
  5 #include <string.h>
  6 #include <pthread.h>
  7 #include <quicktime/quicktime.h>
  8 #include <quicktime/colormodels.h>
  9 #include <quicktime/lqt.h>
 10 
 11 #include "grab-ng.h"
 12 
 13 #define AUDIO_SIZE (64*1024)
 14 
 15 /* ----------------------------------------------------------------------- */
 16 
 17 static int fmtid_to_cmodel[VIDEO_FMT_COUNT] = {
 18     [ VIDEO_RGB24    ] = BC_RGB888,
 19     [ VIDEO_BGR24    ] = BC_BGR888,
 20     [ VIDEO_YUYV     ] = BC_YUV422,
 21     [ VIDEO_YUV420P  ] = BC_YUV420P,
 22 };
 23 
 24 /* ----------------------------------------------------------------------- */
 25 
 26 struct qt_handle {
 27     /* libquicktime handle */
 28     quicktime_t *qt;
 29 
 30     /* format */
 31     struct ng_video_fmt vfmt;
 32     struct ng_audio_fmt afmt;
 33 
 34     /* misc video */
 35     unsigned char **rows;
 36     int rate;
 37 
 38     /* misc audio */
 39     int channels;
 40     int16_t *left,*right;
 41     long long bps;
 42 };
 43 
 44 static void* qt_open(char *moviename)
 45 {
 46     struct qt_handle *h;
 47     char *str;
 48     int i;
 49 
 50     if (NULL == (h = malloc(sizeof(*h))))
 51         return NULL;
 52     memset(h,0,sizeof(*h));
 53 
 54     /* open file */
 55     h->qt = quicktime_open(moviename,1,0);
 56     if (NULL == h->qt) {
 57         fprintf(stderr,"ERROR: can't open file: %s\n",moviename);
 58         free(h);
 59         return NULL;
 60     }
 61 
 62     if (ng_debug) {
 63         /* print misc info */
 64         fprintf(stderr,"quicktime movie %s:\n",moviename);
 65         str = quicktime_get_copyright(h->qt);
 66         if (str)
 67             fprintf(stderr,"  copyright: %s\n",str);
 68         str = quicktime_get_name(h->qt);
 69         if (str)
 70             fprintf(stderr,"  name: %s\n",str);
 71         str = quicktime_get_info(h->qt);
 72         if (str)
 73             fprintf(stderr,"  info: %s\n",str);
 74         
 75         /* print video info */
 76         if (quicktime_has_video(h->qt)) {
 77             fprintf(stderr,"  video: %d track(s)\n",quicktime_video_tracks(h->qt));
 78             for (i = 0; i < quicktime_video_tracks(h->qt); i++) {
 79                 fprintf(stderr,
 80                         "    track #%d\n"
 81                         "      width : %d\n"
 82                         "      height: %d\n"
 83                         "      depth : %d bit\n"
 84                         "      rate  : %.2f fps\n"
 85                         "      codec : %s\n",
 86                         i+1,
 87                         quicktime_video_width(h->qt,i),
 88                         quicktime_video_height(h->qt,i),
 89                         quicktime_video_depth(h->qt,i),
 90                         quicktime_frame_rate(h->qt,i),
 91                         quicktime_video_compressor(h->qt,i));
 92             }
 93         }
 94         
 95         /* print audio info */
 96         if (quicktime_has_audio(h->qt)) {
 97             fprintf(stderr,"  audio: %d track(s)\n",quicktime_audio_tracks(h->qt));
 98             for (i = 0; i < quicktime_audio_tracks(h->qt); i++) {
 99                 fprintf(stderr,
100                         "    track #%d\n"
101                         "      rate  : %ld Hz\n"
102                         "      bits  : %d\n"
103                         "      chans : %d\n"
104                         "      codec : %s\n",
105                         i+1,
106                         quicktime_sample_rate(h->qt,i),
107                         quicktime_audio_bits(h->qt,i),
108                         quicktime_track_channels(h->qt,i),
109                         quicktime_audio_compressor(h->qt,i));
110             }
111         }
112     }
113 
114     /* video format */
115     if (!quicktime_has_video(h->qt)) {
116         if (ng_debug)
117             fprintf(stderr,"qt: no video stream\n");
118     } else if (!quicktime_supported_video(h->qt,0)) {
119         if (ng_debug)
120             fprintf(stderr,"qt: unsupported video codec\n");
121     } else {
122         h->vfmt.width  = quicktime_video_width(h->qt,0);
123         h->vfmt.height = quicktime_video_height(h->qt,0);
124         h->rate = quicktime_frame_rate(h->qt,0);
125     }
126 
127     /* audio format */
128     if (!quicktime_has_audio(h->qt)) {
129         if (ng_debug)
130             fprintf(stderr,"qt: no audio stream\n");
131     } else if (!quicktime_supported_audio(h->qt,0)) {
132         if (ng_debug)
133             fprintf(stderr,"qt: unsupported audio codec\n");
134     } else {
135         h->channels   = quicktime_track_channels(h->qt,0);
136         h->afmt.fmtid = (h->channels > 1) ?
137             AUDIO_S16_NATIVE_STEREO : AUDIO_S16_NATIVE_MONO;
138         h->afmt.rate = quicktime_sample_rate(h->qt,0);
139     }
140 
141     return h;
142 }
143 
144 static struct ng_video_fmt* qt_vfmt(void *handle, int *vfmt, int vn)
145 {
146     struct qt_handle *h = handle;
147     int i;
148 
149     for (i = 0; i < vn; i++) {
150         if (ng_debug)
151             fprintf(stderr,"qt: trying: %d [%s]\n",
152                     vfmt[i],ng_vfmt_to_desc[vfmt[i]]);
153         if (0 == fmtid_to_cmodel[vfmt[i]])
154             continue;
155         if (!quicktime_reads_cmodel(h->qt,fmtid_to_cmodel[vfmt[i]],0))
156             continue;
157         quicktime_set_cmodel(h->qt, fmtid_to_cmodel[vfmt[i]]);
158         h->vfmt.fmtid = vfmt[i];
159         break;
160     }
161     h->vfmt.bytesperline = (h->vfmt.width*ng_vfmt_to_depth[h->vfmt.fmtid]) >> 3;
162     return &h->vfmt;
163 }
164 
165 static struct ng_audio_fmt* qt_afmt(void *handle)
166 {
167     struct qt_handle *h = handle;
168 
169     return h->afmt.fmtid ? &h->afmt : NULL;
170 }
171 
172 static struct ng_video_buf* qt_vdata(void *handle, unsigned int drop)
173 {
174     struct qt_handle *h = handle;
175     struct ng_video_buf *buf;
176     unsigned int i;
177     
178     if (quicktime_video_position(h->qt,0) >= quicktime_video_length(h->qt,0))
179         return NULL;
180 
181     buf = ng_malloc_video_buf(&h->vfmt,h->vfmt.bytesperline*h->vfmt.height);
182     if (!h->rows)
183         h->rows = malloc(h->vfmt.height * sizeof(char*));
184     switch (fmtid_to_cmodel[h->vfmt.fmtid]) {
185     case BC_RGB888:
186     case BC_BGR888:
187         for (i = 0; i < h->vfmt.height; i++)
188             h->rows[i] = buf->data + h->vfmt.width * 3 * i;
189         break;
190     case BC_YUV422:
191         for (i = 0; i < h->vfmt.height; i++)
192             h->rows[i] = buf->data+ h->vfmt.width * 2 * i;
193         break;
194     case BC_YUV420P:
195         h->rows[0] = buf->data;
196         h->rows[1] = buf->data + h->vfmt.width*h->vfmt.height;
197         h->rows[2] = buf->data + h->vfmt.width*h->vfmt.height*5/4;
198         break;
199     default:
200         BUG_ON(1,"unknown cmodel");
201     }
202 
203     /* drop frames */
204     for (i = 0; i < drop; i++)
205         quicktime_read_frame(h->qt,buf->data,0);
206         
207     buf->info.seq  = quicktime_video_position(h->qt,0);
208     buf->info.ts   = (long long) buf->info.seq * 1000000000 / h->rate;
209     lqt_decode_video(h->qt, h->rows, 0);
210     return buf;
211 }
212 
213 static struct ng_audio_buf* qt_adata(void *handle)
214 {
215     struct qt_handle *h = handle;
216     struct ng_audio_buf *buf;
217     int16_t *dest;
218     long pos;
219     int i;
220     
221     if (quicktime_audio_position(h->qt,0) >= quicktime_audio_length(h->qt,0))
222         return NULL;
223 
224     buf = ng_malloc_audio_buf(&h->afmt,AUDIO_SIZE);
225     dest = (int16_t*)buf->data;
226 
227     pos = quicktime_audio_position(h->qt,0);
228     buf->info.ts = (long long) pos * 1000000000 / h->afmt.rate;
229     if (h->channels > 1) {
230         /* stereo: two channels => interlaved samples */
231         if (!h->left)
232             h->left = malloc(AUDIO_SIZE/2);
233         if (!h->right)
234             h->right = malloc(AUDIO_SIZE/2);
235         quicktime_set_audio_position(h->qt,pos,0);
236         quicktime_decode_audio(h->qt,h->left,NULL,AUDIO_SIZE/4,0);
237         quicktime_set_audio_position(h->qt,pos,1);
238         quicktime_decode_audio(h->qt,h->right,NULL,AUDIO_SIZE/4,1);
239         for (i = 0; i < AUDIO_SIZE/4; i++) {
240             dest[2*i+0] = h->left[i];
241             dest[2*i+1] = h->right[i];
242         }
243     } else {
244         /* mono */
245         quicktime_decode_audio(h->qt,dest,NULL,AUDIO_SIZE/2,0);
246     }
247     return buf;
248 }
249 
250 static int64_t qt_frame_time(void *handle)
251 {
252     struct qt_handle *h = handle;
253 
254     return 1000000000 / h->rate;
255 }
256 
257 static int qt_close(void *handle)
258 {
259     struct qt_handle *h = handle;
260 
261     quicktime_close(h->qt);
262     if (h->rows)
263         free(h->rows);
264     free(h);
265     return 0;
266 }
267 
268 /* ----------------------------------------------------------------------- */
269 
270 struct ng_reader qt_reader = {
271     name:       "qt",
272     desc:       "Apple QuickTime format",
273 
274     magic:      { "moov", "mdat" },
275     moff:       {  4,      4     },
276     mlen:       {  4,      4     },
277     
278     rd_open:    qt_open,
279     rd_vfmt:    qt_vfmt,
280     rd_afmt:    qt_afmt,
281     rd_vdata:   qt_vdata,
282     rd_adata:   qt_adata,
283     frame_time: qt_frame_time,
284     rd_close:   qt_close,
285 };
286 
287 extern void ng_plugin_init(void);
288 void ng_plugin_init(void)
289 {
290     ng_reader_register(NG_PLUGIN_MAGIC,__FILE__,&qt_reader);
291 }
292 
  This page was automatically generated by the LXR engine.