/* * 1394-Based Digital Camera Control Library * * Internal functions * * Written by Damien Douxchamps * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "internal.h" #include "utils.h" #include "log.h" #include "register.h" /* These arrays define how many image quadlets there are in a packet given a mode and a frame rate This is defined in the 1394 digital camera spec */ const int quadlets_per_packet_format_0[56] = { -1, -1, 15, 30, 60, 120, 240, 480, 10, 20, 40, 80, 160, 320, 640, 1280, 30, 60, 120, 240, 480, 960, 1920, 3840, 40, 80, 160, 320, 640, 1280, 2560, 5120, 60, 120, 240, 480, 960, 1920, 3840, 7680, 20, 40, 80, 160, 320, 640, 1280, 2560, 40, 80, 160, 320, 640, 1280, 2560, 5120 }; const int quadlets_per_packet_format_1[64] = { -1, 125, 250, 500, 1000, 2000, 4000, 8000, -1, -1, 375, 750, 1500, 3000, 6000, -1, -1, -1, 125, 250, 500, 1000, 2000, 4000, 96, 192, 384, 768, 1536, 3072, 6144, -1, 144, 288, 576, 1152, 2304, 4608, -1, -1, 48, 96, 192, 384, 768, 1536, 3073, 6144, -1, 125, 250, 500, 1000, 2000, 4000, 8000, 96, 192, 384, 768, 1536, 3072, 6144, -1 }; const int quadlets_per_packet_format_2[64] = { 160, 320, 640, 1280, 2560, 5120, -1, -1, 240, 480, 960, 1920, 3840, 7680, -1, -1, 80, 160, 320, 640, 1280, 2560, 5120, -1, 250, 500, 1000, 2000, 4000, 8000, -1, -1, 375, 750, 1500, 3000, 6000, -1, -1, -1, 125, 250, 500, 1000, 2000, 4000, 8000, -1, 160, 320, 640, 1280, 2560, 5120, -1, -1, 250, 500, 1000, 2000, 4000, 8000, -1, -1 }; /******************************************************** get_quadlets_per_packet This routine reports the number of useful image quadlets per packet *********************************************************/ dc1394error_t get_quadlets_per_packet(dc1394video_mode_t mode, dc1394framerate_t frame_rate, uint32_t *qpp) // ERROR handling to be updated { uint32_t mode_index; uint32_t frame_rate_index= frame_rate - DC1394_FRAMERATE_MIN; uint32_t format; dc1394error_t err; err=get_format_from_mode(mode, &format); DC1394_ERR_RTN(err,"Invalid mode ID"); switch(format) { case DC1394_FORMAT0: mode_index= mode - DC1394_VIDEO_MODE_FORMAT0_MIN; if ( ((mode >= DC1394_VIDEO_MODE_FORMAT0_MIN) && (mode <= DC1394_VIDEO_MODE_FORMAT0_MAX)) && ((frame_rate >= DC1394_FRAMERATE_MIN) && (frame_rate <= DC1394_FRAMERATE_MAX)) ) { *qpp=quadlets_per_packet_format_0[DC1394_FRAMERATE_NUM*mode_index+frame_rate_index]; } else { err=DC1394_INVALID_VIDEO_MODE; DC1394_ERR_RTN(err,"Invalid framerate or mode"); } return DC1394_SUCCESS; case DC1394_FORMAT1: mode_index= mode - DC1394_VIDEO_MODE_FORMAT1_MIN; if ( ((mode >= DC1394_VIDEO_MODE_FORMAT1_MIN) && (mode <= DC1394_VIDEO_MODE_FORMAT1_MAX)) && ((frame_rate >= DC1394_FRAMERATE_MIN) && (frame_rate <= DC1394_FRAMERATE_MAX)) ) { *qpp=quadlets_per_packet_format_1[DC1394_FRAMERATE_NUM*mode_index+frame_rate_index]; } else { err=DC1394_INVALID_VIDEO_MODE; DC1394_ERR_RTN(err,"Invalid framerate or mode"); } return DC1394_SUCCESS; case DC1394_FORMAT2: mode_index= mode - DC1394_VIDEO_MODE_FORMAT2_MIN; if ( ((mode >= DC1394_VIDEO_MODE_FORMAT2_MIN) && (mode <= DC1394_VIDEO_MODE_FORMAT2_MAX)) && ((frame_rate >= DC1394_FRAMERATE_MIN) && (frame_rate <= DC1394_FRAMERATE_MAX)) ) { *qpp=quadlets_per_packet_format_2[DC1394_FRAMERATE_NUM*mode_index+frame_rate_index]; } else { err=DC1394_INVALID_VIDEO_MODE; DC1394_ERR_RTN(err,"Invalid framerate or mode"); } return DC1394_SUCCESS; case DC1394_FORMAT6: case DC1394_FORMAT7: err=DC1394_INVALID_VIDEO_FORMAT; DC1394_ERR_RTN(err,"Format 6 and 7 don't have qpp"); break; } return DC1394_FAILURE; } /********************************************************** get_quadlets_from_format This routine reports the number of quadlets that make up a frame given the format and mode ***********************************************************/ dc1394error_t get_quadlets_from_format(dc1394camera_t *camera, dc1394video_mode_t video_mode, uint32_t *quads) { uint32_t w, h, color_coding; uint32_t bpp; dc1394error_t err; err=dc1394_get_image_size_from_video_mode(camera, video_mode, &w, &h); DC1394_ERR_RTN(err, "Invalid mode ID"); err=dc1394_get_color_coding_from_video_mode(camera, video_mode, &color_coding); DC1394_ERR_RTN(err, "Invalid mode ID"); err=dc1394_get_color_coding_bit_size(color_coding, &bpp); DC1394_ERR_RTN(err, "Invalid color mode ID"); *quads=(w*h*bpp)/32; return err; } dc1394bool_t is_feature_bit_set(uint32_t value, dc1394feature_t feature) { if (feature >= DC1394_FEATURE_ZOOM) { if (feature >= DC1394_FEATURE_CAPTURE_SIZE) { feature+= 12; } feature-= DC1394_FEATURE_ZOOM; } else { feature-= DC1394_FEATURE_MIN; } value&=(0x80000000UL >> feature); if (value>0) return DC1394_TRUE; else return DC1394_FALSE; } dc1394error_t get_format_from_mode(dc1394video_mode_t mode, uint32_t *format) { dc1394error_t err=DC1394_SUCCESS; if ((mode>=DC1394_VIDEO_MODE_FORMAT0_MIN)&&(mode<=DC1394_VIDEO_MODE_FORMAT0_MAX)) { *format=DC1394_FORMAT0; } else if ((mode>=DC1394_VIDEO_MODE_FORMAT1_MIN)&&(mode<=DC1394_VIDEO_MODE_FORMAT1_MAX)) { *format=DC1394_FORMAT1; } else if ((mode>=DC1394_VIDEO_MODE_FORMAT2_MIN)&&(mode<=DC1394_VIDEO_MODE_FORMAT2_MAX)) { *format=DC1394_FORMAT2; } else if ((mode>=DC1394_VIDEO_MODE_FORMAT6_MIN)&&(mode<=DC1394_VIDEO_MODE_FORMAT6_MAX)) { *format=DC1394_FORMAT6; } else if ((mode>=DC1394_VIDEO_MODE_FORMAT7_MIN)&&(mode<=DC1394_VIDEO_MODE_FORMAT7_MAX)) { *format=DC1394_FORMAT7; } else { err=DC1394_INVALID_VIDEO_MODE; DC1394_ERR_RTN(err, "The supplied mode does not correspond to any format"); } return err; } dc1394error_t capture_basic_setup (dc1394camera_t * camera, dc1394video_frame_t * frame) { dc1394error_t err; uint32_t bpp; dc1394video_mode_t video_mode; dc1394framerate_t framerate; frame->camera = camera; err=dc1394_video_get_mode(camera,&video_mode); DC1394_ERR_RTN(err, "Unable to get current video mode"); frame->video_mode = video_mode; err=dc1394_get_image_size_from_video_mode(camera, video_mode, frame->size, frame->size + 1); DC1394_ERR_RTN(err,"Could not get width/height from format/mode"); if (dc1394_is_video_mode_scalable(video_mode)==DC1394_TRUE) { err=dc1394_format7_get_packet_size(camera, video_mode, &frame->packet_size); DC1394_ERR_RTN(err, "Unable to get format 7 bytes per packet"); err=dc1394_format7_get_packets_per_frame(camera, video_mode, &frame->packets_per_frame); DC1394_ERR_RTN(err, "Unable to get format 7 packets per frame"); err = dc1394_format7_get_image_position (camera, video_mode, frame->position, frame->position + 1); DC1394_ERR_RTN(err, "Unable to get format 7 image position"); dc1394_format7_get_color_filter (camera, video_mode, &frame->color_filter); } else { err=dc1394_video_get_framerate(camera,&framerate); DC1394_ERR_RTN(err, "Unable to get current video framerate"); err=get_quadlets_per_packet(video_mode, framerate, &frame->packet_size); DC1394_ERR_RTN(err, "Unable to get quadlets per packet"); frame->packet_size *= 4; err= get_quadlets_from_format(camera, video_mode, &frame->packets_per_frame); DC1394_ERR_RTN(err,"Could not get quadlets per frame"); frame->packets_per_frame /= frame->packet_size/4; frame->position[0] = 0; frame->position[1] = 0; frame->color_filter = 0; } dc1394_log_debug("Mode %d, %dx%d, packet size %d, " "packets per frame %d\n", frame->video_mode, frame->size[0], frame->size[1], frame->packet_size, frame->packets_per_frame); if ((frame->packet_size <=0 )|| (frame->packets_per_frame <= 0)) { return DC1394_FAILURE; } frame->yuv_byte_order = DC1394_BYTE_ORDER_UYVY; frame->total_bytes = frame->packets_per_frame * frame->packet_size; err = dc1394_get_color_coding_from_video_mode (camera, video_mode, &frame->color_coding); DC1394_ERR_RTN(err, "Unable to get color coding"); frame->data_depth=0; // to avoid valgrind warnings err = dc1394_video_get_data_depth (camera, &frame->data_depth); DC1394_ERR_RTN(err, "Unable to get data depth"); err = dc1394_get_color_coding_bit_size (frame->color_coding, &bpp); DC1394_ERR_RTN(err, "Unable to get bytes per pixel"); frame->stride = (bpp * frame->size[0])/8; frame->image_bytes = frame->size[1] * frame->stride; frame->padding_bytes = frame->total_bytes - frame->image_bytes; frame->little_endian=0; // not used before 1.32 is out. frame->data_in_padding=0; // not used before 1.32 is out. return DC1394_SUCCESS; }