예제 #1
0
BRCMIMAGE_STATUS_T brcmimage_create(BRCMIMAGE_TYPE_T type, unsigned int encoding, BRCMIMAGE_T **ctx)
{
   BRCMIMAGE_STATUS_T status = BRCMIMAGE_SUCCESS;
   BRCMIMAGE_T **comp;

   if (type == BRCMIMAGE_TYPE_ENCODER)
      comp = &brcmimage_encoder[getEncoderIndexFromType(encoding)];
   else
      comp = &brcmimage_decoder[getEncoderIndexFromType(encoding)];

   vcos_once(&once, brcmimage_init_once);
   LOCK();
   if (!*comp)
   {
      int init1, init2, init3;
      *comp = (BRCMIMAGE_T*)calloc(sizeof(BRCMIMAGE_T), 1);
      if (!*comp)
      {
         UNLOCK();
         return BRCMIMAGE_ERROR_NOMEM;
      }
      (*comp)->type = type;
      (*comp)->encoding = encoding;
      init1 = vcos_mutex_create(&(*comp)->lock, "brcmimage lock") != VCOS_SUCCESS;
      init2 = vcos_mutex_create(&(*comp)->process_lock, "brcmimage process lock") != VCOS_SUCCESS;
      init3 = vcos_semaphore_create(&(*comp)->sema, "brcmimage sema", 0) != VCOS_SUCCESS;
      if (init1 | init2 | init3)
      {
         if (init1) vcos_mutex_delete(&(*comp)->lock);
         if (init2) vcos_mutex_delete(&(*comp)->process_lock);
         if (init3) vcos_semaphore_delete(&(*comp)->sema);
         free(comp);
         UNLOCK();
         return BRCMIMAGE_ERROR_NOMEM;
      }
   }
   (*comp)->ref_count++;
   UNLOCK();

   LOCK_COMP(*comp);
   if (!(*comp)->init)
   {
      if (type == BRCMIMAGE_TYPE_ENCODER)
         status = brcmimage_init_encoder(*comp);
      else
         status = brcmimage_init_decoder(*comp);

      (*comp)->init = status == BRCMIMAGE_SUCCESS;
   }
   UNLOCK_COMP(*comp);

   if (status != BRCMIMAGE_SUCCESS)
      brcmimage_release(*comp);

   *ctx = *comp;
   return status;
}
예제 #2
0
BRCMJPEG_STATUS_T brcmjpeg_create(BRCMJPEG_TYPE_T type, BRCMJPEG_T **ctx)
{
   BRCMJPEG_STATUS_T status = BRCMJPEG_SUCCESS;
   BRCMJPEG_T **comp;

   if (type == BRCMJPEG_TYPE_ENCODER)
      comp = &brcmjpeg_encoder;
   else
      comp = &brcmjpeg_decoder;

   vcos_once(&once, brcmjpeg_init_once);
   LOCK();
   if (!*comp)
   {
      int init1, init2, init3;
      *comp = (BRCMJPEG_T*)calloc(sizeof(BRCMJPEG_T), 1);
      if (!*comp)
      {
         UNLOCK();
         return BRCMJPEG_ERROR_NOMEM;
      }
      (*comp)->type = type;
      init1 = vcos_mutex_create(&(*comp)->lock, "brcmjpeg lock") != VCOS_SUCCESS;
      init2 = vcos_mutex_create(&(*comp)->process_lock, "brcmjpeg process lock") != VCOS_SUCCESS;
      init3 = vcos_semaphore_create(&(*comp)->sema, "brcmjpeg sema", 0) != VCOS_SUCCESS;
      if (init1 | init2 | init3)
      {
         if (init1) vcos_mutex_delete(&(*comp)->lock);
         if (init2) vcos_mutex_delete(&(*comp)->process_lock);
         if (init3) vcos_semaphore_delete(&(*comp)->sema);
         free(comp);
         UNLOCK();
         return BRCMJPEG_ERROR_NOMEM;
      }
   }
   (*comp)->ref_count++;
   UNLOCK();

   LOCK_COMP(*comp);
   if (!(*comp)->init)
   {
      if (type == BRCMJPEG_TYPE_ENCODER)
         status = brcmjpeg_init_encoder(*comp);
      else
         status = brcmjpeg_init_decoder(*comp);

      (*comp)->init = status == BRCMJPEG_SUCCESS;
   }
   UNLOCK_COMP(*comp);

   if (status != BRCMJPEG_SUCCESS)
      brcmjpeg_release(*comp);

   *ctx = *comp;
   return status;
}
VCOS_STATUS_T vcos_init(void)
{
   VCOS_STATUS_T st = VCOS_SUCCESS;

#ifdef HAVE_MTRACE
   // enable glibc memory debugging, if the environment
   // variable MALLOC_TRACE names a valid file.
   mtrace();
#endif

   vcos_mutex_create(&lock, "global_lock");

   vcos_demand(pthread_key_create(&_vcos_thread_current_key, NULL) == 0);

   /* Initialise a VCOS wrapper for the thread which called vcos_init. */
   vcos_semaphore_create(&vcos_thread_main.suspend, NULL, 0);
   vcos_thread_main.thread = pthread_self();
   pthread_setspecific(_vcos_thread_current_key, &vcos_thread_main);

   st = vcos_msgq_init();
   vcos_assert(st == VCOS_SUCCESS);

   vcos_logging_init();

   return st;
}
예제 #4
0
파일: mmal_queue.c 프로젝트: 6by9/userland
/** Create a QUEUE of MMAL_BUFFER_HEADER_T */
MMAL_QUEUE_T *mmal_queue_create(void)
{
   MMAL_QUEUE_T *queue;

   queue = vcos_malloc(sizeof(*queue), "MMAL queue");
   if(!queue) return 0;

   if(vcos_mutex_create(&queue->lock, "MMAL queue lock") != VCOS_SUCCESS )
   {
      vcos_free(queue);
      return 0;
   }

   if(vcos_semaphore_create(&queue->semaphore, "MMAL queue sema", 0) != VCOS_SUCCESS )
   {
      vcos_mutex_delete(&queue->lock);
      vcos_free(queue);
      return 0;
   }

   /* gratuitous lock for coverity */ vcos_mutex_lock(&queue->lock);
   queue->length = 0;
   queue->first = 0;
   queue->last = &queue->first;
   mmal_queue_sanity_check(queue, NULL);
   /* gratuitous unlock for coverity */ vcos_mutex_unlock(&queue->lock);

   return queue;
}
예제 #5
0
static void brcmimage_init_once(void)
{
   vcos_mutex_create(&brcmimage_lock, VCOS_FUNCTION);

   for (int i=0; i < MAX_ENCODER_TYPES; i++)
   {
       brcmimage_encoder[i] = NULL;
       brcmimage_decoder[i] = NULL;
   }

}
예제 #6
0
/** Create a new vidtex instance */
static VIDTEX_T *vidtex_create(EGLNativeWindowType win)
{
   VIDTEX_T *vt;
   VCOS_STATUS_T st;

   vt = vcos_calloc(1, sizeof(*vt), "vidtex");
   if (vt == NULL)
   {
      vcos_log_trace("Memory allocation failure");
      return NULL;
   }

   st = vcos_semaphore_create(&vt->sem_decoded, "vidtex-dec", 0);
   if (st != VCOS_SUCCESS)
   {
      vcos_log_trace("Error creating semaphore");
      goto error_ctx;
   }

   st = vcos_semaphore_create(&vt->sem_drawn, "vidtex-drw", 0);
   if (st != VCOS_SUCCESS)
   {
      vcos_log_trace("Error creating semaphore");
      goto error_sem1;
   }

   st = vcos_mutex_create(&vt->mutex, "vidtex");
   if (st != VCOS_SUCCESS)
   {
      vcos_log_trace("Error creating semaphore");
      goto error_sem2;
   }

   if (vidtex_gl_init(vt, win) != 0)
   {
      vcos_log_trace("Error initialising EGL");
      goto error_mutex;
   }

   vt->quit = false;
   vt->stop_reason = 0;

   return vt;

error_mutex:
   vcos_mutex_delete(&vt->mutex);
error_sem2:
   vcos_semaphore_delete(&vt->sem_drawn);
error_sem1:
   vcos_semaphore_delete(&vt->sem_decoded);
error_ctx:
   vcos_free(vt);
   return NULL;
}
예제 #7
0
static VCOS_STATUS_T vcos_msgq_create(VCOS_MSGQUEUE_T *q)
{
   VCOS_STATUS_T st;

   memset(q, 0, sizeof(*q));

   st = vcos_semaphore_create(&q->sem,"vcos:msgqueue",0);
   if (st == VCOS_SUCCESS)
      st = vcos_mutex_create(&q->lock,"vcos:msgqueue");
   return st;
}
VCOS_STATUS_T vcos_generic_event_flags_create(VCOS_EVENT_FLAGS_T *flags, const char *name)
{
   VCOS_STATUS_T rc;
   if ((rc=vcos_mutex_create(&flags->lock, name)) != VCOS_SUCCESS)
   {
      return rc;
   }

   flags->events = 0;
   flags->waiters.head = flags->waiters.tail = 0;
   return rc;
}
void vcos_logging_init(void)
{
   if (inited)
   {
      // FIXME: should print a warning or something here
      return;
   }

   vcos_mutex_create(&lock, "vcos_log");
   vcos_log_register("default", &dflt_log_category);
   dflt_log_category.flags.want_prefix = 0;
   vcos_assert(!inited);
   inited = 1;
}
예제 #10
0
void vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_CHANNEL_T *local, VCHIQ_CHANNEL_T *remote)
{
   VCOS_THREAD_ATTR_T attrs;
   char threadname[8];
   static int id = 0;

   vcos_assert(is_pow2(VCHIQ_CHANNEL_SIZE));

   vcos_assert(is_pow2(VCHIQ_NUM_CURRENT_BULKS));
   vcos_assert(is_pow2(VCHIQ_NUM_SERVICE_BULKS));

   vcos_assert(sizeof(VCHIQ_HEADER_T) == 8);    /* we require this for consistency between endpoints */

   memset(state, 0, sizeof(VCHIQ_STATE_T));
   state->id = id++;

   /*
      initialize events and mutex
   */

   vcos_event_create(&state->connect, "vchiq");
   vcos_mutex_create(&state->mutex, "vchiq");

   /*
      initialize channel pointers
   */

   state->local  = local;
   state->remote = remote;
   vchiq_init_channel(local);

   /*
      bring up slot handler thread
   */

   vcos_thread_attr_init(&attrs);
   vcos_thread_attr_setstacksize(&attrs, VCHIQ_SLOT_HANDLER_STACK);
   vcos_thread_attr_setpriority(&attrs, 5); /* FIXME: should not be hardcoded */
   vcos_thread_attr_settimeslice(&attrs, 20); /* FIXME: should not be hardcoded */
   strcpy(threadname, "VCHIQ-0");
   threadname[6] += state->id % 10;
   vcos_thread_create(&state->slot_handler_thread, threadname,
                      &attrs, slot_handler_func, state);

   /* Indicate readiness to the other side */
   local->initialised = 1;
}
예제 #11
0
VCOS_STATUS_T vcos_msgq_init(void)
{
   VCOS_STATUS_T st = vcos_mutex_create(&lock,"msgq");
   if (st != VCOS_SUCCESS)
      goto fail_mtx;

   st = vcos_tls_create(&tls_key);
   if (st != VCOS_SUCCESS)
      goto fail_tls;

   endpoints = NULL;
   return st;

fail_tls:
   vcos_mutex_delete(&lock);
fail_mtx:
   return st;
}
예제 #12
0
	CComponent::CComponent(std::string sName, CGraph* pGraph) : m_sName(std::move(sName)), m_hComponent(NULL), m_pGraph(pGraph)
	{
		std::string sStateChangedEventName(m_sName);
		sStateChangedEventName.append(":state_changed_event");
		CHECK_VCOS(vcos_event_create(&m_StateChangedEvent, sStateChangedEventName.c_str()), "failed to create vcos event");
		std::string sEventThreadName(m_sName);
		sEventThreadName.append(":event_thread");
		m_EventThread.Start(&CComponent::EventThreadProc, this, sEventThreadName.c_str());
		std::string sEventQueueMutexName(m_sName);
		sEventQueueMutexName.append(":event_queue_mutex");
		vcos_mutex_create(&m_EventQueueMutex, sEventThreadName.c_str());
		OMX_CALLBACKTYPE Callbacks;
		Callbacks.EventHandler = &CComponent::EventHandler;
		Callbacks.EmptyBufferDone = &CComponent::EmptyBufferDone;
		Callbacks.FillBufferDone = &CComponent::FillBufferDone;
		std::string sError("failed to create component ");
		sError.append(m_sName);
		CHECK_OMX(OMX_GetHandle(&m_hComponent, const_cast<char*>(m_sName.c_str()), this, &Callbacks), sError.c_str());
	}
예제 #13
0
void vcos_logging_init(void)
{
   if (inited)
   {
      /* FIXME: should print a warning or something here */
      return;
   }
   vcos_mutex_create(&lock, "vcos_log");

   vcos_log_platform_init();

   vcos_log_register("default", &dflt_log_category);

#if VCOS_WANT_LOG_CMD
   vcos_cmd_register( &cmd_log );
#endif

   vcos_assert(!inited);
   inited = 1;
}
예제 #14
0
void vc_vchi_gencmd_init (VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections )
{
   VCOS_STATUS_T status;
   int32_t success;
   int i;

   if (gencmd_client.initialised)
     return;

   // record the number of connections
   memset( &gencmd_client, 0, sizeof(GENCMD_SERVICE_T) );
   gencmd_client.num_connections = (int) num_connections;

   status = vcos_mutex_create(&gencmd_client.lock, "HGencmd");
   vcos_assert(status == VCOS_SUCCESS);
   status = vcos_event_create(&gencmd_client.message_available_event, "HGencmd");
   vcos_assert(status == VCOS_SUCCESS);

   for (i=0; i<gencmd_client.num_connections; i++) {

      // Create a 'LONG' service on the each of the connections
      SERVICE_CREATION_T gencmd_parameters = { VCHI_VERSION(VC_GENCMD_VER),
                                               MAKE_FOURCC("GCMD"),      // 4cc service code
                                               connections[i],           // passed in fn ptrs
                                               0,                        // tx fifo size (unused)
                                               0,                        // tx fifo size (unused)
                                               &gencmd_callback,         // service callback
                                               &gencmd_client.message_available_event, // callback parameter
                                               VC_FALSE,                 // want_unaligned_bulk_rx
                                               VC_FALSE,                 // want_unaligned_bulk_tx
                                               VC_FALSE                  // want_crc
                                               };

      success = vchi_service_open( initialise_instance, &gencmd_parameters, &gencmd_client.open_handle[i] );
      assert( success == 0 );
   }

   gencmd_client.initialised = 1;
   release_gencmd_service();
}
예제 #15
0
static void init_once(void)
{
   vcos_mutex_create(&gpuserv_client.lock, VCOS_FUNCTION);
}
VCOS_STATUS_T vcos_generic_reentrant_mutex_create(VCOS_REENTRANT_MUTEX_T *m, const char *name)
{
   m->count = 0;
   m->owner = 0;
   return vcos_mutex_create(&m->mutex, name);
}
예제 #17
0
VCOS_STATUS_T vcos_generic_blockpool_init(VCOS_BLOCKPOOL_T *pool,
      VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size,
      void *start, VCOS_UNSIGNED pool_size, VCOS_UNSIGNED align,
      VCOS_UNSIGNED flags, const char *name)
{
   VCOS_STATUS_T status = VCOS_SUCCESS;

   vcos_unused(name);
   vcos_unused(flags);

   vcos_log_trace(
         "%s: pool %p num_blocks %d block_size %d start %p pool_size %d name %p",
         VCOS_FUNCTION, pool, num_blocks, block_size, start, pool_size, name);

   vcos_demand(pool);
   vcos_demand(start);
   vcos_assert((block_size > 0));
   vcos_assert(num_blocks > 0);

   if (! align)
      align = VCOS_BLOCKPOOL_ALIGN_DEFAULT;

   if (align & 0x3)
   {
      vcos_log_error("%s: invalid alignment %d", VCOS_FUNCTION, align);
      return VCOS_EINVAL;
   }

   if (VCOS_BLOCKPOOL_SIZE(num_blocks, block_size, align) > pool_size)
   {
      vcos_log_error("%s: Pool is too small" \
            " num_blocks %d block_size %d align %d"
            " pool_size %d required size %d", VCOS_FUNCTION,
            num_blocks, block_size, align,
            pool_size, (int) VCOS_BLOCKPOOL_SIZE(num_blocks, block_size, align));
      return VCOS_ENOMEM;
   }

   status = vcos_mutex_create(&pool->mutex, "vcos blockpool mutex");
   if (status != VCOS_SUCCESS)
      return status;

   pool->block_data_size = block_size;

   /* TODO - create flag that if set forces the header to be in its own cache
    * line */
   pool->block_size = VCOS_BLOCKPOOL_ROUND_UP(pool->block_data_size +
         (align >= 4096 ? 32 : 0) +
         sizeof(VCOS_BLOCKPOOL_HEADER_T), align);

   pool->magic = VCOS_BLOCKPOOL_MAGIC;
   pool->num_subpools = 1;
   pool->num_extension_blocks = 0;
   pool->align = align;
   memset(pool->subpools, 0, sizeof(pool->subpools));

   vcos_generic_blockpool_subpool_init(pool, &pool->subpools[0], start,
         pool_size, num_blocks, align, VCOS_BLOCKPOOL_SUBPOOL_FLAG_NONE);

   return status;
}
void os_cond_init(void)
{
   vcos_assert(vcos_cv_inited++ == 0);
   vcos_demand(vcos_mutex_create(&cond_latch,NULL) == VCOS_SUCCESS);
}
예제 #19
0
static void mmal_vc_payload_list_init()
{
   vcos_mutex_create(&mmal_vc_payload_list.lock, "mmal_vc_payload_list");
}
예제 #20
0
/** Allocate a port structure */
MMAL_PORT_T *mmal_port_alloc(MMAL_COMPONENT_T *component, MMAL_PORT_TYPE_T type, unsigned int extra_size)
{
   MMAL_PORT_T *port;
   MMAL_PORT_PRIVATE_CORE_T *core;
   unsigned int name_size = strlen(component->name) + sizeof(PORT_NAME_FORMAT);
   unsigned int size = sizeof(*port) + sizeof(MMAL_PORT_PRIVATE_T) +
      sizeof(MMAL_PORT_PRIVATE_CORE_T) + name_size + extra_size;
   MMAL_BOOL_T lock = 0, lock_send = 0, lock_transit = 0, sema_transit = 0;
   MMAL_BOOL_T lock_stats = 0, lock_connection = 0;

   LOG_TRACE("component:%s type:%u extra:%u", component->name, type, extra_size);

   port = vcos_calloc(1, size, "mmal port");
   if (!port)
   {
      LOG_ERROR("failed to allocate port, size %u", size);
      return 0;
   }
   port->type = type;

   port->priv = (MMAL_PORT_PRIVATE_T *)(port+1);
   port->priv->core = core = (MMAL_PORT_PRIVATE_CORE_T *)(port->priv+1);
   if (extra_size)
      port->priv->module = (struct MMAL_PORT_MODULE_T *)(port->priv->core+1);
   port->component = component;
   port->name = core->name = ((char *)(port->priv->core+1)) + extra_size;
   core->name_size = name_size;
   mmal_port_name_update(port);
   core->queue_last = &core->queue_first;

   port->priv->pf_connect = mmal_port_connect_default;

   lock = vcos_mutex_create(&port->priv->core->lock, "mmal port lock") == VCOS_SUCCESS;
   lock_send = vcos_mutex_create(&port->priv->core->send_lock, "mmal port send lock") == VCOS_SUCCESS;
   lock_transit = vcos_mutex_create(&port->priv->core->transit_lock, "mmal port transit lock") == VCOS_SUCCESS;
   sema_transit = vcos_semaphore_create(&port->priv->core->transit_sema, "mmal port transit sema", 1) == VCOS_SUCCESS;
   lock_stats = vcos_mutex_create(&port->priv->core->stats_lock, "mmal stats lock") == VCOS_SUCCESS;
   lock_connection = vcos_mutex_create(&port->priv->core->connection_lock, "mmal connection lock") == VCOS_SUCCESS;

   if (!lock || !lock_send || !lock_transit || !sema_transit || !lock_stats || !lock_connection)
   {
      LOG_ERROR("%s: failed to create sync objects (%u,%u,%u,%u,%u,%u)",
            port->name, lock, lock_send, lock_transit, sema_transit, lock_stats, lock_connection);
      goto error;
   }

   port->format = mmal_format_alloc();
   if (!port->format)
   {
      LOG_ERROR("%s: failed to allocate format object", port->name);
      goto error;
   }
   port->priv->core->format_ptr_copy = port->format;

   LOG_TRACE("%s: created at %p", port->name, port);
   return port;

 error:
   if (lock) vcos_mutex_delete(&port->priv->core->lock);
   if (lock_send) vcos_mutex_delete(&port->priv->core->send_lock);
   if (lock_transit) vcos_mutex_delete(&port->priv->core->transit_lock);
   if (sema_transit) vcos_semaphore_delete(&port->priv->core->transit_sema);
   if (lock_stats) vcos_mutex_delete(&port->priv->core->stats_lock);
   if (lock_connection) vcos_mutex_delete(&port->priv->core->connection_lock);
   if (port->format) mmal_format_free(port->format);
   vcos_free(port);
   return 0;
}
VCOS_STATUS_T _vcos_named_semaphore_init(void)
{
   memset(sems,0,sizeof(sems));
   return vcos_mutex_create(&lock,"vcosnmsem");
}
예제 #22
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;
}
예제 #23
0
파일: mmalplay.c 프로젝트: ms-iot/userland
int main(int argc, const char **argv)
{
   VCOS_THREAD_ATTR_T attrs;
   int i;

   vcos_init();
   signal(SIGINT, test_signal_handler);

   /* coverity[tainted_data] Ignore unnecessary warning about an attacker
    * being able to pass an arbitrarily long "-vvvvv..." argument */
   if (test_parse_cmdline(argc, argv))
      return -1;

   if (verbosity--)
   {
      static char value[512];
      const char *levels[] = {"warn", "info", "trace"};
      char *env = getenv("VC_LOGLEVEL");
      if (verbosity >= MMAL_COUNTOF(levels)) verbosity = MMAL_COUNTOF(levels) - 1;
      snprintf(value, sizeof(value)-1, "mmalplay:%s,mmal:%s,%s",
               levels[verbosity], levels[verbosity], env ? env : "");
#ifdef WIN32
      _putenv("VC_LOGLEVEL", value, 1);
#else
      setenv("VC_LOGLEVEL", value, 1);
#endif
   }

   vcos_log_register("mmalplay", VCOS_LOG_CATEGORY);
   LOG_INFO("MMAL Video Playback Test App");

   vcos_thread_attr_init(&attrs);
   for (i = 0; i < play_info_count; i++)
   {
      const char *uri = play_info[i].uri;

      memcpy(play_info[i].name, THREAD_PREFIX, sizeof(THREAD_PREFIX));
      if (strlen(uri) >= URI_FOR_THREAD_NAME_MAX)
         uri += strlen(uri) - URI_FOR_THREAD_NAME_MAX;
      strncat(play_info[i].name, uri, URI_FOR_THREAD_NAME_MAX);

      vcos_mutex_create(&play_info[i].lock, "mmalplay");
      play_info[i].options.render_layer = i;

      if (vcos_thread_create(&play_info[i].thread, play_info[i].name, &attrs, mmal_playback, &play_info[i]) != VCOS_SUCCESS)
      {
         LOG_ERROR("Thread creation failure for URI %s", play_info[i].uri);
         return -2;
      }
   }

   if (sleepy_time != 0)
   {
#ifdef WIN32
      Sleep(sleepy_time);
#else
      sleep(sleepy_time);
#endif
      for (i = 0; i < play_info_count; i++)
      {
         vcos_mutex_lock(&play_info[i].lock);
         if (play_info[i].ctx)
            mmalplay_stop(play_info[i].ctx);
         vcos_mutex_unlock(&play_info[i].lock);
      }
   }

   LOG_TRACE("Waiting for threads to terminate");
   for (i = 0; i < play_info_count; i++)
   {
      vcos_thread_join(&play_info[i].thread, NULL);
      LOG_TRACE("Joined thread %d (%i)", i, play_info[i].status);
   }

   LOG_TRACE("Completed");

   /* Check for errors */
   for (i = 0; i < play_info_count; i++)
   {
      if (!play_info[i].status)
         continue;

      LOG_ERROR("Playback of %s failed (%i, %s)", play_info[i].uri,
                play_info[i].status,
                mmal_status_to_string(play_info[i].status));
      fprintf(stderr, "playback of %s failed (%i, %s)\n", play_info[i].uri,
              play_info[i].status,
              mmal_status_to_string(play_info[i].status));
      return play_info[i].status;
   }

   return 0;
}
예제 #24
0
static void brcmjpeg_init_once(void)
{
   vcos_mutex_create(&brcmjpeg_lock, VCOS_FUNCTION);
}
예제 #25
0
VCOS_STATUS_T vcos_platform_init(void)
{
   VCOS_STATUS_T st;
   uint32_t flags = 0;
   int pst;

   st = _vcos_named_semaphore_init();
   if (!vcos_verify(st == VCOS_SUCCESS))
      goto end;

   flags |= VCOS_INIT_NAMED_SEM;

#ifdef HAVE_MTRACE
   /* enable glibc memory debugging, if the environment
    * variable MALLOC_TRACE names a valid file.
    */
   mtrace();
#endif

#ifdef ANDROID
   st = vcos_mutex_create(&printf_lock, "printf");
   if (!vcos_verify(st == VCOS_SUCCESS))
      goto end;

   flags |= VCOS_INIT_PRINTF_LOCK;
#endif

   st = vcos_once(&current_thread_key_once, current_thread_key_init);
   if (!vcos_verify(st == VCOS_SUCCESS))
      goto end;

   /* Initialise a VCOS wrapper for the thread which called vcos_init. */
   st = vcos_semaphore_create(&vcos_thread_main.suspend, NULL, 0);
   if (!vcos_verify(st == VCOS_SUCCESS))
      goto end;

   flags |= VCOS_INIT_MAIN_SEM;

   vcos_thread_main.thread = pthread_self();

   pst = pthread_setspecific(_vcos_thread_current_key, &vcos_thread_main);
   if (!vcos_verify(pst == 0))
   {
      st = VCOS_EINVAL;
      goto end;
   }

   st = vcos_msgq_init();
   if (!vcos_verify(st == VCOS_SUCCESS))
      goto end;

   flags |= VCOS_INIT_MSGQ;

   vcos_logging_init();

end:
   if (st != VCOS_SUCCESS)
      vcos_term(flags);

   return st;
}
예제 #26
0
static void __inline local_mutex_create(LOCAL_MUTEX_T *mutex)
{
   vcos_mutex_create(&mutex->mutex, "vchiq");
}
예제 #27
0
파일: ilcore.c 프로젝트: DSkywalk/RetroArch
/* Atomic creation of lock protecting shared state */
static void initOnce(void)
{
   VCOS_STATUS_T status;
   status = vcos_mutex_create(&lock, VCOS_FUNCTION);
   vcos_demand(status == VCOS_SUCCESS);
}
예제 #28
0
void vc_vchi_dispmanx_init (VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ) {
   VCOS_STATUS_T status;
   int32_t success;
   uint32_t i;

   // record the number of connections
   memset( &dispmanx_client, 0, sizeof(DISPMANX_SERVICE_T) );
   dispmanx_client.num_connections = num_connections;

   status = vcos_mutex_create(&dispmanx_client.lock, "HDispmanx");
   vcos_assert(status == VCOS_SUCCESS);

   status = vcos_event_create(&dispmanx_message_available_event, "HDispmanx");
   vcos_assert(status == VCOS_SUCCESS);

   status = vcos_event_create(&dispmanx_notify_available_event, "HDispmanx");
   vcos_assert(status == VCOS_SUCCESS);

   dispmanx_client.initialised = 1;

   for (i=0; i<dispmanx_client.num_connections; i++) {

      VCOS_THREAD_ATTR_T attrs;

      // Create a 'Client' service on the each of the connections
      SERVICE_CREATION_T dispmanx_parameters = { DISPMANX_CLIENT_NAME,     // 4cc service code
                                                 connections[i],           // passed in fn ptrs
                                                 0,                        // tx fifo size (unused)
                                                 0,                        // tx fifo size (unused)
                                                 &dispmanx_client_callback, // service callback
                                                 &dispmanx_message_available_event,  // callback parameter
                                                 VC_FALSE,                  // want_unaligned_bulk_rx
                                                 VC_FALSE,                  // want_unaligned_bulk_tx
                                                 VC_FALSE,                  // want_crc
                                                 };

      SERVICE_CREATION_T dispmanx_parameters2 = { DISPMANX_NOTIFY_NAME,   // 4cc service code
                                                  connections[i],           // passed in fn ptrs
                                                  0,                        // tx fifo size (unused)
                                                  0,                        // tx fifo size (unused)
                                                  &dispmanx_notify_callback, // service callback
                                                  &dispmanx_notify_available_event,  // callback parameter
                                                  VC_FALSE,                  // want_unaligned_bulk_rx
                                                  VC_FALSE,                  // want_unaligned_bulk_tx
                                                  VC_FALSE,                  // want_crc
                                                   };

      success = vchi_service_open( initialise_instance, &dispmanx_parameters, &dispmanx_client.client_handle[i] );
      vcos_assert( success == 0 );

      // Create the async service of dispman to handle update callback

      success = vchi_service_open( initialise_instance, &dispmanx_parameters2, &dispmanx_client.notify_handle[i] );
      vcos_assert( success == 0 );

      //Create the notifier task
      vcos_thread_attr_init(&attrs);
      vcos_thread_attr_setstacksize(&attrs, 2048);
      vcos_thread_attr_settimeslice(&attrs, 1);

      status = vcos_thread_create(&dispmanx_notify_task, "HDispmanx Notify", &attrs, dispmanx_notify_func, NULL);
      vcos_assert(status == VCOS_SUCCESS);

      // release services until they're actually used
      vchi_service_release(dispmanx_client.client_handle[i]);
      vchi_service_release(dispmanx_client.notify_handle[i]);
   }
}
예제 #29
0
MMAL_STATUS_T mmal_vc_init(void)
{
   VCHIQ_SERVICE_PARAMS_T vchiq_params;
   MMAL_BOOL_T vchiq_initialised = 0, waitpool_initialised = 0;
   MMAL_BOOL_T service_initialised = 0;
   MMAL_STATUS_T status = MMAL_EIO;
   VCHIQ_STATUS_T vchiq_status;
   int count;

   vcos_once(&once, init_once);

   vcos_mutex_lock(&client.lock);

   count = client.refcount++;
   if (count > 0)
   {
      /* Already initialised so nothing to do */
      vcos_mutex_unlock(&client.lock);
      return MMAL_SUCCESS;
   }

   vcos_log_register("mmalipc", VCOS_LOG_CATEGORY);

   /* Initialise a VCHIQ instance */
   vchiq_status = vchiq_initialise(&mmal_vchiq_instance);
   if (vchiq_status != VCHIQ_SUCCESS)
   {
      LOG_ERROR("failed to initialise vchiq");
      status = MMAL_EIO;
      goto error;
   }
   vchiq_initialised = 1;

   vchiq_status = vchiq_connect(mmal_vchiq_instance);
   if (vchiq_status != VCHIQ_SUCCESS)
   {
      LOG_ERROR("failed to connect to vchiq");
      status = MMAL_EIO;
      goto error;
   }

   memset(&vchiq_params,0,sizeof(vchiq_params));
   vchiq_params.fourcc = MMAL_CONTROL_FOURCC();
   vchiq_params.callback = mmal_vc_vchiq_callback;
   vchiq_params.userdata = &client;
   vchiq_params.version = WORKER_VER_MAJOR;
   vchiq_params.version_min = WORKER_VER_MINIMUM;

   vchiq_status = vchiq_open_service(mmal_vchiq_instance, &vchiq_params, &client.service);
   if (vchiq_status != VCHIQ_SUCCESS)
   {
      LOG_ERROR("could not open vchiq service");
      status = MMAL_EIO;
      goto error;
   }
   client.usecount = 1; /* usecount set to 1 by the open call. */
   service_initialised = 1;

   status = create_waitpool(&client.waitpool);
   if (status != MMAL_SUCCESS)
   {
      LOG_ERROR("could not create wait pool");
      goto error;
   }
   waitpool_initialised = 1;

   if (vcos_mutex_create(&client.bulk_lock, "mmal client bulk lock") != VCOS_SUCCESS)
   {
      LOG_ERROR("could not create bulk lock");
      status = MMAL_ENOSPC;
      goto error;
   }

   client.inited = 1;

   vcos_mutex_unlock(&client.lock);
   /* assume we're not using VC immediately.  Do this outside the lock */
   mmal_vc_release();


   return MMAL_SUCCESS;

 error:
   if (waitpool_initialised)
      destroy_waitpool(&client.waitpool);
   if (service_initialised)
   {
      client.usecount = 0;
      vchiq_close_service(client.service);
   }
   if (vchiq_initialised)
      vchiq_shutdown(mmal_vchiq_instance);
   vcos_log_unregister(VCOS_LOG_CATEGORY);
   client.refcount--;

   vcos_mutex_unlock(&client.lock);
   return status;
}