Exemplo n.º 1
0
/*! \brief read a frame from webcam or X11 through grabber_read(),
 * display it,  then encode and split it.
 * Return a list of ast_frame representing the video fragments.
 * The head pointer is returned by the function, the tail pointer
 * is returned as an argument.
 */
static struct ast_frame *get_video_frames(struct video_desc *env, struct ast_frame **tail)
{
	struct video_out_desc *v = &env->out;
	struct ast_frame *dummy;
	struct fbuf_t *loc_src = grabber_read(v);

	if (!loc_src)
		return NULL;	/* can happen, e.g. we are reading too early */

	if (tail == NULL)
		tail = &dummy;
	*tail = NULL;
	/* Scale the video for the encoder, then use it for local rendering
	 * so we will see the same as the remote party.
	 */
	my_scale(loc_src, NULL, &env->enc_in, NULL);
	show_frame(env, WIN_LOCAL);
	if (!v->sendvideo)
		return NULL;
	if (v->enc_out.data == NULL) {
		static volatile int a = 0;
		if (a++ < 2)
			ast_log(LOG_WARNING, "fail, no encoder output buffer\n");
		return NULL;
	}
	v->enc->enc_run(v);
	return v->enc->enc_encap(&v->enc_out, v->mtu, tail);
}
Exemplo n.º 2
0
/*! \brief refreshes the buffers of all the device by calling the
 * grabber_read on each device in the device table.
 * it encodes the primary source buffer, if the picture in picture mode is
 * enabled it encodes (in the buffer to split) the secondary source buffer too.
 * The encoded buffer is splitted to build the local and the remote view.
 * Return a list of ast_frame representing the video fragments.
 * The head pointer is returned by the function, the tail pointer
 * is returned as an argument.
 *
 * \param env = video environment descriptor
 * \param tail = tail ponter (pratically a return value)
 */
static struct ast_frame *get_video_frames(struct video_desc *env, struct ast_frame **tail)
{
	struct video_out_desc *v = &env->out;
	struct ast_frame *dummy;
	struct fbuf_t *loc_src_primary = NULL, *p_read;
	int i;
	/* if no device was found in the config file */
	if (!env->out.device_num)
		return NULL;
	/* every time this function is called we refresh the buffers of every device,
	updating the private device buffer in the device table */
	for (i = 0; i < env->out.device_num; i++) {
		p_read = grabber_read(&env->out.devices[i], env->out.fps);
		/* it is used only if different from NULL, we mantain last good buffer otherwise */
		if (p_read)
			env->out.devices[i].dev_buf = p_read;
	}
	/* select the primary device buffer as the one to encode */
	loc_src_primary = env->out.devices[env->out.device_primary].dev_buf;
	/* loc_src_primary can be NULL if the device has been turned off during
	execution of it is read too early */
	if (loc_src_primary) {
		/* Scale the video for the encoder, then use it for local rendering
		so we will see the same as the remote party */
		my_scale(loc_src_primary, NULL, &env->enc_in, NULL);
	}
	if (env->out.picture_in_picture) { /* the picture in picture mode is enabled */
		struct fbuf_t *loc_src_secondary;
		/* reads from the secondary source */
		loc_src_secondary = env->out.devices[env->out.device_secondary].dev_buf;
		if (loc_src_secondary) {
			env->enc_in.win_x = env->out.pip_x;
			env->enc_in.win_y = env->out.pip_y;
			env->enc_in.win_w = env->enc_in.w/3;
			env->enc_in.win_h = env->enc_in.h/3;
			/* scales to the correct geometry and inserts in
			the enc_in buffer the picture in picture */
			my_scale(loc_src_secondary, NULL, &env->enc_in, NULL);
			/* returns to normal parameters (not picture in picture) */
			env->enc_in.win_x = 0;
			env->enc_in.win_y = 0;
			env->enc_in.win_w = 0;
			env->enc_in.win_h = 0;
		}
		else {
			/* loc_src_secondary can be NULL if the device has been turned off during
			execution of it is read too early */
			env->out.picture_in_picture = 0; /* disable picture in picture */
		}
	}
	show_frame(env, WIN_LOCAL); /* local rendering */
	for (i = 0; i < env->out.device_num; i++) 
		show_frame(env, i+WIN_SRC1); /* rendering of every source device in thumbnails */
	if (tail == NULL)
		tail = &dummy;
	*tail = NULL;
	/* if no reason for encoding, do not encode */
	if (!env->owner || !loc_src_primary || !v->sendvideo)
		return NULL;
	if (v->enc_out.data == NULL) {
		static volatile int a = 0;
		if (a++ < 2)
			ast_log(LOG_WARNING, "fail, no encoder output buffer\n");
		return NULL;
	}
	v->enc->enc_run(v);
	return v->enc->enc_encap(&v->enc_out, v->mtu, tail);
}