visca.c
上传用户:shyika
上传日期:2017-11-25
资源大小:1227k
文件大小:18k
源码类别:

视频捕捉/采集

开发平台:

Unix_Linux

  1. /*
  2.   unicap
  3.   Copyright (C) 2004  Arne Caspari  ( arne_caspari@users.sourceforge.net )
  4.   This program is free software; you can redistribute it and/or modify
  5.   it under the terms of the GNU General Public License as published by
  6.   the Free Software Foundation; either version 2 of the License, or
  7.   (at your option) any later version.
  8.   This program is distributed in the hope that it will be useful,
  9.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.   GNU General Public License for more details.
  12.   You should have received a copy of the GNU General Public License
  13.   along with this program; if not, write to the Free Software
  14.   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  15. */
  16. #include "config.h"
  17. #include <string.h>
  18. #include <netinet/in.h>
  19. #include "unicap.h"
  20. #include "vid21394_base.h"
  21. #include "visca.h"
  22. #include "visca_private.h"
  23. #include "visca_property_table.h"
  24. #if VID21394_DEBUG
  25. #define DEBUG
  26. #endif
  27. #include "debug.h"
  28. // --------------------------------------------------------------------------
  29. // Constants and Definitions
  30. // --------------------------------------------------------------------------
  31. struct ae_mode
  32. {
  33.       char param;
  34.       char *menu_item;
  35. };
  36. struct ae_mode ae_modes[] =
  37. {
  38.    { VISCA_AE_MODE_FULL_AUTO,    VISCA_AE_MENU_ITEM_FULL_AUTO }, 
  39.    { VISCA_AE_MODE_MANUAL,       VISCA_AE_MENU_ITEM_MANUAL }, 
  40.    { VISCA_AE_MODE_SHUTTER_PRIO, VISCA_AE_MENU_ITEM_SHUTTER_PRIO }, 
  41.    { VISCA_AE_MODE_IRIS_PRIO,    VISCA_AE_MENU_ITEM_IRIS_PRIO }, 
  42.    { VISCA_AE_MODE_BRIGHT,       VISCA_AE_MENU_ITEM_BRIGHT },
  43.    { 0xff, 0 }
  44. };
  45. // --------------------------------------------------------------------------
  46. // Helper functions
  47. // --------------------------------------------------------------------------
  48. static void visca_init_command_packet_1( unsigned char *packet_data, unsigned char command, unsigned char param1 )
  49. {
  50.    packet_data[0] = 0x81;
  51.    packet_data[1] = 0x01;
  52.    packet_data[2] = 0x04;
  53.    packet_data[3] = command;
  54.    packet_data[4] = param1;
  55.    packet_data[5] = 0xff;
  56. }
  57. static void visca_init_command_packet_4( unsigned char *packet_data, unsigned char command, 
  58.  unsigned char param1, unsigned char param2, 
  59.  unsigned char param3, unsigned char param4 )
  60. {
  61.    packet_data[0] = 0x81;
  62.    packet_data[1] = 0x01;
  63.    packet_data[2] = 0x04;
  64.    packet_data[3] = command;
  65.    packet_data[4] = param1;
  66.    packet_data[5] = param2;
  67.    packet_data[6] = param3;
  68.    packet_data[7] = param4;
  69.    packet_data[8] = 0xff;
  70. }
  71. static void visca_init_inq_packet( unsigned char *packet_data, unsigned char command )
  72. {
  73.    packet_data[0] = 0x81;
  74.    packet_data[1] = 0x09;
  75.    packet_data[2] = 0x04;
  76.    packet_data[3] = command;
  77.    packet_data[4] = 0xff;
  78. }
  79. static void visca_init_device_type_inq_packet( unsigned char *packet_data )
  80. {
  81.    packet_data[0] = 0x81;
  82.    packet_data[1] = 0x09;
  83.    packet_data[2] = 0x00;
  84.    packet_data[3] = 0x02;
  85.    packet_data[4] = 0xff;
  86. }
  87. static void visca_htofla( unsigned char *ar, size_t s )
  88. {
  89.    unsigned int *i_ar;
  90.    int i;
  91.    i_ar = ( unsigned int *)ar;
  92.    if( s % 4 )
  93.    {
  94.       s += 4 - ( s%4 );
  95.    }
  96.    for( i = 0; i < ( s/4 ); i++ )
  97.    {
  98.       i_ar[i] = htonl( i_ar[i] );
  99.    }
  100. }
  101. // --------------------------------------------------------------------------
  102. // Functions
  103. // --------------------------------------------------------------------------
  104. unicap_status_t visca_check_inq_response( unsigned char *response )
  105. {
  106.    unicap_status_t status = STATUS_SUCCESS;
  107.    if( ( response[1] & 0xf0 ) != VISCA_COMMAND_COMPLETE )
  108.    {
  109.       status = STATUS_FAILURE;
  110.    }
  111.    return status;
  112. }
  113. unicap_status_t visca_set_white_balance( vid21394handle_t vid21394handle, 
  114.  unicap_property_t *property )
  115. {
  116.    int out_bytes, in_bytes;
  117.    unsigned char out_data[8];
  118.    unsigned char in_data[8];
  119.    unicap_status_t status;
  120.    out_bytes = 6;
  121.    in_bytes = 6;
  122.    if( property->flags & UNICAP_FLAGS_AUTO )
  123.    {
  124.       visca_init_command_packet_1( out_data, VISCA_COMMAND_WHITE_BALANCE, VISCA_WHITE_BALANCE_AUTO );
  125.    }
  126.    else
  127.    {
  128.       if( property->value == 3200 )
  129.       {
  130.  visca_init_command_packet_1( out_data, VISCA_COMMAND_WHITE_BALANCE, VISCA_WHITE_BALANCE_INDOOR );
  131.       }
  132.       else
  133.       {
  134.  visca_init_command_packet_1( out_data, VISCA_COMMAND_WHITE_BALANCE, VISCA_WHITE_BALANCE_OUTDOOR );
  135.       }
  136.    }
  137.    visca_htofla( out_data, out_bytes );
  138.    status = vid21394_rs232_io( vid21394handle, 
  139.        out_data, out_bytes, 
  140.        in_data, in_bytes );
  141.    return status;
  142. }
  143. unicap_status_t visca_get_white_balance( vid21394handle_t vid21394handle, 
  144.  unicap_property_t *property )
  145. {
  146.    int out_bytes, in_bytes;
  147.    unsigned char out_data[8];
  148.    unsigned char in_data[8];
  149.    unicap_status_t status;
  150.    out_bytes = 5;
  151.    in_bytes = 4;
  152.    visca_init_inq_packet( out_data, VISCA_COMMAND_WHITE_BALANCE );
  153.    visca_htofla( out_data, out_bytes );
  154.    status = vid21394_rs232_io( vid21394handle, 
  155.        out_data, out_bytes, 
  156.        in_data, in_bytes );
  157.    if( SUCCESS( status ) )
  158.    {
  159.       status = visca_check_inq_response( in_data );
  160.       property->flags = UNICAP_FLAGS_MANUAL;
  161.       switch( in_data[2] )
  162.       {
  163.  case VISCA_WHITE_BALANCE_AUTO:
  164.  {
  165.     property->flags = UNICAP_FLAGS_AUTO;
  166.  }
  167.  break;
  168.  case VISCA_WHITE_BALANCE_INDOOR:
  169.  {
  170.     property->value = 3200;
  171.  }
  172.  break;
  173.  case VISCA_WHITE_BALANCE_OUTDOOR:
  174.  {
  175.     property->value = 5600;
  176.  }
  177.  break;
  178.       }
  179.    }
  180.    return status;
  181. }
  182. unicap_status_t visca_set_zoom( vid21394handle_t vid21394handle, 
  183. unicap_property_t *property )
  184. {
  185.    int out_bytes, in_bytes;
  186.    unsigned char out_data[12];
  187.    unsigned char in_data[8];
  188.    unicap_status_t status;
  189.    unsigned char p1, p2, p3, p4;
  190.    unsigned int value;
  191.    out_bytes = 9;
  192.    in_bytes = 3;
  193.    value = property->value;
  194.    p1 = ( value >> 12 ) & 0xf;
  195.    p2 = ( value >> 8 ) & 0xf;
  196.    p3 = ( value >> 4 ) & 0xf ; 
  197.    p4 = value & 0xf;
  198.    visca_init_command_packet_4( out_data, VISCA_COMMAND_ZOOM_DIRECT, p1, p2, p3, p4 );
  199.    visca_htofla( out_data, out_bytes );
  200.    status = vid21394_rs232_io( vid21394handle, 
  201.        out_data, out_bytes, 
  202.        in_data, in_bytes );
  203.    return status;
  204. }
  205. unicap_status_t visca_get_zoom( vid21394handle_t vid21394handle, 
  206. unicap_property_t *property )
  207. {
  208.    int out_bytes, in_bytes;
  209.    unsigned char out_data[8];
  210.    unsigned char in_data[8];
  211.    unicap_status_t status;
  212.    out_bytes = 5;
  213.    in_bytes = 7;
  214.    visca_init_inq_packet( out_data, VISCA_COMMAND_ZOOM_DIRECT );
  215.    visca_htofla( out_data, out_bytes );
  216.    status = vid21394_rs232_io( vid21394handle, 
  217.        out_data, out_bytes, 
  218.        in_data, in_bytes );
  219.    if( SUCCESS( status ) )
  220.    {
  221.       property->value = ( in_data[2] * 0x1000 + 
  222.   in_data[3] * 0x100 + 
  223.   in_data[4] * 0x10 + 
  224.   in_data[5] );
  225.    }
  226.    return status;
  227. }
  228. unicap_status_t visca_set_focus( vid21394handle_t vid21394handle, 
  229.  unicap_property_t *property )
  230. {
  231.    int out_bytes, in_bytes;
  232.    unsigned char out_data[12];
  233.    unsigned char in_data[8];
  234.    unicap_status_t status;
  235.    if( property->flags & UNICAP_FLAGS_AUTO )
  236.    {
  237.       out_bytes = 6;
  238.       in_bytes = 6;
  239.       visca_init_command_packet_1( out_data, VISCA_COMMAND_FOCUS_AUTO, VISCA_FOCUS_AUTO );
  240.    }
  241.    else
  242.    {
  243.       out_bytes = 6;
  244.       in_bytes = 6;
  245.       visca_init_command_packet_1( out_data, VISCA_COMMAND_FOCUS_AUTO, VISCA_FOCUS_MANUAL );
  246.       visca_htofla( out_data, out_bytes );
  247.       status = vid21394_rs232_io( vid21394handle, 
  248.   out_data, out_bytes, 
  249.   in_data, in_bytes );
  250.       if( SUCCESS( status ) )
  251.       {
  252.  unsigned char p1, p2, p3, p4;
  253.  unsigned int value;
  254.  out_bytes = 9;
  255.  in_bytes = 6;
  256.  value = property->value;
  257.  p1 = ( value >> 12 ) & 0xf;
  258.  p2 = ( value >> 8 ) & 0xf;
  259.  p3 = ( value >>4 ) & 0xf;
  260.  p4 = value & 0xf;
  261.  visca_init_command_packet_4( out_data, VISCA_COMMAND_FOCUS_DIRECT, p1, p2, p3, p4 );
  262.       }
  263.       else
  264.       {
  265.  return status;
  266.       }
  267.    }
  268.    visca_htofla( out_data, out_bytes );
  269.    status = vid21394_rs232_io( vid21394handle, 
  270.        out_data, out_bytes, 
  271.        in_data, in_bytes );
  272.    return status;
  273. }
  274. unicap_status_t visca_get_focus( vid21394handle_t vid21394handle, 
  275.  unicap_property_t *property )
  276. {
  277.    int out_bytes, in_bytes;
  278.    unsigned char out_data[8];
  279.    unsigned char in_data[8];
  280.    unicap_status_t status;
  281.    out_bytes = 5;
  282.    in_bytes = 4;
  283.    visca_init_inq_packet( out_data, VISCA_COMMAND_FOCUS_AUTO );
  284.    visca_htofla( out_data, out_bytes );
  285.    status = vid21394_rs232_io( vid21394handle, 
  286.        out_data, out_bytes, 
  287.        in_data, in_bytes );
  288.    if( SUCCESS( status ) )
  289.    {
  290.       status = visca_check_inq_response( in_data );
  291.       property->flags = UNICAP_FLAGS_MANUAL;
  292.       switch( in_data[2] )
  293.       {
  294.  case VISCA_FOCUS_AUTO:
  295.  {
  296.     property->flags = UNICAP_FLAGS_AUTO;
  297. /*      TRACE( "AUTO FOCUS enabledn" ); */
  298.  }
  299.  break;
  300.  default:
  301.  case VISCA_FOCUS_MANUAL:
  302.  {
  303. /*      TRACE( "MANUAL FOCUS enabledn" ); */
  304.  }
  305.  break;
  306.       }
  307.       out_bytes = 5;
  308.       in_bytes = 7;
  309.       visca_init_inq_packet( out_data, VISCA_COMMAND_FOCUS_DIRECT );
  310.       visca_htofla( out_data, out_bytes );
  311.       status = vid21394_rs232_io( vid21394handle, 
  312.   out_data, out_bytes, 
  313.   in_data, in_bytes );
  314.       if( SUCCESS( status ) )
  315.       {
  316.  property->value = ( in_data[2] * 0x1000 + 
  317.      in_data[3] * 0x100 + 
  318.      in_data[4] * 0x10 + 
  319.      in_data[5] );
  320.       }
  321.    }
  322.    return status;
  323. }
  324. unicap_status_t visca_set_gain( vid21394handle_t vid21394handle, 
  325. unicap_property_t *property )
  326. {
  327.    int out_bytes, in_bytes;
  328.    unsigned char out_data[12];
  329.    unsigned char in_data[8];
  330.    unicap_status_t status;
  331.    unsigned char p3, p4;
  332.    unsigned int value;
  333.    out_bytes = 9;
  334.    in_bytes = 6;
  335.    p3 = ( value & 0xf0 ) >> 8;
  336.    p4 = value & 0xf;
  337.    visca_init_command_packet_4( out_data, VISCA_COMMAND_FOCUS_DIRECT, 0, 0, p3, p4 );
  338.    visca_htofla( out_data, out_bytes );
  339.    status = vid21394_rs232_io( vid21394handle, 
  340.        out_data, out_bytes, 
  341.        in_data, in_bytes );
  342.    return status;
  343. }
  344. unicap_status_t visca_get_gain( vid21394handle_t vid21394handle, 
  345. unicap_property_t *property )
  346. {
  347.    int out_bytes, in_bytes;
  348.    unsigned char out_data[8];
  349.    unsigned char in_data[8];
  350.    unicap_status_t status;
  351.    out_bytes = 5;
  352.    in_bytes = 7;
  353.    visca_init_inq_packet( out_data, VISCA_COMMAND_GAIN_DIRECT );
  354.    visca_htofla( out_data, out_bytes );
  355.    status = vid21394_rs232_io( vid21394handle, 
  356.        out_data, out_bytes, 
  357.        in_data, in_bytes );
  358.    if( SUCCESS( status ) )
  359.    {
  360.       property->value = ( in_data[4] * 0x10 + 
  361.   in_data[5] );
  362.    }
  363.    property->flags = UNICAP_FLAGS_MANUAL;
  364.    return status;
  365. }
  366. unicap_status_t visca_set_shutter( vid21394handle_t vid21394handle, 
  367.    unicap_property_t *property )
  368. {
  369.    int out_bytes, in_bytes;
  370.    unsigned char out_data[12];
  371.    unsigned char in_data[8];
  372.    unicap_status_t status;
  373.    unsigned char p3, p4;
  374.    unsigned int value;
  375.    out_bytes = 9;
  376.    in_bytes = 6;
  377.    p3 = ( value & 0xf0 ) >> 8;
  378.    p4 = value & 0xf;
  379.    visca_init_command_packet_4( out_data, VISCA_COMMAND_SHUTTER_DIRECT, 0, 0, p3, p4 );
  380.    visca_htofla( out_data, out_bytes );
  381.    status = vid21394_rs232_io( vid21394handle, 
  382.        out_data, out_bytes, 
  383.        in_data, in_bytes );
  384.    return status;
  385. }
  386. unicap_status_t visca_get_shutter( vid21394handle_t vid21394handle, 
  387.    unicap_property_t *property )
  388. {
  389.    int out_bytes, in_bytes;
  390.    unsigned char out_data[8];
  391.    unsigned char in_data[8];
  392.    unicap_status_t status;
  393.    out_bytes = 5;
  394.    in_bytes = 7;
  395.    visca_init_inq_packet( out_data, VISCA_COMMAND_SHUTTER_DIRECT );
  396.    visca_htofla( out_data, out_bytes );
  397.    status = vid21394_rs232_io( vid21394handle, 
  398.        out_data, out_bytes, 
  399.        in_data, in_bytes );
  400.    if( SUCCESS( status ) )
  401.    {
  402.       property->value = ( in_data[4] * 0x10 + 
  403.   in_data[5] );
  404.    }
  405.    property->flags = UNICAP_FLAGS_MANUAL;
  406.    return status;
  407. }
  408. unicap_status_t visca_set_iris( vid21394handle_t vid21394handle, 
  409. unicap_property_t *property )
  410. {
  411.    int out_bytes, in_bytes;
  412.    unsigned char out_data[12];
  413.    unsigned char in_data[8];
  414.    unicap_status_t status;
  415.    unsigned char p3, p4;
  416.    unsigned int value;
  417.    out_bytes = 9;
  418.    in_bytes = 6;
  419.    p3 = ( value & 0xf0 ) >> 8;
  420.    p4 = value & 0xf;
  421.    visca_init_command_packet_4( out_data, VISCA_COMMAND_IRIS_DIRECT, 0, 0, p3, p4 );
  422.    visca_htofla( out_data, out_bytes );
  423.    status = vid21394_rs232_io( vid21394handle, 
  424.        out_data, out_bytes, 
  425.        in_data, in_bytes );
  426.    return status;
  427. }
  428. unicap_status_t visca_get_iris( vid21394handle_t vid21394handle, 
  429. unicap_property_t *property )
  430. {
  431.    int out_bytes, in_bytes;
  432.    unsigned char out_data[8];
  433.    unsigned char in_data[8];
  434.    unicap_status_t status;
  435.    out_bytes = 5;
  436.    in_bytes = 7;
  437.    visca_init_inq_packet( out_data, VISCA_COMMAND_IRIS_DIRECT );
  438.    visca_htofla( out_data, out_bytes );
  439.    status = vid21394_rs232_io( vid21394handle, 
  440.        out_data, out_bytes, 
  441.        in_data, in_bytes );
  442.    if( SUCCESS( status ) )
  443.    {
  444.       property->value = ( in_data[4] * 0x10 + 
  445.   in_data[5] );
  446.    }
  447.    property->flags = UNICAP_FLAGS_MANUAL;
  448.    return status;
  449. }
  450. unicap_status_t visca_set_ae_mode( vid21394handle_t vid21394handle, 
  451.    unicap_property_t *property )
  452. {
  453.    int out_bytes, in_bytes;
  454.    unsigned char out_data[8];
  455.    unsigned char in_data[8];
  456.    unicap_status_t status;
  457.    unsigned char param = 0xff;
  458.    int i;
  459.    out_bytes = 6;
  460.    in_bytes = 6;
  461.    for( i = 0; ae_modes[i].param != 0xff; i++ )
  462.    {
  463.       if( !strcmp( property->menu_item, ae_modes[i].menu_item ) )
  464.       {
  465.  param = ae_modes[i].param;
  466.  break;
  467.       }
  468.    }
  469.    if( param == 0xff )
  470.    {
  471.       return STATUS_INVALID_PARAMETER;
  472.    };
  473.    visca_init_command_packet_1( out_data, VISCA_COMMAND_AE_MODE, param );
  474.    visca_htofla( out_data, out_bytes );
  475.    status = vid21394_rs232_io( vid21394handle, 
  476.        out_data, out_bytes, 
  477.        in_data, in_bytes );
  478.    return status;
  479. }
  480. unicap_status_t visca_get_ae_mode( vid21394handle_t vid21394handle, 
  481.    unicap_property_t *property )
  482. {
  483.    int out_bytes, in_bytes;
  484.    unsigned char out_data[8];
  485.    unsigned char in_data[8];
  486.    unicap_status_t status;
  487.    out_bytes = 5;
  488.    in_bytes = 4;
  489.    visca_init_inq_packet( out_data, VISCA_COMMAND_AE_MODE );
  490.    visca_htofla( out_data, out_bytes );
  491.    status = vid21394_rs232_io( vid21394handle, 
  492.        out_data, out_bytes, 
  493.        in_data, in_bytes );
  494.    if( SUCCESS( status ) )
  495.    {
  496.       status = visca_check_inq_response( in_data );
  497.       property->flags = UNICAP_FLAGS_MANUAL;
  498.       switch( in_data[2] )
  499.       {
  500.  case VISCA_AE_MODE_MANUAL:
  501.  {
  502.     strcpy( property->menu_item, VISCA_AE_MENU_ITEM_MANUAL );
  503.  }
  504.  break;
  505.  case VISCA_AE_MODE_FULL_AUTO:
  506.  {
  507.     strcpy( property->menu_item, VISCA_AE_MENU_ITEM_FULL_AUTO );
  508.  }
  509.  break;
  510.  case VISCA_AE_MODE_SHUTTER_PRIO:
  511.  {
  512.     strcpy( property->menu_item, VISCA_AE_MENU_ITEM_SHUTTER_PRIO );
  513.  }
  514.  break;
  515.  case VISCA_AE_MODE_IRIS_PRIO:
  516.  {
  517.     strcpy( property->menu_item, VISCA_AE_MENU_ITEM_IRIS_PRIO );
  518.  }
  519.  break;
  520.  case VISCA_AE_MODE_BRIGHT:
  521.  {
  522.     strcpy( property->menu_item, VISCA_AE_MENU_ITEM_BRIGHT );
  523.  }
  524.  break;
  525.  default:
  526.  {
  527.     strcpy( property->menu_item, "Unknown" );
  528.  }
  529.  break;
  530.       }
  531.    }
  532.    return status;
  533. }
  534. unicap_status_t visca_reenumerate_properties( vid21394handle_t vid21394handle, int *count )
  535. {
  536.    *count = ( sizeof( visca_property_table ) / sizeof( visca_property_t ) );
  537.    return STATUS_SUCCESS;
  538. }
  539. unicap_status_t visca_enumerate_properties( unicap_property_t *property, int index )
  540. {
  541.    if( ( index < 0 ) ||
  542.        ( index >= ( sizeof( visca_property_table ) / sizeof( visca_property_t ) ) ) )
  543.    {
  544.       return STATUS_NO_MATCH;
  545.    }
  546.    unicap_copy_property( property, &visca_property_table[index].property );
  547.    return STATUS_SUCCESS;
  548. }
  549. unicap_status_t visca_set_property( vid21394handle_t vid21394handle, unicap_property_t *property )
  550. {
  551.    int i;
  552.    unicap_status_t status = STATUS_INVALID_PARAMETER;
  553.    for( i = 0; i < ( sizeof( visca_property_table ) / sizeof( visca_property_t ) ); i++ )
  554.    {
  555.       if( !strcmp( visca_property_table[i].property.identifier, property->identifier ) )
  556.       {
  557.  status = visca_property_table[i].set_function( vid21394handle, property );
  558.  break;
  559.       }
  560.    }
  561.    return status;
  562. }
  563. unicap_status_t visca_get_property( vid21394handle_t vid21394handle, unicap_property_t *property )
  564. {
  565.    int i;
  566.    unicap_status_t status = STATUS_INVALID_PARAMETER;
  567.    for( i = 0; i < ( sizeof( visca_property_table ) / sizeof( visca_property_t ) ); i++ )
  568.    {
  569.       if( !strcmp( visca_property_table[i].property.identifier, property->identifier ) )
  570.       {
  571.  unicap_copy_property( property, & visca_property_table[i].property );
  572.  status = visca_property_table[i].get_function( vid21394handle, property );
  573.  break;
  574.       }
  575.    }
  576.    return status;
  577. }
  578. unicap_status_t visca_check_camera( vid21394handle_t vid21394handle, visca_camera_type_t *type )
  579. {
  580.    int out_bytes, in_bytes;
  581.    unsigned char out_data[8];
  582.    unsigned char in_data[10];
  583.    unicap_status_t status = STATUS_FAILURE;
  584.    *type = VISCA_CAMERA_TYPE_NONE;
  585.    out_bytes = 5;
  586.    in_bytes = 10;
  587.    visca_init_device_type_inq_packet( out_data );
  588.    vid21394_rs232_set_baudrate( vid21394handle, 9600 );
  589.    visca_htofla( out_data, out_bytes );
  590.    status = vid21394_rs232_io( vid21394handle, 
  591.        out_data, out_bytes, 
  592.        in_data, in_bytes );
  593.    if( !SUCCESS( status ) )
  594.    {
  595.       TRACE( "Get camera type failedn" );
  596.       return status;
  597.    }
  598.    // Check Vendor ID
  599.    if( ( in_data[2] != 0x0 ) ||
  600.        ( in_data[3] != 0x20 ) )
  601.    {
  602.       TRACE( "Wrong Vendor IDn" );
  603.    } 
  604.    else if( ( in_data[4] != 0x4 ) )  // Check Model ID
  605.    {
  606.       TRACE( "Unknown camera type!n" );
  607.       *type = VISCA_CAMERA_TYPE_UNKNOWN;
  608.    }
  609.    else
  610.    {
  611.       *type = VISCA_CAMERA_TYPE_FCB_IX47;
  612.    }
  613.    return status;
  614. }