vidinput_avc.cxx

来自「开源代码的pwlib的1.10.0版本,使用openh323的1.18.0版本毕」· CXX 代码 · 共 572 行 · 第 1/2 页

CXX
572
字号

int PVideoInputDevice_1394AVC::GetColour()
{
  return -1;
}

BOOL PVideoInputDevice_1394AVC::SetWhiteness(unsigned newWhiteness) 
{
  return FALSE;
}

int PVideoInputDevice_1394AVC::GetWhiteness()
{
  return -1;
}

BOOL PVideoInputDevice_1394AVC::GetParameters (int *whiteness, int *brightness,
                                       int *colour, int *contrast, int *hue)
{
  *whiteness = -1;
  *brightness = -1;
  *colour = -1;
  *hue = -1;
  return FALSE;
}

int PVideoInputDevice_1394AVC::GetNumChannels() 
{
  int Result;
  mutex.Wait();
  if(dico != NULL)
    Result = dico->GetSize();
  else
    Result = 0;

  mutex.Signal();
  return Result;
}

BOOL PVideoInputDevice_1394AVC::SetChannel(int newChannel)
{
  if (PVideoDevice::SetChannel(newChannel) == FALSE)
    return FALSE;

  if(IsCapturing()) {
    Stop();
    Start();
  }
  
  return TRUE;
}

BOOL PVideoInputDevice_1394AVC::SetFrameRate(unsigned rate)
{
  return PVideoDevice::SetFrameRate(rate);
}

BOOL PVideoInputDevice_1394AVC::GetFrameSizeLimits(unsigned & minWidth,
                                                   unsigned & minHeight,
                                                   unsigned & maxWidth,
                                                   unsigned & maxHeight) 
{
  minWidth = 160;
  maxWidth = 320;
  minHeight = 120;
  maxHeight = 240;
  return TRUE;
}


PINDEX PVideoInputDevice_1394AVC::GetMaxFrameBytes()
{
  return GetMaxFrameBytesConverted(frameBytes);
}


BOOL PVideoInputDevice_1394AVC::GetFrameDataNoDelay(BYTE * buffer,
                                                  PINDEX * bytesReturned)
{
  if (!IsCapturing()) return FALSE;

  BOOL frame_complete = FALSE;
  BOOL found_first_frame = FALSE;
  int skipped = 0;
  int broken_frames = 0;
  BYTE capture_buffer[150000];
  BYTE * capture_buffer_end = capture_buffer;
  
  // this starts the bytes' rain
  if (raw1394_start_iso_rcv(handle, 63) < 0) {
    PTRACE(3, "Cannot receive data on channel 63");
    return FALSE;
  }
  // calling the raw1394 event manager, to get a frame:
  while(!frame_complete) {
    raw1394_loop_iterate(handle);
    if (*(uint32_t *)raw_buffer >= 492) {
      if (!found_first_frame) {
        if (raw_buffer[16] == 0x1f && raw_buffer[17] == 0x07)
          found_first_frame = TRUE;
        else
          skipped ++;
      }
      if (skipped > 500) {
        PTRACE (3, "Skipped much too many frames");
        return FALSE;
      }
      if (found_first_frame) {
        if (raw_buffer[16] == 0x1f
            && raw_buffer[17] == 0x07
            && (capture_buffer_end - capture_buffer > 480)) {
          // check for a short read. check if we read less
          // than a NTSC frame because it is the smaller one.
          // still not sure how to handle NTSC vs. PAL
          if (capture_buffer_end - capture_buffer < 120000) {
            broken_frames++;
            capture_buffer_end = capture_buffer;
          }
          else
            frame_complete = TRUE;
        }
        if (!frame_complete) {
          memcpy (capture_buffer_end, raw_buffer+16, 480);
          capture_buffer_end += 480;
        }
      } // found_first_frame
      if (broken_frames > 30) {
        PTRACE(3, "Too many broken frames!");
        return FALSE;
      }
    }
  }
  // stops the bytes from coming at us!
  raw1394_stop_iso_rcv(handle, 63);
  
  dv_decoder_t *dv;
  dv = dv_decoder_new(TRUE, FALSE, FALSE);
  dv->quality = DV_QUALITY_BEST; // FIXME: best!?
  if(dv_parse_header(dv, capture_buffer) < 0) {
    PTRACE(3, "cannot parse dv frame header");
    return FALSE;
  }
  
  dv_color_space_t color_space;
  BYTE * pixels[3];
  int  pitches[3];
  
  pitches[0] = dv->width * 3;
  pitches[1] = pitches[2] = 0;
  
  pixels[0] = (uint8_t *)malloc(dv->width * dv->height * 3);
  pixels[1] = NULL;
  pixels[2] = NULL;
  color_space = e_dv_color_rgb;
  
  dv_decode_full_frame(dv, capture_buffer, color_space, pixels, pitches);
  
  // FIXME: this is a manual resize ; the original author wondered about it
  float xRatio = dv->width / (float)frameWidth;
  float yRatio = dv->height/ (float)frameHeight;
  for(uint y = 0; y < frameHeight; y++)
    for (uint x = 0; x < frameWidth; x++) {
      uint16_t sourceX = (uint16_t) (x * xRatio);
      uint16_t sourceY = (uint16_t) (y * yRatio);
      memcpy (pixels[0]+3*(y*frameWidth+x),
              pixels[0]+3*(sourceY*dv->width+sourceX),
              3);
      
      // FIXME: BGR <-> RGB done by hand
      BYTE temp;
      int offset= (y*frameWidth+x)*3;
      temp = pixels[0][offset+0];
      pixels[0][offset+0] = pixels[0][offset+2];
      pixels[0][offset+2] = temp;
    }
  if (converter != NULL) {
    converter->Convert((const BYTE *)pixels[0], buffer, bytesReturned);
    if (pixels[0] != NULL)
      free(pixels[0]);
  }
  else {
    PTRACE(3, "Converter must exist. Something goes wrong.");
    return FALSE;
  }
  
  return TRUE;
  
}

BOOL PVideoInputDevice_1394AVC::GetFrameData(BYTE * buffer, PINDEX * bytesReturned)
{
  int capturing_duration = 10000; // FIXME: what is it for?
  // notice: funny things happen when it is set too low!
  
  if(frameRate>0) {
    if(msBetweenFrames > capturing_duration)
      PThread::Current()->Sleep(msBetweenFrames - capturing_duration);
    PTime start;
    if(!GetFrameDataNoDelay(buffer, bytesReturned))
      return FALSE;
    PTime end;
    capturing_duration = (int)((end-start).GetMilliSeconds());
    return TRUE;
  }
  return GetFrameDataNoDelay(buffer, bytesReturned);
}

void PVideoInputDevice_1394AVC::ClearMapping()
{
  // do nothing...
}

BOOL PVideoInputDevice_1394AVC::TestAllFormats()
{
  return TRUE;
}

BOOL PVideoInputDevice_1394AVC::SetColourFormat(const PString & newFormat)
{
  if (newFormat != colourFormat)
    return FALSE;
  
  return TRUE;
}

BOOL PVideoInputDevice_1394AVC::SetFrameSize(unsigned width, unsigned height)
{
  // FIXME: shouldn't it return FALSE when asked an unsupported frame size? 
  frameWidth = width;
  frameHeight = height;
  colourFormat = "RGB24";
  nativeVerticalFlip = true;
  frameBytes = PVideoDevice::CalculateFrameBytes(frameWidth,
  frameHeight, colourFormat);
  
  return TRUE;
}

BOOL PVideoInputDevice_1394AVC::SetFrameSizeConverter(unsigned width,
                                                      unsigned height,
                                                          BOOL bScaleNotCrop)
{

  SetFrameSize(width, height);

  if (converter != NULL) 
    delete converter;
  
  desiredFrameWidth = width;
  desiredFrameHeight = height;

  converter = PColourConverter::Create(colourFormat, desiredColourFormat, width, height);
  if (converter == NULL) {
    PTRACE(3, "Failed to make a converter.");
    return FALSE;
  }

  if (converter->SetSrcFrameSize(width,height) == FALSE) {
    PTRACE(3, "Failed to set source frame size of a converter.");
    return FALSE;
  }
  
  if (converter->SetDstFrameSize(desiredFrameWidth, desiredFrameHeight, FALSE) == FALSE) {
    PTRACE(3, "Failed to set destination frame size (+scaling) of a converter.");
    return FALSE;
  }
  
  return TRUE;
}

BOOL PVideoInputDevice_1394AVC::SetColourFormatConverter(const PString &colourFmt)
{
  desiredColourFormat = colourFmt;
  return SetFrameSizeConverter(desiredFrameWidth, desiredFrameHeight, FALSE);
}

int RawISOHandler (raw1394handle_t handle, int channel, size_t length, u_int32_t * data)
{
  if (length < RAW_BUFFER_SIZE) {
    *(u_int32_t *) raw_buffer = length;
    memcpy (raw_buffer + 4, data, length);
  }
  return 0;
}
// End Of File ///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?