📄 nowebcam.c
字号:
/*mediastreamer2 library - modular sound and video processing and streamingCopyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org)This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/#ifdef HAVE_CONFIG_H#include "mediastreamer-config.h"#endif#include "mediastreamer2/mscommon.h"#include "mediastreamer2/msvideo.h"#include "mediastreamer2/msfilter.h"#include "mediastreamer2/msticker.h"#include "mediastreamer2/mswebcam.h"#include "ffmpeg-priv.h"#include <sys/stat.h>#ifdef WIN32#include <fcntl.h>#include <sys/types.h>#include <io.h>#include <stdio.h>#include <malloc.h>#endifstatic mblk_t *jpeg2yuv(uint8_t *jpgbuf, int bufsize, MSVideoSize *reqsize){ AVCodecContext av_context; int got_picture=0; AVFrame orig; AVPicture dest; mblk_t *ret; struct SwsContext *sws_ctx; avcodec_get_context_defaults(&av_context); if (avcodec_open(&av_context,avcodec_find_decoder(CODEC_ID_MJPEG))<0){ ms_error("jpeg2yuv: avcodec_open failed"); return NULL; } if (avcodec_decode_video(&av_context,&orig,&got_picture,jpgbuf,bufsize)<0){ ms_error("jpeg2yuv: avcodec_decode_video failed"); avcodec_close(&av_context); return NULL; } ret=allocb(avpicture_get_size(PIX_FMT_YUV420P,reqsize->width,reqsize->height),0); ret->b_wptr=ret->b_datap->db_lim; avpicture_fill(&dest,ret->b_rptr,PIX_FMT_YUV420P,reqsize->width,reqsize->height); sws_ctx=sws_getContext(av_context.width,av_context.height,PIX_FMT_YUV420P, reqsize->width,reqsize->height,PIX_FMT_YUV420P,SWS_FAST_BILINEAR, NULL, NULL, NULL); if (sws_scale(sws_ctx,orig.data,orig.linesize,0,av_context.height,dest.data,dest.linesize)<0){ ms_error("jpeg2yuv: sws_scale() failed."); } sws_freeContext(sws_ctx); avcodec_close(&av_context); return ret;}mblk_t *ms_load_jpeg_as_yuv(const char *jpgpath, MSVideoSize *reqsize){ mblk_t *m=NULL; struct stat statbuf; uint8_t *jpgbuf;#if !defined(_MSC_VER) int fd=open(jpgpath,O_RDONLY);#else int fd=_open(jpgpath,O_RDONLY);#endif if (fd!=-1){ fstat(fd,&statbuf); jpgbuf=(uint8_t*)alloca(statbuf.st_size);#if !defined(_MSC_VER) read(fd,jpgbuf,statbuf.st_size);#else _read(fd,jpgbuf,statbuf.st_size);#endif m=jpeg2yuv(jpgbuf,statbuf.st_size,reqsize); }else{ ms_error("Cannot load %s",jpgpath); } return m;}#ifndef PACKAGE_DATA_DIR#define PACKAGE_DATA_DIR "."#endif#ifndef NOWEBCAM_JPG#define NOWEBCAM_JPG "nowebcamCIF"#endifmblk_t *ms_load_nowebcam(MSVideoSize *reqsize, int idx){ char tmp[256]; if (idx<0) snprintf(tmp, sizeof(tmp), "%s/images/%s.jpg", PACKAGE_DATA_DIR, NOWEBCAM_JPG); else snprintf(tmp, sizeof(tmp), "%s/images/%s%i.jpg", PACKAGE_DATA_DIR, NOWEBCAM_JPG, idx); return ms_load_jpeg_as_yuv(tmp,reqsize);}typedef struct _SIData{ MSVideoSize vsize; int index; uint64_t lasttime; mblk_t *pic;}SIData;void static_image_init(MSFilter *f){ SIData *d=(SIData*)ms_new(SIData,1); d->vsize.width=MS_VIDEO_SIZE_CIF_W; d->vsize.height=MS_VIDEO_SIZE_CIF_H; d->index=-1; d->lasttime=0; d->pic=NULL; f->data=d;}void static_image_uninit(MSFilter *f){ ms_free(f->data);}void static_image_preprocess(MSFilter *f){ SIData *d=(SIData*)f->data; d->pic=ms_load_nowebcam(&d->vsize,d->index);}void static_image_process(MSFilter *f){ SIData *d=(SIData*)f->data; /*output a frame every second*/ if ((f->ticker->time - d->lasttime>1000) || d->lasttime==0){ if (d->pic) { mblk_t *o=dupb(d->pic); /*prevent mirroring at the output*/ mblk_set_precious_flag(o,1); ms_queue_put(f->outputs[0],o); } d->lasttime=f->ticker->time; }}void static_image_postprocess(MSFilter *f){ SIData *d=(SIData*)f->data; if (d->pic) { freemsg(d->pic); d->pic=NULL; }}int static_image_set_vsize(MSFilter *f, void* data){ SIData *d=(SIData*)f->data; d->vsize=*(MSVideoSize*)data; return 0;}int static_image_get_pix_fmt(MSFilter *f, void *data){ *(MSPixFmt*)data=MS_YUV420P; return 0;}MSFilterMethod static_image_methods[]={ { MS_FILTER_SET_VIDEO_SIZE, static_image_set_vsize }, { MS_FILTER_GET_PIX_FMT, static_image_get_pix_fmt }, { 0,0 }};MSFilterDesc ms_static_image_desc={ MS_STATIC_IMAGE_ID, "MSStaticImage", "A filter that outputs a static image.", MS_FILTER_OTHER, NULL, 0, 1, static_image_init, static_image_preprocess, static_image_process, static_image_postprocess, static_image_uninit, static_image_methods};MS_FILTER_DESC_EXPORT(ms_static_image_desc)static void static_image_detect(MSWebCamManager *obj);static void static_image_cam_init(MSWebCam *cam){ cam->name=ms_strdup("Static picture");}static MSFilter *static_image_create_reader(MSWebCam *obj){ return ms_filter_new_from_desc(&ms_static_image_desc);}MSWebCamDesc static_image_desc={ "StaticImage", &static_image_detect, &static_image_cam_init, &static_image_create_reader, NULL};static void static_image_detect(MSWebCamManager *obj){ MSWebCam *cam=ms_web_cam_new(&static_image_desc); ms_web_cam_manager_add_cam(obj,cam);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -