static gboolean
kms_sdp_rtp_avpf_media_handler_filter_rtcp_fb_attrs (KmsSdpMediaHandler *
    handler, const GstSDPMedia * offer, GstSDPMedia * answer, GError ** error)
{
  KmsSdpRtpAvpfMediaHandler *self = KMS_SDP_RTP_AVPF_MEDIA_HANDLER (handler);
  guint i;

  for (i = 0;; i++) {
    const gchar *val;
    gchar **opts;

    val = gst_sdp_media_get_attribute_val_n (offer, SDP_MEDIA_RTCP_FB, i);

    if (val == NULL) {
      return TRUE;
    }

    opts = g_strsplit (val, " ", 0);

    if (!format_supported (answer, opts[0] /* format */ )) {
      /* Ignore rtcp-fb attribute */
      g_strfreev (opts);
      continue;
    }

    if (g_strcmp0 (opts[1] /* rtcp-fb-val */ , SDP_MEDIA_RTCP_FB_NACK) == 0
        && !self->priv->nack) {
      /* ignore rtcp-fb nack attribute */
      g_strfreev (opts);
      continue;
    }

    if (g_strcmp0 (opts[1] /* rtcp-fb-val */ , SDP_MEDIA_RTCP_FB_GOOG_REMB) == 0
        && !self->priv->remb) {
      /* ignore rtcp-fb goog-remb attribute */
      g_strfreev (opts);
      continue;
    }

    if (!supported_rtcp_fb_val (opts[1] /* rtcp-fb-val */ )) {
      /* ignore unsupported rtcp-fb attribute */
      g_strfreev (opts);
      continue;
    }

    if (gst_sdp_media_add_attribute (answer, SDP_MEDIA_RTCP_FB,
            val) != GST_SDP_OK) {
      g_set_error (error, KMS_SDP_AGENT_ERROR, SDP_AGENT_UNEXPECTED_ERROR,
          "Cannot add media attribute 'a=%s:%s'", SDP_MEDIA_RTCP_FB, val);
      g_strfreev (opts);
      return FALSE;
    }

    g_strfreev (opts);
  }

  return TRUE;
}
Exemple #2
0
HRESULT d2d_bitmap_init_memory(struct d2d_bitmap *bitmap, struct d2d_d3d_render_target *render_target,
        D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc)
{
    D3D10_SUBRESOURCE_DATA resource_data;
    D3D10_TEXTURE2D_DESC texture_desc;
    ID3D10ShaderResourceView *view;
    ID3D10Texture2D *texture;
    HRESULT hr;

    if (!format_supported(&desc->pixelFormat))
    {
        WARN("Tried to create bitmap with unsupported format {%#x / %#x}.\n",
                desc->pixelFormat.format, desc->pixelFormat.alphaMode);
        return D2DERR_UNSUPPORTED_PIXEL_FORMAT;
    }

    texture_desc.Width = size.width;
    texture_desc.Height = size.height;
    texture_desc.MipLevels = 1;
    texture_desc.ArraySize = 1;
    texture_desc.Format = desc->pixelFormat.format;
    texture_desc.SampleDesc.Count = 1;
    texture_desc.SampleDesc.Quality = 0;
    texture_desc.Usage = D3D10_USAGE_DEFAULT;
    texture_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
    texture_desc.CPUAccessFlags = 0;
    texture_desc.MiscFlags = 0;

    resource_data.pSysMem = src_data;
    resource_data.SysMemPitch = pitch;

    if (FAILED(hr = ID3D10Device_CreateTexture2D(render_target->device, &texture_desc,
            src_data ? &resource_data : NULL, &texture)))
    {
        ERR("Failed to create texture, hr %#x.\n", hr);
        return hr;
    }

    hr = ID3D10Device_CreateShaderResourceView(render_target->device, (ID3D10Resource *)texture, NULL, &view);
    ID3D10Texture2D_Release(texture);
    if (FAILED(hr))
    {
        ERR("Failed to create view, hr %#x.\n", hr);
        return hr;
    }

    d2d_bitmap_init(bitmap, render_target->factory, view, size, desc);
    ID3D10ShaderResourceView_Release(view);

    return S_OK;
}
Exemple #3
0
HRESULT d2d_bitmap_init_shared(struct d2d_bitmap *bitmap, struct d2d_d3d_render_target *render_target,
        REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc)
{
    if (IsEqualGUID(iid, &IID_ID2D1Bitmap))
    {
        struct d2d_bitmap *src_impl = unsafe_impl_from_ID2D1Bitmap(data);
        D2D1_BITMAP_PROPERTIES d;
        ID3D10Device *device;

        if (src_impl->factory != render_target->factory)
            return D2DERR_WRONG_FACTORY;

        ID3D10ShaderResourceView_GetDevice(src_impl->view, &device);
        ID3D10Device_Release(device);
        if (device != render_target->device)
            return D2DERR_UNSUPPORTED_OPERATION;

        if (!desc)
        {
            d.pixelFormat = src_impl->format;
            d.dpiX = src_impl->dpi_x;
            d.dpiY = src_impl->dpi_y;
            desc = &d;
        }

        if (!format_supported(&desc->pixelFormat))
        {
            WARN("Tried to create bitmap with unsupported format {%#x / %#x}.\n",
                    desc->pixelFormat.format, desc->pixelFormat.alphaMode);
            return D2DERR_UNSUPPORTED_PIXEL_FORMAT;
        }

        d2d_bitmap_init(bitmap, render_target->factory, src_impl->view, src_impl->pixel_size, desc);

        return S_OK;
    }

    WARN("Unhandled interface %s.\n", debugstr_guid(iid));

    return E_INVALIDARG;
}
Exemple #4
0
int
shveu_setup(
	SHVEU *veu,
	const struct ren_vid_surface *src_surface,
	const struct ren_vid_surface *dst_surface,
	shveu_rotation_t filter_control)
{
	float scale_x, scale_y;
	uint32_t temp;
	uint32_t Y, C;
	const struct veu_format_info *src_info;
	const struct veu_format_info *dst_info;
	struct ren_vid_surface local_src;
	struct ren_vid_surface local_dst;
	struct ren_vid_surface *src = &local_src;
	struct ren_vid_surface *dst = &local_dst;
	void *base_addr;

	if (!veu || !src_surface || !dst_surface) {
		debug_info("ERR: Invalid input - need src and dest");
		return -1;
	}

	src_info = fmt_info(src_surface->format);
	dst_info = fmt_info(dst_surface->format);

	dbg(__func__, __LINE__, "src_user", src_surface);
	dbg(__func__, __LINE__, "dst_user", dst_surface);

	/* scale factors */
	scale_x = (float)dst_surface->w / src_surface->w;
	scale_y = (float)dst_surface->h / src_surface->h;

	if (!format_supported(src_surface->format) || !format_supported(dst_surface->format)) {
		debug_info("ERR: Invalid surface format!");
		return -1;
	}

	/* Scaling limits */
	if (veu_is_veu2h(veu)) {
		if ((scale_x > 8.0) || (scale_y > 8.0)) {
			debug_info("ERR: Outside scaling limits!");
			return -1;
		}
	} else {
		if ((scale_x > 16.0) || (scale_y > 16.0)) {
			debug_info("ERR: Outside scaling limits!");
			return -1;
		}
	}
	if ((scale_x < 1.0/16.0) || (scale_y < 1.0/16.0)) {
		debug_info("ERR: Outside scaling limits!");
		return -1;
	}

	/* source - use a buffer the hardware can access */
	if (get_hw_surface(veu->uiomux, veu->uiores, src, src_surface) < 0) {
		debug_info("ERR: src is not accessible by hardware");
		return -1;
	}
	copy_surface(src, src_surface);

	/* destination - use a buffer the hardware can access */
	if (get_hw_surface(veu->uiomux, veu->uiores, dst, dst_surface) < 0) {
		debug_info("ERR: dest is not accessible by hardware");
		return -1;
	}

	uiomux_lock (veu->uiomux, veu->uiores);

	base_addr = veu->uio_mmio.iomem;

	/* Keep track of the requested surfaces */
	veu->src_user = *src_surface;
	veu->dst_user = *dst_surface;

	/* Keep track of the actual surfaces used */
	veu->src_hw = local_src;
	veu->dst_hw = local_dst;

	/* Software reset */
	if (read_reg(base_addr, VESTR) & 0x1)
		write_reg(base_addr, 0, VESTR);
	while (read_reg(base_addr, VESTR) & 1)
		;

	/* Clear VEU end interrupt flag */
	write_reg(base_addr, 0, VEVTR);

	/* VEU Module reset */
	write_reg(base_addr, 0x100, VBSRR);

	/* default to not using bundle mode */
	write_reg(base_addr, 0, VBSSR);

	/* source */
	Y = uiomux_all_virt_to_phys(src->py);
	C = uiomux_all_virt_to_phys(src->pc);
	write_reg(base_addr, Y, VSAYR);
	write_reg(base_addr, C, VSACR);
	write_reg(base_addr, (src->h << 16) | src->w, VESSR);
	write_reg(base_addr, size_y(src->format, src->pitch), VESWR);

	/* destination */
	Y = uiomux_all_virt_to_phys(dst->py);
	C = uiomux_all_virt_to_phys(dst->pc);

	if (filter_control & 0xFF) {
		if ((filter_control & 0xFF) == 0x10) {
			/* Horizontal Mirror (A) */
			Y += size_y(dst->format, src->w);
			C += size_y(dst->format, src->w);
		} else if ((filter_control & 0xFF) == 0x20) {
			/* Vertical Mirror (B) */
			Y += size_y(dst->format, (src->h-1) * dst->pitch);
			C += size_c(dst->format, (src->h-2) * dst->pitch);
		} else if ((filter_control & 0xFF) == 0x30) {
			/* Rotate 180 (C) */
			Y += size_y(dst->format, src->w);
			C += size_y(dst->format, src->w);
			Y += size_y(dst->format, src->h * dst->pitch);
			C += size_c(dst->format, src->h * dst->pitch);
		} else if ((filter_control & 0xFF) == 1) {
			/* Rotate 90 (D) */
			Y += size_y(dst->format, src->h-16);
			C += size_y(dst->format, src->h-16);
		} else if ((filter_control & 0xFF) == 2) {
			/* Rotate 270 (E) */
			Y += size_y(dst->format, (src->w-16) * dst->pitch);
			C += size_c(dst->format, (src->w-16) * dst->pitch);
		} else if ((filter_control & 0xFF) == 0x11) {
			/* Rotate 90 & Mirror Horizontal (F) */
			/* Nothing to do */
		} else if ((filter_control & 0xFF) == 0x21) {
			/* Rotate 90 & Mirror Vertical (G) */
			Y += size_y(dst->format, src->h-16);
			C += size_y(dst->format, src->h-16);
			Y += size_y(dst->format, (src->w-16) * dst->pitch);
			C += size_c(dst->format, (src->w-16) * dst->pitch);
		}
	}
	write_reg(base_addr, Y, VDAYR);
	write_reg(base_addr, C, VDACR);
	write_reg(base_addr, size_y(dst->format, dst->pitch), VEDWR);

	/* byte/word swapping */
	temp = 0;
#ifdef __LITTLE_ENDIAN__
	temp |= src_info->vswpr;
	temp |= dst_info->vswpr << 4;
#endif
	write_reg(base_addr, temp, VSWPR);

	/* transform control */
	temp = src_info->vtrcr_src;
	temp |= dst_info->vtrcr_dst;
	if (is_rgb(src_surface->format))
		temp |= VTRCR_RY_SRC_RGB;
	if (different_colorspace(src_surface->format, dst_surface->format))
		temp |= VTRCR_TE_BIT_SET;
	if (veu->bt709)
		temp |= VTRCR_BT709;
	if (veu->full_range)
		temp |= VTRCR_FULL_COLOR_CONV;
	write_reg(base_addr, temp, VTRCR);

	if (veu_is_veu2h(veu)) {
		/* color conversion matrix */
		write_reg(base_addr, 0x0cc5, VMCR00);
		write_reg(base_addr, 0x0950, VMCR01);
		write_reg(base_addr, 0x0000, VMCR02);
		write_reg(base_addr, 0x397f, VMCR10);
		write_reg(base_addr, 0x0950, VMCR11);
		write_reg(base_addr, 0x3cdd, VMCR12);
		write_reg(base_addr, 0x0000, VMCR20);
		write_reg(base_addr, 0x0950, VMCR21);
		write_reg(base_addr, 0x1023, VMCR22);
		write_reg(base_addr, 0x00800010, VCOFFR);
	}

	/* Clipping */
	write_reg(base_addr, 0, VRFSR);
	set_clip(base_addr, 0, dst->w);
	set_clip(base_addr, 1, dst->h);

	/* Scaling */
	write_reg(base_addr, 0, VRFCR);
	if (!(filter_control & 0x3)) {
		/* Not a rotate operation */
		set_scale(veu, base_addr, 0, src->w, dst->w, 0);
		set_scale(veu, base_addr, 1, src->h, dst->h, 0);
	}

	/* Filter control - directly pass user arg to register */
	write_reg(base_addr, filter_control, VFMCR);

	return 0;

fail:
	uiomux_unlock(veu->uiomux, veu->uiores);
	return -1;
}