1 /*
2  * 1394-Based Digital Camera Control Library
3  *
4  * Internal functions
5  *
6  * Written by Damien Douxchamps <ddouxchamps@users.sf.net>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22 
23 #include "internal.h"
24 #include "utils.h"
25 #include "log.h"
26 #include "register.h"
27 
28 /*
29   These arrays define how many image quadlets there
30   are in a packet given a mode and a frame rate
31   This is defined in the 1394 digital camera spec
32 */
33 const int quadlets_per_packet_format_0[56] = {
34     -1,  -1,  15,  30,  60,  120,  240,  480,
35     10,  20,  40,  80, 160,  320,  640, 1280,
36     30,  60, 120, 240, 480,  960, 1920, 3840,
37     40,  80, 160, 320, 640, 1280, 2560, 5120,
38     60, 120, 240, 480, 960, 1920, 3840, 7680,
39     20,  40,  80, 160, 320,  640, 1280, 2560,
40     40,  80, 160, 320, 640, 1280, 2560, 5120
41 };
42 
43 const int quadlets_per_packet_format_1[64] =  {
44     -1, 125, 250,  500, 1000, 2000, 4000, 8000,
45     -1,  -1, 375,  750, 1500, 3000, 6000,   -1,
46     -1,  -1, 125,  250,  500, 1000, 2000, 4000,
47     96, 192, 384,  768, 1536, 3072, 6144,   -1,
48     144, 288, 576, 1152, 2304, 4608,   -1,   -1,
49     48,  96, 192,  384,  768, 1536, 3073, 6144,
50     -1, 125, 250,  500, 1000, 2000, 4000, 8000,
51     96, 192, 384,  768, 1536, 3072, 6144,   -1
52 };
53 
54 const int quadlets_per_packet_format_2[64] =  {
55     160, 320,  640, 1280, 2560, 5120,   -1, -1,
56     240, 480,  960, 1920, 3840, 7680,   -1, -1,
57     80, 160,  320,  640, 1280, 2560, 5120, -1,
58     250, 500, 1000, 2000, 4000, 8000,   -1, -1,
59     375, 750, 1500, 3000, 6000,   -1,   -1, -1,
60     125, 250,  500, 1000, 2000, 4000, 8000, -1,
61     160, 320,  640, 1280, 2560, 5120,   -1, -1,
62     250, 500, 1000, 2000, 4000, 8000,   -1, -1
63 };
64 
65 /********************************************************
66  get_quadlets_per_packet
67 
68  This routine reports the number of useful image quadlets
69  per packet
70 *********************************************************/
71 dc1394error_t
get_quadlets_per_packet(dc1394video_mode_t mode,dc1394framerate_t frame_rate,uint32_t * qpp)72 get_quadlets_per_packet(dc1394video_mode_t mode, dc1394framerate_t frame_rate, uint32_t *qpp) // ERROR handling to be updated
73 {
74     uint32_t mode_index;
75     uint32_t frame_rate_index= frame_rate - DC1394_FRAMERATE_MIN;
76     uint32_t format;
77     dc1394error_t err;
78 
79     err=get_format_from_mode(mode, &format);
80     DC1394_ERR_RTN(err,"Invalid mode ID");
81 
82     switch(format) {
83     case DC1394_FORMAT0:
84         mode_index= mode - DC1394_VIDEO_MODE_FORMAT0_MIN;
85 
86         if ( ((mode >= DC1394_VIDEO_MODE_FORMAT0_MIN) && (mode <= DC1394_VIDEO_MODE_FORMAT0_MAX)) &&
87              ((frame_rate >= DC1394_FRAMERATE_MIN) && (frame_rate <= DC1394_FRAMERATE_MAX)) ) {
88             *qpp=quadlets_per_packet_format_0[DC1394_FRAMERATE_NUM*mode_index+frame_rate_index];
89         }
90         else {
91             err=DC1394_INVALID_VIDEO_MODE;
92             DC1394_ERR_RTN(err,"Invalid framerate or mode");
93         }
94         return DC1394_SUCCESS;
95     case DC1394_FORMAT1:
96         mode_index= mode - DC1394_VIDEO_MODE_FORMAT1_MIN;
97 
98         if ( ((mode >= DC1394_VIDEO_MODE_FORMAT1_MIN) && (mode <= DC1394_VIDEO_MODE_FORMAT1_MAX)) &&
99              ((frame_rate >= DC1394_FRAMERATE_MIN) && (frame_rate <= DC1394_FRAMERATE_MAX)) ) {
100             *qpp=quadlets_per_packet_format_1[DC1394_FRAMERATE_NUM*mode_index+frame_rate_index];
101         }
102         else {
103             err=DC1394_INVALID_VIDEO_MODE;
104             DC1394_ERR_RTN(err,"Invalid framerate or mode");
105         }
106         return DC1394_SUCCESS;
107     case DC1394_FORMAT2:
108         mode_index= mode - DC1394_VIDEO_MODE_FORMAT2_MIN;
109 
110         if ( ((mode >= DC1394_VIDEO_MODE_FORMAT2_MIN) && (mode <= DC1394_VIDEO_MODE_FORMAT2_MAX)) &&
111              ((frame_rate >= DC1394_FRAMERATE_MIN) && (frame_rate <= DC1394_FRAMERATE_MAX)) ) {
112             *qpp=quadlets_per_packet_format_2[DC1394_FRAMERATE_NUM*mode_index+frame_rate_index];
113         }
114         else {
115             err=DC1394_INVALID_VIDEO_MODE;
116             DC1394_ERR_RTN(err,"Invalid framerate or mode");
117         }
118         return DC1394_SUCCESS;
119     case DC1394_FORMAT6:
120     case DC1394_FORMAT7:
121         err=DC1394_INVALID_VIDEO_FORMAT;
122         DC1394_ERR_RTN(err,"Format 6 and 7 don't have qpp");
123         break;
124     }
125 
126     return DC1394_FAILURE;
127 }
128 
129 /**********************************************************
130  get_quadlets_from_format
131 
132  This routine reports the number of quadlets that make up a
133  frame given the format and mode
134 ***********************************************************/
135 dc1394error_t
get_quadlets_from_format(dc1394camera_t * camera,dc1394video_mode_t video_mode,uint32_t * quads)136 get_quadlets_from_format(dc1394camera_t *camera, dc1394video_mode_t video_mode, uint32_t *quads)
137 {
138     uint32_t w, h, color_coding;
139     uint32_t bpp;
140     dc1394error_t err;
141 
142     err=dc1394_get_image_size_from_video_mode(camera, video_mode, &w, &h);
143     DC1394_ERR_RTN(err, "Invalid mode ID");
144 
145     err=dc1394_get_color_coding_from_video_mode(camera, video_mode, &color_coding);
146     DC1394_ERR_RTN(err, "Invalid mode ID");
147 
148     err=dc1394_get_color_coding_bit_size(color_coding, &bpp);
149     DC1394_ERR_RTN(err, "Invalid color mode ID");
150 
151     *quads=(w*h*bpp)/32;
152 
153     return err;
154 }
155 
156 dc1394bool_t
is_feature_bit_set(uint32_t value,dc1394feature_t feature)157 is_feature_bit_set(uint32_t value, dc1394feature_t feature)
158 {
159 
160     if (feature >= DC1394_FEATURE_ZOOM) {
161         if (feature >= DC1394_FEATURE_CAPTURE_SIZE) {
162             feature+= 12;
163         }
164         feature-= DC1394_FEATURE_ZOOM;
165     }
166     else {
167         feature-= DC1394_FEATURE_MIN;
168     }
169 
170     value&=(0x80000000UL >> feature);
171 
172     if (value>0)
173         return DC1394_TRUE;
174     else
175         return DC1394_FALSE;
176 }
177 
178 dc1394error_t
get_format_from_mode(dc1394video_mode_t mode,uint32_t * format)179 get_format_from_mode(dc1394video_mode_t mode, uint32_t *format)
180 {
181     dc1394error_t err=DC1394_SUCCESS;
182 
183     if ((mode>=DC1394_VIDEO_MODE_FORMAT0_MIN)&&(mode<=DC1394_VIDEO_MODE_FORMAT0_MAX)) {
184         *format=DC1394_FORMAT0;
185     }
186     else if ((mode>=DC1394_VIDEO_MODE_FORMAT1_MIN)&&(mode<=DC1394_VIDEO_MODE_FORMAT1_MAX)) {
187         *format=DC1394_FORMAT1;
188     }
189     else if ((mode>=DC1394_VIDEO_MODE_FORMAT2_MIN)&&(mode<=DC1394_VIDEO_MODE_FORMAT2_MAX)) {
190         *format=DC1394_FORMAT2;
191     }
192     else if ((mode>=DC1394_VIDEO_MODE_FORMAT6_MIN)&&(mode<=DC1394_VIDEO_MODE_FORMAT6_MAX)) {
193         *format=DC1394_FORMAT6;
194     }
195     else if ((mode>=DC1394_VIDEO_MODE_FORMAT7_MIN)&&(mode<=DC1394_VIDEO_MODE_FORMAT7_MAX)) {
196         *format=DC1394_FORMAT7;
197     }
198     else {
199         err=DC1394_INVALID_VIDEO_MODE;
200         DC1394_ERR_RTN(err, "The supplied mode does not correspond to any format");
201     }
202 
203     return err;
204 }
205 
206 
207 dc1394error_t
capture_basic_setup(dc1394camera_t * camera,dc1394video_frame_t * frame)208 capture_basic_setup (dc1394camera_t * camera, dc1394video_frame_t * frame)
209 {
210     dc1394error_t err;
211     uint32_t bpp;
212     dc1394video_mode_t video_mode;
213     dc1394framerate_t framerate;
214 
215     frame->camera = camera;
216 
217     err=dc1394_video_get_mode(camera,&video_mode);
218     DC1394_ERR_RTN(err, "Unable to get current video mode");
219     frame->video_mode = video_mode;
220 
221     err=dc1394_get_image_size_from_video_mode(camera, video_mode, frame->size, frame->size + 1);
222     DC1394_ERR_RTN(err,"Could not get width/height from format/mode");
223 
224     if (dc1394_is_video_mode_scalable(video_mode)==DC1394_TRUE) {
225 
226         err=dc1394_format7_get_packet_size(camera, video_mode,
227                                            &frame->packet_size);
228         DC1394_ERR_RTN(err, "Unable to get format 7 bytes per packet");
229 
230         err=dc1394_format7_get_packets_per_frame(camera, video_mode,
231                                                  &frame->packets_per_frame);
232         DC1394_ERR_RTN(err, "Unable to get format 7 packets per frame");
233 
234         err = dc1394_format7_get_image_position (camera, video_mode,
235                                                  frame->position, frame->position + 1);
236         DC1394_ERR_RTN(err, "Unable to get format 7 image position");
237 
238         dc1394_format7_get_color_filter (camera, video_mode, &frame->color_filter);
239     }
240     else {
241         err=dc1394_video_get_framerate(camera,&framerate);
242         DC1394_ERR_RTN(err, "Unable to get current video framerate");
243 
244         err=get_quadlets_per_packet(video_mode, framerate, &frame->packet_size);
245         DC1394_ERR_RTN(err, "Unable to get quadlets per packet");
246         frame->packet_size *= 4;
247 
248         err= get_quadlets_from_format(camera, video_mode, &frame->packets_per_frame);
249         DC1394_ERR_RTN(err,"Could not get quadlets per frame");
250         frame->packets_per_frame /= frame->packet_size/4;
251 
252         frame->position[0] = 0;
253         frame->position[1] = 0;
254         frame->color_filter = 0;
255     }
256 
257     dc1394_log_debug("Mode %d, %dx%d, packet size %d, "
258             "packets per frame %d\n",
259             frame->video_mode, frame->size[0], frame->size[1],
260             frame->packet_size, frame->packets_per_frame);
261 
262     if ((frame->packet_size <=0 )||
263         (frame->packets_per_frame <= 0)) {
264         return DC1394_FAILURE;
265     }
266 
267     frame->yuv_byte_order = DC1394_BYTE_ORDER_UYVY;
268 
269     frame->total_bytes = frame->packets_per_frame * frame->packet_size;
270 
271     err = dc1394_get_color_coding_from_video_mode (camera, video_mode, &frame->color_coding);
272     DC1394_ERR_RTN(err, "Unable to get color coding");
273 
274     frame->data_depth=0; // to avoid valgrind warnings
275     err = dc1394_video_get_data_depth (camera, &frame->data_depth);
276     DC1394_ERR_RTN(err, "Unable to get data depth");
277 
278     err = dc1394_get_color_coding_bit_size (frame->color_coding, &bpp);
279     DC1394_ERR_RTN(err, "Unable to get bytes per pixel");
280 
281     frame->stride = (bpp * frame->size[0])/8;
282     frame->image_bytes = frame->size[1] * frame->stride;
283     frame->padding_bytes = frame->total_bytes - frame->image_bytes;
284 
285     frame->little_endian=0;   // not used before 1.32 is out.
286     frame->data_in_padding=0; // not used before 1.32 is out.
287 
288     return DC1394_SUCCESS;
289 }
290 
291