int Private_Impl_Still::startCapture() {
            // If the parameters were changed and this function wasn't called, it will be called here
            // However if the parameters weren't changed, the function won't do anything - it will return right away
            commitParameters();

            if ( encoder_output_port->is_enabled ) {
                cout << API_NAME << ": Could not enable encoder output port. Try waiting longer before attempting to take another picture.\n";
                return -1;
            }
            if ( mmal_port_enable ( encoder_output_port, buffer_callback ) != MMAL_SUCCESS ) {
                cout << API_NAME << ": Could not enable encoder output port.\n";
                return -1;
            }
            int num = mmal_queue_length ( encoder_pool->queue );
            for ( int b = 0; b < num; b++ ) {
                MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get ( encoder_pool->queue );

                if ( !buffer )
                    cout << API_NAME << ": Could not get buffer (#" << b << ") from pool queue.\n";

                if ( mmal_port_send_buffer ( encoder_output_port, buffer ) != MMAL_SUCCESS )
                    cout << API_NAME << ": Could not send a buffer (#" << b << ") to encoder output port.\n";
            }
            if ( mmal_port_parameter_set_boolean ( camera_still_port, MMAL_PARAMETER_CAPTURE, 1 ) != MMAL_SUCCESS ) {
                cout << API_NAME << ": Failed to start capture.\n";
                return -1;
            }
            return 0;
        }
/**After setting parameters video port is initialized with empty buffers
 */
bool Private_Impl::startCapture() {

    if ( !_isOpened ) {
        cerr << __FILE__ << ":" << __LINE__ << ":" << __func__ << " not opened." << endl;
        return false; //already opened
    }
    // start capture
    if ( mmal_port_parameter_set_boolean ( camera_video_port, MMAL_PARAMETER_CAPTURE, 1 ) != MMAL_SUCCESS ) {
        release();
        return false;
    }


    // Send all the buffers to the video port
    int num = mmal_queue_length ( State.video_pool->queue );

    int q;
    for ( q = 0; q < num; q++ ) {
        MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get ( State.video_pool->queue );
        if ( !buffer )
            cerr << "Unable to get a required buffer" << q << " from pool queue" << endl;

        if ( mmal_port_send_buffer ( camera_video_port, buffer ) != MMAL_SUCCESS )
            cerr << "Unable to send a buffer to encoder output port " << q << endl;

    }


    _isCapturing = true;
    return true;
}
Beispiel #3
0
bool CMMALVideo::SendCodecConfigData()
{
  MMAL_STATUS_T status;
  if (!m_dec_input_pool)
    return true;
  // send code config data
  MMAL_BUFFER_HEADER_T *buffer = mmal_queue_timedwait(m_dec_input_pool->queue, 500);
  if (!buffer)
  {
    CLog::Log(LOGERROR, "%s::%s - mmal_queue_get failed", CLASSNAME, __func__);
    return false;
  }

  mmal_buffer_header_reset(buffer);
  buffer->cmd = 0;
  buffer->length = std::min(m_hints.extrasize, buffer->alloc_size);
  memcpy(buffer->data, m_hints.extradata, buffer->length);
  buffer->flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END | MMAL_BUFFER_HEADER_FLAG_CONFIG;
  if (g_advancedSettings.CanLogComponent(LOGVIDEO))
    CLog::Log(LOGDEBUG, "%s::%s - %-8p %-6d flags:%x", CLASSNAME, __func__, buffer, buffer->length, buffer->flags);
  status = mmal_port_send_buffer(m_dec_input, buffer);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed send buffer to decoder input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }
  return true;
}
Beispiel #4
0
void take_frame( char * dump_pointer )
{
   gCallback_data.data_dump = dump_pointer;
   int num = mmal_queue_length(gState.camera_pool->queue);
   int q;

   for (q=0;q<num;q++)
   {
      MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(gState.camera_pool->queue);

      if (!buffer)
         vcos_log_error("Unable to get a required buffer %d from pool queue", q);

      if (mmal_port_send_buffer(gCamera_still_port, buffer)!= MMAL_SUCCESS)
         vcos_log_error("Unable to send a buffer to camera output port (%d)", q);
   }

   if (mmal_port_parameter_set_boolean(gCamera_still_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS)
   {
      vcos_log_error("%s: Failed to start capture", __func__);
   }
   else
   {
      vcos_semaphore_wait(&gCallback_data.complete_semaphore);
   }
}
Beispiel #5
0
void CCameraOutput::OnVideoBufferCallback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
	//to handle the user not reading frames, remove and return any pre-existing ones
	if(mmal_queue_length(OutputQueue)>=2)
	{
		if(MMAL_BUFFER_HEADER_T* existing_buffer = mmal_queue_get(OutputQueue))
		{
			mmal_buffer_header_release(existing_buffer);
			if (port->is_enabled)
			{
				MMAL_STATUS_T status;
				MMAL_BUFFER_HEADER_T *new_buffer;
				new_buffer = mmal_queue_get(BufferPool->queue);
				if (new_buffer)
					status = mmal_port_send_buffer(port, new_buffer);
				if (!new_buffer || status != MMAL_SUCCESS)
					printf("Unable to return a buffer to the video port\n");
			}	
		}
	}

	//add the buffer to the output queue
	mmal_queue_put(OutputQueue,buffer);

	//printf("Video buffer callback, output queue len=%d\n", mmal_queue_length(OutputQueue));
}
Beispiel #6
0
static void encoder_output_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) {
    MMAL_BUFFER_HEADER_T *new_buffer;
    PORT_USERDATA *userdata = (PORT_USERDATA *) port->userdata;
    MMAL_POOL_T *pool = userdata->encoder_output_pool;
    //fprintf(stderr, "INFO:%s\n", __func__);

    mmal_buffer_header_mem_lock(buffer);
    fwrite(buffer->data, 1, buffer->length, stdout);
    mmal_buffer_header_mem_unlock(buffer);

    mmal_buffer_header_release(buffer);
    if (port->is_enabled) {
        MMAL_STATUS_T status;

        new_buffer = mmal_queue_get(pool->queue);

        if (new_buffer) {
            status = mmal_port_send_buffer(port, new_buffer);
        }

        if (!new_buffer || status != MMAL_SUCCESS) {
            fprintf(stderr, "Unable to return a buffer to the video port\n");
        }
    }
}
Beispiel #7
0
/** Populate an output port with a pool of buffers */
static MMAL_STATUS_T mmal_port_populate_from_pool(MMAL_PORT_T* port, MMAL_POOL_T* pool)
{
   MMAL_STATUS_T status = MMAL_SUCCESS;
   uint32_t buffer_idx;
   MMAL_BUFFER_HEADER_T *buffer;

   if (!port->priv->pf_send)
      return MMAL_ENOSYS;

   LOG_TRACE("%s port %p, pool: %p", port->name, port, pool);

   /* Populate port from pool */
   for (buffer_idx = 0; buffer_idx < port->buffer_num; buffer_idx++)
   {
      buffer = mmal_queue_get(pool->queue);
      if (!buffer)
      {
         LOG_ERROR("too few buffers in the pool");
         status = MMAL_ENOMEM;
         break;
      }

      status = mmal_port_send_buffer(port, buffer);
      if (status != MMAL_SUCCESS)
      {
         LOG_ERROR("failed to send buffer to port");
         mmal_buffer_header_release(buffer);
         break;
      }
   }

   return status;
}
int start_capture(RASPIVID_STATE *state) {
    if (!(state->isInit)) init_cam(state);

    //raspicamcontrol_set_flips(state->camera_component, state->camera_parameters.hflip, state->camera_parameters.vflip);
    raspicamcontrol_set_flips(state->camera_component, hflip, vflip);

    MMAL_PORT_T *camera_video_port   = state->camera_component->output[MMAL_CAMERA_VIDEO_PORT];
    //MMAL_PORT_T *encoder_output_port = state->encoder_component->output[0];
    ROS_INFO("Starting video capture (%d, %d, %d, %d)\n", state->width, state->height, state->quality, state->framerate);

    if (mmal_port_parameter_set_boolean(camera_video_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS) {
        return 1;
    }
    // Send all the buffers to the video port
    {
        int num = mmal_queue_length(state->camera_pool->queue);
        int q;
        for (q=0; q < num; q++) {
            MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(state->camera_pool->queue);

            if (!buffer)
                vcos_log_error("Unable to get a required buffer %d from pool queue", q);

            //if (mmal_port_send_buffer(encoder_output_port, buffer)!= MMAL_SUCCESS)
            if (mmal_port_send_buffer(camera_video_port, buffer)!= MMAL_SUCCESS)
                vcos_log_error("Unable to send a buffer to encoder output port (%d)", q);
        }
    }
    ROS_INFO("Video capture started\n");
    return 0;
}
/**
 *  buffer header callback function for encoder
 *
 *  Callback will dump buffer data to the specific file
 *
 * @param port Pointer to port from which callback originated
 * @param buffer mmal buffer header pointer
 */
static void encoder_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{   	
   int complete = 0;

   // We pass our file handle and other stuff in via the userdata field.

   PORT_USERDATA *pData = (PORT_USERDATA *)port->userdata;

   if (pData)
   {
      int bytes_written = buffer->length;

      if (buffer->length && pData->file_handle)
      {
         mmal_buffer_header_mem_lock(buffer);

         bytes_written = fwrite(buffer->data, 1, buffer->length, pData->file_handle);

         mmal_buffer_header_mem_unlock(buffer);
      }

      // We need to check we wrote what we wanted - it's possible we have run out of storage.
      if (bytes_written != buffer->length)
      {
         vcos_log_error("Unable to write buffer to file - aborting");
         complete = 1;
      }

      // Now flag if we have completed
      if (buffer->flags & (MMAL_BUFFER_HEADER_FLAG_FRAME_END | MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED))
         complete = 1;
   }
   else
   {
      vcos_log_error("Received a encoder buffer callback with no state");
   }

   // release buffer back to the pool
   mmal_buffer_header_release(buffer);

   // and send one back to the port (if still open)
   if (port->is_enabled)
   {
      MMAL_STATUS_T status;
      MMAL_BUFFER_HEADER_T *new_buffer;

      new_buffer = mmal_queue_get(pData->pstate->encoder_pool->queue);

      if (new_buffer)
      {
         status = mmal_port_send_buffer(port, new_buffer);
      }
      if (!new_buffer || status != MMAL_SUCCESS)
         vcos_log_error("Unable to return a buffer to the encoder port");
   } 

   if (complete)
      vcos_semaphore_post(&(pData->complete_semaphore));
}
Beispiel #10
0
/* This will output a frame that can be used for OpenCV */
IplImage* cvQueryRPiFrame(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
	MMAL_BUFFER_HEADER_T *new_buffer;
	PORT_USERDATA *pData = (PORT_USERDATA *)port->userdata;

	if (pData)
	{	 
		if (buffer->length)
		{
			/*Convert buffer to RGB IplImage*/
						
			mmal_buffer_header_mem_lock(buffer);

			int w=pData->pstate->width;	// get image size
			int h=pData->pstate->height;
			int h4=h/4;
			
			memcpy(yCSI_CAM->imageData,buffer->data,w*h);
			memcpy(uCSI_CAM->imageData,buffer->data+w*h,w*h4);
			memcpy(vCSI_CAM->imageData,buffer->data+w*h+w*h4,w*h4);
			
			cvResize(uCSI_CAM, uCSI_CAM_BIG, CV_INTER_NN);
			cvResize(vCSI_CAM, vCSI_CAM_BIG, CV_INTER_NN);  //CV_INTER_LINEAR looks better but it's slower
			cvMerge(yCSI_CAM, uCSI_CAM_BIG, vCSI_CAM_BIG, NULL, CSI_CAM_IMAGE);
	
			cvCvtColor(CSI_CAM_IMAGE,CSI_CAM_DSTIMAGE,CV_YCrCb2RGB);	// convert in RGB color space (slow)
			
			mmal_buffer_header_mem_unlock(buffer);		  
		 }
		 else 
		 {
			 vcos_log_error("buffer null");
		 }
      
   }
   else
   {
      vcos_log_error("Received a encoder buffer callback with no state");
   }
   
   // release buffer back to the pool
   mmal_buffer_header_release(buffer);

   // and send one back to the port (if still open)
   if (port->is_enabled)
   {
      MMAL_STATUS_T status;

      new_buffer = mmal_queue_get(pData->pstate->video_pool->queue);

      if (new_buffer)
         status = mmal_port_send_buffer(port, new_buffer);

      if (!new_buffer || status != MMAL_SUCCESS)
         vcos_log_error("Unable to return a buffer to the encoder port");
   }
   
   return CSI_CAM_DSTIMAGE;
}
Beispiel #11
0
  /* This is a camera path endpoint callback setup for GPU encoder data
  |  to the ARM.  The callback should handle final disposition of encoder data.
  */
boolean
out_port_callback(CameraObject *obj, int port_num, void callback())
	{
	MMAL_PORT_T		*port;
	MMAL_STATUS_T	status;
	char			*msg = "mmal_port_enable";
	int				i, n;

	if (!obj->component)
		return FALSE;
	port = obj->component->output[port_num];

	/* Create an initial queue of buffers for the output port.
	|  FIXME? Can't handle callbacks for more than one splitter port
	|  because I only have one pool_out per component.
	*/
	if (!obj->pool_out)
		{
		if ((obj->pool_out = mmal_port_pool_create(port,
						port->buffer_num, port->buffer_size)) == NULL)
			{
			log_printf("out_port_callback %s: mmal_port_pool_create failed.\n",
						obj->name);
			return FALSE;
			}
		}

	/* Connect the callback and initialize buffer pool of data that will
	|  be sent to the callback.
	*/
	if ((status = mmal_port_enable(port, callback)) == MMAL_SUCCESS)
		{
		obj->port_out = port;
		port->userdata = (struct MMAL_PORT_USERDATA_T *) obj;

		/* Send all buffers in the created queue to the GPU output port.
		|  These buffers will then be delivered back to the ARM with filled
		|  GPU data via the above callback where we can process the data
		|  and then resend the buffer back to the port to be refilled.
		*/
		msg = "mmal_port_send_buffer";
		n = mmal_queue_length(obj->pool_out->queue);
		for (i = 0; i < n; ++i)
			{
			status = mmal_port_send_buffer(port,
							mmal_queue_get(obj->pool_out->queue));
			if (status != MMAL_SUCCESS)
				break;
			}
		}
	if (status != MMAL_SUCCESS)
		{
		log_printf("out_port_callback %s: %s failed.  Status %s\n",
						obj->name, msg, mmal_status[status]);
		return FALSE;
		}
	return TRUE;
	}
Beispiel #12
0
static picture_t *deinterlace(filter_t *filter, picture_t *picture)
{
    filter_sys_t *sys = filter->p_sys;
    MMAL_BUFFER_HEADER_T *buffer;
    picture_t *out_picture = NULL;
    picture_t *ret = NULL;
    MMAL_STATUS_T status;
    unsigned i = 0;

    fill_output_port(filter);

    buffer = picture->p_sys->buffer;
    buffer->user_data = picture;
    buffer->pts = picture->date;
    buffer->cmd = 0;

    if (!picture->p_sys->displayed) {
        vlc_mutex_lock(&sys->buffer_cond_mutex);
        status = mmal_port_send_buffer(sys->input, buffer);
        if (status != MMAL_SUCCESS) {
            msg_Err(filter, "Failed to send buffer to input port (status=%"PRIx32" %s)",
                    status, mmal_status_to_string(status));
            picture_Release(picture);
        } else {
            picture->p_sys->displayed = true;
            atomic_fetch_add(&sys->input_in_transit, 1);
            vlc_cond_signal(&sys->buffer_cond);
        }
        vlc_mutex_unlock(&sys->buffer_cond_mutex);
    } else {
        picture_Release(picture);
    }

    /*
     * Send output buffers
     */
    while(atomic_load(&sys->started) && i < 2) {
        if (buffer = mmal_queue_timedwait(sys->filtered_pictures, 2000)) {
            i++;
            if (!out_picture) {
                out_picture = (picture_t *)buffer->user_data;
                ret = out_picture;
            } else {
                out_picture->p_next = (picture_t *)buffer->user_data;
                out_picture = out_picture->p_next;
            }
            out_picture->date = buffer->pts;
        } else {
            msg_Dbg(filter, "Failed waiting for filtered picture");
            break;
        }
    }
    if (out_picture)
        out_picture->p_next = NULL;

    return ret;
}
Beispiel #13
0
/**
 *  buffer header callback function for video
 *
 * @param port Pointer to port from which callback originated
 * @param buffer mmal buffer header pointer
 */
static void video_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
	MMAL_BUFFER_HEADER_T *new_buffer;
	RASPIVID_STATE * state = (RASPIVID_STATE *)port->userdata;		

	if (state)
	{
		if (state->finished) {
			vcos_semaphore_post(&state->capture_done_sem);
			return;
		}
		if (buffer->length)
		{
			mmal_buffer_header_mem_lock(buffer);
 
			//
			// *** PR : OPEN CV Stuff here !
			//
			int w=state->width;	// get image size
			int h=state->height;

			int pixelSize = state->monochrome ? 1 : 3;
			memcpy(state->dstImage->imageData,buffer->data,w*h*pixelSize);	

			vcos_semaphore_post(&state->capture_done_sem);
			vcos_semaphore_wait(&state->capture_sem);

			mmal_buffer_header_mem_unlock(buffer);
		}
		else
		{
			vcos_log_error("buffer null");
		}
	}
	else
	{
		vcos_log_error("Received a encoder buffer callback with no state");
	}

	// release buffer back to the pool
	mmal_buffer_header_release(buffer);

	// and send one back to the port (if still open)
	if (port->is_enabled)
	{
		MMAL_STATUS_T status;

		new_buffer = mmal_queue_get(state->video_pool->queue);

		if (new_buffer)
			status = mmal_port_send_buffer(port, new_buffer);

		if (!new_buffer || status != MMAL_SUCCESS)
			vcos_log_error("Unable to return a buffer to the encoder port");
	}
}
Beispiel #14
0
/**
* buffer header callback function for camera output port
*
* Callback will dump buffer data to the specific file
*
* @param port Pointer to port from which callback originated
* @param buffer mmal buffer header pointer
*/
static void camera_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
   int complete = 0;
   // We pass our file handle and other stuff in via the userdata field.

   PORT_USERDATA *pData = (PORT_USERDATA *)port->userdata;

   if (pData)
   {
      if (buffer->length)
      {
         mmal_buffer_header_mem_lock(buffer);
         int i;
         for( i = 0; i < buffer->length; i++ )
            pData->data_dump[i] = buffer->data[i];

         mmal_buffer_header_mem_unlock(buffer);
      }

      // Check end of frame or error
      if (buffer->flags & (MMAL_BUFFER_HEADER_FLAG_FRAME_END | MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED))
         complete = 1;
   }
   else
   {
      vcos_log_error("Received a camera still buffer callback with no state");
   }

   // release buffer back to the pool
   mmal_buffer_header_release(buffer);

   // and send one back to the port (if still open)
   if (port->is_enabled)
   {
      MMAL_STATUS_T status;
      MMAL_BUFFER_HEADER_T *new_buffer = mmal_queue_get(pData->pstate->camera_pool->queue);

      // and back to the port from there.
      if (new_buffer)
      {
         status = mmal_port_send_buffer(port, new_buffer);
      }

      if (!new_buffer || status != MMAL_SUCCESS)
         vcos_log_error("Unable to return the buffer to the camera still port");
   }

   if (complete)
   {
      vcos_semaphore_post(&(pData->complete_semaphore));
   }
}
Beispiel #15
0
MMAL_POOL_T* CCameraOutput::EnablePortCallbackAndCreateBufferPool(MMAL_PORT_T* port, MMAL_PORT_BH_CB_T cb, int buffer_count)
{
	MMAL_STATUS_T status;
	MMAL_POOL_T* buffer_pool = 0;

	//setup video port buffer and a pool to hold them
	port->buffer_num = buffer_count;
	port->buffer_size = port->buffer_size_recommended;
	printf("Creating pool with %d buffers of size %d\n", port->buffer_num, port->buffer_size);
	buffer_pool = mmal_port_pool_create(port, port->buffer_num, port->buffer_size);
	if (!buffer_pool)
	{
		printf("Couldn't create video buffer pool\n");
		goto error;
	}

	//enable the port and hand it the callback
    port->userdata = (struct MMAL_PORT_USERDATA_T *)this;
	status = mmal_port_enable(port, cb);
	if (status != MMAL_SUCCESS)
	{
		printf("Failed to set video buffer callback\n");
		goto error;
	}

	//send all the buffers in our pool to the video port ready for use
	{
		int num = mmal_queue_length(buffer_pool->queue);
		int q;
		for (q=0;q<num;q++)
		{
			MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(buffer_pool->queue);
			if (!buffer)
			{
				printf("Unable to get a required buffer %d from pool queue\n", q);
				goto error;
			}
			else if (mmal_port_send_buffer(port, buffer)!= MMAL_SUCCESS)
			{
				printf("Unable to send a buffer to port (%d)\n", q);
				goto error;
			}
		}
	}

	return buffer_pool;

error:
	if(buffer_pool)
		mmal_port_pool_destroy(port,buffer_pool);
	return NULL;
}
void consume_queue_on_connection(MMAL_PORT_T *port, MMAL_QUEUE_T *queue)
{
	MMAL_BUFFER_HEADER_T *buffer;
	
	while ((buffer = mmal_queue_get(queue)) != NULL)
	{
		if (mmal_port_send_buffer(port, buffer) != MMAL_SUCCESS)
		{
			mmal_queue_put_back(queue, buffer);
			break;
		}
	}
}
Beispiel #17
0
/**
 *  buffer header callback function for encoder
 *
 *  Callback will dump buffer data to the specific file
 *
 * @param port Pointer to port from which callback originated
 * @param buffer mmal buffer header pointer
 */
static void encoder_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
   MMAL_BUFFER_HEADER_T *new_buffer;

   // We pass our file handle and other stuff in via the userdata field.

   PORT_USERDATA *pData = (PORT_USERDATA *)port->userdata;

   if (pData)
   {
      int bytes_written = buffer->length;

      vcos_assert(pData->file_handle);

      if (buffer->length)
      {
         mmal_buffer_header_mem_lock(buffer);

         bytes_written = fwrite(buffer->data, 1, buffer->length, pData->file_handle);

         mmal_buffer_header_mem_unlock(buffer);
      }

      if (bytes_written != buffer->length)
      {
         vcos_log_error("Failed to write buffer data (%d from %d)- aborting", bytes_written, buffer->length);
         pData->abort = 1;
      }
   }
   else
   {
      vcos_log_error("Received a encoder buffer callback with no state");
   }

   // release buffer back to the pool
   mmal_buffer_header_release(buffer);

   // and send one back to the port (if still open)
   if (port->is_enabled)
   {
      MMAL_STATUS_T status;

      new_buffer = mmal_queue_get(pData->pstate->encoder_pool->queue);

      if (new_buffer)
         status = mmal_port_send_buffer(port, new_buffer);

      if (!new_buffer || status != MMAL_SUCCESS)
         vcos_log_error("Unable to return a buffer to the encoder port");
   }
}
Beispiel #18
0
Datei: vout.c Projekt: Kubink/vlc
static void vd_display(vout_display_t *vd, picture_t *picture,
                subpicture_t *subpicture)
{
    vout_display_sys_t *sys = vd->sys;
    picture_sys_t *pic_sys = picture->p_sys;
    MMAL_BUFFER_HEADER_T *buffer = pic_sys->buffer;
    MMAL_STATUS_T status;

    if (picture->format.i_frame_rate != sys->i_frame_rate ||
        picture->format.i_frame_rate_base != sys->i_frame_rate_base ||
        picture->b_progressive != sys->b_progressive ||
        picture->b_top_field_first != sys->b_top_field_first) {
        sys->b_top_field_first = picture->b_top_field_first;
        sys->b_progressive = picture->b_progressive;
        sys->i_frame_rate = picture->format.i_frame_rate;
        sys->i_frame_rate_base = picture->format.i_frame_rate_base;
        configure_display(vd, NULL, &picture->format);
    }

    if (!pic_sys->displayed || !sys->opaque) {
        buffer->cmd = 0;
        buffer->length = sys->input->buffer_size;

        vlc_mutex_lock(&sys->buffer_mutex);
        while (sys->buffers_in_transit >= MAX_BUFFERS_IN_TRANSIT)
            vlc_cond_wait(&sys->buffer_cond, &sys->buffer_mutex);

        status = mmal_port_send_buffer(sys->input, buffer);
        if (status == MMAL_SUCCESS)
            ++sys->buffers_in_transit;

        vlc_mutex_unlock(&sys->buffer_mutex);
        if (status != MMAL_SUCCESS) {
            msg_Err(vd, "Failed to send buffer to input port. Frame dropped");
            picture_Release(picture);
        }

        pic_sys->displayed = true;
    } else {
        picture_Release(picture);
    }

    display_subpicture(vd, subpicture);

    if (subpicture)
        subpicture_Delete(subpicture);

    if (sys->next_phase_check == 0 && sys->adjust_refresh_rate)
        maintain_phase_sync(vd);
    sys->next_phase_check = (sys->next_phase_check + 1) % PHASE_CHECK_INTERVAL;
}
Beispiel #19
0
static void jpegencoder_buffer_callback (MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) {

  int bytes_written = buffer->length;
  char *filename_temp, *filename_temp2;

  if(mjpeg_cnt == 0) {
    if(!jpegoutput_file) {
      asprintf(&filename_temp, jpeg_filename, image_cnt);
      asprintf(&filename_temp2, "%s.part", filename_temp);
      jpegoutput_file = fopen(filename_temp2, "wb");
      free(filename_temp);
      free(filename_temp2);
      if(!jpegoutput_file) error("Could not open mjpeg-destination");
    }
    if(buffer->length) {
      mmal_buffer_header_mem_lock(buffer);
      bytes_written = fwrite(buffer->data, 1, buffer->length, jpegoutput_file);
      mmal_buffer_header_mem_unlock(buffer);
    }
    if(bytes_written != buffer->length) error("Could not write all bytes");
  }
  
  if(buffer->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END) {
    mjpeg_cnt++;
    if(mjpeg_cnt == divider) {
      fclose(jpegoutput_file);
      jpegoutput_file = NULL;
      asprintf(&filename_temp, jpeg_filename, image_cnt);
      asprintf(&filename_temp2, "%s.part", filename_temp);
      rename(filename_temp2, filename_temp);
      free(filename_temp);
      free(filename_temp2);
      image_cnt++;
      mjpeg_cnt = 0;
    }
  }

  mmal_buffer_header_release(buffer);

  if (port->is_enabled) {
    MMAL_STATUS_T status = MMAL_SUCCESS;
    MMAL_BUFFER_HEADER_T *new_buffer;

    new_buffer = mmal_queue_get(pool_jpegencoder->queue);

    if (new_buffer) status = mmal_port_send_buffer(port, new_buffer);
    if (!new_buffer || status != MMAL_SUCCESS) error("Could not send buffers to port");
  }

}
Beispiel #20
0
/** Populate clock ports from the given pool */
static MMAL_STATUS_T mmal_port_populate_clock_ports(MMAL_PORT_T* output, MMAL_PORT_T* input, MMAL_POOL_T* pool)
{
   MMAL_STATUS_T status = MMAL_SUCCESS;
   MMAL_BUFFER_HEADER_T *buffer;

   if (!output->priv->pf_send || !input->priv->pf_send)
      return MMAL_ENOSYS;

   LOG_TRACE("output %s %p, input %s %p, pool: %p", output->name, output, input->name, input, pool);

   buffer = mmal_queue_get(pool->queue);
   while (buffer)
   {
      status = mmal_port_send_buffer(output, buffer);
      if (status != MMAL_SUCCESS)
      {
         LOG_ERROR("failed to send buffer to clock port %s", output->name);
         mmal_buffer_header_release(buffer);
         break;
      }

      buffer = mmal_queue_get(pool->queue);
      if (buffer)
      {
         status = mmal_port_send_buffer(input, buffer);
         if (status != MMAL_SUCCESS)
         {
            LOG_ERROR("failed to send buffer to clock port %s", output->name);
            mmal_buffer_header_release(buffer);
            break;
         }
         buffer = mmal_queue_get(pool->queue);
      }
   }

   return status;
}
void Private_Impl::video_buffer_callback ( MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer ) {

    MMAL_BUFFER_HEADER_T *new_buffer;
    PORT_USERDATA *pData = ( PORT_USERDATA * ) port->userdata;

    bool hasGrabbed = false;
    
    //pData->_mutex.lock();
    std::unique_lock<std::mutex> lck ( pData->_mutex );
    if ( pData ) {
        if ( pData->wantToGrab &&  buffer->length ) {
            mmal_buffer_header_mem_lock ( buffer );
            //printf("pdata buff length%d\n",pData->_buffData.size);
            pData->_buffData.resize ( buffer->length );


            memcpy ( pData->_buffData.data, buffer->data, buffer->length );
            pData->npts = buffer->pts;
            //tst=buffer->pts;
            pData->wantToGrab = false;
            hasGrabbed = true;
            mmal_buffer_header_mem_unlock ( buffer );
        }

    }
    //pData->_mutex.unlock();
    // if ( hasGrabbed ) pData->Thcond.BroadCast(); //wake up waiting client

    // release buffer back to the pool
    mmal_buffer_header_release ( buffer );

    // and send one back to the port (if still open)
    if ( port->is_enabled ) {
        MMAL_STATUS_T status;
        new_buffer = mmal_queue_get ( pData->pstate->video_pool->queue );


        if ( new_buffer ) {}
        status = mmal_port_send_buffer ( port, new_buffer );

        if ( !new_buffer || status != MMAL_SUCCESS )
            printf ( "Unable to return a buffer to the encoder port\n" );
    }

    if ( pData->pstate->shutterSpeed != 0 )
        mmal_port_parameter_set_uint32 ( pData->pstate->camera_component->control, MMAL_PARAMETER_SHUTTER_SPEED, pData->pstate->shutterSpeed ) ;
    if ( hasGrabbed ) pData->Thcond.BroadCast(); //wake up waiting client

}
Beispiel #22
0
int fill_port_buffer(MMAL_PORT_T *port, MMAL_POOL_T *pool) {
    int q;
    int num = mmal_queue_length(pool->queue);

    for (q = 0; q < num; q++) {
        MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(pool->queue);
        if (!buffer) {
            fprintf(stderr, "Unable to get a required buffer %d from pool queue\n", q);
        }

        if (mmal_port_send_buffer(port, buffer) != MMAL_SUCCESS) {
            fprintf(stderr, "Unable to send a buffer to port (%d)\n", q);
        }
    }
}
Beispiel #23
0
/** Callback for when a buffer from a connected input port is finally released */
static MMAL_BOOL_T mmal_port_connected_pool_cb(MMAL_POOL_T *pool, MMAL_BUFFER_HEADER_T *buffer, void *userdata)
{
   MMAL_PORT_T* port = (MMAL_PORT_T*)userdata;
   MMAL_STATUS_T status;
   MMAL_PARAM_UNUSED(pool);

   LOG_TRACE("released buffer %p, data %p alloc_size %u length %u",
             buffer, buffer->data, buffer->alloc_size, buffer->length);

   /* Pipe the buffer back to the output port */
   status = mmal_port_send_buffer(port, buffer);

   /* Put the buffer back in the pool if we were successful */
   return status != MMAL_SUCCESS;
}
Beispiel #24
0
/** Preview worker thread.
 * Ensures camera preview is supplied with buffers and sends preview frames to GL.
 * @param arg  Pointer to state.
 * @return NULL always.
 */
static void *preview_worker(void *arg)
{
    RASPITEX_STATE* state = arg;
    MMAL_PORT_T *preview_port = state->preview_port;
    MMAL_BUFFER_HEADER_T *buf;
    MMAL_STATUS_T st;
    int rc;

    vcos_log_trace("%s: port %p", VCOS_FUNCTION, preview_port);

    rc = state->ops.create_native_window(state);
    if (rc != 0)
        goto end;

    rc = state->ops.gl_init(state);
    if (rc != 0)
        goto end;

    while (state->preview_stop == 0)
    {
        /* Send empty buffers to camera preview port */
        while ((buf = mmal_queue_get(state->preview_pool->queue)) != NULL)
        {
            st = mmal_port_send_buffer(preview_port, buf);
            if (st != MMAL_SUCCESS)
            {
                vcos_log_error("Failed to send buffer to %s", preview_port->name);
            }
        }
        /* Process returned buffers */
        if (preview_process_returned_bufs(state) != 0)
        {
            vcos_log_error("Preview error. Exiting.");
            state->preview_stop = 1;
        }
    }

end:
    /* Make sure all buffers are returned on exit */
    while ((buf = mmal_queue_get(state->preview_queue)) != NULL)
        mmal_buffer_header_release(buf);

    /* Tear down GL */
    state->ops.gl_term(state);
    vcos_log_trace("Exiting preview worker");
    return NULL;
}
Beispiel #25
0
// Move prepared/split packets from waiting_buffers to the MMAL decoder.
static int ffmmal_fill_input_port(AVCodecContext *avctx)
{
    MMALDecodeContext *ctx = avctx->priv_data;

    while (ctx->waiting_buffers) {
        MMAL_BUFFER_HEADER_T *mbuffer;
        FFBufferEntry *buffer;
        MMAL_STATUS_T status;

        mbuffer = mmal_queue_get(ctx->pool_in->queue);
        if (!mbuffer)
            return 0;

        buffer = ctx->waiting_buffers;

        mmal_buffer_header_reset(mbuffer);
        mbuffer->cmd = 0;
        mbuffer->pts = buffer->pts;
        mbuffer->dts = buffer->dts;
        mbuffer->flags = buffer->flags;
        mbuffer->data = buffer->data;
        mbuffer->length = buffer->length;
        mbuffer->user_data = buffer;
        mbuffer->alloc_size = ctx->decoder->input[0]->buffer_size;

        // Remove from start of the list
        ctx->waiting_buffers = buffer->next;
        if (ctx->waiting_buffers_tail == buffer)
            ctx->waiting_buffers_tail = NULL;

        if ((status = mmal_port_send_buffer(ctx->decoder->input[0], mbuffer))) {
            mmal_buffer_header_release(mbuffer);
            av_buffer_unref(&buffer->ref);
            if (buffer->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
                avpriv_atomic_int_add_and_fetch(&ctx->packets_buffered, -1);
            av_free(buffer);
        }

        if (status) {
            av_log(avctx, AV_LOG_ERROR, "MMAL error %d when sending input\n", (int)status);
            return AVERROR_UNKNOWN;
        }
    }

    return 0;
}
Beispiel #26
0
void PiCam::start() {
    if (mmal_port_parameter_set_boolean(videoPort, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS)
    {
        throw std::runtime_error("Couldn't start video capture");
    }

    vcos_semaphore_create(&frame_semaphore, "frame_semaphore", 0);

    int num = mmal_queue_length(videoPool->queue);
    int q;
    for (q=0;q<num;q++)
    {
        MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(videoPool->queue);
    
        // TODO: Add numbers to these error messages.
        if (!buffer)
            throw std::runtime_error("Unable to get a required buffer from pool queue");
    
        if (mmal_port_send_buffer(videoPort, buffer)!= MMAL_SUCCESS)
            throw std::runtime_error("Unable to send a buffer to an encoder output port");
    }

    std::chrono::time_point<std::chrono::system_clock> t1, t2;
    t1 = std::chrono::system_clock::now();

    /*
    while(true) {
        if(vcos_semaphore_wait(&frame_semaphore) == VCOS_SUCCESS) {
            callback(frame);

            ++numFrames;

            
            if(numFrames >= 30) {
                t2 = std::chrono::system_clock::now();
                std::chrono::duration<float> secs = t2-t1;
                t1 = t2;
                std::cout << (numFrames / secs.count()) << " FPS\n";
                numFrames = 0;
            }

            cv::waitKey(1);
        }
    }
    */
}
Beispiel #27
0
static int send_output_buffer(filter_t *filter)
{
    filter_sys_t *sys = filter->p_sys;
    MMAL_BUFFER_HEADER_T *buffer;
    MMAL_STATUS_T status;
    picture_t *picture;
    int ret = 0;

    if (!sys->output->is_enabled) {
        ret = VLC_EGENERIC;
        goto out;
    }

    picture = filter_NewPicture(filter);
    if (!picture) {
        msg_Warn(filter, "Failed to get new picture");
        ret = -1;
        goto out;
    }
    picture->format.i_frame_rate = filter->fmt_out.video.i_frame_rate;
    picture->format.i_frame_rate_base = filter->fmt_out.video.i_frame_rate_base;

    buffer = picture->p_sys->buffer;
    buffer->user_data = picture;
    buffer->cmd = 0;

    mmal_picture_lock(picture);

    vlc_mutex_lock(&sys->buffer_cond_mutex);
    status = mmal_port_send_buffer(sys->output, buffer);
    if (status != MMAL_SUCCESS) {
        msg_Err(filter, "Failed to send buffer to output port (status=%"PRIx32" %s)",
                status, mmal_status_to_string(status));
        mmal_buffer_header_release(buffer);
        picture_Release(picture);
        ret = -1;
    } else {
        atomic_fetch_add(&sys->output_in_transit, 1);
        vlc_cond_signal(&sys->buffer_cond);
    }
    vlc_mutex_unlock(&sys->buffer_cond_mutex);

out:
    return ret;
}
Beispiel #28
0
/**
 *  buffer header callback function for camera output port
 *
 *  Callback will dump buffer data to the specific file
 *
 * @param port Pointer to port from which callback originated
 * @param buffer mmal buffer header pointer
 */
static void camera_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
   MMAL_STATUS_T status;

   // We pass our file handle and other stuff in via the userdata field.

   PORT_USERDATA *pData = (PORT_USERDATA *)port->userdata;

   if (pData)
   {
      if (buffer->length)
      {
         mmal_buffer_header_mem_lock(buffer);

         fwrite(buffer->data, 1, buffer->length, pData->file_handle);

         mmal_buffer_header_mem_unlock(buffer);
      }

      // What about error conditions?
      if (buffer->flags & (MMAL_BUFFER_HEADER_FLAG_FRAME_END | MMAL_BUFFER_HEADER_FLAG_EOS | MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED))
      {
         vcos_semaphore_post(&(pData->complete_semaphore));
      }
   }
   else
   {
      vcos_log_error("Received a camera still buffer callback with no state");
   }

   // release buffer back to the pool
   mmal_buffer_header_release(buffer);

   // and send one back to the port (if still open)
   if (port->is_enabled)
   {
      MMAL_BUFFER_HEADER_T *new_buffer = mmal_queue_get(pData->pstate->camera_pool->queue);

      // and back to the port from there.
      status = mmal_port_send_buffer(port, new_buffer);

      if (status != MMAL_SUCCESS)
         vcos_log_error("Unable to return the buffer to the camera still port");
   }
}
Beispiel #29
0
void CMMALVideo::Recycle(MMAL_BUFFER_HEADER_T *buffer)
{
  if (g_advancedSettings.CanLogComponent(LOGVIDEO))
    CLog::Log(LOGDEBUG, "%s::%s %p", CLASSNAME, __func__, buffer);

  MMAL_STATUS_T status;
  mmal_buffer_header_reset(buffer);
  buffer->cmd = 0;
  if (g_advancedSettings.CanLogComponent(LOGVIDEO))
    CLog::Log(LOGDEBUG, "%s::%s Send buffer %p from pool to decoder output port %p dts_queue(%d) ready_queue(%d) busy_queue(%d)", CLASSNAME, __func__, buffer, m_dec_output,
      m_dts_queue.size(), m_output_ready.size(), m_output_busy);
  status = mmal_port_send_buffer(m_dec_output, buffer);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s - Failed send buffer to decoder output port (status=0%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return;
  }
}
Beispiel #30
0
/** Connected input port buffer callback */
static void mmal_port_connected_input_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
   LOG_TRACE("buffer %p from connected input port %p: data %p, alloc_size %u, length %u",
             buffer, port, buffer->data, buffer->alloc_size, buffer->length);

   /* Clock ports are bi-directional and a buffer coming from an "input"
    * clock port can potentially have valid payload data, in which case
    * it should be sent directly to the connected port. */
   if (port->type == MMAL_PORT_TYPE_CLOCK && buffer->length)
   {
      MMAL_PORT_T* connected_port = port->priv->core->connected_port;
      mmal_port_send_buffer(connected_port, buffer);
      return;
   }

   /* Simply release buffer back into pool for re-use */
   mmal_buffer_header_release(buffer);
}