static void android_display_process(MSFilter *f){ AndroidDisplay *ad=(AndroidDisplay*)f->data; MSPicture pic; mblk_t *m; ms_filter_lock(f); if (ad->android_video_window){ if ((m=ms_queue_peek_last(f->inputs[0]))!=NULL){ if (ms_yuv_buf_init_from_mblk (&pic,m)==0){ /* schedule display of frame */ if (!ad->ogl || !ad->ogl_free_ready) { /* m is dupb'ed inside ogl_display */ ogl_display_set_yuv_to_display(ad->ogl, m); } else { ms_warning("%s: opengldisplay not ready (%p)", __FUNCTION__, ad->ogl); } JNIEnv *jenv=ms_get_jni_env(); (*jenv)->CallVoidMethod(jenv,ad->android_video_window,ad->request_render_id); } } } ms_filter_unlock(f); ms_queue_flush(f->inputs[0]); if (f->inputs[1] != NULL) ms_queue_flush(f->inputs[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]); }
static void glxvideo_process(MSFilter *f){ GLXVideo *obj=(GLXVideo*)f->data; mblk_t *inm; MSPicture src={0}; 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){ 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]); }
static void MSDisplayProcess (MSFilter *f) { MSPicture pic; mblk_t *inp; // Handle remote image ... if (f->inputs[0]) { if ( (inp = ms_queue_peek_last (f->inputs[0])) ) { if (ms_yuv_buf_init_from_mblk (&pic, inp) == 0) { SDL_LockMutex (picMutex); MSPictureCopyFrom (&picRemote, &pic); picRemoteUpdated = TRUE; SDL_UnlockMutex (picMutex); } } ms_queue_flush (f->inputs[0]); } else { SDL_LockMutex (picMutex); MSPictureCopyFrom (&picRemote, NULL); picRemoteUpdated = TRUE; SDL_UnlockMutex (picMutex); } // Handle local image ... if (f->inputs[1]) { if ( (inp = ms_queue_peek_last (f->inputs[1])) ) { if (ms_yuv_buf_init_from_mblk (&pic, inp) == 0) { SDL_LockMutex (picMutex); MSPictureCopyFrom (&picLocal, &pic); picLocalUpdated = TRUE; SDL_UnlockMutex (picMutex); } } ms_queue_flush (f->inputs[1]); } else { SDL_LockMutex (picMutex); MSPictureCopyFrom (&picLocal, NULL); picLocalUpdated = TRUE; SDL_UnlockMutex (picMutex); } }
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 jpg_process(MSFilter *f){ JpegWriter *s=(JpegWriter*)f->data; if (s->take_pic){ MSPicture yuvbuf; mblk_t *m=ms_queue_peek_last(f->inputs[0]); if (ms_yuv_buf_init_from_mblk(&yuvbuf,m)==0){ MSVideoSize dstsize; dstsize.height = yuvbuf.h; dstsize.width = yuvbuf.w; if(jpeg_enc_yv12(m->b_rptr,dstsize.width,dstsize.height,90,s->filename)) ms_message("Snapshot Ok"); else ms_message("Snapshot failed!"); s->take_pic = FALSE; } goto end; } end: ms_queue_flush(f->inputs[0]); }
static void jpg_process(MSFilter *f){ JpegWriter *s=(JpegWriter*)f->data; ms_filter_lock(f); if (s->file!=NULL && s->codec!=NULL){ MSPicture yuvbuf, yuvjpeg; mblk_t *m=ms_queue_peek_last(f->inputs[0]); if (ms_yuv_buf_init_from_mblk(&yuvbuf,m)==0){ int error,got_pict; int comp_buf_sz=msgdsize(m); uint8_t *comp_buf=(uint8_t*)ms_malloc0(comp_buf_sz); mblk_t *jpegm; struct SwsContext *sws_ctx; struct AVPacket packet; AVCodecContext *avctx=avcodec_alloc_context3(s->codec); memset(&packet, 0, sizeof(packet)); avctx->width=yuvbuf.w; avctx->height=yuvbuf.h; avctx->time_base.num = 1; avctx->time_base.den =1; avctx->pix_fmt=AV_PIX_FMT_YUVJ420P; error=avcodec_open2(avctx,s->codec,NULL); if (error!=0) { ms_error("avcodec_open() failed: %i",error); cleanup(s,NULL, FALSE); av_free(avctx); goto end; } sws_ctx=sws_getContext(avctx->width,avctx->height,AV_PIX_FMT_YUV420P, avctx->width,avctx->height,avctx->pix_fmt,SWS_FAST_BILINEAR,NULL, NULL, NULL); if (sws_ctx==NULL) { ms_error(" sws_getContext() failed."); cleanup(s,avctx, FALSE); goto end; } jpegm=ms_yuv_buf_alloc (&yuvjpeg,avctx->width, avctx->height); #if LIBSWSCALE_VERSION_INT >= AV_VERSION_INT(0,9,0) if (sws_scale(sws_ctx,(const uint8_t *const*)yuvbuf.planes,yuvbuf.strides,0,avctx->height,yuvjpeg.planes,yuvjpeg.strides)<0){ #else if (sws_scale(sws_ctx,(uint8_t **)yuvbuf.planes,yuvbuf.strides,0,avctx->height,yuvjpeg.planes,yuvjpeg.strides)<0){ #endif ms_error("sws_scale() failed."); sws_freeContext(sws_ctx); cleanup(s,avctx, FALSE); freemsg(jpegm); goto end; } sws_freeContext(sws_ctx); av_frame_unref(s->pict); avpicture_fill((AVPicture*)s->pict,(uint8_t*)jpegm->b_rptr,avctx->pix_fmt,avctx->width,avctx->height); packet.data=comp_buf; packet.size=comp_buf_sz; error=avcodec_encode_video2(avctx, &packet, s->pict, &got_pict); if (error<0){ ms_error("Could not encode jpeg picture."); }else{ if (fwrite(comp_buf,packet.size,1,s->file)>0){ ms_message("Snapshot done"); }else{ ms_error("Error writing snapshot."); } } ms_free(comp_buf); cleanup(s,avctx, TRUE); freemsg(jpegm); } goto end; } end: ms_filter_unlock(f); ms_queue_flush(f->inputs[0]); } static MSFilterMethod jpg_methods[]={ { MS_JPEG_WRITER_TAKE_SNAPSHOT, take_snapshot }, { 0,NULL} }; #ifndef _MSC_VER MSFilterDesc ms_jpeg_writer_desc={ .id=MS_JPEG_WRITER_ID, .name="MSJpegWriter", .text="Take a video snapshot as jpg file", .category=MS_FILTER_OTHER, .ninputs=1, .noutputs=0, .init=jpg_init, .process=jpg_process, .uninit=jpg_uninit, .methods=jpg_methods }; #else MSFilterDesc ms_jpeg_writer_desc={ MS_JPEG_WRITER_ID, "MSJpegWriter", "Take a video snapshot as jpg file", MS_FILTER_OTHER, NULL, 1, 0, jpg_init, NULL, jpg_process, NULL, jpg_uninit, jpg_methods }; #endif MS_FILTER_DESC_EXPORT(ms_jpeg_writer_desc)
static void enc_process(MSFilter *f) { mblk_t *im; uint64_t timems = f->ticker->time; uint32_t timestamp = (uint32_t)(timems*90); EncState *s = (EncState *)f->data; unsigned int flags = 0; vpx_codec_err_t err; MSPicture yuv; bool_t is_ref_frame=FALSE; ms_filter_lock(f); #ifdef AVPF_DEBUG ms_message("VP8 enc_process:"); #endif if (!s->ready) { ms_queue_flush(f->inputs[0]); ms_filter_unlock(f); return; } if ((im = ms_queue_peek_last(f->inputs[0])) != NULL) { vpx_image_t img; flags = 0; ms_yuv_buf_init_from_mblk(&yuv, im); vpx_img_wrap(&img, VPX_IMG_FMT_I420, s->vconf.vsize.width, s->vconf.vsize.height, 1, yuv.planes[0]); if ((s->avpf_enabled != TRUE) && ms_video_starter_need_i_frame(&s->starter, f->ticker->time)) { s->force_keyframe = TRUE; } if (s->force_keyframe == TRUE) { ms_message("Forcing vp8 key frame for filter [%p]", f); flags = VPX_EFLAG_FORCE_KF; } else if (s->avpf_enabled == TRUE) { if (s->frame_count == 0) s->force_keyframe = TRUE; enc_fill_encoder_flags(s, &flags); } #ifdef AVPF_DEBUG ms_message("VP8 encoder frames state:"); ms_message("\tgolden: count=%" PRIi64 ", picture_id=0x%04x, ack=%s", s->frames_state.golden.count, s->frames_state.golden.picture_id, (s->frames_state.golden.acknowledged == TRUE) ? "Y" : "N"); ms_message("\taltref: count=%" PRIi64 ", picture_id=0x%04x, ack=%s", s->frames_state.altref.count, s->frames_state.altref.picture_id, (s->frames_state.altref.acknowledged == TRUE) ? "Y" : "N"); #endif err = vpx_codec_encode(&s->codec, &img, s->frame_count, 1, flags, 1000000LL/(2*(int)s->vconf.fps)); /*encoder has half a framerate interval to encode*/ if (err) { ms_error("vpx_codec_encode failed : %d %s (%s)\n", err, vpx_codec_err_to_string(err), vpx_codec_error_detail(&s->codec)); } else { vpx_codec_iter_t iter = NULL; const vpx_codec_cx_pkt_t *pkt; MSList *list = NULL; /* Update the frames state. */ is_ref_frame=FALSE; if (flags & VPX_EFLAG_FORCE_KF) { enc_mark_reference_frame_as_sent(s, VP8_GOLD_FRAME); enc_mark_reference_frame_as_sent(s, VP8_ALTR_FRAME); s->frames_state.golden.is_independant=TRUE; s->frames_state.altref.is_independant=TRUE; s->frames_state.last_independent_frame=s->frame_count; s->force_keyframe = FALSE; is_ref_frame=TRUE; }else if (flags & VP8_EFLAG_FORCE_GF) { enc_mark_reference_frame_as_sent(s, VP8_GOLD_FRAME); is_ref_frame=TRUE; }else if (flags & VP8_EFLAG_FORCE_ARF) { enc_mark_reference_frame_as_sent(s, VP8_ALTR_FRAME); is_ref_frame=TRUE; }else if (flags & VP8_EFLAG_NO_REF_LAST) { enc_mark_reference_frame_as_sent(s, VP8_LAST_FRAME); is_ref_frame=is_reconstruction_frame_sane(s,flags); } if (is_frame_independent(flags)){ s->frames_state.last_independent_frame=s->frame_count; } /* Pack the encoded frame. */ while( (pkt = vpx_codec_get_cx_data(&s->codec, &iter)) ) { if ((pkt->kind == VPX_CODEC_CX_FRAME_PKT) && (pkt->data.frame.sz > 0)) { Vp8RtpFmtPacket *packet = ms_new0(Vp8RtpFmtPacket, 1); packet->m = allocb(pkt->data.frame.sz, 0); memcpy(packet->m->b_wptr, pkt->data.frame.buf, pkt->data.frame.sz); packet->m->b_wptr += pkt->data.frame.sz; mblk_set_timestamp_info(packet->m, timestamp); packet->pd = ms_new0(Vp8RtpFmtPayloadDescriptor, 1); packet->pd->start_of_partition = TRUE; packet->pd->non_reference_frame = s->avpf_enabled && !is_ref_frame; if (s->avpf_enabled == TRUE) { packet->pd->extended_control_bits_present = TRUE; packet->pd->pictureid_present = TRUE; packet->pd->pictureid = s->picture_id; } else { packet->pd->extended_control_bits_present = FALSE; packet->pd->pictureid_present = FALSE; } if (s->flags & VPX_CODEC_USE_OUTPUT_PARTITION) { packet->pd->pid = (uint8_t)pkt->data.frame.partition_id; if (!(pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT)) { mblk_set_marker_info(packet->m, TRUE); } } else { packet->pd->pid = 0; mblk_set_marker_info(packet->m, TRUE); } list = ms_list_append(list, packet); } } #ifdef AVPF_DEBUG ms_message("VP8 encoder picture_id=%i ***| %s | %s | %s | %s", (int)s->picture_id, (flags & VPX_EFLAG_FORCE_KF) ? "KF " : (flags & VP8_EFLAG_FORCE_GF) ? "GF " : (flags & VP8_EFLAG_FORCE_ARF) ? "ARF" : " ", (flags & VP8_EFLAG_NO_REF_GF) ? "NOREFGF" : " ", (flags & VP8_EFLAG_NO_REF_ARF) ? "NOREFARF" : " ", (flags & VP8_EFLAG_NO_REF_LAST) ? "NOREFLAST" : " "); #endif vp8rtpfmt_packer_process(&s->packer, list, f->outputs[0], f->factory); /* Handle video starter if AVPF is not enabled. */ s->frame_count++; if ((s->avpf_enabled != TRUE) && (s->frame_count == 1)) { ms_video_starter_first_frame(&s->starter, f->ticker->time); } /* Increment the pictureID. */ s->picture_id++; #ifdef PICTURE_ID_ON_16_BITS if (s->picture_id == 0) s->picture_id = 0x8000; #else if (s->picture_id == 0x0080) s->picture_id = 0; #endif } } ms_filter_unlock(f); ms_queue_flush(f->inputs[0]); }
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]); }
static void jpg_process(MSFilter *f){ JpegWriter *s=(JpegWriter*)f->data; if (s->file!=NULL && s->codec!=NULL){ MSPicture yuvbuf, yuvjpeg; mblk_t *m=ms_queue_peek_last(f->inputs[0]); if (ms_yuv_buf_init_from_mblk(&yuvbuf,m)==0){ int error; int comp_buf_sz=msgdsize(m); uint8_t *comp_buf=(uint8_t*)alloca(comp_buf_sz); AVFrame pict; mblk_t *jpegm; struct SwsContext *sws_ctx; AVCodecContext *avctx=avcodec_alloc_context(); avctx->width=yuvbuf.w; avctx->height=yuvbuf.h; avctx->time_base.num = 1; avctx->time_base.den =1; avctx->pix_fmt=PIX_FMT_YUVJ420P; error=avcodec_open(avctx,s->codec); if (error!=0) { ms_error("avcodec_open() failed: %i",error); cleanup(s,NULL); av_free(avctx); return; } sws_ctx=sws_getContext(avctx->width,avctx->height,PIX_FMT_YUV420P, avctx->width,avctx->height,avctx->pix_fmt,SWS_FAST_BILINEAR,NULL, NULL, NULL); if (sws_ctx==NULL) { ms_error(" sws_getContext() failed."); cleanup(s,avctx); goto end; } jpegm=ms_yuv_buf_alloc (&yuvjpeg,avctx->width, avctx->height); if (sws_scale(sws_ctx,(const uint8_t *const*)yuvbuf.planes,yuvbuf.strides,0,avctx->height,yuvjpeg.planes,yuvjpeg.strides)<0){ ms_error("sws_scale() failed."); sws_freeContext(sws_ctx); cleanup(s,avctx); freemsg(jpegm); goto end; } sws_freeContext(sws_ctx); avcodec_get_frame_defaults(&pict); avpicture_fill((AVPicture*)&pict,(uint8_t*)jpegm->b_rptr,avctx->pix_fmt,avctx->width,avctx->height); error=avcodec_encode_video(avctx, (uint8_t*)comp_buf,comp_buf_sz, &pict); if (error<0){ ms_error("Could not encode jpeg picture."); }else{ fwrite(comp_buf,error,1,s->file); ms_message("Snapshot done"); } cleanup(s,avctx); freemsg(jpegm); } goto end; } end: ms_queue_flush(f->inputs[0]); }