static int bb10capture_set_vsize(MSFilter *f, void *arg) { BB10Capture *d = (BB10Capture*) f->data; MSVideoSize newSize = *(MSVideoSize*)arg; ms_filter_lock(f); if (!d->camera_openned) { bb10capture_open_camera(d); } if (d->camera_openned) { camera_set_vf_property(d->cam_handle, CAMERA_IMGPROP_WIDTH, newSize.width, CAMERA_IMGPROP_HEIGHT, newSize.height); camera_get_vf_property(d->cam_handle, CAMERA_IMGPROP_WIDTH, &(d->vsize.width), CAMERA_IMGPROP_HEIGHT, &(d->vsize.height)); if (ms_video_size_equal(d->vsize, newSize)) { ms_filter_unlock(f); return 0; } ms_warning("[bb10_capture] vsize %i,%i couldn't be set, instead try using: %i,%i", newSize.width, newSize.height, newSize.height, newSize.width); int tmp = newSize.width; newSize.width = newSize.height; newSize.height = tmp; camera_set_vf_property(d->cam_handle, CAMERA_IMGPROP_WIDTH, newSize.width, CAMERA_IMGPROP_HEIGHT, newSize.height); camera_get_vf_property(d->cam_handle, CAMERA_IMGPROP_WIDTH, &(d->vsize.width), CAMERA_IMGPROP_HEIGHT, &(d->vsize.height)); if (ms_video_size_equal(d->vsize, newSize)) { ms_filter_unlock(f); return 0; } ms_warning("[bb10_capture] vsize %i,%i couldn't be set either, instead using: %i,%i", newSize.width, newSize.height, d->vsize.width, d->vsize.height); } ms_filter_unlock(f); return -1; }
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]); }
/* this function resizes the original pictures to the destination size and converts to rgb. It takes care of reallocating a new SwsContext and rgb buffer if the source/destination sizes have changed. */ static void yuv2rgb_process(Yuv2RgbCtx *ctx, MSPicture *src, MSVideoSize dstsize, bool_t mirroring) { MSVideoSize srcsize; srcsize.width=src->w; srcsize.height=src->h; if (!ms_video_size_equal(dstsize,ctx->dsize) || !ms_video_size_equal(srcsize,ctx->ssize)) { yuv2rgb_prepare(ctx,srcsize,dstsize); } { int rgb_stride=-dstsize.width*3; uint8_t *p; p=ctx->rgb+(dstsize.width*3*(dstsize.height-1)); if (ms_scaler_process(ctx->sws,src->planes,src->strides, &p, &rgb_stride)<0) { ms_error("Error in 420->rgb ms_scaler_process()."); } if (mirroring) rgb24_mirror(ctx->rgb,dstsize.width,dstsize.height,dstsize.width*3); } }
static void vfw_engine_set_video_size(VfwEngine *obj, MSVideoSize vsize){ if (!obj->configured) obj->vsize=vsize; else if (ms_video_size_greater_than(vsize,obj->vsize) && !ms_video_size_equal(vsize,obj->vsize) ){ _vfw_engine_unconfigure(obj); _vfw_engine_disconnect(obj); _vfw_engine_connect(obj); obj->vsize=vsize; _vfw_engine_configure(obj); } }
MSVideoSize ms_video_size_get_just_lower_than(MSVideoSize vs){ MSVideoSize *p; MSVideoSize ret; ret.width=0; ret.height=0; for(p=_ordered_vsizes;p->width!=0;++p){ if (ms_video_size_greater_than(vs,*p) && !ms_video_size_equal(vs,*p)){ ret=*p; }else return ret; } return ret; }
static void bb10display_process(MSFilter *f) { BB10Display *d = (BB10Display*) f->data; mblk_t *inm = NULL; MSPicture src = {0}; ms_filter_lock(f); 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; if (!ms_video_size_equal(newsize, d->vsize)) { ms_debug("[bb10_display] video size changed from %i,%i to %i,%i", newsize.width, newsize.height, d->vsize.width, d->vsize.height); d->vsize = newsize; if (d->pixmap_created) { bb10display_destroyPixmap(d); } bb10display_createPixmap(d); } if (d->window_created) { int wdims[2] = { 0, 0 }; screen_get_window_property_iv(d->window, SCREEN_PROPERTY_SIZE, wdims); if (d->wsize.width != wdims[0] || d->wsize.height != wdims[1]) { ms_debug("[bb10_display] screen size changed from %i,%i to %i,%i", d->wsize.width, d->wsize.height, wdims[0], wdims[1]); d->wsize.width = wdims[0]; d->wsize.height = wdims[1]; d->destroy_and_recreate_window = TRUE; d->last_time_wsize_changed = f->ticker->time; } } if (d->destroy_and_recreate_window && f->ticker->time - d->last_time_wsize_changed >= 500) { if (d->window_created) { bb10display_destroyWindow(d); } bb10display_createWindow(d); d->destroy_and_recreate_window = FALSE; } if (d->window_created && !d->destroy_and_recreate_window) { bb10display_fillWindowBuffer(d, &src); } } } 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]); }
static void video_configuration_stream_base(MSVideoConfiguration* asked, MSVideoConfiguration* expected_result, int payload_type) { video_stream_tester_t* marielle=video_stream_tester_new(); video_stream_tester_t* margaux=video_stream_tester_new(); PayloadType* pt = rtp_profile_get_payload(&rtp_profile, payload_type); bool_t supported = pt?ms_filter_codec_supported(pt->mime_type):FALSE; if (supported) { margaux->vconf=ms_new0(MSVideoConfiguration,1); margaux->vconf->required_bitrate=asked->required_bitrate; margaux->vconf->bitrate_limit=asked->bitrate_limit; margaux->vconf->vsize=asked->vsize; margaux->vconf->fps=asked->fps; init_video_streams(marielle, margaux, FALSE, TRUE, NULL,payload_type); CU_ASSERT_TRUE(wait_for_until_with_parse_events(&marielle->vs->ms, &margaux->vs->ms, &marielle->stats.number_of_RR, 4, 30000, event_queue_cb, &marielle->stats, event_queue_cb, &margaux->stats)); video_stream_get_local_rtp_stats(marielle->vs, &marielle->stats.rtp); video_stream_get_local_rtp_stats(margaux->vs, &margaux->stats.rtp); CU_ASSERT_TRUE(ms_video_size_equal(video_stream_get_received_video_size(marielle->vs), margaux->vconf->vsize)); CU_ASSERT_TRUE(fabs(video_stream_get_received_framerate(marielle->vs)-margaux->vconf->fps) <2); if (ms_web_cam_manager_get_cam(ms_web_cam_manager_get(), "StaticImage: Static picture") != ms_web_cam_manager_get_default_cam(ms_web_cam_manager_get())) { // CU_ASSERT_TRUE(abs(media_stream_get_down_bw((MediaStream*)marielle->vs) - margaux->vconf->required_bitrate) < 0.20f * margaux->vconf->required_bitrate); } /*else this test require a real webcam*/ uninit_video_streams(marielle, margaux); } else { ms_error("VP8 codec is not supported!"); } video_stream_tester_destroy(marielle); video_stream_tester_destroy(margaux); }
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]); }
static void glxvideo_process(MSFilter *f){ GLXVideo *obj=(GLXVideo*)f->data; mblk_t *inm; MSPicture src={0}; bool_t precious=FALSE; XWindowAttributes wa; XGetWindowAttributes(obj->display,obj->window_id,&wa); 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; ogl_display_init(obj->glhelper, wa.width, wa.height); } ms_filter_lock(f); if (!obj->show) { goto end; } if (!obj->ready) glxvideo_prepare(f); if (!obj->ready){ goto end; } glXMakeCurrent( obj->display, obj->window_id, obj->glContext ); 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); } glxvideo_unprepare(f); glxvideo_prepare(f); if (!obj->ready) goto end; } if (obj->mirror && !precious) ms_yuv_buf_mirror(&src); ogl_display_set_yuv_to_display(obj->glhelper, inm); } } if (f->inputs[1]!=NULL && (inm=ms_queue_peek_last(f->inputs[1]))!=0) { if (ms_yuv_buf_init_from_mblk(&src,inm)==0){ ogl_display_set_preview_yuv_to_display(obj->glhelper, inm); } } ogl_display_render(obj->glhelper, 0); glXSwapBuffers ( obj->display, obj->window_id ); 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]); }