Beispiel #1
0
/* ...buffer completion hook (tbd - need that at all?) */
static void __objdet_buffer_release(void *cdata, void *cookie)
{
    GstBuffer      *buffer = cookie;

    TRACE(DEBUG, _b("buffer %p released by engine (count=%d)"), buffer, GST_MINI_OBJECT_REFCOUNT(buffer));

    /* ...release buffer handle */
    gst_buffer_unref(buffer);
}
Beispiel #2
0
/* ...process new input buffer submitted from camera */
static int objdet_input_process(void *data, int i, GstBuffer *buffer)
{
    app_data_t         *app = data;

    TRACE(DEBUG, _b("front-camera: input buffer received (%p, count=%d)"), buffer, GST_MINI_OBJECT_REFCOUNT(buffer));

    /* ...get internal data access lock */
    pthread_mutex_lock(&app->lock);

    /* ...bail out if playback is stopped */
    if ((app->flags & APP_FLAG_EOS) == 0)
    {
        vsink_meta_t       *vmeta = gst_buffer_get_vsink_meta(buffer);
        objdet_meta_t      *ometa = gst_buffer_get_objdet_meta(buffer);

        /* ...attach current vehicle status info to the buffer */
        memcpy(&ometa->info, &app->vehicle, sizeof(vehicle_info_t));

        /* ...release internal data access lock */
        pthread_mutex_unlock(&app->lock);

        /* ...serialize access to the object-detection engine */
        pthread_mutex_lock(&app->access);

        /* ...submit buffer to a processing engine */
        if (objdet_engine_push_buffer(app->od, buffer, vmeta->plane[0], &ometa->info, &ometa->scene, ometa->buf) < 0)
        {
            /* ...silently ignore the error */
            TRACE(ERROR, _x("failed to submit a buffer to detection engine: %m"));
        }
        else
        {
            /* ...buffer submitted successfully; take ownership */
            gst_buffer_ref(buffer);
        }

        /* ...release object-detection engine access lock */
        pthread_mutex_unlock(&app->access);
    }
    else
    {
        /* ...object detection visualization is disabled */
        pthread_mutex_unlock(&app->lock);
    }

    return 0;
}
/* Function for sent each encoder instance to be process after collect the buffers in the sink pads */
GstFlowReturn
gst_tidmai_base_video_dualencoder_entry_buffers_collected (GstCollectPads * pads, GstTIDmaiBaseVideoDualEncoder * video_dualencoder) {
	
	
	
	GST_DEBUG_OBJECT (video_dualencoder, "Entry gst_tidmai_base_video_dualencoder_entry_buffers_collected");
	
	GstTIDmaiBaseDualEncoder *base_dualencoder = GST_TI_DMAI_BASE_DUALENCODER(video_dualencoder);
	GstFlowReturn ret;
	GstBuffer *low_res_buffer;
	GstBuffer *high_res_buffer;
	
	/* Obtain the buffers */
	low_res_buffer = gst_collect_pads_pop (base_dualencoder->collect_sink_pads, 
									base_dualencoder->low_resolution_encoder->collect);
	high_res_buffer = gst_collect_pads_pop (base_dualencoder->collect_sink_pads, 
									base_dualencoder->high_resolution_encoder->collect);
	
	/* Process for the low resolution instance */
	GST_DEBUG_OBJECT (video_dualencoder, "Process low resolution instance");
	ret = gst_tidmai_base_video_dualencoder_realize_instance(video_dualencoder, 
			base_dualencoder->low_resolution_encoder, low_res_buffer);
	
	/* Process for the high resolution instance */
	GST_DEBUG_OBJECT (video_dualencoder, "Process high resolution instance");
	ret = gst_tidmai_base_video_dualencoder_realize_instance(video_dualencoder, 
			base_dualencoder->high_resolution_encoder, high_res_buffer);
			
	/* unref the buffer with the high-resolution for being reuse for the driver */
	gst_buffer_unref(high_res_buffer);
	if(1 == GST_MINI_OBJECT_REFCOUNT(high_res_buffer)) {
		gst_buffer_unref(high_res_buffer);
	}
      	
	GST_DEBUG_OBJECT (video_dualencoder, "Leave gst_tidmai_base_video_dualencoder_entry_buffers_collected");
	
	return ret;
	
}
/**
 * gst_v4l2_buffer_pool_dqbuf:
 * @pool: the pool
 *
 * Dequeue a buffer from the driver.  Some generic error handling is done in
 * this function, but any error handling specific to v4l2src (capture) or
 * v4l2sink (output) can be done outside this function by checking 'errno'
 *
 * Returns: a buffer
 */
GstV4l2Buffer *
gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool)
{
  GstV4l2Object *v4l2object = get_v4l2_object (pool->v4l2elem);
  GstV4l2Buffer *pool_buffer;
  struct v4l2_buffer buffer;

  memset (&buffer, 0x00, sizeof (buffer));
  buffer.type = pool->type;
  buffer.memory = V4L2_MEMORY_MMAP;


  if (v4l2_ioctl (pool->video_fd, VIDIOC_DQBUF, &buffer) >= 0) {

    GST_V4L2_BUFFER_POOL_LOCK (pool);

    /* get our GstBuffer with that index from the pool, if the buffer was
     * outstanding we have a serious problem.
     */
    pool_buffer = pool->buffers[buffer.index];

    if (pool_buffer == NULL) {
      GST_ELEMENT_ERROR (pool->v4l2elem, RESOURCE, FAILED,
          (_("Failed trying to get video frames from device '%s'."),
              v4l2object->videodev),
          (_("No free buffers found in the pool at index %d."), buffer.index));
      GST_V4L2_BUFFER_POOL_UNLOCK (pool);
      return NULL;
    }

    GST_LOG_OBJECT (pool->v4l2elem,
        "grabbed frame %d (ix=%d), flags %08x, pool-ct=%d, buffer=%p",
        buffer.sequence, buffer.index, buffer.flags, pool->num_live_buffers,
        pool_buffer);

    pool->num_live_buffers++;
    GST_DEBUG_OBJECT (pool->v4l2elem, "num_live_buffers++: %d",
        pool->num_live_buffers);

    /* set top/bottom field first if v4l2_buffer has the information */
    if (buffer.field == V4L2_FIELD_INTERLACED_TB)
      GST_BUFFER_FLAG_SET (pool_buffer, GST_VIDEO_BUFFER_TFF);
    if (buffer.field == V4L2_FIELD_INTERLACED_BT)
      GST_BUFFER_FLAG_UNSET (pool_buffer, GST_VIDEO_BUFFER_TFF);

    /* this can change at every frame, esp. with jpeg */
    GST_BUFFER_SIZE (pool_buffer) = buffer.bytesused;

    GST_V4L2_BUFFER_POOL_UNLOCK (pool);

    return pool_buffer;
  }


  GST_WARNING_OBJECT (pool->v4l2elem,
      "problem grabbing frame %d (ix=%d), pool-ct=%d, buf.flags=%d",
      buffer.sequence, buffer.index,
      GST_MINI_OBJECT_REFCOUNT (pool), buffer.flags);

  switch (errno) {
    case EAGAIN:
      GST_WARNING_OBJECT (pool->v4l2elem,
          "Non-blocking I/O has been selected using O_NONBLOCK and"
          " no buffer was in the outgoing queue. device %s",
          v4l2object->videodev);
      break;
    case EINVAL:
      GST_ELEMENT_ERROR (pool->v4l2elem, RESOURCE, FAILED,
          (_("Failed trying to get video frames from device '%s'."),
              v4l2object->videodev),
          (_("The buffer type is not supported, or the index is out of bounds,"
                  " or no buffers have been allocated yet, or the userptr"
                  " or length are invalid. device %s"), v4l2object->videodev));
      break;
    case ENOMEM:
      GST_ELEMENT_ERROR (pool->v4l2elem, RESOURCE, FAILED,
          (_("Failed trying to get video frames from device '%s'. Not enough memory."), v4l2object->videodev), (_("insufficient memory to enqueue a user pointer buffer. device %s."), v4l2object->videodev));
      break;
    case EIO:
      GST_INFO_OBJECT (pool->v4l2elem,
          "VIDIOC_DQBUF failed due to an internal error."
          " Can also indicate temporary problems like signal loss."
          " Note the driver might dequeue an (empty) buffer despite"
          " returning an error, or even stop capturing."
          " device %s", v4l2object->videodev);
      /* have we de-queued a buffer ? */
      if (!(buffer.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))) {
        GST_DEBUG_OBJECT (pool->v4l2elem, "reenqueing buffer");
        /* FIXME ... should we do something here? */
      }
      break;
    case EINTR:
      GST_WARNING_OBJECT (pool->v4l2elem,
          "could not sync on a buffer on device %s", v4l2object->videodev);
      break;
    default:
      GST_WARNING_OBJECT (pool->v4l2elem,
          "Grabbing frame got interrupted on %s unexpectedly. %d: %s.",
          v4l2object->videodev, errno, g_strerror (errno));
      break;
  }

  return NULL;
}
Beispiel #5
0
static GstFlowReturn
gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer)
{
  GstFlowReturn res;
  GstBuffer *outbuf;
  struct v4l2_buffer vbuffer;
  GstV4l2Object *obj = pool->obj;
  GstClockTime timestamp;

  if (obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
    /* select works for input devices when data is available. According to the
     * specs we can also poll to find out when a frame has been displayed but
     * that just seems to lock up here */
    if ((res = gst_v4l2_object_poll (obj)) != GST_FLOW_OK)
      goto poll_error;
  }

  memset (&vbuffer, 0x00, sizeof (vbuffer));
  vbuffer.type = obj->type;
  vbuffer.memory = V4L2_MEMORY_MMAP;

  GST_LOG_OBJECT (pool, "doing DQBUF");
  if (v4l2_ioctl (pool->video_fd, VIDIOC_DQBUF, &vbuffer) < 0)
    goto error;

  /* get our GstBuffer with that index from the pool, if the buffer was
   * outstanding we have a serious problem.
   */
  outbuf = pool->buffers[vbuffer.index];
  if (outbuf == NULL)
    goto no_buffer;

  /* mark the buffer outstanding */
  pool->buffers[vbuffer.index] = NULL;
  pool->num_queued--;

  timestamp = GST_TIMEVAL_TO_TIME (vbuffer.timestamp);

  GST_LOG_OBJECT (pool,
      "dequeued buffer %p seq:%d (ix=%d), used %d, flags %08x, ts %"
      GST_TIME_FORMAT ", pool-queued=%d, buffer=%p", outbuf, vbuffer.sequence,
      vbuffer.index, vbuffer.bytesused, vbuffer.flags,
      GST_TIME_ARGS (timestamp), pool->num_queued, outbuf);

  /* set top/bottom field first if v4l2_buffer has the information */
  if (vbuffer.field == V4L2_FIELD_INTERLACED_TB) {
    GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
  }
  if (vbuffer.field == V4L2_FIELD_INTERLACED_BT) {
    GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
  }

  /* this can change at every frame, esp. with jpeg */
  if (obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
    gst_buffer_resize (outbuf, 0, vbuffer.bytesused);
  else
    gst_buffer_resize (outbuf, 0, vbuffer.length);

  GST_BUFFER_TIMESTAMP (outbuf) = timestamp;

  *buffer = outbuf;

  return GST_FLOW_OK;

  /* ERRORS */
poll_error:
  {
    GST_DEBUG_OBJECT (pool, "poll error %s", gst_flow_get_name (res));
    return res;
  }
error:
  {
    GST_WARNING_OBJECT (pool,
        "problem dequeuing frame %d (ix=%d), pool-ct=%d, buf.flags=%d",
        vbuffer.sequence, vbuffer.index,
        GST_MINI_OBJECT_REFCOUNT (pool), vbuffer.flags);

    switch (errno) {
      case EAGAIN:
        GST_WARNING_OBJECT (pool,
            "Non-blocking I/O has been selected using O_NONBLOCK and"
            " no buffer was in the outgoing queue. device %s", obj->videodev);
        break;
      case EINVAL:
        GST_ERROR_OBJECT (pool,
            "The buffer type is not supported, or the index is out of bounds, "
            "or no buffers have been allocated yet, or the userptr "
            "or length are invalid. device %s", obj->videodev);
        break;
      case ENOMEM:
        GST_ERROR_OBJECT (pool,
            "insufficient memory to enqueue a user pointer buffer");
        break;
      case EIO:
        GST_INFO_OBJECT (pool,
            "VIDIOC_DQBUF failed due to an internal error."
            " Can also indicate temporary problems like signal loss."
            " Note the driver might dequeue an (empty) buffer despite"
            " returning an error, or even stop capturing."
            " device %s", obj->videodev);
        /* have we de-queued a buffer ? */
        if (!(vbuffer.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))) {
          GST_DEBUG_OBJECT (pool, "reenqueing buffer");
          /* FIXME ... should we do something here? */
        }
        break;
      case EINTR:
        GST_WARNING_OBJECT (pool,
            "could not sync on a buffer on device %s", obj->videodev);
        break;
      default:
        GST_WARNING_OBJECT (pool,
            "Grabbing frame got interrupted on %s unexpectedly. %d: %s.",
            obj->videodev, errno, g_strerror (errno));
        break;
    }
    return GST_FLOW_ERROR;
  }
no_buffer:
  {
    GST_ERROR_OBJECT (pool, "No free buffer found in the pool at index %d.",
        vbuffer.index);
    return GST_FLOW_ERROR;
  }
}