www.pudn.com > ReadingPeopleTracker-1.28.rar > IEEE1394Source.cc
/////////////////////////////////////////////////////////////////////////////// // // // IEEE1394Source.cc // // // // This program reads and decodes the DV encoded frames // // from the IEEE1394Adaptor // // // // // // 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// for exit() #include #include "IEEE1394Source.h" #include "Grey8Image.h" namespace ReadingPeopleTracker { IEEE1394Source::IEEE1394Source(int the_quality) { Adaptor = new IEEE1394Adaptor; time = new timeval; frame_count = 0; // variables for DV decoding decoder = dv_decoder_new(false, false, false); // (no add_ntsc_setup, no luma clamping, no chroma clamping) // NB: in newer versions of libdv, dv_init is called by dv_decode_new dv_init(false, false); // (no luma clamping, no chroma clamping) decoder->quality = the_quality; DV_encoded_data = NULL; } IEEE1394Source::~IEEE1394Source() { delete Adaptor; } void IEEE1394Source::acquire_DV_frame() { //tell the adaptor to start getting data DV_encoded_data = Adaptor->capture_frame(Adaptor->get_channel()); //here Adaptor loops with the hardware return; } void IEEE1394Source::DV_decode() { dv_parse_header(decoder, DV_encoded_data->current_frame); xdim = decoder->width; ydim = decoder->height; // create resulting image if it does not exist if (current == NULL) current = new RGB32Image(xdim, ydim); else { // current exists: check dimensions and type if ((current->get_image_type() != RGB32) || (current->get_width() != xdim) || (current->get_height() != ydim)) { cerror << "IEEE1394Source::DV_decode: " << "Error : consecutive input images have " << "different types/dimensions." << endl; exit(1); } } switch(decoder->system) { case e_dv_system_625_50: //for PAL decode_image(current); break; default: break; } return; } int IEEE1394Source::decode_image(Image *image) { unsigned char *pixels[3]; int pitches[3]; // libdv cannot decode into RGB0RGB0... format, only RGBRGB... // Hence we will decode into our local buffer // decompressed_image_data first, then copy the image data over. // // 1 - decode DV data into decompressed_image_data buffer: // pixels[0] = decompressed_image_data; pixels[1] = NULL; // this is unused by libdv pixels[2] = NULL; // this is unused by libdv // pitches[0]: offset (in bytes) between lines pitches[0] = ABS (image->get_pixel(0,1) - image->get_pixel(0,0)); pitches[1] = 0; // this is unused by libdv pitches[2] = 0; // this is unused by libdv dv_decode_full_frame(decoder, DV_encoded_data->current_frame, e_dv_color_rgb, // also avaiable: e_dv_color_bgr0 pixels, pitches); // // 2 - copy image data (RGB pixels) over, padding with 0's // // NB DV thinks in terms of IA_TOP_TO_BOTTOM // see if we need to flip it for the result (*current) unsigned int row; register unsigned int col; register unsigned char *rgb_ptr; register RGB32pixel *rgba_ptr; if (Image::image_storage_mode == IA_TOP_TO_BOTTOM) { // no need to flip the image while converting to 32-bit for (row = 0; row < ydim; row++) { rgba_ptr = (RGB32pixel *) current->get_pixel(0,row); rgb_ptr = pixels[0] + row * pitches[0]; for (col = 0; col < xdim; col++) { // see definition of RGB32pixel in RGB32Image.h rgba_ptr->red = *(rgb_ptr++); // R rgba_ptr->green = *(rgb_ptr++); // G rgba_ptr->blue = *(rgb_ptr++); // B // not necessary to assign alpha, or is it? rgba_ptr->alpha = (unsigned char) 0x00; rgba_ptr++; } } } else { // we need to flip the image while converting to 32-bit for (row = 0; row < ydim; row++) { rgba_ptr = (RGB32pixel *) current->get_pixel(0, ydim - (row+1)); rgb_ptr = pixels[0] + row * pitches[0]; for (col = 0; col < xdim; col++) { // see def'n of RGB32pixel in RGB32Image.h rgba_ptr->red = *(rgb_ptr++); // R rgba_ptr->green = *(rgb_ptr++); // G rgba_ptr->blue = *(rgb_ptr++); // B // not necessary to assign alpha, or is it? rgba_ptr->alpha = (unsigned char) 0x00; rgba_ptr++; } } } return 0; } Image *IEEE1394Source::get_next() { //get the DV-encoded frame acquire_DV_frame(); //DV-decode it DV_decode(); //#ifdef _BSD_SOURCE //apparently works anyway? // // the following requires the BSD 4.3 gettimeofday() gettimeofday(time, NULL); current->set_frame_time_in_ms((time->tv_sec * 1000) + (time->tv_usec / 1000)); // #else // #error "Please re-implement for your system or use BSD compatability" // #endif // ifdef _BSD_SOURCE assert (decoder->width == 720); assert (decoder->height == 576); frame_count++; return current; } } // namespace ReadingPeopleTracker