source: mediastreamer2/linphone/mediastreamer2/src/nowebcam.c @ 180:ecf35790a355

Last change on this file since 180:ecf35790a355 was 180:ecf35790a355, checked in by smorlat <smorlat@…>, 4 years ago
  • allow setting of nowebcam and remote ring path

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@183 3f6dc0c8-ddfe-455d-9043-3cd528dc4637

File size: 6.5 KB
Line 
1/*
2mediastreamer2 library - modular sound and video processing and streaming
3Copyright (C) 2006  Simon MORLAT (simon.morlat@linphone.org)
4
5This program is free software; you can redistribute it and/or
6modify it under the terms of the GNU General Public License
7as published by the Free Software Foundation; either version 2
8of the License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18*/
19
20#ifdef HAVE_CONFIG_H
21#include "mediastreamer-config.h"
22#endif
23
24#include "mediastreamer2/mscommon.h"
25#include "mediastreamer2/msvideo.h"
26#include "mediastreamer2/msfilter.h"
27#include "mediastreamer2/msticker.h"
28#include "mediastreamer2/mswebcam.h"
29
30#include "ffmpeg-priv.h"
31
32#include <sys/stat.h>
33
34#ifdef WIN32
35#include <fcntl.h>
36#include <sys/types.h>
37#include <io.h>
38#include <stdio.h>
39#include <malloc.h>
40#endif
41
42static mblk_t *jpeg2yuv(uint8_t *jpgbuf, int bufsize, MSVideoSize *reqsize){
43        AVCodecContext av_context;
44        int got_picture=0;
45        AVFrame orig;
46        AVPicture dest;
47        mblk_t *ret;
48        struct SwsContext *sws_ctx;
49
50        avcodec_get_context_defaults(&av_context);
51        if (avcodec_open(&av_context,avcodec_find_decoder(CODEC_ID_MJPEG))<0){
52                ms_error("jpeg2yuv: avcodec_open failed");
53                return NULL;
54        }
55        if (avcodec_decode_video(&av_context,&orig,&got_picture,jpgbuf,bufsize)<0){
56                ms_error("jpeg2yuv: avcodec_decode_video failed");
57                avcodec_close(&av_context);
58                return NULL;
59        }
60        ret=allocb(avpicture_get_size(PIX_FMT_YUV420P,reqsize->width,reqsize->height),0);
61        ret->b_wptr=ret->b_datap->db_lim;
62        avpicture_fill(&dest,ret->b_rptr,PIX_FMT_YUV420P,reqsize->width,reqsize->height);
63       
64        sws_ctx=sws_getContext(av_context.width,av_context.height,PIX_FMT_YUV420P,
65                reqsize->width,reqsize->height,PIX_FMT_YUV420P,SWS_FAST_BILINEAR,
66                NULL, NULL, NULL);
67        if (sws_scale(sws_ctx,orig.data,orig.linesize,0,av_context.height,dest.data,dest.linesize)<0){
68                ms_error("jpeg2yuv: sws_scale() failed.");
69        }
70        sws_freeContext(sws_ctx);
71        avcodec_close(&av_context);
72        return ret;
73}
74
75mblk_t *ms_load_jpeg_as_yuv(const char *jpgpath, MSVideoSize *reqsize){
76        mblk_t *m=NULL;
77        struct stat statbuf;
78        uint8_t *jpgbuf;
79#if !defined(_MSC_VER)
80        int fd=open(jpgpath,O_RDONLY);
81#else
82        int fd=_open(jpgpath,O_RDONLY);
83#endif
84        if (fd!=-1){
85                fstat(fd,&statbuf);
86                jpgbuf=(uint8_t*)alloca(statbuf.st_size);
87#if !defined(_MSC_VER)
88                read(fd,jpgbuf,statbuf.st_size);
89#else
90                _read(fd,jpgbuf,statbuf.st_size);
91#endif
92                m=jpeg2yuv(jpgbuf,statbuf.st_size,reqsize);
93        }else{
94                ms_error("Cannot load %s",jpgpath);
95        }
96        return m;
97}
98
99
100
101#ifndef PACKAGE_DATA_DIR
102#define PACKAGE_DATA_DIR "."
103#endif
104
105#ifndef NOWEBCAM_JPG
106#define NOWEBCAM_JPG "nowebcamCIF"
107#endif
108
109static char *def_image=NULL;
110
111static const char *def_image_path=PACKAGE_DATA_DIR "/images/" NOWEBCAM_JPG ".jpg";
112
113
114mblk_t *ms_load_nowebcam(MSVideoSize *reqsize, int idx){
115        char tmp[256];
116        if (idx<0)
117                snprintf(tmp, sizeof(tmp), "%s/images/%s.jpg", PACKAGE_DATA_DIR, NOWEBCAM_JPG);
118        else
119                snprintf(tmp, sizeof(tmp), "%s/images/%s%i.jpg", PACKAGE_DATA_DIR, NOWEBCAM_JPG, idx);
120        return ms_load_jpeg_as_yuv(tmp,reqsize);
121}
122
123typedef struct _SIData{
124        MSVideoSize vsize;
125        char *nowebcamimage;
126        uint64_t lasttime;
127        mblk_t *pic;
128}SIData;
129
130void static_image_init(MSFilter *f){
131        SIData *d=(SIData*)ms_new(SIData,1);
132        d->vsize.width=MS_VIDEO_SIZE_CIF_W;
133        d->vsize.height=MS_VIDEO_SIZE_CIF_H;
134
135        if (def_image==NULL)
136                def_image=ms_strdup(def_image_path);
137
138        d->nowebcamimage=ms_strdup(def_image);
139        d->lasttime=0;
140        d->pic=NULL;
141        f->data=d;
142}
143
144void static_image_uninit(MSFilter *f){
145        ms_free(f->data);
146}
147
148void static_image_preprocess(MSFilter *f){
149        SIData *d=(SIData*)f->data;
150        if (d->pic==NULL){
151                d->pic=ms_load_jpeg_as_yuv(d->nowebcamimage,&d->vsize);
152        }
153}
154
155void static_image_process(MSFilter *f){
156        SIData *d=(SIData*)f->data;
157        /*output a frame every second*/
158        if ((f->ticker->time - d->lasttime>1000) || d->lasttime==0){
159                ms_mutex_lock(&f->lock);
160                if (d->pic) {
161                        mblk_t *o=dupb(d->pic);
162                        /*prevent mirroring at the output*/
163                        mblk_set_precious_flag(o,1);
164                        ms_queue_put(f->outputs[0],o);
165                }
166                ms_mutex_unlock(&f->lock);
167                d->lasttime=f->ticker->time;
168        }
169}
170
171void static_image_postprocess(MSFilter *f){
172        SIData *d=(SIData*)f->data;
173        if (d->pic) {
174                freemsg(d->pic);
175                d->pic=NULL;
176        }
177}
178
179int static_image_set_vsize(MSFilter *f, void* data){
180        SIData *d=(SIData*)f->data;
181        d->vsize=*(MSVideoSize*)data;
182        return 0;
183}
184
185int static_image_get_vsize(MSFilter *f, void* data){
186        SIData *d=(SIData*)f->data;
187        *(MSVideoSize*)data=d->vsize;
188        return 0;
189}
190
191int static_image_get_pix_fmt(MSFilter *f, void *data){
192        *(MSPixFmt*)data=MS_YUV420P;
193        return 0;
194}
195
196static int static_image_set_image(MSFilter *f, void *arg){
197        SIData *d=(SIData*)f->data;
198        const char *image = (const char *)arg;
199        ms_filter_lock(f);
200        if (d->nowebcamimage) ms_free(d->nowebcamimage);
201        if (image!=NULL && image[0]!='\0')
202                d->nowebcamimage=ms_strdup(image);
203        else
204                d->nowebcamimage = def_image;
205
206        if (d->pic!=NULL){
207                freemsg(d->pic);
208                d->pic=NULL;
209        }
210
211        ms_filter_unlock(f);
212        return 0;
213}
214
215MSFilterMethod static_image_methods[]={
216        {       MS_FILTER_SET_VIDEO_SIZE, static_image_set_vsize },
217        {       MS_FILTER_GET_VIDEO_SIZE, static_image_get_vsize },
218        {       MS_FILTER_GET_PIX_FMT, static_image_get_pix_fmt },
219        {       MS_FILTER_SET_IMAGE, static_image_set_image },
220        {       0,0 }
221};
222
223MSFilterDesc ms_static_image_desc={
224        MS_STATIC_IMAGE_ID,
225        "MSStaticImage",
226        "A filter that outputs a static image.",
227        MS_FILTER_OTHER,
228        NULL,
229        0,
230        1,
231        static_image_init,
232        static_image_preprocess,
233        static_image_process,
234        static_image_postprocess,
235        static_image_uninit,
236        static_image_methods
237};
238
239MS_FILTER_DESC_EXPORT(ms_static_image_desc)
240
241static void static_image_detect(MSWebCamManager *obj);
242
243static void static_image_cam_init(MSWebCam *cam){
244        cam->name=ms_strdup("Static picture");
245}
246
247
248static MSFilter *static_image_create_reader(MSWebCam *obj){
249        return ms_filter_new_from_desc(&ms_static_image_desc);
250}
251
252MSWebCamDesc static_image_desc={
253        "StaticImage",
254        &static_image_detect,
255        &static_image_cam_init,
256        &static_image_create_reader,
257        NULL
258};
259
260static void static_image_detect(MSWebCamManager *obj){
261        MSWebCam *cam=ms_web_cam_new(&static_image_desc);
262        ms_web_cam_manager_add_cam(obj,cam);
263}
264
265void ms_static_image_set_default_image(const char *path){
266        if (def_image!=NULL)
267                ms_free(def_image);
268        def_image=NULL;
269        if (path)
270                def_image=ms_strdup(path);
271}
Note: See TracBrowser for help on using the repository browser.