ieee1394adaptor.cc
来自「VC视频对象的跟踪提取原代码(vc视频监控源码)」· CC 代码 · 共 377 行
CC
377 行
///////////////////////////////////////////////////////////////////////////////// //// IEEE1394Adaptor.cc //// //// This program reads individual DV encoded frames //// from the 1394 Digital Camera. //// //// //// Author : Sarah Laval (sl) supervised by Nils T Siebel (nts) //// Created : Mon Jun 17 17:32:34 BST 2002 //// Copyright : The University of Reading //// /////////////////////////////////////////////////////////////////////////////////#include <cassert>#include <cstdlib> // for exit()#include "IEEE1394Adaptor.h"namespace ReadingPeopleTracker{// definition and initialisation of static member variables// all static variables are initialized to zero before // the first object is created.bool IEEE1394Adaptor::dv_frame_has_started;DV_encoded_frame_t IEEE1394Adaptor::buffer;IEEE1394Adaptor::IEEE1394Adaptor(){ handle = NULL; port = 0; num_nodes = 0; channel = 63; packet_length = 0; dv_frame_has_started = false; is_dataflow = false;}IEEE1394Adaptor::~IEEE1394Adaptor(){ disconnect_1394();}void IEEE1394Adaptor::connect_1394(){ struct raw1394_portinfo pinf[16]; int nbport = 0; assert(handle == NULL); handle = raw1394_new_handle(); // Required as initialization. if (handle == NULL) { cerror << " IEEE1394Adaptor::connect :" << " Error : Could not get handle." << endl; exit(1); } else { nbport = raw1394_get_port_info(handle, pinf, 16); // Returns number of available ports. // maximum number of port is here 16. raw1394_get_generation(handle); // give handle's value } if (raw1394_set_port(handle, port) < 0) // attach handle to port. { cerror << " IEEE1394Adaptor::connect :" << " Error : Could not set port." << endl; disconnect_1394(); exit(1); } // port set.}void IEEE1394Adaptor::disconnect_1394(){ iso_handler_t result = NULL; old_iso_handler = NULL; if (is_dataflow) { // ends the dialog with the DV camera. stop_dataflow(); } // clear iso handler raw1394_set_iso_handler(handle, channel, NULL); // restore old iso handler result = raw1394_set_iso_handler(handle, channel, old_iso_handler); if (result != NULL) { cdebug << " IEEE1394Adaptor::disconnect_1394: " << " Warning: could not restore the old iso handler." << endl; } // destroy 1394 handle raw1394_destroy_handle(handle); // remember that handle is not valid any more handle = NULL; return;}int IEEE1394Adaptor::frame_iso_handler(raw1394handle_t handle, int channel, size_t packet_length, quadlet_t *data){ // The PAL/NTSC DV data has the following format://// - packets of 496 bytes length// - packets of 16 bytes length.//// The long packets contain the actual video and audio contents . // // The actual DV data starts at quadlet 4 of the long packet,// so we have 480 bytes of DV data per packet. For PAL, each// frame is made out of 300 packets and there are 25 frames// per second. That is 144000 bytes per frame and 3600000// bytes per second. if (packet_length < 492) // ignore 16-byte packets return 0; assert (packet_length == 492); // we have already retrieve the whole frame if (buffer.buffer_size_used >= 144000) return 0; unsigned char *p = (unsigned char*) & data[3]; int section_type = p[0] >> 5; // section type is in bits 5 - 7 int dif_sequence = p[1] >> 4; // dif sequence number is in bits 4 - 7 int dif_block = p[2]; if ((section_type == 0) && (dif_sequence == 0)) { // we are at the beginning of the frame // check whether we have started to fill up our buffer if (buffer.buffer_size_used > 0) { // re-start reading the frame buffer.buffer_size_used = 0; // no bytes for this frame yet } // we have found the beginning of the frame dv_frame_has_started = true; } if (dv_frame_has_started) { switch (section_type) { case 0: // 1 Header block memcpy(buffer.current_frame + dif_sequence * 150 * 80, p, 480); break; case 1: // 2 Subcode blocks memcpy(buffer.current_frame + dif_sequence * 150 * 80 + (1 + dif_block) * 80, p, 480); break; case 2: // 3 VAUX blocks memcpy(buffer.current_frame + dif_sequence * 150 * 80 + (3 + dif_block) * 80, p, 480); break; case 3: // 9 Audio blocks interleaved with video memcpy(buffer.current_frame + dif_sequence * 150 * 80 + (6 + dif_block * 16) * 80, p, 480); break; case 4: // 135 Video blocks interleaved with audio memcpy(buffer.current_frame + dif_sequence * 150 * 80 + (7 + (dif_block / 15) + dif_block) * 80, p, 480); break; default: // we cannot handle any other data break; } buffer.buffer_size_used += 480; } return 0;}int IEEE1394Adaptor::frame_reset_handler(raw1394handle_t handle, unsigned int generation){ cdebug << " IEEE1394Adaptor::frame_reset_handler: " << " Reset. " << endl; return 0;} void IEEE1394Adaptor::find_camera(){ int camera = -1; // get number of nodes on the bus num_nodes = raw1394_get_nodecount(handle); for (unsigned int node = 0; node < num_nodes; node++) { if (rom1394_get_directory(handle, node, &rom_dir) < 0) { cerror << " IEEE1394Adaptor::find_camera : " << " Error : Cannot read config rom directory for node " << node << endl; raw1394_destroy_handle(handle); exit(1); } // Get the type / protocol of a node if ((rom1394_get_node_type(&rom_dir) == ROM1394_NODE_TYPE_AVC) && avc1394_check_subunit_type(handle, node, AVC1394_SUBUNIT_TYPE_VCR)) { camera = node + 1; } else { // Node #node is not a camera. } } if (camera == -1) { cerror << " IEEE1394Adaptor::find_camera : " << " Error : Could not find AV/C devices on 1394 bus." << endl; disconnect_1394(); exit(0); } else { // There are `camera' camera(s) on the bus if (camera > 1) { cerror << " IEEE1394Adaptor::find_camera : " << " Warning: There is more than one camera on the bus." << " Using one of them. " << endl; } }}void IEEE1394Adaptor::set_iso_handler(){ iso_handler_t result = NULL; old_iso_handler = NULL; // remember old handler (will be returned with NULL parameter) old_iso_handler = raw1394_set_iso_handler(handle, channel, NULL); // Set the handler that will be called when an iso packet arrives // we only do isochronous transfert so we define iso_handler here result = raw1394_set_iso_handler(handle, channel, &IEEE1394Adaptor::frame_iso_handler); if (result != NULL) { cerror << " IEEE1394Adaptor::set_iso_handler: " << " Error: could not set iso handler." << endl; exit(1); }}void IEEE1394Adaptor::start_dataflow(){ int result = 0; result = raw1394_start_iso_rcv(handle, channel); // Start receiving a certain isochronous channel. if(result < 0) { cerror << " IEEE1394Adaptor::start_dataflow : " << " Error : Could not start receiving isochronous channel." << endl; exit(1); } is_dataflow = true;}void IEEE1394Adaptor::stop_dataflow(){ int result = 0; if (handle != NULL) { result = raw1394_stop_iso_rcv(handle, channel); } if (result < 0) { cerror << " IEEE1394Adaptor::stop_dataflow : " << " Error : Could not stop receiving isochronous channel." << endl; exit(1); } is_dataflow = false; return;}DV_encoded_frame_t *IEEE1394Adaptor::capture_frame(int channel){ if (handle == NULL) { // this is the first capture. // open the connection with the device // and declare all the arguments needed. connect_1394(); find_camera(); set_iso_handler(); } // begin communication with the device start_dataflow(); // no data read yet. buffer.buffer_size_used = 0; while (buffer.buffer_size_used < 144000) { raw1394_loop_iterate(handle); // retrieve PAL data from the DV camera. } if (is_dataflow) { // ends the dialog with the DV camera. stop_dataflow(); } return &buffer;}} // namespace ReadingPeopleTracker
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?