コード例 #1
0
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]);
}
コード例 #2
0
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]);
}
コード例 #3
0
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]);
}
コード例 #4
0
ファイル: beam-render.c プロジェクト: HyP3r-/beam-me-up
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);
  }
}
コード例 #5
0
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]);
}
コード例 #6
0
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]);
}
コード例 #7
0
ファイル: jpegwriter.c プロジェクト: Accontech/mediastreamer2
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)
コード例 #8
0
ファイル: vp8.c プロジェクト: Accontech/mediastreamer2
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]);
}
コード例 #9
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]);
}
コード例 #10
0
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]);
}
コード例 #11
0
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]);
}