Commit d8a955b5 authored by Simon Morlat's avatar Simon Morlat

Merge branch 'master' of belledonne-communications.com:mediastreamer2

parents 5e22622c eb953d36
......@@ -115,3 +115,8 @@ EXPORTS
ms_web_cam_get_driver_type
ms_web_cam_get_name
ms_web_cam_get_string_id
ms_video_set_video_func
ms_sws_getContext
ms_sws_freeContext
ms_sws_scale
......@@ -147,7 +147,7 @@ void yuv_buf_init_from_mblk_with_size(MSPicture *buf, mblk_t *m, int w, int h);
mblk_t * yuv_buf_alloc(MSPicture *buf, int w, int h);
void yuv_buf_copy(uint8_t *src_planes[], const int src_strides[],
uint8_t *dst_planes[], const int dst_strides[3], MSVideoSize roi);
void yuv_buf_mirror(YuvBuf *buf);
void ms_yuv_buf_mirror(YuvBuf *buf);
void rgb24_revert(uint8_t *buf, int w, int h, int linesize);
void rgb24_copy_revert(uint8_t *dstbuf, int dstlsz,
const uint8_t *srcbuf, int srclsz, MSVideoSize roi);
......@@ -170,6 +170,36 @@ static inline bool_t ms_video_size_equal(MSVideoSize vs1, MSVideoSize vs2){
MSVideoSize ms_video_size_get_just_lower_than(MSVideoSize vs);
struct ms_SwsContext;
enum PixelFormat;
struct _SwsFilter;
struct ms_SwsContext *ms_sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat,
int dstW, int dstH, enum PixelFormat dstFormat,
int flags, struct _SwsFilter *srcFilter,
struct _SwsFilter *dstFilter, double *param);
void ms_sws_freeContext(struct ms_SwsContext *swsContext);
int ms_sws_scale(struct ms_SwsContext *context, uint8_t* srcSlice[], int srcStride[],
int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]);
typedef struct ms_SwsContext *(*sws_getContextFunc)(int srcW, int srcH, enum PixelFormat srcFormat,
int dstW, int dstH, enum PixelFormat dstFormat,
int flags, struct _SwsFilter *srcFilter,
struct _SwsFilter *dstFilter, double *param);
typedef void (*sws_freeContextFunc)(struct ms_SwsContext *swsContext);
typedef int (*sws_scaleFunc)(struct ms_SwsContext *context, uint8_t* srcSlice[], int srcStride[],
int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]);
typedef void (*yuv_buf_mirrorFunc)(MSPicture *buf);
struct ms_swscaleDesc {
sws_getContextFunc sws_getContext;
sws_freeContextFunc sws_freeContext;
sws_scaleFunc sws_scale;
yuv_buf_mirrorFunc yuv_buf_mirror;
};
void ms_video_set_video_func(struct ms_swscaleDesc *_ms_swscale_desc);
#ifdef __cplusplus
}
#endif
......
......@@ -102,6 +102,8 @@ void ms_display_destroy(MSDisplay *d);
#define MS_VIDEO_OUT_GET_SCALE_FACTOR MS_FILTER_METHOD(MS_VIDEO_OUT_ID,8,float)
#define MS_VIDEO_OUT_SET_SELFVIEW_POS MS_FILTER_METHOD(MS_VIDEO_OUT_ID,9,float[3])
#define MS_VIDEO_OUT_GET_SELFVIEW_POS MS_FILTER_METHOD(MS_VIDEO_OUT_ID,10,float[3])
#define MS_VIDEO_OUT_SET_BACKGROUND_COLOR MS_FILTER_METHOD(MS_VIDEO_OUT_ID,11,int[3])
#define MS_VIDEO_OUT_GET_BACKGROUND_COLOR MS_FILTER_METHOD(MS_VIDEO_OUT_ID,12,int[3])
#ifdef __cplusplus
}
......
......@@ -18,6 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "mediastreamer2/msvideo.h"
#include "ffmpeg-priv.h"
static void yuv_buf_init(YuvBuf *buf, int w, int h, uint8_t *ptr){
int ysize,usize;
......@@ -160,7 +161,7 @@ static void plane_mirror(uint8_t *p, int linesize, int w, int h){
}
/*in place mirroring*/
void yuv_buf_mirror(YuvBuf *buf){
static void yuv_buf_mirror(YuvBuf *buf){
plane_mirror(buf->planes[0],buf->strides[0],buf->w,buf->h);
plane_mirror(buf->planes[1],buf->strides[1],buf->w/2,buf->h/2);
plane_mirror(buf->planes[2],buf->strides[2],buf->w/2,buf->h/2);
......@@ -250,3 +251,53 @@ MSVideoSize ms_video_size_get_just_lower_than(MSVideoSize vs){
}
return ret;
};
struct ms_swscaleDesc ms_swscale_desc = {
NULL,
NULL,
NULL,
NULL
};
struct ms_SwsContext *ms_sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat,
int dstW, int dstH, enum PixelFormat dstFormat,
int flags, struct _SwsFilter *srcFilter,
struct _SwsFilter *dstFilter, double *param)
{
if (ms_swscale_desc.sws_getContext==NULL)
{
ms_swscale_desc.sws_getContext=(sws_getContextFunc)sws_getContext;
ms_swscale_desc.sws_freeContext=(sws_freeContextFunc)sws_freeContext;
ms_swscale_desc.sws_scale=(sws_scaleFunc)sws_scale;
}
return (struct ms_SwsContext *)ms_swscale_desc.sws_getContext(srcW, srcH, srcFormat, dstW, dstH, dstFormat,
flags, srcFilter, dstFilter, param);
}
void ms_sws_freeContext(struct ms_SwsContext *swsContext)
{
ms_swscale_desc.sws_freeContext(swsContext);
}
int ms_sws_scale(struct ms_SwsContext *context, uint8_t* srcSlice[], int srcStride[],
int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[])
{
return ms_swscale_desc.sws_scale(context, srcSlice, srcStride, srcSliceY, srcSliceH, dst, dstStride);
}
void ms_yuv_buf_mirror(YuvBuf *buf)
{
if (ms_swscale_desc.yuv_buf_mirror==NULL)
{
ms_swscale_desc.yuv_buf_mirror=(yuv_buf_mirrorFunc)yuv_buf_mirror;
}
return ms_swscale_desc.yuv_buf_mirror(buf);
}
void ms_video_set_video_func(struct ms_swscaleDesc *_ms_swscale_desc)
{
ms_swscale_desc.sws_getContext=_ms_swscale_desc->sws_getContext;
ms_swscale_desc.sws_freeContext=_ms_swscale_desc->sws_freeContext;
ms_swscale_desc.sws_scale=_ms_swscale_desc->sws_scale;
ms_swscale_desc.yuv_buf_mirror=_ms_swscale_desc->yuv_buf_mirror;
}
......@@ -45,7 +45,7 @@ static mblk_t *jpeg2yuv(uint8_t *jpgbuf, int bufsize, MSVideoSize *reqsize){
AVFrame orig;
AVPicture dest;
mblk_t *ret;
struct SwsContext *sws_ctx;
struct ms_SwsContext *sws_ctx;
AVPacket pkt;
avcodec_get_context_defaults(&av_context);
......@@ -65,23 +65,23 @@ static mblk_t *jpeg2yuv(uint8_t *jpgbuf, int bufsize, MSVideoSize *reqsize){
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,av_context.pix_fmt,
sws_ctx=ms_sws_getContext(av_context.width,av_context.height,av_context.pix_fmt,
reqsize->width,reqsize->height,PIX_FMT_YUV420P,SWS_FAST_BILINEAR,
NULL, NULL, NULL);
if (sws_ctx==NULL) {
ms_error("jpeg2yuv: sws_getContext() failed.");
ms_error("jpeg2yuv: ms_sws_getContext() failed.");
avcodec_close(&av_context);
freemsg(ret);
return 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);
if (ms_sws_scale(sws_ctx,orig.data,orig.linesize,0,av_context.height,dest.data,dest.linesize)<0){
ms_error("jpeg2yuv: ms_sws_scale() failed.");
ms_sws_freeContext(sws_ctx);
avcodec_close(&av_context);
freemsg(ret);
return NULL;
}
sws_freeContext(sws_ctx);
ms_sws_freeContext(sws_ctx);
avcodec_close(&av_context);
return ret;
}
......
......@@ -71,7 +71,7 @@ MSPixFmt ffmpeg_pix_fmt_to_ms(int fmt){
typedef struct PixConvState{
YuvBuf outbuf;
mblk_t *yuv_msg;
struct SwsContext *sws_ctx;
struct ms_SwsContext *sws_ctx;
MSVideoSize size;
enum PixelFormat in_fmt;
enum PixelFormat out_fmt;
......@@ -92,7 +92,7 @@ static void pixconv_init(MSFilter *f){
static void pixconv_uninit(MSFilter *f){
PixConvState *s=(PixConvState*)f->data;
if (s->sws_ctx!=NULL){
sws_freeContext(s->sws_ctx);
ms_sws_freeContext(s->sws_ctx);
s->sws_ctx=NULL;
}
if (s->yuv_msg!=NULL) freemsg(s->yuv_msg);
......@@ -127,7 +127,7 @@ static void pixconv_process(MSFilter *f){
avpicture_fill(&inbuf,im->b_rptr,s->in_fmt,s->size.width,s->size.height);
om=pixconv_alloc_mblk(s);
if (s->sws_ctx==NULL){
s->sws_ctx=sws_getContext(s->size.width,s->size.height,
s->sws_ctx=ms_sws_getContext(s->size.width,s->size.height,
s->in_fmt,s->size.width,s->size.height,
s->out_fmt,SWS_FAST_BILINEAR,
NULL, NULL, NULL);
......@@ -136,9 +136,9 @@ static void pixconv_process(MSFilter *f){
inbuf.data[0]+=inbuf.linesize[0]*(s->size.height-1);
inbuf.linesize[0]=-inbuf.linesize[0];
}
if (sws_scale(s->sws_ctx,inbuf.data,inbuf.linesize, 0,
if (ms_sws_scale(s->sws_ctx,inbuf.data,inbuf.linesize, 0,
s->size.height, s->outbuf.planes, s->outbuf.strides)<0){
ms_error("MSPixConv: Error in sws_scale().");
ms_error("MSPixConv: Error in ms_sws_scale().");
}
freemsg(im);
}
......
......@@ -31,7 +31,7 @@ typedef struct SizeConvState{
MSVideoSize target_vsize;
MSVideoSize in_vsize;
YuvBuf outbuf;
struct SwsContext *sws_ctx;
struct ms_SwsContext *sws_ctx;
mblk_t *om;
float fps;
float start_time;
......@@ -66,7 +66,7 @@ static void size_conv_uninit(MSFilter *f){
static void size_conv_postprocess(MSFilter *f){
SizeConvState *s=(SizeConvState*)f->data;
if (s->sws_ctx!=NULL) {
sws_freeContext(s->sws_ctx);
ms_sws_freeContext(s->sws_ctx);
s->sws_ctx=NULL;
}
if (s->om!=NULL){
......@@ -93,14 +93,14 @@ static mblk_t *size_conv_alloc_mblk(SizeConvState *s){
return dupmsg(s->om);
}
static struct SwsContext * get_resampler(SizeConvState *s, int w, int h){
static struct ms_SwsContext * get_resampler(SizeConvState *s, int w, int h){
if (s->in_vsize.width!=w ||
s->in_vsize.height!=h || s->sws_ctx==NULL){
if (s->sws_ctx!=NULL){
sws_freeContext(s->sws_ctx);
ms_sws_freeContext(s->sws_ctx);
s->sws_ctx=NULL;
}
s->sws_ctx=sws_getContext(w,h,PIX_FMT_YUV420P,
s->sws_ctx=ms_sws_getContext(w,h,PIX_FMT_YUV420P,
s->target_vsize.width,s->target_vsize.height,PIX_FMT_YUV420P,
SWS_FAST_BILINEAR,NULL, NULL, NULL);
s->in_vsize.width=w;
......@@ -151,11 +151,11 @@ static void size_conv_process(MSFilter *f){
inbuf.h==s->target_vsize.height){
ms_queue_put(f->outputs[0],im);
}else{
struct SwsContext *sws_ctx=get_resampler(s,inbuf.w,inbuf.h);
struct ms_SwsContext *sws_ctx=get_resampler(s,inbuf.w,inbuf.h);
mblk_t *om=size_conv_alloc_mblk(s);
if (sws_scale(sws_ctx,inbuf.planes,inbuf.strides, 0,
if (ms_sws_scale(sws_ctx,inbuf.planes,inbuf.strides, 0,
inbuf.h, s->outbuf.planes, s->outbuf.strides)<0){
ms_error("MSSizeConv: error in sws_scale().");
ms_error("MSSizeConv: error in ms_sws_scale().");
}
ms_queue_put(f->outputs[0],om);
freemsg(im);
......@@ -175,7 +175,7 @@ static int sizeconv_set_vsize(MSFilter *f, void*arg){
freemsg(s->om);
s->om=NULL;
if (s->sws_ctx!=NULL) {
sws_freeContext(s->sws_ctx);
ms_sws_freeContext(s->sws_ctx);
s->sws_ctx=NULL;
}
ms_filter_unlock(f);
......
......@@ -37,7 +37,7 @@ typedef struct DecState{
mblk_t *input;
YuvBuf outbuf;
mblk_t *yuv_msg;
struct SwsContext *sws_ctx;
struct ms_SwsContext *sws_ctx;
enum PixelFormat output_pix_fmt;
uint8_t dci[512];
int dci_size;
......@@ -92,7 +92,7 @@ static void dec_uninit(MSFilter *f){
if (s->input!=NULL) freemsg(s->input);
if (s->yuv_msg!=NULL) freemsg(s->yuv_msg);
if (s->sws_ctx!=NULL){
sws_freeContext(s->sws_ctx);
ms_sws_freeContext(s->sws_ctx);
s->sws_ctx=NULL;
}
ms_free(s);
......@@ -567,21 +567,33 @@ read_rfc2435_header(DecState *s,mblk_t *inm)
static mblk_t *get_as_yuvmsg(MSFilter *f, DecState *s, AVFrame *orig){
AVCodecContext *ctx=&s->av_context;
if (ctx->width==0 || ctx->height==0){
ms_error("%s: wrong image size provided by decoder.",f->desc->name);
return NULL;
}
if (orig->data[0]==NULL){
ms_error("%s: no image data.",f->desc->name);
return NULL;
}
if (s->outbuf.w!=ctx->width || s->outbuf.h!=ctx->height){
if (s->sws_ctx!=NULL){
sws_freeContext(s->sws_ctx);
ms_sws_freeContext(s->sws_ctx);
s->sws_ctx=NULL;
}
s->yuv_msg=yuv_buf_alloc(&s->outbuf,ctx->width,ctx->height);
s->outbuf.w=ctx->width;
s->outbuf.h=ctx->height;
s->sws_ctx=sws_getContext(ctx->width,ctx->height,ctx->pix_fmt,
s->sws_ctx=ms_sws_getContext(ctx->width,ctx->height,ctx->pix_fmt,
ctx->width,ctx->height,s->output_pix_fmt,SWS_FAST_BILINEAR,
NULL, NULL, NULL);
}
if (sws_scale(s->sws_ctx,orig->data,orig->linesize, 0,
if (s->sws_ctx==NULL){
ms_error("%s: missing rescaling context.",f->desc->name);
return NULL;
}
if (ms_sws_scale(s->sws_ctx,orig->data,orig->linesize, 0,
ctx->height, s->outbuf.planes, s->outbuf.strides)<0){
ms_error("%s: error in sws_scale().",f->desc->name);
ms_error("%s: error in ms_sws_scale().",f->desc->name);
}
return dupmsg(s->yuv_msg);
}
......@@ -625,7 +637,9 @@ static void dec_process_frame(MSFilter *f, mblk_t *inm){
break;
}
if (got_picture) {
ms_queue_put(f->outputs[0],get_as_yuvmsg(f,s,&orig));
mblk_t *om = get_as_yuvmsg(f,s,&orig);
if (om!=NULL)
ms_queue_put(f->outputs[0],om);
}
frame->b_rptr+=len;
}
......
......@@ -109,7 +109,13 @@ static void sdl_display_uninit(MSDisplay *obj);
static int sdl_create_window(SdlDisplay *wd, int w, int h){
static bool_t once=TRUE;
wd->sdl_screen = SDL_SetVideoMode(w,h, 0,SDL_SWSURFACE|SDL_RESIZABLE);
wd->sdl_screen = SDL_SetVideoMode(w,h, 0,SDL_HWSURFACE|SDL_RESIZABLE);
if (wd->sdl_screen == NULL ) {
ms_warning("no hardware for video mode: %s\n",
SDL_GetError());
}
if (wd->sdl_screen == NULL )
wd->sdl_screen = SDL_SetVideoMode(w,h, 0,SDL_SWSURFACE|SDL_RESIZABLE);
if (wd->sdl_screen == NULL ) {
ms_warning("Couldn't set video mode: %s\n",
SDL_GetError());
......@@ -278,14 +284,13 @@ typedef struct _WinDisplay{
MSPicture fb_selfview;
uint8_t *rgb_selfview;
int rgb_len_selfview;
struct SwsContext *sws_selfview;
struct ms_SwsContext *sws_selfview;
MSDisplayEvent last_rsz;
uint8_t *rgb;
uint8_t *black;
int last_rect_w;
int last_rect_h;
int rgb_len;
struct SwsContext *sws;
struct ms_SwsContext *sws;
bool_t new_ev;
}WinDisplay;
......@@ -377,10 +382,9 @@ static bool_t win_display_init(MSDisplay *obj, MSFilter *f, MSPicture *fbuf, MSP
wd->fb.planes[2]=NULL;
wd->fb.planes[3]=NULL;
if (wd->rgb) ms_free(wd->rgb);
if (wd->black) ms_free(wd->black);
wd->rgb=NULL;
wd->rgb_len=0;
sws_freeContext(wd->sws);
ms_sws_freeContext(wd->sws);
wd->sws=NULL;
if (wd->fb_selfview.planes[0]) ms_free(wd->fb_selfview.planes[0]);
wd->fb_selfview.planes[0]=NULL;
......@@ -390,9 +394,8 @@ static bool_t win_display_init(MSDisplay *obj, MSFilter *f, MSPicture *fbuf, MSP
if (wd->rgb_selfview) ms_free(wd->rgb_selfview);
wd->rgb_selfview=NULL;
wd->rgb_len_selfview=0;
sws_freeContext(wd->sws_selfview);
ms_sws_freeContext(wd->sws_selfview);
wd->sws_selfview=NULL;
wd->black=NULL;
wd->last_rect_w=0;
wd->last_rect_h=0;
}
......@@ -454,7 +457,6 @@ static bool_t win_display_init(MSDisplay *obj, MSFilter *f, MSPicture *fbuf, MSP
if (wd->fb.planes[0]) ms_free(wd->fb.planes[0]);
if (wd->rgb) ms_free(wd->rgb);
if (wd->black) ms_free(wd->black);
ysize=wd->fb.w*wd->fb.h;
usize=ysize/4;
fbuf->planes[0]=wd->fb.planes[0]=(uint8_t*)ms_malloc0(ysize+2*usize);
......@@ -468,7 +470,6 @@ static bool_t win_display_init(MSDisplay *obj, MSFilter *f, MSPicture *fbuf, MSP
wd->rgb_len=ysize*3;
wd->rgb=(uint8_t*)ms_malloc0(wd->rgb_len);
wd->black = (uint8_t*)ms_malloc0(wd->rgb_len);
wd->last_rect_w=0;
wd->last_rect_h=0;
return TRUE;
......@@ -490,13 +491,13 @@ static void yuv420p_to_rgb(WinDisplay *wd, MSPicture *src, uint8_t *rgb){
p=rgb+(src->w*3*(src->h-1));
if (wd->sws==NULL){
wd->sws=sws_getContext(src->w,src->h,PIX_FMT_YUV420P,
wd->sws=ms_sws_getContext(src->w,src->h,PIX_FMT_YUV420P,
src->w,src->h, PIX_FMT_BGR24,
SWS_FAST_BILINEAR, NULL, NULL, NULL);
}
if (sws_scale(wd->sws,src->planes,src->strides, 0,
if (ms_sws_scale(wd->sws,src->planes,src->strides, 0,
src->h, &p, &rgb_stride)<0){
ms_error("Error in 420->rgb sws_scale().");
ms_error("Error in 420->rgb ms_sws_scale().");
}
}
......@@ -506,13 +507,13 @@ static void yuv420p_to_rgb_selfview(WinDisplay *wd, MSPicture *src, uint8_t *rgb
p=rgb+(src->w*3*(src->h-1));
if (wd->sws_selfview==NULL){
wd->sws_selfview=sws_getContext(src->w,src->h,PIX_FMT_YUV420P,
wd->sws_selfview=ms_sws_getContext(src->w,src->h,PIX_FMT_YUV420P,
src->w,src->h, PIX_FMT_BGR24,
SWS_FAST_BILINEAR, NULL, NULL, NULL);
}
if (sws_scale(wd->sws_selfview,src->planes,src->strides, 0,
if (ms_sws_scale(wd->sws_selfview,src->planes,src->strides, 0,
src->h, &p, &rgb_stride)<0){
ms_error("Error in 420->rgb sws_scale().");
ms_error("Error in 420->rgb ms_sws_scale().");
}
}
......@@ -544,9 +545,11 @@ static void win_display_update(MSDisplay *obj, int new_image, int new_selfview){
int corner;
float sv_scalefactor;
float sv_pos[3];
int color[3];
HDC dd_hdc;
HBITMAP dd_bmp;
HBRUSH brush;
BOOL dont_draw;
if (wd->window==NULL) return;
......@@ -602,11 +605,15 @@ static void win_display_update(MSDisplay *obj, int new_image, int new_selfview){
HGDIOBJ old_object = SelectObject(dd_hdc, dd_bmp);
dont_draw = DrawDibBegin(wd->ddh,dd_hdc, 0, 0, &bi, 0, 0, DDF_BUFFER);
//full screen in black
ret=DrawDibDraw(wd->ddh,dd_hdc,0,0,
rect.right,rect.bottom,
&bi,wd->black,
0,0,bi.biWidth,bi.biHeight,dont_draw?DDF_DONTDRAW:0);
/* full screen in background color */
color[0]=color[1]=color[2]=0;
if (wd->filter)
ms_filter_call_method(wd->filter, MS_VIDEO_OUT_GET_BACKGROUND_COLOR, &color);
brush = CreateSolidBrush(RGB(color[0],color[1],color[2]));
FillRect(dd_hdc, &rect, brush);
DeleteObject(brush);
corner = 0;
sv_scalefactor = SCALE_FACTOR;
......@@ -792,11 +799,10 @@ static void win_display_uninit(MSDisplay *obj){
if (wd->ddh) DrawDibClose(wd->ddh);
if (wd->fb_selfview.planes[0]) ms_free(wd->fb_selfview.planes[0]);
if (wd->rgb_selfview) ms_free(wd->rgb_selfview);
if (wd->sws_selfview) sws_freeContext(wd->sws_selfview);
if (wd->sws_selfview) ms_sws_freeContext(wd->sws_selfview);
if (wd->fb.planes[0]) ms_free(wd->fb.planes[0]);
if (wd->rgb) ms_free(wd->rgb);
if (wd->black) ms_free(wd->black);
if (wd->sws) sws_freeContext(wd->sws);
if (wd->sws) ms_sws_freeContext(wd->sws);
ms_free(wd);
}
......@@ -877,9 +883,10 @@ typedef struct VideoOut
int corner; /*for selfview*/
float scale_factor; /*for selfview*/
float sv_posx,sv_posy;
int background_color[3];
struct SwsContext *sws1;
struct SwsContext *sws2;
struct ms_SwsContext *sws1;
struct ms_SwsContext *sws2;
MSDisplay *display;
bool_t own_display;
bool_t ready;
......@@ -936,6 +943,7 @@ static void video_out_init(MSFilter *f){
obj->corner=0;
obj->scale_factor=SCALE_FACTOR;
obj->sv_posx=obj->sv_posy=SELVIEW_POS_INACTIVE;
obj->background_color[0]=obj->background_color[1]=obj->background_color[2]=0;
obj->sws1=NULL;
obj->sws2=NULL;
obj->display=NULL;
......@@ -953,11 +961,11 @@ static void video_out_uninit(MSFilter *f){
if (obj->display!=NULL && obj->own_display)
ms_display_destroy(obj->display);
if (obj->sws1!=NULL){
sws_freeContext(obj->sws1);
ms_sws_freeContext(obj->sws1);
obj->sws1=NULL;
}
if (obj->sws2!=NULL){
sws_freeContext(obj->sws2);
ms_sws_freeContext(obj->sws2);
obj->sws2=NULL;
}
if (obj->local_msg!=NULL) {
......@@ -982,11 +990,11 @@ static void video_out_prepare(MSFilter *f){
obj->display=NULL;
}
if (obj->sws1!=NULL){
sws_freeContext(obj->sws1);
ms_sws_freeContext(obj->sws1);
obj->sws1=NULL;
}
if (obj->sws2!=NULL){
sws_freeContext(obj->sws2);
ms_sws_freeContext(obj->sws2);
obj->sws2=NULL;
}
if (obj->local_msg!=NULL) {
......@@ -1052,16 +1060,16 @@ static void video_out_process(MSFilter *f){
if (yuv_buf_init_from_mblk(&src,inm)==0){
if (obj->sws2==NULL){
obj->sws2=sws_getContext(src.w,src.h,PIX_FMT_YUV420P,
obj->sws2=ms_sws_getContext(src.w,src.h,PIX_FMT_YUV420P,
obj->fbuf_selfview.w,obj->fbuf_selfview.h,PIX_FMT_YUV420P,
SWS_FAST_BILINEAR, NULL, NULL, NULL);
}
ms_display_lock(obj->display);
if (sws_scale(obj->sws2,src.planes,src.strides, 0,
if (ms_sws_scale(obj->sws2,src.planes,src.strides, 0,
src.h, obj->fbuf_selfview.planes, obj->fbuf_selfview.strides)<0){
ms_error("Error in sws_scale().");
ms_error("Error in ms_sws_scale().");
}
if (!mblk_get_precious_flag(inm)) yuv_buf_mirror(&obj->fbuf_selfview);
if (!mblk_get_precious_flag(inm)) ms_yuv_buf_mirror(&obj->fbuf_selfview);
ms_display_unlock(obj->display);
update_selfview=1;
}
......@@ -1070,7 +1078,7 @@ static void video_out_process(MSFilter *f){
if (yuv_buf_init_from_mblk(&src,inm)==0){
if (obj->sws2==NULL){
obj->sws2=sws_getContext(src.w,src.h,PIX_FMT_YUV420P,
obj->sws2=ms_sws_getContext(src.w,src.h,PIX_FMT_YUV420P,
obj->local_pic.w,obj->local_pic.h,PIX_FMT_YUV420P,
SWS_FAST_BILINEAR, NULL, NULL, NULL);
}
......@@ -1080,11 +1088,11 @@ static void video_out_process(MSFilter *f){
}
if (obj->local_pic.planes[0]!=NULL)
{
if (sws_scale(obj->sws2,src.planes,src.strides, 0,
if (ms_sws_scale(obj->sws2,src.planes,src.strides, 0,
src.h, obj->local_pic.planes, obj->local_pic.strides)<0){
ms_error("Error in sws_scale().");
ms_error("Error in ms_sws_scale().");
}
if (!mblk_get_precious_flag(inm)) yuv_buf_mirror(&obj->local_pic);
if (!mblk_get_precious_flag(inm)) ms_yuv_buf_mirror(&obj->local_pic);
update=1;
}
}
......@@ -1118,16 +1126,16 @@ static void video_out_process(MSFilter *f){
}
}
if (obj->sws1==NULL){
obj->sws1=sws_getContext(src.w,src.h,PIX_FMT_YUV420P,
obj->sws1=ms_sws_getContext(src.w,src.h,PIX_FMT_YUV420P,
obj->fbuf.w,obj->fbuf.h,PIX_FMT_YUV420P,
SWS_FAST_BILINEAR, NULL, NULL, NULL);
}
ms_display_lock(obj->display);
if (sws_scale(obj->sws1,src.planes,src.strides, 0,
if (ms_sws_scale(obj->sws1,src.planes,src.strides, 0,
src.h, obj->fbuf.planes, obj->fbuf.strides)<0){
ms_error("Error in sws_scale().");
ms_error("Error in ms_sws_scale().");
}
if (obj->mirror && !mblk_get_precious_flag(inm)) yuv_buf_mirror(&obj->fbuf);
if (obj->mirror && !mblk_get_precious_flag(inm)) ms_yuv_buf_mirror(&obj->fbuf);
ms_display_unlock(obj->display);
}
update=1;
......@@ -1271,6 +1279,23 @@ static int video_out_get_selfview_pos(MSFilter *f,void *arg){
((float*)arg)[2]=(float)100.0/s->scale_factor;
return 0;
}
static int video_out_set_background_color(MSFilter *f,void *arg){
VideoOut *s=(VideoOut*)f->data;
s->background_color[0]=((int*)arg)[0];
s->background_color[1]=((int*)arg)[1];
s->background_color[2]=((int*)arg)[2];
return 0;