winvideods.c
来自「mediastreamer2是开源的网络传输媒体流的库」· C语言 代码 · 共 1,534 行 · 第 1/3 页
C
1,534 行
}
//RemoveGraphFromRot(s->rotregvalue);
if (s->m_pGraph!=NULL)
{
if (s->m_pNullRenderer!=NULL)
s->m_pGraph->RemoveFilter(s->m_pNullRenderer);
if (s->m_pIDXFilter!=NULL)
s->m_pGraph->RemoveFilter(s->m_pIDXFilter);
if (s->m_pDeviceFilter!=NULL)
s->m_pGraph->RemoveFilter(s->m_pDeviceFilter);
}
if (s->m_pNullRenderer)
s->m_pNullRenderer->Release();
if (s->m_pIDXFilter)
s->m_pIDXFilter->Release();
if (s->m_pDeviceFilter)
s->m_pDeviceFilter->Release();
if (s->m_pBuilder)
s->m_pBuilder->Release();
if (s->m_pControl)
s->m_pControl->Release();
if (s->m_pGraph)
s->m_pGraph->Release();
if (s->m_pDXFilter!=NULL)
s->m_pDXFilter->Release();
s->m_pNullRenderer=NULL;
s->m_pIDXFilter=NULL;
s->m_pDeviceFilter=NULL;
s->m_pBuilder=NULL;
s->m_pControl=NULL;
s->m_pGraph=NULL;
s->m_pDXFilter=NULL;
CoUninitialize();
s_callback = NULL;
flushq(&s->rq,0);
ms_message("v4w: checked device size=%ix%i format=%i (err=%i)", s->vsize.width, s->vsize.height, s->pix_fmt, i);
return i;
}
static int _v4w_start(V4wState *s, void *arg)
{
int i;
s->frame_count=-1;
i = v4w_open_videodevice(s);
if (s->rotregvalue==0){
//RemoveGraphFromRot(s->rotregvalue);
if (s->m_pGraph!=NULL)
{
if (s->m_pNullRenderer!=NULL)
s->m_pGraph->RemoveFilter(s->m_pNullRenderer);
if (s->m_pIDXFilter!=NULL)
s->m_pGraph->RemoveFilter(s->m_pIDXFilter);
if (s->m_pDeviceFilter!=NULL)
s->m_pGraph->RemoveFilter(s->m_pDeviceFilter);
}
if (s->m_pNullRenderer)
s->m_pNullRenderer->Release();
if (s->m_pIDXFilter)
s->m_pIDXFilter->Release();
if (s->m_pDeviceFilter)
s->m_pDeviceFilter->Release();
if (s->m_pBuilder)
s->m_pBuilder->Release();
if (s->m_pControl)
s->m_pControl->Release();
if (s->m_pGraph)
s->m_pGraph->Release();
if (s->m_pDXFilter!=NULL)
s->m_pDXFilter->Release();
s->m_pNullRenderer=NULL;
s->m_pIDXFilter=NULL;
s->m_pDeviceFilter=NULL;
s->m_pBuilder=NULL;
s->m_pControl=NULL;
s->m_pGraph=NULL;
s->m_pDXFilter=NULL;
CoUninitialize();
s_callback = NULL;
flushq(&s->rq,0);
ms_message("v4w: graph not started (err=%i)", i);
s->rotregvalue=0;
s->pix_fmt = MS_YUV420P;
}
return i;
}
static int _v4w_stop(V4wState *s, void *arg){
s->frame_count=-1;
if (s->rotregvalue>0){
HRESULT hr = s->m_pControl->Stop();
if(FAILED(hr))
{
ms_message("v4w: could not stop graph");
}
if (s->m_pGraph!=NULL)
{
if (s->m_pNullRenderer!=NULL)
s->m_pGraph->RemoveFilter(s->m_pNullRenderer);
if (s->m_pIDXFilter!=NULL)
s->m_pGraph->RemoveFilter(s->m_pIDXFilter);
if (s->m_pDeviceFilter!=NULL)
s->m_pGraph->RemoveFilter(s->m_pDeviceFilter);
}
if (s->m_pNullRenderer)
s->m_pNullRenderer->Release();
if (s->m_pIDXFilter)
s->m_pIDXFilter->Release();
if (s->m_pDeviceFilter)
s->m_pDeviceFilter->Release();
if (s->m_pBuilder)
s->m_pBuilder->Release();
if (s->m_pControl)
s->m_pControl->Release();
if (s->m_pGraph)
s->m_pGraph->Release();
if (s->m_pDXFilter!=NULL)
s->m_pDXFilter->Release();
s->m_pNullRenderer=NULL;
s->m_pIDXFilter=NULL;
s->m_pDeviceFilter=NULL;
s->m_pBuilder=NULL;
s->m_pControl=NULL;
s->m_pGraph=NULL;
s->m_pDXFilter=NULL;
CoUninitialize();
s_callback = NULL;
flushq(&s->rq,0);
ms_message("v4w: graph destroyed");
s->rotregvalue=0;
}
return 0;
}
static void v4w_uninit(MSFilter *f){
V4wState *s=(V4wState*)f->data;
int idx;
flushq(&s->rq,0);
ms_mutex_destroy(&s->mutex);
for (idx=0;idx<10;idx++)
{
if (s->mire[idx]==NULL)
break;
freemsg(s->mire[idx]);
}
if (s->rotregvalue>0){
HRESULT hr = s->m_pControl->Stop();
if(FAILED(hr))
{
ms_message("v4w: could not stop graph");
}
if (s->m_pGraph!=NULL)
{
if (s->m_pNullRenderer!=NULL)
s->m_pGraph->RemoveFilter(s->m_pNullRenderer);
if (s->m_pIDXFilter!=NULL)
s->m_pGraph->RemoveFilter(s->m_pIDXFilter);
if (s->m_pDeviceFilter!=NULL)
s->m_pGraph->RemoveFilter(s->m_pDeviceFilter);
}
if (s->m_pNullRenderer)
s->m_pNullRenderer->Release();
if (s->m_pIDXFilter)
s->m_pIDXFilter->Release();
if (s->m_pDeviceFilter)
s->m_pDeviceFilter->Release();
if (s->m_pBuilder)
s->m_pBuilder->Release();
if (s->m_pControl)
s->m_pControl->Release();
if (s->m_pGraph)
s->m_pGraph->Release();
if (s->m_pDXFilter!=NULL)
s->m_pDXFilter->Release();
s->m_pNullRenderer=NULL;
s->m_pIDXFilter=NULL;
s->m_pDeviceFilter=NULL;
s->m_pBuilder=NULL;
s->m_pControl=NULL;
s->m_pGraph=NULL;
s->m_pDXFilter=NULL;
CoUninitialize();
s_callback = NULL;
flushq(&s->rq,0);
ms_message("v4w: graph destroyed");
s->rotregvalue=0;
}
ms_free(s);
}
static mblk_t * v4w_make_nowebcam(V4wState *s){
#if defined(_WIN32_WCE)
return NULL;
#else
int idx;
int count;
if(s->mire[0]==NULL && s->frame_ind==0 && s->nowebcamimage[0] != '\0')
{
s->mire[0] = ms_load_jpeg_as_yuv(s->nowebcamimage,&s->vsize);
}
if (s->mire[0]==NULL && s->frame_ind==0){
/* load several images to fake a movie */
for (idx=0;idx<10;idx++)
{
s->mire[idx]=ms_load_nowebcam(&s->vsize, idx);
if (s->mire[idx]==NULL)
break;
}
if (idx==0)
s->mire[0]=ms_load_nowebcam(&s->vsize, -1);
}
for (count=0;count<10;count++)
{
if (s->mire[count]==NULL)
break;
}
s->frame_ind++;
if (count==0)
return NULL;
idx = s->frame_ind%count;
if (s->mire[idx]!=NULL)
return s->mire[idx];
return s->mire[0];
#endif
}
static void v4w_preprocess(MSFilter * obj){
V4wState *s=(V4wState*)obj->data;
if (s->rotregvalue==0)
_v4w_start(s, NULL);
if (s->rotregvalue==0)
s->fps=1;
}
static void v4w_postprocess(MSFilter * obj){
V4wState *s=(V4wState*)obj->data;
s->start_time=0;
s->frame_count=-1;
flushq(&s->rq,0);
}
static void v4w_process(MSFilter * obj){
V4wState *s=(V4wState*)obj->data;
mblk_t *m;
uint32_t timestamp;
int cur_frame;
if (s->frame_count==-1){
s->start_time=obj->ticker->time;
s->frame_count=0;
}
cur_frame=((obj->ticker->time-s->start_time)*s->fps/1000.0);
if (cur_frame>s->frame_count){
mblk_t *om=NULL;
ms_mutex_lock(&s->mutex);
/*keep the most recent frame if several frames have been captured */
if (s->rotregvalue!=0){
while((m=getq(&s->rq))!=NULL){
if (om!=NULL) freemsg(om);
om=m;
}
}else {
mblk_t *nowebcam = v4w_make_nowebcam(s);
if (nowebcam!=NULL){
om=dupmsg(nowebcam);
mblk_set_precious_flag(om,1);
}
}
ms_mutex_unlock(&s->mutex);
if (om!=NULL){
timestamp=obj->ticker->time*90;/* rtp uses a 90000 Hz clockrate for video*/
mblk_set_timestamp_info(om,timestamp);
ms_queue_put(obj->outputs[0],om);
/*ms_message("picture sent");*/
}
s->frame_count++;
}
}
static int v4w_set_fps(MSFilter *f, void *arg){
V4wState *s=(V4wState*)f->data;
s->fps=*((float*)arg);
s->frame_count=-1; /* reset counter used for fps */
return 0;
}
static int v4w_set_pix_fmt(MSFilter *f,void *arg){
V4wState *s=(V4wState*)f->data;
s->pix_fmt=*((MSPixFmt*)arg);
return 0;
}
static int v4w_get_pix_fmt(MSFilter *f,void *arg){
V4wState *s=(V4wState*)f->data;
if (s->rotregvalue==0){
_v4w_test(s, NULL); /* check supported format */ *((MSPixFmt*)arg) = (MSPixFmt)s->pix_fmt; return 0; } *((MSPixFmt*)arg) = (MSPixFmt)s->pix_fmt;
return 0;
}
static int v4w_set_vsize(MSFilter *f, void *arg){
V4wState *s=(V4wState*)f->data;
s->vsize=*((MSVideoSize*)arg);
return 0;
}
static int v4w_get_vsize(MSFilter *f, void *arg){
V4wState *s=(V4wState*)f->data;
MSVideoSize *vs=(MSVideoSize*)arg;
vs->width=s->vsize.width;
vs->height=s->vsize.height;
return 0;
}
static int v4w_set_device(MSFilter *f, void *arg){
V4wState *s=(V4wState*)f->data;
s->devidx=*((int*)arg);
return 0;
}
static int v4w_set_image(MSFilter *f, void *arg){
int idx;
V4wState *s=(V4wState*)f->data;
char *image = (char *)arg;
ms_mutex_lock(&s->mutex);
if (image!=NULL && image[0]!='\0')
snprintf(s->nowebcamimage, sizeof(s->nowebcamimage), "%s", image);
else
s->nowebcamimage[0] = '\0';
for (idx=0;idx<10;idx++)
{
if (s->mire[idx]==NULL)
break;
freemsg(s->mire[idx]);
s->mire[idx]=NULL;
}
s->frame_ind=0;
ms_mutex_unlock(&s->mutex);
return 0;
}
static int v4w_set_name(MSFilter *f, void *arg){ V4wState *s=(V4wState*)f->data; snprintf(s->dev, sizeof(s->dev), (char*)arg); return 0;}
static MSFilterMethod methods[]={
{ MS_FILTER_SET_FPS , v4w_set_fps },
{ MS_FILTER_SET_PIX_FMT , v4w_set_pix_fmt },
{ MS_FILTER_GET_PIX_FMT , v4w_get_pix_fmt },
{ MS_FILTER_SET_VIDEO_SIZE, v4w_set_vsize },
{ MS_FILTER_GET_VIDEO_SIZE, v4w_get_vsize },
{ MS_V4L_SET_DEVICE, v4w_set_device },
{ MS_FILTER_SET_IMAGE, v4w_set_image },
{ 0 , NULL }
};
#ifdef _MSC_VER
MSFilterDesc ms_v4w_desc={
MS_V4L_ID,
"MSV4w",
N_("A video4windows compatible source filter to stream pictures."),
MS_FILTER_OTHER,
NULL,
0,
1,
v4w_init,
v4w_preprocess,
v4w_process,
v4w_postprocess,
v4w_uninit,
methods
};
#else
MSFilterDesc ms_v4w_desc={
.id=MS_V4L_ID,
.name="MSV4w",
.text=N_("A video4windows compatible source filter to stream pictures."),
.ninputs=0,
.noutputs=1,
.category=MS_FILTER_OTHER,
.init=v4w_init,
.preprocess=v4w_preprocess,
.process=v4w_process,
.postprocess=v4w_postprocess,
.uninit=v4w_uninit,
.methods=methods
};
#endif
MS_FILTER_DESC_EXPORT(ms_v4w_desc)
static MSFilter *vfw_create_reader(MSWebCam *obj){
MSFilter *f=ms_filter_new_from_desc(&ms_v4w_desc);
v4w_set_name(f,obj->name); return f;
}
static void vfw_detect(MSWebCamManager *obj);
static void vfw_cam_init(MSWebCam *cam){
}
MSWebCamDesc ms_directx_cam_desc={
"DirectX Video Grabber",
&vfw_detect,
&vfw_cam_init,
&vfw_create_reader,
NULL
};
static void vfw_detect(MSWebCamManager *obj){
ICreateDevEnum *pCreateDevEnum = NULL;
IEnumMoniker *pEnumMoniker = NULL;
IMoniker *pMoniker = NULL;
HRESULT hr;
ULONG nFetched = 0;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (PVOID *)&pCreateDevEnum);
if(FAILED(hr))
{
return ;
}
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&pEnumMoniker, 0);
if (FAILED(hr) || pEnumMoniker == NULL) {
//printf("no device\n");
return ;
}
pEnumMoniker->Reset();
int pos=0;
while(S_OK == pEnumMoniker->Next(1, &pMoniker, &nFetched) )
{
IPropertyBag *pBag; hr = pMoniker->BindToStorage( 0, 0, IID_IPropertyBag, (void**) &pBag ); if( hr != S_OK ) continue; VARIANT var; VariantInit(&var); hr = pBag->Read( L"FriendlyName", &var, NULL ); if( hr != S_OK ) { pMoniker->Release(); continue; } //USES_CONVERSION; char szName[256]; WideCharToMultiByte(CP_ACP,0,var.bstrVal,-1,szName,256,0,0); VariantClear(&var); MSWebCam *cam=ms_web_cam_new(&ms_directx_cam_desc);
cam->name=ms_strdup(szName);
ms_web_cam_manager_add_cam(obj,cam);
pMoniker->Release(); pBag->Release(); pMoniker=NULL; pBag=NULL; }
pEnumMoniker->Release();
pCreateDevEnum->Release();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?