diff --git a/THIRD-PARTY-NOTICES b/THIRD-PARTY-NOTICES index bc8f3ff47..b46924a5a 100644 --- a/THIRD-PARTY-NOTICES +++ b/THIRD-PARTY-NOTICES @@ -50,6 +50,13 @@ Wan 2.1 / Wan 2.2 Apache-2.0 https://github.com/Wan-Video/Wan2.1 Wan-Video team. Model weights are downloaded from upstream at runtime and are not redistributed in this repository. +Real-ESRGAN BSD-3-Clause https://github.com/xinntao/Real-ESRGAN +BasicSR Apache-2.0 https://github.com/XPixelGroup/BasicSR + The optional Real-ESRGAN integration implements RRDBNet and compact SRVGG + architecture definitions compatible with public Real-ESRGAN checkpoints. + Model weights are downloaded from upstream at runtime and are not + redistributed in this repository. + ================================================================================ Optional integration: integrations/omnidreams ================================================================================ @@ -100,6 +107,12 @@ aiohttp Apache-2.0 https://github.com/aio-libs/aiohttp aiortc BSD-3-Clause https://github.com/aiortc/aiortc opencv-python-headless Apache-2.0 https://github.com/opencv/opencv-python +================================================================================ +Optional integration: integrations/realesrgan +================================================================================ + +opencv-python-headless Apache-2.0 https://github.com/opencv/opencv-python + ================================================================================ Source-level redistributions ================================================================================ diff --git a/feed_uplift_video.sh b/feed_uplift_video.sh new file mode 100755 index 000000000..d2ef3cb70 --- /dev/null +++ b/feed_uplift_video.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euo pipefail + +cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +usage() { + cat <<'EOF' +Usage: + ./feed_uplift_video.sh /path/to/input.mp4 [flashdreams-feed-frames args...] + +Environment: + UPLIFT_SERVER Server address. Default: 127.0.0.1:8090 + UPLIFT_TARGET_FPS Feed rate. Default: 30 + +Examples: + ./feed_uplift_video.sh /tmp/clip.mp4 + UPLIFT_SERVER=galaxy-ts4-108:8090 ./feed_uplift_video.sh /tmp/clip.mp4 + ./feed_uplift_video.sh /tmp/clip.mp4 --no_pace + ./feed_uplift_video.sh /tmp/clip.mp4 --max_chunks 20 +EOF +} + +if [[ $# -lt 1 || "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then + usage + exit 0 +fi + +INPUT_VIDEO="$1" +shift + +SERVER="${UPLIFT_SERVER:-${FLASHVSR_UPLIFT_SERVER:-127.0.0.1:8090}}" +TARGET_FPS="${UPLIFT_TARGET_FPS:-${FLASHVSR_TARGET_FPS:-30}}" + +export PYTHONPATH="integrations/flashvsr:flashdreams${PYTHONPATH:+:${PYTHONPATH}}" + +echo "Feeding ${INPUT_VIDEO} continuously to uplift server at ${SERVER}" +exec uv run --package flashdreams --extra serving flashdreams-feed-frames \ + --server "${SERVER}" \ + --input "${INPUT_VIDEO}" \ + --target_fps "${TARGET_FPS}" \ + "$@" diff --git a/flashdreams/flashdreams/scripts/cli.py b/flashdreams/flashdreams/scripts/cli.py index e6c69ae7f..70dc2ae6e 100644 --- a/flashdreams/flashdreams/scripts/cli.py +++ b/flashdreams/flashdreams/scripts/cli.py @@ -28,6 +28,7 @@ flashdreams-run wan21-i2v-14b-480p --prompt "..." --image-path frame.png flashdreams-run --no-instantiate template-offline # resolve config only flashdreams-run wan21-t2v-1.3b-480p --postprocess.preset flashvsr-v1.1-sparse-2.0 + flashdreams-run wan21-t2v-1.3b-480p --postprocess.preset realesrgan # Multi-GPU via context-parallelism (integration transformers auto-detect # CP size from the launcher's WORLD group). ``--no-python`` tells diff --git a/flashdreams/flashdreams/serving/uplift/__init__.py b/flashdreams/flashdreams/serving/uplift/__init__.py new file mode 100644 index 000000000..559cc7ac1 --- /dev/null +++ b/flashdreams/flashdreams/serving/uplift/__init__.py @@ -0,0 +1,4 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""Shared gRPC uplift protocol, client, and browser-viewer utilities.""" diff --git a/integrations/flashvsr/flashvsr/grpc/protos/__init__.py b/flashdreams/flashdreams/serving/uplift/protos/__init__.py similarity index 90% rename from integrations/flashvsr/flashvsr/grpc/protos/__init__.py rename to flashdreams/flashdreams/serving/uplift/protos/__init__.py index e8ae61670..b33e22d78 100644 --- a/integrations/flashvsr/flashvsr/grpc/protos/__init__.py +++ b/flashdreams/flashdreams/serving/uplift/protos/__init__.py @@ -13,5 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Generated protobuf modules for FlashVSR gRPC serving.""" - +"""Generated protobuf modules for FlashDreams video uplift serving.""" diff --git a/integrations/flashvsr/flashvsr/grpc/protos/flashvsr.proto b/flashdreams/flashdreams/serving/uplift/protos/uplift.proto similarity index 95% rename from integrations/flashvsr/flashvsr/grpc/protos/flashvsr.proto rename to flashdreams/flashdreams/serving/uplift/protos/uplift.proto index 4efab6b28..4ff2ab456 100644 --- a/integrations/flashvsr/flashvsr/grpc/protos/flashvsr.proto +++ b/flashdreams/flashdreams/serving/uplift/protos/uplift.proto @@ -15,12 +15,13 @@ syntax = "proto3"; -package flashvsr; +package flashdreams.uplift; // --------------------------------------------------------------------------- -// FlashVSR gRPC Service +// FlashDreams video uplift gRPC service // -// Streaming video super-resolution (2× or 4×) using a diffusion-based model. +// Streaming video super-resolution (2× or 4×) using any server-side model +// implementation that speaks this protocol. // Two usage patterns: // // Unary chunk-by-chunk flow (best for integration into existing pipelines): @@ -36,7 +37,7 @@ package flashvsr; // get_status — liveness/readiness check // --------------------------------------------------------------------------- -service FlashVSR { +service VideoUplift { rpc get_status (StatusRequest) returns (StatusResponse); rpc start_session (StartSessionRequest) returns (StartSessionResponse); rpc end_session (EndSessionRequest) returns (EndSessionResponse); @@ -53,7 +54,7 @@ message StatusRequest {} message StatusResponse { bool ready = 1; // true once the model is loaded string device = 2; // e.g. "cuda:0" - string model_name = 3; // e.g. "FlashVSR-v1.1" + string model_name = 3; // e.g. "FlashVSR-v1.1" or "RealESRGAN/x2plus" repeated string active_sessions = 4; // currently open session IDs } diff --git a/flashdreams/flashdreams/serving/uplift/protos/uplift_pb2.py b/flashdreams/flashdreams/serving/uplift/protos/uplift_pb2.py new file mode 100644 index 000000000..936b5a3a9 --- /dev/null +++ b/flashdreams/flashdreams/serving/uplift/protos/uplift_pb2.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: flashdreams/serving/uplift/protos/uplift.proto +# Protobuf Python Version: 6.31.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 31, + 1, + '', + 'flashdreams/serving/uplift/protos/uplift.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n.flashdreams/serving/uplift/protos/uplift.proto\x12\x12\x66lashdreams.uplift\"\x0f\n\rStatusRequest\"\\\n\x0eStatusResponse\x12\r\n\x05ready\x18\x01 \x01(\x08\x12\x0e\n\x06\x64\x65vice\x18\x02 \x01(\t\x12\x12\n\nmodel_name\x18\x03 \x01(\t\x12\x17\n\x0f\x61\x63tive_sessions\x18\x04 \x03(\t\"y\n\x13StartSessionRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x14\n\x0cinput_height\x18\x02 \x01(\x05\x12\x13\n\x0binput_width\x18\x03 \x01(\x05\x12\r\n\x05scale\x18\x04 \x01(\x05\x12\x14\n\x0csparse_ratio\x18\x05 \x01(\x02\"J\n\x14StartSessionResponse\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\r\n\x05\x65rror\x18\x03 \x01(\t\"\'\n\x11\x45ndSessionRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\"%\n\x12\x45ndSessionResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\"\xbb\x02\n\x13UpscaleChunkRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x14\n\x0cinput_height\x18\x02 \x01(\x05\x12\x13\n\x0binput_width\x18\x03 \x01(\x05\x12\r\n\x05scale\x18\x04 \x01(\x05\x12\x14\n\x0csparse_ratio\x18\x05 \x01(\x02\x12\x12\n\nframes_rgb\x18\x06 \x01(\x0c\x12\x12\n\nnum_frames\x18\x07 \x01(\x05\x12\x0e\n\x06height\x18\x08 \x01(\x05\x12\r\n\x05width\x18\t \x01(\x05\x12\x13\n\x0b\x63hunk_index\x18\n \x01(\x05\x12\x39\n\x0e\x66rame_encoding\x18\x0b \x01(\x0e\x32!.flashdreams.uplift.FrameEncoding\x12\x13\n\x0b\x66rames_jpeg\x18\x0c \x03(\x0c\x12\x14\n\x0c\x64isplay_only\x18\r \x01(\x08\"\xc1\x01\n\x14UpscaleChunkResponse\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x12\n\nframes_rgb\x18\x02 \x01(\x0c\x12\x12\n\nnum_frames\x18\x03 \x01(\x05\x12\x0e\n\x06height\x18\x04 \x01(\x05\x12\r\n\x05width\x18\x05 \x01(\x05\x12\x13\n\x0b\x63hunk_index\x18\x06 \x01(\x05\x12\x12\n\nelapsed_ms\x18\x07 \x01(\x02\x12\r\n\x05\x65rror\x18\x08 \x01(\t\x12\x16\n\x0e\x66rames_omitted\x18\t \x01(\x08*D\n\rFrameEncoding\x12\x1a\n\x16\x46RAME_ENCODING_RAW_RGB\x10\x00\x12\x17\n\x13\x46RAME_ENCODING_JPEG\x10\x01\x32\xf0\x03\n\x0bVideoUplift\x12S\n\nget_status\x12!.flashdreams.uplift.StatusRequest\x1a\".flashdreams.uplift.StatusResponse\x12\x62\n\rstart_session\x12\'.flashdreams.uplift.StartSessionRequest\x1a(.flashdreams.uplift.StartSessionResponse\x12\\\n\x0b\x65nd_session\x12%.flashdreams.uplift.EndSessionRequest\x1a&.flashdreams.uplift.EndSessionResponse\x12\x62\n\rupscale_chunk\x12\'.flashdreams.uplift.UpscaleChunkRequest\x1a(.flashdreams.uplift.UpscaleChunkResponse\x12\x66\n\rupscale_video\x12\'.flashdreams.uplift.UpscaleChunkRequest\x1a(.flashdreams.uplift.UpscaleChunkResponse(\x01\x30\x01\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flashdreams.serving.uplift.protos.uplift_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None + _globals['_FRAMEENCODING']._serialized_start=974 + _globals['_FRAMEENCODING']._serialized_end=1042 + _globals['_STATUSREQUEST']._serialized_start=70 + _globals['_STATUSREQUEST']._serialized_end=85 + _globals['_STATUSRESPONSE']._serialized_start=87 + _globals['_STATUSRESPONSE']._serialized_end=179 + _globals['_STARTSESSIONREQUEST']._serialized_start=181 + _globals['_STARTSESSIONREQUEST']._serialized_end=302 + _globals['_STARTSESSIONRESPONSE']._serialized_start=304 + _globals['_STARTSESSIONRESPONSE']._serialized_end=378 + _globals['_ENDSESSIONREQUEST']._serialized_start=380 + _globals['_ENDSESSIONREQUEST']._serialized_end=419 + _globals['_ENDSESSIONRESPONSE']._serialized_start=421 + _globals['_ENDSESSIONRESPONSE']._serialized_end=458 + _globals['_UPSCALECHUNKREQUEST']._serialized_start=461 + _globals['_UPSCALECHUNKREQUEST']._serialized_end=776 + _globals['_UPSCALECHUNKRESPONSE']._serialized_start=779 + _globals['_UPSCALECHUNKRESPONSE']._serialized_end=972 + _globals['_VIDEOUPLIFT']._serialized_start=1045 + _globals['_VIDEOUPLIFT']._serialized_end=1541 +# @@protoc_insertion_point(module_scope) diff --git a/integrations/flashvsr/flashvsr/grpc/protos/flashvsr_pb2.pyi b/flashdreams/flashdreams/serving/uplift/protos/uplift_pb2.pyi similarity index 100% rename from integrations/flashvsr/flashvsr/grpc/protos/flashvsr_pb2.pyi rename to flashdreams/flashdreams/serving/uplift/protos/uplift_pb2.pyi diff --git a/integrations/flashvsr/flashvsr/grpc/protos/flashvsr_pb2_grpc.py b/flashdreams/flashdreams/serving/uplift/protos/uplift_pb2_grpc.py similarity index 63% rename from integrations/flashvsr/flashvsr/grpc/protos/flashvsr_pb2_grpc.py rename to flashdreams/flashdreams/serving/uplift/protos/uplift_pb2_grpc.py index d1d1f52de..246b7777f 100644 --- a/integrations/flashvsr/flashvsr/grpc/protos/flashvsr_pb2_grpc.py +++ b/flashdreams/flashdreams/serving/uplift/protos/uplift_pb2_grpc.py @@ -5,7 +5,7 @@ import grpc import warnings -from flashvsr.grpc.protos import flashvsr_pb2 as flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2 +from flashdreams.serving.uplift.protos import uplift_pb2 as flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2 GRPC_GENERATED_VERSION = '1.80.0' GRPC_VERSION = grpc.__version__ @@ -20,18 +20,19 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + ' but the generated code in flashvsr/grpc/protos/flashvsr_pb2_grpc.py depends on' + + ' but the generated code in flashdreams/serving/uplift/protos/uplift_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' ) -class FlashVSRStub(object): +class VideoUpliftStub(object): """--------------------------------------------------------------------------- - FlashVSR gRPC Service + FlashDreams video uplift gRPC service - Streaming video super-resolution (2× or 4×) using a diffusion-based model. + Streaming video super-resolution (2× or 4×) using any server-side model + implementation that speaks this protocol. Two usage patterns: Unary chunk-by-chunk flow (best for integration into existing pipelines): @@ -56,37 +57,38 @@ def __init__(self, channel): channel: A grpc.Channel. """ self.get_status = channel.unary_unary( - '/flashvsr.FlashVSR/get_status', - request_serializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.StatusRequest.SerializeToString, - response_deserializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.StatusResponse.FromString, + '/flashdreams.uplift.VideoUplift/get_status', + request_serializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.StatusRequest.SerializeToString, + response_deserializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.StatusResponse.FromString, _registered_method=True) self.start_session = channel.unary_unary( - '/flashvsr.FlashVSR/start_session', - request_serializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.StartSessionRequest.SerializeToString, - response_deserializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.StartSessionResponse.FromString, + '/flashdreams.uplift.VideoUplift/start_session', + request_serializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.StartSessionRequest.SerializeToString, + response_deserializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.StartSessionResponse.FromString, _registered_method=True) self.end_session = channel.unary_unary( - '/flashvsr.FlashVSR/end_session', - request_serializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.EndSessionRequest.SerializeToString, - response_deserializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.EndSessionResponse.FromString, + '/flashdreams.uplift.VideoUplift/end_session', + request_serializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.EndSessionRequest.SerializeToString, + response_deserializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.EndSessionResponse.FromString, _registered_method=True) self.upscale_chunk = channel.unary_unary( - '/flashvsr.FlashVSR/upscale_chunk', - request_serializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.UpscaleChunkRequest.SerializeToString, - response_deserializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.UpscaleChunkResponse.FromString, + '/flashdreams.uplift.VideoUplift/upscale_chunk', + request_serializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.UpscaleChunkRequest.SerializeToString, + response_deserializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.UpscaleChunkResponse.FromString, _registered_method=True) self.upscale_video = channel.stream_stream( - '/flashvsr.FlashVSR/upscale_video', - request_serializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.UpscaleChunkRequest.SerializeToString, - response_deserializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.UpscaleChunkResponse.FromString, + '/flashdreams.uplift.VideoUplift/upscale_video', + request_serializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.UpscaleChunkRequest.SerializeToString, + response_deserializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.UpscaleChunkResponse.FromString, _registered_method=True) -class FlashVSRServicer(object): +class VideoUpliftServicer(object): """--------------------------------------------------------------------------- - FlashVSR gRPC Service + FlashDreams video uplift gRPC service - Streaming video super-resolution (2× or 4×) using a diffusion-based model. + Streaming video super-resolution (2× or 4×) using any server-side model + implementation that speaks this protocol. Two usage patterns: Unary chunk-by-chunk flow (best for integration into existing pipelines): @@ -135,46 +137,47 @@ def upscale_video(self, request_iterator, context): raise NotImplementedError('Method not implemented!') -def add_FlashVSRServicer_to_server(servicer, server): +def add_VideoUpliftServicer_to_server(servicer, server): rpc_method_handlers = { 'get_status': grpc.unary_unary_rpc_method_handler( servicer.get_status, - request_deserializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.StatusRequest.FromString, - response_serializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.StatusResponse.SerializeToString, + request_deserializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.StatusRequest.FromString, + response_serializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.StatusResponse.SerializeToString, ), 'start_session': grpc.unary_unary_rpc_method_handler( servicer.start_session, - request_deserializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.StartSessionRequest.FromString, - response_serializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.StartSessionResponse.SerializeToString, + request_deserializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.StartSessionRequest.FromString, + response_serializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.StartSessionResponse.SerializeToString, ), 'end_session': grpc.unary_unary_rpc_method_handler( servicer.end_session, - request_deserializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.EndSessionRequest.FromString, - response_serializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.EndSessionResponse.SerializeToString, + request_deserializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.EndSessionRequest.FromString, + response_serializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.EndSessionResponse.SerializeToString, ), 'upscale_chunk': grpc.unary_unary_rpc_method_handler( servicer.upscale_chunk, - request_deserializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.UpscaleChunkRequest.FromString, - response_serializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.UpscaleChunkResponse.SerializeToString, + request_deserializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.UpscaleChunkRequest.FromString, + response_serializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.UpscaleChunkResponse.SerializeToString, ), 'upscale_video': grpc.stream_stream_rpc_method_handler( servicer.upscale_video, - request_deserializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.UpscaleChunkRequest.FromString, - response_serializer=flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.UpscaleChunkResponse.SerializeToString, + request_deserializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.UpscaleChunkRequest.FromString, + response_serializer=flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.UpscaleChunkResponse.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( - 'flashvsr.FlashVSR', rpc_method_handlers) + 'flashdreams.uplift.VideoUplift', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) - server.add_registered_method_handlers('flashvsr.FlashVSR', rpc_method_handlers) + server.add_registered_method_handlers('flashdreams.uplift.VideoUplift', rpc_method_handlers) # This class is part of an EXPERIMENTAL API. -class FlashVSR(object): +class VideoUplift(object): """--------------------------------------------------------------------------- - FlashVSR gRPC Service + FlashDreams video uplift gRPC service - Streaming video super-resolution (2× or 4×) using a diffusion-based model. + Streaming video super-resolution (2× or 4×) using any server-side model + implementation that speaks this protocol. Two usage patterns: Unary chunk-by-chunk flow (best for integration into existing pipelines): @@ -206,9 +209,9 @@ def get_status(request, return grpc.experimental.unary_unary( request, target, - '/flashvsr.FlashVSR/get_status', - flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.StatusRequest.SerializeToString, - flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.StatusResponse.FromString, + '/flashdreams.uplift.VideoUplift/get_status', + flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.StatusRequest.SerializeToString, + flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.StatusResponse.FromString, options, channel_credentials, insecure, @@ -233,9 +236,9 @@ def start_session(request, return grpc.experimental.unary_unary( request, target, - '/flashvsr.FlashVSR/start_session', - flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.StartSessionRequest.SerializeToString, - flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.StartSessionResponse.FromString, + '/flashdreams.uplift.VideoUplift/start_session', + flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.StartSessionRequest.SerializeToString, + flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.StartSessionResponse.FromString, options, channel_credentials, insecure, @@ -260,9 +263,9 @@ def end_session(request, return grpc.experimental.unary_unary( request, target, - '/flashvsr.FlashVSR/end_session', - flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.EndSessionRequest.SerializeToString, - flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.EndSessionResponse.FromString, + '/flashdreams.uplift.VideoUplift/end_session', + flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.EndSessionRequest.SerializeToString, + flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.EndSessionResponse.FromString, options, channel_credentials, insecure, @@ -287,9 +290,9 @@ def upscale_chunk(request, return grpc.experimental.unary_unary( request, target, - '/flashvsr.FlashVSR/upscale_chunk', - flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.UpscaleChunkRequest.SerializeToString, - flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.UpscaleChunkResponse.FromString, + '/flashdreams.uplift.VideoUplift/upscale_chunk', + flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.UpscaleChunkRequest.SerializeToString, + flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.UpscaleChunkResponse.FromString, options, channel_credentials, insecure, @@ -314,9 +317,9 @@ def upscale_video(request_iterator, return grpc.experimental.stream_stream( request_iterator, target, - '/flashvsr.FlashVSR/upscale_video', - flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.UpscaleChunkRequest.SerializeToString, - flashvsr_dot_grpc_dot_protos_dot_flashvsr__pb2.UpscaleChunkResponse.FromString, + '/flashdreams.uplift.VideoUplift/upscale_video', + flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.UpscaleChunkRequest.SerializeToString, + flashdreams_dot_serving_dot_uplift_dot_protos_dot_uplift__pb2.UpscaleChunkResponse.FromString, options, channel_credentials, insecure, diff --git a/integrations/flashvsr/flashvsr/grpc/streaming_view.py b/flashdreams/flashdreams/serving/uplift/streaming_view.py similarity index 92% rename from integrations/flashvsr/flashvsr/grpc/streaming_view.py rename to flashdreams/flashdreams/serving/uplift/streaming_view.py index eec54f48b..0b4964ad7 100644 --- a/integrations/flashvsr/flashvsr/grpc/streaming_view.py +++ b/flashdreams/flashdreams/serving/uplift/streaming_view.py @@ -13,13 +13,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""HTTP MJPEG viewer support for the FlashVSR gRPC server.""" +"""HTTP MJPEG viewer support for video uplift servers.""" import io import queue import threading import time -from dataclasses import dataclass +from dataclasses import dataclass, field from http import HTTPStatus from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer @@ -31,6 +31,7 @@ DEFAULT_VIEWER_JPEG_QUALITY = 90 DEFAULT_VIEWER_JPEG_BACKEND = "auto" DEFAULT_VIEWER_MAX_FPS = 60.0 +DEFAULT_VIEWER_PLAYBACK_FPS = 30.0 DEFAULT_VIEWER_FRAME_STRIDE = 1 _VIEWER_STOP = object() @@ -40,6 +41,7 @@ @dataclass class _ViewerPlaybackChunk: elapsed_ms: float + ready_at: float = field(default_factory=time.perf_counter) frames: np.ndarray | None = None jpegs: list[bytes] | None = None @@ -154,6 +156,7 @@ def __init__( jpeg_backend: str, chunk_queue_depth: int, max_fps: float, + playback_fps: float, frame_stride: int, ) -> None: self.host = host @@ -162,6 +165,7 @@ def __init__( self.jpeg_backend = jpeg_backend self.chunk_queue_depth = max(1, int(chunk_queue_depth)) self.max_fps = float(max_fps) + self.playback_fps = float(playback_fps) self.frame_stride = max(1, int(frame_stride)) self.original_hub = _MjpegFrameHub() self.upscaled_hub = _MjpegFrameHub() @@ -207,7 +211,7 @@ def _send_index(self) -> None:
-