⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video_v4l2_source.cpp

📁 MPEG4音频视频压缩编码(含G.711/ACC/H.261等)
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is MPEG4IP. *  * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2003-2005.  All Rights Reserved. *  * Contributor(s):  *              Waqar Mohsin            wmohsin@cisco.com *              Bill May     wmay@cisco.com *              Charlie Normand  charlienormand@cantab.net alias cpn24 */#include "mp4live.h"#include <sys/mman.h>#include "video_v4l_source.h"#include "video_util_rgb.h"#include "video_util_filter.h"#include "video_util_convert.h"const char *get_linux_video_type (void){  return "V4L2";}int CV4LVideoSource::ThreadMain(void) {  debug_message("v4l2 thread start");  m_v4l_mutex = NULL;  m_waiting_frames_return = false;  while (true) {    int rc;   if (m_source && m_waiting_frames_return == false) {     rc = SDL_SemTryWait(m_myMsgQueueSemaphore);    } else {      rc = SDL_SemWait(m_myMsgQueueSemaphore);    }    // semaphore error    if (rc == -1) {      break;    }     // message pending    if (rc == 0) {      CMsg* pMsg = m_myMsgQueue.get_message();            if (pMsg != NULL) {        switch (pMsg->get_value()) {        case MSG_NODE_STOP_THREAD:          while (DoStopCapture() == false) {	    SDL_Delay(10);	// ensure things get cleaned up	    debug_message("waiting for stop thread");	  }          delete pMsg;	  debug_message("v4l2 thread exit");          return 0;        case MSG_NODE_START:          DoStartCapture();	  debug_message("v4l2 thread start capture");          break;        case MSG_NODE_STOP:	  debug_message("v4l2 thread stop capture");          DoStopCapture();          break;        }        delete pMsg;      }     }    if (m_source) {      try {        ProcessVideo();      }      catch (...) {        DoStopCapture();        break;      }    } else {      DoStopCapture();    }  }  debug_message("v4l2 thread exit");  return -1;}void CV4LVideoSource::DoStartCapture(void){  if (m_source) {    return;  }  if (m_v4l_mutex == NULL)   m_v4l_mutex = SDL_CreateMutex();  if (!Init()) return;  m_source = true;}bool CV4LVideoSource::DoStopCapture(void){  if (m_source) {    debug_message("dostopcapture - releasing device");  ReleaseDevice();  }  m_source = false;  if (ReleaseBuffers() == false) {    debug_message("releasebuffers false");    return false;  }  SDL_DestroyMutex(m_v4l_mutex);  m_v4l_mutex = NULL;  return true;}bool CV4LVideoSource::Init(void){  m_pConfig->CalculateVideoFrameSize();  InitVideo(true);  SetVideoSrcSize(                  m_pConfig->GetIntegerValue(CONFIG_VIDEO_RAW_WIDTH),                  m_pConfig->GetIntegerValue(CONFIG_VIDEO_RAW_HEIGHT),                  m_pConfig->GetIntegerValue(CONFIG_VIDEO_RAW_WIDTH));  if (!InitDevice()) return false;  m_maxPasses = (u_int8_t)(m_videoSrcFrameRate + 0.5);  return true;}static const uint32_t formats[] = {  V4L2_PIX_FMT_YVU420,  V4L2_PIX_FMT_YUV420,  V4L2_PIX_FMT_YUYV,  V4L2_PIX_FMT_UYVY,  V4L2_PIX_FMT_YYUV,  V4L2_PIX_FMT_NV12,  V4L2_PIX_FMT_RGB24,  V4L2_PIX_FMT_BGR24,};bool CV4LVideoSource::InitDevice(void){  int rc;  SDL_LockMutex(m_v4l_mutex);  if (m_buffers != NULL) {    unreleased_capture_buffers_t *p =       MALLOC_STRUCTURE(unreleased_capture_buffers_t);    debug_message("creating unreleased capture buffer, version %u", 		  m_hardware_version);    p->buffer_list = m_buffers;    m_buffers = NULL;    p->hardware_version = m_hardware_version;    p->next = m_unreleased_buffers_list;    m_unreleased_buffers_list = p;  }  m_hardware_version++;  SDL_UnlockMutex(m_v4l_mutex);  const char* deviceName = m_pConfig->GetStringValue(CONFIG_VIDEO_SOURCE_NAME);  int buftype = V4L2_BUF_TYPE_VIDEO_CAPTURE;  bool pass = false;  v4l2_std_id std;  if (m_videoDevice != -1)    debug_message("video device already open !!!");  // open the video device  m_videoDevice = open(deviceName, O_RDWR);  if (m_videoDevice < 0) {    error_message("Failed to open %s: %s", deviceName, strerror(errno));    return false;  }  // query device capabilities  struct v4l2_capability capability;  memset(&capability, 0, sizeof(capability));  rc = ioctl(m_videoDevice, VIDIOC_QUERYCAP, &capability);  if (rc < 0) {    error_message("Failed to query video capabilities for %s", deviceName);    goto failure;  }  // make sure device supports video capture  if (!(capability.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {    error_message("Device %s is not capable of video capture!", deviceName);    goto failure;  }  // query attributes of video input  struct v4l2_input input;  memset(&input, 0, sizeof(input));  uint input_value;  input_value = m_pConfig->GetIntegerValue(CONFIG_VIDEO_INPUT);  if (m_pConfig->m_videoCapabilities != NULL) {    uint compare_value = m_pConfig->m_videoCapabilities->m_numInputs;    if (compare_value > 0) compare_value--;    if (input_value > compare_value) {      input_value = 0;      m_pConfig->SetIntegerValue(CONFIG_VIDEO_INPUT, input_value);      error_message("Video input value exceed capabilities; replacing with 0");    }  }  input.index = input_value;  rc = ioctl(m_videoDevice, VIDIOC_ENUMINPUT, &input);  if (rc < 0) {    error_message("Failed to enumerate video input %d for %s",                  input.index, deviceName);    //goto failure;  }  // select video input  rc = ioctl(m_videoDevice, VIDIOC_S_INPUT, &input.index);  if (rc < 0) {    error_message("Failed to select video input %d for %s",                  input.index, deviceName);    //goto failure;  }    // select video input standard type  switch(m_pConfig->GetIntegerValue(CONFIG_VIDEO_SIGNAL)) {  case VIDEO_SIGNAL_PAL:    std = V4L2_STD_PAL;    break;  case VIDEO_SIGNAL_NTSC:    std = V4L2_STD_NTSC;    break;  case VIDEO_SIGNAL_SECAM:    std = V4L2_STD_SECAM;    break;  }  rc = ioctl(m_videoDevice, VIDIOC_S_STD, &std);  if (rc < 0) {    error_message("Failed to select video standard for %s", deviceName);    //goto failure;  }  if (m_pConfig->GetIntegerValue(CONFIG_VIDEO_SIGNAL) == VIDEO_SIGNAL_NTSC) {    m_videoSrcFrameRate = VIDEO_NTSC_FRAME_RATE;  } else {    m_videoSrcFrameRate = VIDEO_PAL_FRAME_RATE;  }  // input source has a tuner  if (input.type == V4L2_INPUT_TYPE_TUNER) {    // get tuner info    if ((int32_t)m_pConfig->GetIntegerValue(CONFIG_VIDEO_TUNER) == -1) {      m_pConfig->SetIntegerValue(CONFIG_VIDEO_TUNER, 0);    }    // query tuner attributes    struct v4l2_tuner tuner;    memset(&tuner, 0, sizeof(tuner));    tuner.index = m_pConfig->GetIntegerValue(CONFIG_VIDEO_TUNER);    //tuner.index = input.tuner;    rc = ioctl(m_videoDevice, VIDIOC_G_TUNER, &tuner);    if (rc < 0) {      error_message("Failed to query tuner attributes for %s", deviceName);    }    // tuner is an analog TV tuner    if (tuner.type == V4L2_TUNER_ANALOG_TV) {      // tune in the desired frequency (channel)      struct CHANLISTS* pChannelList = chanlists;      struct CHANLIST* pChannel =        pChannelList[m_pConfig->GetIntegerValue(CONFIG_VIDEO_CHANNEL_LIST_INDEX)].list;      unsigned long videoFrequencyKHz =        pChannel[m_pConfig->GetIntegerValue(CONFIG_VIDEO_CHANNEL_INDEX)].freq;      unsigned long videoFrequencyTuner =        ((videoFrequencyKHz / 1000) << 4) | ((videoFrequencyKHz % 1000) >> 6);      struct v4l2_frequency frequency;      memset(&frequency, 0, sizeof(frequency));      frequency.tuner = tuner.index;      frequency.type = tuner.type;      frequency.frequency = videoFrequencyTuner;      rc = ioctl(m_videoDevice, VIDIOC_S_FREQUENCY, &frequency);      if (rc < 0) {        error_message("Failed to set video tuner frequency for %s", deviceName);      }    }  }  // query image format    // select image format  uint32_t width, height;  width = m_pConfig->GetIntegerValue(CONFIG_VIDEO_RAW_WIDTH);  height = m_pConfig->GetIntegerValue(CONFIG_VIDEO_RAW_HEIGHT);  if (strncasecmp(m_pConfig->GetStringValue(CONFIG_VIDEO_FILTER),		  VIDEO_FILTER_DECIMATE,		  strlen(VIDEO_FILTER_DECIMATE)) == 0) {    uint32_t max_width, max_height;    switch (m_pConfig->GetIntegerValue(CONFIG_VIDEO_SIGNAL)) {    case VIDEO_SIGNAL_NTSC:      max_width = 720;      max_height = 480;      break;    case VIDEO_SIGNAL_PAL:    case VIDEO_SIGNAL_SECAM:    default:      max_width = 768;      max_height = 576;      break;    }    if (max_width < width * 2 || max_height < height * 2) {      error_message("Decimate filter choosen with too large video size - %ux%u max %ux%u",		    width, height, max_width / 2, max_height / 2);    } else {      m_decimate_filter = true;      width *= 2;      height *= 2;    }  }  for (uint ix = 0;        pass == false && ix < NUM_ELEMENTS_IN_ARRAY(formats);        ix++) {    struct v4l2_format format;    memset(&format, 0, sizeof(format));    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;    rc = ioctl(m_videoDevice, VIDIOC_G_FMT, &format);    if (rc < 0) {      error_message("Failed to query video image format for %s", deviceName);      goto failure;    }    format.fmt.pix.width = width;    format.fmt.pix.height = height;    format.fmt.pix.pixelformat = formats[ix];    rc = ioctl(m_videoDevice, VIDIOC_S_FMT, &format);    if (rc == 0 && format.fmt.pix.pixelformat == formats[ix]) {      m_format = formats[ix];      pass = true;    } else {      debug_message("format %c%c%c%c return code %d", 		    formats[ix] & 0xff,		    formats[ix] >> 8,		    formats[ix] >> 16,		    formats[ix] >> 24,		    rc);    }    if (format.fmt.pix.width != width) {      error_message("format %u - returned width %u not selected %u", 		    formats[ix], format.fmt.pix.width, width);    }    if (format.fmt.pix.height != height) {      error_message("format %u - returned height %u not selected %u", 

⌨️ 快捷键说明

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