Exemple #1
0
/** Send a buffer header to a port */
static MMAL_STATUS_T splitter_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
   MMAL_COMPONENT_T *component = port->component;
   MMAL_COMPONENT_MODULE_T *module = component->priv->module;
   MMAL_PORT_T *in_port, *out_port;
   MMAL_BUFFER_HEADER_T *in;
   MMAL_STATUS_T status;
   unsigned int i;

   mmal_queue_put(port->priv->module->queue, buffer);

   if (module->error)
      return MMAL_SUCCESS; /* Just do nothing */

   /* Get input buffer header */
   in_port = component->input[0];
   in = mmal_queue_get(in_port->priv->module->queue);
   if (!in)
      return MMAL_SUCCESS; /* Nothing to do */

   for (i = 0; i < component->output_num; i++)
   {
      out_port = component->output[i];
      status = splitter_send_output(in, out_port);

      if (status != MMAL_SUCCESS && status != MMAL_EAGAIN)
         goto error;

      if (status == MMAL_SUCCESS)
         module->sent_flags |= (1<<i);
   }

   /* Check if we're done with the input buffer */
   if ((module->sent_flags & module->enabled_flags) == module->enabled_flags)
   {
      in->length = 0; /* Consume the input buffer */
      mmal_port_buffer_header_callback(in_port, in);
      module->sent_flags = 0;
      return MMAL_SUCCESS;
   }

   /* We're not done yet so put the buffer back in the queue */
   mmal_queue_put(in_port->priv->module->queue, in);
   return MMAL_SUCCESS;

 error:
   mmal_queue_put(in_port->priv->module->queue, in);

   status = mmal_event_error_send(port->component, status);
   if (status != MMAL_SUCCESS)
   {
      LOG_ERROR("unable to send an error event buffer (%i)", (int)status);
      return MMAL_SUCCESS;
   }
   module->error = 1;
   return MMAL_SUCCESS;
}
Exemple #2
0
static void output_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
    AVCodecContext *avctx = (AVCodecContext*)port->userdata;
    MMALDecodeContext *ctx = avctx->priv_data;

    mmal_queue_put(ctx->queue_decoded_frames, buffer);
}
Exemple #3
0
static void output_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
    filter_t *filter = (filter_t *)port->userdata;
    filter_sys_t *sys = filter->p_sys;
    picture_t *picture;

    if (buffer->cmd == 0) {
        vlc_mutex_lock(&sys->buffer_cond_mutex);
        if (buffer->length > 0) {
            atomic_store(&sys->started, true);
            mmal_queue_put(sys->filtered_pictures, buffer);
            picture = (picture_t *)buffer->user_data;
        } else {
            picture = (picture_t *)buffer->user_data;
            picture_Release(picture);
        }

        atomic_fetch_sub(&sys->output_in_transit, 1);
        vlc_cond_signal(&sys->buffer_cond);
        vlc_mutex_unlock(&sys->buffer_cond_mutex);
    } else if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) {
        msg_Warn(filter, "MMAL_EVENT_FORMAT_CHANGED seen but not handled");
        mmal_buffer_header_release(buffer);
    } else {
        mmal_buffer_header_release(buffer);
    }
}
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));
}
Exemple #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);
}
Exemple #6
0
CMMALRenderer::~CMMALRenderer()
{
    CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__);
    // shutdown thread
    mmal_queue_put(m_release_queue, &m_quit_packet);
    m_sync.Wait();
    mmal_queue_destroy(m_release_queue);
    UnInit();
}
Exemple #7
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);
}
/** Buffer sending */
static MMAL_STATUS_T sdl_port_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
   MMAL_COMPONENT_T *component = port->component;
   MMAL_COMPONENT_MODULE_T *module = component->priv->module;

   mmal_queue_put(module->queue, buffer);
   mmal_component_action_trigger(port->component);

   return MMAL_SUCCESS;
}
Exemple #9
0
/** Callback from an output port. Buffer is queued for the next component. */
static void mmal_connection_bh_out_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
   MMAL_CONNECTION_T *connection = (MMAL_CONNECTION_T *)port->userdata;
   MMAL_PARAM_UNUSED(port);
   LOG_TRACE("(%s)%p,%p,%p,%i", port->name, port, buffer, buffer->data, (int)buffer->length);

   /* Queue the buffer produced by the output port */
   mmal_queue_put(connection->queue, buffer);

   if (connection->callback)
      connection->callback(connection);
}
Exemple #10
0
static MMAL_STATUS_T mmal_port_clock_send(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
   MMAL_PORT_MODULE_T *module = port->priv->module;

   if (buffer->length)
      return mmal_port_clock_process_buffer(port, buffer);

   /* Queue empty buffers to be used later when forwarding clock updates */
   mmal_queue_put(module->queue, buffer);

   return MMAL_SUCCESS;
}
Exemple #11
0
/** Callback from the pool. Buffer is available. */
static MMAL_BOOL_T mmal_connection_bh_release_cb(MMAL_POOL_T *pool, MMAL_BUFFER_HEADER_T *buffer,
   void *userdata)
{
   MMAL_CONNECTION_T *connection = (MMAL_CONNECTION_T *)userdata;
   MMAL_PARAM_UNUSED(pool);

   mmal_queue_put(pool->queue, buffer);

   if (connection->callback)
      connection->callback(connection);

   return 0;
}
/**
 * MMAL Callback from camera preview output port.
 * @param port The camera preview port.
 * @param buf The new preview buffer.
 **/
static void preview_output_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buf)
{
	RASPITEX_STATE *state = (RASPITEX_STATE*) port->userdata;

	if (buf->length == 0)
		{
		vcos_log_trace("%s: zero-length buffer => EOS", port->name);
		state->preview_stop = 1;
		mmal_buffer_header_release(buf);
		}
	else if (buf->data == NULL)
		{
		vcos_log_trace("%s: zero buffer handle", port->name);
		mmal_buffer_header_release(buf);
		}
	else
		{
		/* Enqueue the preview frame for rendering and return to
		* avoid blocking MMAL core.
		*/
		//mmal_queue_put(state->preview_queue, buf);
		
		//to handle the user not reading frames, remove and return any pre-existing ones
		if(mmal_queue_length( state->preview_queue ) >= 2)
			{
			//fprintf(stderr, "mmal_queue_length too long\n" );
			
			MMAL_BUFFER_HEADER_T *existing_buffer = mmal_queue_get( state->preview_queue );
			
			if(existing_buffer)
				{
				mmal_buffer_header_release(existing_buffer);
				
				if (port->is_enabled)
					{
					fill_port_buffer_simple( port, state->preview_pool, "preview_output_cb" );
					}	// if (port->is_enabled)
				
				}	// if(existing_buffer)
			}
		
		//add the buffer to the output queue
		mmal_queue_put(state->preview_queue, buf );
		}
}
Exemple #13
0
void CMMALRenderer::vout_input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
    CMMALVideoBuffer *omvb = (CMMALVideoBuffer *)buffer->user_data;

#if defined(MMAL_DEBUG_VERBOSE)
    CLog::Log(LOGDEBUG, "%s::%s port:%p buffer %p (%p), len %d cmd:%x", CLASSNAME, __func__, port, buffer, omvb, buffer->length, buffer->cmd);
#endif

    if (m_format == RENDER_FMT_MMAL)
    {
        mmal_queue_put(m_release_queue, buffer);
    }
    else if (m_format == RENDER_FMT_YUV420P)
    {
        mmal_buffer_header_release(buffer);
    }
    else assert(0);
}
Exemple #14
0
static void output_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
    decoder_t *dec = (decoder_t *)port->userdata;
    decoder_sys_t *sys = dec->p_sys;
    picture_t *picture;
    MMAL_EVENT_FORMAT_CHANGED_T *fmt;
    MMAL_ES_FORMAT_T *format;

    if (buffer->cmd == 0) {
        if (buffer->length > 0) {
            mmal_queue_put(sys->decoded_pictures, buffer);
        } else {
            picture = (picture_t *)buffer->user_data;
            picture_Release(picture);
            if (sys->output_pool) {
                buffer->user_data = NULL;
                buffer->alloc_size = 0;
                buffer->data = NULL;
                mmal_buffer_header_release(buffer);
            }
        }
        atomic_fetch_sub(&sys->output_in_transit, 1);
        vlc_sem_post(&sys->sem);
    } else if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) {
        fmt = mmal_event_format_changed_get(buffer);

        format = mmal_format_alloc();
        mmal_format_full_copy(format, fmt->format);

        if (sys->opaque)
            format->encoding = MMAL_ENCODING_OPAQUE;

        sys->output_format = format;

        mmal_buffer_header_release(buffer);
    } else {
        mmal_buffer_header_release(buffer);
    }
}
Exemple #15
0
/**
 * MMAL Callback from camera preview output port.
 * @param port The camera preview port.
 * @param buf The new preview buffer.
 **/
static void preview_output_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buf)
{
    RASPITEX_STATE *state = (RASPITEX_STATE*) port->userdata;

    if (buf->length == 0)
    {
        vcos_log_trace("%s: zero-length buffer => EOS", port->name);
        state->preview_stop = 1;
        mmal_buffer_header_release(buf);
    }
    else if (buf->data == NULL)
    {
        vcos_log_trace("%s: zero buffer handle", port->name);
        mmal_buffer_header_release(buf);
    }
    else
    {
        /* Enqueue the preview frame for rendering and return to
         * avoid blocking MMAL core.
         */
        mmal_queue_put(state->preview_queue, buf);
    }
}
Exemple #16
0
void CMMALRenderer::RenderUpdate(bool clear, DWORD flags, DWORD alpha)
{
  CSingleLock lock(m_sharedSection);
  int source = m_iYV12RenderBuffer;
  CMMALBuffer *omvb = nullptr;

  if (!m_bConfigured)
  {
    if (g_advancedSettings.CanLogComponent(LOGVIDEO))
      CLog::Log(LOGDEBUG, "%s::%s - not configured: clear:%d flags:%x alpha:%d source:%d", CLASSNAME, __func__, clear, flags, alpha, source);
    goto exit;
  }

  if (m_format == RENDER_FMT_MMAL)
    omvb = m_buffers[source];

  // we only want to upload frames once
  if (omvb && omvb->mmal_buffer && omvb->mmal_buffer->flags & MMAL_BUFFER_HEADER_FLAG_USER1)
  {
    if (g_advancedSettings.CanLogComponent(LOGVIDEO))
      CLog::Log(LOGDEBUG, "%s::%s - MMAL: clear:%d flags:%x alpha:%d source:%d omvb:%p mmal:%p mflags:%x skipping", CLASSNAME, __func__, clear, flags, alpha, source, omvb, omvb->mmal_buffer, omvb->mmal_buffer->flags);
    goto exit;
  }

  ManageRenderArea();

  if (m_format != RENDER_FMT_MMAL)
  {
    if (g_advancedSettings.CanLogComponent(LOGVIDEO))
      CLog::Log(LOGDEBUG, "%s::%s - bypass: clear:%d flags:%x alpha:%d source:%d format:%d", CLASSNAME, __func__, clear, flags, alpha, source, m_format);
    goto exit;
  }
  SetVideoRect(m_sourceRect, m_destRect);

  if (omvb && omvb->mmal_buffer)
  {
    if (g_advancedSettings.CanLogComponent(LOGVIDEO))
      CLog::Log(LOGDEBUG, "%s::%s - MMAL: clear:%d flags:%x alpha:%d source:%d omvb:%p mmal:%p mflags:%x", CLASSNAME, __func__, clear, flags, alpha, source, omvb, omvb->mmal_buffer, omvb->mmal_buffer->flags);
    // check for changes in aligned sizes
    if (omvb->m_width != (uint32_t)m_vout_input->format->es->video.crop.width || omvb->m_height != (uint32_t)m_vout_input->format->es->video.crop.height ||
        omvb->m_aligned_width != m_vout_input->format->es->video.width || omvb->m_aligned_height != m_vout_input->format->es->video.height)
    {
      CLog::Log(LOGDEBUG, "%s::%s Changing dimensions from %dx%d (%dx%d) to %dx%d (%dx%d)", CLASSNAME, __func__,
          m_vout_input->format->es->video.crop.width, m_vout_input->format->es->video.crop.height, omvb->m_width, omvb->m_height,
          m_vout_input->format->es->video.width, m_vout_input->format->es->video.height, omvb->m_aligned_width, omvb->m_aligned_height);
      m_vout_input->format->es->video.width = omvb->m_aligned_width;
      m_vout_input->format->es->video.height = omvb->m_aligned_height;
      m_vout_input->format->es->video.crop.width = omvb->m_width;
      m_vout_input->format->es->video.crop.height = omvb->m_height;
      MMAL_STATUS_T status = mmal_port_format_commit(m_vout_input);
      if (status != MMAL_SUCCESS)
      {
        CLog::Log(LOGERROR, "%s::%s Failed to commit vout input format (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
        goto exit;
      }
    }
    m_inflight++;
    assert(omvb->mmal_buffer && omvb->mmal_buffer->data && omvb->mmal_buffer->length);
    omvb->Acquire();
    omvb->mmal_buffer->flags |= MMAL_BUFFER_HEADER_FLAG_USER1 | MMAL_BUFFER_HEADER_FLAG_USER2;
    omvb->mmal_buffer->user_data = omvb;
    if (m_queue && m_fps > 0.0f)
      mmal_queue_put(m_queue, omvb->mmal_buffer);
    else
      mmal_port_send_buffer(m_vout_input, omvb->mmal_buffer);
  }
  else
    CLog::Log(LOGDEBUG, "%s::%s - MMAL: No buffer to update clear:%d flags:%x alpha:%d source:%d omvb:%p mmal:%p", CLASSNAME, __func__, clear, flags, alpha, source, omvb, omvb ? omvb->mmal_buffer : nullptr);

exit:
   lock.Leave();
   g_RBP.WaitVsync();
}