static void pixconv_process(MSFilter *f){ mblk_t *im,*om=NULL; PixConvState *s=(PixConvState*)f->data; while((im=ms_queue_get(f->inputs[0]))!=NULL){ if (s->in_fmt==s->out_fmt){ om=im; }else{ MSPicture inbuf; if (ms_picture_init_from_mblk_with_size(&inbuf,im,s->in_fmt,s->size.width,s->size.height)==0){ om=pixconv_alloc_mblk(s); if (s->scaler==NULL){ s->scaler=ms_scaler_create_context(inbuf.w, inbuf.h, s->in_fmt,inbuf.w,inbuf.h, s->out_fmt,MS_SCALER_METHOD_BILINEAR); } if (s->in_fmt==MS_RGB24_REV){ inbuf.planes[0]+=inbuf.strides[0]*(inbuf.h-1); inbuf.strides[0]=-inbuf.strides[0]; } if (ms_scaler_process (s->scaler,inbuf.planes,inbuf.strides, s->outbuf.planes, s->outbuf.strides)<0){ ms_error("MSPixConv: Error in ms_sws_scale()."); } } freemsg(im); } if (om!=NULL) ms_queue_put(f->outputs[0],om); } }
static void android_display_process(MSFilter *f){ AndroidDisplay *ad=(AndroidDisplay*)f->data; MSPicture pic; mblk_t *m; ms_filter_lock(f); if (ad->jbitmap!=0 && !ad->orientation_change_pending){ if ((m=ms_queue_peek_last(f->inputs[0]))!=NULL){ if (ms_yuv_buf_init_from_mblk (&pic,m)==0){ MSVideoSize wsize={ad->bmpinfo.width,ad->bmpinfo.height}; MSVideoSize vsize={pic.w, pic.h}; MSRect vrect; MSPicture dest={0}; void *pixels=NULL; JNIEnv *jenv=ms_get_jni_env(); if (!ms_video_size_equal(vsize,ad->vsize)){ ms_message("Video to display has size %ix%i",vsize.width,vsize.height); ad->vsize=vsize; if (ad->sws){ ms_scaler_context_free(ad->sws); ad->sws=NULL; } /*select_orientation(ad,wsize,vsize);*/ } ms_layout_compute(wsize,vsize,vsize,-1,0,&vrect, NULL); if (ad->sws==NULL){ ad->sws=ms_scaler_create_context (vsize.width,vsize.height,MS_YUV420P, vrect.w,vrect.h,MS_RGB565,MS_SCALER_METHOD_BILINEAR); if (ad->sws==NULL){ ms_fatal("Could not obtain sws context !"); } } if (sym_AndroidBitmap_lockPixels(jenv,ad->jbitmap,&pixels)==0){ if (pixels!=NULL){ dest.planes[0]=(uint8_t*)pixels+(vrect.y*ad->bmpinfo.stride)+(vrect.x*2); dest.strides[0]=ad->bmpinfo.stride; ms_scaler_process(ad->sws,pic.planes,pic.strides,dest.planes,dest.strides); }else ms_warning("Pixels==NULL in android bitmap !"); sym_AndroidBitmap_unlockPixels(jenv,ad->jbitmap); }else{ ms_error("AndroidBitmap_lockPixels() failed !"); } (*jenv)->CallVoidMethod(jenv,ad->android_video_window,ad->update_id); } } } ms_filter_unlock(f); ms_queue_flush(f->inputs[0]); ms_queue_flush(f->inputs[1]); }
static void yuv2rgb_prepare(Yuv2RgbCtx *ctx, MSVideoSize src, MSVideoSize dst) { if (ctx->sws!=NULL) yuv2rgb_uninit(ctx); ctx->sws=ms_scaler_create_context(src.width,src.height,MS_YUV420P, dst.width,dst.height, MS_RGB24_REV, MS_SCALER_METHOD_BILINEAR); ctx->dsize=dst; ctx->ssize=src; ctx->rgblen=dst.width*dst.height*3; ctx->rgb=(uint8_t*)ms_malloc0(ctx->rgblen+dst.width); }
static MSScalerContext * 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){ ms_scaler_context_free(s->sws_ctx); s->sws_ctx=NULL; } s->sws_ctx=ms_scaler_create_context(w,h,MS_YUV420P, s->target_vsize.width,s->target_vsize.height,MS_YUV420P, MS_SCALER_METHOD_BILINEAR); s->in_vsize.width=w; s->in_vsize.height=h; } return s->sws_ctx; }
static void x11video_process(MSFilter *f){ X11Video *obj=(X11Video*)f->data; mblk_t *inm; int update=0; MSPicture lsrc={0}; MSPicture src={0}; MSRect mainrect,localrect; bool_t precious=FALSE; bool_t local_precious=FALSE; XWindowAttributes wa; MSTickerLateEvent late_info; ms_filter_lock(f); if ((obj->window_id == 0) || (x11_error == TRUE)) goto end; XGetWindowAttributes(obj->display,obj->window_id,&wa); if (x11_error == TRUE) { ms_error("Could not get window attributes for window %lu", obj->window_id); goto end; } if (wa.width!=obj->wsize.width || wa.height!=obj->wsize.height){ ms_warning("Resized to %ix%i", wa.width,wa.height); obj->wsize.width=wa.width; obj->wsize.height=wa.height; XClearWindow(obj->display,obj->window_id); } ms_ticker_get_last_late_tick(f->ticker, &late_info); if(late_info.current_late_ms > 100) { ms_warning("Dropping frames because we're late"); goto end; } if (!obj->show) { goto end; } if (!obj->ready){ goto end; } if (f->inputs[0]!=NULL && (inm=ms_queue_peek_last(f->inputs[0]))!=0) { if (ms_yuv_buf_init_from_mblk(&src,inm)==0){ MSVideoSize newsize; newsize.width=src.w; newsize.height=src.h; precious=mblk_get_precious_flag(inm); if (!ms_video_size_equal(newsize,obj->vsize) ) { ms_message("received size is %ix%i",newsize.width,newsize.height); obj->vsize=newsize; if (obj->autofit){ MSVideoSize new_window_size; static const MSVideoSize min_size=MS_VIDEO_SIZE_QVGA; /*don't resize less than QVGA, it is too small*/ if (min_size.width*min_size.height>newsize.width*newsize.height){ new_window_size.width=newsize.width*2; new_window_size.height=newsize.height*2; }else new_window_size=newsize; obj->wsize=new_window_size; ms_message("autofit: new window size should be %ix%i",new_window_size.width,new_window_size.height); XResizeWindow(obj->display,obj->window_id,new_window_size.width,new_window_size.height); XSync(obj->display,FALSE); } x11video_unprepare(f); x11video_prepare(f); if (!obj->ready) goto end; } } update=1; } /*process last video message for local preview*/ if (obj->corner!=-1 && f->inputs[1]!=NULL && (inm=ms_queue_peek_last(f->inputs[1]))!=0) { if (ms_yuv_buf_init_from_mblk(&lsrc,inm)==0){ obj->lsize.width=lsrc.w; obj->lsize.height=lsrc.h; local_precious=mblk_get_precious_flag(inm); update=1; } } ms_layout_compute(obj->vsize, obj->vsize,obj->lsize,obj->corner,obj->scale_factor,&mainrect,&localrect); if (lsrc.w!=0 && obj->corner!=-1){ /* first reduce the local preview image into a temporary image*/ if (obj->local_msg==NULL){ obj->local_msg=ms_yuv_buf_alloc(&obj->local_pic,localrect.w,localrect.h); } if (obj->sws2==NULL){ obj->sws2=ms_scaler_create_context(lsrc.w,lsrc.h,MS_YUV420P,localrect.w,localrect.h,MS_YUV420P, MS_SCALER_METHOD_BILINEAR); } ms_scaler_process(obj->sws2,lsrc.planes,lsrc.strides,obj->local_pic.planes,obj->local_pic.strides); if (!local_precious) ms_yuv_buf_mirror(&obj->local_pic); } if (update && src.w!=0){ ms_yuv_buf_copy(src.planes,src.strides,obj->fbuf.planes,obj->fbuf.strides,obj->vsize); if (obj->mirror && !precious) ms_yuv_buf_mirror(&obj->fbuf); } /*copy resized local view into a corner:*/ if (update && obj->local_msg!=NULL && obj->corner!=-1){ MSPicture corner=obj->fbuf; MSVideoSize roi; roi.width=obj->local_pic.w; roi.height=obj->local_pic.h; corner.w=obj->local_pic.w; corner.h=obj->local_pic.h; corner.planes[0]+=localrect.x+(localrect.y*corner.strides[0]); corner.planes[1]+=(localrect.x/2)+((localrect.y/2)*corner.strides[1]); corner.planes[2]+=(localrect.x/2)+((localrect.y/2)*corner.strides[2]); corner.planes[3]=0; ms_yuv_buf_copy(obj->local_pic.planes,obj->local_pic.strides, corner.planes,corner.strides,roi); } if (update){ MSRect rect; ms_layout_center_rectangle(obj->wsize,obj->vsize,&rect); //ms_message("XvShmPutImage() %ix%i --> %ix%i",obj->fbuf.w,obj->fbuf.h,obj->wsize.width,obj->wsize.height); XvShmPutImage(obj->display,obj->port,obj->window_id,obj->gc, obj->xv_image, 0,0,obj->fbuf.w,obj->fbuf.h, rect.x,rect.y,rect.w,rect.h,TRUE); XSync(obj->display,FALSE); } end: ms_filter_unlock(f); if (f->inputs[0]!=NULL) ms_queue_flush(f->inputs[0]); if (f->inputs[1]!=NULL) ms_queue_flush(f->inputs[1]); }