Linux下实现视频读取
V4L(video4linux是一些视频系统,视频软件、音频软件的基础,经常时候在需要采集图像的场合,如视频监控,webcam,可视电话,经常
使用在embedded linux中是linux嵌入式开发中经常使用的系统接口。它是linux内核提供给用户空间的编程接口,各种的视频和音频设备开
发相应的驱动程序后,就可以通过v4l提供的系统API来控制视频和音频设备,也就是说v4l分为两层,底层为音视频设备在内核中的驱动,上
层为系统提供的API,而对于我们来说需要的就是使用这些系统API。
V4L2是V4L的升级版本,为linux下视频设备程序提供了一套接口规范。包括一套数据结构和底层V4L2驱动接口。V4L2采用流水线的方式,
操作更简单直观,基本遵循打开视频设备、设置格式、处理数据、关闭设备,更多的具体操作通过ioctl函数来实现。
1、打开设备
int open(const char *device_name, int flags);
int fd = open("/dev/video0", O_RDONLY); //O_NONBLOCK --非阻塞(不推荐使用)
2、关闭设备 int close(int fd)
int ret = close(fd);
3、v4l2_capability 查看属性
int ioctl(int fd, int request, struct v4l2_capability *argp);
struct v4l2_capability
{
u8 driver[16]; // 驱动名字
u8 card[32]; // 设备名字
u8 bus_info[32]; // 设备在系统中的位置
u32 version; // 驱动版本号
u32 capabilities; // 设备支持的操作
u32 reserved[4]; // 保留字段
};
4、设置视频格式与制式
相关函数:
int ioctl(int fd, int request, struct v4l2_fmtdesc *argp);
int ioctl(int fd, int request, struct v4l2_format *argp);
相关结构体:
v4l2_cropcap 结构体用来设置摄像头的捕捉能力,在捕捉上视频时应先先设置
v4l2_cropcap 的 type 域,再通过 VIDIO_CROPCAP 操作命令获取设备捕捉能力的参数,保存于 v4l2_cropcap 结构体中,包括 bounds
(最大捕捉方框的左上角坐标和宽高),defrect(默认捕捉方框的左上角坐标和宽高)等。
v4l2_format 结构体用来设置摄像头的视频制式、帧格式等,在设置这个参数时应先填 好 v4l2_format 的各个域,如 type(传输流类型),
fmt.pix.width(宽),fmt.pix.heigth(高),fmt.pix.field(采样区域,如隔行采样),fmt.pix.pixelformat(采样类型,如 YUV4:2:2),
然后通过 VIDIO_S_FMT 操作命令设置视频捕捉格式。
struct v4l2_fmtdesc
{
u32 index; // 要查询的格式序号,应用程序设置
enum v4l2_buf_type type; // 帧类型,应用程序设置
u32 flags; // 是否为压缩格式
u8 description[32]; // 格式名称
u32 pixelformat; // 格式
u32 reserved[4]; // 保留
};
所有的视频格式可以能下面的方法查看
#define v4l2_fourcc(a, b, c, d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
All format : VIDIOC_ENUM_FMT, v4l2_fmtdesc
struct v4l2_format
{
enum v4l2_buf_type type; // 帧类型,应用程序设置
union fmt
{
struct v4l2_pix_format pix; // 视频设备使用
struct v4l2_window win;
struct v4l2_vbi_format vbi;
struct v4l2_sliced_vbi_format sliced;
u8 raw_data[200];
};
};
struct v4l2_pix_format
{
u32 width; // 帧宽,单位像素
u32 height; // 帧高,单位像素
u32 pixelformat; // 帧格式
enum v4l2_field field;
u32 bytesperline;
u32 sizeimage;
enum v4l2_colorspace colorspace;
u32 priv;
};
5、查看视频的帧率
int ioctl(int fd, int request, struct v4l2_streamparm parm* argp);
struct v4l2_streamparm parm;
parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
其中VIDIOC_G_PARM是用取帧率的,VIDIOC_S_PARM是用来设定帧率
6、定制ioctl函数
在内核目录下找到kernel/include/linux/videodev2.h头文件,你可查看所有的io控制的命令
/*
* Experimental, third param 0--video, 1--tracking
*/
#define VIDIOC_POCCESS_NOTIFY _IOW('V', 99, int) //add by Henry.Wen 20131126
实例:
#ifndef CAMERA_V4L2CAMERA_H
#define CAMERA_V4L2CAMERA_H #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <getopt.h> /* getopt_long() */
#include <fcntl.h> /* low-level i/o */
#include <unistd.h>
#include <errno.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <asm/types.h> /* for videodev2.h */
#include <linux/videodev2.h> #define CONFIG_CAMERA_UVC_INVAL_FRAMECNT 5 namespace v4l2
{
/**
* return error code
*/
enum _RET_ERROR_CODE
{
RET_ERROR_FAIL = -1,
RET_ERROR_OK = 0,
RET_ERROR_CAPTURE_NULL = -9999,
RET_ERROR_CAPTURE_NAME,
RET_ERROR_CAPTURE_CAPABILITY,
RET_ERROR_CAPTURE_FORMAT,
RET_ERROR_CAPTURE_BUFFER,
RET_ERROR_CAPTURE_OUTMEMORY,
RET_ERROR_CAPTURE_MMAP,
RET_ERROR_CAPTURE_FORM,
RET_ERROR_CAPTURE_MUMAP,
RET_ERROR_CAPTURE_VIDIOC,
}; /**
* Name: video_format enum
* Function: Describe formats V4L2 will support
*/
typedef enum _pFormat
{
UNKNOWN,
YUYV,
MJPEG,
YV12,
YU12,
NV12,
NV21,
H264,
}pFormat; /**
* frame width and height infomation
*/
typedef struct _V4l2Info
{
unsigned int width;
unsigned int height;
unsigned int stepWidth;
unsigned int length;
void* buffer;
}V4l2Info; /**
* caputre properties
*/
typedef struct _V4l2Capture
{
pFormat format;
char name[31];//dev_name
int fd;
unsigned int rate;
unsigned int quality;
unsigned int brightness;
V4l2Info v4l2Info;
}V4l2Capture; /**
*
*/
class V4l2Camera
{
public:
V4l2Camera();
virtual ~V4l2Camera(); public:
/**
* get the number of cameras
*
* @return the number of camera
*/
static int getNumberOfCameras(); /**
* initialize v4l2 device
* @param capture v4l2 capture handl
* @param width frame width
* @param height fram height
*
* @return 0/other successful or failure
*/
int InitDevice(V4l2Capture *capture, pFormat format, const char* name, unsigned int rate, unsigned int width, unsigned int height); /**
* initialize v4l2 device
* @param capture v4l2 capture handl
* @param width frame width
* @param height fram height
*
* @return 0/other successful or failure
*/
int UninitDevice(V4l2Capture *capture); /**
* Set v4l2 device brightness
* @param capture v4l2 capture handl
* @param value brightness value
*
* @return 0/other successful or failure
*/
int SetBrightness(V4l2Capture *capture, unsigned int value); /**
* start v4l2 device
* @param fd v4l2 capture handl
*
* @return 0/other successful or failure
*/
int StartDevice(int fd); /**
* stop v4l2 device
* @fd capture v4l2 capture handl
*
* @return 0/other successful or failure
*/
int StopDevice(int fd); /**
* Get frame data
* @param capture v4l2 capture handl
*
* @return 0/other successful or failure
*/
int GetFrame(V4l2Capture *capture); private:
int InitMmap(int fd); int xioctl(int fd, int request, void *arg); unsigned int GetCameraFormat(pFormat format); int AdjustV4l2Info(unsigned int& width, unsigned int& height); int MSleep(int fd, unsigned int msec); int MatchCameraAuto(int cameraId); private:
typedef struct _Buffers
{
void *start;
size_t length;
}V4l2Buffers; int m_stime;
V4l2Buffers* m_buffers;
unsigned int m_nBuffers;
V4l2Capture* m_capture; static int mNumberOfCameras;
static int mCameraIndex[10];
int mUsbCameraIvalidFrameCnt;
bool m_InitDevice;
};
}//end namespace
#endif //CAMERA_V4L2CAMERA_H
V4l2Camera.cpp
#include "V4l2Camera.h" namespace v4l2
{
#define BUFFERS_COUNT 4
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
#define MEMST_VALUE(x) memset(&(x), 0, sizeof (x)) const V4l2Info g_v4l2Info[] = {{160, 120}, {320, 240}, {640, 480}, {1024, 768}, {1200, 900}, {1440, 1080}, {1600, 900}, {1600, 1200}}; V4l2Camera::V4l2Camera()
{
// TODO Auto-generated constructor stub
m_capture = NULL;
mUsbCameraIvalidFrameCnt = 0;
m_InitDevice = false;
} V4l2Camera::~V4l2Camera()
{
// TODO Auto-generated destructor stub
if(m_capture)
UninitDevice(m_capture);
} int V4l2Camera::xioctl(int fd, int request, void *arg)
{
int r;
int nCount= 0; do
{
r = ioctl (fd, request, arg);
}while (RET_ERROR_FAIL == r && (EINTR == errno) && (++nCount < 100)); return r;
} int V4l2Camera::mNumberOfCameras = 0;
int V4l2Camera::mCameraIndex[] = {0}; unsigned int V4l2Camera::GetCameraFormat(pFormat format)
{
unsigned int ret = UNKNOWN;
switch(format)
{
case YUYV:
ret = V4L2_PIX_FMT_YUYV;
break;
case MJPEG:
ret = V4L2_PIX_FMT_MJPEG;
break;
case YV12:
ret = V4L2_PIX_FMT_YVU420;
break;
case YU12:
ret = V4L2_PIX_FMT_YUV420;
break;
case NV12:
ret = V4L2_PIX_FMT_NV12;
break;
case NV21:
ret = V4L2_PIX_FMT_NV21;
break;
case H264:
ret = V4L2_PIX_FMT_MPEG;
break;
default:
break;
}
return ret;
} int V4l2Camera::InitMmap(int fd)
{
int ret = RET_ERROR_OK;
struct v4l2_requestbuffers req;
req.count = BUFFERS_COUNT;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP; if (RET_ERROR_FAIL == xioctl (fd, VIDIOC_REQBUFS, &req) || req.count < 2)
{
return RET_ERROR_CAPTURE_BUFFER;
} m_buffers = (V4l2Buffers*)calloc(req.count, sizeof(V4l2Buffers)); if (!m_buffers)
{
return RET_ERROR_CAPTURE_OUTMEMORY;
} for (m_nBuffers = 0; m_nBuffers < req.count; ++m_nBuffers)
{
struct v4l2_buffer buf; MEMST_VALUE (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = m_nBuffers; if (RET_ERROR_FAIL == xioctl (fd, VIDIOC_QUERYBUF, &buf))
{
ret = RET_ERROR_CAPTURE_BUFFER;
break;
} m_buffers[m_nBuffers].length = buf.length;
m_buffers[m_nBuffers].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset); if (MAP_FAILED == m_buffers[m_nBuffers].start)
{
ret = RET_ERROR_CAPTURE_MMAP;
break;
}
}
return ret;
} int V4l2Camera::AdjustV4l2Info(unsigned int& width, unsigned int& height)
{
int ret = RET_ERROR_FAIL;
int index = 0;
for(int nCount = ARRAY_LEN(g_v4l2Info) - 1, i = nCount; i >= 0; --i)
{
if(width <= (g_v4l2Info[i].width + 50))
{
index = i;
ret = RET_ERROR_OK;
}
else if(0 != nCount)
{
width = g_v4l2Info[index].width;
height = g_v4l2Info[index].height;
break;
}
}
return ret;
} int V4l2Camera::getNumberOfCameras()
{
char cam_path[20];
int fd = -1, i=0;
struct v4l2_capability capability; mNumberOfCameras = 0;
memset(mCameraIndex,0x00,sizeof(mCameraIndex)); for (i = 0; i < 10; ++i)
{
memset(cam_path,0x00,20);
sprintf(cam_path, "/dev/video%d",i);
fd = open(cam_path, O_RDONLY);
if (fd < 0)
continue; memset(&capability, 0, sizeof(struct v4l2_capability));
if (ioctl(fd, VIDIOC_QUERYCAP, &capability) < 0)
{
//LOGE("Video device(%s): query capability not supported.\n", cam_path);
goto loop_continue;
} if ((capability.capabilities
& (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING))
!= (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING))
{
}
else
{
mCameraIndex[mNumberOfCameras] = i;
mNumberOfCameras++;
} loop_continue:
if (fd > 0)
{
close(fd);
fd = -1;
}
continue;
} return mNumberOfCameras;
} int V4l2Camera::MatchCameraAuto(int cameraId)
{
if (mNumberOfCameras <= 0 || mNumberOfCameras > 10 || cameraId < 0)
{
return -1;
} // search for camera ID normally
for (int i = 0; i < mNumberOfCameras; ++i)
{
if (cameraId == mCameraIndex[i])
{
return cameraId;
}
} if (mNumberOfCameras == 1)
{
return mCameraIndex[0];
} return cameraId > mCameraIndex[mNumberOfCameras -1] ? mCameraIndex[mNumberOfCameras -1] : mCameraIndex[0];
} int V4l2Camera::InitDevice(V4l2Capture *capture, pFormat format, const char* name, unsigned int rate, unsigned int width, unsigned int height)
{
// TODO Auto-generated function stub
struct stat st;
int fd = 0, nRealCameraNameLen = 0, nMinCameraNameLen = 0;
int ret = RET_ERROR_OK;
char szcameraID[4], szCameraName[20];
int cameraId = 0;
struct v4l2_capability cap;
struct v4l2_cropcap cropcap;
struct v4l2_crop crop; if(NULL == capture || NULL == name || 0 == rate || 0 == width || 0 == height) {
ret = RET_ERROR_CAPTURE_NULL;
goto InitDeviceFAILED;
} if ((nRealCameraNameLen = strlen(name)) < (nMinCameraNameLen =strlen("/dev/video0"))) {
ret = RET_ERROR_CAPTURE_NULL;
goto InitDeviceFAILED;
}
// Get camera ID memset(szcameraID,0x00,4);
for (int i=0;i<3;i++) {
if (nRealCameraNameLen >= (nMinCameraNameLen + i))
szcameraID[i] = name[nMinCameraNameLen - 1 + i];
} cameraId = atoi(szcameraID);
mNumberOfCameras = 0;
memset(mCameraIndex, 0x00, sizeof(mCameraIndex));
if (0 == getNumberOfCameras()) {
//LOGE("There is NO camera!");
ret = RET_ERROR_CAPTURE_NAME;
goto InitDeviceFAILED;
} if (-1 == (cameraId = MatchCameraAuto(cameraId))) {
//LOGE("There is NO camera!");
ret = RET_ERROR_CAPTURE_NAME;
goto InitDeviceFAILED;
} memset(szCameraName, 0x00, 20);
sprintf(szCameraName, "/dev/video%d", cameraId);
//LOGI("camera name is %s.", name);
//
if ((RET_ERROR_FAIL == stat (szCameraName, &st)) || (!S_ISCHR (st.st_mode))
|| (RET_ERROR_FAIL == (fd = open(szCameraName, O_RDWR | O_NONBLOCK, 0))))
{
ret = RET_ERROR_CAPTURE_NAME;
goto InitDeviceFAILED;
} if (RET_ERROR_FAIL == xioctl(fd, VIDIOC_QUERYCAP, &cap) || !(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
|| !(cap.capabilities & V4L2_CAP_STREAMING))
{
ret = RET_ERROR_CAPTURE_CAPABILITY;
goto InitDeviceFAILED;
} MEMST_VALUE(cropcap);
cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if(RET_ERROR_OK == xioctl (fd, VIDIOC_CROPCAP, &cropcap))
{
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
crop.c = cropcap.defrect; /* reset to default */ xioctl(fd, VIDIOC_S_CROP, &crop);
} struct v4l2_format fmt;
MEMST_VALUE (fmt); ret = GetCameraFormat(format);
if(UNKNOWN == ret) {
return RET_ERROR_CAPTURE_FORMAT;
goto InitDeviceFAILED;
} if(RET_ERROR_OK != AdjustV4l2Info(width, height))
{
ret = RET_ERROR_CAPTURE_FORM;
goto InitDeviceFAILED;
} //SetBrightness(capture, capture->brightness);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = width;
fmt.fmt.pix.height = height;
fmt.fmt.pix.pixelformat = ret;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
printf("%s(%d) pixel format is %d\n", __FUNCTION__,__LINE__,ret); if (RET_ERROR_FAIL == xioctl (fd, VIDIOC_S_FMT, &fmt)) {
ret = RET_ERROR_CAPTURE_FORMAT;
goto InitDeviceFAILED;
} if(RET_ERROR_OK != (ret = InitMmap(fd)) ) {// || RET_ERROR_OK != (ret = SetBrightness(capture, capture->brightness)))
goto InitDeviceFAILED;
} // set video frame rate
struct v4l2_streamparm parm;
parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (RET_ERROR_OK != ioctl(fd, VIDIOC_G_PARM, &parm)) {
//LOGI("VIDIOC_G_PARM fail....");
} parm.parm.capture.timeperframe.numerator = 1;
parm.parm.capture.timeperframe.denominator = rate;
if (RET_ERROR_OK != ioctl(fd, VIDIOC_S_PARM, &parm)) {
//LOGI("VIDIOC_S_PARM Fail....");
} //check setting of frame rate
memset(&parm, 0x00, sizeof(v4l2_streamparm));
parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(fd, VIDIOC_G_PARM, &parm);
if (ret != RET_ERROR_OK) {
//LOGI("VIDIOC_G_PARM fail....");
} capture->fd = fd;
capture->v4l2Info.width = fmt.fmt.pix.width;
capture->v4l2Info.height = fmt.fmt.pix.height;
capture->format = format;
capture->rate = rate;
capture->v4l2Info.length = fmt.fmt.pix.sizeimage;
capture->v4l2Info.stepWidth = fmt.fmt.pix.bytesperline;
capture->v4l2Info.buffer = malloc(fmt.fmt.pix.sizeimage);
strncpy(capture->name, name, sizeof(capture->name)); m_stime = 1000 / rate;
m_capture = capture;
m_InitDevice = true; return ret; InitDeviceFAILED:
if (fd >= 0)
{
close(fd);
fd = -1;
} return ret;
} int V4l2Camera::UninitDevice(V4l2Capture *capture)
{
// TODO Auto-generated function stub
printf("%s(%d)...[BEGIN]\n", __FUNCTION__, __LINE__);
int ret = RET_ERROR_OK;
if (!m_InitDevice) {
return ret;
} else {
m_InitDevice = false;
}
if (m_buffers) {
for (unsigned int i = 0; i < m_nBuffers; ++i) {
printf("%s(%d) munmap() i = %d\n", __FUNCTION__, __LINE__, i);
if (RET_ERROR_FAIL == munmap(m_buffers[i].start, m_buffers[i].length)) {
ret = RET_ERROR_CAPTURE_MUMAP;
break;
}
} if (RET_ERROR_OK == ret) {
printf("%s(%d) free(m_buffers)\n", __FUNCTION__, __LINE__);
free(m_buffers);
}
m_buffers = NULL;
if (capture) {
if (capture->v4l2Info.buffer) {
printf("%s(%d) free(capture->v4l2Info.buffer)\n", __FUNCTION__,
__LINE__);
free(capture->v4l2Info.buffer);
capture->v4l2Info.buffer = NULL;
} if (capture->fd >= 0) {
printf("%s(%d) close(capture->fd)\n", __FUNCTION__, __LINE__);
ret = close(capture->fd);
}
} }
printf("%s(%d)...[END]\n", __FUNCTION__, __LINE__);
return ret;
} int V4l2Camera::SetBrightness(V4l2Capture *capture, unsigned int value)
{
// TODO Auto-generated function stub
if(!capture || value > 10000)
return RET_ERROR_FAIL; struct v4l2_control control;
control.id = V4L2_CID_BRIGHTNESS;
control.value = 255; if(RET_ERROR_FAIL == xioctl(capture->fd, VIDIOC_S_CTRL, &control))
{
return RET_ERROR_FAIL;
}
capture->brightness = control.value; return RET_ERROR_OK;
} int V4l2Camera::StartDevice(int fd)
{
// TODO Auto-generated function stub
if(fd < 0)
return RET_ERROR_FAIL; int ret = RET_ERROR_OK;
for (unsigned int i = 0; i < m_nBuffers; ++i)
{
struct v4l2_buffer buf;
MEMST_VALUE(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i; if (RET_ERROR_FAIL == xioctl(fd, VIDIOC_QBUF, &buf))
{
ret = RET_ERROR_CAPTURE_VIDIOC;
break;
}
} enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (RET_ERROR_FAIL == xioctl(fd, VIDIOC_STREAMON, &type))
ret = RET_ERROR_CAPTURE_VIDIOC; return ret;
} int V4l2Camera::StopDevice(int fd)
{
// TODO Auto-generated function stub
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (RET_ERROR_FAIL == xioctl(fd, VIDIOC_STREAMOFF, &type))
{
return RET_ERROR_FAIL;
}
return 0;
} int V4l2Camera::MSleep(int fd, unsigned int msec)
{
fd_set fds;
FD_ZERO (&fds);
FD_SET (fd, &fds); struct timeval tv;
tv.tv_sec = msec;
tv.tv_usec = 0; return select (fd + 1, &fds, NULL, NULL, &tv);
} int V4l2Camera::GetFrame(V4l2Capture *capture)
{
// TODO Auto-generated function stub
if(!capture)
return RET_ERROR_FAIL; int fd = capture->fd; if(RET_ERROR_FAIL == MSleep(capture->fd, m_stime))
return RET_ERROR_FAIL; struct v4l2_buffer buf; MEMST_VALUE(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.reserved = 0; // Skip the first CONFIG_CAMERA_UVC_INVAL_FRAMECNT video frames
// because they are possibly invalid
if (mUsbCameraIvalidFrameCnt< CONFIG_CAMERA_UVC_INVAL_FRAMECNT) {
mUsbCameraIvalidFrameCnt++;
if(xioctl(fd, VIDIOC_DQBUF, &buf) >= 0) {
xioctl(fd, VIDIOC_QBUF, &buf);
}
return RET_ERROR_OK;
} if(RET_ERROR_FAIL == xioctl(fd, VIDIOC_DQBUF, &buf) || buf.index >= m_nBuffers)
{
return RET_ERROR_FAIL;
} memcpy(capture->v4l2Info.buffer, m_buffers[buf.index].start, buf.bytesused); if(RET_ERROR_FAIL == xioctl(fd, VIDIOC_QBUF, &buf))
return RET_ERROR_FAIL; return RET_ERROR_OK;
}
}//end namespace
Linux下实现视频读取的更多相关文章
- Linux下实现视频读取(二)---camera參数设定
Camera的可设置项极多,V4L2 支持了不少.但Sam之前对这些设置的使用方法和涵义都是在看videodev2.h中边看边理解.感觉很生涩. 直到写这篇blog时,才发现v4l2有专门的SPEC来 ...
- Linux下实现视频读取(三)---Buffer的准备和数据读取
前面主要介绍的是:V4L2 的一些设置接口,如亮度,饱和度.曝光时间,帧数,增益.白平衡等.今天看看V4L2 得到数据的几个关键ioctl,Buffer的申请和数据的抓取. 1. 初始化 Memory ...
- Linux下的视频字幕编辑
一.Linux下的字幕编辑软件 常用的有subtitleeditor, gnome-subtitles, gaupol 1.gnome-subtitles:不支持多字幕文件批量处理2.gaupol:全 ...
- 嵌入式Linux下MP4视频录制库MP4V2移植和简单介绍
**************************************************************************************************** ...
- Linux下从视频提取音频的方法
Linux下可以利用mencoder将视频里的音频提取出来.方法如下: 1.首先安装mencoder.对于Ubuntu来说,软件仓库里就有mencoder,可直接输入如下命令安装 sudo apt-g ...
- Linux 下 Bash配置文件读取
Linux安装时可能要修改的配置文件:/etc/profile./etc/bashrc(ubuntu没有这个文件,对应地,其有/etc/bash.bashrc文件.我用的是ubuntu系统,所以下面将 ...
- Linux下安装视频转换工具ffmpeg
ffmpeg下载地址:http://ffmpeg.org/releases/ 1.首先需要安装解码器集合(包含安装ffmpeg用到的所有解码器)下载地址: 链接:https://pan.baidu.c ...
- Linux下用C读取配置文件。类似ini这样。
Introduction ccl is the customizable configuration library, a collection of functions for applicatio ...
- 基于Linux的v4l2视频架构驱动编写(转载)
转自:http://www.linuxidc.com/Linux/2011-03/33022.htm 其实,我刚开始一直都不知道怎么写驱动,什么都不懂的,只知道我需要在做项目的过程中学习,所以,我就自 ...
随机推荐
- (转)Arcgis for JS之地图自适应调整
http://blog.csdn.net/gisshixisheng/article/details/42675897 概述:本节讲述的内容为当浏览器大小发生变化或者地图展示区域的大小发生变化时,地图 ...
- java这个404你能解决吗?
前言 本文首发于公众号[我的小碗汤]本公众号免费提供csdn下载服务,海量IT学习资源,如果你准备入IT坑,励志成为优秀的程序猿,那么这些资源很适合你,包括但不限于java.go.python.spr ...
- Tomcat jsp页面显示有问题
1.干掉tomcat下的work文件夹里面的东西,让jsp文件重新编译,相当于清楚缓存 2.work 里面是 jsp 编译的类 ,只要jsp 被访问了,就会被编译,就会生成相应的类 3.tomcat下 ...
- PAT_A1105#Spiral Matrix
Source: PAT A1105 Spiral Matrix (25 分) Description: This time your job is to fill a sequence of N po ...
- Labview学习笔记(一)
一.概述 Labview是一种工业标准图形化编程工具,主要用于开发测试.测量与控制系统,拥有一个可以完成任何编程任务的庞大函数库,包括数据采集.GPIB.串口控制.数据分析.数据显示及数据存储等. L ...
- 51nod1079 中国剩余定理【数论】
一个正整数K,给出K Mod 一些质数的结果,求符合条件的最小的K.例如,K % 2 = 1, K % 3 = 2, K % 5 = 3.符合条件的最小的K = 23. Input 第1行:1个数N表 ...
- 从零开始创建一个 PHP 扩展
创建一个扩展的基本步骤都有哪些.示例中,我们将实现如下功能: <?phpecho say();?> 输出内容: $ php ./test.php$ hello word 在扩展中实现一个s ...
- GOF23设计模式之原型模式
GOF23设计模式之原型模式 1)通过 new 产生一个对象需要飞船繁琐的数据准备或访问权限,则可以使用原型模式. 2)就算 java 中的克隆技术,以某个对象为原型,复制出新的对象.显然,新的对象具 ...
- Ajax跨域访问的问题
在本机调试Ajax的时候如果服务器在另外的网址,Chrome会出现 Origin is not allowed by Access-Control-Allow-Origin. 解决方案是禁用Chro ...
- POJ1789&ZOJ2158--Truck History【最小生成树变形】
链接:http://poj.org/problem?id=1789 题意:卡车公司有悠久的历史,它的每一种卡车都有一个唯一的字符串来表示,长度为7,它的全部卡车(除了第一辆)都是由曾经的卡车派生出来的 ...