接嵌入式網絡視頻採集源程序servfox解析01
跟蹤進入 init_videoIn()
/*******************************************************************************************************
init_videoIn()函數在spcav4l.c中定義,這個函數主要用來初始化視頻採集設備。
int
init_videoIn (struct vdIn *vd, char *device, int width, int height,int format, int grabmethod)
{
/*************************************************************************************
它的幾個參數是由server.c中傳遞進來的:
if (init_videoIn(&videoIn, videodevice, width, height, format,grabmethod) != 0)
其中
videoIn;在spcav4l.h中定義的struct vdIn videoIn結構體
videodevice = "/dev/video0"; //前面輸入的
int width = 352;(640)
int height = 288;(320)
int format = VIDEO_PALETTE_JPEG;
int grabmethod = 1;
**************************************************************************************/
int err = -1;
int i;
if (vd == NULL || device == NULL)
return -1;
if (width == 0 || height == 0)
return -1;
if(grabmethod < 0 || grabmethod > 1)
grabmethod = 1; //read by default,設置read方式爲默認方式
/*************************************************************************************
// check format檢查格式,
我們先來看一下 struct vdIn結構體,在spcav4l.h中定義 ,它是對 Video4Linux視頻設備數據
結構的定義。
struct vdIn {
int fd; //設備
描述符,
文件描述符
char *videodevice ; //設備,
視頻捕捉接口文件
struct video_mmap vmmap;
struct video_capability videocap;
// 包含設備的基本信息(設備名稱、支持的最大最小分辨率、信號源 信息等)
int mmapsize;
struct video_mbuf videombuf;
//映射的幀信息,實際是映射到攝像頭存儲緩衝區的幀信息,包括幀的 大小(size),最多支持的幀數(frames) 每幀相對基址的偏移(offset)
struct video_picture videopict;
//採集圖像的各種屬性
struct video_window videowin;
struct video_channel videochan;
int cameratype ;
//
是否能capture,彩色還是黑白,是否 能裁剪等等
char *cameraname;
//設備名稱
char bridge[9];
int sizenative; // available size in jpeg
int sizeothers; // others palette
int palette; // available palette
int norme ; // set spca506 usb video grabber
int channel ; // set spca506 usb video grabber
//信號源個數
int grabMethod ;
unsigned char *pFramebuffer;
//指向內存映射的指針
unsigned char *ptframe[4];
//指向壓縮後的幀的指針數組
int framelock[4];
pthread_mutex_t grabmutex;
// 視頻採集線程和傳輸線程的互斥信號
int framesizeIn ;
// 視頻幀的大小
volatile int frame_cour;
// 指向壓縮後的幀的指針數組下標
int bppIn;
// 採集的視頻幀的BPP
--- --------------------------------------------------------------------------------------------
我們在流媒體文件的編碼過程中總是試圖得到最佳的圖像質量,這可以通過調整編碼過程中幀的 大小或編碼碼率來實現。在此可通過位每像素(BPP,BitPerPixel)來確定幀的大小或編碼碼率,從而 得到理想的圖像質量。
位每像素(BPP)是通過調整幀的大小或編碼碼率得到最佳圖像質量的一個重要參考指標.
如果已確認要編碼的視頻圖像幀的大小,但不確定採用何種編碼碼率可以得到最佳的編碼圖像質量, 可採用如公式1確定編碼碼率。
公式1:編碼碼率=位每像素×幀率×寬度×高度
(Bitrate=BPP×FrameRate×Width×Height )
----------------------------------------------------------------------------------------------------
int hdrwidth;
// 採集的視頻幀的寬度
int hdrheight;
// 採集的視頻幀的高度
int formatIn;
//採集的視頻幀的格式
int signalquit;
//停止視頻採集的信號
};
**************************************************************************************/
vd->videodevice = NULL;
vd->cameraname = NULL;
vd->videodevice = NULL;
vd->videodevice = (char *) realloc (vd->videodevice, 16);
vd->cameraname = (char *) realloc (vd->cameraname, 32);
/*************************************************************************************
realloc
原型:extern void *realloc(void *mem_address, unsigned int newsize);
用法:#include <stdlib.h> 有些編譯器需要#include <alloc.h>
功能:改變mem_address所指內存區域的大小爲newsize長度
。
說明:如果重新分配成功則返回指向被分配內存的指針
,否則返回空指針NULL。
當內存不再使用時,應使用free()函數將內存塊釋放。
注意:這裏原始內存中的數據還是保持不變的。
**************************************************************************************/
snprintf (vd->videodevice, 12, "%s", device);
/*************************************************************************************
把server.c中傳遞進來的device指向的videodevice = "/dev/video0"複製到 vd->videodevice中
使 vd->videodevice就指向 "/dev/video0"
**************************************************************************************/
if(debug) printf("video %s /n",vd->videodevice);
memset (vd->cameraname, 0, sizeof (vd->cameraname));
memset(vd->bridge, 0, sizeof(vd->bridge));
vd->signalquit = 1; //信號設置
vd->hdrwidth = width;//傳遞寬高
vd->hdrheight = height;
/* compute the max frame size */
vd->formatIn = format; //傳進來的 format = VIDEO_PALETTE_JPEG;
vd->bppIn = GetDepth (vd->formatIn);
/**************************************************************************************
GetDepth()是 前面聲明的函數, spcav4l.c 後面有定義
static int
GetDepth (int format)
{
int depth;
switch (format)
{
case VIDEO_PALETTE_JPEG:
{
depth = 8;
}
break;
case VIDEO_PALETTE_RAW:
{
depth = 8;
}
break;
case VIDEO_PALETTE_YUV420P:
{
depth = (8 * 3) >> 1;
}
break;
case VIDEO_PALETTE_RGB565:
depth = 16;
break;
case VIDEO_PALETTE_RGB24:
depth = 24;
break;
case VIDEO_PALETTE_RGB32:
{
depth = 32;
}
break;
default:
depth = -1;
break;
}
return depth;
}
*****************************************************************************************/
vd->grabMethod = grabmethod; //mmap or read
vd->pFramebuffer = NULL;
/* init and check all setting */
err = init_v4l (vd);
跟蹤進入
init_v4l (vd)
**************************************************************************************/
init_v4l (vd)是
前面聲明的函數,後面有定義,執行videodevice = "/dev/video0"的打開,
我們跟蹤進入
init_v4l (vd)來看看,看看它裏面做了哪些工作
跟蹤進入 init_v4l (vd)
**************************************************************************************/
init_videoIn()函數還沒有完,請看下一篇:嵌入式網絡視頻採集源程序servfox解析03