Compare commits

..

No commits in common. "b0ac76b5c6c2a88b841a89efa7d8dbb658848d7d" and "0b43c15602a2151d4bffb1a5baa6e11df102e869" have entirely different histories.

2 changed files with 259 additions and 271 deletions

View File

@ -255,7 +255,6 @@ class OpenVINOModelRunner(BaseModelRunner):
def __init__(self, model_path: str, device: str, model_type: str, **kwargs): def __init__(self, model_path: str, device: str, model_type: str, **kwargs):
self.model_path = model_path self.model_path = model_path
self.device = device self.device = device
self.model_type = model_type
if device == "NPU" and not OpenVINOModelRunner.is_model_npu_supported( if device == "NPU" and not OpenVINOModelRunner.is_model_npu_supported(
model_type model_type
@ -342,13 +341,6 @@ class OpenVINOModelRunner(BaseModelRunner):
# Lock prevents concurrent access to infer_request # Lock prevents concurrent access to infer_request
# Needed for JinaV2: genai thread (text) + embeddings thread (vision) # Needed for JinaV2: genai thread (text) + embeddings thread (vision)
with self._inference_lock: with self._inference_lock:
from frigate.embeddings.types import EnrichmentModelTypeEnum
if self.model_type in [EnrichmentModelTypeEnum.arcface.value]:
# For face recognition models, create a fresh infer_request
# for each inference to avoid state pollution that causes incorrect results.
self.infer_request = self.compiled_model.create_infer_request()
# Handle single input case for backward compatibility # Handle single input case for backward compatibility
if ( if (
len(inputs) == 1 len(inputs) == 1

View File

@ -1030,298 +1030,294 @@ function FrigateCameraFeatures({
disabled={!cameraEnabled || debug || isSnapshotLoading} disabled={!cameraEnabled || debug || isSnapshotLoading}
loading={isSnapshotLoading} loading={isSnapshotLoading}
/> />
{!fullscreen && ( <DropdownMenu modal={false}>
<DropdownMenu modal={false}> <DropdownMenuTrigger>
<DropdownMenuTrigger> <div
<div className={cn(
className={cn( "flex flex-col items-center justify-center rounded-lg bg-secondary p-2 text-secondary-foreground md:p-0",
"flex flex-col items-center justify-center rounded-lg bg-secondary p-2 text-secondary-foreground md:p-0", )}
)} >
> <FaCog
<FaCog className={`text-secondary-foreground" size-5 md:m-[6px]`}
className={`text-secondary-foreground" size-5 md:m-[6px]`} />
/> </div>
</div> </DropdownMenuTrigger>
</DropdownMenuTrigger> <DropdownMenuContent className="max-w-96">
<DropdownMenuContent className="max-w-96"> <div className="flex flex-col gap-5 p-4">
<div className="flex flex-col gap-5 p-4"> {!isRestreamed && (
{!isRestreamed && ( <div className="flex flex-col gap-2">
<div className="flex flex-col gap-2"> <Label>
<Label> {t("streaming.label", { ns: "components/dialog" })}
{t("streaming.label", { ns: "components/dialog" })} </Label>
</Label> <div className="flex flex-row items-center gap-1 text-sm text-muted-foreground">
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground"> <LuX className="size-4 text-danger" />
<LuX className="size-4 text-danger" /> <div>
<div> {t("streaming.restreaming.disabled", {
{t("streaming.restreaming.disabled", { ns: "components/dialog",
})}
</div>
<Popover>
<PopoverTrigger asChild>
<div className="cursor-pointer p-0">
<LuInfo className="size-4" />
<span className="sr-only">
{t("button.info", { ns: "common" })}
</span>
</div>
</PopoverTrigger>
<PopoverContent className="w-80 text-xs">
{t("streaming.restreaming.desc.title", {
ns: "components/dialog", ns: "components/dialog",
})} })}
</div> <div className="mt-2 flex items-center text-primary">
<Popover> <Link
<PopoverTrigger asChild> to={getLocaleDocUrl("configuration/live")}
<div className="cursor-pointer p-0"> target="_blank"
<LuInfo className="size-4" /> rel="noopener noreferrer"
<span className="sr-only"> className="inline"
{t("button.info", { ns: "common" })} >
</span> {t("readTheDocumentation", { ns: "common" })}
</div> <LuExternalLink className="ml-2 inline-flex size-3" />
</PopoverTrigger> </Link>
<PopoverContent className="w-80 text-xs"> </div>
{t("streaming.restreaming.desc.title", { </PopoverContent>
ns: "components/dialog", </Popover>
})}
<div className="mt-2 flex items-center text-primary">
<Link
to={getLocaleDocUrl("configuration/live")}
target="_blank"
rel="noopener noreferrer"
className="inline"
>
{t("readTheDocumentation", { ns: "common" })}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</PopoverContent>
</Popover>
</div>
</div> </div>
)} </div>
{isRestreamed && )}
Object.values(camera.live.streams).length > 0 && ( {isRestreamed &&
<div className="flex flex-col gap-1"> Object.values(camera.live.streams).length > 0 && (
<Label htmlFor="streaming-method"> <div className="flex flex-col gap-1">
{t("stream.title")} <Label htmlFor="streaming-method">
</Label> {t("stream.title")}
<Select </Label>
value={streamName} <Select
disabled={debug} value={streamName}
onValueChange={(value) => { disabled={debug}
setStreamName?.(value); onValueChange={(value) => {
}} setStreamName?.(value);
> }}
<SelectTrigger className="w-full"> >
<SelectValue> <SelectTrigger className="w-full">
{Object.keys(camera.live.streams).find( <SelectValue>
(key) => camera.live.streams[key] === streamName, {Object.keys(camera.live.streams).find(
)} (key) => camera.live.streams[key] === streamName,
</SelectValue> )}
</SelectTrigger> </SelectValue>
</SelectTrigger>
<SelectContent> <SelectContent>
<SelectGroup> <SelectGroup>
{Object.entries(camera.live.streams).map( {Object.entries(camera.live.streams).map(
([stream, name]) => ( ([stream, name]) => (
<SelectItem <SelectItem
key={stream} key={stream}
className="cursor-pointer" className="cursor-pointer"
value={name} value={name}
> >
{stream} {stream}
</SelectItem> </SelectItem>
), ),
)} )}
</SelectGroup> </SelectGroup>
</SelectContent> </SelectContent>
</Select> </Select>
{debug && ( {debug && (
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground">
<>
<LuX className="size-8 text-danger" />
<div>{t("stream.debug.picker")}</div>
</>
</div>
)}
{preferredLiveMode != "jsmpeg" &&
!debug &&
isRestreamed && (
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground"> <div className="flex flex-row items-center gap-1 text-sm text-muted-foreground">
<> {supportsAudioOutput ? (
<LuX className="size-8 text-danger" /> <>
<div>{t("stream.debug.picker")}</div> <LuCheck className="size-4 text-success" />
</> <div>{t("stream.audio.available")}</div>
</>
) : (
<>
<LuX className="size-4 text-danger" />
<div>{t("stream.audio.unavailable")}</div>
<Popover>
<PopoverTrigger asChild>
<div className="cursor-pointer p-0">
<LuInfo className="size-4" />
<span className="sr-only">
{t("button.info", { ns: "common" })}
</span>
</div>
</PopoverTrigger>
<PopoverContent className="w-80 text-xs">
{t("stream.audio.tips.title")}
<div className="mt-2 flex items-center text-primary">
<Link
to={getLocaleDocUrl("configuration/live")}
target="_blank"
rel="noopener noreferrer"
className="inline"
>
{t("readTheDocumentation", {
ns: "common",
})}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</PopoverContent>
</Popover>
</>
)}
</div>
)}
{preferredLiveMode != "jsmpeg" &&
!debug &&
isRestreamed &&
supportsAudioOutput && (
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground">
{supports2WayTalk ? (
<>
<LuCheck className="size-4 text-success" />
<div>{t("stream.twoWayTalk.available")}</div>
</>
) : (
<>
<LuX className="size-4 text-danger" />
<div>{t("stream.twoWayTalk.unavailable")}</div>
<Popover>
<PopoverTrigger asChild>
<div className="cursor-pointer p-0">
<LuInfo className="size-4" />
<span className="sr-only">
{t("button.info", { ns: "common" })}
</span>
</div>
</PopoverTrigger>
<PopoverContent className="w-80 text-xs">
{t("stream.twoWayTalk.tips")}
<div className="mt-2 flex items-center text-primary">
<Link
to={getLocaleDocUrl(
"configuration/live/#webrtc-extra-configuration",
)}
target="_blank"
rel="noopener noreferrer"
className="inline"
>
{t("readTheDocumentation", {
ns: "common",
})}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</PopoverContent>
</Popover>
</>
)}
</div> </div>
)} )}
{preferredLiveMode != "jsmpeg" && {preferredLiveMode == "jsmpeg" &&
!debug && !debug &&
isRestreamed && ( isRestreamed && (
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground"> <div className="flex flex-col items-center gap-3">
{supportsAudioOutput ? ( <div className="flex flex-row items-center gap-2">
<> <IoIosWarning className="mr-1 size-8 text-danger" />
<LuCheck className="size-4 text-success" />
<div>{t("stream.audio.available")}</div>
</>
) : (
<>
<LuX className="size-4 text-danger" />
<div>{t("stream.audio.unavailable")}</div>
<Popover>
<PopoverTrigger asChild>
<div className="cursor-pointer p-0">
<LuInfo className="size-4" />
<span className="sr-only">
{t("button.info", { ns: "common" })}
</span>
</div>
</PopoverTrigger>
<PopoverContent className="w-80 text-xs">
{t("stream.audio.tips.title")}
<div className="mt-2 flex items-center text-primary">
<Link
to={getLocaleDocUrl(
"configuration/live",
)}
target="_blank"
rel="noopener noreferrer"
className="inline"
>
{t("readTheDocumentation", {
ns: "common",
})}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</PopoverContent>
</Popover>
</>
)}
</div>
)}
{preferredLiveMode != "jsmpeg" &&
!debug &&
isRestreamed &&
supportsAudioOutput && (
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground">
{supports2WayTalk ? (
<>
<LuCheck className="size-4 text-success" />
<div>{t("stream.twoWayTalk.available")}</div>
</>
) : (
<>
<LuX className="size-4 text-danger" />
<div>{t("stream.twoWayTalk.unavailable")}</div>
<Popover>
<PopoverTrigger asChild>
<div className="cursor-pointer p-0">
<LuInfo className="size-4" />
<span className="sr-only">
{t("button.info", { ns: "common" })}
</span>
</div>
</PopoverTrigger>
<PopoverContent className="w-80 text-xs">
{t("stream.twoWayTalk.tips")}
<div className="mt-2 flex items-center text-primary">
<Link
to={getLocaleDocUrl(
"configuration/live/#webrtc-extra-configuration",
)}
target="_blank"
rel="noopener noreferrer"
className="inline"
>
{t("readTheDocumentation", {
ns: "common",
})}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</PopoverContent>
</Popover>
</>
)}
</div>
)}
{preferredLiveMode == "jsmpeg" && <p className="text-sm">
!debug && {t("stream.lowBandwidth.tips")}
isRestreamed && ( </p>
<div className="flex flex-col items-center gap-3"> </div>
<div className="flex flex-row items-center gap-2"> <Button
<IoIosWarning className="mr-1 size-8 text-danger" /> className={`flex items-center gap-2.5 rounded-lg`}
aria-label={t("stream.lowBandwidth.resetStream")}
<p className="text-sm"> variant="outline"
{t("stream.lowBandwidth.tips")} size="sm"
</p> onClick={() => setLowBandwidth(false)}
>
<MdOutlineRestartAlt className="size-5 text-primary-variant" />
<div className="text-primary-variant">
{t("stream.lowBandwidth.resetStream")}
</div> </div>
<Button </Button>
className={`flex items-center gap-2.5 rounded-lg`} </div>
aria-label={t("stream.lowBandwidth.resetStream")} )}
variant="outline"
size="sm"
onClick={() => setLowBandwidth(false)}
>
<MdOutlineRestartAlt className="size-5 text-primary-variant" />
<div className="text-primary-variant">
{t("stream.lowBandwidth.resetStream")}
</div>
</Button>
</div>
)}
</div>
)}
{isRestreamed && (
<div className="flex flex-col gap-1">
<div className="flex items-center justify-between">
<Label
className="mx-0 cursor-pointer text-primary"
htmlFor="backgroundplay"
>
{t("stream.playInBackground.label")}
</Label>
<Switch
className="ml-1"
id="backgroundplay"
disabled={debug}
checked={playInBackground}
onCheckedChange={(checked) =>
setPlayInBackground(checked)
}
/>
</div>
<p className="text-sm text-muted-foreground">
{t("stream.playInBackground.tips")}
</p>
</div> </div>
)} )}
{isRestreamed && (
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<Label <Label
className="mx-0 cursor-pointer text-primary" className="mx-0 cursor-pointer text-primary"
htmlFor="showstats" htmlFor="backgroundplay"
> >
{t("streaming.showStats.label", { {t("stream.playInBackground.label")}
ns: "components/dialog",
})}
</Label> </Label>
<Switch <Switch
className="ml-1" className="ml-1"
id="showstats" id="backgroundplay"
disabled={debug} disabled={debug}
checked={showStats} checked={playInBackground}
onCheckedChange={(checked) => setShowStats(checked)} onCheckedChange={(checked) =>
setPlayInBackground(checked)
}
/> />
</div> </div>
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
{t("streaming.showStats.desc", { {t("stream.playInBackground.tips")}
ns: "components/dialog",
})}
</p> </p>
</div> </div>
<div className="flex flex-col gap-1"> )}
<div className="flex items-center justify-between"> <div className="flex flex-col gap-1">
<Label <div className="flex items-center justify-between">
className="mx-0 cursor-pointer text-primary" <Label
htmlFor="debug" className="mx-0 cursor-pointer text-primary"
> htmlFor="showstats"
{t("streaming.debugView", { >
ns: "components/dialog", {t("streaming.showStats.label", {
})} ns: "components/dialog",
</Label> })}
<Switch </Label>
className="ml-1" <Switch
id="debug" className="ml-1"
checked={debug} id="showstats"
onCheckedChange={(checked) => setDebug(checked)} disabled={debug}
/> checked={showStats}
</div> onCheckedChange={(checked) => setShowStats(checked)}
/>
</div>
<p className="text-sm text-muted-foreground">
{t("streaming.showStats.desc", {
ns: "components/dialog",
})}
</p>
</div>
<div className="flex flex-col gap-1">
<div className="flex items-center justify-between">
<Label
className="mx-0 cursor-pointer text-primary"
htmlFor="debug"
>
{t("streaming.debugView", {
ns: "components/dialog",
})}
</Label>
<Switch
className="ml-1"
id="debug"
checked={debug}
onCheckedChange={(checked) => setDebug(checked)}
/>
</div> </div>
</div> </div>
</DropdownMenuContent> </div>
</DropdownMenu> </DropdownMenuContent>
)} </DropdownMenu>
</> </>
); );
} }