Пример #1
0
static gboolean
gst_mir_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
{
    GstMirSink *sink = GST_MIR_SINK (bsink);
    GstBufferPool *pool;
    GstStructure *config;
    GstCaps *caps;
    guint size = 0;
    gboolean need_pool;
    GstAllocator *allocator;
    GstAllocationParams params;

    GST_DEBUG_OBJECT (sink, "Proposing ALLOCATION params");

    gst_allocation_params_init (&params);

    gst_query_parse_allocation (query, &caps, &need_pool);
    if (!caps)
        goto no_caps;

    GST_OBJECT_LOCK (sink);
    pool = sink->pool ? gst_object_ref (sink->pool) : NULL;
    GST_OBJECT_UNLOCK (sink);

    GST_DEBUG_OBJECT (sink, "pool: %p, need_pool: %d", pool, need_pool);

    if (pool) {
        GstCaps *pcaps;
        GST_WARNING_OBJECT (sink, "already have a pool");

        /* We had a pool, check caps */
        config = gst_buffer_pool_get_config (pool);
        gst_buffer_pool_config_get_params (config, &pcaps, &size, NULL, NULL);

        if (!gst_caps_is_equal (caps, pcaps)) {
            /* Different caps, we can't use this pool */
            gst_object_unref (pool);
            pool = NULL;
        }
        gst_structure_free (config);
    }

    if (pool == NULL && need_pool) {
        GstVideoInfo info;
        info.size = 0;

        if (!gst_video_info_from_caps (&info, caps))
            goto invalid_caps;

        GST_DEBUG_OBJECT (sink, "size: %d", size);
        GST_DEBUG_OBJECT (sink, "caps %" GST_PTR_FORMAT, caps);
        GST_DEBUG_OBJECT (sink, "create new pool");
        pool = gst_mir_buffer_pool_new (sink);

        /* The normal size of a frame */
        size = (info.size == 0) ? info.height * info.width : info.size;

        config = gst_buffer_pool_get_config (pool);
        gst_buffer_pool_config_set_params (config, caps, size, 2, 0);
        if (!gst_buffer_pool_set_config (pool, config))
            goto config_failed;
    }

    if (pool) {
        /* We are doing hardware rendering */
        gst_mir_buffer_pool_set_hardware_rendering (pool, TRUE);

        // FIXME: How many buffers min do we need? It's 2 right now.
        GST_DEBUG_OBJECT (sink, "size: %d", size);
        GST_DEBUG_OBJECT (sink, "adding allocation pool");
        gst_query_add_allocation_pool (query, pool, size, 2, 0);
        gst_object_unref (pool);
    }

    /* First the default allocator */
    if (!gst_mir_image_memory_is_mappable ()) {
        allocator = gst_allocator_find (NULL);
        gst_query_add_allocation_param (query, allocator, &params);
        gst_object_unref (allocator);
    }

    allocator = gst_mir_image_allocator_obtain ();
    if (!gst_mir_image_memory_is_mappable ())
        params.flags |= GST_MEMORY_FLAG_NOT_MAPPABLE;
    gst_query_add_allocation_param (query, allocator, &params);
    gst_object_unref (allocator);

    //gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);

    return TRUE;

    /* ERRORS */
no_caps:
    {
        GST_DEBUG_OBJECT (bsink, "no caps specified");
        return FALSE;
    }
invalid_caps:
    {
        GST_DEBUG_OBJECT (bsink, "invalid caps specified");
        return FALSE;
    }
config_failed:
    {
        GST_DEBUG_OBJECT (bsink, "failed setting config");
        gst_object_unref (pool);
        return FALSE;
    }
}
Пример #2
0
// FIXME: rename this function since it no longer makes sense
static GstBuffer *
gst_mir_allocate_native_window_buffer (GstBufferPool * pool,
    GstAllocator * allocator, GstBufferPoolAcquireParams * params,
    GstVideoFormat format, gint width, gint height)
{
  GstMirBufferPool *m_pool = GST_MIR_BUFFER_POOL_CAST (pool);
  GstBuffer *buffer;
  GstMemory *mem = { NULL };
  gsize size = 0;
  gint stride = 0;
  GstMemoryFlags flags = 0;

  GST_DEBUG_OBJECT (pool, "%s", __PRETTY_FUNCTION__);

  if (!gst_mir_image_memory_is_mappable ())
    flags |= GST_MEMORY_FLAG_NOT_MAPPABLE;

  flags |= GST_MEMORY_FLAG_NO_SHARE;

  switch (format) {
      gsize buffer_id = 0;

    case GST_VIDEO_FORMAT_RGB:
    case GST_VIDEO_FORMAT_BGR:
    case GST_VIDEO_FORMAT_RGB16:
    case GST_VIDEO_FORMAT_NV12:
    case GST_VIDEO_FORMAT_NV21:
    case GST_VIDEO_FORMAT_RGBA:
    case GST_VIDEO_FORMAT_BGRA:
    case GST_VIDEO_FORMAT_ARGB:
    case GST_VIDEO_FORMAT_ABGR:
    case GST_VIDEO_FORMAT_RGBx:
    case GST_VIDEO_FORMAT_BGRx:
    case GST_VIDEO_FORMAT_xRGB:
    case GST_VIDEO_FORMAT_xBGR:
    case GST_VIDEO_FORMAT_AYUV:
    case GST_VIDEO_FORMAT_YV12:
    case GST_VIDEO_FORMAT_I420:
    case GST_VIDEO_FORMAT_Y444:
    case GST_VIDEO_FORMAT_Y42B:
    case GST_VIDEO_FORMAT_Y41B:{

      GST_WARNING_OBJECT (m_pool,
          "Allocating new Mir image, height: %d, width: %d, size: %d", height,
          width, size);

      /* A fallback to make sure we have a size */
      if (size == 0)
        size = height * width;

      stride = size / height;
      size = stride * height;

      GST_WARNING_OBJECT (m_pool, "stride: %d, size: %d", stride, size);

      //if (m_pool->sink->surface_texture_client) {
      buffer_id = 0;

      GST_WARNING_OBJECT (m_pool, "Allocating new buffer memory of size: %d",
          size);
      mem =
          gst_mir_image_allocator_wrap (allocator, m_pool->codec_delegate,
          buffer_id, flags, size, NULL, NULL);
      if (mem == NULL)
        GST_WARNING_OBJECT (m_pool, "mem is NULL!");
      //}

      break;
    }
    default:
      GST_WARNING_OBJECT (m_pool,
          "Using the default buffer allocator, hit the default case");
      if (GST_BUFFER_POOL_CLASS (gst_mir_buffer_pool_parent_class)->alloc_buffer
          (pool, &buffer, params) != GST_FLOW_OK)
        return NULL;
      break;
  }

  buffer = gst_buffer_new ();
  if (!buffer) {
    GST_WARNING_OBJECT (m_pool, "Fallback memory allocation");
    if (GST_BUFFER_POOL_CLASS (gst_mir_buffer_pool_parent_class)->alloc_buffer
        (pool, &buffer, params) != GST_FLOW_OK)
      return NULL;
  }

  GST_DEBUG ("Appending memory to GstBuffer");
  gst_buffer_append_memory (buffer, mem);

  return buffer;
}