예제 #1
0
파일: mmalcam.c 프로젝트: billw2/pikrellcam
  /* Connect two mmal components which will transer data via an ARM callback.
  |  A components output data may be processed or altered before being
  |  passed to a components input port.  The camera out object will be passed
  |  as userdata to the callback as it must have the callback_port_in and
  |  callback_pool_in values.
  */
boolean
ports_callback_connect(CameraObject *out, int port_num,
			CameraObject *in, void callback())
	{
	MMAL_PORT_T		*callback_port_in;
	MMAL_STATUS_T	status;
	boolean			result;

	if (!out->component || !in->component)
		return FALSE;
	callback_port_in = in->component->input[0];

	/* Create the buffer pool and queue for the input port the callback
	|  will send buffers to after processing. Input port is likely an encoder.
	*/
	out->callback_port_in = callback_port_in;
	out->callback_pool_in = mmal_port_pool_create(callback_port_in,
						callback_port_in->buffer_num, callback_port_in->buffer_size);

	if ((status = mmal_port_enable(callback_port_in, input_buffer_callback))
					!= MMAL_SUCCESS)
		{
		log_printf(
			"ports_callback_connect %s: mmal_port_enable failed.  Status %s\n",
                        in->name, mmal_status[status]);
		result = FALSE;
		}
	else
		result = out_port_callback(out, port_num, callback);

	return result;
	}
예제 #2
0
void
camera_start(void)
	{
	MMAL_STATUS_T	status;

	motion_init();
	circular_buffer_init();

	camera_create();

	/* ====== Create the camera preview port path ====== :
	|  preview --(tunnel)--> resizer --> I420_callback --> jpeg_encoder --> mjpeg_callback
	|                                   (draws on frame)                   (writes stream mjpeg.jpg)
	*/
	pikrellcam.mjpeg_height = pikrellcam.mjpeg_width *
					pikrellcam.camera_config.video_height / pikrellcam.camera_config.video_width;
	pikrellcam.mjpeg_width &= ~0xf;		/* Make resize multiple of 16 */
	pikrellcam.mjpeg_height &= ~0xf;
	resizer_create("stream_resizer", &stream_resizer,
							camera.component->output[CAMERA_PREVIEW_PORT],
							pikrellcam.mjpeg_width, pikrellcam.mjpeg_height);
	ports_tunnel_connect(&camera, CAMERA_PREVIEW_PORT, &stream_resizer);
	jpeg_encoder_create("mjpeg_encoder", &mjpeg_encoder,
					stream_resizer.component->output[0], pikrellcam.mjpeg_quality);
	ports_callback_connect(&stream_resizer, 0, &mjpeg_encoder,
					I420_video_callback);
	out_port_callback(&mjpeg_encoder, 0, mjpeg_callback);


	/* ====== Create the camera still port path ====== :
	|  camera_capture --(tunnel)--> jpeg_encoder --> still_jpeg__callback
	|                                               (writes stills and timelapse jpegs)
	*/
	jpeg_encoder_create("still_jpeg_encoder", &still_jpeg_encoder,
					NULL, pikrellcam.camera_adjust.still_quality);
	ports_tunnel_connect(&camera, CAMERA_CAPTURE_PORT, &still_jpeg_encoder);
	out_port_callback(&still_jpeg_encoder, 0, still_jpeg_callback);


	/* ====== Create the camera video port path ====== :
	|  camera_video--(tunnel)-->h264 encoder-->video_h264_encoder_callback
	|                                         (writes data into video circular buffer)
	|                                         (records video / checks motion vectors)
	|                                         (schedules mjpeg.jpg copy into previews)
	*/
	h264_encoder_create("video_h264_encoder", &video_h264_encoder, NULL);
	ports_tunnel_connect(&camera, CAMERA_VIDEO_PORT, &video_h264_encoder);
	out_port_callback(&video_h264_encoder, 0, video_h264_encoder_callback);

	time(&pikrellcam.t_start);

	/* Turn on the video stream. It free runs into the video circular buffer.
	*/
	if ((status = mmal_port_parameter_set_boolean(
				camera.component->output[CAMERA_VIDEO_PORT],
				MMAL_PARAMETER_CAPTURE, 1)) != MMAL_SUCCESS)
		log_printf("Video capture startup failed. Status %s\n",
					mmal_status[status]);

	/* With everything created and running, set the config'ed camera params.
	*/
	mmalcam_config_parameters_set_camera();

	display_init();
	video_circular_buffer.state = VCB_STATE_NONE;
	video_circular_buffer.pause = FALSE;
	}