示例#1
0
  /* Connect a component output[portnum] to a components input[0] using
  |  TUNNELLING to keep processing within the GPU (no callbacks to the
  |  ARM for these connections).
  */
boolean
ports_tunnel_connect(CameraObject *out, int port_num, CameraObject *in)
	{
	MMAL_PORT_T			*out_port, *in_port;
	MMAL_CONNECTION_T	*connection = NULL;
	MMAL_STATUS_T		status;
	char				*msg = "mmal_connection_create";
	boolean				result = TRUE;

	if (!out->component || !in->component)
		return FALSE;
	out_port = out->component->output[port_num];
	in_port =  in->component->input[0];

	if ((status = mmal_connection_create(&connection, out_port, in_port,
					  MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT
					| MMAL_CONNECTION_FLAG_TUNNELLING))  == MMAL_SUCCESS)
		{
		msg = "mmal_connection_enable";
		status = mmal_connection_enable(connection);
		}
	if (status != MMAL_SUCCESS)
		{
		if (connection)
			mmal_connection_destroy(connection);
		connection = NULL;
		result = FALSE;
		log_printf("ports_tunnel_connect %s_out->%s_in: %s failed.  Status %s\n",
						out->name, in->name, msg, mmal_status[status]);
		}
	in->input_connection = connection;
	return result;
	}
MMAL_STATUS_T Private_Impl_Still::connectPorts ( MMAL_PORT_T *output_port, MMAL_PORT_T *input_port, MMAL_CONNECTION_T **connection ) {
    MMAL_STATUS_T status =  mmal_connection_create ( connection, output_port, input_port, MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT );
    if ( status == MMAL_SUCCESS ) {
        status =  mmal_connection_enable ( *connection );
        if ( status != MMAL_SUCCESS )
            mmal_connection_destroy ( *connection );
    }

    return status;
}
/**
 * Connect two specific ports together
 *
 * @param output_port Pointer the output port
 * @param input_port Pointer the input port
 * @param Pointer to a mmal connection pointer, reassigned if function successful
 * @return Returns a MMAL_STATUS_T giving result of operation
 *
 */
static MMAL_STATUS_T connect_ports(MMAL_PORT_T *output_port, MMAL_PORT_T *input_port, MMAL_CONNECTION_T **connection)
{
	MMAL_STATUS_T status;

	status =  mmal_connection_create(connection, output_port, input_port, MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT);

	if (status == MMAL_SUCCESS)
	{
		status =  mmal_connection_enable(*connection);
		if (status != MMAL_SUCCESS)
		{
			vcos_log_error("Failed to connect ports %s and %s - status %d", output_port->name, input_port->name);
			mmal_connection_destroy(*connection);
		}
	}

	return status;
}
示例#4
0
int setup_preview(PORT_USERDATA *userdata) {
    MMAL_STATUS_T status;
    MMAL_COMPONENT_T *preview = 0;
    MMAL_CONNECTION_T *camera_preview_connection = 0;
    MMAL_PORT_T *preview_input_port;

    status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &preview);
    if (status != MMAL_SUCCESS) {
        fprintf(stderr, "Error: unable to create preview (%u)\n", status);
        return -1;
    }
    userdata->preview = preview;
    preview_input_port = preview->input[0];

    {
        MMAL_DISPLAYREGION_T param;
        param.hdr.id = MMAL_PARAMETER_DISPLAYREGION;
        param.hdr.size = sizeof (MMAL_DISPLAYREGION_T);
        param.set = MMAL_DISPLAY_SET_LAYER;
        param.layer = 0;
        param.set |= MMAL_DISPLAY_SET_FULLSCREEN;
        param.fullscreen = 1;
        status = mmal_port_parameter_set(preview_input_port, &param.hdr);
        if (status != MMAL_SUCCESS && status != MMAL_ENOSYS) {
            fprintf(stderr, "Error: unable to set preview port parameters (%u)\n", status);
            return -1;
        }
    }


    status = mmal_connection_create(&camera_preview_connection, userdata->camera_preview_port, preview_input_port, MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT);
    if (status != MMAL_SUCCESS) {
        fprintf(stderr, "Error: unable to create connection (%u)\n", status);
        return -1;
    }

    status = mmal_connection_enable(camera_preview_connection);
    if (status != MMAL_SUCCESS) {
        fprintf(stderr, "Error: unable to enable connection (%u)\n", status);
        return -1;
    }
    //fprintf(stderr, "INFO: preview created\n");
    return 0;
}
示例#5
0
bool CCameraOutput::Init(int width, int height, MMAL_COMPONENT_T* input_component, int input_port_idx, bool do_argb_conversion)
{
	printf("Init camera output with %d/%d\n",width,height);
	Width = width;
	Height = height;

	MMAL_COMPONENT_T *resizer = 0;
	MMAL_CONNECTION_T* connection = 0;
	MMAL_STATUS_T status;
	MMAL_POOL_T* video_buffer_pool = 0;
	MMAL_QUEUE_T* output_queue = 0;

	//got the port we're receiving from
	MMAL_PORT_T* input_port = input_component->output[input_port_idx];

	//check if user wants conversion to argb or the width or height is different to the input
	if(do_argb_conversion || width != input_port->format->es->video.width || height != input_port->format->es->video.height)
	{
		//create the resizing component, reading from the splitter output
		resizer = CreateResizeComponentAndSetupPorts(input_port,do_argb_conversion);
		if(!resizer)
			goto error;

		//create and enable a connection between the video output and the resizer input
		status = mmal_connection_create(&connection, input_port, resizer->input[0], MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT);
		if (status != MMAL_SUCCESS)
		{
			printf("Failed to create connection\n");
			goto error;
		}
		status = mmal_connection_enable(connection);
		if (status != MMAL_SUCCESS)
		{
			printf("Failed to enable connection\n");
			goto error;
		}

		//set the buffer pool port to be the resizer output
		BufferPort = resizer->output[0];
	}
	else
	{
		//no convert/resize needed so just set the buffer pool port to be the input port
		BufferPort = input_port;
	}

	//setup the video buffer callback
	video_buffer_pool = EnablePortCallbackAndCreateBufferPool(BufferPort,VideoBufferCallback,3);
	if(!video_buffer_pool)
		goto error;

	//create the output queue
	output_queue = mmal_queue_create();
	if(!output_queue)
	{
		printf("Failed to create output queue\n");
		goto error;
	}

	ResizerComponent = resizer;
	BufferPool = video_buffer_pool;
	OutputQueue = output_queue;
	Connection = connection;

	return true;

error:

	if(output_queue)
		mmal_queue_destroy(output_queue);
	if(video_buffer_pool)
		mmal_port_pool_destroy(resizer->output[0],video_buffer_pool);
	if(connection)
		mmal_connection_destroy(connection);
	if(resizer)
		mmal_component_destroy(resizer);

	return false;
}
示例#6
0
bool CCamera::Init(int width, int height, int framerate, int num_levels, bool do_argb_conversion)
{
	//init broadcom host - QUESTION: can this be called more than once??
	bcm_host_init();

	//store basic parameters
	Width = width;       
	Height = height;
	FrameRate = framerate;

	// Set up the camera_parameters to default
	raspicamcontrol_set_defaults(&CameraParameters);

	// Change default parameter, i.e .rotate image
	int rotation = 90;
	int my_rotation = ((rotation % 360 ) / 90) * 90;
	CameraParameters.rotation = my_rotation;
	//ret = mmal_port_parameter_set_int32(camera->output[0], MMAL_PARAMETER_ROTATION, my_rotation);
	//mmal_port_parameter_set_int32(camera->output[1], MMAL_PARAMETER_ROTATION, my_rotation);
	//mmal_port_parameter_set_int32(camera->output[2], MMAL_PARAMETER_ROTATION, my_rotation);

#ifdef WITH_ENCODER
	MMAL_COMPONENT_T *encoder = 0;
#endif

	MMAL_COMPONENT_T *camera = 0;
	MMAL_COMPONENT_T *splitter = 0;
	MMAL_CONNECTION_T* vid_to_split_connection = 0;
	MMAL_PORT_T *video_port = NULL;
	MMAL_STATUS_T status;
	CCameraOutput* outputs[4]; memset(outputs,0,sizeof(outputs));

	//create the camera component
	camera = CreateCameraComponentAndSetupPorts();
	if (!camera)
		goto error;

	//get the video port
	video_port = camera->output[MMAL_CAMERA_VIDEO_PORT];
	video_port->buffer_num = 3;

	//create the splitter component
	splitter = CreateSplitterComponentAndSetupPorts(video_port);
	if(!splitter)
		goto error;

	//create and enable a connection between the video output and the resizer input
	status = mmal_connection_create(&vid_to_split_connection, video_port, splitter->input[0], MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT);
	if (status != MMAL_SUCCESS)
	{
		printf("Failed to create connection\n");
		goto error;
	}
	status = mmal_connection_enable(vid_to_split_connection);
	if (status != MMAL_SUCCESS)
	{
		printf("Failed to enable connection\n");
		goto error;
	}

	//setup all the outputs
	for(int i = 0; i < num_levels; i++)
	{
		outputs[i] = new CCameraOutput();
		if(!outputs[i]->Init(Width >> i,Height >> i,splitter,i,do_argb_conversion))
		{
			printf("Failed to initialize output %d\n",i);
			goto error;
		}
	}

#ifdef WITH_ENCODER
	encoder = CreateEncoderComponentAndSetupPorts();
	if (!encoder)
		goto error;
#endif

	//begin capture
	if (mmal_port_parameter_set_boolean(video_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS)
	{
		printf("Failed to start capture\n");
		goto error;
	}

	//store created info
	CameraComponent = camera;
	SplitterComponent = splitter;
	VidToSplitConn = vid_to_split_connection;
	memcpy(Outputs,outputs,sizeof(outputs));

	//return success
	printf("Camera successfully created\n");
	return true;

error:
	if(vid_to_split_connection)
		mmal_connection_destroy(vid_to_split_connection);
	if(camera)
		mmal_component_destroy(camera);
	if(splitter)
		mmal_component_destroy(splitter);
	for(int i = 0; i < 4; i++)
	{
		if(outputs[i])
		{
			outputs[i]->Release();
			delete outputs[i];
		}
	}
#ifdef WITH_ENCODER
	if(encoder){}
#endif

	return false;
}
int main(int argc, char **argv)
{
	MMAL_COMPONENT_T *camera =0;
	MMAL_COMPONENT_T *preview=0;
	MMAL_COMPONENT_T *encoder=0;
	MMAL_CONNECTION_T *preview_conn=0;
	MMAL_CONNECTION_T *encoder_conn=0;
	USERDATA_T callback_data;

	// bcm should be initialized before any GPU call is made
	bcm_host_init();

	setNonDefaultOptions(argc, argv);

	// Open file to save the video 
	open_new_file_handle(&callback_data, output_file_name);
	fprintf(stderr, "Output Filename: %s\n", output_file_name);

	// Create Camera, set default values and enable it
	vcos_assert((mmal_component_create(MMAL_COMPONENT_DEFAULT_CAMERA, &camera) == MMAL_SUCCESS) 
		&& "Failed creating camera component");

	vcos_assert((set_camera_component_defaults(camera)) == MMAL_SUCCESS
		&& "Failed setting camera components default values");

	vcos_assert((mmal_component_enable(camera) == MMAL_SUCCESS) 
		&& "Failed to enable camera component");

	// Create Preview, set default values and enable it
	vcos_assert((mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &preview) == MMAL_SUCCESS) 
		&& "Failed creating preview component");

	vcos_assert((set_preview_component_defaults(preview) == MMAL_SUCCESS) 
		&& "Failed setting preview components default values");

	vcos_assert((mmal_component_enable(preview) == MMAL_SUCCESS) 
		&& "Failed to enable camera component");

	// Create Encoder, set defaults, enable it and create encoder pool
        vcos_assert((mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_ENCODER, &encoder) == MMAL_SUCCESS)
                && "Failed to create encoder component");

        vcos_assert((encoder->input_num && encoder->output_num)
                && "Video encoder does not have input/output ports\n");

        set_encoder_component_defaults(encoder);

        vcos_assert((mmal_component_enable(encoder) == MMAL_SUCCESS)
		&& "Failed enabling encoder component");

        callback_data.pool = (MMAL_POOL_T *)mmal_port_pool_create(encoder->output[0],
                        encoder->output[0]->buffer_num, encoder->output[0]->buffer_size);

        vcos_assert(callback_data.pool && "Failed creating encoder pool\n");

	// Setup connections
	vcos_assert((mmal_connection_create(&preview_conn, camera->output[0], preview->input[0], 
		MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT) == MMAL_SUCCESS) 
		&& "Failed stablishing connection between camera output 0 and preview");

	vcos_assert((mmal_connection_enable(preview_conn) == MMAL_SUCCESS) 
		&& "Failed enabling connection between camera output 0 and preview");

        vcos_assert((mmal_connection_create(&encoder_conn, camera->output[1], encoder->input[0],
        //        MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT) == MMAL_SUCCESS)
                MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT) == MMAL_SUCCESS)
                && "Failed creating encoder connection to capture (camera output 1)");

        vcos_assert((mmal_connection_enable(encoder_conn) == MMAL_SUCCESS)
                && "Failed enabling encoder connection to capture (campera output 1)");

	encoder_conn->callback = connection_video2encoder_callback;

	// Set callback and enable encoder port
	encoder->output[0]->userdata = (struct MMAL_PORT_USERDATA_T *)&callback_data;
	vcos_assert(MMAL_SUCCESS == mmal_port_enable(encoder->output[0], encoder_callback));


	// Send the buffer to encode output port
	MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(callback_data.pool->queue);
	vcos_assert((mmal_port_send_buffer(encoder->output[0], buffer)== MMAL_SUCCESS)
		&& "Unable to send buffer to encoder output port");

	vcos_assert((mmal_port_parameter_set_boolean(camera->output[1], MMAL_PARAMETER_CAPTURE, 1) == MMAL_SUCCESS) 
		&& "Unable to set camera->output[1] capture parameter");

	consume_queue_on_connection(encoder_conn->out, encoder_conn->pool->queue);

	while(1)
	{
        	vcos_sleep(1000); // wait for exit call	
		if (exit_prog){
        		vcos_sleep(500); // exit called, wait for all buffers be flushed
			break;
		}
	}

	return 0;
}
示例#8
0
static MMAL_STATUS_T mmalplay_connection_create(MMALPLAY_T *ctx, MMAL_PORT_T *out, MMAL_PORT_T *in, uint32_t flags)
{
   MMAL_CONNECTION_T **connection = &ctx->connection[ctx->connection_num];
   uint32_t encoding_override = MMAL_ENCODING_UNKNOWN;
   MMAL_RECT_T *rect_override = NULL;
   MMAL_BOOL_T format_override = MMAL_FALSE;
   MMAL_STATUS_T status;

   if (ctx->connection_num >= MMAL_COUNTOF(ctx->connection))
      return MMAL_ENOMEM;

   /* Globally enable tunnelling if requested by the user */
   flags |= ctx->options.tunnelling ? MMAL_CONNECTION_FLAG_TUNNELLING : 0;

   /* Apply any override to the format specified by the user */
   if (out == ctx->video_out_port)
   {
      encoding_override = ctx->options.output_format;
      rect_override = &ctx->options.output_rect;
   }
   else if (out == ctx->converter_out_port)
   {
      encoding_override = ctx->options.render_format;
      rect_override = &ctx->options.render_rect;
   }

   if (encoding_override != MMAL_ENCODING_UNKNOWN &&
       encoding_override != out->format->encoding)
   {
      out->format->encoding = encoding_override;
      format_override = MMAL_TRUE;
   }

   if (rect_override && rect_override->width && rect_override->height)
   {
      out->format->es->video.crop = *rect_override;
      out->format->es->video.width = rect_override->width;
      out->format->es->video.height = rect_override->height;
      format_override = MMAL_TRUE;
   }

   if (format_override)
   {
      status = mmal_port_format_commit(out);
      if (status != MMAL_SUCCESS)
      {
         LOG_ERROR("cannot override format on output port %s", out->name);
         return status;
      }
   }

   /* Create the actual connection */
   status = mmal_connection_create(connection, out, in, flags);
   if (status != MMAL_SUCCESS)
   {
      LOG_ERROR("cannot create connection");
      return status;
   }

   /* Set our connection callback */
   (*connection)->callback = mmalplay_connection_cb;
   (*connection)->user_data = (void *)ctx;

   log_format(out->format, out);
   log_format(in->format, in);

   ctx->connection_num++;
   return MMAL_SUCCESS;
}
示例#9
0
bool CMMALVideo::CreateDeinterlace(EINTERLACEMETHOD interlace_method)
{
  MMAL_STATUS_T status;

  if (g_advancedSettings.CanLogComponent(LOGVIDEO))
    CLog::Log(LOGDEBUG, "%s::%s method:%d", CLASSNAME, __func__, interlace_method);

  assert(!m_deint);
  assert(m_dec_output == m_dec->output[0]);

  status = mmal_port_disable(m_dec_output);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to disable decoder output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  /* Create deinterlace filter */
  status = mmal_component_create("vc.ril.image_fx", &m_deint);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to create deinterlace component (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }
  MMAL_PARAMETER_IMAGEFX_PARAMETERS_T imfx_param = {{MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, sizeof(imfx_param)},
        interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED || interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF ?
            MMAL_PARAM_IMAGEFX_DEINTERLACE_ADV : MMAL_PARAM_IMAGEFX_DEINTERLACE_FAST,
        3, {3, 0, interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF || interlace_method == VS_INTERLACEMETHOD_MMAL_BOB_HALF }};
  status = mmal_port_parameter_set(m_deint->output[0], &imfx_param.hdr);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to set deinterlace parameters (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  MMAL_PORT_T *m_deint_input = m_deint->input[0];
  m_deint_input->userdata = (struct MMAL_PORT_USERDATA_T *)this;

  // Now connect the decoder output port to deinterlace input port
  status =  mmal_connection_create(&m_deint_connection, m_dec->output[0], m_deint->input[0], MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to connect deinterlacer component %s (status=%x %s)", CLASSNAME, __func__, m_deint->name, status, mmal_status_to_string(status));
    return false;
  }

  status =  mmal_connection_enable(m_deint_connection);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to enable connection %s (status=%x %s)", CLASSNAME, __func__, m_deint->name, status, mmal_status_to_string(status));
    return false;
  }

  mmal_format_copy(m_deint->output[0]->format, m_es_format);
  status = mmal_port_format_commit(m_deint->output[0]);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to commit deint output format (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  status = mmal_component_enable(m_deint);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to enable deinterlacer component %s (status=%x %s)", CLASSNAME, __func__, m_deint->name, status, mmal_status_to_string(status));
    return false;
  }

  m_deint->output[0]->buffer_size = m_deint->output[0]->buffer_size_min;
  m_deint->output[0]->buffer_num = m_deint->output[0]->buffer_num_recommended;
  m_deint->output[0]->userdata = (struct MMAL_PORT_USERDATA_T *)this;
  status = mmal_port_enable(m_deint->output[0], dec_output_port_cb_static);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to enable decoder output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  m_dec_output = m_deint->output[0];
  m_interlace_method = interlace_method;

  return true;
}
示例#10
0
/* Create Simple Video Player instance. */
SVP_T *svp_create(const char *uri, SVP_CALLBACKS_T *callbacks, const SVP_OPTS_T *opts)
{
   SVP_T *svp;
   MMAL_STATUS_T st;
   VCOS_STATUS_T vst;
   MMAL_PORT_T *reader_output = NULL;
   MMAL_COMPONENT_T *video_decode = NULL;
   MMAL_PORT_T *video_output = NULL;

   LOG_TRACE("Creating player for %s", (uri ? uri : "camera preview"));

   vcos_assert(callbacks->video_frame_cb);
   vcos_assert(callbacks->stop_cb);

   svp = vcos_calloc(1, sizeof(*svp), "svp");
   CHECK_STATUS((svp ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to allocate context");

   svp->opts = *opts;
   svp->callbacks = *callbacks;

   /* Semaphore used for synchronising buffer handling for decoded frames */
   vst = vcos_semaphore_create(&svp->sema, "svp-sem", 0);
   CHECK_STATUS((vst == VCOS_SUCCESS ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to create semaphore");
   svp->created |= SVP_CREATED_SEM;

   vst = vcos_mutex_create(&svp->mutex, "svp-mutex");
   CHECK_STATUS((vst == VCOS_SUCCESS ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to create mutex");
   svp->created |= SVP_CREATED_MUTEX;

   vst = vcos_timer_create(&svp->timer, "svp-timer", svp_timer_cb, svp);
   CHECK_STATUS((vst == VCOS_SUCCESS ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to create timer");
   svp->created |= SVP_CREATED_TIMER;

   vst = vcos_timer_create(&svp->wd_timer, "svp-wd-timer", svp_watchdog_cb, svp);
   CHECK_STATUS((vst == VCOS_SUCCESS ? MMAL_SUCCESS : MMAL_ENOMEM), "Failed to create timer");
   svp->created |= SVP_CREATED_WD_TIMER;

   /* Create components */
   svp->reader = NULL;
   svp->video_decode = NULL;
   svp->camera = NULL;
   svp->connection = NULL;

   if (uri)
   {
      /* Video from URI: setup container_reader -> video_decode */

      /* Create and set up container reader */
      st = mmal_component_create(MMAL_COMPONENT_DEFAULT_CONTAINER_READER, &svp->reader);
      CHECK_STATUS(st, "Failed to create container reader");

      st = svp_setup_reader(svp->reader, uri, &reader_output);
      if (st != MMAL_SUCCESS)
         goto error;

      st = mmal_component_enable(svp->reader);
      CHECK_STATUS(st, "Failed to enable container reader");

      st = svp_port_enable(svp, svp->reader->control, svp_bh_control_cb);
      CHECK_STATUS(st, "Failed to enable container reader control port");

      /* Create and set up video decoder */
      st = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &svp->video_decode);
      CHECK_STATUS(st, "Failed to create video decoder");

      video_decode = svp->video_decode;
      video_output = video_decode->output[0];

      st = mmal_component_enable(video_decode);
      CHECK_STATUS(st, "Failed to enable video decoder");

      st = svp_port_enable(svp, video_decode->control, svp_bh_control_cb);
      CHECK_STATUS(st, "Failed to enable video decoder control port");
   }
   else
   {
      /* Camera preview */
      MMAL_PARAMETER_CAMERA_CONFIG_T config;

      st = mmal_component_create(MMAL_COMPONENT_DEFAULT_CAMERA, &svp->camera);
      CHECK_STATUS(st, "Failed to create camera");

      st = mmal_component_enable(svp->camera);
      CHECK_STATUS(st, "Failed to enable camera");

      st = svp_port_enable(svp, svp->camera->control, svp_bh_control_cb);
      CHECK_STATUS(st, "Failed to enable camera control port");

      video_output = svp->camera->output[0]; /* Preview port */
   }

   st = mmal_port_parameter_set_boolean(video_output, MMAL_PARAMETER_ZERO_COPY, MMAL_TRUE);
   CHECK_STATUS((st == MMAL_ENOSYS ? MMAL_SUCCESS : st), "Failed to enable zero copy");

   if (uri)
   {
      /* Create connection: container_reader -> video_decoder */
      st = mmal_connection_create(&svp->connection, reader_output, video_decode->input[0],
                                  MMAL_CONNECTION_FLAG_TUNNELLING);
      CHECK_STATUS(st, "Failed to create connection");
   }

   /* Set video output port format.
    * Opaque encoding ensures we get buffer data as handles to relocatable heap. */
   video_output->format->encoding = MMAL_ENCODING_OPAQUE;

   if (!uri)
   {
      /* Set video format for camera preview */
      MMAL_VIDEO_FORMAT_T *vfmt = &video_output->format->es->video;

      CHECK_STATUS((video_output->format->type == MMAL_ES_TYPE_VIDEO) ? MMAL_SUCCESS : MMAL_EINVAL,
                   "Output port isn't video format");

      vfmt->width = SVP_CAMERA_WIDTH;
      vfmt->height = SVP_CAMERA_HEIGHT;
      vfmt->crop.x = 0;
      vfmt->crop.y = 0;
      vfmt->crop.width = vfmt->width;
      vfmt->crop.height = vfmt->height;
      vfmt->frame_rate.num = SVP_CAMERA_FRAMERATE;
      vfmt->frame_rate.den = 1;
   }

   st = mmal_port_format_commit(video_output);
   CHECK_STATUS(st, "Failed to set output port format");

   /* Finally, set buffer num/size. N.B. For container_reader/video_decode, must be after
    * connection created, in order for port format to propagate.
    * Don't enable video output port until want to produce frames. */
   video_output->buffer_num = video_output->buffer_num_recommended;
   video_output->buffer_size = video_output->buffer_size_recommended;

   /* Pool + queue to hold decoded video frames */
   svp->out_pool = mmal_port_pool_create(video_output, video_output->buffer_num,
                                         video_output->buffer_size);
   CHECK_STATUS((svp->out_pool ? MMAL_SUCCESS : MMAL_ENOMEM), "Error allocating pool");
   svp->queue = mmal_queue_create();
   CHECK_STATUS((svp ? MMAL_SUCCESS : MMAL_ENOMEM), "Error allocating queue");

   svp->video_output = video_output;

   return svp;

error:
   svp_destroy(svp);
   return NULL;
}
示例#11
0
文件: RaspiMJPEG.c 项目: jrv/userland
int main (int argc, char* argv[]) {

  MMAL_STATUS_T status;
  int i, max, fd, length, cam_setting;
  unsigned long int cam_setting_long;
  char readbuf[20];
  char *filename_temp, *filename_temp2, *cmd_temp;

  bcm_host_init();
  
  //
  // read arguments
  //
  unsigned char of_set = 0;
  for(i=1; i<argc; i++) {
    if(strcmp(argv[i], "--version") == 0) {
      printf("RaspiMJPEG Version ");
      printf(VERSION);
      printf("\n");
      exit(0);
    }
    else if(strcmp(argv[i], "-w") == 0) {
      i++;
      width = atoi(argv[i]);
    }
    else if(strcmp(argv[i], "-h") == 0) {
      i++;
      height = atoi(argv[i]);
    }
    else if(strcmp(argv[i], "-wp") == 0) {
      i++;
      width_pic = atoi(argv[i]);
    }
    else if(strcmp(argv[i], "-hp") == 0) {
      i++;
      height_pic = atoi(argv[i]);
    }
    else if(strcmp(argv[i], "-q") == 0) {
      i++;
      quality = atoi(argv[i]);
    }
    else if(strcmp(argv[i], "-d") == 0) {
      i++;
      divider = atoi(argv[i]);
    }
    else if(strcmp(argv[i], "-p") == 0) {
      mp4box = 1;
    }
    else if(strcmp(argv[i], "-ic") == 0) {
      i++;
      image2_cnt = atoi(argv[i]);
    }
    else if(strcmp(argv[i], "-vc") == 0) {
      i++;
      video_cnt = atoi(argv[i]);
    }
    else if(strcmp(argv[i], "-of") == 0) {
      i++;
      jpeg_filename = argv[i];
      of_set = 1;
    }
    else if(strcmp(argv[i], "-if") == 0) {
      i++;
      jpeg2_filename = argv[i];
      of_set = 1;
    }
    else if(strcmp(argv[i], "-cf") == 0) {
      i++;
      pipe_filename = argv[i];
    }
    else if(strcmp(argv[i], "-vf") == 0) {
      i++;
      h264_filename = argv[i];
    }
    else if(strcmp(argv[i], "-sf") == 0) {
      i++;
      status_filename = argv[i];
    }
    else if(strcmp(argv[i], "-pa") == 0) {
      autostart = 0;
      idle = 1;
    }
    else if(strcmp(argv[i], "-md") == 0) {
      motion_detection = 1;
    }
    else if(strcmp(argv[i], "-fp") == 0) {
      preview_mode = RES_4_3;
    }
    else if(strcmp(argv[i], "-audio") == 0) {
      audio_mode = 1;
    }
    else error("Invalid arguments");
  }
  if(!of_set) error("Output file not specified");
  
  //
  // init
  //
  if(autostart) start_all();
  if(motion_detection) {
    if(system("motion") == -1) error("Could not start Motion");
  }

  //
  // run
  //
  if(autostart) {
    if(pipe_filename != 0) printf("MJPEG streaming, ready to receive commands\n");
    else printf("MJPEG streaming\n");
  }
  else {
    if(pipe_filename != 0) printf("MJPEG idle, ready to receive commands\n");
    else printf("MJPEG idle\n");
  }

  struct sigaction action;
  memset(&action, 0, sizeof(struct sigaction));
  action.sa_handler = term;
  sigaction(SIGTERM, &action, NULL);
  sigaction(SIGINT, &action, NULL);
  
  if(status_filename != 0) {
    status_file = fopen(status_filename, "w");
    if(!status_file) error("Could not open/create status-file");
    if(autostart) {
      if(!motion_detection) {
        fprintf(status_file, "ready");
      }
      else fprintf(status_file, "md_ready");
    }
    else fprintf(status_file, "halted");
    fclose(status_file);
  }
  
  while(running) {
    if(pipe_filename != 0) {

      fd = open(pipe_filename, O_RDONLY | O_NONBLOCK);
      if(fd < 0) error("Could not open PIPE");
      fcntl(fd, F_SETFL, 0);
      length = read(fd, readbuf, 20);
      close(fd);

      if(length) {
        if((readbuf[0]=='p') && (readbuf[1]=='m')) {
          stop_all();
          readbuf[0] = ' ';
          readbuf[1] = ' ';
          readbuf[length] = 0;
          if(strcmp(readbuf, "   4_3") == 0) preview_mode = RES_4_3;
          else if(strcmp(readbuf, "   16_9_STD") == 0) preview_mode = RES_16_9_STD;
          else if(strcmp(readbuf, "   16_9_WIDE") == 0) preview_mode = RES_16_9_WIDE;
          start_all();
          printf("Changed preview mode\n");
          if(status_filename != 0) {
            status_file = fopen(status_filename, "w");
            fprintf(status_file, "ready");
            fclose(status_file);
          }
        }
        else if((readbuf[0]=='c') && (readbuf[1]=='a')) {
          if(readbuf[3]=='1') {
            if(!capturing) {
              status = mmal_component_enable(h264encoder);
              if(status != MMAL_SUCCESS) error("Could not enable h264encoder");
              pool_h264encoder = mmal_port_pool_create(h264encoder->output[0], h264encoder->output[0]->buffer_num, h264encoder->output[0]->buffer_size);
              if(!pool_h264encoder) error("Could not create pool");
              status = mmal_connection_create(&con_cam_h264, camera->output[1], h264encoder->input[0], MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT);
              if(status != MMAL_SUCCESS) error("Could not create connecton camera -> video converter");
              status = mmal_connection_enable(con_cam_h264);
              if(status != MMAL_SUCCESS) error("Could not enable connection camera -> video converter");
              currTime = time(NULL);
              localTime = localtime (&currTime);
              if(mp4box) {
                asprintf(&filename_temp, h264_filename, video_cnt, localTime->tm_year+1900, localTime->tm_mon+1, localTime->tm_mday, localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
                asprintf(&filename_temp2, "%s.h264", filename_temp);
              }
              else {
                asprintf(&filename_temp2, h264_filename, video_cnt, localTime->tm_year+1900, localTime->tm_mon+1, localTime->tm_mday, localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
              }
              h264output_file = fopen(filename_temp2, "wb");
              free(filename_temp2);
              if(mp4box) { 
			if(audio_mode) {
				asprintf(&cmd_temp, "/usr/bin/arecord -q -D hw:1,0 -f S16_LE -t wav | /usr/bin/lame - %s.mp3 -S &", filename_temp);
				printf("Audio recording with \"%s\\n", cmd_temp);
                		if(system(cmd_temp) == -1) error("Could not start audio recording");
			}
			free(filename_temp);
	      }
              if(!h264output_file) error("Could not open/create video-file");
              status = mmal_port_enable(h264encoder->output[0], h264encoder_buffer_callback);
              if(status != MMAL_SUCCESS) error("Could not enable video port");
              max = mmal_queue_length(pool_h264encoder->queue);
              for(i=0;i<max;i++) {
                MMAL_BUFFER_HEADER_T *h264buffer = mmal_queue_get(pool_h264encoder->queue);
                if(!h264buffer) error("Could not create video pool header");
                status = mmal_port_send_buffer(h264encoder->output[0], h264buffer);
                if(status != MMAL_SUCCESS) error("Could not send buffers to video port");
              }
              mmal_port_parameter_set_boolean(camera->output[1], MMAL_PARAMETER_CAPTURE, 1);
              if(status != MMAL_SUCCESS) error("Could not start capture");
              printf("Capturing started\n");
              if(status_filename != 0) {
                status_file = fopen(status_filename, "w");
                if(!motion_detection) fprintf(status_file, "video");
                else fprintf(status_file, "md_video");
                fclose(status_file);
              }
              capturing = 1;
            }
          }
          else {
            if(capturing) {
              mmal_port_parameter_set_boolean(camera->output[1], MMAL_PARAMETER_CAPTURE, 0);
              if(status != MMAL_SUCCESS) error("Could not stop capture");
              status = mmal_port_disable(h264encoder->output[0]);
              if(status != MMAL_SUCCESS) error("Could not disable video port");
              status = mmal_connection_destroy(con_cam_h264);
              if(status != MMAL_SUCCESS) error("Could not destroy connection camera -> video encoder");
              mmal_port_pool_destroy(h264encoder->output[0], pool_h264encoder);
              if(status != MMAL_SUCCESS) error("Could not destroy video buffer pool");
              status = mmal_component_disable(h264encoder);
              if(status != MMAL_SUCCESS) error("Could not disable video converter");
              fclose(h264output_file);
              h264output_file = NULL;
              printf("Capturing stopped\n");
              if(mp4box) {
                printf("Boxing started\n");
                status_file = fopen(status_filename, "w");
                if(!motion_detection) fprintf(status_file, "boxing");
                else fprintf(status_file, "md_boxing");
                fclose(status_file);
                asprintf(&filename_temp, h264_filename, video_cnt, localTime->tm_year+1900, localTime->tm_mon+1, localTime->tm_mday, localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
		if(audio_mode) {
                	asprintf(&cmd_temp, "/usr/bin/killall arecord > /dev/null");
			if(system(cmd_temp) == -1) error("Could not stop audio recording");
			free(cmd_temp);
                	asprintf(&cmd_temp, "MP4Box -fps 25 -add %s.h264 -add %s.mp3 %s > /dev/null", filename_temp, filename_temp, filename_temp);
		} else {
			asprintf(&cmd_temp, "MP4Box -fps 25 -add %s.h264 %s > /dev/null", filename_temp, filename_temp);
		}
                if(system(cmd_temp) == -1) error("Could not start MP4Box");
                asprintf(&filename_temp2, "%s.h264", filename_temp);
                remove(filename_temp2);
                free(filename_temp2);
		if (audio_mode) {
                	asprintf(&filename_temp2, "%s.mp3", filename_temp);
                	remove(filename_temp2);
                	free(filename_temp2);
		}
                free(filename_temp);
                free(cmd_temp);
                printf("Boxing stopped\n");
              }
              video_cnt++;
              if(status_filename != 0) {
                status_file = fopen(status_filename, "w");
                if(!motion_detection) fprintf(status_file, "ready");
                else fprintf(status_file, "md_ready");
                fclose(status_file);
              }
              capturing = 0;
            }
          }
        }
        else if((readbuf[0]=='i') && (readbuf[1]=='m')) {
          capt_img();
        }
        else if((readbuf[0]=='t') && (readbuf[1]=='l')) {
          readbuf[0] = ' ';
          readbuf[1] = ' ';
          readbuf[length] = 0;
          time_between_pic = atoi(readbuf);
          if(time_between_pic) {
            if(status_filename != 0) {
              status_file = fopen(status_filename, "w");
              fprintf(status_file, "timelapse");
              fclose(status_file);
            }
            timelapse = 1;
            printf("Timelapse started\n");
          }
          else {
            if(status_filename != 0) {
              status_file = fopen(status_filename, "w");
              fprintf(status_file, "ready");
              fclose(status_file);
            }
            timelapse = 0;
            printf("Timelapse stopped\n");
          }
        }
        else if((readbuf[0]=='s') && (readbuf[1]=='h')) {
          readbuf[0] = ' ';
          readbuf[1] = ' ';
          readbuf[length] = 0;
          cam_setting = atoi(readbuf);
          MMAL_RATIONAL_T value = {cam_setting, 100};
          status = mmal_port_parameter_set_rational(camera->control, MMAL_PARAMETER_SHARPNESS, value);
          if(status != MMAL_SUCCESS) error("Could not set sharpness");
          printf("Sharpness: %d\n", cam_setting);
        }
        else if((readbuf[0]=='c') && (readbuf[1]=='o')) {
          readbuf[0] = ' ';
          readbuf[1] = ' ';
          readbuf[length] = 0;
          cam_setting = atoi(readbuf);
          MMAL_RATIONAL_T value = {cam_setting, 100};
          status = mmal_port_parameter_set_rational(camera->control, MMAL_PARAMETER_CONTRAST, value);
          if(status != MMAL_SUCCESS) error("Could not set contrast");
          printf("Contrast: %d\n", cam_setting);
        }
        else if((readbuf[0]=='b') && (readbuf[1]=='r')) {
          readbuf[0] = ' ';
          readbuf[1] = ' ';
          readbuf[length] = 0;
          cam_setting = atoi(readbuf);
          MMAL_RATIONAL_T value = {cam_setting, 100};
          status = mmal_port_parameter_set_rational(camera->control, MMAL_PARAMETER_BRIGHTNESS, value);
          if(status != MMAL_SUCCESS) error("Could not set brightness");
          printf("Brightness: %d\n", cam_setting);
        }
        else if((readbuf[0]=='s') && (readbuf[1]=='a')) {
          readbuf[0] = ' ';
          readbuf[1] = ' ';
          readbuf[length] = 0;
          cam_setting = atoi(readbuf);
          MMAL_RATIONAL_T value = {cam_setting, 100};
          status = mmal_port_parameter_set_rational(camera->control, MMAL_PARAMETER_SATURATION, value);
          if(status != MMAL_SUCCESS) error("Could not set saturation");
          printf("Saturation: %d\n", cam_setting);
        }
        else if((readbuf[0]=='i') && (readbuf[1]=='s')) {
          readbuf[0] = ' ';
          readbuf[1] = ' ';
          readbuf[length] = 0;
          cam_setting = atoi(readbuf);
          status = mmal_port_parameter_set_uint32(camera->control, MMAL_PARAMETER_ISO, cam_setting);
          if(status != MMAL_SUCCESS) error("Could not set ISO");
          printf("ISO: %d\n", cam_setting);
        }
        else if((readbuf[0]=='v') && (readbuf[1]=='s')) {
          if(readbuf[3]=='1') {
            status = mmal_port_parameter_set_boolean(camera->control, MMAL_PARAMETER_VIDEO_STABILISATION, 1);
            printf("Video Stabilisation ON\n");
          }
          else {
            status = mmal_port_parameter_set_boolean(camera->control, MMAL_PARAMETER_VIDEO_STABILISATION, 0);
            printf("Video Stabilisation OFF\n");
          }
          if(status != MMAL_SUCCESS) error("Could not set video stabilisation");
        }
        else if((readbuf[0]=='e') && (readbuf[1]=='c')) {
          readbuf[0] = ' ';
          readbuf[1] = ' ';
          readbuf[length] = 0;
          cam_setting = atoi(readbuf);
          status = mmal_port_parameter_set_int32(camera->control, MMAL_PARAMETER_EXPOSURE_COMP, cam_setting);
          if(status != MMAL_SUCCESS) error("Could not set exposure compensation");
          printf("Exposure Compensation: %d\n", cam_setting);
        }
        else if((readbuf[0]=='e') && (readbuf[1]=='m')) {
          readbuf[0] = ' ';
          readbuf[1] = ' ';
          readbuf[length] = 0;
          MMAL_PARAM_EXPOSUREMODE_T mode = MMAL_PARAM_EXPOSUREMODE_OFF;
          if(strcmp(readbuf, "   auto") == 0) mode = MMAL_PARAM_EXPOSUREMODE_AUTO;
          else if(strcmp(readbuf, "   night") == 0) mode = MMAL_PARAM_EXPOSUREMODE_NIGHT;
          else if(strcmp(readbuf, "   nightpreview") == 0) mode = MMAL_PARAM_EXPOSUREMODE_NIGHTPREVIEW;
          else if(strcmp(readbuf, "   backlight") == 0) mode = MMAL_PARAM_EXPOSUREMODE_BACKLIGHT;
          else if(strcmp(readbuf, "   spotlight") == 0) mode = MMAL_PARAM_EXPOSUREMODE_SPOTLIGHT;
          else if(strcmp(readbuf, "   sports") == 0) mode = MMAL_PARAM_EXPOSUREMODE_SPORTS;
          else if(strcmp(readbuf, "   snow") == 0) mode = MMAL_PARAM_EXPOSUREMODE_SNOW;
          else if(strcmp(readbuf, "   beach") == 0) mode = MMAL_PARAM_EXPOSUREMODE_BEACH;
          else if(strcmp(readbuf, "   verylong") == 0) mode = MMAL_PARAM_EXPOSUREMODE_VERYLONG;
          else if(strcmp(readbuf, "   fixedfps") == 0) mode = MMAL_PARAM_EXPOSUREMODE_FIXEDFPS;
          else if(strcmp(readbuf, "   antishake") == 0) mode = MMAL_PARAM_EXPOSUREMODE_ANTISHAKE;
          else if(strcmp(readbuf, "   fireworks") == 0) mode = MMAL_PARAM_EXPOSUREMODE_FIREWORKS;
          MMAL_PARAMETER_EXPOSUREMODE_T exp_mode = {{MMAL_PARAMETER_EXPOSURE_MODE,sizeof(exp_mode)}, mode};
          status = mmal_port_parameter_set(camera->control, &exp_mode.hdr);
          if(status != MMAL_SUCCESS) error("Could not set exposure mode");
          printf("Exposure mode changed\n");
        }
        else if((readbuf[0]=='w') && (readbuf[1]=='b')) {
          readbuf[0] = ' ';
          readbuf[1] = ' ';
          readbuf[length] = 0;
          MMAL_PARAM_AWBMODE_T awb_mode = MMAL_PARAM_AWBMODE_OFF;
          if(strcmp(readbuf, "   auto") == 0) awb_mode = MMAL_PARAM_AWBMODE_AUTO;
          else if(strcmp(readbuf, "   auto") == 0) awb_mode = MMAL_PARAM_AWBMODE_AUTO;
          else if(strcmp(readbuf, "   sun") == 0) awb_mode = MMAL_PARAM_AWBMODE_SUNLIGHT;
          else if(strcmp(readbuf, "   cloudy") == 0) awb_mode = MMAL_PARAM_AWBMODE_CLOUDY;
          else if(strcmp(readbuf, "   shade") == 0) awb_mode = MMAL_PARAM_AWBMODE_SHADE;
          else if(strcmp(readbuf, "   tungsten") == 0) awb_mode = MMAL_PARAM_AWBMODE_TUNGSTEN;
          else if(strcmp(readbuf, "   fluorescent") == 0) awb_mode = MMAL_PARAM_AWBMODE_FLUORESCENT;
          else if(strcmp(readbuf, "   incandescent") == 0) awb_mode = MMAL_PARAM_AWBMODE_INCANDESCENT;
          else if(strcmp(readbuf, "   flash") == 0) awb_mode = MMAL_PARAM_AWBMODE_FLASH;
          else if(strcmp(readbuf, "   horizon") == 0) awb_mode = MMAL_PARAM_AWBMODE_HORIZON;
          MMAL_PARAMETER_AWBMODE_T param = {{MMAL_PARAMETER_AWB_MODE,sizeof(param)}, awb_mode};
          status = mmal_port_parameter_set(camera->control, &param.hdr);
          if(status != MMAL_SUCCESS) error("Could not set white balance");
          printf("White balance changed\n");
        }
        else if((readbuf[0]=='r') && (readbuf[1]=='o')) {
          readbuf[0] = ' ';
          readbuf[1] = ' ';
          readbuf[length] = 0;
          cam_setting = atoi(readbuf);
          status = mmal_port_parameter_set_int32(camera->output[0], MMAL_PARAMETER_ROTATION, cam_setting);
          if(status != MMAL_SUCCESS) error("Could not set rotation (0)");
          status = mmal_port_parameter_set_int32(camera->output[1], MMAL_PARAMETER_ROTATION, cam_setting);
          if(status != MMAL_SUCCESS) error("Could not set rotation (1)");
          status = mmal_port_parameter_set_int32(camera->output[2], MMAL_PARAMETER_ROTATION, cam_setting);
          if(status != MMAL_SUCCESS) error("Could not set rotation (2)");
          printf("Rotation: %d\n", cam_setting);
        }
        else if((readbuf[0]=='q') && (readbuf[1]=='u')) {
          readbuf[0] = ' ';
          readbuf[1] = ' ';
          readbuf[length] = 0;
          cam_setting = atoi(readbuf);
          status = mmal_port_parameter_set_uint32(jpegencoder2->output[0], MMAL_PARAMETER_JPEG_Q_FACTOR, cam_setting);
          if(status != MMAL_SUCCESS) error("Could not set quality");
          printf("Quality: %d\n", cam_setting);
        }
        else if((readbuf[0]=='b') && (readbuf[1]=='i')) {
          readbuf[0] = ' ';
          readbuf[1] = ' ';
          readbuf[length] = 0;
          cam_setting_long = strtoull(readbuf, NULL, 0);
          h264encoder->output[0]->format->bitrate = cam_setting_long;
          status = mmal_port_format_commit(h264encoder->output[0]);
          if(status != MMAL_SUCCESS) error("Could not set bitrate");
          printf("Bitrate: %lu\n", cam_setting_long);
        }
        else if((readbuf[0]=='r') && (readbuf[1]=='u')) {
          if(readbuf[3]=='0') {
            stop_all();
            idle = 1;
            printf("Stream halted\n");
            if(status_filename != 0) {
              status_file = fopen(status_filename, "w");
              fprintf(status_file, "halted");
              fclose(status_file);
            }
          }
          else {
            start_all();
            idle = 0;
            printf("Stream continued\n");
            if(status_filename != 0) {
              status_file = fopen(status_filename, "w");
              fprintf(status_file, "ready");
              fclose(status_file);
            }
          }
        }
        else if((readbuf[0]=='m') && (readbuf[1]=='d')) {
          if(readbuf[3]=='0') {
            motion_detection = 0;
            if(system("killall motion") == -1) error("Could not stop Motion");
            printf("Motion detection stopped\n");
            if(status_filename != 0) {
              status_file = fopen(status_filename, "w");
              fprintf(status_file, "ready");
              fclose(status_file);
            }
          }
          else {
            motion_detection = 1;
            if(system("motion") == -1) error("Could not start Motion");
            printf("Motion detection started\n");
            if(status_filename != 0) {
              status_file = fopen(status_filename, "w");
              fprintf(status_file, "md_ready");
              fclose(status_file);
            }
          }
        }
      }

    }
    if(timelapse) {
      tl_cnt++;
      if(tl_cnt >= time_between_pic) {
        if(capturing == 0) {
          capt_img();
          tl_cnt = 0;
        }
      }
    }
    usleep(100000);
  }
  
  printf("SIGINT/SIGTERM received, stopping\n");
  
  //
  // tidy up
  //
  if(!idle) stop_all();

  return 0;

}
示例#12
0
文件: RaspiMJPEG.c 项目: jrv/userland
void start_all (void) {

  MMAL_STATUS_T status;
  MMAL_ES_FORMAT_T *format;
  int max, i;
  unsigned int video_width, video_height;
  
  //
  // get resolution
  //
  if(preview_mode == RES_16_9_STD) {
    video_width = 1920;
    video_height = 1080;
  }
  else if(preview_mode == RES_16_9_WIDE) {
    video_width = 1296;
    video_height = 730;
  }
  else {
    video_width = 1296;
    video_height = 976;
  }
  
  //
  // create camera
  //
  status = mmal_component_create(MMAL_COMPONENT_DEFAULT_CAMERA, &camera);
  if(status != MMAL_SUCCESS) error("Could not create camera");
  status = mmal_port_enable(camera->control, camera_control_callback);
  if(status != MMAL_SUCCESS) error("Could not enable camera control port");

  MMAL_PARAMETER_CAMERA_CONFIG_T cam_config = {
    {MMAL_PARAMETER_CAMERA_CONFIG, sizeof(cam_config)},
    .max_stills_w = 2592,
    .max_stills_h = 1944,
    .stills_yuv422 = 0,
    .one_shot_stills = 1,
    .max_preview_video_w = video_width,
    .max_preview_video_h = video_height,
    .num_preview_video_frames = 3,
    .stills_capture_circular_buffer_height = 0,
    .fast_preview_resume = 0,
    .use_stc_timestamp = MMAL_PARAM_TIMESTAMP_MODE_RESET_STC
  };
  mmal_port_parameter_set(camera->control, &cam_config.hdr);
  
  format = camera->output[0]->format;
  format->es->video.width = video_width;
  format->es->video.height = video_height;
  format->es->video.crop.x = 0;
  format->es->video.crop.y = 0;
  format->es->video.crop.width = video_width;
  format->es->video.crop.height = video_height;
  format->es->video.frame_rate.num = 0;
  format->es->video.frame_rate.den = 1;
  status = mmal_port_format_commit(camera->output[0]);
  if(status != MMAL_SUCCESS) error("Coult not set preview format");

  format = camera->output[1]->format;
  format->encoding_variant = MMAL_ENCODING_I420;
  format->encoding = MMAL_ENCODING_OPAQUE;
  format->es->video.width = video_width;
  format->es->video.height = video_height;
  format->es->video.crop.x = 0;
  format->es->video.crop.y = 0;
  format->es->video.crop.width = video_width;
  format->es->video.crop.height = video_height;
  format->es->video.frame_rate.num = 25;
  format->es->video.frame_rate.den = 1;
  status = mmal_port_format_commit(camera->output[1]);
  if(status != MMAL_SUCCESS) error("Could not set video format");
  if(camera->output[1]->buffer_num < 3)
    camera->output[1]->buffer_num = 3;
  
  format = camera->output[2]->format;
  format->encoding = MMAL_ENCODING_OPAQUE;
  format->es->video.width = 2592;
  format->es->video.height = 1944;
  format->es->video.crop.x = 0;
  format->es->video.crop.y = 0;
  format->es->video.crop.width = 2592;
  format->es->video.crop.height = 1944;
  format->es->video.frame_rate.num = 0;
  format->es->video.frame_rate.den = 1;
  status = mmal_port_format_commit(camera->output[2]);
  if(status != MMAL_SUCCESS) error("Could not set still format");
  if(camera->output[2]->buffer_num < 3)
    camera->output[2]->buffer_num = 3;

  status = mmal_component_enable(camera);
  if(status != MMAL_SUCCESS) error("Could not enable camera");

  //
  // create jpeg-encoder
  //
  status = mmal_component_create(MMAL_COMPONENT_DEFAULT_IMAGE_ENCODER, &jpegencoder);
  if(status != MMAL_SUCCESS && status != MMAL_ENOSYS) error("Could not create image encoder");

  mmal_format_copy(jpegencoder->output[0]->format, jpegencoder->input[0]->format);
  jpegencoder->output[0]->format->encoding = MMAL_ENCODING_JPEG;
  jpegencoder->output[0]->buffer_size = jpegencoder->output[0]->buffer_size_recommended;
  if(jpegencoder->output[0]->buffer_size < jpegencoder->output[0]->buffer_size_min)
    jpegencoder->output[0]->buffer_size = jpegencoder->output[0]->buffer_size_min;
  jpegencoder->output[0]->buffer_num = jpegencoder->output[0]->buffer_num_recommended;
  if(jpegencoder->output[0]->buffer_num < jpegencoder->output[0]->buffer_num_min)
    jpegencoder->output[0]->buffer_num = jpegencoder->output[0]->buffer_num_min;
  status = mmal_port_format_commit(jpegencoder->output[0]);
  if(status != MMAL_SUCCESS) error("Could not set image format");
  status = mmal_port_parameter_set_uint32(jpegencoder->output[0], MMAL_PARAMETER_JPEG_Q_FACTOR, quality);
  if(status != MMAL_SUCCESS) error("Could not set jpeg quality");

  status = mmal_component_enable(jpegencoder);
  if(status != MMAL_SUCCESS) error("Could not enable image encoder");
  pool_jpegencoder = mmal_port_pool_create(jpegencoder->output[0], jpegencoder->output[0]->buffer_num, jpegencoder->output[0]->buffer_size);
  if(!pool_jpegencoder) error("Could not create image buffer pool");

  //
  // create second jpeg-encoder
  //
  status = mmal_component_create(MMAL_COMPONENT_DEFAULT_IMAGE_ENCODER, &jpegencoder2);
  if(status != MMAL_SUCCESS && status != MMAL_ENOSYS) error("Could not create image encoder 2");

  mmal_format_copy(jpegencoder2->output[0]->format, jpegencoder2->input[0]->format);
  jpegencoder2->output[0]->format->encoding = MMAL_ENCODING_JPEG;
  jpegencoder2->output[0]->buffer_size = jpegencoder2->output[0]->buffer_size_recommended;
  if(jpegencoder2->output[0]->buffer_size < jpegencoder2->output[0]->buffer_size_min)
    jpegencoder2->output[0]->buffer_size = jpegencoder2->output[0]->buffer_size_min;
  jpegencoder2->output[0]->buffer_num = jpegencoder2->output[0]->buffer_num_recommended;
  if(jpegencoder2->output[0]->buffer_num < jpegencoder2->output[0]->buffer_num_min)
    jpegencoder2->output[0]->buffer_num = jpegencoder2->output[0]->buffer_num_min;
  status = mmal_port_format_commit(jpegencoder2->output[0]);
  if(status != MMAL_SUCCESS) error("Could not set image format 2");
  status = mmal_port_parameter_set_uint32(jpegencoder2->output[0], MMAL_PARAMETER_JPEG_Q_FACTOR, 85);
  if(status != MMAL_SUCCESS) error("Could not set jpeg quality 2");

  status = mmal_component_enable(jpegencoder2);
  if(status != MMAL_SUCCESS) error("Could not enable image encoder 2");
  pool_jpegencoder2 = mmal_port_pool_create(jpegencoder2->output[0], jpegencoder2->output[0]->buffer_num, jpegencoder2->output[0]->buffer_size);
  if(!pool_jpegencoder2) error("Could not create image buffer pool 2");

  //
  // create h264-encoder
  //
  status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_ENCODER, &h264encoder);
  if(status != MMAL_SUCCESS && status != MMAL_ENOSYS) error("Could not create video encoder");

  mmal_format_copy(h264encoder->output[0]->format, h264encoder->input[0]->format);
  h264encoder->output[0]->format->encoding = MMAL_ENCODING_H264;
  h264encoder->output[0]->format->bitrate = 17000000;
  h264encoder->output[0]->buffer_size = h264encoder->output[0]->buffer_size_recommended;
  if(h264encoder->output[0]->buffer_size < h264encoder->output[0]->buffer_size_min)
    h264encoder->output[0]->buffer_size = h264encoder->output[0]->buffer_size_min;
  h264encoder->output[0]->buffer_num = h264encoder->output[0]->buffer_num_recommended;
  if(h264encoder->output[0]->buffer_num < h264encoder->output[0]->buffer_num_min)
    h264encoder->output[0]->buffer_num = h264encoder->output[0]->buffer_num_min;
  h264encoder->output[0]->format->es->video.frame_rate.num = 0;
  h264encoder->output[0]->format->es->video.frame_rate.den = 1;
  status = mmal_port_format_commit(h264encoder->output[0]);
  if(status != MMAL_SUCCESS) error("Could not set video format");

  MMAL_PARAMETER_UINT32_T param2 = {{ MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT, sizeof(param2)}, 25};
  status = mmal_port_parameter_set(h264encoder->output[0], &param2.hdr);
  if(status != MMAL_SUCCESS) error("Could not set video quantisation");

  MMAL_PARAMETER_UINT32_T param3 = {{ MMAL_PARAMETER_VIDEO_ENCODE_QP_P, sizeof(param3)}, 31};
  status = mmal_port_parameter_set(h264encoder->output[0], &param3.hdr);
  if(status != MMAL_SUCCESS) error("Could not set video quantisation");

  MMAL_PARAMETER_VIDEO_PROFILE_T param4;
  param4.hdr.id = MMAL_PARAMETER_PROFILE;
  param4.hdr.size = sizeof(param4);
  param4.profile[0].profile = MMAL_VIDEO_PROFILE_H264_HIGH;
  param4.profile[0].level = MMAL_VIDEO_LEVEL_H264_4;
  status = mmal_port_parameter_set(h264encoder->output[0], &param4.hdr);
  if(status != MMAL_SUCCESS) error("Could not set video port format");

  status = mmal_port_parameter_set_boolean(h264encoder->input[0], MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, 1);
  if(status != MMAL_SUCCESS) error("Could not set immutable flag");

  status = mmal_port_parameter_set_boolean(h264encoder->output[0], MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER, 0);
  if(status != MMAL_SUCCESS) error("Could not set inline flag");

  //
  // create image-resizer
  //
  status = mmal_component_create("vc.ril.resize", &resizer);
  if(status != MMAL_SUCCESS && status != MMAL_ENOSYS) error("Could not create image resizer");
  
  format = resizer->output[0]->format;
  format->es->video.width = (preview_mode==RES_4_3) ? width_pic : width;
  format->es->video.height = (preview_mode==RES_4_3) ? height_pic : height;
  format->es->video.crop.x = 0;
  format->es->video.crop.y = 0;
  format->es->video.crop.width = (preview_mode==RES_4_3) ? width_pic : width;
  format->es->video.crop.height = (preview_mode==RES_4_3) ? height_pic : height;
  format->es->video.frame_rate.num = 30;
  format->es->video.frame_rate.den = 1;
  status = mmal_port_format_commit(resizer->output[0]);
  if(status != MMAL_SUCCESS) error("Could not set image resizer output");
  
  status = mmal_component_enable(resizer);
  if(status != MMAL_SUCCESS) error("Could not enable image resizer");

  //
  // connect
  //
  status = mmal_connection_create(&con_cam_res, camera->output[0], resizer->input[0], MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT);
  if(status != MMAL_SUCCESS) error("Could not create connection camera -> resizer");
  status = mmal_connection_enable(con_cam_res);
  if(status != MMAL_SUCCESS) error("Could not enable connection camera -> resizer");
  
  status = mmal_connection_create(&con_res_jpeg, resizer->output[0], jpegencoder->input[0], MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT);
  if(status != MMAL_SUCCESS) error("Could not create connection resizer -> encoder");
  status = mmal_connection_enable(con_res_jpeg);
  if(status != MMAL_SUCCESS) error("Could not enable connection resizer -> encoder");

  status = mmal_port_enable(jpegencoder->output[0], jpegencoder_buffer_callback);
  if(status != MMAL_SUCCESS) error("Could not enable jpeg port");
  max = mmal_queue_length(pool_jpegencoder->queue);
  for(i=0;i<max;i++) {
    MMAL_BUFFER_HEADER_T *jpegbuffer = mmal_queue_get(pool_jpegencoder->queue);

    if(!jpegbuffer) error("Could not create jpeg buffer header");
    status = mmal_port_send_buffer(jpegencoder->output[0], jpegbuffer);
    if(status != MMAL_SUCCESS) error("Could not send buffers to jpeg port");
  }

  status = mmal_connection_create(&con_cam_jpeg, camera->output[2], jpegencoder2->input[0], MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT);
  if(status != MMAL_SUCCESS) error("Could not create connection camera -> encoder");
  status = mmal_connection_enable(con_cam_jpeg);
  if(status != MMAL_SUCCESS) error("Could not enable connection camera -> encoder");
  
  status = mmal_port_enable(jpegencoder2->output[0], jpegencoder2_buffer_callback);
  if(status != MMAL_SUCCESS) error("Could not enable jpeg port 2");
  max = mmal_queue_length(pool_jpegencoder2->queue);
  for(i=0;i<max;i++) {
    MMAL_BUFFER_HEADER_T *jpegbuffer2 = mmal_queue_get(pool_jpegencoder2->queue);

    if(!jpegbuffer2) error("Could not create jpeg buffer header 2");
    status = mmal_port_send_buffer(jpegencoder2->output[0], jpegbuffer2);
    if(status != MMAL_SUCCESS) error("Could not send buffers to jpeg port 2");
  }

}
示例#13
0
/** Create an instance of a component  */
static MMAL_STATUS_T mmal_component_create_aggregator_pipeline(const char *full_name,
   const char *component_names, MMAL_COMPONENT_T *component)
{
   MMAL_GRAPH_T *graph = 0;
   MMAL_COMPONENT_T *subcomponent[2] = {0};
   MMAL_STATUS_T status = MMAL_ENOMEM;
   unsigned int length;
   char *orig, *names;

   length = strlen(component_names);
   names = orig = vcos_calloc(1, length + 1, "mmal aggregator");
   if (!names)
      goto error;
   memcpy(names, component_names, length);

   /* We'll build the aggregator using a graph */
   status = mmal_graph_create(&graph, sizeof(MMAL_GRAPH_USERDATA_T));
   if (status != MMAL_SUCCESS)
      goto error;
   graph->pf_parameter_get = aggregator_parameter_get;
   graph->pf_parameter_set = aggregator_parameter_set;

   /* Iterate through all the specified components */
   while (*names)
   {
      MMAL_CONNECTION_T *connection;
      const char *name;

      /* Switch to a new connection */
      if (subcomponent[0])
         mmal_component_destroy(subcomponent[0]);
      subcomponent[0] = subcomponent[1];
      subcomponent[1] = 0;

      /* Extract the name of the next component */
      for (name = names; *names && *names != ':'; names++);

      /* Replace the separator */
      if (*names)
         *(names++) = 0;

      /* Skip empty strings */
      if (!*name)
         continue;

      status = mmal_component_create(name, &subcomponent[1]);
      if (status != MMAL_SUCCESS)
         goto error;

      status = mmal_graph_add_component(graph, subcomponent[1]);
      if (status != MMAL_SUCCESS)
         goto error;

      /* Special case for dealing with the first component in the chain */
      if (!subcomponent[0])
      {
         /* Add first input port if any */
         if (subcomponent[1]->input_num)
         {
            status = mmal_graph_add_port(graph, subcomponent[1]->input[0]);
            if (status != MMAL_SUCCESS)
               goto error;
         }
         continue;
      }

      /* Create connection between the 2 ports */
      if (subcomponent[0]->output_num < 1 || subcomponent[1]->input_num < 1)
         goto error;
      status = mmal_connection_create(&connection, subcomponent[0]->output[0],
         subcomponent[1]->input[0], 0);
      if (status != MMAL_SUCCESS)
         goto error;

      status = mmal_graph_add_connection(graph, connection);
      /* Now the connection is added to the graph we don't care about it anymore */
      mmal_connection_destroy(connection);
      if (status != MMAL_SUCCESS)
         goto error;
   }

   /* Add last output port if any */
   if (subcomponent[1] && subcomponent[1]->output_num && subcomponent[1]->output[0])
   {
      status = mmal_graph_add_port(graph, subcomponent[1]->output[0]);
      if (status != MMAL_SUCCESS)
         goto error;
   }

   /* Build the graph */
   component->priv->module = (struct MMAL_COMPONENT_MODULE_T *)graph;
   status = mmal_graph_component_constructor(full_name, component);
   if (status != MMAL_SUCCESS)
      goto error;

 end:
   if (subcomponent[0])
      mmal_component_destroy(subcomponent[0]);
   if (subcomponent[1])
      mmal_component_destroy(subcomponent[1]);
   vcos_free(orig);
   return status;

 error:
   if (graph)
      mmal_graph_destroy(graph);
   goto end;
}
示例#14
0
bool CCamera::Init(int width, int height, int framerate, int num_levels, bool do_argb_conversion)
{
	//init broadcom host - QUESTION: can this be called more than once??
	bcm_host_init();

	//store basic parameters
	Width = width;       
	Height = height;
	FrameRate = framerate;

	// Set up the camera_parameters to default
	raspicamcontrol_set_defaults(&CameraParameters);

	MMAL_COMPONENT_T *camera = 0;
	MMAL_COMPONENT_T *splitter = 0;
	MMAL_CONNECTION_T* vid_to_split_connection = 0;
	MMAL_PORT_T *video_port = NULL;
	MMAL_STATUS_T status;
	CCameraOutput* outputs[4]; memset(outputs,0,sizeof(outputs));

	//create the camera component
	camera = CreateCameraComponentAndSetupPorts();
	if (!camera)
		goto error;

	//get the video port
	video_port = camera->output[MMAL_CAMERA_VIDEO_PORT];
	video_port->buffer_num = 3;

	//create the splitter component
	splitter = CreateSplitterComponentAndSetupPorts(video_port);
	if(!splitter)
		goto error;

	//create and enable a connection between the video output and the resizer input
	status = mmal_connection_create(&vid_to_split_connection, video_port, splitter->input[0], MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT);
	if (status != MMAL_SUCCESS)
	{
		printf("Failed to create connection\n");
		goto error;
	}
	status = mmal_connection_enable(vid_to_split_connection);
	if (status != MMAL_SUCCESS)
	{
		printf("Failed to enable connection\n");
		goto error;
	}

	//setup all the outputs
	for(int i = 0; i < num_levels; i++)
	{
		outputs[i] = new CCameraOutput();
		if(!outputs[i]->Init(Width >> i,Height >> i,splitter,i,do_argb_conversion))
		{
			printf("Failed to initialize output %d\n",i);
			goto error;
		}
	}

	//begin capture
	if (mmal_port_parameter_set_boolean(video_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS)
	{
		printf("Failed to start capture\n");
		goto error;
	}

	//store created info
	CameraComponent = camera;
	SplitterComponent = splitter;
	VidToSplitConn = vid_to_split_connection;
	memcpy(Outputs,outputs,sizeof(outputs));
  
  //custom parameters
  raspicamcontrol_set_saturation(camera, 0);
  raspicamcontrol_set_contrast(camera, 100);
  raspicamcontrol_set_brightness(camera, 50);
  //raspicamcontrol_set_exposure_mode(camera, MMAL_PARAM_EXPOSUREMODE_OFF);
  //raspicamcontrol_set_awb_mode(camera, MMAL_PARAM_AWBMODE_OFF);
  raspicamcontrol_set_shutter_speed(camera, 2400);
  
  

	//return success
	printf("Camera successfully created\n");
	return true;

error:
	if(vid_to_split_connection)
		mmal_connection_destroy(vid_to_split_connection);
	if(camera)
		mmal_component_destroy(camera);
	if(splitter)
		mmal_component_destroy(splitter);
	for(int i = 0; i < 4; i++)
	{
		if(outputs[i])
		{
			outputs[i]->Release();
			delete outputs[i];
		}
	}
	return false;
}
示例#15
0
int main(int argc, char** argv) {
    MMAL_COMPONENT_T *camera = 0;
    MMAL_COMPONENT_T *preview = 0;
    MMAL_ES_FORMAT_T *format;
    MMAL_STATUS_T status;
    MMAL_PORT_T *camera_preview_port = NULL, *camera_video_port = NULL, *camera_still_port = NULL;
    MMAL_PORT_T *preview_input_port = NULL;

    MMAL_CONNECTION_T *camera_preview_connection = 0;

    printf("Running...\n");


    bcm_host_init();

    status = mmal_component_create(MMAL_COMPONENT_DEFAULT_CAMERA, &camera);
    if (status != MMAL_SUCCESS) {
        printf("Error: create camera %x\n", status);
        return -1;
    }

    camera_preview_port = camera->output[MMAL_CAMERA_PREVIEW_PORT];
    camera_video_port = camera->output[MMAL_CAMERA_VIDEO_PORT];
    camera_still_port = camera->output[MMAL_CAMERA_CAPTURE_PORT];

    {
        MMAL_PARAMETER_CAMERA_CONFIG_T cam_config = {
            { MMAL_PARAMETER_CAMERA_CONFIG, sizeof (cam_config)},
            .max_stills_w = 1280,
            .max_stills_h = 720,
            .stills_yuv422 = 0,
            .one_shot_stills = 1,
            .max_preview_video_w = 1280,
            .max_preview_video_h = 720,
            .num_preview_video_frames = 3,
            .stills_capture_circular_buffer_height = 0,
            .fast_preview_resume = 0,
            .use_stc_timestamp = MMAL_PARAM_TIMESTAMP_MODE_RESET_STC
        };
        mmal_port_parameter_set(camera->control, &cam_config.hdr);
    }

    format = camera_preview_port->format;

    format->encoding = MMAL_ENCODING_OPAQUE;
    format->encoding_variant = MMAL_ENCODING_I420;

    format->es->video.width = 1280;
    format->es->video.height = 720;
    format->es->video.crop.x = 0;
    format->es->video.crop.y = 0;
    format->es->video.crop.width = 1280;
    format->es->video.crop.height = 720;

    status = mmal_port_format_commit(camera_preview_port);

    if (status != MMAL_SUCCESS) {
        printf("Error: camera viewfinder format couldn't be set\n");
        return -1;
    }

    status = mmal_component_enable(camera);

    status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &preview);
    if (status != MMAL_SUCCESS) {
        printf("Error: unable to create preview (%u)\n", status);
        return -1;
    }
    preview_input_port = preview->input[0];

    {
        MMAL_DISPLAYREGION_T param;
        param.hdr.id = MMAL_PARAMETER_DISPLAYREGION;
        param.hdr.size = sizeof (MMAL_DISPLAYREGION_T);
        param.set = MMAL_DISPLAY_SET_LAYER;
        param.layer = 0;
        param.set |= MMAL_DISPLAY_SET_FULLSCREEN;
        param.fullscreen = 1;
        status = mmal_port_parameter_set(preview_input_port, &param.hdr);
        if (status != MMAL_SUCCESS && status != MMAL_ENOSYS) {
            printf("Error: unable to set preview port parameters (%u)\n", status);
            return -1;
        }
    }

    status = mmal_connection_create(&camera_preview_connection, camera_preview_port, preview_input_port, MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT);
    if (status != MMAL_SUCCESS) {
        printf("Error: unable to create connection (%u)\n", status);
        return -1;
    }

    status = mmal_connection_enable(camera_preview_connection);
    if (status != MMAL_SUCCESS) {
        printf("Error: unable to enable connection (%u)\n", status);
        return -1;
    }
    
    while (1);

    return 0;
}