Commit c8c47d58 authored by Aymeric Moizard's avatar Aymeric Moizard

support for external replacement for swscale

parent 303b2d3b
......@@ -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
......
......@@ -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);
......@@ -569,19 +569,19 @@ static mblk_t *get_as_yuvmsg(MSFilter *f, DecState *s, AVFrame *orig){
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 (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);
}
......
......@@ -278,13 +278,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;
int last_rect_w;
int last_rect_h;
int rgb_len;
struct SwsContext *sws;
struct ms_SwsContext *sws;
bool_t new_ev;
}WinDisplay;
......@@ -378,7 +378,7 @@ static bool_t win_display_init(MSDisplay *obj, MSFilter *f, MSPicture *fbuf, MSP
if (wd->rgb) ms_free(wd->rgb);
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;
......@@ -388,7 +388,7 @@ 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->last_rect_w=0;
wd->last_rect_h=0;
......@@ -485,13 +485,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().");
}
}
......@@ -501,13 +501,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().");
}
}
......@@ -793,10 +793,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->sws) sws_freeContext(wd->sws);
if (wd->sws) ms_sws_freeContext(wd->sws);
ms_free(wd);
}
......@@ -879,8 +879,8 @@ typedef struct VideoOut
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;
......@@ -955,11 +955,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) {
......@@ -984,11 +984,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) {
......@@ -1054,16 +1054,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;
}
......@@ -1072,7 +1072,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);
}
......@@ -1082,11 +1082,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;
}
}
......@@ -1120,16 +1120,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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment