Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions core/src/graphics/yuv_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ impl YuvPipeline {
// For R8Unorm textures, bytes_per_row = texture_width (1 byte per pixel).
// So we align the texture width to 256.
let y_tex_w = align_to(width, 256);
let uv_tex_w = align_to(width / 2, 256);
let uv_tex_w = align_to(width.div_ceil(2), 256);
let uv_h = height.div_ceil(2);

let y_tex = device.create_texture(&wgpu::TextureDescriptor {
label: Some("YUV Y texture"),
Expand All @@ -136,7 +137,7 @@ impl YuvPipeline {
label: Some("YUV U texture"),
size: wgpu::Extent3d {
width: uv_tex_w,
height: height / 2,
height: uv_h,
depth_or_array_layers: 1,
},
mip_level_count: 1,
Expand All @@ -151,7 +152,7 @@ impl YuvPipeline {
label: Some("YUV V texture"),
size: wgpu::Extent3d {
width: uv_tex_w,
height: height / 2,
height: uv_h,
depth_or_array_layers: 1,
},
mip_level_count: 1,
Expand Down Expand Up @@ -241,8 +242,8 @@ impl YuvPipeline {
};

let y_tex_w = align_to(frame.width, 256);
let uv_tex_w = align_to(frame.width / 2, 256);
let uv_h = frame.height / 2;
let uv_tex_w = align_to(frame.width.div_ceil(2), 256);
let uv_h = frame.height.div_ceil(2);

let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("YUV upload encoder"),
Expand Down
4 changes: 2 additions & 2 deletions core/src/livekit/video.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl VideoBuffer {

// GPU-aligned strides (wgpu requires bytes_per_row multiple of 256)
let y_stride = align_to(width, 256);
let uv_stride = align_to(width / 2, 256);
let uv_stride = align_to(width.div_ceil(2), 256);
self.stride_y = y_stride;
self.stride_u = uv_stride;
self.stride_v = uv_stride;
Expand All @@ -67,7 +67,7 @@ impl VideoBuffer {
.copy_from_slice(&dy[src_start..src_start + width as usize]);
}

let uv_w = (width / 2) as usize;
let uv_w = width.div_ceil(2) as usize;
for row in 0..chroma_height as usize {
let src_start = row * src_stride_u as usize;
let dst_start = row * uv_stride as usize;
Expand Down
2 changes: 2 additions & 0 deletions web-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
"@livekit/components-react": "^2.9.17",
"@livekit/components-styles": "^1.2.0",
"@radix-ui/react-dialog": "1.1.15",
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-label": "^2.1.8",
"@radix-ui/react-popover": "1.1.15",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-switch": "^1.2.6",
Expand Down
146 changes: 146 additions & 0 deletions web-app/src/components/ui/select.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import * as React from "react";
import * as SelectPrimitive from "@radix-ui/react-select";
import { cn } from "@/lib/utils";
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "@radix-ui/react-icons";
import clsx from "clsx";

const Select = SelectPrimitive.Root;

const SelectGroup = SelectPrimitive.Group;

const SelectValue = SelectPrimitive.Value;

const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> & { iconClassName?: string }
>(({ className, children, iconClassName = "", ...props }, ref) => (
<SelectPrimitive.Trigger
ref={ref}
className={cn(
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-slate-400 dark:border-slate-200 bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-white data-[placeholder]:text-slate-500 focus:outline-none focus:ring-1 focus:ring-slate-950 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1 dark:border-slate-500 dark:ring-offset-slate-950 dark:data-[placeholder]:text-slate-400 dark:focus:ring-slate-300",
className,
)}
{...props}
>
{children}
<SelectPrimitive.Icon asChild>
<ChevronDownIcon className={clsx("size-4 opacity-70", iconClassName)} />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
));
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;

const SelectScrollUpButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollUpButton
ref={ref}
className={cn("flex cursor-default items-center justify-center py-1", className)}
{...props}
>
<ChevronUpIcon className="h-4 w-4" />
</SelectPrimitive.ScrollUpButton>
));
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;

const SelectScrollDownButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollDownButton
ref={ref}
className={cn("flex cursor-default items-center justify-center py-1", className)}
{...props}
>
<ChevronDownIcon className="h-4 w-4" />
</SelectPrimitive.ScrollDownButton>
));
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;

const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
>(({ className, children, position = "popper", ...props }, ref) => (
<SelectPrimitive.Portal>
<SelectPrimitive.Content
ref={ref}
className={cn(
"relative z-50 max-h-[var(--radix-select-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border border-slate-200 bg-white text-slate-950 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[var(--radix-select-content-transform-origin)] dark:border-slate-800 dark:bg-slate-600 dark:text-slate-50",
position === "popper" &&
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
className,
)}
position={position}
{...props}
>
<SelectScrollUpButton />
<SelectPrimitive.Viewport
className={cn(
"p-1",
position === "popper" &&
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]",
)}
>
{children}
</SelectPrimitive.Viewport>
<SelectScrollDownButton />
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
));
SelectContent.displayName = SelectPrimitive.Content.displayName;

const SelectLabel = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Label ref={ref} className={cn("px-2 py-1.5 text-sm font-semibold", className)} {...props} />
));
SelectLabel.displayName = SelectPrimitive.Label.displayName;

const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Item
ref={ref}
className={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-slate-100 focus:text-slate-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-slate-800 dark:focus:text-slate-50",
className,
)}
{...props}
>
<span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<CheckIcon className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
));
SelectItem.displayName = SelectPrimitive.Item.displayName;

const SelectSeparator = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Separator
ref={ref}
className={cn("-mx-1 my-1 h-px bg-slate-100 dark:bg-slate-800", className)}
{...props}
/>
));
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;

export {
Select,
SelectGroup,
SelectValue,
SelectTrigger,
SelectContent,
SelectLabel,
SelectItem,
SelectSeparator,
SelectScrollUpButton,
SelectScrollDownButton,
};
Loading
Loading