static void *guard_func(void *param)
{
   GUARD_T *st = (GUARD_T *) param;
   uint32_t set;

   while(1)
   {
      int i;
      vcos_event_flags_get(&st->event, -1, VCOS_OR_CONSUME, 0, &set);

      vcos_semaphore_wait(&st->go);

      if(st->quit)
         break;
      
      for(i=0; i<2; i++)
      {
         if(vcos_event_flags_get(&st->event, 1, VCOS_OR, st->wait[i], &set) != VCOS_SUCCESS)
         {
            int j;
            st->timeout[i] = 1;
            for(j=0; j<st->post[i]; j++)
               vcos_semaphore_post(st->guard);
         }
         else
            st->timeout[i] = 0;
      }

      vcos_semaphore_post(&st->done);
   }

   vcos_thread_exit(NULL);
   return NULL;
}
Esempio n. 2
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");
	}
}
void raspiCamCvReleaseCapture(RaspiCamCvCapture ** capture)
{
	RASPIVID_STATE * state = (*capture)->pState;

	// Unblock the the callback.
	state->finished = 1;
	vcos_semaphore_post(&state->capture_sem);
	vcos_semaphore_wait(&state->capture_done_sem);

	vcos_semaphore_delete(&state->capture_sem);
	vcos_semaphore_delete(&state->capture_done_sem);

	if (state->camera_component)
		mmal_component_disable(state->camera_component);

	destroy_camera_component(state);

	cvReleaseImage(&state->pu);
	if (state->graymode==0) {
		cvReleaseImage(&state->pv);
		cvReleaseImage(&state->py);
	}

	if (state->graymode==0) {
		cvReleaseImage(&state->pu_big);
		cvReleaseImage(&state->pv_big);
		cvReleaseImage(&state->yuvImage);
		cvReleaseImage(&state->dstImage);
	}

	free(state);
	free(*capture);
	*capture = 0;
}
Esempio n. 4
0
/** Wrapper function around the real thread function. Posts the semaphore
  * when completed.
  */
static int vcos_thread_wrapper(void *arg)
{
   void *ret;
   VCOS_THREAD_T *thread = arg;

   vcos_assert(thread->magic == VCOS_THREAD_MAGIC);

   thread->thread.thread = current;

   vcos_add_thread(thread);

#ifdef VCOS_WANT_TLS_EMULATION
   vcos_tls_thread_register(&thread->_tls);
#endif

   if (thread->legacy)
   {
      LEGACY_ENTRY_FN_T fn = (LEGACY_ENTRY_FN_T)thread->entry;
      fn(0,thread->arg);
      ret = 0;
   }
   else
   {
      ret = thread->entry(thread->arg);
   }

   thread->exit_data = ret;

   vcos_remove_thread(current);

   /* For join and cleanup */
   vcos_semaphore_post(&thread->wait);

   return 0;
}
Esempio n. 5
0
/** Callback from video decode output port. */
static void svp_bh_output_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buf)
{
   SVP_T *svp = (SVP_T *)port->userdata;

   if (buf->length == 0)
   {
      LOG_TRACE("%s: zero-length buffer => EOS", port->name);
      svp_set_stop(svp, SVP_STOP_EOS); // This shouldn't be necessary, but it is ...
      mmal_buffer_header_release(buf);
   }
   else if (buf->data == NULL)
   {
      LOG_ERROR("%s: zero buffer handle", port->name);
      mmal_buffer_header_release(buf);
   }
   else
   {
      /* Reset watchdog timer */
      vcos_timer_set(&svp->wd_timer, SVP_WATCHDOG_TIMEOUT_MS);

      /* Enqueue the decoded frame so we can return quickly to MMAL core */
      mmal_queue_put(svp->queue, buf);
   }

   /* Notify worker */
   vcos_semaphore_post(&svp->sema);
}
Esempio n. 6
0
/** Callback from a control port. */
static void svp_bh_control_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buf)
{
   SVP_T *svp = (SVP_T *)port->userdata;

   switch (buf->cmd)
   {
   case MMAL_EVENT_EOS:
      LOG_TRACE("%s: EOS", port->name);
      svp_set_stop(svp, SVP_STOP_EOS);
      break;

   case MMAL_EVENT_ERROR:
      LOG_ERROR("%s: MMAL error: %s", port->name,
                mmal_status_to_string(*(MMAL_STATUS_T *)buf->data));
      svp_set_stop(svp, SVP_STOP_ERROR);
      break;

   default:
      LOG_TRACE("%s: buf %p, event %4.4s", port->name, buf, (char *)&buf->cmd);
      break;
   }

   mmal_buffer_header_release(buf);

   vcos_semaphore_post(&svp->sema);
}
static void vcos_thread_wrapper(int argc, void *arg)
#endif
{
   int i;
   void *ret;
   VCOS_THREAD_T *thread = (VCOS_THREAD_T *)arg;

   vcos_assert(thread->magic == VCOS_THREAD_MAGIC);

#ifdef VCOS_WANT_TLS_EMULATION
   vcos_tls_thread_register(&thread->_tls);
#endif

   if (thread->legacy)
   {
      LEGACY_ENTRY_FN_T fn = (LEGACY_ENTRY_FN_T)thread->entry;
      fn(0,thread->arg);
      ret = 0;
   }
   else
   {
      ret = thread->entry(thread->arg);
   }

   // call termination functions
   for (i=0; i<VCOS_MAX_EXIT_HANDLERS; i++)
   {
      if (thread->at_exit[i].pfn) {
         thread->at_exit[i].pfn(thread->at_exit[i].cxt);
      }
   }

   thread->exit_data = ret;
   vcos_semaphore_post(&thread->wait);
}
Esempio n. 8
0
/** Callback to receive stop notification. Sets quit flag and posts semaphore.
 * @param ctx          VIDTEX_T instance. Declared as void * in order to use as SVP callback.
 * @param stop_reason  SVP stop reason.
 */
static void vidtex_stop_cb(void *ctx, uint32_t stop_reason)
{
   VIDTEX_T *vt = ctx;
   vt->stop_reason = stop_reason;
   vidtex_set_quit(vt, true);
   vcos_semaphore_post(&vt->sem_decoded);
}
Esempio n. 9
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_SUCCESS;
      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));

}
Esempio n. 10
0
/** Return a waiter to the pool.
  */
static void release_waiter(MMAL_CLIENT_T *client, MMAL_WAITER_T *waiter)
{
   LOG_TRACE("at %p", waiter);
   vcos_assert(waiter);
   vcos_assert(waiter->inuse);
   waiter->inuse = 0;
   vcos_semaphore_post(&client->waitpool.sem);
}
Esempio n. 11
0
/** Watchdog timer callback - stops playback */
static void svp_watchdog_cb(void *ctx)
{
   SVP_T *svp = ctx;
   LOG_ERROR("%s: no frames received for %d ms, aborting", svp->video_output->name,
             SVP_WATCHDOG_TIMEOUT_MS);
   svp_set_stop(svp, SVP_STOP_ERROR);
   vcos_semaphore_post(&svp->sema);
}
Esempio n. 12
0
IplImage * raspiCamCvQueryFrame(RaspiCamCvCapture * capture)
{
	RASPIVID_STATE * state = capture->pState;
	vcos_semaphore_post(&state->capture_sem);
	vcos_semaphore_wait(&state->capture_done_sem);

	return state->dstImage;
}
Esempio n. 13
0
static void waiter_deinit(WAITER_T *waiter, int *passed)
{
   waiter->quit = 1;
   vcos_semaphore_post(&waiter->go);

   vcos_thread_join(&waiter->thread,NULL);

   vcos_semaphore_delete(&waiter->go);
   vcos_semaphore_delete(&waiter->done);
}
Esempio n. 14
0
/** Callback from the input port.
 * Buffer has been consumed and is available to be used again. */
static void input_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
   struct CONTEXT_T *ctx = (struct CONTEXT_T *)port->userdata;

   /* The decoder is done with the data, just recycle the buffer header into its pool */
   mmal_buffer_header_release(buffer);

   /* Kick the processing thread */
   vcos_semaphore_post(&ctx->semaphore);
}
Esempio n. 15
0
/** Callback from the output port.
 * Buffer has been produced by the port and is available for processing. */
static void output_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
   struct CONTEXT_T *ctx = (struct CONTEXT_T *)port->userdata;

   /* Queue the decoded video frame */
   mmal_queue_put(ctx->queue, buffer);

   /* Kick the processing thread */
   vcos_semaphore_post(&ctx->semaphore);
}
static void guard_deinit(GUARD_T *guard, int *passed)
{
   guard->quit = 1;
   vcos_semaphore_post(&guard->go);

   vcos_thread_join(&guard->thread,0);

   vcos_semaphore_delete(&guard->go);
   vcos_semaphore_delete(&guard->done);
   vcos_event_flags_delete(&guard->event);
}
Esempio n. 17
0
static OMX_ERRORTYPE vcil_out_ComponentTunnelRequest(OMX_IN  OMX_HANDLETYPE hComponent,
      OMX_IN  OMX_U32 nPort,
      OMX_IN  OMX_HANDLETYPE hTunneledComp,
      OMX_IN  OMX_U32 nTunneledPort,
      OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup)
{
   OMX_COMPONENTTYPE *pComp = (OMX_COMPONENTTYPE *) hComponent;
   VC_PRIVATE_COMPONENT_T *comp;
   IL_TUNNEL_REQUEST_EXECUTE_T exe;
   IL_TUNNEL_REQUEST_RESPONSE_T resp;
   VC_PRIVATE_COMPONENT_T *list;
   ILCS_COMMON_T *st;
   int rlen = sizeof(resp);

   if(!pComp)
      return OMX_ErrorBadParameter;

   st = pComp->pApplicationPrivate;
   comp = (VC_PRIVATE_COMPONENT_T *) pComp->pComponentPrivate;

   exe.reference = comp->reference;
   exe.port = nPort;
   exe.tunnel_port = nTunneledPort;
   if (pTunnelSetup)
      exe.setup = *pTunnelSetup;

   // the other component may be on the host or on VC.  Look through our list
   // so we can tell, and tell ILCS on VC the details.
   vcos_semaphore_wait(&st->component_lock);

   list = st->component_list;
   while (list != NULL && list->comp != (void *) hTunneledComp)
      list = list->next;

   vcos_semaphore_post(&st->component_lock);

   if (list == NULL)
   {
      exe.tunnel_ref = hTunneledComp;
      exe.tunnel_host = OMX_TRUE;
   }
   else
   {
      exe.tunnel_ref = list->reference;
      exe.tunnel_host = OMX_FALSE;
   }

   if(ilcs_execute_function(st->ilcs, IL_COMPONENT_TUNNEL_REQUEST, &exe, sizeof(exe), &resp, &rlen) < 0 || rlen != sizeof(resp))
      return OMX_ErrorHardware;

   if (pTunnelSetup)
      *pTunnelSetup = resp.setup;
   return resp.err;
}
// Called by OMX when the encoder component has filled
// the output buffer with H.264 encoded video data
static OMX_ERRORTYPE fill_output_buffer_done_handler(
        OMX_HANDLETYPE hComponent,
        OMX_PTR pAppData,
        OMX_BUFFERHEADERTYPE* pBuffer) {
    appctx *ctx = ((appctx*)pAppData);
    vcos_semaphore_wait(&ctx->handler_lock);
    // The main loop can now flush the buffer to output file
    ctx->encoder_output_buffer_available = 1;
    vcos_semaphore_post(&ctx->handler_lock);
    return OMX_ErrorNone;
}
Esempio n. 19
0
static OMX_ERRORTYPE vcil_out_ComponentDeInit(OMX_IN OMX_HANDLETYPE hComponent)
{
   OMX_COMPONENTTYPE *pComp = (OMX_COMPONENTTYPE *) hComponent;
   VC_PRIVATE_COMPONENT_T *comp;
   IL_EXECUTE_HEADER_T exe;
   IL_RESPONSE_HEADER_T resp;
   ILCS_COMMON_T *st;
   int rlen = sizeof(resp);

   if(!pComp)
      return OMX_ErrorBadParameter;

   st = pComp->pApplicationPrivate;
   comp = (VC_PRIVATE_COMPONENT_T *) pComp->pComponentPrivate;

   exe.reference = comp->reference;

   if(ilcs_execute_function(st->ilcs, IL_COMPONENT_DEINIT, &exe, sizeof(exe), &resp, &rlen) < 0 || rlen != sizeof(resp) ||
      resp.err == OMX_ErrorNone)
   {
      // remove from list, assuming that we successfully managed to deinit
      // this component, or that ilcs has returned an error.  The assumption
      // here is that if the component has managed to correctly signal an
      // error, it still exists, but if the transport has failed then we might
      // as well try and cleanup
      VC_PRIVATE_COMPONENT_T *list, *prev;

      vcos_semaphore_wait(&st->component_lock);

      list = st->component_list;
      prev = NULL;

      while (list != NULL && list != comp)
      {
         prev = list;
         list = list->next;
      }

      // failing to find this component is not a good sign.
      if(vcos_verify(list))
      {
         if (prev == NULL)
            st->component_list = list->next;
         else
            prev->next = list->next;
      }

      vcos_semaphore_post(&st->component_lock);
      vcos_free(comp);
   }

   return resp.err;
}
Esempio n. 20
0
/** Callback to receive decoded video frame */
static void vidtex_video_frame_cb(void *ctx, void *ob)
{
   if (ob)
   {
      VIDTEX_T *vt = ctx;
      /* coverity[missing_lock] Coverity gets confused by the semaphore locking scheme */
      vt->video_frame = ob;
      vcos_semaphore_post(&vt->sem_decoded);
      vcos_semaphore_wait(&vt->sem_drawn);
      vt->video_frame = NULL;
   }
}
Esempio n. 21
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));
   }
}
Esempio n. 22
0
/** Put a MMAL_BUFFER_HEADER_T back at the start of a QUEUE. */
void mmal_queue_put_back(MMAL_QUEUE_T *queue, MMAL_BUFFER_HEADER_T *buffer)
{
   if(!queue || !buffer) return;

   vcos_mutex_lock(&queue->lock);
   mmal_queue_sanity_check(queue, buffer);
   queue->length++;
   buffer->next = queue->first;
   queue->first = buffer;
   if(queue->last == &queue->first) queue->last = &buffer->next;
   vcos_semaphore_post(&queue->semaphore);
   vcos_mutex_unlock(&queue->lock);
}
static void block_until_flushed(appctx *ctx) {
    int quit;
    while(!quit) {
        vcos_semaphore_wait(&ctx->handler_lock);
        if(ctx->flushed) {
            ctx->flushed = 0;
            quit = 1;
        }
        vcos_semaphore_post(&ctx->handler_lock);
        if(!quit) {
            usleep(10000);
        }
    }
}
static void graph_connection_cb(MMAL_CONNECTION_T *connection)
{
   MMAL_GRAPH_PRIVATE_T *graph = (MMAL_GRAPH_PRIVATE_T *)connection->user_data;
   MMAL_BUFFER_HEADER_T *buffer;

   if (connection->flags == MMAL_CONNECTION_FLAG_DIRECT &&
       (buffer = mmal_queue_get(connection->queue)) != NULL)
   {
      graph_process_buffer(graph, connection, buffer);
      return;
   }

   vcos_semaphore_post(&graph->sema);
}
// OMX calls this handler for all the events it emits
static OMX_ERRORTYPE event_handler(
        OMX_HANDLETYPE hComponent,
        OMX_PTR pAppData,
        OMX_EVENTTYPE eEvent,
        OMX_U32 nData1,
        OMX_U32 nData2,
        OMX_PTR pEventData) {

    dump_event(hComponent, eEvent, nData1, nData2);

    appctx *ctx = (appctx *)pAppData;

    switch(eEvent) {
        case OMX_EventCmdComplete:
            vcos_semaphore_wait(&ctx->handler_lock);
            if(nData1 == OMX_CommandFlush) {
                ctx->flushed = 1;
            }
            vcos_semaphore_post(&ctx->handler_lock);
            break;
        case OMX_EventParamOrConfigChanged:
            vcos_semaphore_wait(&ctx->handler_lock);
            if(nData2 == OMX_IndexParamCameraDeviceNumber) {
                ctx->camera_ready = 1;
            }
            vcos_semaphore_post(&ctx->handler_lock);
            break;
        case OMX_EventError:
            omx_die(nData1, "error event received");
            break;
        default:
            break;
    }

    return OMX_ErrorNone;
}
Esempio n. 26
0
IplImage * raspiCamCvQueryFrame_New_Final(RaspiCamCvCapture * capture) {
	RASPIVID_STATE * state = capture->pState;
	vcos_semaphore_post(&state->capture_sem);
	vcos_semaphore_wait(&state->capture_done_sem);

	cvResize(state->pu, state->pu_big, CV_INTER_NN);
	cvResize(state->pv, state->pv_big, CV_INTER_NN);  //CV_INTER_LINEAR looks better but it's slower
	//cvResize(state->pu, state->pu_big, CV_INTER_AREA);
	//cvResize(state->pv, state->pv_big, CV_INTER_AREA);
	cvMerge(state->py, state->pu_big, state->pv_big, NULL, state->yuvImage);
	//cvMerge(state->py, state->pu, state->pv, NULL, state->yuvImage);

	//cvCvtColor(state->yuvImage,state->dstImage,CV_YCrCb2RGB);	// convert in RGB color space (slow)
	return state->yuvImage;
}
/**
 * <DFN>vc_hdcp2_service_send_command</DFN> sends a command which has no reply to Videocore
 * side HDCP2 service.
 *
 * @param client_handle is the vchi client handle
 *
 * @param sema is the locking semaphore to protect the buffer
 * 
 * @param command is the command (VC_HDCP2_CMD_CODE_T in vc_hdcp2service_defs.h)
 *
 * @param buffer is the command buffer to be sent
 *
 * @param length is the size of buffer in bytes
 *
 * @return zero if successful, VCHI error code if failed
 */
int32_t vc_hdcp2_service_send_command(VCHI_SERVICE_HANDLE_T client_handle,
                                      VCOS_SEMAPHORE_T *sema,
                                      uint32_t command, void *buffer, uint32_t length) {
   VCHI_MSG_VECTOR_T vector[] = { {&command, sizeof(command)},
                                  {buffer, length} };
   VCOS_STATUS_T status;
   int32_t success = 0;
   vcos_assert(sema);
   status = vcos_semaphore_wait(sema);
   vcos_assert(status == VCOS_SUCCESS);
   success = vchi_msg_queuev( client_handle, vector, sizeof(vector)/sizeof(vector[0]),
                              VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL );
   status = vcos_semaphore_post(sema);
   vcos_assert(status == VCOS_SUCCESS);
   return success;
}
Esempio n. 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");
   }
}
Esempio n. 29
0
static _VCOS_INLINE
void vcos_msg_send_helper(VCOS_MSGQUEUE_T *src,
                           VCOS_MSGQUEUE_T *dest,
                           uint32_t code,
                           VCOS_MSG_T *msg)
{
   vcos_assert(msg);
   vcos_assert(dest);

   msg->code = code;
   msg->dst = dest;
   msg->src = src;
   msg->next = NULL;
   msg->src_thread = vcos_thread_current();

   msgq_append(dest, msg);
   vcos_semaphore_post(&dest->sem);
}
Esempio n. 30
0
/**
 * Writes the next GL frame-buffer to a RAW .ppm formatted file
 * using the specified file-handle.
 * @param state Pointer to the GL preview state.
 * @param outpt_file Output file handle for the ppm image.
 * @return Zero on success.
 */
int raspitex_capture(RASPITEX_STATE *state, FILE *output_file)
{
    int rc = 0;
    uint8_t *buffer = NULL;
    size_t size = 0;

    vcos_log_trace("%s: state %p file %p", VCOS_FUNCTION,
                   state, output_file);

    if (state && output_file)
    {
        /* Only request one capture at a time */
        vcos_semaphore_wait(&state->capture.start_sem);
        state->capture.request = 1;

        /* Wait for capture to start */
        vcos_semaphore_wait(&state->capture.completed_sem);

        /* Take ownership of the captured buffer */
        buffer = state->capture.buffer;
        size = state->capture.size;

        state->capture.request = 0;
        state->capture.buffer = 0;
        state->capture.size = 0;

        /* Allow another capture to be requested */
        vcos_semaphore_post(&state->capture.start_sem);
    }
    if (size == 0 || ! buffer)
    {
        vcos_log_error("%s: capture failed", VCOS_FUNCTION);
        rc = -1;
        goto end;
    }

    raspitexutil_brga_to_rgba(buffer, size);
    rc = write_tga(output_file, state->width, state->height, buffer, size);
    fflush(output_file);

end:
    free(buffer);
    return rc;
}