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; }
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; }
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; }
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; }